Merge "cas: convert MediaCas to HIDL"
diff --git a/Android.mk b/Android.mk
index 1e61e44..6fb5aec 100644
--- a/Android.mk
+++ b/Android.mk
@@ -292,6 +292,7 @@
 	core/java/android/service/euicc/IGetEidCallback.aidl \
 	core/java/android/service/euicc/IGetEuiccInfoCallback.aidl \
 	core/java/android/service/euicc/IGetEuiccProfileInfoListCallback.aidl \
+	core/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl \
 	core/java/android/service/euicc/ISwitchToSubscriptionCallback.aidl \
 	core/java/android/service/euicc/IUpdateSubscriptionNicknameCallback.aidl \
 	core/java/android/service/gatekeeper/IGateKeeperService.aidl \
diff --git a/api/current.txt b/api/current.txt
index 2f8a451..0eab1fd 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -1935,6 +1935,7 @@
     field public static final int VideoView_error_text_invalid_progressive_playback = 17039381; // 0x1040015
     field public static final int VideoView_error_text_unknown = 17039377; // 0x1040011
     field public static final int VideoView_error_title = 17039378; // 0x1040012
+    field public static final int autofill = 17039386; // 0x104001a
     field public static final int cancel = 17039360; // 0x1040000
     field public static final int copy = 17039361; // 0x1040001
     field public static final int copyUrl = 17039362; // 0x1040002
@@ -3162,6 +3163,7 @@
 
   public final class AnimatorSet extends android.animation.Animator {
     ctor public AnimatorSet();
+    method public android.animation.AnimatorSet clone();
     method public java.util.ArrayList<android.animation.Animator> getChildAnimations();
     method public long getCurrentPlayTime();
     method public long getDuration();
@@ -3280,6 +3282,7 @@
 
   public final class ObjectAnimator extends android.animation.ValueAnimator {
     ctor public ObjectAnimator();
+    method public android.animation.ObjectAnimator clone();
     method public java.lang.String getPropertyName();
     method public java.lang.Object getTarget();
     method public static android.animation.ObjectAnimator ofArgb(java.lang.Object, java.lang.String, int...);
@@ -3305,6 +3308,7 @@
     method public static <T, V> android.animation.ObjectAnimator ofObject(T, android.util.Property<T, V>, android.animation.TypeConverter<android.graphics.PointF, V>, android.graphics.Path);
     method public static android.animation.ObjectAnimator ofPropertyValuesHolder(java.lang.Object, android.animation.PropertyValuesHolder...);
     method public void setAutoCancel(boolean);
+    method public android.animation.ObjectAnimator setDuration(long);
     method public void setProperty(android.util.Property);
     method public void setPropertyName(java.lang.String);
   }
@@ -3386,6 +3390,7 @@
     ctor public ValueAnimator();
     method public void addUpdateListener(android.animation.ValueAnimator.AnimatorUpdateListener);
     method public static boolean areAnimatorsEnabled();
+    method public android.animation.ValueAnimator clone();
     method public float getAnimatedFraction();
     method public java.lang.Object getAnimatedValue();
     method public java.lang.Object getAnimatedValue(java.lang.String);
@@ -4204,6 +4209,12 @@
 
   public class Application extends android.content.ContextWrapper implements android.content.ComponentCallbacks2 {
     ctor public Application();
+    method public android.app.Activity instantiateActivity(java.lang.ClassLoader, java.lang.String, android.content.Intent);
+    method public android.app.backup.BackupAgent instantiateBackupAgent(java.lang.ClassLoader, java.lang.String);
+    method public android.app.Instrumentation instantiateInstrumentation(java.lang.ClassLoader, java.lang.String);
+    method public android.content.ContentProvider instantiateProvider(java.lang.ClassLoader, java.lang.String);
+    method public android.content.BroadcastReceiver instantiateReceiver(java.lang.ClassLoader, java.lang.String, android.content.Intent);
+    method public android.app.Service instantiateService(java.lang.ClassLoader, java.lang.String, android.content.Intent);
     method public void onConfigurationChanged(android.content.res.Configuration);
     method public void onCreate();
     method public void onLowMemory();
@@ -4959,6 +4970,7 @@
     ctor public IntentService(java.lang.String);
     method public android.os.IBinder onBind(android.content.Intent);
     method protected abstract void onHandleIntent(android.content.Intent);
+    method public void onStart(android.content.Intent, int);
     method public void setIntentRedelivery(boolean);
   }
 
@@ -11066,6 +11078,7 @@
 
   public static class AssetFileDescriptor.AutoCloseInputStream extends android.os.ParcelFileDescriptor.AutoCloseInputStream {
     ctor public AssetFileDescriptor.AutoCloseInputStream(android.content.res.AssetFileDescriptor) throws java.io.IOException;
+    method public void mark(int);
   }
 
   public static class AssetFileDescriptor.AutoCloseOutputStream extends android.os.ParcelFileDescriptor.AutoCloseOutputStream {
@@ -11373,6 +11386,7 @@
     method public void copyStringToBuffer(int, android.database.CharArrayBuffer);
     method public void deactivate();
     method public void fillWindow(int, android.database.CursorWindow);
+    method protected void finalize();
     method public byte[] getBlob(int);
     method public int getColumnCount();
     method public int getColumnIndex(java.lang.String);
@@ -13847,6 +13861,7 @@
     method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
+    method public void setDither(boolean);
     method public void setOpacity(int);
     method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
   }
@@ -13927,6 +13942,7 @@
     method public void setAlpha(int);
     method public void setAntiAlias(boolean);
     method public void setColorFilter(android.graphics.ColorFilter);
+    method public void setDither(boolean);
     method public void setGravity(int);
     method public void setMipMap(boolean);
     method public void setTargetDensity(android.graphics.Canvas);
@@ -14052,6 +14068,7 @@
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
     method protected void setConstantState(android.graphics.drawable.DrawableContainer.DrawableContainerState);
+    method public void setDither(boolean);
     method public void setEnterFadeDuration(int);
     method public void setExitFadeDuration(int);
     method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
@@ -14118,6 +14135,7 @@
     method public void setColors(int[]);
     method public void setCornerRadii(float[]);
     method public void setCornerRadius(float);
+    method public void setDither(boolean);
     method public void setGradientCenter(float, float);
     method public void setGradientRadius(float);
     method public void setGradientType(int);
@@ -14212,6 +14230,7 @@
     method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
+    method public void setDither(boolean);
     method public void setDrawable(int, android.graphics.drawable.Drawable);
     method public boolean setDrawableByLayerId(int, android.graphics.drawable.Drawable);
     method public void setId(int, int);
@@ -14252,6 +14271,7 @@
     method public android.graphics.Paint getPaint();
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
+    method public void setDither(boolean);
     method public void setTargetDensity(android.graphics.Canvas);
     method public void setTargetDensity(android.util.DisplayMetrics);
     method public void setTargetDensity(int);
@@ -14314,6 +14334,7 @@
     method protected void onDraw(android.graphics.drawable.shapes.Shape, android.graphics.Canvas, android.graphics.Paint);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
+    method public void setDither(boolean);
     method public void setIntrinsicHeight(int);
     method public void setIntrinsicWidth(int);
     method public void setPadding(int, int, int, int);
@@ -14355,27 +14376,32 @@
 
   public class ArcShape extends android.graphics.drawable.shapes.RectShape {
     ctor public ArcShape(float, float);
+    method public android.graphics.drawable.shapes.ArcShape clone() throws java.lang.CloneNotSupportedException;
     method public final float getStartAngle();
     method public final float getSweepAngle();
   }
 
   public class OvalShape extends android.graphics.drawable.shapes.RectShape {
     ctor public OvalShape();
+    method public android.graphics.drawable.shapes.OvalShape clone() throws java.lang.CloneNotSupportedException;
   }
 
   public class PathShape extends android.graphics.drawable.shapes.Shape {
     ctor public PathShape(android.graphics.Path, float, float);
+    method public android.graphics.drawable.shapes.PathShape clone() throws java.lang.CloneNotSupportedException;
     method public void draw(android.graphics.Canvas, android.graphics.Paint);
   }
 
   public class RectShape extends android.graphics.drawable.shapes.Shape {
     ctor public RectShape();
+    method public android.graphics.drawable.shapes.RectShape clone() throws java.lang.CloneNotSupportedException;
     method public void draw(android.graphics.Canvas, android.graphics.Paint);
     method protected final android.graphics.RectF rect();
   }
 
   public class RoundRectShape extends android.graphics.drawable.shapes.RectShape {
     ctor public RoundRectShape(float[], android.graphics.RectF, float[]);
+    method public android.graphics.drawable.shapes.RoundRectShape clone() throws java.lang.CloneNotSupportedException;
   }
 
   public abstract class Shape implements java.lang.Cloneable {
@@ -14460,6 +14486,7 @@
     method public final void autoFocus(android.hardware.Camera.AutoFocusCallback);
     method public final void cancelAutoFocus();
     method public final boolean enableShutterSound(boolean);
+    method protected void finalize();
     method public static void getCameraInfo(int, android.hardware.Camera.CameraInfo);
     method public static int getNumberOfCameras();
     method public android.hardware.Camera.Parameters getParameters();
@@ -15069,6 +15096,7 @@
     method public <T> T get(android.hardware.camera2.CameraCharacteristics.Key<T>);
     method public java.util.List<android.hardware.camera2.CaptureRequest.Key<?>> getAvailableCaptureRequestKeys();
     method public java.util.List<android.hardware.camera2.CaptureResult.Key<?>> getAvailableCaptureResultKeys();
+    method public java.util.List<android.hardware.camera2.CameraCharacteristics.Key<?>> getKeys();
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> CONTROL_AE_AVAILABLE_ANTIBANDING_MODES;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> CONTROL_AE_AVAILABLE_MODES;
@@ -15425,6 +15453,7 @@
   public final class CaptureRequest extends android.hardware.camera2.CameraMetadata implements android.os.Parcelable {
     method public int describeContents();
     method public <T> T get(android.hardware.camera2.CaptureRequest.Key<T>);
+    method public java.util.List<android.hardware.camera2.CaptureRequest.Key<?>> getKeys();
     method public java.lang.Object getTag();
     method public boolean isReprocess();
     method public void writeToParcel(android.os.Parcel, int);
@@ -15503,6 +15532,7 @@
   public class CaptureResult extends android.hardware.camera2.CameraMetadata {
     method public <T> T get(android.hardware.camera2.CaptureResult.Key<T>);
     method public long getFrameNumber();
+    method public java.util.List<android.hardware.camera2.CaptureResult.Key<?>> getKeys();
     method public android.hardware.camera2.CaptureRequest getRequest();
     method public int getSequenceId();
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Boolean> BLACK_LEVEL_LOCK;
@@ -17936,6 +17966,7 @@
   }
 
   public class DateIntervalFormat extends android.icu.text.UFormat {
+    method public synchronized java.lang.Object clone();
     method public final java.lang.StringBuffer format(java.lang.Object, java.lang.StringBuffer, java.text.FieldPosition);
     method public final synchronized java.lang.StringBuffer format(android.icu.util.DateInterval, java.lang.StringBuffer, java.text.FieldPosition);
     method public final synchronized java.lang.StringBuffer format(android.icu.util.Calendar, android.icu.util.Calendar, java.lang.StringBuffer, java.text.FieldPosition);
@@ -18719,6 +18750,7 @@
 
   public final class RuleBasedCollator extends android.icu.text.Collator {
     ctor public RuleBasedCollator(java.lang.String) throws java.lang.Exception;
+    method public android.icu.text.RuleBasedCollator cloneAsThawed();
     method public int compare(java.lang.String, java.lang.String);
     method public android.icu.text.CollationElementIterator getCollationElementIterator(java.lang.String);
     method public android.icu.text.CollationElementIterator getCollationElementIterator(java.text.CharacterIterator);
@@ -18745,6 +18777,7 @@
     method public void setFrenchCollation(boolean);
     method public void setFrenchCollationDefault();
     method public void setLowerCaseFirst(boolean);
+    method public android.icu.text.RuleBasedCollator setMaxVariable(int);
     method public void setNumericCollation(boolean);
     method public void setNumericCollationDefault();
     method public void setStrengthDefault();
@@ -21265,6 +21298,7 @@
     ctor public AudioRecord(int, int, int, int, int) throws java.lang.IllegalArgumentException;
     method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
     method public deprecated void addOnRoutingChangedListener(android.media.AudioRecord.OnRoutingChangedListener, android.os.Handler);
+    method protected void finalize();
     method public int getAudioFormat();
     method public int getAudioSessionId();
     method public int getAudioSource();
@@ -21369,6 +21403,7 @@
     method public deprecated void addOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener, android.os.Handler);
     method public int attachAuxEffect(int);
     method public android.media.VolumeShaper createVolumeShaper(android.media.VolumeShaper.Configuration);
+    method protected void finalize();
     method public void flush();
     method public int getAudioFormat();
     method public int getAudioSessionId();
@@ -21767,6 +21802,7 @@
     method public boolean clearQueue();
     method public java.lang.Object clone() throws java.lang.CloneNotSupportedException;
     method public boolean closeJetFile();
+    method protected void finalize();
     method public static android.media.JetPlayer getJetPlayer();
     method public static int getMaxTracks();
     method public boolean loadJetFile(java.lang.String);
@@ -21806,6 +21842,7 @@
     ctor public MediaCas(int) throws android.media.MediaCasException.UnsupportedCasException;
     method public void close();
     method public static android.media.MediaCas.PluginDescriptor[] enumeratePlugins();
+    method protected void finalize();
     method public static boolean isSystemIdSupported(int);
     method public android.media.MediaCas.Session openSession() throws android.media.MediaCasException;
     method public void processEmm(byte[], int, int) throws android.media.MediaCasException;
@@ -21862,6 +21899,7 @@
     method public static android.view.Surface createPersistentInputSurface();
     method public final int dequeueInputBuffer(long);
     method public final int dequeueOutputBuffer(android.media.MediaCodec.BufferInfo, long);
+    method protected void finalize();
     method public final void flush();
     method public android.media.MediaCodecInfo getCodecInfo();
     method public java.nio.ByteBuffer getInputBuffer(int);
@@ -22273,6 +22311,7 @@
 
   public final class MediaCrypto {
     ctor public MediaCrypto(java.util.UUID, byte[]) throws android.media.MediaCryptoException;
+    method protected void finalize();
     method public static final boolean isCryptoSchemeSupported(java.util.UUID);
     method public final void release();
     method public final boolean requiresSecureDecoderComponent(java.lang.String);
@@ -22293,6 +22332,7 @@
     ctor public MediaDescrambler(int) throws android.media.MediaCasException.UnsupportedCasException;
     method public void close();
     method public final int descramble(java.nio.ByteBuffer, java.nio.ByteBuffer, android.media.MediaCodec.CryptoInfo);
+    method protected void finalize();
     method public final boolean requiresSecureDecoderComponent(java.lang.String);
     method public final void setMediaCasSession(android.media.MediaCas.Session);
   }
@@ -22335,6 +22375,7 @@
   public final class MediaDrm {
     ctor public MediaDrm(java.util.UUID) throws android.media.UnsupportedSchemeException;
     method public void closeSession(byte[]);
+    method protected void finalize();
     method public android.media.MediaDrm.CryptoSession getCryptoSession(byte[], java.lang.String, java.lang.String);
     method public android.media.MediaDrm.KeyRequest getKeyRequest(byte[], byte[], java.lang.String, int, java.util.HashMap<java.lang.String, java.lang.String>) throws android.media.NotProvisionedException;
     method public byte[] getPropertyByteArray(java.lang.String);
@@ -22431,6 +22472,7 @@
   public final class MediaExtractor {
     ctor public MediaExtractor();
     method public boolean advance();
+    method protected void finalize();
     method public long getCachedDuration();
     method public android.media.MediaExtractor.CasInfo getCasInfo(int);
     method public android.media.DrmInitData getDrmInitData();
@@ -22732,6 +22774,7 @@
     method public static android.media.MediaPlayer create(android.content.Context, int, android.media.AudioAttributes, int);
     method public android.media.VolumeShaper createVolumeShaper(android.media.VolumeShaper.Configuration);
     method public void deselectTrack(int) throws java.lang.IllegalStateException;
+    method protected void finalize();
     method public int getAudioSessionId();
     method public int getCurrentPosition();
     method public android.media.MediaPlayer.DrmInfo getDrmInfo();
@@ -22927,6 +22970,7 @@
 
   public class MediaRecorder {
     ctor public MediaRecorder();
+    method protected void finalize();
     method public static final int getAudioSourceMax();
     method public int getMaxAmplitude() throws java.lang.IllegalStateException;
     method public android.os.PersistableBundle getMetrics();
@@ -23198,6 +23242,7 @@
   public final class MediaSync {
     ctor public MediaSync();
     method public final android.view.Surface createInputSurface();
+    method protected void finalize();
     method public void flush();
     method public android.media.PlaybackParams getPlaybackParams();
     method public android.media.SyncParams getSyncParams();
@@ -23317,6 +23362,10 @@
 
   public deprecated class RemoteControlClient.MetadataEditor extends android.media.MediaMetadataEditor {
     method public synchronized void apply();
+    method public synchronized android.media.RemoteControlClient.MetadataEditor putBitmap(int, android.graphics.Bitmap) throws java.lang.IllegalArgumentException;
+    method public synchronized android.media.RemoteControlClient.MetadataEditor putLong(int, long) throws java.lang.IllegalArgumentException;
+    method public synchronized android.media.RemoteControlClient.MetadataEditor putObject(int, java.lang.Object) throws java.lang.IllegalArgumentException;
+    method public synchronized android.media.RemoteControlClient.MetadataEditor putString(int, java.lang.String) throws java.lang.IllegalArgumentException;
     field public static final int BITMAP_KEY_ARTWORK = 100; // 0x64
   }
 
@@ -23363,6 +23412,7 @@
   }
 
   public class Ringtone {
+    method protected void finalize();
     method public android.media.AudioAttributes getAudioAttributes();
     method public deprecated int getStreamType();
     method public java.lang.String getTitle(android.content.Context);
@@ -23416,6 +23466,7 @@
     ctor public deprecated SoundPool(int, int, int);
     method public final void autoPause();
     method public final void autoResume();
+    method protected void finalize();
     method public int load(java.lang.String, int);
     method public int load(android.content.Context, int, int);
     method public int load(android.content.res.AssetFileDescriptor, int);
@@ -23484,6 +23535,7 @@
 
   public class ToneGenerator {
     ctor public ToneGenerator(int, int);
+    method protected void finalize();
     method public final int getAudioSessionId();
     method public void release();
     method public boolean startTone(int);
@@ -23616,6 +23668,7 @@
   public final class VolumeShaper implements java.lang.AutoCloseable {
     method public void apply(android.media.VolumeShaper.Operation);
     method public void close();
+    method protected void finalize();
     method public float getVolume();
     method public void replace(android.media.VolumeShaper.Configuration, android.media.VolumeShaper.Operation, boolean);
   }
@@ -23670,6 +23723,7 @@
   }
 
   public class AudioEffect {
+    method protected void finalize();
     method public android.media.audiofx.AudioEffect.Descriptor getDescriptor() throws java.lang.IllegalStateException;
     method public boolean getEnabled() throws java.lang.IllegalStateException;
     method public int getId() throws java.lang.IllegalStateException;
@@ -23922,6 +23976,7 @@
 
   public class Visualizer {
     ctor public Visualizer(int) throws java.lang.RuntimeException, java.lang.UnsupportedOperationException;
+    method protected void finalize();
     method public int getCaptureSize() throws java.lang.IllegalStateException;
     method public static int[] getCaptureSizeRange();
     method public boolean getEnabled();
@@ -30585,6 +30640,7 @@
     method public void putStringArrayList(java.lang.String, java.util.ArrayList<java.lang.String>);
     method public void readFromParcel(android.os.Parcel);
     method public void setClassLoader(java.lang.ClassLoader);
+    method public synchronized java.lang.String toString();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.os.Bundle> CREATOR;
     field public static final android.os.Bundle EMPTY;
@@ -30815,6 +30871,7 @@
   public abstract class FileObserver {
     ctor public FileObserver(java.lang.String);
     ctor public FileObserver(java.lang.String, int);
+    method protected void finalize();
     method public abstract void onEvent(int, java.lang.String);
     method public void startWatching();
     method public void stopWatching();
@@ -30968,6 +31025,7 @@
     ctor public MemoryFile(java.lang.String, int) throws java.io.IOException;
     method public synchronized boolean allowPurging(boolean) throws java.io.IOException;
     method public void close();
+    method protected void finalize();
     method public java.io.InputStream getInputStream();
     method public java.io.OutputStream getOutputStream();
     method public boolean isPurgingAllowed();
@@ -31267,6 +31325,7 @@
     method public int describeContents();
     method public android.os.PersistableBundle getPersistableBundle(java.lang.String);
     method public void putPersistableBundle(java.lang.String, android.os.PersistableBundle);
+    method public synchronized java.lang.String toString();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.os.PersistableBundle> CREATOR;
     field public static final android.os.PersistableBundle EMPTY;
@@ -35589,6 +35648,7 @@
     method public static android.renderscript.AllocationAdapter create1D(android.renderscript.RenderScript, android.renderscript.Allocation);
     method public static android.renderscript.AllocationAdapter create2D(android.renderscript.RenderScript, android.renderscript.Allocation);
     method public static android.renderscript.AllocationAdapter createTyped(android.renderscript.RenderScript, android.renderscript.Allocation, android.renderscript.Type);
+    method public synchronized void resize(int);
     method public void setFace(android.renderscript.Type.CubemapFace);
     method public void setLOD(int);
     method public void setX(int);
@@ -40275,6 +40335,7 @@
 
   public static deprecated class SmsMessage.SubmitPdu {
     ctor public deprecated SmsMessage.SubmitPdu();
+    method public deprecated java.lang.String toString();
     field public deprecated byte[] encodedMessage;
     field public deprecated byte[] encodedScAddress;
   }
@@ -40338,6 +40399,7 @@
     method public java.util.List<junit.framework.TestCase> getTestCases();
     method public java.lang.String getTestClassName();
     method public junit.framework.TestResult getTestResult();
+    method protected java.lang.Class loadSuiteClass(java.lang.String) throws java.lang.ClassNotFoundException;
     method protected void runFailed(java.lang.String);
     method public void runTest();
     method public void runTest(junit.framework.TestResult);
@@ -40598,10 +40660,12 @@
     ctor protected MockContentProvider();
     ctor public MockContentProvider(android.content.Context);
     ctor public MockContentProvider(android.content.Context, java.lang.String, java.lang.String, android.content.pm.PathPermission[]);
+    method public android.content.ContentProviderResult[] applyBatch(java.util.ArrayList<android.content.ContentProviderOperation>);
     method public int delete(android.net.Uri, java.lang.String, java.lang.String[]);
     method public java.lang.String getType(android.net.Uri);
     method public android.net.Uri insert(android.net.Uri, android.content.ContentValues);
     method public boolean onCreate();
+    method public android.content.res.AssetFileDescriptor openTypedAssetFile(android.net.Uri, java.lang.String, android.os.Bundle);
     method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
     method public int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]);
   }
@@ -40871,6 +40935,10 @@
 
   public deprecated class MockResources extends android.content.res.Resources {
     ctor public MockResources();
+    method public int getColor(int) throws android.content.res.Resources.NotFoundException;
+    method public android.content.res.ColorStateList getColorStateList(int) throws android.content.res.Resources.NotFoundException;
+    method public android.graphics.drawable.Drawable getDrawable(int) throws android.content.res.Resources.NotFoundException;
+    method public void updateConfiguration(android.content.res.Configuration, android.util.DisplayMetrics);
   }
 
 }
@@ -42119,6 +42187,7 @@
 
   public abstract class MetricAffectingSpan extends android.text.style.CharacterStyle implements android.text.style.UpdateLayout {
     ctor public MetricAffectingSpan();
+    method public android.text.style.MetricAffectingSpan getUnderlying();
     method public abstract void updateMeasureState(android.text.TextPaint);
   }
 
@@ -42799,14 +42868,28 @@
   public class TransitionSet extends android.transition.Transition {
     ctor public TransitionSet();
     ctor public TransitionSet(android.content.Context, android.util.AttributeSet);
+    method public android.transition.TransitionSet addListener(android.transition.Transition.TransitionListener);
+    method public android.transition.TransitionSet addTarget(android.view.View);
+    method public android.transition.TransitionSet addTarget(int);
+    method public android.transition.TransitionSet addTarget(java.lang.String);
+    method public android.transition.TransitionSet addTarget(java.lang.Class);
     method public android.transition.TransitionSet addTransition(android.transition.Transition);
     method public void captureEndValues(android.transition.TransitionValues);
     method public void captureStartValues(android.transition.TransitionValues);
+    method public android.transition.TransitionSet clone();
     method public int getOrdering();
     method public android.transition.Transition getTransitionAt(int);
     method public int getTransitionCount();
+    method public android.transition.TransitionSet removeListener(android.transition.Transition.TransitionListener);
+    method public android.transition.TransitionSet removeTarget(int);
+    method public android.transition.TransitionSet removeTarget(android.view.View);
+    method public android.transition.TransitionSet removeTarget(java.lang.Class);
+    method public android.transition.TransitionSet removeTarget(java.lang.String);
     method public android.transition.TransitionSet removeTransition(android.transition.Transition);
+    method public android.transition.TransitionSet setDuration(long);
+    method public android.transition.TransitionSet setInterpolator(android.animation.TimeInterpolator);
     method public android.transition.TransitionSet setOrdering(int);
+    method public android.transition.TransitionSet setStartDelay(long);
     field public static final int ORDERING_SEQUENTIAL = 1; // 0x1
     field public static final int ORDERING_TOGETHER = 0; // 0x0
   }
@@ -42971,6 +43054,9 @@
 
   public class Base64InputStream extends java.io.FilterInputStream {
     ctor public Base64InputStream(java.io.InputStream, int);
+    method public int available();
+    method public void mark(int);
+    method public void reset();
   }
 
   public class Base64OutputStream extends java.io.FilterOutputStream {
@@ -45086,6 +45172,7 @@
     method public android.graphics.Canvas lockCanvas();
     method public android.graphics.Canvas lockCanvas(android.graphics.Rect);
     method protected final void onDraw(android.graphics.Canvas);
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable);
     method public void setOpaque(boolean);
     method public void setSurfaceTexture(android.graphics.SurfaceTexture);
     method public void setSurfaceTextureListener(android.view.TextureView.SurfaceTextureListener);
@@ -46109,6 +46196,7 @@
     method public int getLayoutMode();
     method public android.animation.LayoutTransition getLayoutTransition();
     method public int getNestedScrollAxes();
+    method public android.view.ViewGroupOverlay getOverlay();
     method public int getPersistentDrawingCache();
     method public boolean getTouchscreenBlocksFocus();
     method public int indexOfChild(android.view.View);
@@ -47388,6 +47476,7 @@
     ctor public Animation(android.content.Context, android.util.AttributeSet);
     method protected void applyTransformation(float, android.view.animation.Transformation);
     method public void cancel();
+    method protected android.view.animation.Animation clone() throws java.lang.CloneNotSupportedException;
     method public long computeDurationHint();
     method protected void ensureInterpolator();
     method public int getBackgroundColor();
@@ -47459,6 +47548,7 @@
     ctor public AnimationSet(android.content.Context, android.util.AttributeSet);
     ctor public AnimationSet(boolean);
     method public void addAnimation(android.view.animation.Animation);
+    method protected android.view.animation.AnimationSet clone() throws java.lang.CloneNotSupportedException;
     method public java.util.List<android.view.animation.Animation> getAnimations();
   }
 
@@ -48309,6 +48399,10 @@
   public final deprecated class CookieSyncManager extends android.webkit.WebSyncManager {
     method public static android.webkit.CookieSyncManager createInstance(android.content.Context);
     method public static android.webkit.CookieSyncManager getInstance();
+    method public deprecated void resetSync();
+    method public deprecated void startSync();
+    method public deprecated void stopSync();
+    method public deprecated void sync();
     method protected deprecated void syncFromRamToFlash();
     field protected static final java.lang.String LOGTAG = "websync";
     field protected android.webkit.WebViewDatabase mDataBase;
@@ -48861,6 +48955,7 @@
     method public void setWebChromeClient(android.webkit.WebChromeClient);
     method public static void setWebContentsDebuggingEnabled(boolean);
     method public void setWebViewClient(android.webkit.WebViewClient);
+    method public deprecated boolean shouldDelayChildPressedState();
     method public deprecated boolean showFindDialog(java.lang.String, boolean);
     method public static void shutdownSafeBrowsing();
     method public void stopLoading();
@@ -48993,6 +49088,7 @@
     method public void clearTextFilter();
     method public void deferNotifyDataSetChanged();
     method public void fling(int);
+    method public android.widget.AbsListView.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public int getCacheColorHint();
     method public int getCheckedItemCount();
     method public long[] getCheckedItemIds();
@@ -49159,6 +49255,9 @@
     ctor public ActionMenuView(android.content.Context);
     ctor public ActionMenuView(android.content.Context, android.util.AttributeSet);
     method public void dismissPopupMenus();
+    method protected android.widget.ActionMenuView.LayoutParams generateDefaultLayoutParams();
+    method public android.widget.ActionMenuView.LayoutParams generateLayoutParams(android.util.AttributeSet);
+    method protected android.widget.ActionMenuView.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public android.view.Menu getMenu();
     method public android.graphics.drawable.Drawable getOverflowIcon();
     method public int getPopupTheme();
@@ -49334,7 +49433,6 @@
     method public void addAll(T...);
     method public void clear();
     method public static android.widget.ArrayAdapter<java.lang.CharSequence> createFromResource(android.content.Context, int, int);
-    method public java.lang.CharSequence[] getAutofillOptions();
     method public android.content.Context getContext();
     method public int getCount();
     method public android.content.res.Resources.Theme getDropDownViewTheme();
@@ -49424,6 +49522,7 @@
     method public void notifyDataSetChanged();
     method public void notifyDataSetInvalidated();
     method public void registerDataSetObserver(android.database.DataSetObserver);
+    method public void setAutofillOptions(java.lang.CharSequence...);
     method public void unregisterDataSetObserver(android.database.DataSetObserver);
   }
 
@@ -49702,6 +49801,7 @@
     ctor public EditText(android.content.Context, android.util.AttributeSet, int);
     ctor public EditText(android.content.Context, android.util.AttributeSet, int, int);
     method public void extendSelection(int);
+    method public android.text.Editable getText();
     method public void selectAll();
     method public void setSelection(int, int);
     method public void setSelection(int);
@@ -49823,6 +49923,8 @@
     ctor public FrameLayout(android.content.Context, android.util.AttributeSet);
     ctor public FrameLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public FrameLayout(android.content.Context, android.util.AttributeSet, int, int);
+    method protected android.widget.FrameLayout.LayoutParams generateDefaultLayoutParams();
+    method public android.widget.FrameLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public deprecated boolean getConsiderGoneChildrenWhenMeasuring();
     method public boolean getMeasureAllChildren();
     method protected void onLayout(boolean, int, int, int, int);
@@ -49869,6 +49971,9 @@
     ctor public GridLayout(android.content.Context, android.util.AttributeSet);
     ctor public GridLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public GridLayout(android.content.Context, android.util.AttributeSet, int, int);
+    method protected android.widget.GridLayout.LayoutParams generateDefaultLayoutParams();
+    method public android.widget.GridLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
+    method protected android.widget.GridLayout.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public int getAlignmentMode();
     method public int getColumnCount();
     method public int getOrientation();
@@ -50081,6 +50186,9 @@
     ctor public LinearLayout(android.content.Context, android.util.AttributeSet);
     ctor public LinearLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public LinearLayout(android.content.Context, android.util.AttributeSet, int, int);
+    method protected android.widget.LinearLayout.LayoutParams generateDefaultLayoutParams();
+    method public android.widget.LinearLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
+    method protected android.widget.LinearLayout.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public int getBaselineAlignedChildIndex();
     method public android.graphics.drawable.Drawable getDividerDrawable();
     method public int getDividerPadding();
@@ -50467,6 +50575,8 @@
     method public final synchronized void incrementSecondaryProgressBy(int);
     method public boolean isAnimating();
     method public synchronized boolean isIndeterminate();
+    method protected synchronized void onDraw(android.graphics.Canvas);
+    method protected synchronized void onMeasure(int, int);
     method public void onRestoreInstanceState(android.os.Parcelable);
     method public android.os.Parcelable onSaveInstanceState();
     method public synchronized void setIndeterminate(boolean);
@@ -50522,6 +50632,7 @@
     ctor public RadioGroup(android.content.Context, android.util.AttributeSet);
     method public void check(int);
     method public void clearCheck();
+    method public android.widget.RadioGroup.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public int getCheckedRadioButtonId();
     method public void setOnCheckedChangeListener(android.widget.RadioGroup.OnCheckedChangeListener);
   }
@@ -50564,6 +50675,7 @@
     ctor public RelativeLayout(android.content.Context, android.util.AttributeSet);
     ctor public RelativeLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public RelativeLayout(android.content.Context, android.util.AttributeSet, int, int);
+    method public android.widget.RelativeLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public int getGravity();
     method protected void onLayout(boolean, int, int, int, int);
     method public void setGravity(int);
@@ -51107,6 +51219,7 @@
   public class TableLayout extends android.widget.LinearLayout {
     ctor public TableLayout(android.content.Context);
     ctor public TableLayout(android.content.Context, android.util.AttributeSet);
+    method public android.widget.TableLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public boolean isColumnCollapsed(int);
     method public boolean isColumnShrinkable(int);
     method public boolean isColumnStretchable(int);
@@ -51131,6 +51244,7 @@
   public class TableRow extends android.widget.LinearLayout {
     ctor public TableRow(android.content.Context);
     ctor public TableRow(android.content.Context, android.util.AttributeSet);
+    method public android.widget.TableRow.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public android.view.View getVirtualChildAt(int);
     method public int getVirtualChildCount();
   }
@@ -51472,6 +51586,7 @@
     ctor public ToggleButton(android.content.Context);
     method public java.lang.CharSequence getTextOff();
     method public java.lang.CharSequence getTextOn();
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable);
     method public void setTextOff(java.lang.CharSequence);
     method public void setTextOn(java.lang.CharSequence);
   }
@@ -51483,6 +51598,9 @@
     ctor public Toolbar(android.content.Context, android.util.AttributeSet, int, int);
     method public void collapseActionView();
     method public void dismissPopupMenus();
+    method protected android.widget.Toolbar.LayoutParams generateDefaultLayoutParams();
+    method public android.widget.Toolbar.LayoutParams generateLayoutParams(android.util.AttributeSet);
+    method protected android.widget.Toolbar.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public int getContentInsetEnd();
     method public int getContentInsetEndWithActions();
     method public int getContentInsetLeft();
@@ -52004,6 +52122,8 @@
   public class BaseDexClassLoader extends java.lang.ClassLoader {
     ctor public BaseDexClassLoader(java.lang.String, java.io.File, java.lang.String, java.lang.ClassLoader);
     method public java.lang.String findLibrary(java.lang.String);
+    method protected java.util.Enumeration<java.net.URL> findResources(java.lang.String);
+    method protected synchronized java.lang.Package getPackage(java.lang.String);
   }
 
   public class DexClassLoader extends dalvik.system.BaseDexClassLoader {
@@ -52225,6 +52345,10 @@
   public class BufferedInputStream extends java.io.FilterInputStream {
     ctor public BufferedInputStream(java.io.InputStream);
     ctor public BufferedInputStream(java.io.InputStream, int);
+    method public synchronized int available() throws java.io.IOException;
+    method public synchronized int read() throws java.io.IOException;
+    method public synchronized int read(byte[], int, int) throws java.io.IOException;
+    method public synchronized long skip(long) throws java.io.IOException;
     field protected volatile byte[] buf;
     field protected int count;
     field protected int marklimit;
@@ -52235,6 +52359,9 @@
   public class BufferedOutputStream extends java.io.FilterOutputStream {
     ctor public BufferedOutputStream(java.io.OutputStream);
     ctor public BufferedOutputStream(java.io.OutputStream, int);
+    method public synchronized void flush() throws java.io.IOException;
+    method public synchronized void write(int) throws java.io.IOException;
+    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     field protected byte[] buf;
     field protected int count;
   }
@@ -52260,7 +52387,12 @@
   public class ByteArrayInputStream extends java.io.InputStream {
     ctor public ByteArrayInputStream(byte[]);
     ctor public ByteArrayInputStream(byte[], int, int);
+    method public synchronized int available();
+    method public void mark(int);
     method public synchronized int read();
+    method public synchronized int read(byte[], int, int);
+    method public synchronized void reset();
+    method public synchronized long skip(long);
     field protected byte[] buf;
     field protected int count;
     field protected int mark;
@@ -52273,9 +52405,11 @@
     method public synchronized void reset();
     method public synchronized int size();
     method public synchronized byte[] toByteArray();
+    method public synchronized java.lang.String toString();
     method public synchronized java.lang.String toString(java.lang.String) throws java.io.UnsupportedEncodingException;
     method public deprecated synchronized java.lang.String toString(int);
     method public synchronized void write(int);
+    method public synchronized void write(byte[], int, int);
     method public synchronized void writeTo(java.io.OutputStream) throws java.io.IOException;
     field protected byte[] buf;
     field protected int count;
@@ -52295,12 +52429,17 @@
   public class CharArrayWriter extends java.io.Writer {
     ctor public CharArrayWriter();
     ctor public CharArrayWriter(int);
+    method public java.io.CharArrayWriter append(java.lang.CharSequence);
+    method public java.io.CharArrayWriter append(java.lang.CharSequence, int, int);
+    method public java.io.CharArrayWriter append(char);
     method public void close();
     method public void flush();
     method public void reset();
     method public int size();
     method public char[] toCharArray();
+    method public void write(int);
     method public void write(char[], int, int);
+    method public void write(java.lang.String, int, int);
     method public void writeTo(java.io.Writer) throws java.io.IOException;
     field protected char[] buf;
     field protected int count;
@@ -52387,6 +52526,8 @@
   public class DataOutputStream extends java.io.FilterOutputStream implements java.io.DataOutput {
     ctor public DataOutputStream(java.io.OutputStream);
     method public final int size();
+    method public synchronized void write(int) throws java.io.IOException;
+    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     method public final void writeBoolean(boolean) throws java.io.IOException;
     method public final void writeByte(int) throws java.io.IOException;
     method public final void writeBytes(java.lang.String) throws java.io.IOException;
@@ -52486,6 +52627,7 @@
     ctor public FileInputStream(java.lang.String) throws java.io.FileNotFoundException;
     ctor public FileInputStream(java.io.File) throws java.io.FileNotFoundException;
     ctor public FileInputStream(java.io.FileDescriptor);
+    method protected void finalize() throws java.io.IOException;
     method public java.nio.channels.FileChannel getChannel();
     method public final java.io.FileDescriptor getFD() throws java.io.IOException;
     method public int read() throws java.io.IOException;
@@ -52502,6 +52644,7 @@
     ctor public FileOutputStream(java.io.File) throws java.io.FileNotFoundException;
     ctor public FileOutputStream(java.io.File, boolean) throws java.io.FileNotFoundException;
     ctor public FileOutputStream(java.io.FileDescriptor);
+    method protected void finalize() throws java.io.IOException;
     method public java.nio.channels.FileChannel getChannel();
     method public final java.io.FileDescriptor getFD() throws java.io.IOException;
     method public void write(int) throws java.io.IOException;
@@ -52615,6 +52758,8 @@
   public deprecated class LineNumberInputStream extends java.io.FilterInputStream {
     ctor public LineNumberInputStream(java.io.InputStream);
     method public int getLineNumber();
+    method public void mark(int);
+    method public void reset() throws java.io.IOException;
     method public void setLineNumber(int);
   }
 
@@ -52844,8 +52989,10 @@
     ctor public PipedInputStream(java.io.PipedOutputStream, int) throws java.io.IOException;
     ctor public PipedInputStream();
     ctor public PipedInputStream(int);
+    method public synchronized int available() throws java.io.IOException;
     method public void connect(java.io.PipedOutputStream) throws java.io.IOException;
     method public synchronized int read() throws java.io.IOException;
+    method public synchronized int read(byte[], int, int) throws java.io.IOException;
     method protected synchronized void receive(int) throws java.io.IOException;
     field protected static final int PIPE_SIZE = 1024; // 0x400
     field protected byte[] buffer;
@@ -52857,6 +53004,7 @@
     ctor public PipedOutputStream(java.io.PipedInputStream) throws java.io.IOException;
     ctor public PipedOutputStream();
     method public synchronized void connect(java.io.PipedInputStream) throws java.io.IOException;
+    method public synchronized void flush() throws java.io.IOException;
     method public void write(int) throws java.io.IOException;
   }
 
@@ -52867,7 +53015,9 @@
     ctor public PipedReader(int);
     method public void close() throws java.io.IOException;
     method public void connect(java.io.PipedWriter) throws java.io.IOException;
+    method public synchronized int read() throws java.io.IOException;
     method public synchronized int read(char[], int, int) throws java.io.IOException;
+    method public synchronized boolean ready() throws java.io.IOException;
   }
 
   public class PipedWriter extends java.io.Writer {
@@ -52892,6 +53042,8 @@
     method public java.io.PrintStream append(char);
     method public boolean checkError();
     method protected void clearError();
+    method public void close();
+    method public void flush();
     method public java.io.PrintStream format(java.lang.String, java.lang.Object...);
     method public java.io.PrintStream format(java.util.Locale, java.lang.String, java.lang.Object...);
     method public void print(boolean);
@@ -52916,6 +53068,8 @@
     method public void println(java.lang.String);
     method public void println(java.lang.Object);
     method protected void setError();
+    method public void write(int);
+    method public void write(byte[], int, int);
   }
 
   public class PrintWriter extends java.io.Writer {
@@ -52927,6 +53081,9 @@
     ctor public PrintWriter(java.lang.String, java.lang.String) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
     ctor public PrintWriter(java.io.File) throws java.io.FileNotFoundException;
     ctor public PrintWriter(java.io.File, java.lang.String) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
+    method public java.io.PrintWriter append(java.lang.CharSequence);
+    method public java.io.PrintWriter append(java.lang.CharSequence, int, int);
+    method public java.io.PrintWriter append(char);
     method public boolean checkError();
     method protected void clearError();
     method public void close();
@@ -52955,13 +53112,18 @@
     method public void println(java.lang.String);
     method public void println(java.lang.Object);
     method protected void setError();
+    method public void write(int);
     method public void write(char[], int, int);
+    method public void write(char[]);
+    method public void write(java.lang.String, int, int);
+    method public void write(java.lang.String);
     field protected java.io.Writer out;
   }
 
   public class PushbackInputStream extends java.io.FilterInputStream {
     ctor public PushbackInputStream(java.io.InputStream, int);
     ctor public PushbackInputStream(java.io.InputStream);
+    method public synchronized void close() throws java.io.IOException;
     method public void unread(int) throws java.io.IOException;
     method public void unread(byte[], int, int) throws java.io.IOException;
     method public void unread(byte[]) throws java.io.IOException;
@@ -53085,7 +53247,11 @@
 
   public deprecated class StringBufferInputStream extends java.io.InputStream {
     ctor public StringBufferInputStream(java.lang.String);
+    method public synchronized int available();
     method public synchronized int read();
+    method public synchronized int read(byte[], int, int);
+    method public synchronized void reset();
+    method public synchronized long skip(long);
     field protected java.lang.String buffer;
     field protected int count;
     field protected int pos;
@@ -53100,10 +53266,16 @@
   public class StringWriter extends java.io.Writer {
     ctor public StringWriter();
     ctor public StringWriter(int);
+    method public java.io.StringWriter append(java.lang.CharSequence);
+    method public java.io.StringWriter append(java.lang.CharSequence, int, int);
+    method public java.io.StringWriter append(char);
     method public void close() throws java.io.IOException;
     method public void flush();
     method public java.lang.StringBuffer getBuffer();
+    method public void write(int);
     method public void write(char[], int, int);
+    method public void write(java.lang.String);
+    method public void write(java.lang.String, int, int);
   }
 
   public class SyncFailedException extends java.io.IOException {
@@ -53118,6 +53290,7 @@
   public class UncheckedIOException extends java.lang.RuntimeException {
     ctor public UncheckedIOException(java.lang.String, java.io.IOException);
     ctor public UncheckedIOException(java.io.IOException);
+    method public java.io.IOException getCause();
   }
 
   public class UnsupportedEncodingException extends java.io.IOException {
@@ -53127,6 +53300,7 @@
 
   public class WriteAbortedException extends java.io.ObjectStreamException {
     ctor public WriteAbortedException(java.lang.String, java.lang.Exception);
+    method public java.lang.Throwable getCause();
     field public java.lang.Exception detail;
   }
 
@@ -53894,6 +54068,7 @@
     ctor public ClassNotFoundException();
     ctor public ClassNotFoundException(java.lang.String);
     ctor public ClassNotFoundException(java.lang.String, java.lang.Throwable);
+    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getException();
   }
 
@@ -53998,6 +54173,7 @@
     ctor public ExceptionInInitializerError();
     ctor public ExceptionInInitializerError(java.lang.Throwable);
     ctor public ExceptionInInitializerError(java.lang.String);
+    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getException();
   }
 
@@ -54785,8 +54961,16 @@
     method public synchronized java.lang.StringBuffer append(float);
     method public synchronized java.lang.StringBuffer append(double);
     method public synchronized java.lang.StringBuffer appendCodePoint(int);
+    method public synchronized int capacity();
+    method public synchronized char charAt(int);
+    method public synchronized int codePointAt(int);
+    method public synchronized int codePointBefore(int);
+    method public synchronized int codePointCount(int, int);
     method public synchronized java.lang.StringBuffer delete(int, int);
     method public synchronized java.lang.StringBuffer deleteCharAt(int);
+    method public synchronized void ensureCapacity(int);
+    method public synchronized void getChars(int, int, char[], int);
+    method public synchronized int indexOf(java.lang.String, int);
     method public synchronized java.lang.StringBuffer insert(int, char[], int, int);
     method public synchronized java.lang.StringBuffer insert(int, java.lang.Object);
     method public synchronized java.lang.StringBuffer insert(int, java.lang.String);
@@ -54799,9 +54983,18 @@
     method public java.lang.StringBuffer insert(int, long);
     method public java.lang.StringBuffer insert(int, float);
     method public java.lang.StringBuffer insert(int, double);
+    method public synchronized int lastIndexOf(java.lang.String, int);
+    method public synchronized int length();
+    method public synchronized int offsetByCodePoints(int, int);
     method public synchronized java.lang.StringBuffer replace(int, int, java.lang.String);
     method public synchronized java.lang.StringBuffer reverse();
+    method public synchronized void setCharAt(int, char);
+    method public synchronized void setLength(int);
+    method public synchronized java.lang.CharSequence subSequence(int, int);
+    method public synchronized java.lang.String substring(int);
+    method public synchronized java.lang.String substring(int, int);
     method public synchronized java.lang.String toString();
+    method public synchronized void trimToSize();
   }
 
   public final class StringBuilder extends java.lang.AbstractStringBuilder implements java.lang.CharSequence java.io.Serializable {
@@ -55456,6 +55649,7 @@
     ctor protected InvocationTargetException();
     ctor public InvocationTargetException(java.lang.Throwable);
     ctor public InvocationTargetException(java.lang.Throwable, java.lang.String);
+    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getTargetException();
   }
 
@@ -55571,6 +55765,7 @@
   public class UndeclaredThrowableException extends java.lang.RuntimeException {
     ctor public UndeclaredThrowableException(java.lang.Throwable);
     ctor public UndeclaredThrowableException(java.lang.Throwable, java.lang.String);
+    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getUndeclaredThrowable();
   }
 
@@ -56468,6 +56663,7 @@
     method public java.lang.String getQuery();
     method public java.lang.String getRef();
     method public java.lang.String getUserInfo();
+    method public synchronized int hashCode();
     method public java.net.URLConnection openConnection() throws java.io.IOException;
     method public java.net.URLConnection openConnection(java.net.Proxy) throws java.io.IOException;
     method public final java.io.InputStream openStream() throws java.io.IOException;
@@ -56697,7 +56893,6 @@
     method public final int arrayOffset();
     method public abstract java.nio.CharBuffer asReadOnlyBuffer();
     method public final char charAt(int);
-    method public java.util.stream.IntStream chars();
     method public abstract java.nio.CharBuffer compact();
     method public int compareTo(java.nio.CharBuffer);
     method public abstract java.nio.CharBuffer duplicate();
@@ -57554,6 +57749,7 @@
 
   public final class DirectoryIteratorException extends java.util.ConcurrentModificationException {
     ctor public DirectoryIteratorException(java.io.IOException);
+    method public java.io.IOException getCause();
   }
 
   public class DirectoryNotEmptyException extends java.nio.file.FileSystemException {
@@ -58519,9 +58715,11 @@
   public static class KeyStore.PasswordProtection implements javax.security.auth.Destroyable java.security.KeyStore.ProtectionParameter {
     ctor public KeyStore.PasswordProtection(char[]);
     ctor public KeyStore.PasswordProtection(char[], java.lang.String, java.security.spec.AlgorithmParameterSpec);
+    method public synchronized void destroy() throws javax.security.auth.DestroyFailedException;
     method public synchronized char[] getPassword();
     method public java.lang.String getProtectionAlgorithm();
     method public java.security.spec.AlgorithmParameterSpec getProtectionParameters();
+    method public synchronized boolean isDestroyed();
   }
 
   public static final class KeyStore.PrivateKeyEntry implements java.security.KeyStore.Entry {
@@ -58701,6 +58899,7 @@
 
   public class PrivilegedActionException extends java.lang.Exception {
     ctor public PrivilegedActionException(java.lang.Exception);
+    method public java.lang.Throwable getCause();
     method public java.lang.Exception getException();
   }
 
@@ -58723,22 +58922,30 @@
     method public synchronized java.lang.Object compute(java.lang.Object, java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
     method public synchronized java.lang.Object computeIfAbsent(java.lang.Object, java.util.function.Function<? super java.lang.Object, ? extends java.lang.Object>);
     method public synchronized java.lang.Object computeIfPresent(java.lang.Object, java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
+    method public java.util.Enumeration<java.lang.Object> elements();
+    method public synchronized java.util.Set<java.util.Map.Entry<java.lang.Object, java.lang.Object>> entrySet();
     method public synchronized void forEach(java.util.function.BiConsumer<? super java.lang.Object, ? super java.lang.Object>);
+    method public java.lang.Object get(java.lang.Object);
     method public java.lang.String getInfo();
     method public java.lang.String getName();
     method public synchronized java.lang.Object getOrDefault(java.lang.Object, java.lang.Object);
     method public synchronized java.security.Provider.Service getService(java.lang.String, java.lang.String);
     method public synchronized java.util.Set<java.security.Provider.Service> getServices();
     method public double getVersion();
+    method public java.util.Set<java.lang.Object> keySet();
+    method public java.util.Enumeration<java.lang.Object> keys();
     method public synchronized java.lang.Object merge(java.lang.Object, java.lang.Object, java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
     method public synchronized java.lang.Object put(java.lang.Object, java.lang.Object);
     method public synchronized void putAll(java.util.Map<?, ?>);
     method public synchronized java.lang.Object putIfAbsent(java.lang.Object, java.lang.Object);
     method protected synchronized void putService(java.security.Provider.Service);
+    method public synchronized java.lang.Object remove(java.lang.Object);
     method protected synchronized void removeService(java.security.Provider.Service);
     method public synchronized boolean replace(java.lang.Object, java.lang.Object, java.lang.Object);
     method public synchronized java.lang.Object replace(java.lang.Object, java.lang.Object);
     method public synchronized void replaceAll(java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
+    method public java.lang.String toString();
+    method public java.util.Collection<java.lang.Object> values();
   }
 
   public static class Provider.Service {
@@ -58784,7 +58991,9 @@
     method public final java.security.Provider getProvider();
     method public static byte[] getSeed(int);
     method protected final int next(int);
+    method public synchronized void nextBytes(byte[]);
     method public synchronized void setSeed(byte[]);
+    method public void setSeed(long);
   }
 
   public abstract class SecureRandomSpi implements java.io.Serializable {
@@ -59331,6 +59540,7 @@
 
   public abstract class PKIXRevocationChecker extends java.security.cert.PKIXCertPathChecker {
     ctor protected PKIXRevocationChecker();
+    method public java.security.cert.PKIXRevocationChecker clone();
     method public java.util.List<java.security.cert.Extension> getOcspExtensions();
     method public java.net.URI getOcspResponder();
     method public java.security.cert.X509Certificate getOcspResponderCert();
@@ -61583,7 +61793,6 @@
   public final class DayOfWeek extends java.lang.Enum implements java.time.temporal.TemporalAccessor java.time.temporal.TemporalAdjuster {
     method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
     method public static java.time.DayOfWeek from(java.time.temporal.TemporalAccessor);
-    method public int get(java.time.temporal.TemporalField);
     method public java.lang.String getDisplayName(java.time.format.TextStyle, java.util.Locale);
     method public long getLong(java.time.temporal.TemporalField);
     method public int getValue();
@@ -61591,8 +61800,6 @@
     method public java.time.DayOfWeek minus(long);
     method public static java.time.DayOfWeek of(int);
     method public java.time.DayOfWeek plus(long);
-    method public <R> R query(java.time.temporal.TemporalQuery<R>);
-    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     method public static java.time.DayOfWeek valueOf(java.lang.String);
     method public static final java.time.DayOfWeek[] values();
     enum_constant public static final java.time.DayOfWeek FRIDAY;
@@ -61668,6 +61875,8 @@
     method public boolean isBefore(java.time.Instant);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
+    method public java.time.Instant minus(java.time.temporal.TemporalAmount);
+    method public java.time.Instant minus(long, java.time.temporal.TemporalUnit);
     method public java.time.Instant minusMillis(long);
     method public java.time.Instant minusNanos(long);
     method public java.time.Instant minusSeconds(long);
@@ -61677,6 +61886,7 @@
     method public static java.time.Instant ofEpochSecond(long);
     method public static java.time.Instant ofEpochSecond(long, long);
     method public static java.time.Instant parse(java.lang.CharSequence);
+    method public java.time.Instant plus(java.time.temporal.TemporalAmount);
     method public java.time.Instant plus(long, java.time.temporal.TemporalUnit);
     method public java.time.Instant plusMillis(long);
     method public java.time.Instant plusNanos(long);
@@ -61684,6 +61894,7 @@
     method public long toEpochMilli();
     method public java.time.Instant truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.Instant with(java.time.temporal.TemporalAdjuster);
     method public java.time.Instant with(java.time.temporal.TemporalField, long);
     field public static final java.time.Instant EPOCH;
     field public static final java.time.Instant MAX;
@@ -61693,6 +61904,7 @@
   public final class LocalDate implements java.time.chrono.ChronoLocalDate java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
     method public java.time.LocalDateTime atStartOfDay();
     method public java.time.ZonedDateTime atStartOfDay(java.time.ZoneId);
+    method public java.time.LocalDateTime atTime(java.time.LocalTime);
     method public java.time.LocalDateTime atTime(int, int);
     method public java.time.LocalDateTime atTime(int, int, int);
     method public java.time.LocalDateTime atTime(int, int, int, int);
@@ -61707,6 +61919,8 @@
     method public int getMonthValue();
     method public int getYear();
     method public int lengthOfMonth();
+    method public java.time.LocalDate minus(java.time.temporal.TemporalAmount);
+    method public java.time.LocalDate minus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDate minusDays(long);
     method public java.time.LocalDate minusMonths(long);
     method public java.time.LocalDate minusWeeks(long);
@@ -61720,12 +61934,16 @@
     method public static java.time.LocalDate ofYearDay(int, int);
     method public static java.time.LocalDate parse(java.lang.CharSequence);
     method public static java.time.LocalDate parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
+    method public java.time.LocalDate plus(java.time.temporal.TemporalAmount);
+    method public java.time.LocalDate plus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDate plusDays(long);
     method public java.time.LocalDate plusMonths(long);
     method public java.time.LocalDate plusWeeks(long);
     method public java.time.LocalDate plusYears(long);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
     method public java.time.Period until(java.time.chrono.ChronoLocalDate);
+    method public java.time.LocalDate with(java.time.temporal.TemporalAdjuster);
+    method public java.time.LocalDate with(java.time.temporal.TemporalField, long);
     method public java.time.LocalDate withDayOfMonth(int);
     method public java.time.LocalDate withDayOfYear(int);
     method public java.time.LocalDate withMonth(int);
@@ -61750,6 +61968,8 @@
     method public int getSecond();
     method public int getYear();
     method public boolean isSupported(java.time.temporal.TemporalField);
+    method public java.time.LocalDateTime minus(java.time.temporal.TemporalAmount);
+    method public java.time.LocalDateTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDateTime minusDays(long);
     method public java.time.LocalDateTime minusHours(long);
     method public java.time.LocalDateTime minusMinutes(long);
@@ -61772,6 +61992,7 @@
     method public static java.time.LocalDateTime ofInstant(java.time.Instant, java.time.ZoneId);
     method public static java.time.LocalDateTime parse(java.lang.CharSequence);
     method public static java.time.LocalDateTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
+    method public java.time.LocalDateTime plus(java.time.temporal.TemporalAmount);
     method public java.time.LocalDateTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDateTime plusDays(long);
     method public java.time.LocalDateTime plusHours(long);
@@ -61785,6 +62006,7 @@
     method public java.time.LocalTime toLocalTime();
     method public java.time.LocalDateTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.LocalDateTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.LocalDateTime with(java.time.temporal.TemporalField, long);
     method public java.time.LocalDateTime withDayOfMonth(int);
     method public java.time.LocalDateTime withDayOfYear(int);
@@ -61814,6 +62036,8 @@
     method public boolean isBefore(java.time.LocalTime);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
+    method public java.time.LocalTime minus(java.time.temporal.TemporalAmount);
+    method public java.time.LocalTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalTime minusHours(long);
     method public java.time.LocalTime minusMinutes(long);
     method public java.time.LocalTime minusNanos(long);
@@ -61828,6 +62052,7 @@
     method public static java.time.LocalTime ofSecondOfDay(long);
     method public static java.time.LocalTime parse(java.lang.CharSequence);
     method public static java.time.LocalTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
+    method public java.time.LocalTime plus(java.time.temporal.TemporalAmount);
     method public java.time.LocalTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalTime plusHours(long);
     method public java.time.LocalTime plusMinutes(long);
@@ -61837,6 +62062,7 @@
     method public int toSecondOfDay();
     method public java.time.LocalTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.LocalTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.LocalTime with(java.time.temporal.TemporalField, long);
     method public java.time.LocalTime withHour(int);
     method public java.time.LocalTime withMinute(int);
@@ -61853,7 +62079,6 @@
     method public int firstDayOfYear(boolean);
     method public java.time.Month firstMonthOfQuarter();
     method public static java.time.Month from(java.time.temporal.TemporalAccessor);
-    method public int get(java.time.temporal.TemporalField);
     method public java.lang.String getDisplayName(java.time.format.TextStyle, java.util.Locale);
     method public long getLong(java.time.temporal.TemporalField);
     method public int getValue();
@@ -61864,8 +62089,6 @@
     method public java.time.Month minus(long);
     method public static java.time.Month of(int);
     method public java.time.Month plus(long);
-    method public <R> R query(java.time.temporal.TemporalQuery<R>);
-    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     method public static java.time.Month valueOf(java.lang.String);
     method public static final java.time.Month[] values();
     enum_constant public static final java.time.Month APRIL;
@@ -61932,6 +62155,8 @@
     method public boolean isEqual(java.time.OffsetDateTime);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
+    method public java.time.OffsetDateTime minus(java.time.temporal.TemporalAmount);
+    method public java.time.OffsetDateTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetDateTime minusDays(long);
     method public java.time.OffsetDateTime minusHours(long);
     method public java.time.OffsetDateTime minusMinutes(long);
@@ -61949,6 +62174,7 @@
     method public static java.time.OffsetDateTime ofInstant(java.time.Instant, java.time.ZoneId);
     method public static java.time.OffsetDateTime parse(java.lang.CharSequence);
     method public static java.time.OffsetDateTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
+    method public java.time.OffsetDateTime plus(java.time.temporal.TemporalAmount);
     method public java.time.OffsetDateTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetDateTime plusDays(long);
     method public java.time.OffsetDateTime plusHours(long);
@@ -61968,6 +62194,7 @@
     method public java.time.ZonedDateTime toZonedDateTime();
     method public java.time.OffsetDateTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.OffsetDateTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.OffsetDateTime with(java.time.temporal.TemporalField, long);
     method public java.time.OffsetDateTime withDayOfMonth(int);
     method public java.time.OffsetDateTime withDayOfYear(int);
@@ -62000,6 +62227,8 @@
     method public boolean isEqual(java.time.OffsetTime);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
+    method public java.time.OffsetTime minus(java.time.temporal.TemporalAmount);
+    method public java.time.OffsetTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetTime minusHours(long);
     method public java.time.OffsetTime minusMinutes(long);
     method public java.time.OffsetTime minusNanos(long);
@@ -62012,6 +62241,7 @@
     method public static java.time.OffsetTime ofInstant(java.time.Instant, java.time.ZoneId);
     method public static java.time.OffsetTime parse(java.lang.CharSequence);
     method public static java.time.OffsetTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
+    method public java.time.OffsetTime plus(java.time.temporal.TemporalAmount);
     method public java.time.OffsetTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetTime plusHours(long);
     method public java.time.OffsetTime plusMinutes(long);
@@ -62020,6 +62250,7 @@
     method public java.time.LocalTime toLocalTime();
     method public java.time.OffsetTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.OffsetTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.OffsetTime with(java.time.temporal.TemporalField, long);
     method public java.time.OffsetTime withHour(int);
     method public java.time.OffsetTime withMinute(int);
@@ -62046,6 +62277,7 @@
     method public java.time.Period minusMonths(long);
     method public java.time.Period minusYears(long);
     method public java.time.Period multipliedBy(int);
+    method public java.time.Period negated();
     method public java.time.Period normalized();
     method public static java.time.Period of(int, int, int);
     method public static java.time.Period ofDays(int);
@@ -62084,6 +62316,8 @@
     method public boolean isSupported(java.time.temporal.TemporalUnit);
     method public boolean isValidMonthDay(java.time.MonthDay);
     method public int length();
+    method public java.time.Year minus(java.time.temporal.TemporalAmount);
+    method public java.time.Year minus(long, java.time.temporal.TemporalUnit);
     method public java.time.Year minusYears(long);
     method public static java.time.Year now();
     method public static java.time.Year now(java.time.ZoneId);
@@ -62091,9 +62325,11 @@
     method public static java.time.Year of(int);
     method public static java.time.Year parse(java.lang.CharSequence);
     method public static java.time.Year parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
+    method public java.time.Year plus(java.time.temporal.TemporalAmount);
     method public java.time.Year plus(long, java.time.temporal.TemporalUnit);
     method public java.time.Year plusYears(long);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.Year with(java.time.temporal.TemporalAdjuster);
     method public java.time.Year with(java.time.temporal.TemporalField, long);
     field public static final int MAX_VALUE = 999999999; // 0x3b9ac9ff
     field public static final int MIN_VALUE = -999999999; // 0xc4653601
@@ -62118,6 +62354,8 @@
     method public boolean isValidDay(int);
     method public int lengthOfMonth();
     method public int lengthOfYear();
+    method public java.time.YearMonth minus(java.time.temporal.TemporalAmount);
+    method public java.time.YearMonth minus(long, java.time.temporal.TemporalUnit);
     method public java.time.YearMonth minusMonths(long);
     method public java.time.YearMonth minusYears(long);
     method public static java.time.YearMonth now();
@@ -62127,10 +62365,12 @@
     method public static java.time.YearMonth of(int, int);
     method public static java.time.YearMonth parse(java.lang.CharSequence);
     method public static java.time.YearMonth parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
+    method public java.time.YearMonth plus(java.time.temporal.TemporalAmount);
     method public java.time.YearMonth plus(long, java.time.temporal.TemporalUnit);
     method public java.time.YearMonth plusMonths(long);
     method public java.time.YearMonth plusYears(long);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.YearMonth with(java.time.temporal.TemporalAdjuster);
     method public java.time.YearMonth with(java.time.temporal.TemporalField, long);
     method public java.time.YearMonth withMonth(int);
     method public java.time.YearMonth withYear(int);
@@ -62154,7 +62394,6 @@
     method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
     method public int compareTo(java.time.ZoneOffset);
     method public static java.time.ZoneOffset from(java.time.temporal.TemporalAccessor);
-    method public int get(java.time.temporal.TemporalField);
     method public java.lang.String getId();
     method public long getLong(java.time.temporal.TemporalField);
     method public java.time.zone.ZoneRules getRules();
@@ -62165,8 +62404,6 @@
     method public static java.time.ZoneOffset ofHoursMinutes(int, int);
     method public static java.time.ZoneOffset ofHoursMinutesSeconds(int, int, int);
     method public static java.time.ZoneOffset ofTotalSeconds(int);
-    method public <R> R query(java.time.temporal.TemporalQuery<R>);
-    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     field public static final java.time.ZoneOffset MAX;
     field public static final java.time.ZoneOffset MIN;
     field public static final java.time.ZoneOffset UTC;
@@ -62187,6 +62424,8 @@
     method public int getYear();
     method public java.time.ZoneId getZone();
     method public boolean isSupported(java.time.temporal.TemporalField);
+    method public java.time.ZonedDateTime minus(java.time.temporal.TemporalAmount);
+    method public java.time.ZonedDateTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.ZonedDateTime minusDays(long);
     method public java.time.ZonedDateTime minusHours(long);
     method public java.time.ZonedDateTime minusMinutes(long);
@@ -62207,6 +62446,7 @@
     method public static java.time.ZonedDateTime ofStrict(java.time.LocalDateTime, java.time.ZoneOffset, java.time.ZoneId);
     method public static java.time.ZonedDateTime parse(java.lang.CharSequence);
     method public static java.time.ZonedDateTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
+    method public java.time.ZonedDateTime plus(java.time.temporal.TemporalAmount);
     method public java.time.ZonedDateTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.ZonedDateTime plusDays(long);
     method public java.time.ZonedDateTime plusHours(long);
@@ -62216,10 +62456,12 @@
     method public java.time.ZonedDateTime plusSeconds(long);
     method public java.time.ZonedDateTime plusWeeks(long);
     method public java.time.ZonedDateTime plusYears(long);
+    method public java.time.LocalDate toLocalDate();
     method public java.time.LocalDateTime toLocalDateTime();
     method public java.time.OffsetDateTime toOffsetDateTime();
     method public java.time.ZonedDateTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.ZonedDateTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.ZonedDateTime with(java.time.temporal.TemporalField, long);
     method public java.time.ZonedDateTime withDayOfMonth(int);
     method public java.time.ZonedDateTime withDayOfYear(int);
@@ -62264,17 +62506,27 @@
     method public default boolean isSupported(java.time.temporal.TemporalUnit);
     method public abstract int lengthOfMonth();
     method public default int lengthOfYear();
+    method public default java.time.chrono.ChronoLocalDate minus(java.time.temporal.TemporalAmount);
+    method public default java.time.chrono.ChronoLocalDate minus(long, java.time.temporal.TemporalUnit);
+    method public default java.time.chrono.ChronoLocalDate plus(java.time.temporal.TemporalAmount);
     method public default java.time.chrono.ChronoLocalDate plus(long, java.time.temporal.TemporalUnit);
     method public static java.util.Comparator<java.time.chrono.ChronoLocalDate> timeLineOrder();
     method public default long toEpochDay();
     method public abstract java.lang.String toString();
     method public abstract long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
     method public abstract java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
+    method public default java.time.chrono.ChronoLocalDate with(java.time.temporal.TemporalAdjuster);
     method public default java.time.chrono.ChronoLocalDate with(java.time.temporal.TemporalField, long);
   }
 
    abstract class ChronoLocalDateImpl<D extends java.time.chrono.ChronoLocalDate> implements java.time.chrono.ChronoLocalDate java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
+    method public D minus(java.time.temporal.TemporalAmount);
+    method public D minus(long, java.time.temporal.TemporalUnit);
+    method public D plus(java.time.temporal.TemporalAmount);
+    method public D plus(long, java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public D with(java.time.temporal.TemporalAdjuster);
+    method public D with(java.time.temporal.TemporalField, long);
   }
 
   public abstract interface ChronoLocalDateTime<D extends java.time.chrono.ChronoLocalDate> implements java.lang.Comparable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
@@ -62291,6 +62543,9 @@
     method public default boolean isEqual(java.time.chrono.ChronoLocalDateTime<?>);
     method public abstract boolean isSupported(java.time.temporal.TemporalField);
     method public default boolean isSupported(java.time.temporal.TemporalUnit);
+    method public default java.time.chrono.ChronoLocalDateTime<D> minus(java.time.temporal.TemporalAmount);
+    method public default java.time.chrono.ChronoLocalDateTime<D> minus(long, java.time.temporal.TemporalUnit);
+    method public default java.time.chrono.ChronoLocalDateTime<D> plus(java.time.temporal.TemporalAmount);
     method public abstract java.time.chrono.ChronoLocalDateTime<D> plus(long, java.time.temporal.TemporalUnit);
     method public static java.util.Comparator<java.time.chrono.ChronoLocalDateTime<?>> timeLineOrder();
     method public default long toEpochSecond(java.time.ZoneOffset);
@@ -62298,6 +62553,7 @@
     method public abstract D toLocalDate();
     method public abstract java.time.LocalTime toLocalTime();
     method public abstract java.lang.String toString();
+    method public default java.time.chrono.ChronoLocalDateTime<D> with(java.time.temporal.TemporalAdjuster);
     method public abstract java.time.chrono.ChronoLocalDateTime<D> with(java.time.temporal.TemporalField, long);
   }
 
@@ -62335,6 +62591,9 @@
     method public default boolean isEqual(java.time.chrono.ChronoZonedDateTime<?>);
     method public abstract boolean isSupported(java.time.temporal.TemporalField);
     method public default boolean isSupported(java.time.temporal.TemporalUnit);
+    method public default java.time.chrono.ChronoZonedDateTime<D> minus(java.time.temporal.TemporalAmount);
+    method public default java.time.chrono.ChronoZonedDateTime<D> minus(long, java.time.temporal.TemporalUnit);
+    method public default java.time.chrono.ChronoZonedDateTime<D> plus(java.time.temporal.TemporalAmount);
     method public abstract java.time.chrono.ChronoZonedDateTime<D> plus(long, java.time.temporal.TemporalUnit);
     method public static java.util.Comparator<java.time.chrono.ChronoZonedDateTime<?>> timeLineOrder();
     method public default long toEpochSecond();
@@ -62343,6 +62602,7 @@
     method public abstract java.time.chrono.ChronoLocalDateTime<D> toLocalDateTime();
     method public default java.time.LocalTime toLocalTime();
     method public abstract java.lang.String toString();
+    method public default java.time.chrono.ChronoZonedDateTime<D> with(java.time.temporal.TemporalAdjuster);
     method public abstract java.time.chrono.ChronoZonedDateTime<D> with(java.time.temporal.TemporalField, long);
     method public abstract java.time.chrono.ChronoZonedDateTime<D> withEarlierOffsetAtOverlap();
     method public abstract java.time.chrono.ChronoZonedDateTime<D> withLaterOffsetAtOverlap();
@@ -62409,6 +62669,7 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.HijrahDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
+    method public java.time.chrono.HijrahDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.HijrahDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.HijrahDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.HijrahChronology INSTANCE;
@@ -62420,23 +62681,24 @@
     method public java.time.chrono.HijrahChronology getChronology();
     method public java.time.chrono.HijrahEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
-    method public boolean isLeapYear();
     method public int lengthOfMonth();
-    method public int lengthOfYear();
+    method public java.time.chrono.HijrahDate minus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.HijrahDate minus(long, java.time.temporal.TemporalUnit);
     method public static java.time.chrono.HijrahDate now();
     method public static java.time.chrono.HijrahDate now(java.time.ZoneId);
     method public static java.time.chrono.HijrahDate now(java.time.Clock);
     method public static java.time.chrono.HijrahDate of(int, int, int);
-    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
-    method public long toEpochDay();
+    method public java.time.chrono.HijrahDate plus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.HijrahDate plus(long, java.time.temporal.TemporalUnit);
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
+    method public java.time.chrono.HijrahDate with(java.time.temporal.TemporalField, long);
+    method public java.time.chrono.HijrahDate with(java.time.temporal.TemporalAdjuster);
     method public java.time.chrono.HijrahDate withVariant(java.time.chrono.HijrahChronology);
   }
 
   public final class HijrahEra extends java.lang.Enum implements java.time.chrono.Era {
     method public int getValue();
     method public static java.time.chrono.HijrahEra of(int);
-    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     method public static java.time.chrono.HijrahEra valueOf(java.lang.String);
     method public static final java.time.chrono.HijrahEra[] values();
     enum_constant public static final java.time.chrono.HijrahEra AH;
@@ -62461,6 +62723,7 @@
     method public java.time.Period period(int, int, int);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
+    method public java.time.LocalDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.ZonedDateTime zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.ZonedDateTime zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.IsoChronology INSTANCE;
@@ -62493,6 +62756,7 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.JapaneseDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
+    method public java.time.chrono.JapaneseDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.JapaneseDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.JapaneseDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.JapaneseChronology INSTANCE;
@@ -62504,17 +62768,19 @@
     method public java.time.chrono.JapaneseChronology getChronology();
     method public java.time.chrono.JapaneseEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
-    method public boolean isSupported(java.time.temporal.TemporalField);
     method public int lengthOfMonth();
-    method public int lengthOfYear();
+    method public java.time.chrono.JapaneseDate minus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.JapaneseDate minus(long, java.time.temporal.TemporalUnit);
     method public static java.time.chrono.JapaneseDate now();
     method public static java.time.chrono.JapaneseDate now(java.time.ZoneId);
     method public static java.time.chrono.JapaneseDate now(java.time.Clock);
     method public static java.time.chrono.JapaneseDate of(java.time.chrono.JapaneseEra, int, int, int);
     method public static java.time.chrono.JapaneseDate of(int, int, int);
-    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
-    method public long toEpochDay();
+    method public java.time.chrono.JapaneseDate plus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.JapaneseDate plus(long, java.time.temporal.TemporalUnit);
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
+    method public java.time.chrono.JapaneseDate with(java.time.temporal.TemporalField, long);
+    method public java.time.chrono.JapaneseDate with(java.time.temporal.TemporalAdjuster);
   }
 
   public final class JapaneseEra implements java.time.chrono.Era java.io.Serializable {
@@ -62546,6 +62812,7 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.MinguoDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
+    method public java.time.chrono.MinguoDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.MinguoDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.MinguoDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.MinguoChronology INSTANCE;
@@ -62558,13 +62825,17 @@
     method public java.time.chrono.MinguoEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
     method public int lengthOfMonth();
+    method public java.time.chrono.MinguoDate minus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.MinguoDate minus(long, java.time.temporal.TemporalUnit);
     method public static java.time.chrono.MinguoDate now();
     method public static java.time.chrono.MinguoDate now(java.time.ZoneId);
     method public static java.time.chrono.MinguoDate now(java.time.Clock);
     method public static java.time.chrono.MinguoDate of(int, int, int);
-    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
-    method public long toEpochDay();
+    method public java.time.chrono.MinguoDate plus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.MinguoDate plus(long, java.time.temporal.TemporalUnit);
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
+    method public java.time.chrono.MinguoDate with(java.time.temporal.TemporalField, long);
+    method public java.time.chrono.MinguoDate with(java.time.temporal.TemporalAdjuster);
   }
 
   public final class MinguoEra extends java.lang.Enum implements java.time.chrono.Era {
@@ -62594,6 +62865,7 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.ThaiBuddhistDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
+    method public java.time.chrono.ThaiBuddhistDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.ThaiBuddhistDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.ThaiBuddhistDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.ThaiBuddhistChronology INSTANCE;
@@ -62606,13 +62878,17 @@
     method public java.time.chrono.ThaiBuddhistEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
     method public int lengthOfMonth();
+    method public java.time.chrono.ThaiBuddhistDate minus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.ThaiBuddhistDate minus(long, java.time.temporal.TemporalUnit);
     method public static java.time.chrono.ThaiBuddhistDate now();
     method public static java.time.chrono.ThaiBuddhistDate now(java.time.ZoneId);
     method public static java.time.chrono.ThaiBuddhistDate now(java.time.Clock);
     method public static java.time.chrono.ThaiBuddhistDate of(int, int, int);
-    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
-    method public long toEpochDay();
+    method public java.time.chrono.ThaiBuddhistDate plus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.ThaiBuddhistDate plus(long, java.time.temporal.TemporalUnit);
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
+    method public java.time.chrono.ThaiBuddhistDate with(java.time.temporal.TemporalField, long);
+    method public java.time.chrono.ThaiBuddhistDate with(java.time.temporal.TemporalAdjuster);
   }
 
   public final class ThaiBuddhistEra extends java.lang.Enum implements java.time.chrono.Era {
@@ -62791,7 +63067,6 @@
     method public int checkValidIntValue(long);
     method public long checkValidValue(long);
     method public java.time.temporal.TemporalUnit getBaseUnit();
-    method public java.lang.String getDisplayName(java.util.Locale);
     method public long getFrom(java.time.temporal.TemporalAccessor);
     method public java.time.temporal.TemporalUnit getRangeUnit();
     method public boolean isDateBased();
@@ -62839,7 +63114,6 @@
     method public java.time.Duration getDuration();
     method public boolean isDateBased();
     method public boolean isDurationEstimated();
-    method public boolean isSupportedBy(java.time.temporal.Temporal);
     method public boolean isTimeBased();
     method public static java.time.temporal.ChronoUnit valueOf(java.lang.String);
     method public static final java.time.temporal.ChronoUnit[] values();
@@ -63179,7 +63453,6 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
-    method public java.util.Spliterator<E> spliterator();
   }
 
   public class ArrayList<E> extends java.util.AbstractList implements java.lang.Cloneable java.util.List java.util.RandomAccess java.io.Serializable {
@@ -63190,11 +63463,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 void replaceAll(java.util.function.UnaryOperator<E>);
     method public int size();
-    method public void sort(java.util.Comparator<? super E>);
-    method public java.util.Spliterator<E> spliterator();
     method public void trimToSize();
   }
 
@@ -63565,6 +63834,7 @@
     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 default java.util.Spliterator<E> spliterator();
     method public default java.util.stream.Stream<E> stream();
     method public abstract java.lang.Object[] toArray();
     method public abstract <T> T[] toArray(T[]);
@@ -63905,18 +64175,7 @@
     ctor public HashMap();
     ctor public HashMap(java.util.Map<? extends K, ? extends V>);
     method public java.lang.Object clone();
-    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.Set<java.util.Map.Entry<K, V>> entrySet();
-    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
-    method public V getOrDefault(java.lang.Object, V);
-    method public V merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
-    method public V putIfAbsent(K, V);
-    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>);
   }
 
   public class HashSet<E> extends java.util.AbstractSet implements java.lang.Cloneable java.io.Serializable java.util.Set {
@@ -63927,7 +64186,6 @@
     method public java.lang.Object clone();
     method public java.util.Iterator<E> iterator();
     method public int size();
-    method public java.util.Spliterator<E> spliterator();
   }
 
   public class Hashtable<K, V> extends java.util.Dictionary implements java.lang.Cloneable java.util.Map java.io.Serializable {
@@ -63945,9 +64203,11 @@
     method public boolean containsValue(java.lang.Object);
     method public synchronized java.util.Enumeration<V> elements();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+    method public synchronized boolean equals(java.lang.Object);
     method public synchronized void forEach(java.util.function.BiConsumer<? super K, ? super V>);
     method public synchronized V get(java.lang.Object);
     method public synchronized V getOrDefault(java.lang.Object, V);
+    method public synchronized int hashCode();
     method public synchronized boolean isEmpty();
     method public java.util.Set<K> keySet();
     method public synchronized java.util.Enumeration<K> keys();
@@ -63962,6 +64222,7 @@
     method public synchronized V replace(K, V);
     method public synchronized void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public synchronized int size();
+    method public synchronized java.lang.String toString();
     method public java.util.Collection<V> values();
   }
 
@@ -63971,8 +64232,6 @@
     ctor public IdentityHashMap(java.util.Map<? extends K, ? extends V>);
     method public java.lang.Object clone();
     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 replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
   }
 
   public class IllegalFormatCodePointException extends java.util.IllegalFormatException {
@@ -64083,7 +64342,6 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
-    method public java.util.Spliterator<E> spliterator();
   }
 
   public abstract interface List<E> implements java.util.Collection {
@@ -64706,6 +64964,7 @@
     ctor public SimpleTimeZone(int, java.lang.String, int, int, int, int, int, int, int, int, int, int, int);
     method public int getOffset(int, int, int, int, int, int);
     method public int getRawOffset();
+    method public synchronized int hashCode();
     method public boolean inDaylightTime(java.util.Date);
     method public void setDSTSavings(int);
     method public void setEndRule(int, int, int, int);
@@ -64978,7 +65237,6 @@
     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 java.util.NavigableMap<K, V> headMap(K, boolean);
     method public java.util.SortedMap<K, V> headMap(K);
     method public java.util.Map.Entry<K, V> higherEntry(K);
@@ -64990,9 +65248,6 @@
     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();
-    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.NavigableMap<K, V> subMap(K, boolean, K, boolean);
     method public java.util.SortedMap<K, V> subMap(K, K);
     method public java.util.NavigableMap<K, V> tailMap(K, boolean);
@@ -65020,7 +65275,6 @@
     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.SortedSet<E> subSet(E, E);
     method public java.util.NavigableSet<E> tailSet(E, boolean);
@@ -65057,30 +65311,49 @@
     ctor public Vector(int);
     ctor public Vector();
     ctor public Vector(java.util.Collection<? extends E>);
+    method public synchronized boolean add(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 void addElement(E);
     method public synchronized int capacity();
     method public synchronized java.lang.Object clone();
+    method public synchronized boolean containsAll(java.util.Collection<?>);
     method public synchronized void copyInto(java.lang.Object[]);
     method public synchronized E elementAt(int);
     method public java.util.Enumeration<E> elements();
     method public synchronized void ensureCapacity(int);
+    method public synchronized boolean equals(java.lang.Object);
     method public synchronized E firstElement();
     method public synchronized void forEach(java.util.function.Consumer<? super E>);
     method public synchronized E get(int);
+    method public synchronized int hashCode();
     method public synchronized int indexOf(java.lang.Object, int);
     method public synchronized void insertElementAt(E, int);
+    method public synchronized boolean isEmpty();
+    method public synchronized java.util.Iterator<E> iterator();
     method public synchronized E lastElement();
+    method public synchronized int lastIndexOf(java.lang.Object);
     method public synchronized int lastIndexOf(java.lang.Object, int);
+    method public synchronized java.util.ListIterator<E> listIterator(int);
+    method public synchronized java.util.ListIterator<E> listIterator();
+    method public synchronized E remove(int);
+    method public synchronized boolean removeAll(java.util.Collection<?>);
     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 protected synchronized void removeRange(int, int);
     method public synchronized void replaceAll(java.util.function.UnaryOperator<E>);
+    method public synchronized boolean retainAll(java.util.Collection<?>);
+    method public synchronized E set(int, E);
     method public synchronized void setElementAt(E, int);
     method public synchronized void setSize(int);
     method public synchronized int size();
     method public synchronized void sort(java.util.Comparator<? super E>);
-    method public java.util.Spliterator<E> spliterator();
+    method public synchronized java.util.List<E> subList(int, int);
+    method public synchronized java.lang.Object[] toArray();
+    method public synchronized <T> T[] toArray(T[]);
+    method public synchronized java.lang.String toString();
     method public synchronized void trimToSize();
     field protected int capacityIncrement;
     field protected int elementCount;
@@ -65093,8 +65366,6 @@
     ctor public WeakHashMap();
     ctor public WeakHashMap(java.util.Map<? extends K, ? extends V>);
     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 replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
   }
 
 }
@@ -65129,7 +65400,6 @@
     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;
   }
 
@@ -65320,13 +65590,9 @@
     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 <U> 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>>);
@@ -65335,14 +65601,11 @@
     method public <U> 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 <U> 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 <K> java.util.concurrent.ConcurrentHashMap.KeySetView<K, java.lang.Boolean> newKeySet();
     method public static <K> java.util.concurrent.ConcurrentHashMap.KeySetView<K, java.lang.Boolean> newKeySet(int);
-    method public V putIfAbsent(K, V);
     method public <U> 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> 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>);
@@ -65362,10 +65625,6 @@
     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> U search(long, java.util.function.BiFunction<? super K, ? super V, ? extends U>);
     method public <U> U searchEntries(long, java.util.function.Function<java.util.Map.Entry<K, V>, ? extends U>);
     method public <U> U searchKeys(long, java.util.function.Function<? super K, ? extends U>);
@@ -65426,7 +65685,6 @@
     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<E> extends java.util.AbstractQueue implements java.util.Queue java.io.Serializable {
@@ -65437,7 +65695,6 @@
     method public E peek();
     method public E poll();
     method public int size();
-    method public java.util.Spliterator<E> spliterator();
   }
 
   public abstract interface ConcurrentMap<K, V> implements java.util.Map {
@@ -65469,9 +65726,6 @@
     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();
@@ -65479,25 +65733,18 @@
     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);
     method public K higherKey(K);
+    method public java.util.NavigableSet<K> keySet();
     method public java.util.Map.Entry<K, V> lastEntry();
     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();
-    method public V putIfAbsent(K, V);
-    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);
@@ -65525,7 +65772,6 @@
     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);
@@ -65572,9 +65818,7 @@
     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 {
@@ -65733,6 +65977,7 @@
     method public java.lang.Thread.UncaughtExceptionHandler getUncaughtExceptionHandler();
     method public boolean hasQueuedSubmissions();
     method public <T> T invoke(java.util.concurrent.ForkJoinTask<T>);
+    method public <T> java.util.List<java.util.concurrent.Future<T>> invokeAll(java.util.Collection<? extends java.util.concurrent.Callable<T>>);
     method public boolean isQuiescent();
     method public boolean isShutdown();
     method public boolean isTerminated();
@@ -65742,6 +65987,9 @@
     method public void shutdown();
     method public java.util.List<java.lang.Runnable> shutdownNow();
     method public <T> java.util.concurrent.ForkJoinTask<T> submit(java.util.concurrent.ForkJoinTask<T>);
+    method public <T> java.util.concurrent.ForkJoinTask<T> submit(java.util.concurrent.Callable<T>);
+    method public <T> java.util.concurrent.ForkJoinTask<T> submit(java.lang.Runnable, T);
+    method public java.util.concurrent.ForkJoinTask<?> submit(java.lang.Runnable);
     field public static final java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory defaultForkJoinWorkerThreadFactory;
   }
 
@@ -65865,7 +66113,6 @@
     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;
@@ -65886,7 +66133,6 @@
     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;
   }
 
@@ -65906,7 +66152,6 @@
     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);
@@ -65954,7 +66199,6 @@
     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;
   }
 
@@ -66058,7 +66302,6 @@
     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;
   }
 
@@ -66070,9 +66313,11 @@
     method public static java.util.concurrent.ThreadLocalRandom current();
     method public double nextDouble(double);
     method public double nextDouble(double, double);
+    method public double nextGaussian();
     method public int nextInt(int, int);
     method public long nextLong(long);
     method public long nextLong(long, long);
+    method public void setSeed(long);
   }
 
   public class ThreadPoolExecutor extends java.util.concurrent.AbstractExecutorService {
@@ -66086,6 +66331,7 @@
     method public boolean awaitTermination(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
     method protected void beforeExecute(java.lang.Thread, java.lang.Runnable);
     method public void execute(java.lang.Runnable);
+    method protected void finalize();
     method public int getActiveCount();
     method public long getCompletedTaskCount();
     method public int getCorePoolSize();
@@ -66956,8 +67202,11 @@
     ctor public JarFile(java.io.File) throws java.io.IOException;
     ctor public JarFile(java.io.File, boolean) throws java.io.IOException;
     ctor public JarFile(java.io.File, boolean, int) throws java.io.IOException;
+    method public java.util.Enumeration<java.util.jar.JarEntry> entries();
+    method public synchronized java.io.InputStream getInputStream(java.util.zip.ZipEntry) throws java.io.IOException;
     method public java.util.jar.JarEntry getJarEntry(java.lang.String);
     method public java.util.jar.Manifest getManifest() throws java.io.IOException;
+    method public java.util.stream.Stream<java.util.jar.JarEntry> stream();
     field public static final java.lang.String MANIFEST_NAME = "META-INF/MANIFEST.MF";
   }
 
@@ -67037,6 +67286,8 @@
 
   public class ConsoleHandler extends java.util.logging.StreamHandler {
     ctor public ConsoleHandler();
+    method public void close();
+    method public void publish(java.util.logging.LogRecord);
   }
 
   public class ErrorManager {
@@ -67826,6 +68077,7 @@
     method public int deflate(byte[]);
     method public int deflate(byte[], int, int, int);
     method public void end();
+    method protected void finalize();
     method public void finish();
     method public boolean finished();
     method public int getAdler();
@@ -67858,6 +68110,8 @@
     ctor public DeflaterInputStream(java.io.InputStream);
     ctor public DeflaterInputStream(java.io.InputStream, java.util.zip.Deflater);
     ctor public DeflaterInputStream(java.io.InputStream, java.util.zip.Deflater, int);
+    method public void mark(int);
+    method public void reset() throws java.io.IOException;
     field protected final byte[] buf;
     field protected final java.util.zip.Deflater def;
   }
@@ -67888,6 +68142,7 @@
     ctor public GZIPOutputStream(java.io.OutputStream, int, boolean) throws java.io.IOException;
     ctor public GZIPOutputStream(java.io.OutputStream) throws java.io.IOException;
     ctor public GZIPOutputStream(java.io.OutputStream, boolean) throws java.io.IOException;
+    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     field protected java.util.zip.CRC32 crc;
   }
 
@@ -67895,6 +68150,7 @@
     ctor public Inflater(boolean);
     ctor public Inflater();
     method public void end();
+    method protected void finalize();
     method public boolean finished();
     method public int getAdler();
     method public long getBytesRead();
@@ -68021,6 +68277,7 @@
     ctor public ZipFile(java.io.File, java.nio.charset.Charset) throws java.io.IOException;
     method public void close() throws java.io.IOException;
     method public java.util.Enumeration<? extends java.util.zip.ZipEntry> entries();
+    method protected void finalize() throws java.io.IOException;
     method public java.lang.String getComment();
     method public java.util.zip.ZipEntry getEntry(java.lang.String);
     method public java.io.InputStream getInputStream(java.util.zip.ZipEntry) throws java.io.IOException;
@@ -68127,6 +68384,7 @@
     method public void setComment(java.lang.String);
     method public void setLevel(int);
     method public void setMethod(int);
+    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     field public static final int CENATT = 36; // 0x24
     field public static final int CENATX = 38; // 0x26
     field public static final int CENCOM = 32; // 0x20
@@ -68283,6 +68541,7 @@
 
   public class ExemptionMechanism {
     ctor protected ExemptionMechanism(javax.crypto.ExemptionMechanismSpi, java.security.Provider, java.lang.String);
+    method protected void finalize();
     method public final byte[] genExemptionBlob() throws javax.crypto.ExemptionMechanismException, java.lang.IllegalStateException;
     method public final int genExemptionBlob(byte[]) throws javax.crypto.ExemptionMechanismException, java.lang.IllegalStateException, javax.crypto.ShortBufferException;
     method public final int genExemptionBlob(byte[], int) throws javax.crypto.ExemptionMechanismException, java.lang.IllegalStateException, javax.crypto.ShortBufferException;
@@ -70671,6 +70930,7 @@
     ctor public TransformerException(java.lang.String, java.lang.Throwable);
     ctor public TransformerException(java.lang.String, javax.xml.transform.SourceLocator);
     ctor public TransformerException(java.lang.String, javax.xml.transform.SourceLocator, java.lang.Throwable);
+    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getException();
     method public java.lang.String getLocationAsString();
     method public javax.xml.transform.SourceLocator getLocator();
@@ -70941,6 +71201,7 @@
   public class XPathException extends java.lang.Exception {
     ctor public XPathException(java.lang.String);
     ctor public XPathException(java.lang.Throwable);
+    method public java.lang.Throwable getCause();
   }
 
   public abstract interface XPathExpression {
diff --git a/api/system-current.txt b/api/system-current.txt
index 40a92bd..833e1f6 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -2064,6 +2064,7 @@
     field public static final int VideoView_error_text_invalid_progressive_playback = 17039381; // 0x1040015
     field public static final int VideoView_error_text_unknown = 17039377; // 0x1040011
     field public static final int VideoView_error_title = 17039378; // 0x1040012
+    field public static final int autofill = 17039386; // 0x104001a
     field public static final int cancel = 17039360; // 0x1040000
     field public static final int copy = 17039361; // 0x1040001
     field public static final int copyUrl = 17039362; // 0x1040002
@@ -3293,6 +3294,7 @@
 
   public final class AnimatorSet extends android.animation.Animator {
     ctor public AnimatorSet();
+    method public android.animation.AnimatorSet clone();
     method public java.util.ArrayList<android.animation.Animator> getChildAnimations();
     method public long getCurrentPlayTime();
     method public long getDuration();
@@ -3411,6 +3413,7 @@
 
   public final class ObjectAnimator extends android.animation.ValueAnimator {
     ctor public ObjectAnimator();
+    method public android.animation.ObjectAnimator clone();
     method public java.lang.String getPropertyName();
     method public java.lang.Object getTarget();
     method public static android.animation.ObjectAnimator ofArgb(java.lang.Object, java.lang.String, int...);
@@ -3436,6 +3439,7 @@
     method public static <T, V> android.animation.ObjectAnimator ofObject(T, android.util.Property<T, V>, android.animation.TypeConverter<android.graphics.PointF, V>, android.graphics.Path);
     method public static android.animation.ObjectAnimator ofPropertyValuesHolder(java.lang.Object, android.animation.PropertyValuesHolder...);
     method public void setAutoCancel(boolean);
+    method public android.animation.ObjectAnimator setDuration(long);
     method public void setProperty(android.util.Property);
     method public void setPropertyName(java.lang.String);
   }
@@ -3517,6 +3521,7 @@
     ctor public ValueAnimator();
     method public void addUpdateListener(android.animation.ValueAnimator.AnimatorUpdateListener);
     method public static boolean areAnimatorsEnabled();
+    method public android.animation.ValueAnimator clone();
     method public float getAnimatedFraction();
     method public java.lang.Object getAnimatedValue();
     method public java.lang.Object getAnimatedValue(java.lang.String);
@@ -4359,6 +4364,12 @@
 
   public class Application extends android.content.ContextWrapper implements android.content.ComponentCallbacks2 {
     ctor public Application();
+    method public android.app.Activity instantiateActivity(java.lang.ClassLoader, java.lang.String, android.content.Intent);
+    method public android.app.backup.BackupAgent instantiateBackupAgent(java.lang.ClassLoader, java.lang.String);
+    method public android.app.Instrumentation instantiateInstrumentation(java.lang.ClassLoader, java.lang.String);
+    method public android.content.ContentProvider instantiateProvider(java.lang.ClassLoader, java.lang.String);
+    method public android.content.BroadcastReceiver instantiateReceiver(java.lang.ClassLoader, java.lang.String, android.content.Intent);
+    method public android.app.Service instantiateService(java.lang.ClassLoader, java.lang.String, android.content.Intent);
     method public void onConfigurationChanged(android.content.res.Configuration);
     method public void onCreate();
     method public void onLowMemory();
@@ -5141,6 +5152,7 @@
     ctor public IntentService(java.lang.String);
     method public android.os.IBinder onBind(android.content.Intent);
     method protected abstract void onHandleIntent(android.content.Intent);
+    method public void onStart(android.content.Intent, int);
     method public void setIntentRedelivery(boolean);
   }
 
@@ -11853,6 +11865,7 @@
 
   public static class AssetFileDescriptor.AutoCloseInputStream extends android.os.ParcelFileDescriptor.AutoCloseInputStream {
     ctor public AssetFileDescriptor.AutoCloseInputStream(android.content.res.AssetFileDescriptor) throws java.io.IOException;
+    method public void mark(int);
   }
 
   public static class AssetFileDescriptor.AutoCloseOutputStream extends android.os.ParcelFileDescriptor.AutoCloseOutputStream {
@@ -12160,6 +12173,7 @@
     method public void copyStringToBuffer(int, android.database.CharArrayBuffer);
     method public void deactivate();
     method public void fillWindow(int, android.database.CursorWindow);
+    method protected void finalize();
     method public byte[] getBlob(int);
     method public int getColumnCount();
     method public int getColumnIndex(java.lang.String);
@@ -14634,6 +14648,7 @@
     method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
+    method public void setDither(boolean);
     method public void setOpacity(int);
     method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
   }
@@ -14714,6 +14729,7 @@
     method public void setAlpha(int);
     method public void setAntiAlias(boolean);
     method public void setColorFilter(android.graphics.ColorFilter);
+    method public void setDither(boolean);
     method public void setGravity(int);
     method public void setMipMap(boolean);
     method public void setTargetDensity(android.graphics.Canvas);
@@ -14839,6 +14855,7 @@
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
     method protected void setConstantState(android.graphics.drawable.DrawableContainer.DrawableContainerState);
+    method public void setDither(boolean);
     method public void setEnterFadeDuration(int);
     method public void setExitFadeDuration(int);
     method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
@@ -14905,6 +14922,7 @@
     method public void setColors(int[]);
     method public void setCornerRadii(float[]);
     method public void setCornerRadius(float);
+    method public void setDither(boolean);
     method public void setGradientCenter(float, float);
     method public void setGradientRadius(float);
     method public void setGradientType(int);
@@ -14999,6 +15017,7 @@
     method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
+    method public void setDither(boolean);
     method public void setDrawable(int, android.graphics.drawable.Drawable);
     method public boolean setDrawableByLayerId(int, android.graphics.drawable.Drawable);
     method public void setId(int, int);
@@ -15039,6 +15058,7 @@
     method public android.graphics.Paint getPaint();
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
+    method public void setDither(boolean);
     method public void setTargetDensity(android.graphics.Canvas);
     method public void setTargetDensity(android.util.DisplayMetrics);
     method public void setTargetDensity(int);
@@ -15101,6 +15121,7 @@
     method protected void onDraw(android.graphics.drawable.shapes.Shape, android.graphics.Canvas, android.graphics.Paint);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
+    method public void setDither(boolean);
     method public void setIntrinsicHeight(int);
     method public void setIntrinsicWidth(int);
     method public void setPadding(int, int, int, int);
@@ -15142,27 +15163,32 @@
 
   public class ArcShape extends android.graphics.drawable.shapes.RectShape {
     ctor public ArcShape(float, float);
+    method public android.graphics.drawable.shapes.ArcShape clone() throws java.lang.CloneNotSupportedException;
     method public final float getStartAngle();
     method public final float getSweepAngle();
   }
 
   public class OvalShape extends android.graphics.drawable.shapes.RectShape {
     ctor public OvalShape();
+    method public android.graphics.drawable.shapes.OvalShape clone() throws java.lang.CloneNotSupportedException;
   }
 
   public class PathShape extends android.graphics.drawable.shapes.Shape {
     ctor public PathShape(android.graphics.Path, float, float);
+    method public android.graphics.drawable.shapes.PathShape clone() throws java.lang.CloneNotSupportedException;
     method public void draw(android.graphics.Canvas, android.graphics.Paint);
   }
 
   public class RectShape extends android.graphics.drawable.shapes.Shape {
     ctor public RectShape();
+    method public android.graphics.drawable.shapes.RectShape clone() throws java.lang.CloneNotSupportedException;
     method public void draw(android.graphics.Canvas, android.graphics.Paint);
     method protected final android.graphics.RectF rect();
   }
 
   public class RoundRectShape extends android.graphics.drawable.shapes.RectShape {
     ctor public RoundRectShape(float[], android.graphics.RectF, float[]);
+    method public android.graphics.drawable.shapes.RoundRectShape clone() throws java.lang.CloneNotSupportedException;
   }
 
   public abstract class Shape implements java.lang.Cloneable {
@@ -15247,6 +15273,7 @@
     method public final void autoFocus(android.hardware.Camera.AutoFocusCallback);
     method public final void cancelAutoFocus();
     method public final boolean enableShutterSound(boolean);
+    method protected void finalize();
     method public static void getCameraInfo(int, android.hardware.Camera.CameraInfo);
     method public static int getNumberOfCameras();
     method public android.hardware.Camera.Parameters getParameters();
@@ -15864,6 +15891,7 @@
     method public <T> T get(android.hardware.camera2.CameraCharacteristics.Key<T>);
     method public java.util.List<android.hardware.camera2.CaptureRequest.Key<?>> getAvailableCaptureRequestKeys();
     method public java.util.List<android.hardware.camera2.CaptureResult.Key<?>> getAvailableCaptureResultKeys();
+    method public java.util.List<android.hardware.camera2.CameraCharacteristics.Key<?>> getKeys();
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> CONTROL_AE_AVAILABLE_ANTIBANDING_MODES;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> CONTROL_AE_AVAILABLE_MODES;
@@ -16224,6 +16252,7 @@
   public final class CaptureRequest extends android.hardware.camera2.CameraMetadata implements android.os.Parcelable {
     method public int describeContents();
     method public <T> T get(android.hardware.camera2.CaptureRequest.Key<T>);
+    method public java.util.List<android.hardware.camera2.CaptureRequest.Key<?>> getKeys();
     method public java.lang.Object getTag();
     method public boolean isReprocess();
     method public void writeToParcel(android.os.Parcel, int);
@@ -16302,6 +16331,7 @@
   public class CaptureResult extends android.hardware.camera2.CameraMetadata {
     method public <T> T get(android.hardware.camera2.CaptureResult.Key<T>);
     method public long getFrameNumber();
+    method public java.util.List<android.hardware.camera2.CaptureResult.Key<?>> getKeys();
     method public android.hardware.camera2.CaptureRequest getRequest();
     method public int getSequenceId();
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Boolean> BLACK_LEVEL_LOCK;
@@ -19451,6 +19481,7 @@
   }
 
   public class DateIntervalFormat extends android.icu.text.UFormat {
+    method public synchronized java.lang.Object clone();
     method public final java.lang.StringBuffer format(java.lang.Object, java.lang.StringBuffer, java.text.FieldPosition);
     method public final synchronized java.lang.StringBuffer format(android.icu.util.DateInterval, java.lang.StringBuffer, java.text.FieldPosition);
     method public final synchronized java.lang.StringBuffer format(android.icu.util.Calendar, android.icu.util.Calendar, java.lang.StringBuffer, java.text.FieldPosition);
@@ -20234,6 +20265,7 @@
 
   public final class RuleBasedCollator extends android.icu.text.Collator {
     ctor public RuleBasedCollator(java.lang.String) throws java.lang.Exception;
+    method public android.icu.text.RuleBasedCollator cloneAsThawed();
     method public int compare(java.lang.String, java.lang.String);
     method public android.icu.text.CollationElementIterator getCollationElementIterator(java.lang.String);
     method public android.icu.text.CollationElementIterator getCollationElementIterator(java.text.CharacterIterator);
@@ -20260,6 +20292,7 @@
     method public void setFrenchCollation(boolean);
     method public void setFrenchCollationDefault();
     method public void setLowerCaseFirst(boolean);
+    method public android.icu.text.RuleBasedCollator setMaxVariable(int);
     method public void setNumericCollation(boolean);
     method public void setNumericCollationDefault();
     method public void setStrengthDefault();
@@ -23112,6 +23145,7 @@
     ctor public AudioRecord(android.media.AudioAttributes, android.media.AudioFormat, int, int) throws java.lang.IllegalArgumentException;
     method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
     method public deprecated void addOnRoutingChangedListener(android.media.AudioRecord.OnRoutingChangedListener, android.os.Handler);
+    method protected void finalize();
     method public int getAudioFormat();
     method public int getAudioSessionId();
     method public int getAudioSource();
@@ -23218,6 +23252,7 @@
     method public deprecated void addOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener, android.os.Handler);
     method public int attachAuxEffect(int);
     method public android.media.VolumeShaper createVolumeShaper(android.media.VolumeShaper.Configuration);
+    method protected void finalize();
     method public void flush();
     method public int getAudioFormat();
     method public int getAudioSessionId();
@@ -23616,6 +23651,7 @@
     method public boolean clearQueue();
     method public java.lang.Object clone() throws java.lang.CloneNotSupportedException;
     method public boolean closeJetFile();
+    method protected void finalize();
     method public static android.media.JetPlayer getJetPlayer();
     method public static int getMaxTracks();
     method public boolean loadJetFile(java.lang.String);
@@ -23655,6 +23691,7 @@
     ctor public MediaCas(int) throws android.media.MediaCasException.UnsupportedCasException;
     method public void close();
     method public static android.media.MediaCas.PluginDescriptor[] enumeratePlugins();
+    method protected void finalize();
     method public static boolean isSystemIdSupported(int);
     method public android.media.MediaCas.Session openSession() throws android.media.MediaCasException;
     method public void processEmm(byte[], int, int) throws android.media.MediaCasException;
@@ -23711,6 +23748,7 @@
     method public static android.view.Surface createPersistentInputSurface();
     method public final int dequeueInputBuffer(long);
     method public final int dequeueOutputBuffer(android.media.MediaCodec.BufferInfo, long);
+    method protected void finalize();
     method public final void flush();
     method public android.media.MediaCodecInfo getCodecInfo();
     method public java.nio.ByteBuffer getInputBuffer(int);
@@ -24122,6 +24160,7 @@
 
   public final class MediaCrypto {
     ctor public MediaCrypto(java.util.UUID, byte[]) throws android.media.MediaCryptoException;
+    method protected void finalize();
     method public static final boolean isCryptoSchemeSupported(java.util.UUID);
     method public final void release();
     method public final boolean requiresSecureDecoderComponent(java.lang.String);
@@ -24142,6 +24181,7 @@
     ctor public MediaDescrambler(int) throws android.media.MediaCasException.UnsupportedCasException;
     method public void close();
     method public final int descramble(java.nio.ByteBuffer, java.nio.ByteBuffer, android.media.MediaCodec.CryptoInfo);
+    method protected void finalize();
     method public final boolean requiresSecureDecoderComponent(java.lang.String);
     method public final void setMediaCasSession(android.media.MediaCas.Session);
   }
@@ -24184,6 +24224,7 @@
   public final class MediaDrm {
     ctor public MediaDrm(java.util.UUID) throws android.media.UnsupportedSchemeException;
     method public void closeSession(byte[]);
+    method protected void finalize();
     method public android.media.MediaDrm.CryptoSession getCryptoSession(byte[], java.lang.String, java.lang.String);
     method public android.media.MediaDrm.KeyRequest getKeyRequest(byte[], byte[], java.lang.String, int, java.util.HashMap<java.lang.String, java.lang.String>) throws android.media.NotProvisionedException;
     method public byte[] getPropertyByteArray(java.lang.String);
@@ -24280,6 +24321,7 @@
   public final class MediaExtractor {
     ctor public MediaExtractor();
     method public boolean advance();
+    method protected void finalize();
     method public long getCachedDuration();
     method public android.media.MediaExtractor.CasInfo getCasInfo(int);
     method public android.media.DrmInitData getDrmInitData();
@@ -24581,6 +24623,7 @@
     method public static android.media.MediaPlayer create(android.content.Context, int, android.media.AudioAttributes, int);
     method public android.media.VolumeShaper createVolumeShaper(android.media.VolumeShaper.Configuration);
     method public void deselectTrack(int) throws java.lang.IllegalStateException;
+    method protected void finalize();
     method public int getAudioSessionId();
     method public int getCurrentPosition();
     method public android.media.MediaPlayer.DrmInfo getDrmInfo();
@@ -24776,6 +24819,7 @@
 
   public class MediaRecorder {
     ctor public MediaRecorder();
+    method protected void finalize();
     method public static final int getAudioSourceMax();
     method public int getMaxAmplitude() throws java.lang.IllegalStateException;
     method public android.os.PersistableBundle getMetrics();
@@ -25049,6 +25093,7 @@
   public final class MediaSync {
     ctor public MediaSync();
     method public final android.view.Surface createInputSurface();
+    method protected void finalize();
     method public void flush();
     method public android.media.PlaybackParams getPlaybackParams();
     method public android.media.SyncParams getSyncParams();
@@ -25177,6 +25222,10 @@
 
   public deprecated class RemoteControlClient.MetadataEditor extends android.media.MediaMetadataEditor {
     method public synchronized void apply();
+    method public synchronized android.media.RemoteControlClient.MetadataEditor putBitmap(int, android.graphics.Bitmap) throws java.lang.IllegalArgumentException;
+    method public synchronized android.media.RemoteControlClient.MetadataEditor putLong(int, long) throws java.lang.IllegalArgumentException;
+    method public synchronized android.media.RemoteControlClient.MetadataEditor putObject(int, java.lang.Object) throws java.lang.IllegalArgumentException;
+    method public synchronized android.media.RemoteControlClient.MetadataEditor putString(int, java.lang.String) throws java.lang.IllegalArgumentException;
     field public static final int BITMAP_KEY_ARTWORK = 100; // 0x64
   }
 
@@ -25223,6 +25272,7 @@
   }
 
   public class Ringtone {
+    method protected void finalize();
     method public android.media.AudioAttributes getAudioAttributes();
     method public deprecated int getStreamType();
     method public java.lang.String getTitle(android.content.Context);
@@ -25276,6 +25326,7 @@
     ctor public deprecated SoundPool(int, int, int);
     method public final void autoPause();
     method public final void autoResume();
+    method protected void finalize();
     method public int load(java.lang.String, int);
     method public int load(android.content.Context, int, int);
     method public int load(android.content.res.AssetFileDescriptor, int);
@@ -25344,6 +25395,7 @@
 
   public class ToneGenerator {
     ctor public ToneGenerator(int, int);
+    method protected void finalize();
     method public final int getAudioSessionId();
     method public void release();
     method public boolean startTone(int);
@@ -25476,6 +25528,7 @@
   public final class VolumeShaper implements java.lang.AutoCloseable {
     method public void apply(android.media.VolumeShaper.Operation);
     method public void close();
+    method protected void finalize();
     method public float getVolume();
     method public void replace(android.media.VolumeShaper.Configuration, android.media.VolumeShaper.Operation, boolean);
   }
@@ -25530,6 +25583,7 @@
   }
 
   public class AudioEffect {
+    method protected void finalize();
     method public android.media.audiofx.AudioEffect.Descriptor getDescriptor() throws java.lang.IllegalStateException;
     method public boolean getEnabled() throws java.lang.IllegalStateException;
     method public int getId() throws java.lang.IllegalStateException;
@@ -25782,6 +25836,7 @@
 
   public class Visualizer {
     ctor public Visualizer(int) throws java.lang.RuntimeException, java.lang.UnsupportedOperationException;
+    method protected void finalize();
     method public int getCaptureSize() throws java.lang.IllegalStateException;
     method public static int[] getCaptureSizeRange();
     method public boolean getEnabled();
@@ -28046,6 +28101,7 @@
     method public static void incrementOperationCount(int, int);
     method public static void setThreadStatsTag(int);
     method public static void setThreadStatsTagBackup();
+    method public static void setThreadStatsTagCode();
     method public static void setThreadStatsTagRestore();
     method public static void setThreadStatsUid(int);
     method public static void tagDatagramSocket(java.net.DatagramSocket) throws java.net.SocketException;
@@ -33302,6 +33358,7 @@
     method public void putStringArrayList(java.lang.String, java.util.ArrayList<java.lang.String>);
     method public void readFromParcel(android.os.Parcel);
     method public void setClassLoader(java.lang.ClassLoader);
+    method public synchronized java.lang.String toString();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.os.Bundle> CREATOR;
     field public static final android.os.Bundle EMPTY;
@@ -33543,6 +33600,7 @@
   public abstract class FileObserver {
     ctor public FileObserver(java.lang.String);
     ctor public FileObserver(java.lang.String, int);
+    method protected void finalize();
     method public abstract void onEvent(int, java.lang.String);
     method public void startWatching();
     method public void stopWatching();
@@ -33717,6 +33775,7 @@
     ctor public MemoryFile(java.lang.String, int) throws java.io.IOException;
     method public synchronized boolean allowPurging(boolean) throws java.io.IOException;
     method public void close();
+    method protected void finalize();
     method public java.io.InputStream getInputStream();
     method public java.io.OutputStream getOutputStream();
     method public boolean isPurgingAllowed();
@@ -34016,6 +34075,7 @@
     method public int describeContents();
     method public android.os.PersistableBundle getPersistableBundle(java.lang.String);
     method public void putPersistableBundle(java.lang.String, android.os.PersistableBundle);
+    method public synchronized java.lang.String toString();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.os.PersistableBundle> CREATOR;
     field public static final android.os.PersistableBundle EMPTY;
@@ -38653,6 +38713,7 @@
     method public static android.renderscript.AllocationAdapter create1D(android.renderscript.RenderScript, android.renderscript.Allocation);
     method public static android.renderscript.AllocationAdapter create2D(android.renderscript.RenderScript, android.renderscript.Allocation);
     method public static android.renderscript.AllocationAdapter createTyped(android.renderscript.RenderScript, android.renderscript.Allocation, android.renderscript.Type);
+    method public synchronized void resize(int);
     method public void setFace(android.renderscript.Type.CubemapFace);
     method public void setLOD(int);
     method public void setX(int);
@@ -43786,6 +43847,7 @@
 
   public static deprecated class SmsMessage.SubmitPdu {
     ctor public deprecated SmsMessage.SubmitPdu();
+    method public deprecated java.lang.String toString();
     field public deprecated byte[] encodedMessage;
     field public deprecated byte[] encodedScAddress;
   }
@@ -43858,6 +43920,7 @@
     method public java.util.List<junit.framework.TestCase> getTestCases();
     method public java.lang.String getTestClassName();
     method public junit.framework.TestResult getTestResult();
+    method protected java.lang.Class loadSuiteClass(java.lang.String) throws java.lang.ClassNotFoundException;
     method protected void runFailed(java.lang.String);
     method public void runTest();
     method public void runTest(junit.framework.TestResult);
@@ -44118,10 +44181,12 @@
     ctor protected MockContentProvider();
     ctor public MockContentProvider(android.content.Context);
     ctor public MockContentProvider(android.content.Context, java.lang.String, java.lang.String, android.content.pm.PathPermission[]);
+    method public android.content.ContentProviderResult[] applyBatch(java.util.ArrayList<android.content.ContentProviderOperation>);
     method public int delete(android.net.Uri, java.lang.String, java.lang.String[]);
     method public java.lang.String getType(android.net.Uri);
     method public android.net.Uri insert(android.net.Uri, android.content.ContentValues);
     method public boolean onCreate();
+    method public android.content.res.AssetFileDescriptor openTypedAssetFile(android.net.Uri, java.lang.String, android.os.Bundle);
     method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
     method public int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]);
   }
@@ -44416,6 +44481,10 @@
 
   public deprecated class MockResources extends android.content.res.Resources {
     ctor public MockResources();
+    method public int getColor(int) throws android.content.res.Resources.NotFoundException;
+    method public android.content.res.ColorStateList getColorStateList(int) throws android.content.res.Resources.NotFoundException;
+    method public android.graphics.drawable.Drawable getDrawable(int) throws android.content.res.Resources.NotFoundException;
+    method public void updateConfiguration(android.content.res.Configuration, android.util.DisplayMetrics);
   }
 
 }
@@ -45664,6 +45733,7 @@
 
   public abstract class MetricAffectingSpan extends android.text.style.CharacterStyle implements android.text.style.UpdateLayout {
     ctor public MetricAffectingSpan();
+    method public android.text.style.MetricAffectingSpan getUnderlying();
     method public abstract void updateMeasureState(android.text.TextPaint);
   }
 
@@ -46344,14 +46414,28 @@
   public class TransitionSet extends android.transition.Transition {
     ctor public TransitionSet();
     ctor public TransitionSet(android.content.Context, android.util.AttributeSet);
+    method public android.transition.TransitionSet addListener(android.transition.Transition.TransitionListener);
+    method public android.transition.TransitionSet addTarget(android.view.View);
+    method public android.transition.TransitionSet addTarget(int);
+    method public android.transition.TransitionSet addTarget(java.lang.String);
+    method public android.transition.TransitionSet addTarget(java.lang.Class);
     method public android.transition.TransitionSet addTransition(android.transition.Transition);
     method public void captureEndValues(android.transition.TransitionValues);
     method public void captureStartValues(android.transition.TransitionValues);
+    method public android.transition.TransitionSet clone();
     method public int getOrdering();
     method public android.transition.Transition getTransitionAt(int);
     method public int getTransitionCount();
+    method public android.transition.TransitionSet removeListener(android.transition.Transition.TransitionListener);
+    method public android.transition.TransitionSet removeTarget(int);
+    method public android.transition.TransitionSet removeTarget(android.view.View);
+    method public android.transition.TransitionSet removeTarget(java.lang.Class);
+    method public android.transition.TransitionSet removeTarget(java.lang.String);
     method public android.transition.TransitionSet removeTransition(android.transition.Transition);
+    method public android.transition.TransitionSet setDuration(long);
+    method public android.transition.TransitionSet setInterpolator(android.animation.TimeInterpolator);
     method public android.transition.TransitionSet setOrdering(int);
+    method public android.transition.TransitionSet setStartDelay(long);
     field public static final int ORDERING_SEQUENTIAL = 1; // 0x1
     field public static final int ORDERING_TOGETHER = 0; // 0x0
   }
@@ -46516,6 +46600,9 @@
 
   public class Base64InputStream extends java.io.FilterInputStream {
     ctor public Base64InputStream(java.io.InputStream, int);
+    method public int available();
+    method public void mark(int);
+    method public void reset();
   }
 
   public class Base64OutputStream extends java.io.FilterOutputStream {
@@ -48633,6 +48720,7 @@
     method public android.graphics.Canvas lockCanvas();
     method public android.graphics.Canvas lockCanvas(android.graphics.Rect);
     method protected final void onDraw(android.graphics.Canvas);
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable);
     method public void setOpaque(boolean);
     method public void setSurfaceTexture(android.graphics.SurfaceTexture);
     method public void setSurfaceTextureListener(android.view.TextureView.SurfaceTextureListener);
@@ -49656,6 +49744,7 @@
     method public int getLayoutMode();
     method public android.animation.LayoutTransition getLayoutTransition();
     method public int getNestedScrollAxes();
+    method public android.view.ViewGroupOverlay getOverlay();
     method public int getPersistentDrawingCache();
     method public boolean getTouchscreenBlocksFocus();
     method public int indexOfChild(android.view.View);
@@ -50939,6 +51028,7 @@
     ctor public Animation(android.content.Context, android.util.AttributeSet);
     method protected void applyTransformation(float, android.view.animation.Transformation);
     method public void cancel();
+    method protected android.view.animation.Animation clone() throws java.lang.CloneNotSupportedException;
     method public long computeDurationHint();
     method protected void ensureInterpolator();
     method public int getBackgroundColor();
@@ -51010,6 +51100,7 @@
     ctor public AnimationSet(android.content.Context, android.util.AttributeSet);
     ctor public AnimationSet(boolean);
     method public void addAnimation(android.view.animation.Animation);
+    method protected android.view.animation.AnimationSet clone() throws java.lang.CloneNotSupportedException;
     method public java.util.List<android.view.animation.Animation> getAnimations();
   }
 
@@ -51865,6 +51956,10 @@
   public final deprecated class CookieSyncManager extends android.webkit.WebSyncManager {
     method public static android.webkit.CookieSyncManager createInstance(android.content.Context);
     method public static android.webkit.CookieSyncManager getInstance();
+    method public deprecated void resetSync();
+    method public deprecated void startSync();
+    method public deprecated void stopSync();
+    method public deprecated void sync();
     method protected deprecated void syncFromRamToFlash();
     field protected static final java.lang.String LOGTAG = "websync";
     field protected android.webkit.WebViewDatabase mDataBase;
@@ -52506,6 +52601,7 @@
     method public void setWebChromeClient(android.webkit.WebChromeClient);
     method public static void setWebContentsDebuggingEnabled(boolean);
     method public void setWebViewClient(android.webkit.WebViewClient);
+    method public deprecated boolean shouldDelayChildPressedState();
     method public deprecated boolean showFindDialog(java.lang.String, boolean);
     method public static void shutdownSafeBrowsing();
     method public void stopLoading();
@@ -52911,6 +53007,7 @@
     method public void clearTextFilter();
     method public void deferNotifyDataSetChanged();
     method public void fling(int);
+    method public android.widget.AbsListView.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public int getCacheColorHint();
     method public int getCheckedItemCount();
     method public long[] getCheckedItemIds();
@@ -53077,6 +53174,9 @@
     ctor public ActionMenuView(android.content.Context);
     ctor public ActionMenuView(android.content.Context, android.util.AttributeSet);
     method public void dismissPopupMenus();
+    method protected android.widget.ActionMenuView.LayoutParams generateDefaultLayoutParams();
+    method public android.widget.ActionMenuView.LayoutParams generateLayoutParams(android.util.AttributeSet);
+    method protected android.widget.ActionMenuView.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public android.view.Menu getMenu();
     method public android.graphics.drawable.Drawable getOverflowIcon();
     method public int getPopupTheme();
@@ -53252,7 +53352,6 @@
     method public void addAll(T...);
     method public void clear();
     method public static android.widget.ArrayAdapter<java.lang.CharSequence> createFromResource(android.content.Context, int, int);
-    method public java.lang.CharSequence[] getAutofillOptions();
     method public android.content.Context getContext();
     method public int getCount();
     method public android.content.res.Resources.Theme getDropDownViewTheme();
@@ -53342,6 +53441,7 @@
     method public void notifyDataSetChanged();
     method public void notifyDataSetInvalidated();
     method public void registerDataSetObserver(android.database.DataSetObserver);
+    method public void setAutofillOptions(java.lang.CharSequence...);
     method public void unregisterDataSetObserver(android.database.DataSetObserver);
   }
 
@@ -53620,6 +53720,7 @@
     ctor public EditText(android.content.Context, android.util.AttributeSet, int);
     ctor public EditText(android.content.Context, android.util.AttributeSet, int, int);
     method public void extendSelection(int);
+    method public android.text.Editable getText();
     method public void selectAll();
     method public void setSelection(int, int);
     method public void setSelection(int);
@@ -53741,6 +53842,8 @@
     ctor public FrameLayout(android.content.Context, android.util.AttributeSet);
     ctor public FrameLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public FrameLayout(android.content.Context, android.util.AttributeSet, int, int);
+    method protected android.widget.FrameLayout.LayoutParams generateDefaultLayoutParams();
+    method public android.widget.FrameLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public deprecated boolean getConsiderGoneChildrenWhenMeasuring();
     method public boolean getMeasureAllChildren();
     method protected void onLayout(boolean, int, int, int, int);
@@ -53787,6 +53890,9 @@
     ctor public GridLayout(android.content.Context, android.util.AttributeSet);
     ctor public GridLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public GridLayout(android.content.Context, android.util.AttributeSet, int, int);
+    method protected android.widget.GridLayout.LayoutParams generateDefaultLayoutParams();
+    method public android.widget.GridLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
+    method protected android.widget.GridLayout.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public int getAlignmentMode();
     method public int getColumnCount();
     method public int getOrientation();
@@ -53999,6 +54105,9 @@
     ctor public LinearLayout(android.content.Context, android.util.AttributeSet);
     ctor public LinearLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public LinearLayout(android.content.Context, android.util.AttributeSet, int, int);
+    method protected android.widget.LinearLayout.LayoutParams generateDefaultLayoutParams();
+    method public android.widget.LinearLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
+    method protected android.widget.LinearLayout.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public int getBaselineAlignedChildIndex();
     method public android.graphics.drawable.Drawable getDividerDrawable();
     method public int getDividerPadding();
@@ -54385,6 +54494,8 @@
     method public final synchronized void incrementSecondaryProgressBy(int);
     method public boolean isAnimating();
     method public synchronized boolean isIndeterminate();
+    method protected synchronized void onDraw(android.graphics.Canvas);
+    method protected synchronized void onMeasure(int, int);
     method public void onRestoreInstanceState(android.os.Parcelable);
     method public android.os.Parcelable onSaveInstanceState();
     method public synchronized void setIndeterminate(boolean);
@@ -54440,6 +54551,7 @@
     ctor public RadioGroup(android.content.Context, android.util.AttributeSet);
     method public void check(int);
     method public void clearCheck();
+    method public android.widget.RadioGroup.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public int getCheckedRadioButtonId();
     method public void setOnCheckedChangeListener(android.widget.RadioGroup.OnCheckedChangeListener);
   }
@@ -54482,6 +54594,7 @@
     ctor public RelativeLayout(android.content.Context, android.util.AttributeSet);
     ctor public RelativeLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public RelativeLayout(android.content.Context, android.util.AttributeSet, int, int);
+    method public android.widget.RelativeLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public int getGravity();
     method protected void onLayout(boolean, int, int, int, int);
     method public void setGravity(int);
@@ -55025,6 +55138,7 @@
   public class TableLayout extends android.widget.LinearLayout {
     ctor public TableLayout(android.content.Context);
     ctor public TableLayout(android.content.Context, android.util.AttributeSet);
+    method public android.widget.TableLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public boolean isColumnCollapsed(int);
     method public boolean isColumnShrinkable(int);
     method public boolean isColumnStretchable(int);
@@ -55049,6 +55163,7 @@
   public class TableRow extends android.widget.LinearLayout {
     ctor public TableRow(android.content.Context);
     ctor public TableRow(android.content.Context, android.util.AttributeSet);
+    method public android.widget.TableRow.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public android.view.View getVirtualChildAt(int);
     method public int getVirtualChildCount();
   }
@@ -55390,6 +55505,7 @@
     ctor public ToggleButton(android.content.Context);
     method public java.lang.CharSequence getTextOff();
     method public java.lang.CharSequence getTextOn();
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable);
     method public void setTextOff(java.lang.CharSequence);
     method public void setTextOn(java.lang.CharSequence);
   }
@@ -55401,6 +55517,9 @@
     ctor public Toolbar(android.content.Context, android.util.AttributeSet, int, int);
     method public void collapseActionView();
     method public void dismissPopupMenus();
+    method protected android.widget.Toolbar.LayoutParams generateDefaultLayoutParams();
+    method public android.widget.Toolbar.LayoutParams generateLayoutParams(android.util.AttributeSet);
+    method protected android.widget.Toolbar.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public int getContentInsetEnd();
     method public int getContentInsetEndWithActions();
     method public int getContentInsetLeft();
@@ -55922,6 +56041,8 @@
   public class BaseDexClassLoader extends java.lang.ClassLoader {
     ctor public BaseDexClassLoader(java.lang.String, java.io.File, java.lang.String, java.lang.ClassLoader);
     method public java.lang.String findLibrary(java.lang.String);
+    method protected java.util.Enumeration<java.net.URL> findResources(java.lang.String);
+    method protected synchronized java.lang.Package getPackage(java.lang.String);
   }
 
   public class DexClassLoader extends dalvik.system.BaseDexClassLoader {
@@ -56143,6 +56264,10 @@
   public class BufferedInputStream extends java.io.FilterInputStream {
     ctor public BufferedInputStream(java.io.InputStream);
     ctor public BufferedInputStream(java.io.InputStream, int);
+    method public synchronized int available() throws java.io.IOException;
+    method public synchronized int read() throws java.io.IOException;
+    method public synchronized int read(byte[], int, int) throws java.io.IOException;
+    method public synchronized long skip(long) throws java.io.IOException;
     field protected volatile byte[] buf;
     field protected int count;
     field protected int marklimit;
@@ -56153,6 +56278,9 @@
   public class BufferedOutputStream extends java.io.FilterOutputStream {
     ctor public BufferedOutputStream(java.io.OutputStream);
     ctor public BufferedOutputStream(java.io.OutputStream, int);
+    method public synchronized void flush() throws java.io.IOException;
+    method public synchronized void write(int) throws java.io.IOException;
+    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     field protected byte[] buf;
     field protected int count;
   }
@@ -56178,7 +56306,12 @@
   public class ByteArrayInputStream extends java.io.InputStream {
     ctor public ByteArrayInputStream(byte[]);
     ctor public ByteArrayInputStream(byte[], int, int);
+    method public synchronized int available();
+    method public void mark(int);
     method public synchronized int read();
+    method public synchronized int read(byte[], int, int);
+    method public synchronized void reset();
+    method public synchronized long skip(long);
     field protected byte[] buf;
     field protected int count;
     field protected int mark;
@@ -56191,9 +56324,11 @@
     method public synchronized void reset();
     method public synchronized int size();
     method public synchronized byte[] toByteArray();
+    method public synchronized java.lang.String toString();
     method public synchronized java.lang.String toString(java.lang.String) throws java.io.UnsupportedEncodingException;
     method public deprecated synchronized java.lang.String toString(int);
     method public synchronized void write(int);
+    method public synchronized void write(byte[], int, int);
     method public synchronized void writeTo(java.io.OutputStream) throws java.io.IOException;
     field protected byte[] buf;
     field protected int count;
@@ -56213,12 +56348,17 @@
   public class CharArrayWriter extends java.io.Writer {
     ctor public CharArrayWriter();
     ctor public CharArrayWriter(int);
+    method public java.io.CharArrayWriter append(java.lang.CharSequence);
+    method public java.io.CharArrayWriter append(java.lang.CharSequence, int, int);
+    method public java.io.CharArrayWriter append(char);
     method public void close();
     method public void flush();
     method public void reset();
     method public int size();
     method public char[] toCharArray();
+    method public void write(int);
     method public void write(char[], int, int);
+    method public void write(java.lang.String, int, int);
     method public void writeTo(java.io.Writer) throws java.io.IOException;
     field protected char[] buf;
     field protected int count;
@@ -56305,6 +56445,8 @@
   public class DataOutputStream extends java.io.FilterOutputStream implements java.io.DataOutput {
     ctor public DataOutputStream(java.io.OutputStream);
     method public final int size();
+    method public synchronized void write(int) throws java.io.IOException;
+    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     method public final void writeBoolean(boolean) throws java.io.IOException;
     method public final void writeByte(int) throws java.io.IOException;
     method public final void writeBytes(java.lang.String) throws java.io.IOException;
@@ -56404,6 +56546,7 @@
     ctor public FileInputStream(java.lang.String) throws java.io.FileNotFoundException;
     ctor public FileInputStream(java.io.File) throws java.io.FileNotFoundException;
     ctor public FileInputStream(java.io.FileDescriptor);
+    method protected void finalize() throws java.io.IOException;
     method public java.nio.channels.FileChannel getChannel();
     method public final java.io.FileDescriptor getFD() throws java.io.IOException;
     method public int read() throws java.io.IOException;
@@ -56420,6 +56563,7 @@
     ctor public FileOutputStream(java.io.File) throws java.io.FileNotFoundException;
     ctor public FileOutputStream(java.io.File, boolean) throws java.io.FileNotFoundException;
     ctor public FileOutputStream(java.io.FileDescriptor);
+    method protected void finalize() throws java.io.IOException;
     method public java.nio.channels.FileChannel getChannel();
     method public final java.io.FileDescriptor getFD() throws java.io.IOException;
     method public void write(int) throws java.io.IOException;
@@ -56533,6 +56677,8 @@
   public deprecated class LineNumberInputStream extends java.io.FilterInputStream {
     ctor public LineNumberInputStream(java.io.InputStream);
     method public int getLineNumber();
+    method public void mark(int);
+    method public void reset() throws java.io.IOException;
     method public void setLineNumber(int);
   }
 
@@ -56762,8 +56908,10 @@
     ctor public PipedInputStream(java.io.PipedOutputStream, int) throws java.io.IOException;
     ctor public PipedInputStream();
     ctor public PipedInputStream(int);
+    method public synchronized int available() throws java.io.IOException;
     method public void connect(java.io.PipedOutputStream) throws java.io.IOException;
     method public synchronized int read() throws java.io.IOException;
+    method public synchronized int read(byte[], int, int) throws java.io.IOException;
     method protected synchronized void receive(int) throws java.io.IOException;
     field protected static final int PIPE_SIZE = 1024; // 0x400
     field protected byte[] buffer;
@@ -56775,6 +56923,7 @@
     ctor public PipedOutputStream(java.io.PipedInputStream) throws java.io.IOException;
     ctor public PipedOutputStream();
     method public synchronized void connect(java.io.PipedInputStream) throws java.io.IOException;
+    method public synchronized void flush() throws java.io.IOException;
     method public void write(int) throws java.io.IOException;
   }
 
@@ -56785,7 +56934,9 @@
     ctor public PipedReader(int);
     method public void close() throws java.io.IOException;
     method public void connect(java.io.PipedWriter) throws java.io.IOException;
+    method public synchronized int read() throws java.io.IOException;
     method public synchronized int read(char[], int, int) throws java.io.IOException;
+    method public synchronized boolean ready() throws java.io.IOException;
   }
 
   public class PipedWriter extends java.io.Writer {
@@ -56810,6 +56961,8 @@
     method public java.io.PrintStream append(char);
     method public boolean checkError();
     method protected void clearError();
+    method public void close();
+    method public void flush();
     method public java.io.PrintStream format(java.lang.String, java.lang.Object...);
     method public java.io.PrintStream format(java.util.Locale, java.lang.String, java.lang.Object...);
     method public void print(boolean);
@@ -56834,6 +56987,8 @@
     method public void println(java.lang.String);
     method public void println(java.lang.Object);
     method protected void setError();
+    method public void write(int);
+    method public void write(byte[], int, int);
   }
 
   public class PrintWriter extends java.io.Writer {
@@ -56845,6 +57000,9 @@
     ctor public PrintWriter(java.lang.String, java.lang.String) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
     ctor public PrintWriter(java.io.File) throws java.io.FileNotFoundException;
     ctor public PrintWriter(java.io.File, java.lang.String) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
+    method public java.io.PrintWriter append(java.lang.CharSequence);
+    method public java.io.PrintWriter append(java.lang.CharSequence, int, int);
+    method public java.io.PrintWriter append(char);
     method public boolean checkError();
     method protected void clearError();
     method public void close();
@@ -56873,13 +57031,18 @@
     method public void println(java.lang.String);
     method public void println(java.lang.Object);
     method protected void setError();
+    method public void write(int);
     method public void write(char[], int, int);
+    method public void write(char[]);
+    method public void write(java.lang.String, int, int);
+    method public void write(java.lang.String);
     field protected java.io.Writer out;
   }
 
   public class PushbackInputStream extends java.io.FilterInputStream {
     ctor public PushbackInputStream(java.io.InputStream, int);
     ctor public PushbackInputStream(java.io.InputStream);
+    method public synchronized void close() throws java.io.IOException;
     method public void unread(int) throws java.io.IOException;
     method public void unread(byte[], int, int) throws java.io.IOException;
     method public void unread(byte[]) throws java.io.IOException;
@@ -57003,7 +57166,11 @@
 
   public deprecated class StringBufferInputStream extends java.io.InputStream {
     ctor public StringBufferInputStream(java.lang.String);
+    method public synchronized int available();
     method public synchronized int read();
+    method public synchronized int read(byte[], int, int);
+    method public synchronized void reset();
+    method public synchronized long skip(long);
     field protected java.lang.String buffer;
     field protected int count;
     field protected int pos;
@@ -57018,10 +57185,16 @@
   public class StringWriter extends java.io.Writer {
     ctor public StringWriter();
     ctor public StringWriter(int);
+    method public java.io.StringWriter append(java.lang.CharSequence);
+    method public java.io.StringWriter append(java.lang.CharSequence, int, int);
+    method public java.io.StringWriter append(char);
     method public void close() throws java.io.IOException;
     method public void flush();
     method public java.lang.StringBuffer getBuffer();
+    method public void write(int);
     method public void write(char[], int, int);
+    method public void write(java.lang.String);
+    method public void write(java.lang.String, int, int);
   }
 
   public class SyncFailedException extends java.io.IOException {
@@ -57036,6 +57209,7 @@
   public class UncheckedIOException extends java.lang.RuntimeException {
     ctor public UncheckedIOException(java.lang.String, java.io.IOException);
     ctor public UncheckedIOException(java.io.IOException);
+    method public java.io.IOException getCause();
   }
 
   public class UnsupportedEncodingException extends java.io.IOException {
@@ -57045,6 +57219,7 @@
 
   public class WriteAbortedException extends java.io.ObjectStreamException {
     ctor public WriteAbortedException(java.lang.String, java.lang.Exception);
+    method public java.lang.Throwable getCause();
     field public java.lang.Exception detail;
   }
 
@@ -57812,6 +57987,7 @@
     ctor public ClassNotFoundException();
     ctor public ClassNotFoundException(java.lang.String);
     ctor public ClassNotFoundException(java.lang.String, java.lang.Throwable);
+    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getException();
   }
 
@@ -57916,6 +58092,7 @@
     ctor public ExceptionInInitializerError();
     ctor public ExceptionInInitializerError(java.lang.Throwable);
     ctor public ExceptionInInitializerError(java.lang.String);
+    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getException();
   }
 
@@ -58703,8 +58880,16 @@
     method public synchronized java.lang.StringBuffer append(float);
     method public synchronized java.lang.StringBuffer append(double);
     method public synchronized java.lang.StringBuffer appendCodePoint(int);
+    method public synchronized int capacity();
+    method public synchronized char charAt(int);
+    method public synchronized int codePointAt(int);
+    method public synchronized int codePointBefore(int);
+    method public synchronized int codePointCount(int, int);
     method public synchronized java.lang.StringBuffer delete(int, int);
     method public synchronized java.lang.StringBuffer deleteCharAt(int);
+    method public synchronized void ensureCapacity(int);
+    method public synchronized void getChars(int, int, char[], int);
+    method public synchronized int indexOf(java.lang.String, int);
     method public synchronized java.lang.StringBuffer insert(int, char[], int, int);
     method public synchronized java.lang.StringBuffer insert(int, java.lang.Object);
     method public synchronized java.lang.StringBuffer insert(int, java.lang.String);
@@ -58717,9 +58902,18 @@
     method public java.lang.StringBuffer insert(int, long);
     method public java.lang.StringBuffer insert(int, float);
     method public java.lang.StringBuffer insert(int, double);
+    method public synchronized int lastIndexOf(java.lang.String, int);
+    method public synchronized int length();
+    method public synchronized int offsetByCodePoints(int, int);
     method public synchronized java.lang.StringBuffer replace(int, int, java.lang.String);
     method public synchronized java.lang.StringBuffer reverse();
+    method public synchronized void setCharAt(int, char);
+    method public synchronized void setLength(int);
+    method public synchronized java.lang.CharSequence subSequence(int, int);
+    method public synchronized java.lang.String substring(int);
+    method public synchronized java.lang.String substring(int, int);
     method public synchronized java.lang.String toString();
+    method public synchronized void trimToSize();
   }
 
   public final class StringBuilder extends java.lang.AbstractStringBuilder implements java.lang.CharSequence java.io.Serializable {
@@ -59374,6 +59568,7 @@
     ctor protected InvocationTargetException();
     ctor public InvocationTargetException(java.lang.Throwable);
     ctor public InvocationTargetException(java.lang.Throwable, java.lang.String);
+    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getTargetException();
   }
 
@@ -59489,6 +59684,7 @@
   public class UndeclaredThrowableException extends java.lang.RuntimeException {
     ctor public UndeclaredThrowableException(java.lang.Throwable);
     ctor public UndeclaredThrowableException(java.lang.Throwable, java.lang.String);
+    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getUndeclaredThrowable();
   }
 
@@ -60386,6 +60582,7 @@
     method public java.lang.String getQuery();
     method public java.lang.String getRef();
     method public java.lang.String getUserInfo();
+    method public synchronized int hashCode();
     method public java.net.URLConnection openConnection() throws java.io.IOException;
     method public java.net.URLConnection openConnection(java.net.Proxy) throws java.io.IOException;
     method public final java.io.InputStream openStream() throws java.io.IOException;
@@ -60615,7 +60812,6 @@
     method public final int arrayOffset();
     method public abstract java.nio.CharBuffer asReadOnlyBuffer();
     method public final char charAt(int);
-    method public java.util.stream.IntStream chars();
     method public abstract java.nio.CharBuffer compact();
     method public int compareTo(java.nio.CharBuffer);
     method public abstract java.nio.CharBuffer duplicate();
@@ -61472,6 +61668,7 @@
 
   public final class DirectoryIteratorException extends java.util.ConcurrentModificationException {
     ctor public DirectoryIteratorException(java.io.IOException);
+    method public java.io.IOException getCause();
   }
 
   public class DirectoryNotEmptyException extends java.nio.file.FileSystemException {
@@ -62437,9 +62634,11 @@
   public static class KeyStore.PasswordProtection implements javax.security.auth.Destroyable java.security.KeyStore.ProtectionParameter {
     ctor public KeyStore.PasswordProtection(char[]);
     ctor public KeyStore.PasswordProtection(char[], java.lang.String, java.security.spec.AlgorithmParameterSpec);
+    method public synchronized void destroy() throws javax.security.auth.DestroyFailedException;
     method public synchronized char[] getPassword();
     method public java.lang.String getProtectionAlgorithm();
     method public java.security.spec.AlgorithmParameterSpec getProtectionParameters();
+    method public synchronized boolean isDestroyed();
   }
 
   public static final class KeyStore.PrivateKeyEntry implements java.security.KeyStore.Entry {
@@ -62619,6 +62818,7 @@
 
   public class PrivilegedActionException extends java.lang.Exception {
     ctor public PrivilegedActionException(java.lang.Exception);
+    method public java.lang.Throwable getCause();
     method public java.lang.Exception getException();
   }
 
@@ -62641,22 +62841,30 @@
     method public synchronized java.lang.Object compute(java.lang.Object, java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
     method public synchronized java.lang.Object computeIfAbsent(java.lang.Object, java.util.function.Function<? super java.lang.Object, ? extends java.lang.Object>);
     method public synchronized java.lang.Object computeIfPresent(java.lang.Object, java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
+    method public java.util.Enumeration<java.lang.Object> elements();
+    method public synchronized java.util.Set<java.util.Map.Entry<java.lang.Object, java.lang.Object>> entrySet();
     method public synchronized void forEach(java.util.function.BiConsumer<? super java.lang.Object, ? super java.lang.Object>);
+    method public java.lang.Object get(java.lang.Object);
     method public java.lang.String getInfo();
     method public java.lang.String getName();
     method public synchronized java.lang.Object getOrDefault(java.lang.Object, java.lang.Object);
     method public synchronized java.security.Provider.Service getService(java.lang.String, java.lang.String);
     method public synchronized java.util.Set<java.security.Provider.Service> getServices();
     method public double getVersion();
+    method public java.util.Set<java.lang.Object> keySet();
+    method public java.util.Enumeration<java.lang.Object> keys();
     method public synchronized java.lang.Object merge(java.lang.Object, java.lang.Object, java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
     method public synchronized java.lang.Object put(java.lang.Object, java.lang.Object);
     method public synchronized void putAll(java.util.Map<?, ?>);
     method public synchronized java.lang.Object putIfAbsent(java.lang.Object, java.lang.Object);
     method protected synchronized void putService(java.security.Provider.Service);
+    method public synchronized java.lang.Object remove(java.lang.Object);
     method protected synchronized void removeService(java.security.Provider.Service);
     method public synchronized boolean replace(java.lang.Object, java.lang.Object, java.lang.Object);
     method public synchronized java.lang.Object replace(java.lang.Object, java.lang.Object);
     method public synchronized void replaceAll(java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
+    method public java.lang.String toString();
+    method public java.util.Collection<java.lang.Object> values();
   }
 
   public static class Provider.Service {
@@ -62702,7 +62910,9 @@
     method public final java.security.Provider getProvider();
     method public static byte[] getSeed(int);
     method protected final int next(int);
+    method public synchronized void nextBytes(byte[]);
     method public synchronized void setSeed(byte[]);
+    method public void setSeed(long);
   }
 
   public abstract class SecureRandomSpi implements java.io.Serializable {
@@ -63249,6 +63459,7 @@
 
   public abstract class PKIXRevocationChecker extends java.security.cert.PKIXCertPathChecker {
     ctor protected PKIXRevocationChecker();
+    method public java.security.cert.PKIXRevocationChecker clone();
     method public java.util.List<java.security.cert.Extension> getOcspExtensions();
     method public java.net.URI getOcspResponder();
     method public java.security.cert.X509Certificate getOcspResponderCert();
@@ -65501,7 +65712,6 @@
   public final class DayOfWeek extends java.lang.Enum implements java.time.temporal.TemporalAccessor java.time.temporal.TemporalAdjuster {
     method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
     method public static java.time.DayOfWeek from(java.time.temporal.TemporalAccessor);
-    method public int get(java.time.temporal.TemporalField);
     method public java.lang.String getDisplayName(java.time.format.TextStyle, java.util.Locale);
     method public long getLong(java.time.temporal.TemporalField);
     method public int getValue();
@@ -65509,8 +65719,6 @@
     method public java.time.DayOfWeek minus(long);
     method public static java.time.DayOfWeek of(int);
     method public java.time.DayOfWeek plus(long);
-    method public <R> R query(java.time.temporal.TemporalQuery<R>);
-    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     method public static java.time.DayOfWeek valueOf(java.lang.String);
     method public static final java.time.DayOfWeek[] values();
     enum_constant public static final java.time.DayOfWeek FRIDAY;
@@ -65586,6 +65794,8 @@
     method public boolean isBefore(java.time.Instant);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
+    method public java.time.Instant minus(java.time.temporal.TemporalAmount);
+    method public java.time.Instant minus(long, java.time.temporal.TemporalUnit);
     method public java.time.Instant minusMillis(long);
     method public java.time.Instant minusNanos(long);
     method public java.time.Instant minusSeconds(long);
@@ -65595,6 +65805,7 @@
     method public static java.time.Instant ofEpochSecond(long);
     method public static java.time.Instant ofEpochSecond(long, long);
     method public static java.time.Instant parse(java.lang.CharSequence);
+    method public java.time.Instant plus(java.time.temporal.TemporalAmount);
     method public java.time.Instant plus(long, java.time.temporal.TemporalUnit);
     method public java.time.Instant plusMillis(long);
     method public java.time.Instant plusNanos(long);
@@ -65602,6 +65813,7 @@
     method public long toEpochMilli();
     method public java.time.Instant truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.Instant with(java.time.temporal.TemporalAdjuster);
     method public java.time.Instant with(java.time.temporal.TemporalField, long);
     field public static final java.time.Instant EPOCH;
     field public static final java.time.Instant MAX;
@@ -65611,6 +65823,7 @@
   public final class LocalDate implements java.time.chrono.ChronoLocalDate java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
     method public java.time.LocalDateTime atStartOfDay();
     method public java.time.ZonedDateTime atStartOfDay(java.time.ZoneId);
+    method public java.time.LocalDateTime atTime(java.time.LocalTime);
     method public java.time.LocalDateTime atTime(int, int);
     method public java.time.LocalDateTime atTime(int, int, int);
     method public java.time.LocalDateTime atTime(int, int, int, int);
@@ -65625,6 +65838,8 @@
     method public int getMonthValue();
     method public int getYear();
     method public int lengthOfMonth();
+    method public java.time.LocalDate minus(java.time.temporal.TemporalAmount);
+    method public java.time.LocalDate minus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDate minusDays(long);
     method public java.time.LocalDate minusMonths(long);
     method public java.time.LocalDate minusWeeks(long);
@@ -65638,12 +65853,16 @@
     method public static java.time.LocalDate ofYearDay(int, int);
     method public static java.time.LocalDate parse(java.lang.CharSequence);
     method public static java.time.LocalDate parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
+    method public java.time.LocalDate plus(java.time.temporal.TemporalAmount);
+    method public java.time.LocalDate plus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDate plusDays(long);
     method public java.time.LocalDate plusMonths(long);
     method public java.time.LocalDate plusWeeks(long);
     method public java.time.LocalDate plusYears(long);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
     method public java.time.Period until(java.time.chrono.ChronoLocalDate);
+    method public java.time.LocalDate with(java.time.temporal.TemporalAdjuster);
+    method public java.time.LocalDate with(java.time.temporal.TemporalField, long);
     method public java.time.LocalDate withDayOfMonth(int);
     method public java.time.LocalDate withDayOfYear(int);
     method public java.time.LocalDate withMonth(int);
@@ -65668,6 +65887,8 @@
     method public int getSecond();
     method public int getYear();
     method public boolean isSupported(java.time.temporal.TemporalField);
+    method public java.time.LocalDateTime minus(java.time.temporal.TemporalAmount);
+    method public java.time.LocalDateTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDateTime minusDays(long);
     method public java.time.LocalDateTime minusHours(long);
     method public java.time.LocalDateTime minusMinutes(long);
@@ -65690,6 +65911,7 @@
     method public static java.time.LocalDateTime ofInstant(java.time.Instant, java.time.ZoneId);
     method public static java.time.LocalDateTime parse(java.lang.CharSequence);
     method public static java.time.LocalDateTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
+    method public java.time.LocalDateTime plus(java.time.temporal.TemporalAmount);
     method public java.time.LocalDateTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDateTime plusDays(long);
     method public java.time.LocalDateTime plusHours(long);
@@ -65703,6 +65925,7 @@
     method public java.time.LocalTime toLocalTime();
     method public java.time.LocalDateTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.LocalDateTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.LocalDateTime with(java.time.temporal.TemporalField, long);
     method public java.time.LocalDateTime withDayOfMonth(int);
     method public java.time.LocalDateTime withDayOfYear(int);
@@ -65732,6 +65955,8 @@
     method public boolean isBefore(java.time.LocalTime);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
+    method public java.time.LocalTime minus(java.time.temporal.TemporalAmount);
+    method public java.time.LocalTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalTime minusHours(long);
     method public java.time.LocalTime minusMinutes(long);
     method public java.time.LocalTime minusNanos(long);
@@ -65746,6 +65971,7 @@
     method public static java.time.LocalTime ofSecondOfDay(long);
     method public static java.time.LocalTime parse(java.lang.CharSequence);
     method public static java.time.LocalTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
+    method public java.time.LocalTime plus(java.time.temporal.TemporalAmount);
     method public java.time.LocalTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalTime plusHours(long);
     method public java.time.LocalTime plusMinutes(long);
@@ -65755,6 +65981,7 @@
     method public int toSecondOfDay();
     method public java.time.LocalTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.LocalTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.LocalTime with(java.time.temporal.TemporalField, long);
     method public java.time.LocalTime withHour(int);
     method public java.time.LocalTime withMinute(int);
@@ -65771,7 +65998,6 @@
     method public int firstDayOfYear(boolean);
     method public java.time.Month firstMonthOfQuarter();
     method public static java.time.Month from(java.time.temporal.TemporalAccessor);
-    method public int get(java.time.temporal.TemporalField);
     method public java.lang.String getDisplayName(java.time.format.TextStyle, java.util.Locale);
     method public long getLong(java.time.temporal.TemporalField);
     method public int getValue();
@@ -65782,8 +66008,6 @@
     method public java.time.Month minus(long);
     method public static java.time.Month of(int);
     method public java.time.Month plus(long);
-    method public <R> R query(java.time.temporal.TemporalQuery<R>);
-    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     method public static java.time.Month valueOf(java.lang.String);
     method public static final java.time.Month[] values();
     enum_constant public static final java.time.Month APRIL;
@@ -65850,6 +66074,8 @@
     method public boolean isEqual(java.time.OffsetDateTime);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
+    method public java.time.OffsetDateTime minus(java.time.temporal.TemporalAmount);
+    method public java.time.OffsetDateTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetDateTime minusDays(long);
     method public java.time.OffsetDateTime minusHours(long);
     method public java.time.OffsetDateTime minusMinutes(long);
@@ -65867,6 +66093,7 @@
     method public static java.time.OffsetDateTime ofInstant(java.time.Instant, java.time.ZoneId);
     method public static java.time.OffsetDateTime parse(java.lang.CharSequence);
     method public static java.time.OffsetDateTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
+    method public java.time.OffsetDateTime plus(java.time.temporal.TemporalAmount);
     method public java.time.OffsetDateTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetDateTime plusDays(long);
     method public java.time.OffsetDateTime plusHours(long);
@@ -65886,6 +66113,7 @@
     method public java.time.ZonedDateTime toZonedDateTime();
     method public java.time.OffsetDateTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.OffsetDateTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.OffsetDateTime with(java.time.temporal.TemporalField, long);
     method public java.time.OffsetDateTime withDayOfMonth(int);
     method public java.time.OffsetDateTime withDayOfYear(int);
@@ -65918,6 +66146,8 @@
     method public boolean isEqual(java.time.OffsetTime);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
+    method public java.time.OffsetTime minus(java.time.temporal.TemporalAmount);
+    method public java.time.OffsetTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetTime minusHours(long);
     method public java.time.OffsetTime minusMinutes(long);
     method public java.time.OffsetTime minusNanos(long);
@@ -65930,6 +66160,7 @@
     method public static java.time.OffsetTime ofInstant(java.time.Instant, java.time.ZoneId);
     method public static java.time.OffsetTime parse(java.lang.CharSequence);
     method public static java.time.OffsetTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
+    method public java.time.OffsetTime plus(java.time.temporal.TemporalAmount);
     method public java.time.OffsetTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetTime plusHours(long);
     method public java.time.OffsetTime plusMinutes(long);
@@ -65938,6 +66169,7 @@
     method public java.time.LocalTime toLocalTime();
     method public java.time.OffsetTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.OffsetTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.OffsetTime with(java.time.temporal.TemporalField, long);
     method public java.time.OffsetTime withHour(int);
     method public java.time.OffsetTime withMinute(int);
@@ -65964,6 +66196,7 @@
     method public java.time.Period minusMonths(long);
     method public java.time.Period minusYears(long);
     method public java.time.Period multipliedBy(int);
+    method public java.time.Period negated();
     method public java.time.Period normalized();
     method public static java.time.Period of(int, int, int);
     method public static java.time.Period ofDays(int);
@@ -66002,6 +66235,8 @@
     method public boolean isSupported(java.time.temporal.TemporalUnit);
     method public boolean isValidMonthDay(java.time.MonthDay);
     method public int length();
+    method public java.time.Year minus(java.time.temporal.TemporalAmount);
+    method public java.time.Year minus(long, java.time.temporal.TemporalUnit);
     method public java.time.Year minusYears(long);
     method public static java.time.Year now();
     method public static java.time.Year now(java.time.ZoneId);
@@ -66009,9 +66244,11 @@
     method public static java.time.Year of(int);
     method public static java.time.Year parse(java.lang.CharSequence);
     method public static java.time.Year parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
+    method public java.time.Year plus(java.time.temporal.TemporalAmount);
     method public java.time.Year plus(long, java.time.temporal.TemporalUnit);
     method public java.time.Year plusYears(long);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.Year with(java.time.temporal.TemporalAdjuster);
     method public java.time.Year with(java.time.temporal.TemporalField, long);
     field public static final int MAX_VALUE = 999999999; // 0x3b9ac9ff
     field public static final int MIN_VALUE = -999999999; // 0xc4653601
@@ -66036,6 +66273,8 @@
     method public boolean isValidDay(int);
     method public int lengthOfMonth();
     method public int lengthOfYear();
+    method public java.time.YearMonth minus(java.time.temporal.TemporalAmount);
+    method public java.time.YearMonth minus(long, java.time.temporal.TemporalUnit);
     method public java.time.YearMonth minusMonths(long);
     method public java.time.YearMonth minusYears(long);
     method public static java.time.YearMonth now();
@@ -66045,10 +66284,12 @@
     method public static java.time.YearMonth of(int, int);
     method public static java.time.YearMonth parse(java.lang.CharSequence);
     method public static java.time.YearMonth parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
+    method public java.time.YearMonth plus(java.time.temporal.TemporalAmount);
     method public java.time.YearMonth plus(long, java.time.temporal.TemporalUnit);
     method public java.time.YearMonth plusMonths(long);
     method public java.time.YearMonth plusYears(long);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.YearMonth with(java.time.temporal.TemporalAdjuster);
     method public java.time.YearMonth with(java.time.temporal.TemporalField, long);
     method public java.time.YearMonth withMonth(int);
     method public java.time.YearMonth withYear(int);
@@ -66072,7 +66313,6 @@
     method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
     method public int compareTo(java.time.ZoneOffset);
     method public static java.time.ZoneOffset from(java.time.temporal.TemporalAccessor);
-    method public int get(java.time.temporal.TemporalField);
     method public java.lang.String getId();
     method public long getLong(java.time.temporal.TemporalField);
     method public java.time.zone.ZoneRules getRules();
@@ -66083,8 +66323,6 @@
     method public static java.time.ZoneOffset ofHoursMinutes(int, int);
     method public static java.time.ZoneOffset ofHoursMinutesSeconds(int, int, int);
     method public static java.time.ZoneOffset ofTotalSeconds(int);
-    method public <R> R query(java.time.temporal.TemporalQuery<R>);
-    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     field public static final java.time.ZoneOffset MAX;
     field public static final java.time.ZoneOffset MIN;
     field public static final java.time.ZoneOffset UTC;
@@ -66105,6 +66343,8 @@
     method public int getYear();
     method public java.time.ZoneId getZone();
     method public boolean isSupported(java.time.temporal.TemporalField);
+    method public java.time.ZonedDateTime minus(java.time.temporal.TemporalAmount);
+    method public java.time.ZonedDateTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.ZonedDateTime minusDays(long);
     method public java.time.ZonedDateTime minusHours(long);
     method public java.time.ZonedDateTime minusMinutes(long);
@@ -66125,6 +66365,7 @@
     method public static java.time.ZonedDateTime ofStrict(java.time.LocalDateTime, java.time.ZoneOffset, java.time.ZoneId);
     method public static java.time.ZonedDateTime parse(java.lang.CharSequence);
     method public static java.time.ZonedDateTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
+    method public java.time.ZonedDateTime plus(java.time.temporal.TemporalAmount);
     method public java.time.ZonedDateTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.ZonedDateTime plusDays(long);
     method public java.time.ZonedDateTime plusHours(long);
@@ -66134,10 +66375,12 @@
     method public java.time.ZonedDateTime plusSeconds(long);
     method public java.time.ZonedDateTime plusWeeks(long);
     method public java.time.ZonedDateTime plusYears(long);
+    method public java.time.LocalDate toLocalDate();
     method public java.time.LocalDateTime toLocalDateTime();
     method public java.time.OffsetDateTime toOffsetDateTime();
     method public java.time.ZonedDateTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.ZonedDateTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.ZonedDateTime with(java.time.temporal.TemporalField, long);
     method public java.time.ZonedDateTime withDayOfMonth(int);
     method public java.time.ZonedDateTime withDayOfYear(int);
@@ -66182,17 +66425,27 @@
     method public default boolean isSupported(java.time.temporal.TemporalUnit);
     method public abstract int lengthOfMonth();
     method public default int lengthOfYear();
+    method public default java.time.chrono.ChronoLocalDate minus(java.time.temporal.TemporalAmount);
+    method public default java.time.chrono.ChronoLocalDate minus(long, java.time.temporal.TemporalUnit);
+    method public default java.time.chrono.ChronoLocalDate plus(java.time.temporal.TemporalAmount);
     method public default java.time.chrono.ChronoLocalDate plus(long, java.time.temporal.TemporalUnit);
     method public static java.util.Comparator<java.time.chrono.ChronoLocalDate> timeLineOrder();
     method public default long toEpochDay();
     method public abstract java.lang.String toString();
     method public abstract long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
     method public abstract java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
+    method public default java.time.chrono.ChronoLocalDate with(java.time.temporal.TemporalAdjuster);
     method public default java.time.chrono.ChronoLocalDate with(java.time.temporal.TemporalField, long);
   }
 
    abstract class ChronoLocalDateImpl<D extends java.time.chrono.ChronoLocalDate> implements java.time.chrono.ChronoLocalDate java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
+    method public D minus(java.time.temporal.TemporalAmount);
+    method public D minus(long, java.time.temporal.TemporalUnit);
+    method public D plus(java.time.temporal.TemporalAmount);
+    method public D plus(long, java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public D with(java.time.temporal.TemporalAdjuster);
+    method public D with(java.time.temporal.TemporalField, long);
   }
 
   public abstract interface ChronoLocalDateTime<D extends java.time.chrono.ChronoLocalDate> implements java.lang.Comparable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
@@ -66209,6 +66462,9 @@
     method public default boolean isEqual(java.time.chrono.ChronoLocalDateTime<?>);
     method public abstract boolean isSupported(java.time.temporal.TemporalField);
     method public default boolean isSupported(java.time.temporal.TemporalUnit);
+    method public default java.time.chrono.ChronoLocalDateTime<D> minus(java.time.temporal.TemporalAmount);
+    method public default java.time.chrono.ChronoLocalDateTime<D> minus(long, java.time.temporal.TemporalUnit);
+    method public default java.time.chrono.ChronoLocalDateTime<D> plus(java.time.temporal.TemporalAmount);
     method public abstract java.time.chrono.ChronoLocalDateTime<D> plus(long, java.time.temporal.TemporalUnit);
     method public static java.util.Comparator<java.time.chrono.ChronoLocalDateTime<?>> timeLineOrder();
     method public default long toEpochSecond(java.time.ZoneOffset);
@@ -66216,6 +66472,7 @@
     method public abstract D toLocalDate();
     method public abstract java.time.LocalTime toLocalTime();
     method public abstract java.lang.String toString();
+    method public default java.time.chrono.ChronoLocalDateTime<D> with(java.time.temporal.TemporalAdjuster);
     method public abstract java.time.chrono.ChronoLocalDateTime<D> with(java.time.temporal.TemporalField, long);
   }
 
@@ -66253,6 +66510,9 @@
     method public default boolean isEqual(java.time.chrono.ChronoZonedDateTime<?>);
     method public abstract boolean isSupported(java.time.temporal.TemporalField);
     method public default boolean isSupported(java.time.temporal.TemporalUnit);
+    method public default java.time.chrono.ChronoZonedDateTime<D> minus(java.time.temporal.TemporalAmount);
+    method public default java.time.chrono.ChronoZonedDateTime<D> minus(long, java.time.temporal.TemporalUnit);
+    method public default java.time.chrono.ChronoZonedDateTime<D> plus(java.time.temporal.TemporalAmount);
     method public abstract java.time.chrono.ChronoZonedDateTime<D> plus(long, java.time.temporal.TemporalUnit);
     method public static java.util.Comparator<java.time.chrono.ChronoZonedDateTime<?>> timeLineOrder();
     method public default long toEpochSecond();
@@ -66261,6 +66521,7 @@
     method public abstract java.time.chrono.ChronoLocalDateTime<D> toLocalDateTime();
     method public default java.time.LocalTime toLocalTime();
     method public abstract java.lang.String toString();
+    method public default java.time.chrono.ChronoZonedDateTime<D> with(java.time.temporal.TemporalAdjuster);
     method public abstract java.time.chrono.ChronoZonedDateTime<D> with(java.time.temporal.TemporalField, long);
     method public abstract java.time.chrono.ChronoZonedDateTime<D> withEarlierOffsetAtOverlap();
     method public abstract java.time.chrono.ChronoZonedDateTime<D> withLaterOffsetAtOverlap();
@@ -66327,6 +66588,7 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.HijrahDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
+    method public java.time.chrono.HijrahDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.HijrahDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.HijrahDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.HijrahChronology INSTANCE;
@@ -66338,23 +66600,24 @@
     method public java.time.chrono.HijrahChronology getChronology();
     method public java.time.chrono.HijrahEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
-    method public boolean isLeapYear();
     method public int lengthOfMonth();
-    method public int lengthOfYear();
+    method public java.time.chrono.HijrahDate minus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.HijrahDate minus(long, java.time.temporal.TemporalUnit);
     method public static java.time.chrono.HijrahDate now();
     method public static java.time.chrono.HijrahDate now(java.time.ZoneId);
     method public static java.time.chrono.HijrahDate now(java.time.Clock);
     method public static java.time.chrono.HijrahDate of(int, int, int);
-    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
-    method public long toEpochDay();
+    method public java.time.chrono.HijrahDate plus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.HijrahDate plus(long, java.time.temporal.TemporalUnit);
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
+    method public java.time.chrono.HijrahDate with(java.time.temporal.TemporalField, long);
+    method public java.time.chrono.HijrahDate with(java.time.temporal.TemporalAdjuster);
     method public java.time.chrono.HijrahDate withVariant(java.time.chrono.HijrahChronology);
   }
 
   public final class HijrahEra extends java.lang.Enum implements java.time.chrono.Era {
     method public int getValue();
     method public static java.time.chrono.HijrahEra of(int);
-    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     method public static java.time.chrono.HijrahEra valueOf(java.lang.String);
     method public static final java.time.chrono.HijrahEra[] values();
     enum_constant public static final java.time.chrono.HijrahEra AH;
@@ -66379,6 +66642,7 @@
     method public java.time.Period period(int, int, int);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
+    method public java.time.LocalDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.ZonedDateTime zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.ZonedDateTime zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.IsoChronology INSTANCE;
@@ -66411,6 +66675,7 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.JapaneseDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
+    method public java.time.chrono.JapaneseDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.JapaneseDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.JapaneseDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.JapaneseChronology INSTANCE;
@@ -66422,17 +66687,19 @@
     method public java.time.chrono.JapaneseChronology getChronology();
     method public java.time.chrono.JapaneseEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
-    method public boolean isSupported(java.time.temporal.TemporalField);
     method public int lengthOfMonth();
-    method public int lengthOfYear();
+    method public java.time.chrono.JapaneseDate minus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.JapaneseDate minus(long, java.time.temporal.TemporalUnit);
     method public static java.time.chrono.JapaneseDate now();
     method public static java.time.chrono.JapaneseDate now(java.time.ZoneId);
     method public static java.time.chrono.JapaneseDate now(java.time.Clock);
     method public static java.time.chrono.JapaneseDate of(java.time.chrono.JapaneseEra, int, int, int);
     method public static java.time.chrono.JapaneseDate of(int, int, int);
-    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
-    method public long toEpochDay();
+    method public java.time.chrono.JapaneseDate plus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.JapaneseDate plus(long, java.time.temporal.TemporalUnit);
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
+    method public java.time.chrono.JapaneseDate with(java.time.temporal.TemporalField, long);
+    method public java.time.chrono.JapaneseDate with(java.time.temporal.TemporalAdjuster);
   }
 
   public final class JapaneseEra implements java.time.chrono.Era java.io.Serializable {
@@ -66464,6 +66731,7 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.MinguoDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
+    method public java.time.chrono.MinguoDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.MinguoDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.MinguoDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.MinguoChronology INSTANCE;
@@ -66476,13 +66744,17 @@
     method public java.time.chrono.MinguoEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
     method public int lengthOfMonth();
+    method public java.time.chrono.MinguoDate minus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.MinguoDate minus(long, java.time.temporal.TemporalUnit);
     method public static java.time.chrono.MinguoDate now();
     method public static java.time.chrono.MinguoDate now(java.time.ZoneId);
     method public static java.time.chrono.MinguoDate now(java.time.Clock);
     method public static java.time.chrono.MinguoDate of(int, int, int);
-    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
-    method public long toEpochDay();
+    method public java.time.chrono.MinguoDate plus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.MinguoDate plus(long, java.time.temporal.TemporalUnit);
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
+    method public java.time.chrono.MinguoDate with(java.time.temporal.TemporalField, long);
+    method public java.time.chrono.MinguoDate with(java.time.temporal.TemporalAdjuster);
   }
 
   public final class MinguoEra extends java.lang.Enum implements java.time.chrono.Era {
@@ -66512,6 +66784,7 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.ThaiBuddhistDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
+    method public java.time.chrono.ThaiBuddhistDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.ThaiBuddhistDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.ThaiBuddhistDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.ThaiBuddhistChronology INSTANCE;
@@ -66524,13 +66797,17 @@
     method public java.time.chrono.ThaiBuddhistEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
     method public int lengthOfMonth();
+    method public java.time.chrono.ThaiBuddhistDate minus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.ThaiBuddhistDate minus(long, java.time.temporal.TemporalUnit);
     method public static java.time.chrono.ThaiBuddhistDate now();
     method public static java.time.chrono.ThaiBuddhistDate now(java.time.ZoneId);
     method public static java.time.chrono.ThaiBuddhistDate now(java.time.Clock);
     method public static java.time.chrono.ThaiBuddhistDate of(int, int, int);
-    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
-    method public long toEpochDay();
+    method public java.time.chrono.ThaiBuddhistDate plus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.ThaiBuddhistDate plus(long, java.time.temporal.TemporalUnit);
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
+    method public java.time.chrono.ThaiBuddhistDate with(java.time.temporal.TemporalField, long);
+    method public java.time.chrono.ThaiBuddhistDate with(java.time.temporal.TemporalAdjuster);
   }
 
   public final class ThaiBuddhistEra extends java.lang.Enum implements java.time.chrono.Era {
@@ -66709,7 +66986,6 @@
     method public int checkValidIntValue(long);
     method public long checkValidValue(long);
     method public java.time.temporal.TemporalUnit getBaseUnit();
-    method public java.lang.String getDisplayName(java.util.Locale);
     method public long getFrom(java.time.temporal.TemporalAccessor);
     method public java.time.temporal.TemporalUnit getRangeUnit();
     method public boolean isDateBased();
@@ -66757,7 +67033,6 @@
     method public java.time.Duration getDuration();
     method public boolean isDateBased();
     method public boolean isDurationEstimated();
-    method public boolean isSupportedBy(java.time.temporal.Temporal);
     method public boolean isTimeBased();
     method public static java.time.temporal.ChronoUnit valueOf(java.lang.String);
     method public static final java.time.temporal.ChronoUnit[] values();
@@ -67097,7 +67372,6 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
-    method public java.util.Spliterator<E> spliterator();
   }
 
   public class ArrayList<E> extends java.util.AbstractList implements java.lang.Cloneable java.util.List java.util.RandomAccess java.io.Serializable {
@@ -67108,11 +67382,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 void replaceAll(java.util.function.UnaryOperator<E>);
     method public int size();
-    method public void sort(java.util.Comparator<? super E>);
-    method public java.util.Spliterator<E> spliterator();
     method public void trimToSize();
   }
 
@@ -67483,6 +67753,7 @@
     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 default java.util.Spliterator<E> spliterator();
     method public default java.util.stream.Stream<E> stream();
     method public abstract java.lang.Object[] toArray();
     method public abstract <T> T[] toArray(T[]);
@@ -67823,18 +68094,7 @@
     ctor public HashMap();
     ctor public HashMap(java.util.Map<? extends K, ? extends V>);
     method public java.lang.Object clone();
-    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.Set<java.util.Map.Entry<K, V>> entrySet();
-    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
-    method public V getOrDefault(java.lang.Object, V);
-    method public V merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
-    method public V putIfAbsent(K, V);
-    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>);
   }
 
   public class HashSet<E> extends java.util.AbstractSet implements java.lang.Cloneable java.io.Serializable java.util.Set {
@@ -67845,7 +68105,6 @@
     method public java.lang.Object clone();
     method public java.util.Iterator<E> iterator();
     method public int size();
-    method public java.util.Spliterator<E> spliterator();
   }
 
   public class Hashtable<K, V> extends java.util.Dictionary implements java.lang.Cloneable java.util.Map java.io.Serializable {
@@ -67863,9 +68122,11 @@
     method public boolean containsValue(java.lang.Object);
     method public synchronized java.util.Enumeration<V> elements();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+    method public synchronized boolean equals(java.lang.Object);
     method public synchronized void forEach(java.util.function.BiConsumer<? super K, ? super V>);
     method public synchronized V get(java.lang.Object);
     method public synchronized V getOrDefault(java.lang.Object, V);
+    method public synchronized int hashCode();
     method public synchronized boolean isEmpty();
     method public java.util.Set<K> keySet();
     method public synchronized java.util.Enumeration<K> keys();
@@ -67880,6 +68141,7 @@
     method public synchronized V replace(K, V);
     method public synchronized void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public synchronized int size();
+    method public synchronized java.lang.String toString();
     method public java.util.Collection<V> values();
   }
 
@@ -67889,8 +68151,6 @@
     ctor public IdentityHashMap(java.util.Map<? extends K, ? extends V>);
     method public java.lang.Object clone();
     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 replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
   }
 
   public class IllegalFormatCodePointException extends java.util.IllegalFormatException {
@@ -68001,7 +68261,6 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
-    method public java.util.Spliterator<E> spliterator();
   }
 
   public abstract interface List<E> implements java.util.Collection {
@@ -68624,6 +68883,7 @@
     ctor public SimpleTimeZone(int, java.lang.String, int, int, int, int, int, int, int, int, int, int, int);
     method public int getOffset(int, int, int, int, int, int);
     method public int getRawOffset();
+    method public synchronized int hashCode();
     method public boolean inDaylightTime(java.util.Date);
     method public void setDSTSavings(int);
     method public void setEndRule(int, int, int, int);
@@ -68896,7 +69156,6 @@
     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 java.util.NavigableMap<K, V> headMap(K, boolean);
     method public java.util.SortedMap<K, V> headMap(K);
     method public java.util.Map.Entry<K, V> higherEntry(K);
@@ -68908,9 +69167,6 @@
     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();
-    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.NavigableMap<K, V> subMap(K, boolean, K, boolean);
     method public java.util.SortedMap<K, V> subMap(K, K);
     method public java.util.NavigableMap<K, V> tailMap(K, boolean);
@@ -68938,7 +69194,6 @@
     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.SortedSet<E> subSet(E, E);
     method public java.util.NavigableSet<E> tailSet(E, boolean);
@@ -68975,30 +69230,49 @@
     ctor public Vector(int);
     ctor public Vector();
     ctor public Vector(java.util.Collection<? extends E>);
+    method public synchronized boolean add(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 void addElement(E);
     method public synchronized int capacity();
     method public synchronized java.lang.Object clone();
+    method public synchronized boolean containsAll(java.util.Collection<?>);
     method public synchronized void copyInto(java.lang.Object[]);
     method public synchronized E elementAt(int);
     method public java.util.Enumeration<E> elements();
     method public synchronized void ensureCapacity(int);
+    method public synchronized boolean equals(java.lang.Object);
     method public synchronized E firstElement();
     method public synchronized void forEach(java.util.function.Consumer<? super E>);
     method public synchronized E get(int);
+    method public synchronized int hashCode();
     method public synchronized int indexOf(java.lang.Object, int);
     method public synchronized void insertElementAt(E, int);
+    method public synchronized boolean isEmpty();
+    method public synchronized java.util.Iterator<E> iterator();
     method public synchronized E lastElement();
+    method public synchronized int lastIndexOf(java.lang.Object);
     method public synchronized int lastIndexOf(java.lang.Object, int);
+    method public synchronized java.util.ListIterator<E> listIterator(int);
+    method public synchronized java.util.ListIterator<E> listIterator();
+    method public synchronized E remove(int);
+    method public synchronized boolean removeAll(java.util.Collection<?>);
     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 protected synchronized void removeRange(int, int);
     method public synchronized void replaceAll(java.util.function.UnaryOperator<E>);
+    method public synchronized boolean retainAll(java.util.Collection<?>);
+    method public synchronized E set(int, E);
     method public synchronized void setElementAt(E, int);
     method public synchronized void setSize(int);
     method public synchronized int size();
     method public synchronized void sort(java.util.Comparator<? super E>);
-    method public java.util.Spliterator<E> spliterator();
+    method public synchronized java.util.List<E> subList(int, int);
+    method public synchronized java.lang.Object[] toArray();
+    method public synchronized <T> T[] toArray(T[]);
+    method public synchronized java.lang.String toString();
     method public synchronized void trimToSize();
     field protected int capacityIncrement;
     field protected int elementCount;
@@ -69011,8 +69285,6 @@
     ctor public WeakHashMap();
     ctor public WeakHashMap(java.util.Map<? extends K, ? extends V>);
     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 replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
   }
 
 }
@@ -69047,7 +69319,6 @@
     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;
   }
 
@@ -69238,13 +69509,9 @@
     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 <U> 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>>);
@@ -69253,14 +69520,11 @@
     method public <U> 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 <U> 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 <K> java.util.concurrent.ConcurrentHashMap.KeySetView<K, java.lang.Boolean> newKeySet();
     method public static <K> java.util.concurrent.ConcurrentHashMap.KeySetView<K, java.lang.Boolean> newKeySet(int);
-    method public V putIfAbsent(K, V);
     method public <U> 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> 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>);
@@ -69280,10 +69544,6 @@
     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> U search(long, java.util.function.BiFunction<? super K, ? super V, ? extends U>);
     method public <U> U searchEntries(long, java.util.function.Function<java.util.Map.Entry<K, V>, ? extends U>);
     method public <U> U searchKeys(long, java.util.function.Function<? super K, ? extends U>);
@@ -69344,7 +69604,6 @@
     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<E> extends java.util.AbstractQueue implements java.util.Queue java.io.Serializable {
@@ -69355,7 +69614,6 @@
     method public E peek();
     method public E poll();
     method public int size();
-    method public java.util.Spliterator<E> spliterator();
   }
 
   public abstract interface ConcurrentMap<K, V> implements java.util.Map {
@@ -69387,9 +69645,6 @@
     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();
@@ -69397,25 +69652,18 @@
     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);
     method public K higherKey(K);
+    method public java.util.NavigableSet<K> keySet();
     method public java.util.Map.Entry<K, V> lastEntry();
     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();
-    method public V putIfAbsent(K, V);
-    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);
@@ -69443,7 +69691,6 @@
     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);
@@ -69490,9 +69737,7 @@
     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 {
@@ -69651,6 +69896,7 @@
     method public java.lang.Thread.UncaughtExceptionHandler getUncaughtExceptionHandler();
     method public boolean hasQueuedSubmissions();
     method public <T> T invoke(java.util.concurrent.ForkJoinTask<T>);
+    method public <T> java.util.List<java.util.concurrent.Future<T>> invokeAll(java.util.Collection<? extends java.util.concurrent.Callable<T>>);
     method public boolean isQuiescent();
     method public boolean isShutdown();
     method public boolean isTerminated();
@@ -69660,6 +69906,9 @@
     method public void shutdown();
     method public java.util.List<java.lang.Runnable> shutdownNow();
     method public <T> java.util.concurrent.ForkJoinTask<T> submit(java.util.concurrent.ForkJoinTask<T>);
+    method public <T> java.util.concurrent.ForkJoinTask<T> submit(java.util.concurrent.Callable<T>);
+    method public <T> java.util.concurrent.ForkJoinTask<T> submit(java.lang.Runnable, T);
+    method public java.util.concurrent.ForkJoinTask<?> submit(java.lang.Runnable);
     field public static final java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory defaultForkJoinWorkerThreadFactory;
   }
 
@@ -69783,7 +70032,6 @@
     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;
@@ -69804,7 +70052,6 @@
     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;
   }
 
@@ -69824,7 +70071,6 @@
     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);
@@ -69872,7 +70118,6 @@
     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;
   }
 
@@ -69976,7 +70221,6 @@
     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;
   }
 
@@ -69988,9 +70232,11 @@
     method public static java.util.concurrent.ThreadLocalRandom current();
     method public double nextDouble(double);
     method public double nextDouble(double, double);
+    method public double nextGaussian();
     method public int nextInt(int, int);
     method public long nextLong(long);
     method public long nextLong(long, long);
+    method public void setSeed(long);
   }
 
   public class ThreadPoolExecutor extends java.util.concurrent.AbstractExecutorService {
@@ -70004,6 +70250,7 @@
     method public boolean awaitTermination(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
     method protected void beforeExecute(java.lang.Thread, java.lang.Runnable);
     method public void execute(java.lang.Runnable);
+    method protected void finalize();
     method public int getActiveCount();
     method public long getCompletedTaskCount();
     method public int getCorePoolSize();
@@ -70874,8 +71121,11 @@
     ctor public JarFile(java.io.File) throws java.io.IOException;
     ctor public JarFile(java.io.File, boolean) throws java.io.IOException;
     ctor public JarFile(java.io.File, boolean, int) throws java.io.IOException;
+    method public java.util.Enumeration<java.util.jar.JarEntry> entries();
+    method public synchronized java.io.InputStream getInputStream(java.util.zip.ZipEntry) throws java.io.IOException;
     method public java.util.jar.JarEntry getJarEntry(java.lang.String);
     method public java.util.jar.Manifest getManifest() throws java.io.IOException;
+    method public java.util.stream.Stream<java.util.jar.JarEntry> stream();
     field public static final java.lang.String MANIFEST_NAME = "META-INF/MANIFEST.MF";
   }
 
@@ -70955,6 +71205,8 @@
 
   public class ConsoleHandler extends java.util.logging.StreamHandler {
     ctor public ConsoleHandler();
+    method public void close();
+    method public void publish(java.util.logging.LogRecord);
   }
 
   public class ErrorManager {
@@ -71744,6 +71996,7 @@
     method public int deflate(byte[]);
     method public int deflate(byte[], int, int, int);
     method public void end();
+    method protected void finalize();
     method public void finish();
     method public boolean finished();
     method public int getAdler();
@@ -71776,6 +72029,8 @@
     ctor public DeflaterInputStream(java.io.InputStream);
     ctor public DeflaterInputStream(java.io.InputStream, java.util.zip.Deflater);
     ctor public DeflaterInputStream(java.io.InputStream, java.util.zip.Deflater, int);
+    method public void mark(int);
+    method public void reset() throws java.io.IOException;
     field protected final byte[] buf;
     field protected final java.util.zip.Deflater def;
   }
@@ -71806,6 +72061,7 @@
     ctor public GZIPOutputStream(java.io.OutputStream, int, boolean) throws java.io.IOException;
     ctor public GZIPOutputStream(java.io.OutputStream) throws java.io.IOException;
     ctor public GZIPOutputStream(java.io.OutputStream, boolean) throws java.io.IOException;
+    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     field protected java.util.zip.CRC32 crc;
   }
 
@@ -71813,6 +72069,7 @@
     ctor public Inflater(boolean);
     ctor public Inflater();
     method public void end();
+    method protected void finalize();
     method public boolean finished();
     method public int getAdler();
     method public long getBytesRead();
@@ -71939,6 +72196,7 @@
     ctor public ZipFile(java.io.File, java.nio.charset.Charset) throws java.io.IOException;
     method public void close() throws java.io.IOException;
     method public java.util.Enumeration<? extends java.util.zip.ZipEntry> entries();
+    method protected void finalize() throws java.io.IOException;
     method public java.lang.String getComment();
     method public java.util.zip.ZipEntry getEntry(java.lang.String);
     method public java.io.InputStream getInputStream(java.util.zip.ZipEntry) throws java.io.IOException;
@@ -72045,6 +72303,7 @@
     method public void setComment(java.lang.String);
     method public void setLevel(int);
     method public void setMethod(int);
+    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     field public static final int CENATT = 36; // 0x24
     field public static final int CENATX = 38; // 0x26
     field public static final int CENCOM = 32; // 0x20
@@ -72201,6 +72460,7 @@
 
   public class ExemptionMechanism {
     ctor protected ExemptionMechanism(javax.crypto.ExemptionMechanismSpi, java.security.Provider, java.lang.String);
+    method protected void finalize();
     method public final byte[] genExemptionBlob() throws javax.crypto.ExemptionMechanismException, java.lang.IllegalStateException;
     method public final int genExemptionBlob(byte[]) throws javax.crypto.ExemptionMechanismException, java.lang.IllegalStateException, javax.crypto.ShortBufferException;
     method public final int genExemptionBlob(byte[], int) throws javax.crypto.ExemptionMechanismException, java.lang.IllegalStateException, javax.crypto.ShortBufferException;
@@ -74589,6 +74849,7 @@
     ctor public TransformerException(java.lang.String, java.lang.Throwable);
     ctor public TransformerException(java.lang.String, javax.xml.transform.SourceLocator);
     ctor public TransformerException(java.lang.String, javax.xml.transform.SourceLocator, java.lang.Throwable);
+    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getException();
     method public java.lang.String getLocationAsString();
     method public javax.xml.transform.SourceLocator getLocator();
@@ -74859,6 +75120,7 @@
   public class XPathException extends java.lang.Exception {
     ctor public XPathException(java.lang.String);
     ctor public XPathException(java.lang.Throwable);
+    method public java.lang.Throwable getCause();
   }
 
   public abstract interface XPathExpression {
diff --git a/api/test-current.txt b/api/test-current.txt
index f118965..e6c22ae 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -1935,6 +1935,7 @@
     field public static final int VideoView_error_text_invalid_progressive_playback = 17039381; // 0x1040015
     field public static final int VideoView_error_text_unknown = 17039377; // 0x1040011
     field public static final int VideoView_error_title = 17039378; // 0x1040012
+    field public static final int autofill = 17039386; // 0x104001a
     field public static final int cancel = 17039360; // 0x1040000
     field public static final int copy = 17039361; // 0x1040001
     field public static final int copyUrl = 17039362; // 0x1040002
@@ -3162,6 +3163,7 @@
 
   public final class AnimatorSet extends android.animation.Animator {
     ctor public AnimatorSet();
+    method public android.animation.AnimatorSet clone();
     method public java.util.ArrayList<android.animation.Animator> getChildAnimations();
     method public long getCurrentPlayTime();
     method public long getDuration();
@@ -3280,6 +3282,7 @@
 
   public final class ObjectAnimator extends android.animation.ValueAnimator {
     ctor public ObjectAnimator();
+    method public android.animation.ObjectAnimator clone();
     method public java.lang.String getPropertyName();
     method public java.lang.Object getTarget();
     method public static android.animation.ObjectAnimator ofArgb(java.lang.Object, java.lang.String, int...);
@@ -3305,6 +3308,7 @@
     method public static <T, V> android.animation.ObjectAnimator ofObject(T, android.util.Property<T, V>, android.animation.TypeConverter<android.graphics.PointF, V>, android.graphics.Path);
     method public static android.animation.ObjectAnimator ofPropertyValuesHolder(java.lang.Object, android.animation.PropertyValuesHolder...);
     method public void setAutoCancel(boolean);
+    method public android.animation.ObjectAnimator setDuration(long);
     method public void setProperty(android.util.Property);
     method public void setPropertyName(java.lang.String);
   }
@@ -3386,6 +3390,7 @@
     ctor public ValueAnimator();
     method public void addUpdateListener(android.animation.ValueAnimator.AnimatorUpdateListener);
     method public static boolean areAnimatorsEnabled();
+    method public android.animation.ValueAnimator clone();
     method public float getAnimatedFraction();
     method public java.lang.Object getAnimatedValue();
     method public java.lang.Object getAnimatedValue(java.lang.String);
@@ -4217,6 +4222,12 @@
 
   public class Application extends android.content.ContextWrapper implements android.content.ComponentCallbacks2 {
     ctor public Application();
+    method public android.app.Activity instantiateActivity(java.lang.ClassLoader, java.lang.String, android.content.Intent);
+    method public android.app.backup.BackupAgent instantiateBackupAgent(java.lang.ClassLoader, java.lang.String);
+    method public android.app.Instrumentation instantiateInstrumentation(java.lang.ClassLoader, java.lang.String);
+    method public android.content.ContentProvider instantiateProvider(java.lang.ClassLoader, java.lang.String);
+    method public android.content.BroadcastReceiver instantiateReceiver(java.lang.ClassLoader, java.lang.String, android.content.Intent);
+    method public android.app.Service instantiateService(java.lang.ClassLoader, java.lang.String, android.content.Intent);
     method public void onConfigurationChanged(android.content.res.Configuration);
     method public void onCreate();
     method public void onLowMemory();
@@ -4972,6 +4983,7 @@
     ctor public IntentService(java.lang.String);
     method public android.os.IBinder onBind(android.content.Intent);
     method protected abstract void onHandleIntent(android.content.Intent);
+    method public void onStart(android.content.Intent, int);
     method public void setIntentRedelivery(boolean);
   }
 
@@ -11109,6 +11121,7 @@
 
   public static class AssetFileDescriptor.AutoCloseInputStream extends android.os.ParcelFileDescriptor.AutoCloseInputStream {
     ctor public AssetFileDescriptor.AutoCloseInputStream(android.content.res.AssetFileDescriptor) throws java.io.IOException;
+    method public void mark(int);
   }
 
   public static class AssetFileDescriptor.AutoCloseOutputStream extends android.os.ParcelFileDescriptor.AutoCloseOutputStream {
@@ -11416,6 +11429,7 @@
     method public void copyStringToBuffer(int, android.database.CharArrayBuffer);
     method public void deactivate();
     method public void fillWindow(int, android.database.CursorWindow);
+    method protected void finalize();
     method public byte[] getBlob(int);
     method public int getColumnCount();
     method public int getColumnIndex(java.lang.String);
@@ -13891,6 +13905,7 @@
     method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
+    method public void setDither(boolean);
     method public void setOpacity(int);
     method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
     field public static final float MASK_SIZE = 100.0f;
@@ -13972,6 +13987,7 @@
     method public void setAlpha(int);
     method public void setAntiAlias(boolean);
     method public void setColorFilter(android.graphics.ColorFilter);
+    method public void setDither(boolean);
     method public void setGravity(int);
     method public void setMipMap(boolean);
     method public void setTargetDensity(android.graphics.Canvas);
@@ -14099,6 +14115,7 @@
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
     method protected void setConstantState(android.graphics.drawable.DrawableContainer.DrawableContainerState);
+    method public void setDither(boolean);
     method public void setEnterFadeDuration(int);
     method public void setExitFadeDuration(int);
     method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
@@ -14165,6 +14182,7 @@
     method public void setColors(int[]);
     method public void setCornerRadii(float[]);
     method public void setCornerRadius(float);
+    method public void setDither(boolean);
     method public void setGradientCenter(float, float);
     method public void setGradientRadius(float);
     method public void setGradientType(int);
@@ -14259,6 +14277,7 @@
     method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
+    method public void setDither(boolean);
     method public void setDrawable(int, android.graphics.drawable.Drawable);
     method public boolean setDrawableByLayerId(int, android.graphics.drawable.Drawable);
     method public void setId(int, int);
@@ -14299,6 +14318,7 @@
     method public android.graphics.Paint getPaint();
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
+    method public void setDither(boolean);
     method public void setTargetDensity(android.graphics.Canvas);
     method public void setTargetDensity(android.util.DisplayMetrics);
     method public void setTargetDensity(int);
@@ -14361,6 +14381,7 @@
     method protected void onDraw(android.graphics.drawable.shapes.Shape, android.graphics.Canvas, android.graphics.Paint);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
+    method public void setDither(boolean);
     method public void setIntrinsicHeight(int);
     method public void setIntrinsicWidth(int);
     method public void setPadding(int, int, int, int);
@@ -14403,27 +14424,32 @@
 
   public class ArcShape extends android.graphics.drawable.shapes.RectShape {
     ctor public ArcShape(float, float);
+    method public android.graphics.drawable.shapes.ArcShape clone() throws java.lang.CloneNotSupportedException;
     method public final float getStartAngle();
     method public final float getSweepAngle();
   }
 
   public class OvalShape extends android.graphics.drawable.shapes.RectShape {
     ctor public OvalShape();
+    method public android.graphics.drawable.shapes.OvalShape clone() throws java.lang.CloneNotSupportedException;
   }
 
   public class PathShape extends android.graphics.drawable.shapes.Shape {
     ctor public PathShape(android.graphics.Path, float, float);
+    method public android.graphics.drawable.shapes.PathShape clone() throws java.lang.CloneNotSupportedException;
     method public void draw(android.graphics.Canvas, android.graphics.Paint);
   }
 
   public class RectShape extends android.graphics.drawable.shapes.Shape {
     ctor public RectShape();
+    method public android.graphics.drawable.shapes.RectShape clone() throws java.lang.CloneNotSupportedException;
     method public void draw(android.graphics.Canvas, android.graphics.Paint);
     method protected final android.graphics.RectF rect();
   }
 
   public class RoundRectShape extends android.graphics.drawable.shapes.RectShape {
     ctor public RoundRectShape(float[], android.graphics.RectF, float[]);
+    method public android.graphics.drawable.shapes.RoundRectShape clone() throws java.lang.CloneNotSupportedException;
   }
 
   public abstract class Shape implements java.lang.Cloneable {
@@ -14508,6 +14534,7 @@
     method public final void autoFocus(android.hardware.Camera.AutoFocusCallback);
     method public final void cancelAutoFocus();
     method public final boolean enableShutterSound(boolean);
+    method protected void finalize();
     method public static void getCameraInfo(int, android.hardware.Camera.CameraInfo);
     method public static int getNumberOfCameras();
     method public android.hardware.Camera.Parameters getParameters();
@@ -15117,6 +15144,7 @@
     method public <T> T get(android.hardware.camera2.CameraCharacteristics.Key<T>);
     method public java.util.List<android.hardware.camera2.CaptureRequest.Key<?>> getAvailableCaptureRequestKeys();
     method public java.util.List<android.hardware.camera2.CaptureResult.Key<?>> getAvailableCaptureResultKeys();
+    method public java.util.List<android.hardware.camera2.CameraCharacteristics.Key<?>> getKeys();
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> CONTROL_AE_AVAILABLE_ANTIBANDING_MODES;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> CONTROL_AE_AVAILABLE_MODES;
@@ -15477,6 +15505,7 @@
   public final class CaptureRequest extends android.hardware.camera2.CameraMetadata implements android.os.Parcelable {
     method public int describeContents();
     method public <T> T get(android.hardware.camera2.CaptureRequest.Key<T>);
+    method public java.util.List<android.hardware.camera2.CaptureRequest.Key<?>> getKeys();
     method public java.lang.Object getTag();
     method public boolean isReprocess();
     method public void writeToParcel(android.os.Parcel, int);
@@ -15555,6 +15584,7 @@
   public class CaptureResult extends android.hardware.camera2.CameraMetadata {
     method public <T> T get(android.hardware.camera2.CaptureResult.Key<T>);
     method public long getFrameNumber();
+    method public java.util.List<android.hardware.camera2.CaptureResult.Key<?>> getKeys();
     method public android.hardware.camera2.CaptureRequest getRequest();
     method public int getSequenceId();
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Boolean> BLACK_LEVEL_LOCK;
@@ -17988,6 +18018,7 @@
   }
 
   public class DateIntervalFormat extends android.icu.text.UFormat {
+    method public synchronized java.lang.Object clone();
     method public final java.lang.StringBuffer format(java.lang.Object, java.lang.StringBuffer, java.text.FieldPosition);
     method public final synchronized java.lang.StringBuffer format(android.icu.util.DateInterval, java.lang.StringBuffer, java.text.FieldPosition);
     method public final synchronized java.lang.StringBuffer format(android.icu.util.Calendar, android.icu.util.Calendar, java.lang.StringBuffer, java.text.FieldPosition);
@@ -18771,6 +18802,7 @@
 
   public final class RuleBasedCollator extends android.icu.text.Collator {
     ctor public RuleBasedCollator(java.lang.String) throws java.lang.Exception;
+    method public android.icu.text.RuleBasedCollator cloneAsThawed();
     method public int compare(java.lang.String, java.lang.String);
     method public android.icu.text.CollationElementIterator getCollationElementIterator(java.lang.String);
     method public android.icu.text.CollationElementIterator getCollationElementIterator(java.text.CharacterIterator);
@@ -18797,6 +18829,7 @@
     method public void setFrenchCollation(boolean);
     method public void setFrenchCollationDefault();
     method public void setLowerCaseFirst(boolean);
+    method public android.icu.text.RuleBasedCollator setMaxVariable(int);
     method public void setNumericCollation(boolean);
     method public void setNumericCollationDefault();
     method public void setStrengthDefault();
@@ -21375,6 +21408,7 @@
     ctor public AudioRecord(int, int, int, int, int) throws java.lang.IllegalArgumentException;
     method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
     method public deprecated void addOnRoutingChangedListener(android.media.AudioRecord.OnRoutingChangedListener, android.os.Handler);
+    method protected void finalize();
     method public int getAudioFormat();
     method public int getAudioSessionId();
     method public int getAudioSource();
@@ -21479,6 +21513,7 @@
     method public deprecated void addOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener, android.os.Handler);
     method public int attachAuxEffect(int);
     method public android.media.VolumeShaper createVolumeShaper(android.media.VolumeShaper.Configuration);
+    method protected void finalize();
     method public void flush();
     method public int getAudioFormat();
     method public int getAudioSessionId();
@@ -21877,6 +21912,7 @@
     method public boolean clearQueue();
     method public java.lang.Object clone() throws java.lang.CloneNotSupportedException;
     method public boolean closeJetFile();
+    method protected void finalize();
     method public static android.media.JetPlayer getJetPlayer();
     method public static int getMaxTracks();
     method public boolean loadJetFile(java.lang.String);
@@ -21916,6 +21952,7 @@
     ctor public MediaCas(int) throws android.media.MediaCasException.UnsupportedCasException;
     method public void close();
     method public static android.media.MediaCas.PluginDescriptor[] enumeratePlugins();
+    method protected void finalize();
     method public static boolean isSystemIdSupported(int);
     method public android.media.MediaCas.Session openSession() throws android.media.MediaCasException;
     method public void processEmm(byte[], int, int) throws android.media.MediaCasException;
@@ -21972,6 +22009,7 @@
     method public static android.view.Surface createPersistentInputSurface();
     method public final int dequeueInputBuffer(long);
     method public final int dequeueOutputBuffer(android.media.MediaCodec.BufferInfo, long);
+    method protected void finalize();
     method public final void flush();
     method public android.media.MediaCodecInfo getCodecInfo();
     method public java.nio.ByteBuffer getInputBuffer(int);
@@ -22383,6 +22421,7 @@
 
   public final class MediaCrypto {
     ctor public MediaCrypto(java.util.UUID, byte[]) throws android.media.MediaCryptoException;
+    method protected void finalize();
     method public static final boolean isCryptoSchemeSupported(java.util.UUID);
     method public final void release();
     method public final boolean requiresSecureDecoderComponent(java.lang.String);
@@ -22403,6 +22442,7 @@
     ctor public MediaDescrambler(int) throws android.media.MediaCasException.UnsupportedCasException;
     method public void close();
     method public final int descramble(java.nio.ByteBuffer, java.nio.ByteBuffer, android.media.MediaCodec.CryptoInfo);
+    method protected void finalize();
     method public final boolean requiresSecureDecoderComponent(java.lang.String);
     method public final void setMediaCasSession(android.media.MediaCas.Session);
   }
@@ -22445,6 +22485,7 @@
   public final class MediaDrm {
     ctor public MediaDrm(java.util.UUID) throws android.media.UnsupportedSchemeException;
     method public void closeSession(byte[]);
+    method protected void finalize();
     method public android.media.MediaDrm.CryptoSession getCryptoSession(byte[], java.lang.String, java.lang.String);
     method public android.media.MediaDrm.KeyRequest getKeyRequest(byte[], byte[], java.lang.String, int, java.util.HashMap<java.lang.String, java.lang.String>) throws android.media.NotProvisionedException;
     method public byte[] getPropertyByteArray(java.lang.String);
@@ -22541,6 +22582,7 @@
   public final class MediaExtractor {
     ctor public MediaExtractor();
     method public boolean advance();
+    method protected void finalize();
     method public long getCachedDuration();
     method public android.media.MediaExtractor.CasInfo getCasInfo(int);
     method public android.media.DrmInitData getDrmInitData();
@@ -22842,6 +22884,7 @@
     method public static android.media.MediaPlayer create(android.content.Context, int, android.media.AudioAttributes, int);
     method public android.media.VolumeShaper createVolumeShaper(android.media.VolumeShaper.Configuration);
     method public void deselectTrack(int) throws java.lang.IllegalStateException;
+    method protected void finalize();
     method public int getAudioSessionId();
     method public int getCurrentPosition();
     method public android.media.MediaPlayer.DrmInfo getDrmInfo();
@@ -23037,6 +23080,7 @@
 
   public class MediaRecorder {
     ctor public MediaRecorder();
+    method protected void finalize();
     method public static final int getAudioSourceMax();
     method public int getMaxAmplitude() throws java.lang.IllegalStateException;
     method public android.os.PersistableBundle getMetrics();
@@ -23308,6 +23352,7 @@
   public final class MediaSync {
     ctor public MediaSync();
     method public final android.view.Surface createInputSurface();
+    method protected void finalize();
     method public void flush();
     method public android.media.PlaybackParams getPlaybackParams();
     method public android.media.SyncParams getSyncParams();
@@ -23427,6 +23472,10 @@
 
   public deprecated class RemoteControlClient.MetadataEditor extends android.media.MediaMetadataEditor {
     method public synchronized void apply();
+    method public synchronized android.media.RemoteControlClient.MetadataEditor putBitmap(int, android.graphics.Bitmap) throws java.lang.IllegalArgumentException;
+    method public synchronized android.media.RemoteControlClient.MetadataEditor putLong(int, long) throws java.lang.IllegalArgumentException;
+    method public synchronized android.media.RemoteControlClient.MetadataEditor putObject(int, java.lang.Object) throws java.lang.IllegalArgumentException;
+    method public synchronized android.media.RemoteControlClient.MetadataEditor putString(int, java.lang.String) throws java.lang.IllegalArgumentException;
     field public static final int BITMAP_KEY_ARTWORK = 100; // 0x64
   }
 
@@ -23473,6 +23522,7 @@
   }
 
   public class Ringtone {
+    method protected void finalize();
     method public android.media.AudioAttributes getAudioAttributes();
     method public deprecated int getStreamType();
     method public java.lang.String getTitle(android.content.Context);
@@ -23526,6 +23576,7 @@
     ctor public deprecated SoundPool(int, int, int);
     method public final void autoPause();
     method public final void autoResume();
+    method protected void finalize();
     method public int load(java.lang.String, int);
     method public int load(android.content.Context, int, int);
     method public int load(android.content.res.AssetFileDescriptor, int);
@@ -23594,6 +23645,7 @@
 
   public class ToneGenerator {
     ctor public ToneGenerator(int, int);
+    method protected void finalize();
     method public final int getAudioSessionId();
     method public void release();
     method public boolean startTone(int);
@@ -23726,6 +23778,7 @@
   public final class VolumeShaper implements java.lang.AutoCloseable {
     method public void apply(android.media.VolumeShaper.Operation);
     method public void close();
+    method protected void finalize();
     method public float getVolume();
     method public void replace(android.media.VolumeShaper.Configuration, android.media.VolumeShaper.Operation, boolean);
   }
@@ -23780,6 +23833,7 @@
   }
 
   public class AudioEffect {
+    method protected void finalize();
     method public android.media.audiofx.AudioEffect.Descriptor getDescriptor() throws java.lang.IllegalStateException;
     method public boolean getEnabled() throws java.lang.IllegalStateException;
     method public int getId() throws java.lang.IllegalStateException;
@@ -24032,6 +24086,7 @@
 
   public class Visualizer {
     ctor public Visualizer(int) throws java.lang.RuntimeException, java.lang.UnsupportedOperationException;
+    method protected void finalize();
     method public int getCaptureSize() throws java.lang.IllegalStateException;
     method public static int[] getCaptureSizeRange();
     method public boolean getEnabled();
@@ -30695,6 +30750,7 @@
     method public void putStringArrayList(java.lang.String, java.util.ArrayList<java.lang.String>);
     method public void readFromParcel(android.os.Parcel);
     method public void setClassLoader(java.lang.ClassLoader);
+    method public synchronized java.lang.String toString();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.os.Bundle> CREATOR;
     field public static final android.os.Bundle EMPTY;
@@ -30925,6 +30981,7 @@
   public abstract class FileObserver {
     ctor public FileObserver(java.lang.String);
     ctor public FileObserver(java.lang.String, int);
+    method protected void finalize();
     method public abstract void onEvent(int, java.lang.String);
     method public void startWatching();
     method public void stopWatching();
@@ -31099,6 +31156,7 @@
     ctor public MemoryFile(java.lang.String, int) throws java.io.IOException;
     method public synchronized boolean allowPurging(boolean) throws java.io.IOException;
     method public void close();
+    method protected void finalize();
     method public java.io.InputStream getInputStream();
     method public java.io.OutputStream getOutputStream();
     method public boolean isPurgingAllowed();
@@ -31398,6 +31456,7 @@
     method public int describeContents();
     method public android.os.PersistableBundle getPersistableBundle(java.lang.String);
     method public void putPersistableBundle(java.lang.String, android.os.PersistableBundle);
+    method public synchronized java.lang.String toString();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.os.PersistableBundle> CREATOR;
     field public static final android.os.PersistableBundle EMPTY;
@@ -31550,6 +31609,7 @@
     method public static android.os.StrictMode.VmPolicy getVmPolicy();
     method public static void noteSlowCall(java.lang.String);
     method public static void setThreadPolicy(android.os.StrictMode.ThreadPolicy);
+    method public static void setViolationListener(android.os.StrictMode.ViolationListener);
     method public static void setVmPolicy(android.os.StrictMode.VmPolicy);
   }
 
@@ -31583,6 +31643,10 @@
     method public android.os.StrictMode.ThreadPolicy.Builder permitUnbufferedIo();
   }
 
+  public static abstract interface StrictMode.ViolationListener {
+    method public abstract void onViolation(java.lang.String);
+  }
+
   public static final class StrictMode.VmPolicy {
     field public static final android.os.StrictMode.VmPolicy LAX;
   }
@@ -35744,6 +35808,7 @@
     method public static android.renderscript.AllocationAdapter create1D(android.renderscript.RenderScript, android.renderscript.Allocation);
     method public static android.renderscript.AllocationAdapter create2D(android.renderscript.RenderScript, android.renderscript.Allocation);
     method public static android.renderscript.AllocationAdapter createTyped(android.renderscript.RenderScript, android.renderscript.Allocation, android.renderscript.Type);
+    method public synchronized void resize(int);
     method public void setFace(android.renderscript.Type.CubemapFace);
     method public void setLOD(int);
     method public void setX(int);
@@ -40499,6 +40564,7 @@
 
   public static deprecated class SmsMessage.SubmitPdu {
     ctor public deprecated SmsMessage.SubmitPdu();
+    method public deprecated java.lang.String toString();
     field public deprecated byte[] encodedMessage;
     field public deprecated byte[] encodedScAddress;
   }
@@ -40562,6 +40628,7 @@
     method public java.util.List<junit.framework.TestCase> getTestCases();
     method public java.lang.String getTestClassName();
     method public junit.framework.TestResult getTestResult();
+    method protected java.lang.Class loadSuiteClass(java.lang.String) throws java.lang.ClassNotFoundException;
     method protected void runFailed(java.lang.String);
     method public void runTest();
     method public void runTest(junit.framework.TestResult);
@@ -40822,10 +40889,12 @@
     ctor protected MockContentProvider();
     ctor public MockContentProvider(android.content.Context);
     ctor public MockContentProvider(android.content.Context, java.lang.String, java.lang.String, android.content.pm.PathPermission[]);
+    method public android.content.ContentProviderResult[] applyBatch(java.util.ArrayList<android.content.ContentProviderOperation>);
     method public int delete(android.net.Uri, java.lang.String, java.lang.String[]);
     method public java.lang.String getType(android.net.Uri);
     method public android.net.Uri insert(android.net.Uri, android.content.ContentValues);
     method public boolean onCreate();
+    method public android.content.res.AssetFileDescriptor openTypedAssetFile(android.net.Uri, java.lang.String, android.os.Bundle);
     method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
     method public int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]);
   }
@@ -41099,6 +41168,10 @@
 
   public deprecated class MockResources extends android.content.res.Resources {
     ctor public MockResources();
+    method public int getColor(int) throws android.content.res.Resources.NotFoundException;
+    method public android.content.res.ColorStateList getColorStateList(int) throws android.content.res.Resources.NotFoundException;
+    method public android.graphics.drawable.Drawable getDrawable(int) throws android.content.res.Resources.NotFoundException;
+    method public void updateConfiguration(android.content.res.Configuration, android.util.DisplayMetrics);
   }
 
 }
@@ -42347,6 +42420,7 @@
 
   public abstract class MetricAffectingSpan extends android.text.style.CharacterStyle implements android.text.style.UpdateLayout {
     ctor public MetricAffectingSpan();
+    method public android.text.style.MetricAffectingSpan getUnderlying();
     method public abstract void updateMeasureState(android.text.TextPaint);
   }
 
@@ -43028,14 +43102,28 @@
   public class TransitionSet extends android.transition.Transition {
     ctor public TransitionSet();
     ctor public TransitionSet(android.content.Context, android.util.AttributeSet);
+    method public android.transition.TransitionSet addListener(android.transition.Transition.TransitionListener);
+    method public android.transition.TransitionSet addTarget(android.view.View);
+    method public android.transition.TransitionSet addTarget(int);
+    method public android.transition.TransitionSet addTarget(java.lang.String);
+    method public android.transition.TransitionSet addTarget(java.lang.Class);
     method public android.transition.TransitionSet addTransition(android.transition.Transition);
     method public void captureEndValues(android.transition.TransitionValues);
     method public void captureStartValues(android.transition.TransitionValues);
+    method public android.transition.TransitionSet clone();
     method public int getOrdering();
     method public android.transition.Transition getTransitionAt(int);
     method public int getTransitionCount();
+    method public android.transition.TransitionSet removeListener(android.transition.Transition.TransitionListener);
+    method public android.transition.TransitionSet removeTarget(int);
+    method public android.transition.TransitionSet removeTarget(android.view.View);
+    method public android.transition.TransitionSet removeTarget(java.lang.Class);
+    method public android.transition.TransitionSet removeTarget(java.lang.String);
     method public android.transition.TransitionSet removeTransition(android.transition.Transition);
+    method public android.transition.TransitionSet setDuration(long);
+    method public android.transition.TransitionSet setInterpolator(android.animation.TimeInterpolator);
     method public android.transition.TransitionSet setOrdering(int);
+    method public android.transition.TransitionSet setStartDelay(long);
     field public static final int ORDERING_SEQUENTIAL = 1; // 0x1
     field public static final int ORDERING_TOGETHER = 0; // 0x0
   }
@@ -43200,6 +43288,9 @@
 
   public class Base64InputStream extends java.io.FilterInputStream {
     ctor public Base64InputStream(java.io.InputStream, int);
+    method public int available();
+    method public void mark(int);
+    method public void reset();
   }
 
   public class Base64OutputStream extends java.io.FilterOutputStream {
@@ -45487,6 +45578,7 @@
     method public android.graphics.Canvas lockCanvas();
     method public android.graphics.Canvas lockCanvas(android.graphics.Rect);
     method protected final void onDraw(android.graphics.Canvas);
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable);
     method public void setOpaque(boolean);
     method public void setSurfaceTexture(android.graphics.SurfaceTexture);
     method public void setSurfaceTextureListener(android.view.TextureView.SurfaceTextureListener);
@@ -46519,6 +46611,7 @@
     method public int getLayoutMode();
     method public android.animation.LayoutTransition getLayoutTransition();
     method public int getNestedScrollAxes();
+    method public android.view.ViewGroupOverlay getOverlay();
     method public int getPersistentDrawingCache();
     method public boolean getTouchscreenBlocksFocus();
     method public int indexOfChild(android.view.View);
@@ -47804,6 +47897,7 @@
     ctor public Animation(android.content.Context, android.util.AttributeSet);
     method protected void applyTransformation(float, android.view.animation.Transformation);
     method public void cancel();
+    method protected android.view.animation.Animation clone() throws java.lang.CloneNotSupportedException;
     method public long computeDurationHint();
     method protected void ensureInterpolator();
     method public int getBackgroundColor();
@@ -47875,6 +47969,7 @@
     ctor public AnimationSet(android.content.Context, android.util.AttributeSet);
     ctor public AnimationSet(boolean);
     method public void addAnimation(android.view.animation.Animation);
+    method protected android.view.animation.AnimationSet clone() throws java.lang.CloneNotSupportedException;
     method public java.util.List<android.view.animation.Animation> getAnimations();
   }
 
@@ -48725,6 +48820,10 @@
   public final deprecated class CookieSyncManager extends android.webkit.WebSyncManager {
     method public static android.webkit.CookieSyncManager createInstance(android.content.Context);
     method public static android.webkit.CookieSyncManager getInstance();
+    method public deprecated void resetSync();
+    method public deprecated void startSync();
+    method public deprecated void stopSync();
+    method public deprecated void sync();
     method protected deprecated void syncFromRamToFlash();
     field protected static final java.lang.String LOGTAG = "websync";
     field protected android.webkit.WebViewDatabase mDataBase;
@@ -49277,6 +49376,7 @@
     method public void setWebChromeClient(android.webkit.WebChromeClient);
     method public static void setWebContentsDebuggingEnabled(boolean);
     method public void setWebViewClient(android.webkit.WebViewClient);
+    method public deprecated boolean shouldDelayChildPressedState();
     method public deprecated boolean showFindDialog(java.lang.String, boolean);
     method public static void shutdownSafeBrowsing();
     method public void stopLoading();
@@ -49409,6 +49509,7 @@
     method public void clearTextFilter();
     method public void deferNotifyDataSetChanged();
     method public void fling(int);
+    method public android.widget.AbsListView.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public int getCacheColorHint();
     method public int getCheckedItemCount();
     method public long[] getCheckedItemIds();
@@ -49575,6 +49676,9 @@
     ctor public ActionMenuView(android.content.Context);
     ctor public ActionMenuView(android.content.Context, android.util.AttributeSet);
     method public void dismissPopupMenus();
+    method protected android.widget.ActionMenuView.LayoutParams generateDefaultLayoutParams();
+    method public android.widget.ActionMenuView.LayoutParams generateLayoutParams(android.util.AttributeSet);
+    method protected android.widget.ActionMenuView.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public android.view.Menu getMenu();
     method public android.graphics.drawable.Drawable getOverflowIcon();
     method public int getPopupTheme();
@@ -49750,7 +49854,6 @@
     method public void addAll(T...);
     method public void clear();
     method public static android.widget.ArrayAdapter<java.lang.CharSequence> createFromResource(android.content.Context, int, int);
-    method public java.lang.CharSequence[] getAutofillOptions();
     method public android.content.Context getContext();
     method public int getCount();
     method public android.content.res.Resources.Theme getDropDownViewTheme();
@@ -49840,6 +49943,7 @@
     method public void notifyDataSetChanged();
     method public void notifyDataSetInvalidated();
     method public void registerDataSetObserver(android.database.DataSetObserver);
+    method public void setAutofillOptions(java.lang.CharSequence...);
     method public void unregisterDataSetObserver(android.database.DataSetObserver);
   }
 
@@ -50122,6 +50226,7 @@
     ctor public EditText(android.content.Context, android.util.AttributeSet, int);
     ctor public EditText(android.content.Context, android.util.AttributeSet, int, int);
     method public void extendSelection(int);
+    method public android.text.Editable getText();
     method public void selectAll();
     method public void setSelection(int, int);
     method public void setSelection(int);
@@ -50243,6 +50348,8 @@
     ctor public FrameLayout(android.content.Context, android.util.AttributeSet);
     ctor public FrameLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public FrameLayout(android.content.Context, android.util.AttributeSet, int, int);
+    method protected android.widget.FrameLayout.LayoutParams generateDefaultLayoutParams();
+    method public android.widget.FrameLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public deprecated boolean getConsiderGoneChildrenWhenMeasuring();
     method public boolean getMeasureAllChildren();
     method protected void onLayout(boolean, int, int, int, int);
@@ -50289,6 +50396,9 @@
     ctor public GridLayout(android.content.Context, android.util.AttributeSet);
     ctor public GridLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public GridLayout(android.content.Context, android.util.AttributeSet, int, int);
+    method protected android.widget.GridLayout.LayoutParams generateDefaultLayoutParams();
+    method public android.widget.GridLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
+    method protected android.widget.GridLayout.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public int getAlignmentMode();
     method public int getColumnCount();
     method public int getOrientation();
@@ -50501,6 +50611,9 @@
     ctor public LinearLayout(android.content.Context, android.util.AttributeSet);
     ctor public LinearLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public LinearLayout(android.content.Context, android.util.AttributeSet, int, int);
+    method protected android.widget.LinearLayout.LayoutParams generateDefaultLayoutParams();
+    method public android.widget.LinearLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
+    method protected android.widget.LinearLayout.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public int getBaselineAlignedChildIndex();
     method public android.graphics.drawable.Drawable getDividerDrawable();
     method public int getDividerPadding();
@@ -50889,6 +51002,8 @@
     method public final synchronized void incrementSecondaryProgressBy(int);
     method public boolean isAnimating();
     method public synchronized boolean isIndeterminate();
+    method protected synchronized void onDraw(android.graphics.Canvas);
+    method protected synchronized void onMeasure(int, int);
     method public void onRestoreInstanceState(android.os.Parcelable);
     method public android.os.Parcelable onSaveInstanceState();
     method public synchronized void setIndeterminate(boolean);
@@ -50944,6 +51059,7 @@
     ctor public RadioGroup(android.content.Context, android.util.AttributeSet);
     method public void check(int);
     method public void clearCheck();
+    method public android.widget.RadioGroup.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public int getCheckedRadioButtonId();
     method public void setOnCheckedChangeListener(android.widget.RadioGroup.OnCheckedChangeListener);
   }
@@ -50986,6 +51102,7 @@
     ctor public RelativeLayout(android.content.Context, android.util.AttributeSet);
     ctor public RelativeLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public RelativeLayout(android.content.Context, android.util.AttributeSet, int, int);
+    method public android.widget.RelativeLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public int getGravity();
     method protected void onLayout(boolean, int, int, int, int);
     method public void setGravity(int);
@@ -51530,6 +51647,7 @@
   public class TableLayout extends android.widget.LinearLayout {
     ctor public TableLayout(android.content.Context);
     ctor public TableLayout(android.content.Context, android.util.AttributeSet);
+    method public android.widget.TableLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public boolean isColumnCollapsed(int);
     method public boolean isColumnShrinkable(int);
     method public boolean isColumnStretchable(int);
@@ -51554,6 +51672,7 @@
   public class TableRow extends android.widget.LinearLayout {
     ctor public TableRow(android.content.Context);
     ctor public TableRow(android.content.Context, android.util.AttributeSet);
+    method public android.widget.TableRow.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public android.view.View getVirtualChildAt(int);
     method public int getVirtualChildCount();
   }
@@ -51902,6 +52021,7 @@
     ctor public ToggleButton(android.content.Context);
     method public java.lang.CharSequence getTextOff();
     method public java.lang.CharSequence getTextOn();
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable);
     method public void setTextOff(java.lang.CharSequence);
     method public void setTextOn(java.lang.CharSequence);
   }
@@ -51913,6 +52033,9 @@
     ctor public Toolbar(android.content.Context, android.util.AttributeSet, int, int);
     method public void collapseActionView();
     method public void dismissPopupMenus();
+    method protected android.widget.Toolbar.LayoutParams generateDefaultLayoutParams();
+    method public android.widget.Toolbar.LayoutParams generateLayoutParams(android.util.AttributeSet);
+    method protected android.widget.Toolbar.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public int getContentInsetEnd();
     method public int getContentInsetEndWithActions();
     method public int getContentInsetLeft();
@@ -52435,6 +52558,8 @@
   public class BaseDexClassLoader extends java.lang.ClassLoader {
     ctor public BaseDexClassLoader(java.lang.String, java.io.File, java.lang.String, java.lang.ClassLoader);
     method public java.lang.String findLibrary(java.lang.String);
+    method protected java.util.Enumeration<java.net.URL> findResources(java.lang.String);
+    method protected synchronized java.lang.Package getPackage(java.lang.String);
   }
 
   public class DexClassLoader extends dalvik.system.BaseDexClassLoader {
@@ -52656,6 +52781,10 @@
   public class BufferedInputStream extends java.io.FilterInputStream {
     ctor public BufferedInputStream(java.io.InputStream);
     ctor public BufferedInputStream(java.io.InputStream, int);
+    method public synchronized int available() throws java.io.IOException;
+    method public synchronized int read() throws java.io.IOException;
+    method public synchronized int read(byte[], int, int) throws java.io.IOException;
+    method public synchronized long skip(long) throws java.io.IOException;
     field protected volatile byte[] buf;
     field protected int count;
     field protected int marklimit;
@@ -52666,6 +52795,9 @@
   public class BufferedOutputStream extends java.io.FilterOutputStream {
     ctor public BufferedOutputStream(java.io.OutputStream);
     ctor public BufferedOutputStream(java.io.OutputStream, int);
+    method public synchronized void flush() throws java.io.IOException;
+    method public synchronized void write(int) throws java.io.IOException;
+    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     field protected byte[] buf;
     field protected int count;
   }
@@ -52691,7 +52823,12 @@
   public class ByteArrayInputStream extends java.io.InputStream {
     ctor public ByteArrayInputStream(byte[]);
     ctor public ByteArrayInputStream(byte[], int, int);
+    method public synchronized int available();
+    method public void mark(int);
     method public synchronized int read();
+    method public synchronized int read(byte[], int, int);
+    method public synchronized void reset();
+    method public synchronized long skip(long);
     field protected byte[] buf;
     field protected int count;
     field protected int mark;
@@ -52704,9 +52841,11 @@
     method public synchronized void reset();
     method public synchronized int size();
     method public synchronized byte[] toByteArray();
+    method public synchronized java.lang.String toString();
     method public synchronized java.lang.String toString(java.lang.String) throws java.io.UnsupportedEncodingException;
     method public deprecated synchronized java.lang.String toString(int);
     method public synchronized void write(int);
+    method public synchronized void write(byte[], int, int);
     method public synchronized void writeTo(java.io.OutputStream) throws java.io.IOException;
     field protected byte[] buf;
     field protected int count;
@@ -52726,12 +52865,17 @@
   public class CharArrayWriter extends java.io.Writer {
     ctor public CharArrayWriter();
     ctor public CharArrayWriter(int);
+    method public java.io.CharArrayWriter append(java.lang.CharSequence);
+    method public java.io.CharArrayWriter append(java.lang.CharSequence, int, int);
+    method public java.io.CharArrayWriter append(char);
     method public void close();
     method public void flush();
     method public void reset();
     method public int size();
     method public char[] toCharArray();
+    method public void write(int);
     method public void write(char[], int, int);
+    method public void write(java.lang.String, int, int);
     method public void writeTo(java.io.Writer) throws java.io.IOException;
     field protected char[] buf;
     field protected int count;
@@ -52818,6 +52962,8 @@
   public class DataOutputStream extends java.io.FilterOutputStream implements java.io.DataOutput {
     ctor public DataOutputStream(java.io.OutputStream);
     method public final int size();
+    method public synchronized void write(int) throws java.io.IOException;
+    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     method public final void writeBoolean(boolean) throws java.io.IOException;
     method public final void writeByte(int) throws java.io.IOException;
     method public final void writeBytes(java.lang.String) throws java.io.IOException;
@@ -52917,6 +53063,7 @@
     ctor public FileInputStream(java.lang.String) throws java.io.FileNotFoundException;
     ctor public FileInputStream(java.io.File) throws java.io.FileNotFoundException;
     ctor public FileInputStream(java.io.FileDescriptor);
+    method protected void finalize() throws java.io.IOException;
     method public java.nio.channels.FileChannel getChannel();
     method public final java.io.FileDescriptor getFD() throws java.io.IOException;
     method public int read() throws java.io.IOException;
@@ -52933,6 +53080,7 @@
     ctor public FileOutputStream(java.io.File) throws java.io.FileNotFoundException;
     ctor public FileOutputStream(java.io.File, boolean) throws java.io.FileNotFoundException;
     ctor public FileOutputStream(java.io.FileDescriptor);
+    method protected void finalize() throws java.io.IOException;
     method public java.nio.channels.FileChannel getChannel();
     method public final java.io.FileDescriptor getFD() throws java.io.IOException;
     method public void write(int) throws java.io.IOException;
@@ -53046,6 +53194,8 @@
   public deprecated class LineNumberInputStream extends java.io.FilterInputStream {
     ctor public LineNumberInputStream(java.io.InputStream);
     method public int getLineNumber();
+    method public void mark(int);
+    method public void reset() throws java.io.IOException;
     method public void setLineNumber(int);
   }
 
@@ -53275,8 +53425,10 @@
     ctor public PipedInputStream(java.io.PipedOutputStream, int) throws java.io.IOException;
     ctor public PipedInputStream();
     ctor public PipedInputStream(int);
+    method public synchronized int available() throws java.io.IOException;
     method public void connect(java.io.PipedOutputStream) throws java.io.IOException;
     method public synchronized int read() throws java.io.IOException;
+    method public synchronized int read(byte[], int, int) throws java.io.IOException;
     method protected synchronized void receive(int) throws java.io.IOException;
     field protected static final int PIPE_SIZE = 1024; // 0x400
     field protected byte[] buffer;
@@ -53288,6 +53440,7 @@
     ctor public PipedOutputStream(java.io.PipedInputStream) throws java.io.IOException;
     ctor public PipedOutputStream();
     method public synchronized void connect(java.io.PipedInputStream) throws java.io.IOException;
+    method public synchronized void flush() throws java.io.IOException;
     method public void write(int) throws java.io.IOException;
   }
 
@@ -53298,7 +53451,9 @@
     ctor public PipedReader(int);
     method public void close() throws java.io.IOException;
     method public void connect(java.io.PipedWriter) throws java.io.IOException;
+    method public synchronized int read() throws java.io.IOException;
     method public synchronized int read(char[], int, int) throws java.io.IOException;
+    method public synchronized boolean ready() throws java.io.IOException;
   }
 
   public class PipedWriter extends java.io.Writer {
@@ -53323,6 +53478,8 @@
     method public java.io.PrintStream append(char);
     method public boolean checkError();
     method protected void clearError();
+    method public void close();
+    method public void flush();
     method public java.io.PrintStream format(java.lang.String, java.lang.Object...);
     method public java.io.PrintStream format(java.util.Locale, java.lang.String, java.lang.Object...);
     method public void print(boolean);
@@ -53347,6 +53504,8 @@
     method public void println(java.lang.String);
     method public void println(java.lang.Object);
     method protected void setError();
+    method public void write(int);
+    method public void write(byte[], int, int);
   }
 
   public class PrintWriter extends java.io.Writer {
@@ -53358,6 +53517,9 @@
     ctor public PrintWriter(java.lang.String, java.lang.String) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
     ctor public PrintWriter(java.io.File) throws java.io.FileNotFoundException;
     ctor public PrintWriter(java.io.File, java.lang.String) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
+    method public java.io.PrintWriter append(java.lang.CharSequence);
+    method public java.io.PrintWriter append(java.lang.CharSequence, int, int);
+    method public java.io.PrintWriter append(char);
     method public boolean checkError();
     method protected void clearError();
     method public void close();
@@ -53386,13 +53548,18 @@
     method public void println(java.lang.String);
     method public void println(java.lang.Object);
     method protected void setError();
+    method public void write(int);
     method public void write(char[], int, int);
+    method public void write(char[]);
+    method public void write(java.lang.String, int, int);
+    method public void write(java.lang.String);
     field protected java.io.Writer out;
   }
 
   public class PushbackInputStream extends java.io.FilterInputStream {
     ctor public PushbackInputStream(java.io.InputStream, int);
     ctor public PushbackInputStream(java.io.InputStream);
+    method public synchronized void close() throws java.io.IOException;
     method public void unread(int) throws java.io.IOException;
     method public void unread(byte[], int, int) throws java.io.IOException;
     method public void unread(byte[]) throws java.io.IOException;
@@ -53516,7 +53683,11 @@
 
   public deprecated class StringBufferInputStream extends java.io.InputStream {
     ctor public StringBufferInputStream(java.lang.String);
+    method public synchronized int available();
     method public synchronized int read();
+    method public synchronized int read(byte[], int, int);
+    method public synchronized void reset();
+    method public synchronized long skip(long);
     field protected java.lang.String buffer;
     field protected int count;
     field protected int pos;
@@ -53531,10 +53702,16 @@
   public class StringWriter extends java.io.Writer {
     ctor public StringWriter();
     ctor public StringWriter(int);
+    method public java.io.StringWriter append(java.lang.CharSequence);
+    method public java.io.StringWriter append(java.lang.CharSequence, int, int);
+    method public java.io.StringWriter append(char);
     method public void close() throws java.io.IOException;
     method public void flush();
     method public java.lang.StringBuffer getBuffer();
+    method public void write(int);
     method public void write(char[], int, int);
+    method public void write(java.lang.String);
+    method public void write(java.lang.String, int, int);
   }
 
   public class SyncFailedException extends java.io.IOException {
@@ -53549,6 +53726,7 @@
   public class UncheckedIOException extends java.lang.RuntimeException {
     ctor public UncheckedIOException(java.lang.String, java.io.IOException);
     ctor public UncheckedIOException(java.io.IOException);
+    method public java.io.IOException getCause();
   }
 
   public class UnsupportedEncodingException extends java.io.IOException {
@@ -53558,6 +53736,7 @@
 
   public class WriteAbortedException extends java.io.ObjectStreamException {
     ctor public WriteAbortedException(java.lang.String, java.lang.Exception);
+    method public java.lang.Throwable getCause();
     field public java.lang.Exception detail;
   }
 
@@ -54325,6 +54504,7 @@
     ctor public ClassNotFoundException();
     ctor public ClassNotFoundException(java.lang.String);
     ctor public ClassNotFoundException(java.lang.String, java.lang.Throwable);
+    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getException();
   }
 
@@ -54429,6 +54609,7 @@
     ctor public ExceptionInInitializerError();
     ctor public ExceptionInInitializerError(java.lang.Throwable);
     ctor public ExceptionInInitializerError(java.lang.String);
+    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getException();
   }
 
@@ -55216,8 +55397,16 @@
     method public synchronized java.lang.StringBuffer append(float);
     method public synchronized java.lang.StringBuffer append(double);
     method public synchronized java.lang.StringBuffer appendCodePoint(int);
+    method public synchronized int capacity();
+    method public synchronized char charAt(int);
+    method public synchronized int codePointAt(int);
+    method public synchronized int codePointBefore(int);
+    method public synchronized int codePointCount(int, int);
     method public synchronized java.lang.StringBuffer delete(int, int);
     method public synchronized java.lang.StringBuffer deleteCharAt(int);
+    method public synchronized void ensureCapacity(int);
+    method public synchronized void getChars(int, int, char[], int);
+    method public synchronized int indexOf(java.lang.String, int);
     method public synchronized java.lang.StringBuffer insert(int, char[], int, int);
     method public synchronized java.lang.StringBuffer insert(int, java.lang.Object);
     method public synchronized java.lang.StringBuffer insert(int, java.lang.String);
@@ -55230,9 +55419,18 @@
     method public java.lang.StringBuffer insert(int, long);
     method public java.lang.StringBuffer insert(int, float);
     method public java.lang.StringBuffer insert(int, double);
+    method public synchronized int lastIndexOf(java.lang.String, int);
+    method public synchronized int length();
+    method public synchronized int offsetByCodePoints(int, int);
     method public synchronized java.lang.StringBuffer replace(int, int, java.lang.String);
     method public synchronized java.lang.StringBuffer reverse();
+    method public synchronized void setCharAt(int, char);
+    method public synchronized void setLength(int);
+    method public synchronized java.lang.CharSequence subSequence(int, int);
+    method public synchronized java.lang.String substring(int);
+    method public synchronized java.lang.String substring(int, int);
     method public synchronized java.lang.String toString();
+    method public synchronized void trimToSize();
   }
 
   public final class StringBuilder extends java.lang.AbstractStringBuilder implements java.lang.CharSequence java.io.Serializable {
@@ -55887,6 +56085,7 @@
     ctor protected InvocationTargetException();
     ctor public InvocationTargetException(java.lang.Throwable);
     ctor public InvocationTargetException(java.lang.Throwable, java.lang.String);
+    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getTargetException();
   }
 
@@ -56002,6 +56201,7 @@
   public class UndeclaredThrowableException extends java.lang.RuntimeException {
     ctor public UndeclaredThrowableException(java.lang.Throwable);
     ctor public UndeclaredThrowableException(java.lang.Throwable, java.lang.String);
+    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getUndeclaredThrowable();
   }
 
@@ -56899,6 +57099,7 @@
     method public java.lang.String getQuery();
     method public java.lang.String getRef();
     method public java.lang.String getUserInfo();
+    method public synchronized int hashCode();
     method public java.net.URLConnection openConnection() throws java.io.IOException;
     method public java.net.URLConnection openConnection(java.net.Proxy) throws java.io.IOException;
     method public final java.io.InputStream openStream() throws java.io.IOException;
@@ -57128,7 +57329,6 @@
     method public final int arrayOffset();
     method public abstract java.nio.CharBuffer asReadOnlyBuffer();
     method public final char charAt(int);
-    method public java.util.stream.IntStream chars();
     method public abstract java.nio.CharBuffer compact();
     method public int compareTo(java.nio.CharBuffer);
     method public abstract java.nio.CharBuffer duplicate();
@@ -57985,6 +58185,7 @@
 
   public final class DirectoryIteratorException extends java.util.ConcurrentModificationException {
     ctor public DirectoryIteratorException(java.io.IOException);
+    method public java.io.IOException getCause();
   }
 
   public class DirectoryNotEmptyException extends java.nio.file.FileSystemException {
@@ -58950,9 +59151,11 @@
   public static class KeyStore.PasswordProtection implements javax.security.auth.Destroyable java.security.KeyStore.ProtectionParameter {
     ctor public KeyStore.PasswordProtection(char[]);
     ctor public KeyStore.PasswordProtection(char[], java.lang.String, java.security.spec.AlgorithmParameterSpec);
+    method public synchronized void destroy() throws javax.security.auth.DestroyFailedException;
     method public synchronized char[] getPassword();
     method public java.lang.String getProtectionAlgorithm();
     method public java.security.spec.AlgorithmParameterSpec getProtectionParameters();
+    method public synchronized boolean isDestroyed();
   }
 
   public static final class KeyStore.PrivateKeyEntry implements java.security.KeyStore.Entry {
@@ -59132,6 +59335,7 @@
 
   public class PrivilegedActionException extends java.lang.Exception {
     ctor public PrivilegedActionException(java.lang.Exception);
+    method public java.lang.Throwable getCause();
     method public java.lang.Exception getException();
   }
 
@@ -59154,22 +59358,30 @@
     method public synchronized java.lang.Object compute(java.lang.Object, java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
     method public synchronized java.lang.Object computeIfAbsent(java.lang.Object, java.util.function.Function<? super java.lang.Object, ? extends java.lang.Object>);
     method public synchronized java.lang.Object computeIfPresent(java.lang.Object, java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
+    method public java.util.Enumeration<java.lang.Object> elements();
+    method public synchronized java.util.Set<java.util.Map.Entry<java.lang.Object, java.lang.Object>> entrySet();
     method public synchronized void forEach(java.util.function.BiConsumer<? super java.lang.Object, ? super java.lang.Object>);
+    method public java.lang.Object get(java.lang.Object);
     method public java.lang.String getInfo();
     method public java.lang.String getName();
     method public synchronized java.lang.Object getOrDefault(java.lang.Object, java.lang.Object);
     method public synchronized java.security.Provider.Service getService(java.lang.String, java.lang.String);
     method public synchronized java.util.Set<java.security.Provider.Service> getServices();
     method public double getVersion();
+    method public java.util.Set<java.lang.Object> keySet();
+    method public java.util.Enumeration<java.lang.Object> keys();
     method public synchronized java.lang.Object merge(java.lang.Object, java.lang.Object, java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
     method public synchronized java.lang.Object put(java.lang.Object, java.lang.Object);
     method public synchronized void putAll(java.util.Map<?, ?>);
     method public synchronized java.lang.Object putIfAbsent(java.lang.Object, java.lang.Object);
     method protected synchronized void putService(java.security.Provider.Service);
+    method public synchronized java.lang.Object remove(java.lang.Object);
     method protected synchronized void removeService(java.security.Provider.Service);
     method public synchronized boolean replace(java.lang.Object, java.lang.Object, java.lang.Object);
     method public synchronized java.lang.Object replace(java.lang.Object, java.lang.Object);
     method public synchronized void replaceAll(java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
+    method public java.lang.String toString();
+    method public java.util.Collection<java.lang.Object> values();
   }
 
   public static class Provider.Service {
@@ -59215,7 +59427,9 @@
     method public final java.security.Provider getProvider();
     method public static byte[] getSeed(int);
     method protected final int next(int);
+    method public synchronized void nextBytes(byte[]);
     method public synchronized void setSeed(byte[]);
+    method public void setSeed(long);
   }
 
   public abstract class SecureRandomSpi implements java.io.Serializable {
@@ -59762,6 +59976,7 @@
 
   public abstract class PKIXRevocationChecker extends java.security.cert.PKIXCertPathChecker {
     ctor protected PKIXRevocationChecker();
+    method public java.security.cert.PKIXRevocationChecker clone();
     method public java.util.List<java.security.cert.Extension> getOcspExtensions();
     method public java.net.URI getOcspResponder();
     method public java.security.cert.X509Certificate getOcspResponderCert();
@@ -62014,7 +62229,6 @@
   public final class DayOfWeek extends java.lang.Enum implements java.time.temporal.TemporalAccessor java.time.temporal.TemporalAdjuster {
     method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
     method public static java.time.DayOfWeek from(java.time.temporal.TemporalAccessor);
-    method public int get(java.time.temporal.TemporalField);
     method public java.lang.String getDisplayName(java.time.format.TextStyle, java.util.Locale);
     method public long getLong(java.time.temporal.TemporalField);
     method public int getValue();
@@ -62022,8 +62236,6 @@
     method public java.time.DayOfWeek minus(long);
     method public static java.time.DayOfWeek of(int);
     method public java.time.DayOfWeek plus(long);
-    method public <R> R query(java.time.temporal.TemporalQuery<R>);
-    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     method public static java.time.DayOfWeek valueOf(java.lang.String);
     method public static final java.time.DayOfWeek[] values();
     enum_constant public static final java.time.DayOfWeek FRIDAY;
@@ -62099,6 +62311,8 @@
     method public boolean isBefore(java.time.Instant);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
+    method public java.time.Instant minus(java.time.temporal.TemporalAmount);
+    method public java.time.Instant minus(long, java.time.temporal.TemporalUnit);
     method public java.time.Instant minusMillis(long);
     method public java.time.Instant minusNanos(long);
     method public java.time.Instant minusSeconds(long);
@@ -62108,6 +62322,7 @@
     method public static java.time.Instant ofEpochSecond(long);
     method public static java.time.Instant ofEpochSecond(long, long);
     method public static java.time.Instant parse(java.lang.CharSequence);
+    method public java.time.Instant plus(java.time.temporal.TemporalAmount);
     method public java.time.Instant plus(long, java.time.temporal.TemporalUnit);
     method public java.time.Instant plusMillis(long);
     method public java.time.Instant plusNanos(long);
@@ -62115,6 +62330,7 @@
     method public long toEpochMilli();
     method public java.time.Instant truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.Instant with(java.time.temporal.TemporalAdjuster);
     method public java.time.Instant with(java.time.temporal.TemporalField, long);
     field public static final java.time.Instant EPOCH;
     field public static final java.time.Instant MAX;
@@ -62124,6 +62340,7 @@
   public final class LocalDate implements java.time.chrono.ChronoLocalDate java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
     method public java.time.LocalDateTime atStartOfDay();
     method public java.time.ZonedDateTime atStartOfDay(java.time.ZoneId);
+    method public java.time.LocalDateTime atTime(java.time.LocalTime);
     method public java.time.LocalDateTime atTime(int, int);
     method public java.time.LocalDateTime atTime(int, int, int);
     method public java.time.LocalDateTime atTime(int, int, int, int);
@@ -62138,6 +62355,8 @@
     method public int getMonthValue();
     method public int getYear();
     method public int lengthOfMonth();
+    method public java.time.LocalDate minus(java.time.temporal.TemporalAmount);
+    method public java.time.LocalDate minus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDate minusDays(long);
     method public java.time.LocalDate minusMonths(long);
     method public java.time.LocalDate minusWeeks(long);
@@ -62151,12 +62370,16 @@
     method public static java.time.LocalDate ofYearDay(int, int);
     method public static java.time.LocalDate parse(java.lang.CharSequence);
     method public static java.time.LocalDate parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
+    method public java.time.LocalDate plus(java.time.temporal.TemporalAmount);
+    method public java.time.LocalDate plus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDate plusDays(long);
     method public java.time.LocalDate plusMonths(long);
     method public java.time.LocalDate plusWeeks(long);
     method public java.time.LocalDate plusYears(long);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
     method public java.time.Period until(java.time.chrono.ChronoLocalDate);
+    method public java.time.LocalDate with(java.time.temporal.TemporalAdjuster);
+    method public java.time.LocalDate with(java.time.temporal.TemporalField, long);
     method public java.time.LocalDate withDayOfMonth(int);
     method public java.time.LocalDate withDayOfYear(int);
     method public java.time.LocalDate withMonth(int);
@@ -62181,6 +62404,8 @@
     method public int getSecond();
     method public int getYear();
     method public boolean isSupported(java.time.temporal.TemporalField);
+    method public java.time.LocalDateTime minus(java.time.temporal.TemporalAmount);
+    method public java.time.LocalDateTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDateTime minusDays(long);
     method public java.time.LocalDateTime minusHours(long);
     method public java.time.LocalDateTime minusMinutes(long);
@@ -62203,6 +62428,7 @@
     method public static java.time.LocalDateTime ofInstant(java.time.Instant, java.time.ZoneId);
     method public static java.time.LocalDateTime parse(java.lang.CharSequence);
     method public static java.time.LocalDateTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
+    method public java.time.LocalDateTime plus(java.time.temporal.TemporalAmount);
     method public java.time.LocalDateTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDateTime plusDays(long);
     method public java.time.LocalDateTime plusHours(long);
@@ -62216,6 +62442,7 @@
     method public java.time.LocalTime toLocalTime();
     method public java.time.LocalDateTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.LocalDateTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.LocalDateTime with(java.time.temporal.TemporalField, long);
     method public java.time.LocalDateTime withDayOfMonth(int);
     method public java.time.LocalDateTime withDayOfYear(int);
@@ -62245,6 +62472,8 @@
     method public boolean isBefore(java.time.LocalTime);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
+    method public java.time.LocalTime minus(java.time.temporal.TemporalAmount);
+    method public java.time.LocalTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalTime minusHours(long);
     method public java.time.LocalTime minusMinutes(long);
     method public java.time.LocalTime minusNanos(long);
@@ -62259,6 +62488,7 @@
     method public static java.time.LocalTime ofSecondOfDay(long);
     method public static java.time.LocalTime parse(java.lang.CharSequence);
     method public static java.time.LocalTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
+    method public java.time.LocalTime plus(java.time.temporal.TemporalAmount);
     method public java.time.LocalTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalTime plusHours(long);
     method public java.time.LocalTime plusMinutes(long);
@@ -62268,6 +62498,7 @@
     method public int toSecondOfDay();
     method public java.time.LocalTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.LocalTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.LocalTime with(java.time.temporal.TemporalField, long);
     method public java.time.LocalTime withHour(int);
     method public java.time.LocalTime withMinute(int);
@@ -62284,7 +62515,6 @@
     method public int firstDayOfYear(boolean);
     method public java.time.Month firstMonthOfQuarter();
     method public static java.time.Month from(java.time.temporal.TemporalAccessor);
-    method public int get(java.time.temporal.TemporalField);
     method public java.lang.String getDisplayName(java.time.format.TextStyle, java.util.Locale);
     method public long getLong(java.time.temporal.TemporalField);
     method public int getValue();
@@ -62295,8 +62525,6 @@
     method public java.time.Month minus(long);
     method public static java.time.Month of(int);
     method public java.time.Month plus(long);
-    method public <R> R query(java.time.temporal.TemporalQuery<R>);
-    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     method public static java.time.Month valueOf(java.lang.String);
     method public static final java.time.Month[] values();
     enum_constant public static final java.time.Month APRIL;
@@ -62363,6 +62591,8 @@
     method public boolean isEqual(java.time.OffsetDateTime);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
+    method public java.time.OffsetDateTime minus(java.time.temporal.TemporalAmount);
+    method public java.time.OffsetDateTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetDateTime minusDays(long);
     method public java.time.OffsetDateTime minusHours(long);
     method public java.time.OffsetDateTime minusMinutes(long);
@@ -62380,6 +62610,7 @@
     method public static java.time.OffsetDateTime ofInstant(java.time.Instant, java.time.ZoneId);
     method public static java.time.OffsetDateTime parse(java.lang.CharSequence);
     method public static java.time.OffsetDateTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
+    method public java.time.OffsetDateTime plus(java.time.temporal.TemporalAmount);
     method public java.time.OffsetDateTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetDateTime plusDays(long);
     method public java.time.OffsetDateTime plusHours(long);
@@ -62399,6 +62630,7 @@
     method public java.time.ZonedDateTime toZonedDateTime();
     method public java.time.OffsetDateTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.OffsetDateTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.OffsetDateTime with(java.time.temporal.TemporalField, long);
     method public java.time.OffsetDateTime withDayOfMonth(int);
     method public java.time.OffsetDateTime withDayOfYear(int);
@@ -62431,6 +62663,8 @@
     method public boolean isEqual(java.time.OffsetTime);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
+    method public java.time.OffsetTime minus(java.time.temporal.TemporalAmount);
+    method public java.time.OffsetTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetTime minusHours(long);
     method public java.time.OffsetTime minusMinutes(long);
     method public java.time.OffsetTime minusNanos(long);
@@ -62443,6 +62677,7 @@
     method public static java.time.OffsetTime ofInstant(java.time.Instant, java.time.ZoneId);
     method public static java.time.OffsetTime parse(java.lang.CharSequence);
     method public static java.time.OffsetTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
+    method public java.time.OffsetTime plus(java.time.temporal.TemporalAmount);
     method public java.time.OffsetTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetTime plusHours(long);
     method public java.time.OffsetTime plusMinutes(long);
@@ -62451,6 +62686,7 @@
     method public java.time.LocalTime toLocalTime();
     method public java.time.OffsetTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.OffsetTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.OffsetTime with(java.time.temporal.TemporalField, long);
     method public java.time.OffsetTime withHour(int);
     method public java.time.OffsetTime withMinute(int);
@@ -62477,6 +62713,7 @@
     method public java.time.Period minusMonths(long);
     method public java.time.Period minusYears(long);
     method public java.time.Period multipliedBy(int);
+    method public java.time.Period negated();
     method public java.time.Period normalized();
     method public static java.time.Period of(int, int, int);
     method public static java.time.Period ofDays(int);
@@ -62515,6 +62752,8 @@
     method public boolean isSupported(java.time.temporal.TemporalUnit);
     method public boolean isValidMonthDay(java.time.MonthDay);
     method public int length();
+    method public java.time.Year minus(java.time.temporal.TemporalAmount);
+    method public java.time.Year minus(long, java.time.temporal.TemporalUnit);
     method public java.time.Year minusYears(long);
     method public static java.time.Year now();
     method public static java.time.Year now(java.time.ZoneId);
@@ -62522,9 +62761,11 @@
     method public static java.time.Year of(int);
     method public static java.time.Year parse(java.lang.CharSequence);
     method public static java.time.Year parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
+    method public java.time.Year plus(java.time.temporal.TemporalAmount);
     method public java.time.Year plus(long, java.time.temporal.TemporalUnit);
     method public java.time.Year plusYears(long);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.Year with(java.time.temporal.TemporalAdjuster);
     method public java.time.Year with(java.time.temporal.TemporalField, long);
     field public static final int MAX_VALUE = 999999999; // 0x3b9ac9ff
     field public static final int MIN_VALUE = -999999999; // 0xc4653601
@@ -62549,6 +62790,8 @@
     method public boolean isValidDay(int);
     method public int lengthOfMonth();
     method public int lengthOfYear();
+    method public java.time.YearMonth minus(java.time.temporal.TemporalAmount);
+    method public java.time.YearMonth minus(long, java.time.temporal.TemporalUnit);
     method public java.time.YearMonth minusMonths(long);
     method public java.time.YearMonth minusYears(long);
     method public static java.time.YearMonth now();
@@ -62558,10 +62801,12 @@
     method public static java.time.YearMonth of(int, int);
     method public static java.time.YearMonth parse(java.lang.CharSequence);
     method public static java.time.YearMonth parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
+    method public java.time.YearMonth plus(java.time.temporal.TemporalAmount);
     method public java.time.YearMonth plus(long, java.time.temporal.TemporalUnit);
     method public java.time.YearMonth plusMonths(long);
     method public java.time.YearMonth plusYears(long);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.YearMonth with(java.time.temporal.TemporalAdjuster);
     method public java.time.YearMonth with(java.time.temporal.TemporalField, long);
     method public java.time.YearMonth withMonth(int);
     method public java.time.YearMonth withYear(int);
@@ -62585,7 +62830,6 @@
     method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
     method public int compareTo(java.time.ZoneOffset);
     method public static java.time.ZoneOffset from(java.time.temporal.TemporalAccessor);
-    method public int get(java.time.temporal.TemporalField);
     method public java.lang.String getId();
     method public long getLong(java.time.temporal.TemporalField);
     method public java.time.zone.ZoneRules getRules();
@@ -62596,8 +62840,6 @@
     method public static java.time.ZoneOffset ofHoursMinutes(int, int);
     method public static java.time.ZoneOffset ofHoursMinutesSeconds(int, int, int);
     method public static java.time.ZoneOffset ofTotalSeconds(int);
-    method public <R> R query(java.time.temporal.TemporalQuery<R>);
-    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     field public static final java.time.ZoneOffset MAX;
     field public static final java.time.ZoneOffset MIN;
     field public static final java.time.ZoneOffset UTC;
@@ -62618,6 +62860,8 @@
     method public int getYear();
     method public java.time.ZoneId getZone();
     method public boolean isSupported(java.time.temporal.TemporalField);
+    method public java.time.ZonedDateTime minus(java.time.temporal.TemporalAmount);
+    method public java.time.ZonedDateTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.ZonedDateTime minusDays(long);
     method public java.time.ZonedDateTime minusHours(long);
     method public java.time.ZonedDateTime minusMinutes(long);
@@ -62638,6 +62882,7 @@
     method public static java.time.ZonedDateTime ofStrict(java.time.LocalDateTime, java.time.ZoneOffset, java.time.ZoneId);
     method public static java.time.ZonedDateTime parse(java.lang.CharSequence);
     method public static java.time.ZonedDateTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
+    method public java.time.ZonedDateTime plus(java.time.temporal.TemporalAmount);
     method public java.time.ZonedDateTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.ZonedDateTime plusDays(long);
     method public java.time.ZonedDateTime plusHours(long);
@@ -62647,10 +62892,12 @@
     method public java.time.ZonedDateTime plusSeconds(long);
     method public java.time.ZonedDateTime plusWeeks(long);
     method public java.time.ZonedDateTime plusYears(long);
+    method public java.time.LocalDate toLocalDate();
     method public java.time.LocalDateTime toLocalDateTime();
     method public java.time.OffsetDateTime toOffsetDateTime();
     method public java.time.ZonedDateTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.ZonedDateTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.ZonedDateTime with(java.time.temporal.TemporalField, long);
     method public java.time.ZonedDateTime withDayOfMonth(int);
     method public java.time.ZonedDateTime withDayOfYear(int);
@@ -62695,17 +62942,27 @@
     method public default boolean isSupported(java.time.temporal.TemporalUnit);
     method public abstract int lengthOfMonth();
     method public default int lengthOfYear();
+    method public default java.time.chrono.ChronoLocalDate minus(java.time.temporal.TemporalAmount);
+    method public default java.time.chrono.ChronoLocalDate minus(long, java.time.temporal.TemporalUnit);
+    method public default java.time.chrono.ChronoLocalDate plus(java.time.temporal.TemporalAmount);
     method public default java.time.chrono.ChronoLocalDate plus(long, java.time.temporal.TemporalUnit);
     method public static java.util.Comparator<java.time.chrono.ChronoLocalDate> timeLineOrder();
     method public default long toEpochDay();
     method public abstract java.lang.String toString();
     method public abstract long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
     method public abstract java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
+    method public default java.time.chrono.ChronoLocalDate with(java.time.temporal.TemporalAdjuster);
     method public default java.time.chrono.ChronoLocalDate with(java.time.temporal.TemporalField, long);
   }
 
    abstract class ChronoLocalDateImpl<D extends java.time.chrono.ChronoLocalDate> implements java.time.chrono.ChronoLocalDate java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
+    method public D minus(java.time.temporal.TemporalAmount);
+    method public D minus(long, java.time.temporal.TemporalUnit);
+    method public D plus(java.time.temporal.TemporalAmount);
+    method public D plus(long, java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public D with(java.time.temporal.TemporalAdjuster);
+    method public D with(java.time.temporal.TemporalField, long);
   }
 
   public abstract interface ChronoLocalDateTime<D extends java.time.chrono.ChronoLocalDate> implements java.lang.Comparable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
@@ -62722,6 +62979,9 @@
     method public default boolean isEqual(java.time.chrono.ChronoLocalDateTime<?>);
     method public abstract boolean isSupported(java.time.temporal.TemporalField);
     method public default boolean isSupported(java.time.temporal.TemporalUnit);
+    method public default java.time.chrono.ChronoLocalDateTime<D> minus(java.time.temporal.TemporalAmount);
+    method public default java.time.chrono.ChronoLocalDateTime<D> minus(long, java.time.temporal.TemporalUnit);
+    method public default java.time.chrono.ChronoLocalDateTime<D> plus(java.time.temporal.TemporalAmount);
     method public abstract java.time.chrono.ChronoLocalDateTime<D> plus(long, java.time.temporal.TemporalUnit);
     method public static java.util.Comparator<java.time.chrono.ChronoLocalDateTime<?>> timeLineOrder();
     method public default long toEpochSecond(java.time.ZoneOffset);
@@ -62729,6 +62989,7 @@
     method public abstract D toLocalDate();
     method public abstract java.time.LocalTime toLocalTime();
     method public abstract java.lang.String toString();
+    method public default java.time.chrono.ChronoLocalDateTime<D> with(java.time.temporal.TemporalAdjuster);
     method public abstract java.time.chrono.ChronoLocalDateTime<D> with(java.time.temporal.TemporalField, long);
   }
 
@@ -62766,6 +63027,9 @@
     method public default boolean isEqual(java.time.chrono.ChronoZonedDateTime<?>);
     method public abstract boolean isSupported(java.time.temporal.TemporalField);
     method public default boolean isSupported(java.time.temporal.TemporalUnit);
+    method public default java.time.chrono.ChronoZonedDateTime<D> minus(java.time.temporal.TemporalAmount);
+    method public default java.time.chrono.ChronoZonedDateTime<D> minus(long, java.time.temporal.TemporalUnit);
+    method public default java.time.chrono.ChronoZonedDateTime<D> plus(java.time.temporal.TemporalAmount);
     method public abstract java.time.chrono.ChronoZonedDateTime<D> plus(long, java.time.temporal.TemporalUnit);
     method public static java.util.Comparator<java.time.chrono.ChronoZonedDateTime<?>> timeLineOrder();
     method public default long toEpochSecond();
@@ -62774,6 +63038,7 @@
     method public abstract java.time.chrono.ChronoLocalDateTime<D> toLocalDateTime();
     method public default java.time.LocalTime toLocalTime();
     method public abstract java.lang.String toString();
+    method public default java.time.chrono.ChronoZonedDateTime<D> with(java.time.temporal.TemporalAdjuster);
     method public abstract java.time.chrono.ChronoZonedDateTime<D> with(java.time.temporal.TemporalField, long);
     method public abstract java.time.chrono.ChronoZonedDateTime<D> withEarlierOffsetAtOverlap();
     method public abstract java.time.chrono.ChronoZonedDateTime<D> withLaterOffsetAtOverlap();
@@ -62840,6 +63105,7 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.HijrahDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
+    method public java.time.chrono.HijrahDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.HijrahDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.HijrahDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.HijrahChronology INSTANCE;
@@ -62851,23 +63117,24 @@
     method public java.time.chrono.HijrahChronology getChronology();
     method public java.time.chrono.HijrahEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
-    method public boolean isLeapYear();
     method public int lengthOfMonth();
-    method public int lengthOfYear();
+    method public java.time.chrono.HijrahDate minus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.HijrahDate minus(long, java.time.temporal.TemporalUnit);
     method public static java.time.chrono.HijrahDate now();
     method public static java.time.chrono.HijrahDate now(java.time.ZoneId);
     method public static java.time.chrono.HijrahDate now(java.time.Clock);
     method public static java.time.chrono.HijrahDate of(int, int, int);
-    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
-    method public long toEpochDay();
+    method public java.time.chrono.HijrahDate plus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.HijrahDate plus(long, java.time.temporal.TemporalUnit);
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
+    method public java.time.chrono.HijrahDate with(java.time.temporal.TemporalField, long);
+    method public java.time.chrono.HijrahDate with(java.time.temporal.TemporalAdjuster);
     method public java.time.chrono.HijrahDate withVariant(java.time.chrono.HijrahChronology);
   }
 
   public final class HijrahEra extends java.lang.Enum implements java.time.chrono.Era {
     method public int getValue();
     method public static java.time.chrono.HijrahEra of(int);
-    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     method public static java.time.chrono.HijrahEra valueOf(java.lang.String);
     method public static final java.time.chrono.HijrahEra[] values();
     enum_constant public static final java.time.chrono.HijrahEra AH;
@@ -62892,6 +63159,7 @@
     method public java.time.Period period(int, int, int);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
+    method public java.time.LocalDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.ZonedDateTime zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.ZonedDateTime zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.IsoChronology INSTANCE;
@@ -62924,6 +63192,7 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.JapaneseDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
+    method public java.time.chrono.JapaneseDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.JapaneseDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.JapaneseDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.JapaneseChronology INSTANCE;
@@ -62935,17 +63204,19 @@
     method public java.time.chrono.JapaneseChronology getChronology();
     method public java.time.chrono.JapaneseEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
-    method public boolean isSupported(java.time.temporal.TemporalField);
     method public int lengthOfMonth();
-    method public int lengthOfYear();
+    method public java.time.chrono.JapaneseDate minus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.JapaneseDate minus(long, java.time.temporal.TemporalUnit);
     method public static java.time.chrono.JapaneseDate now();
     method public static java.time.chrono.JapaneseDate now(java.time.ZoneId);
     method public static java.time.chrono.JapaneseDate now(java.time.Clock);
     method public static java.time.chrono.JapaneseDate of(java.time.chrono.JapaneseEra, int, int, int);
     method public static java.time.chrono.JapaneseDate of(int, int, int);
-    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
-    method public long toEpochDay();
+    method public java.time.chrono.JapaneseDate plus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.JapaneseDate plus(long, java.time.temporal.TemporalUnit);
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
+    method public java.time.chrono.JapaneseDate with(java.time.temporal.TemporalField, long);
+    method public java.time.chrono.JapaneseDate with(java.time.temporal.TemporalAdjuster);
   }
 
   public final class JapaneseEra implements java.time.chrono.Era java.io.Serializable {
@@ -62977,6 +63248,7 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.MinguoDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
+    method public java.time.chrono.MinguoDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.MinguoDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.MinguoDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.MinguoChronology INSTANCE;
@@ -62989,13 +63261,17 @@
     method public java.time.chrono.MinguoEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
     method public int lengthOfMonth();
+    method public java.time.chrono.MinguoDate minus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.MinguoDate minus(long, java.time.temporal.TemporalUnit);
     method public static java.time.chrono.MinguoDate now();
     method public static java.time.chrono.MinguoDate now(java.time.ZoneId);
     method public static java.time.chrono.MinguoDate now(java.time.Clock);
     method public static java.time.chrono.MinguoDate of(int, int, int);
-    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
-    method public long toEpochDay();
+    method public java.time.chrono.MinguoDate plus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.MinguoDate plus(long, java.time.temporal.TemporalUnit);
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
+    method public java.time.chrono.MinguoDate with(java.time.temporal.TemporalField, long);
+    method public java.time.chrono.MinguoDate with(java.time.temporal.TemporalAdjuster);
   }
 
   public final class MinguoEra extends java.lang.Enum implements java.time.chrono.Era {
@@ -63025,6 +63301,7 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.ThaiBuddhistDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
+    method public java.time.chrono.ThaiBuddhistDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.ThaiBuddhistDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.ThaiBuddhistDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.ThaiBuddhistChronology INSTANCE;
@@ -63037,13 +63314,17 @@
     method public java.time.chrono.ThaiBuddhistEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
     method public int lengthOfMonth();
+    method public java.time.chrono.ThaiBuddhistDate minus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.ThaiBuddhistDate minus(long, java.time.temporal.TemporalUnit);
     method public static java.time.chrono.ThaiBuddhistDate now();
     method public static java.time.chrono.ThaiBuddhistDate now(java.time.ZoneId);
     method public static java.time.chrono.ThaiBuddhistDate now(java.time.Clock);
     method public static java.time.chrono.ThaiBuddhistDate of(int, int, int);
-    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
-    method public long toEpochDay();
+    method public java.time.chrono.ThaiBuddhistDate plus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.ThaiBuddhistDate plus(long, java.time.temporal.TemporalUnit);
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
+    method public java.time.chrono.ThaiBuddhistDate with(java.time.temporal.TemporalField, long);
+    method public java.time.chrono.ThaiBuddhistDate with(java.time.temporal.TemporalAdjuster);
   }
 
   public final class ThaiBuddhistEra extends java.lang.Enum implements java.time.chrono.Era {
@@ -63222,7 +63503,6 @@
     method public int checkValidIntValue(long);
     method public long checkValidValue(long);
     method public java.time.temporal.TemporalUnit getBaseUnit();
-    method public java.lang.String getDisplayName(java.util.Locale);
     method public long getFrom(java.time.temporal.TemporalAccessor);
     method public java.time.temporal.TemporalUnit getRangeUnit();
     method public boolean isDateBased();
@@ -63270,7 +63550,6 @@
     method public java.time.Duration getDuration();
     method public boolean isDateBased();
     method public boolean isDurationEstimated();
-    method public boolean isSupportedBy(java.time.temporal.Temporal);
     method public boolean isTimeBased();
     method public static java.time.temporal.ChronoUnit valueOf(java.lang.String);
     method public static final java.time.temporal.ChronoUnit[] values();
@@ -63610,7 +63889,6 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
-    method public java.util.Spliterator<E> spliterator();
   }
 
   public class ArrayList<E> extends java.util.AbstractList implements java.lang.Cloneable java.util.List java.util.RandomAccess java.io.Serializable {
@@ -63621,11 +63899,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 void replaceAll(java.util.function.UnaryOperator<E>);
     method public int size();
-    method public void sort(java.util.Comparator<? super E>);
-    method public java.util.Spliterator<E> spliterator();
     method public void trimToSize();
   }
 
@@ -63996,6 +64270,7 @@
     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 default java.util.Spliterator<E> spliterator();
     method public default java.util.stream.Stream<E> stream();
     method public abstract java.lang.Object[] toArray();
     method public abstract <T> T[] toArray(T[]);
@@ -64336,18 +64611,7 @@
     ctor public HashMap();
     ctor public HashMap(java.util.Map<? extends K, ? extends V>);
     method public java.lang.Object clone();
-    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.Set<java.util.Map.Entry<K, V>> entrySet();
-    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
-    method public V getOrDefault(java.lang.Object, V);
-    method public V merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
-    method public V putIfAbsent(K, V);
-    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>);
   }
 
   public class HashSet<E> extends java.util.AbstractSet implements java.lang.Cloneable java.io.Serializable java.util.Set {
@@ -64358,7 +64622,6 @@
     method public java.lang.Object clone();
     method public java.util.Iterator<E> iterator();
     method public int size();
-    method public java.util.Spliterator<E> spliterator();
   }
 
   public class Hashtable<K, V> extends java.util.Dictionary implements java.lang.Cloneable java.util.Map java.io.Serializable {
@@ -64376,9 +64639,11 @@
     method public boolean containsValue(java.lang.Object);
     method public synchronized java.util.Enumeration<V> elements();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+    method public synchronized boolean equals(java.lang.Object);
     method public synchronized void forEach(java.util.function.BiConsumer<? super K, ? super V>);
     method public synchronized V get(java.lang.Object);
     method public synchronized V getOrDefault(java.lang.Object, V);
+    method public synchronized int hashCode();
     method public synchronized boolean isEmpty();
     method public java.util.Set<K> keySet();
     method public synchronized java.util.Enumeration<K> keys();
@@ -64393,6 +64658,7 @@
     method public synchronized V replace(K, V);
     method public synchronized void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public synchronized int size();
+    method public synchronized java.lang.String toString();
     method public java.util.Collection<V> values();
   }
 
@@ -64402,8 +64668,6 @@
     ctor public IdentityHashMap(java.util.Map<? extends K, ? extends V>);
     method public java.lang.Object clone();
     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 replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
   }
 
   public class IllegalFormatCodePointException extends java.util.IllegalFormatException {
@@ -64514,7 +64778,6 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
-    method public java.util.Spliterator<E> spliterator();
   }
 
   public abstract interface List<E> implements java.util.Collection {
@@ -65137,6 +65400,7 @@
     ctor public SimpleTimeZone(int, java.lang.String, int, int, int, int, int, int, int, int, int, int, int);
     method public int getOffset(int, int, int, int, int, int);
     method public int getRawOffset();
+    method public synchronized int hashCode();
     method public boolean inDaylightTime(java.util.Date);
     method public void setDSTSavings(int);
     method public void setEndRule(int, int, int, int);
@@ -65409,7 +65673,6 @@
     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 java.util.NavigableMap<K, V> headMap(K, boolean);
     method public java.util.SortedMap<K, V> headMap(K);
     method public java.util.Map.Entry<K, V> higherEntry(K);
@@ -65421,9 +65684,6 @@
     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();
-    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.NavigableMap<K, V> subMap(K, boolean, K, boolean);
     method public java.util.SortedMap<K, V> subMap(K, K);
     method public java.util.NavigableMap<K, V> tailMap(K, boolean);
@@ -65451,7 +65711,6 @@
     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.SortedSet<E> subSet(E, E);
     method public java.util.NavigableSet<E> tailSet(E, boolean);
@@ -65488,30 +65747,49 @@
     ctor public Vector(int);
     ctor public Vector();
     ctor public Vector(java.util.Collection<? extends E>);
+    method public synchronized boolean add(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 void addElement(E);
     method public synchronized int capacity();
     method public synchronized java.lang.Object clone();
+    method public synchronized boolean containsAll(java.util.Collection<?>);
     method public synchronized void copyInto(java.lang.Object[]);
     method public synchronized E elementAt(int);
     method public java.util.Enumeration<E> elements();
     method public synchronized void ensureCapacity(int);
+    method public synchronized boolean equals(java.lang.Object);
     method public synchronized E firstElement();
     method public synchronized void forEach(java.util.function.Consumer<? super E>);
     method public synchronized E get(int);
+    method public synchronized int hashCode();
     method public synchronized int indexOf(java.lang.Object, int);
     method public synchronized void insertElementAt(E, int);
+    method public synchronized boolean isEmpty();
+    method public synchronized java.util.Iterator<E> iterator();
     method public synchronized E lastElement();
+    method public synchronized int lastIndexOf(java.lang.Object);
     method public synchronized int lastIndexOf(java.lang.Object, int);
+    method public synchronized java.util.ListIterator<E> listIterator(int);
+    method public synchronized java.util.ListIterator<E> listIterator();
+    method public synchronized E remove(int);
+    method public synchronized boolean removeAll(java.util.Collection<?>);
     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 protected synchronized void removeRange(int, int);
     method public synchronized void replaceAll(java.util.function.UnaryOperator<E>);
+    method public synchronized boolean retainAll(java.util.Collection<?>);
+    method public synchronized E set(int, E);
     method public synchronized void setElementAt(E, int);
     method public synchronized void setSize(int);
     method public synchronized int size();
     method public synchronized void sort(java.util.Comparator<? super E>);
-    method public java.util.Spliterator<E> spliterator();
+    method public synchronized java.util.List<E> subList(int, int);
+    method public synchronized java.lang.Object[] toArray();
+    method public synchronized <T> T[] toArray(T[]);
+    method public synchronized java.lang.String toString();
     method public synchronized void trimToSize();
     field protected int capacityIncrement;
     field protected int elementCount;
@@ -65524,8 +65802,6 @@
     ctor public WeakHashMap();
     ctor public WeakHashMap(java.util.Map<? extends K, ? extends V>);
     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 replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
   }
 
 }
@@ -65560,7 +65836,6 @@
     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;
   }
 
@@ -65751,13 +66026,9 @@
     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 <U> 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>>);
@@ -65766,14 +66037,11 @@
     method public <U> 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 <U> 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 <K> java.util.concurrent.ConcurrentHashMap.KeySetView<K, java.lang.Boolean> newKeySet();
     method public static <K> java.util.concurrent.ConcurrentHashMap.KeySetView<K, java.lang.Boolean> newKeySet(int);
-    method public V putIfAbsent(K, V);
     method public <U> 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> 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>);
@@ -65793,10 +66061,6 @@
     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> U search(long, java.util.function.BiFunction<? super K, ? super V, ? extends U>);
     method public <U> U searchEntries(long, java.util.function.Function<java.util.Map.Entry<K, V>, ? extends U>);
     method public <U> U searchKeys(long, java.util.function.Function<? super K, ? extends U>);
@@ -65857,7 +66121,6 @@
     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<E> extends java.util.AbstractQueue implements java.util.Queue java.io.Serializable {
@@ -65868,7 +66131,6 @@
     method public E peek();
     method public E poll();
     method public int size();
-    method public java.util.Spliterator<E> spliterator();
   }
 
   public abstract interface ConcurrentMap<K, V> implements java.util.Map {
@@ -65900,9 +66162,6 @@
     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();
@@ -65910,25 +66169,18 @@
     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);
     method public K higherKey(K);
+    method public java.util.NavigableSet<K> keySet();
     method public java.util.Map.Entry<K, V> lastEntry();
     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();
-    method public V putIfAbsent(K, V);
-    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);
@@ -65956,7 +66208,6 @@
     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);
@@ -66003,9 +66254,7 @@
     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 {
@@ -66164,6 +66413,7 @@
     method public java.lang.Thread.UncaughtExceptionHandler getUncaughtExceptionHandler();
     method public boolean hasQueuedSubmissions();
     method public <T> T invoke(java.util.concurrent.ForkJoinTask<T>);
+    method public <T> java.util.List<java.util.concurrent.Future<T>> invokeAll(java.util.Collection<? extends java.util.concurrent.Callable<T>>);
     method public boolean isQuiescent();
     method public boolean isShutdown();
     method public boolean isTerminated();
@@ -66173,6 +66423,9 @@
     method public void shutdown();
     method public java.util.List<java.lang.Runnable> shutdownNow();
     method public <T> java.util.concurrent.ForkJoinTask<T> submit(java.util.concurrent.ForkJoinTask<T>);
+    method public <T> java.util.concurrent.ForkJoinTask<T> submit(java.util.concurrent.Callable<T>);
+    method public <T> java.util.concurrent.ForkJoinTask<T> submit(java.lang.Runnable, T);
+    method public java.util.concurrent.ForkJoinTask<?> submit(java.lang.Runnable);
     field public static final java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory defaultForkJoinWorkerThreadFactory;
   }
 
@@ -66296,7 +66549,6 @@
     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;
@@ -66317,7 +66569,6 @@
     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;
   }
 
@@ -66337,7 +66588,6 @@
     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);
@@ -66385,7 +66635,6 @@
     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;
   }
 
@@ -66489,7 +66738,6 @@
     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;
   }
 
@@ -66501,9 +66749,11 @@
     method public static java.util.concurrent.ThreadLocalRandom current();
     method public double nextDouble(double);
     method public double nextDouble(double, double);
+    method public double nextGaussian();
     method public int nextInt(int, int);
     method public long nextLong(long);
     method public long nextLong(long, long);
+    method public void setSeed(long);
   }
 
   public class ThreadPoolExecutor extends java.util.concurrent.AbstractExecutorService {
@@ -66517,6 +66767,7 @@
     method public boolean awaitTermination(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
     method protected void beforeExecute(java.lang.Thread, java.lang.Runnable);
     method public void execute(java.lang.Runnable);
+    method protected void finalize();
     method public int getActiveCount();
     method public long getCompletedTaskCount();
     method public int getCorePoolSize();
@@ -67387,8 +67638,11 @@
     ctor public JarFile(java.io.File) throws java.io.IOException;
     ctor public JarFile(java.io.File, boolean) throws java.io.IOException;
     ctor public JarFile(java.io.File, boolean, int) throws java.io.IOException;
+    method public java.util.Enumeration<java.util.jar.JarEntry> entries();
+    method public synchronized java.io.InputStream getInputStream(java.util.zip.ZipEntry) throws java.io.IOException;
     method public java.util.jar.JarEntry getJarEntry(java.lang.String);
     method public java.util.jar.Manifest getManifest() throws java.io.IOException;
+    method public java.util.stream.Stream<java.util.jar.JarEntry> stream();
     field public static final java.lang.String MANIFEST_NAME = "META-INF/MANIFEST.MF";
   }
 
@@ -67468,6 +67722,8 @@
 
   public class ConsoleHandler extends java.util.logging.StreamHandler {
     ctor public ConsoleHandler();
+    method public void close();
+    method public void publish(java.util.logging.LogRecord);
   }
 
   public class ErrorManager {
@@ -68257,6 +68513,7 @@
     method public int deflate(byte[]);
     method public int deflate(byte[], int, int, int);
     method public void end();
+    method protected void finalize();
     method public void finish();
     method public boolean finished();
     method public int getAdler();
@@ -68289,6 +68546,8 @@
     ctor public DeflaterInputStream(java.io.InputStream);
     ctor public DeflaterInputStream(java.io.InputStream, java.util.zip.Deflater);
     ctor public DeflaterInputStream(java.io.InputStream, java.util.zip.Deflater, int);
+    method public void mark(int);
+    method public void reset() throws java.io.IOException;
     field protected final byte[] buf;
     field protected final java.util.zip.Deflater def;
   }
@@ -68319,6 +68578,7 @@
     ctor public GZIPOutputStream(java.io.OutputStream, int, boolean) throws java.io.IOException;
     ctor public GZIPOutputStream(java.io.OutputStream) throws java.io.IOException;
     ctor public GZIPOutputStream(java.io.OutputStream, boolean) throws java.io.IOException;
+    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     field protected java.util.zip.CRC32 crc;
   }
 
@@ -68326,6 +68586,7 @@
     ctor public Inflater(boolean);
     ctor public Inflater();
     method public void end();
+    method protected void finalize();
     method public boolean finished();
     method public int getAdler();
     method public long getBytesRead();
@@ -68452,6 +68713,7 @@
     ctor public ZipFile(java.io.File, java.nio.charset.Charset) throws java.io.IOException;
     method public void close() throws java.io.IOException;
     method public java.util.Enumeration<? extends java.util.zip.ZipEntry> entries();
+    method protected void finalize() throws java.io.IOException;
     method public java.lang.String getComment();
     method public java.util.zip.ZipEntry getEntry(java.lang.String);
     method public java.io.InputStream getInputStream(java.util.zip.ZipEntry) throws java.io.IOException;
@@ -68558,6 +68820,7 @@
     method public void setComment(java.lang.String);
     method public void setLevel(int);
     method public void setMethod(int);
+    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     field public static final int CENATT = 36; // 0x24
     field public static final int CENATX = 38; // 0x26
     field public static final int CENCOM = 32; // 0x20
@@ -68714,6 +68977,7 @@
 
   public class ExemptionMechanism {
     ctor protected ExemptionMechanism(javax.crypto.ExemptionMechanismSpi, java.security.Provider, java.lang.String);
+    method protected void finalize();
     method public final byte[] genExemptionBlob() throws javax.crypto.ExemptionMechanismException, java.lang.IllegalStateException;
     method public final int genExemptionBlob(byte[]) throws javax.crypto.ExemptionMechanismException, java.lang.IllegalStateException, javax.crypto.ShortBufferException;
     method public final int genExemptionBlob(byte[], int) throws javax.crypto.ExemptionMechanismException, java.lang.IllegalStateException, javax.crypto.ShortBufferException;
@@ -71102,6 +71366,7 @@
     ctor public TransformerException(java.lang.String, java.lang.Throwable);
     ctor public TransformerException(java.lang.String, javax.xml.transform.SourceLocator);
     ctor public TransformerException(java.lang.String, javax.xml.transform.SourceLocator, java.lang.Throwable);
+    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getException();
     method public java.lang.String getLocationAsString();
     method public javax.xml.transform.SourceLocator getLocator();
@@ -71372,6 +71637,7 @@
   public class XPathException extends java.lang.Exception {
     ctor public XPathException(java.lang.String);
     ctor public XPathException(java.lang.Throwable);
+    method public java.lang.Throwable getCause();
   }
 
   public abstract interface XPathExpression {
diff --git a/cmds/locksettings/src/com/android/commands/locksettings/LockSettingsCmd.java b/cmds/locksettings/src/com/android/commands/locksettings/LockSettingsCmd.java
index 1e426d6..b9fedd3 100644
--- a/cmds/locksettings/src/com/android/commands/locksettings/LockSettingsCmd.java
+++ b/cmds/locksettings/src/com/android/commands/locksettings/LockSettingsCmd.java
@@ -33,6 +33,10 @@
             "       locksettings set-pin [--old OLD_CREDENTIAL] NEW_PIN\n" +
             "       locksettings set-password [--old OLD_CREDENTIAL] NEW_PASSWORD\n" +
             "       locksettings clear [--old OLD_CREDENTIAL]\n" +
+            "       locksettings verify [--old OLD_CREDENTIAL]\n" +
+            "\n" +
+            "flags: \n" +
+            "       --user USER_ID: specify the user, default value is current user\n" +
             "\n" +
             "locksettings set-pattern: sets a pattern\n" +
             "    A pattern is specified by a non-separated list of numbers that index the cell\n" +
@@ -44,7 +48,9 @@
             "\n" +
             "locksettings set-password: sets a password\n" +
             "\n" +
-            "locksettings clear: clears the unlock credential\n";
+            "locksettings clear: clears the unlock credential\n" +
+            "\n" +
+            "locksettings verify: verifies the credential and unlocks the user\n";
 
     public static void main(String[] args) {
         (new LockSettingsCmd()).run(args);
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index 71be632..2366878 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -253,5 +253,5 @@
     }
 
     // b/36066697: Avoid running static destructors.
-    _exit(1);
+    _exit(0);
 }
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 199e856..06dbe82 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -360,6 +360,13 @@
             FIRST_START_NON_FATAL_ERROR_CODE + 1;
 
     /**
+     * Result for IActivityManaqer.startActivity: a new activity start was aborted. Never returned
+     * externally.
+     * @hide
+     */
+    public static final int START_ABORTED = FIRST_START_NON_FATAL_ERROR_CODE + 2;
+
+    /**
      * Flag for IActivityManaqer.startActivity: do special start mode where
      * a new activity is launched only if it is needed.
      * @hide
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 905a3ee..4a01fe6 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2361,13 +2361,13 @@
                         memInfo.nativeSwappablePss, memInfo.nativeSharedDirty,
                         memInfo.nativePrivateDirty, memInfo.nativeSharedClean,
                         memInfo.nativePrivateClean, memInfo.hasSwappedOutPss ?
-                        memInfo.nativeSwappedOut : memInfo.nativeSwappedOutPss,
+                        memInfo.nativeSwappedOutPss : memInfo.nativeSwappedOut,
                         nativeMax, nativeAllocated, nativeFree);
                 printRow(pw, HEAP_FULL_COLUMN, "Dalvik Heap", memInfo.dalvikPss,
                         memInfo.dalvikSwappablePss, memInfo.dalvikSharedDirty,
                         memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean,
                         memInfo.dalvikPrivateClean, memInfo.hasSwappedOutPss ?
-                        memInfo.dalvikSwappedOut : memInfo.dalvikSwappedOutPss,
+                        memInfo.dalvikSwappedOutPss : memInfo.dalvikSwappedOut,
                         dalvikMax, dalvikAllocated, dalvikFree);
             } else {
                 printRow(pw, HEAP_COLUMN, "", "Pss", "Private",
@@ -2678,8 +2678,14 @@
         Activity activity = null;
         try {
             java.lang.ClassLoader cl = appContext.getClassLoader();
-            activity = mInstrumentation.newActivity(
-                    cl, component.getClassName(), r.intent);
+            if (appContext.getApplicationContext() instanceof Application) {
+                activity = ((Application) appContext.getApplicationContext())
+                        .instantiateActivity(cl, component.getClassName(), r.intent);
+            }
+            if (activity == null) {
+                activity = mInstrumentation.newActivity(
+                        cl, component.getClassName(), r.intent);
+            }
             StrictMode.incrementExpectedActivityCount(activity.getClass());
             r.intent.setExtrasClassLoader(cl);
             r.intent.prepareToEnterProcess();
@@ -2956,6 +2962,7 @@
             r.activity.mTemporaryPause = true;
             mInstrumentation.callActivityOnPause(r.activity);
         }
+        checkAndBlockForNetworkAccess();
         deliverNewIntents(r, intents);
         if (resumed) {
             r.activity.performResume();
@@ -3204,7 +3211,8 @@
             data.intent.setExtrasClassLoader(cl);
             data.intent.prepareToEnterProcess();
             data.setExtrasClassLoader(cl);
-            receiver = (BroadcastReceiver)cl.loadClass(component).newInstance();
+            receiver = instantiate(cl, component, data.intent, app,
+                    Application::instantiateReceiver);
         } catch (Exception e) {
             if (DEBUG_BROADCAST) Slog.i(TAG,
                     "Finishing failed broadcast to " + data.intent.getComponent());
@@ -3292,12 +3300,13 @@
             } else {
                 try {
                     if (DEBUG_BACKUP) Slog.v(TAG, "Initializing agent class " + classname);
+                    ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
 
                     java.lang.ClassLoader cl = packageInfo.getClassLoader();
-                    agent = (BackupAgent) cl.loadClass(classname).newInstance();
+                    agent = instantiate(cl, classname, context,
+                            Application::instantiateBackupAgent);
 
                     // set up the agent's context
-                    ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
                     context.setOuterContext(agent);
                     agent.attach(context);
 
@@ -3357,9 +3366,12 @@
         LoadedApk packageInfo = getPackageInfoNoCheck(
                 data.info.applicationInfo, data.compatInfo);
         Service service = null;
+        Application app = null;
         try {
+            app = packageInfo.makeApplication(false, mInstrumentation);
             java.lang.ClassLoader cl = packageInfo.getClassLoader();
-            service = (Service) cl.loadClass(data.info.name).newInstance();
+            service = instantiate(cl, data.info.name, data.intent, app,
+                    Application::instantiateService);
         } catch (Exception e) {
             if (!mInstrumentation.onException(service, e)) {
                 throw new RuntimeException(
@@ -3374,7 +3386,6 @@
             ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
             context.setOuterContext(service);
 
-            Application app = packageInfo.makeApplication(false, mInstrumentation);
             service.attach(context, this, data.info.name, data.token, app,
                     ActivityManager.getService());
             service.onCreate();
@@ -3585,6 +3596,7 @@
             try {
                 r.activity.onStateNotSaved();
                 r.activity.mFragments.noteStateNotSaved();
+                checkAndBlockForNetworkAccess();
                 if (r.pendingIntents != null) {
                     deliverNewIntents(r, r.pendingIntents);
                     r.pendingIntents = null;
@@ -4340,6 +4352,7 @@
                     }
                 }
             }
+            checkAndBlockForNetworkAccess();
             deliverResults(r, res.results);
             if (resumed) {
                 r.activity.performResume();
@@ -5691,8 +5704,8 @@
 
             try {
                 final ClassLoader cl = instrContext.getClassLoader();
-                mInstrumentation = (Instrumentation)
-                    cl.loadClass(data.instrumentationName.getClassName()).newInstance();
+                mInstrumentation = instantiate(cl, data.instrumentationName.getClassName(),
+                        instrContext, Application::instantiateInstrumentation);
             } catch (Exception e) {
                 throw new RuntimeException(
                     "Unable to instantiate instrumentation "
@@ -6237,8 +6250,8 @@
 
             try {
                 final java.lang.ClassLoader cl = c.getClassLoader();
-                localProvider = (ContentProvider)cl.
-                    loadClass(info.name).newInstance();
+                localProvider = instantiate(cl, info.name, context,
+                        Application::instantiateProvider);
                 provider = localProvider.getIContentProvider();
                 if (provider == null) {
                     Slog.e(TAG, "Failed to instantiate class " +
@@ -6437,6 +6450,38 @@
         }
     }
 
+    private <T> T instantiate(ClassLoader cl, String className, Context c,
+            Instantiator<T> instantiator)
+            throws ClassNotFoundException, IllegalAccessException, InstantiationException {
+        if (c.getApplicationContext() instanceof Application) {
+            T a = instantiator.instantiate((Application) c.getApplicationContext(),
+                    cl, className);
+            if (a != null) return a;
+        }
+        return (T) cl.loadClass(className).newInstance();
+    }
+
+    private <T> T instantiate(ClassLoader cl, String className, Intent intent, Context c,
+            IntentInstantiator<T> instantiator)
+            throws ClassNotFoundException, IllegalAccessException, InstantiationException {
+        if (c.getApplicationContext() instanceof Application) {
+            T a = instantiator.instantiate((Application) c.getApplicationContext(),
+                    cl, className, intent);
+            if (a != null) return a;
+        }
+        return (T) cl.loadClass(className).newInstance();
+    }
+
+    private interface Instantiator<T> {
+        T instantiate(Application app, ClassLoader cl, String className)
+                throws ClassNotFoundException, IllegalAccessException, InstantiationException;
+    }
+
+    private interface IntentInstantiator<T> {
+        T instantiate(Application app, ClassLoader cl, String className, Intent intent)
+                throws ClassNotFoundException, IllegalAccessException, InstantiationException;
+    }
+
     private static class EventLoggingReporter implements EventLogger.Reporter {
         @Override
         public void report (int code, Object... list) {
diff --git a/core/java/android/app/Application.java b/core/java/android/app/Application.java
index 156df36..cc23ec9 100644
--- a/core/java/android/app/Application.java
+++ b/core/java/android/app/Application.java
@@ -16,17 +16,20 @@
 
 package android.app;
 
-import java.util.ArrayList;
-
 import android.annotation.CallSuper;
+import android.app.backup.BackupAgent;
+import android.content.BroadcastReceiver;
 import android.content.ComponentCallbacks;
 import android.content.ComponentCallbacks2;
+import android.content.ContentProvider;
 import android.content.Context;
 import android.content.ContextWrapper;
 import android.content.Intent;
 import android.content.res.Configuration;
 import android.os.Bundle;
 
+import java.util.ArrayList;
+
 /**
  * Base class for maintaining global application state. You can provide your own
  * implementation by creating a subclass and specifying the fully-qualified name
@@ -289,4 +292,73 @@
             }
         }
     }
+
+    /**
+     * Allows application to override the creation of activities. This can be used to
+     * perform things such as dependency injection or class loader changes to these
+     * classes. Return null to use the default creation flow.
+     * @param cl The default classloader to use for instantiation.
+     * @param className The class to be instantiated.
+     * @param intent Intent creating the class.
+     */
+    public Activity instantiateActivity(ClassLoader cl, String className, Intent intent) {
+        return null;
+    }
+
+    /**
+     * Allows application to override the creation of receivers. This can be used to
+     * perform things such as dependency injection or class loader changes to these
+     * classes. Return null to use the default creation flow.
+     * @param cl The default classloader to use for instantiation.
+     * @param className The class to be instantiated.
+     * @param intent Intent creating the class.
+     */
+    public BroadcastReceiver instantiateReceiver(ClassLoader cl, String className, Intent intent) {
+        return null;
+    }
+
+    /**
+     * Allows application to override the creation of services. This can be used to
+     * perform things such as dependency injection or class loader changes to these
+     * classes. Return null to use the default creation flow.
+     * @param cl The default classloader to use for instantiation.
+     * @param className The class to be instantiated.
+     * @param intent Intent creating the class.
+     */
+    public Service instantiateService(ClassLoader cl, String className, Intent intent) {
+        return null;
+    }
+
+    /**
+     * Allows application to override the creation of providers. This can be used to
+     * perform things such as dependency injection or class loader changes to these
+     * classes. Return null to use the default creation flow.
+     * @param cl The default classloader to use for instantiation.
+     * @param className The class to be instantiated.
+     */
+    public ContentProvider instantiateProvider(ClassLoader cl, String className) {
+        return null;
+    }
+
+    /**
+     * Allows application to override the creation of backup agents. This can be used to
+     * perform things such as dependency injection or class loader changes to these
+     * classes. Return null to use the default creation flow.
+     * @param cl The default classloader to use for instantiation.
+     * @param className The class to be instantiated.
+     */
+    public BackupAgent instantiateBackupAgent(ClassLoader cl, String className) {
+        return null;
+    }
+
+    /**
+     * Allows application to override the creation of instrumentation. This can be used to
+     * perform things such as dependency injection or class loader changes to these
+     * classes. Return null to use the default creation flow.
+     * @param cl The default classloader to use for instantiation.
+     * @param className The class to be instantiated.
+     */
+    public Instrumentation instantiateInstrumentation(ClassLoader cl, String className) {
+        return null;
+    }
 }
\ No newline at end of file
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index a040520f..9c9d655 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -63,6 +63,7 @@
 import android.os.SystemProperties;
 import android.os.Trace;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.os.storage.IStorageManager;
 import android.os.storage.StorageManager;
 import android.system.ErrnoException;
@@ -370,13 +371,6 @@
         return getSharedPreferences(file, mode);
     }
 
-    private boolean isBuggy() {
-        // STOPSHIP: fix buggy apps
-        if (SystemProperties.getBoolean("fw.ignore_buggy", false)) return false;
-        if ("com.google.android.tts".equals(getApplicationInfo().packageName)) return true;
-        return false;
-    }
-
     @Override
     public SharedPreferences getSharedPreferences(File file, int mode) {
         SharedPreferencesImpl sp;
@@ -387,9 +381,8 @@
                 checkMode(mode);
                 if (getApplicationInfo().targetSdkVersion >= android.os.Build.VERSION_CODES.O) {
                     if (isCredentialProtectedStorage()
-                            && !getSystemService(StorageManager.class).isUserKeyUnlocked(
-                            UserHandle.myUserId())
-                            && !isBuggy()) {
+                            && !getSystemService(UserManager.class)
+                                    .isUserUnlockingOrUnlocked(UserHandle.myUserId())) {
                         throw new IllegalStateException("SharedPreferences in credential encrypted "
                                 + "storage are not available until after user is unlocked");
                     }
@@ -2157,6 +2150,14 @@
     }
 
     @Override
+    public boolean canLoadUnsafeResources() {
+        if (getPackageName().equals(getOpPackageName())) {
+            return true;
+        }
+        return (mFlags & Context.CONTEXT_IGNORE_SECURITY) != 0;
+    }
+
+    @Override
     public Display getDisplay() {
         if (mDisplay == null) {
             return mResourcesManager.getAdjustedDisplay(Display.DEFAULT_DISPLAY,
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 46f115f..79e5407 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -455,6 +455,7 @@
                 if (!outZipPaths.contains(lib)) {
                     outZipPaths.add(index, lib);
                     index++;
+                    appendApkLibPathIfNeeded(lib, aInfo, outLibPaths);
                 }
             }
         }
@@ -463,11 +464,33 @@
             for (String lib : instrumentationLibs) {
                 if (!outZipPaths.contains(lib)) {
                     outZipPaths.add(0, lib);
+                    appendApkLibPathIfNeeded(lib, aInfo, outLibPaths);
                 }
             }
         }
     }
 
+    /**
+     * This method appends a path to the appropriate native library folder of a
+     * library if this library is hosted in an APK. This allows support for native
+     * shared libraries. The library API is determined based on the application
+     * ABI.
+     *
+     * @param path Path to the library.
+     * @param applicationInfo The application depending on the library.
+     * @param outLibPaths List to which to add the native lib path if needed.
+     */
+    private static void appendApkLibPathIfNeeded(@NonNull String path,
+            @NonNull ApplicationInfo applicationInfo, @Nullable List<String> outLibPaths) {
+        // Looking at the suffix is a little hacky but a safe and simple solution.
+        // We will be revisiting code in the next release and clean this up.
+        if (outLibPaths != null && applicationInfo.primaryCpuAbi != null && path.endsWith(".apk")) {
+            if (applicationInfo.targetSdkVersion >= Build.VERSION_CODES.O) {
+                outLibPaths.add(path + "!/lib/" + applicationInfo.primaryCpuAbi);
+            }
+        }
+    }
+
     /*
      * All indices received by the super class should be shifted by 1 when accessing mSplitNames,
      * etc. The super class assumes the base APK is index 0, while the PackageManager APIs don't
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 1d1a590..5a08cf3 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -4937,7 +4937,6 @@
             if (mStyle != null) {
                 mStyle.buildStyled(mN);
             }
-
             if (mContext.getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.N
                     && (useExistingRemoteView())) {
                 if (mN.contentView == null) {
@@ -4980,18 +4979,20 @@
 
         /**
          * Removes RemoteViews that were created for compatibility from {@param n}, if they did not
-         * change.
+         * change. Also removes extenders on low ram devices, as
+         * {@link android.service.notification.NotificationListenerService} services are disabled.
          *
          * @return {@param n}, if no stripping is needed, otherwise a stripped clone of {@param n}.
          *
          * @hide
          */
-        public static Notification maybeCloneStrippedForDelivery(Notification n) {
+        public static Notification maybeCloneStrippedForDelivery(Notification n, boolean isLowRam) {
             String templateClass = n.extras.getString(EXTRA_TEMPLATE);
 
             // Only strip views for known Styles because we won't know how to
             // re-create them otherwise.
-            if (!TextUtils.isEmpty(templateClass)
+            if (!isLowRam
+                    && !TextUtils.isEmpty(templateClass)
                     && getNotificationStyleClass(templateClass) == null) {
                 return n;
             }
@@ -5008,7 +5009,8 @@
                             n.headsUpContentView.getSequenceNumber();
 
             // Nothing to do here, no need to clone.
-            if (!stripContentView && !stripBigContentView && !stripHeadsUpContentView) {
+            if (!isLowRam
+                    && !stripContentView && !stripBigContentView && !stripHeadsUpContentView) {
                 return n;
             }
 
@@ -5025,6 +5027,11 @@
                 clone.headsUpContentView = null;
                 clone.extras.remove(EXTRA_REBUILD_HEADS_UP_CONTENT_VIEW_ACTION_COUNT);
             }
+            if (isLowRam) {
+                clone.extras.remove(Notification.TvExtender.EXTRA_TV_EXTENDER);
+                clone.extras.remove(WearableExtender.EXTRA_WEARABLE_EXTENSIONS);
+                clone.extras.remove(CarExtender.EXTRA_CAR_EXTENDER);
+            }
             return clone;
         }
 
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index a519125..26889a1 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -307,7 +307,9 @@
             }
         }
         if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
-        final Notification copy = Builder.maybeCloneStrippedForDelivery(notification);
+        ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
+        boolean isLowRam = am.isLowRamDevice();
+        final Notification copy = Builder.maybeCloneStrippedForDelivery(notification, isLowRam);
         try {
             service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
                     copy, user.getIdentifier());
diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java
index d9b6eed..5a356d9 100644
--- a/core/java/android/app/admin/DeviceAdminReceiver.java
+++ b/core/java/android/app/admin/DeviceAdminReceiver.java
@@ -238,8 +238,7 @@
      * {@link android.app.admin.DevicePolicyManager#isProfileOwnerApp}. You will generally handle
      * this in {@link DeviceAdminReceiver#onProfileProvisioningComplete}.
      *
-     * <p>Input: Nothing.</p>
-     * <p>Output: Nothing</p>
+     * @see DevicePolicyManager#ACTION_PROVISIONING_SUCCESSFUL
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     @BroadcastBehavior(explicitOnly = true)
@@ -669,6 +668,11 @@
      * profile owner needs to wait for data to be available if required (e.g. android device ids or
      * other data that is set as a result of server interactions).
      *
+     * <p>From version {@link android.os.Build.VERSION_CODES#O}, when managed provisioning has
+     * completed, along with this callback the activity intent
+     * {@link DevicePolicyManager#ACTION_PROVISIONING_SUCCESSFUL} will also be sent to the same
+     * application.
+     *
      * @param context The running context as per {@link #onReceive}.
      * @param intent The received intent as per {@link #onReceive}.
      */
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index ff9425e..f612eaa 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -55,7 +55,6 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.ContactsContract.Directory;
-import android.provider.Settings;
 import android.security.Credentials;
 import android.service.restrictions.RestrictionsReceiver;
 import android.telephony.TelephonyManager;
@@ -170,8 +169,7 @@
      *
      * <p>From version {@link android.os.Build.VERSION_CODES#O}, when managed provisioning has
      * completed, along with the above broadcast, activity intent
-     * {@link #ACTION_PROVISIONING_SUCCESSFUL} will also be sent to the application specified in
-     * the provisioning intent.
+     * {@link #ACTION_PROVISIONING_SUCCESSFUL} will also be sent to the profile owner.
      *
      * <p>If provisioning fails, the managedProfile is removed so the device returns to its
      * previous state.
@@ -858,8 +856,7 @@
      * {@link DeviceAdminReceiver#ACTION_PROFILE_PROVISIONING_COMPLETE} broadcast but this will be
      * delivered faster as it's an activity intent.
      *
-     * <p>The intent is only sent to the application on the profile that requested provisioning. In
-     * the device owner case the profile is the primary user.
+     * <p>The intent is only sent to the new device or profile owner.
      *
      * @see #ACTION_PROVISION_MANAGED_PROFILE
      * @see #ACTION_PROVISION_MANAGED_DEVICE
@@ -3135,6 +3132,14 @@
     public static final int WIPE_RESET_PROTECTION_DATA = 0x0002;
 
     /**
+     * Flag for {@link #wipeData(int)}: also erase the device's eUICC data.
+     *
+     * TODO(b/35851809): make this public.
+     * @hide
+     */
+    public static final int WIPE_EUICC = 0x0004;
+
+    /**
      * Ask that all user data be wiped. If called as a secondary user, the user will be removed and
      * other users will remain unaffected. Calling from the primary user will cause the device to
      * reboot, erasing all device data - including all the secondary users and their data - while
@@ -6417,34 +6422,35 @@
     }
 
     /**
-     * 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.
+     * Called by device owners to update {@link android.provider.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:
      * <ul>
-     * <li>{@link Settings.Global#ADB_ENABLED}</li>
-     * <li>{@link Settings.Global#AUTO_TIME}</li>
-     * <li>{@link Settings.Global#AUTO_TIME_ZONE}</li>
-     * <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
+     * <li>{@link android.provider.Settings.Global#ADB_ENABLED}</li>
+     * <li>{@link android.provider.Settings.Global#AUTO_TIME}</li>
+     * <li>{@link android.provider.Settings.Global#AUTO_TIME_ZONE}</li>
+     * <li>{@link android.provider.Settings.Global#DATA_ROAMING}</li>
+     * <li>{@link android.provider.Settings.Global#USB_MASS_STORAGE_ENABLED}</li>
+     * <li>{@link android.provider.Settings.Global#WIFI_SLEEP_POLICY}</li>
+     * <li>{@link android.provider.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 android.provider.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}:
      * <ul>
-     * <li>{@link Settings.Global#BLUETOOTH_ON}. Use
+     * <li>{@link android.provider.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
+     * <li>{@link android.provider.Settings.Global#DEVELOPMENT_SETTINGS_ENABLED}</li>
+     * <li>{@link android.provider.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
+     * <li>{@link android.provider.Settings.Global#NETWORK_PREFERENCE}</li>
+     * <li>{@link android.provider.Settings.Global#WIFI_ON}. Use
      * {@link android.net.wifi.WifiManager#setWifiEnabled(boolean)} instead.</li>
      * </ul>
      *
@@ -6465,19 +6471,19 @@
     }
 
     /**
-     * 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.
+     * Called by profile or device owners to update {@link android.provider.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:
      * <ul>
-     * <li>{@link Settings.Secure#DEFAULT_INPUT_METHOD}</li>
-     * <li>{@link Settings.Secure#SKIP_FIRST_USE_HINTS}</li>
+     * <li>{@link android.provider.Settings.Secure#DEFAULT_INPUT_METHOD}</li>
+     * <li>{@link android.provider.Settings.Secure#SKIP_FIRST_USE_HINTS}</li>
      * </ul>
      * <p>
      * A device owner can additionally update the following settings:
      * <ul>
-     * <li>{@link Settings.Secure#LOCATION_MODE}</li>
+     * <li>{@link android.provider.Settings.Secure#LOCATION_MODE}</li>
      * </ul>
      *
      * <strong>Note: Starting from Android O, apps should no longer call this method with the
diff --git a/core/java/android/app/timezone/RulesState.java b/core/java/android/app/timezone/RulesState.java
index 33f4e80..7d6ad21 100644
--- a/core/java/android/app/timezone/RulesState.java
+++ b/core/java/android/app/timezone/RulesState.java
@@ -174,29 +174,14 @@
     }
 
     /**
-     * Returns true if the distro IANA rules version supplied is newer or the same as the version in
-     * the system image data files.
+     * Returns true if the system image data files contain IANA rules data that are newer than the
+     * distro IANA rules version supplied, i.e. true when the version specified would be "worse"
+     * than the one that is in the system image. Returns false if the system image version is the
+     * same or older, i.e. false when the version specified would be "better" than the one that is
+     * in the system image.
      */
-    public boolean isSystemVersionOlderThan(DistroRulesVersion distroRulesVersion) {
-        return mSystemRulesVersion.compareTo(distroRulesVersion.getRulesVersion()) < 0;
-    }
-
-    public boolean isDistroInstalled() {
-        return mDistroStatus == DISTRO_STATUS_INSTALLED;
-    }
-
-    /**
-     * Returns true if the rules version supplied is newer than the one currently installed. If
-     * there is no installed distro this method throws IllegalStateException.
-     */
-    public boolean isInstalledDistroOlderThan(DistroRulesVersion distroRulesVersion) {
-        if (mOperationInProgress) {
-            throw new IllegalStateException("Distro state not known: operation in progress.");
-        }
-        if (!isDistroInstalled()) {
-            throw new IllegalStateException("No distro installed.");
-        }
-        return mInstalledDistroRulesVersion.isOlderThan(distroRulesVersion);
+    public boolean isSystemVersionNewerThan(DistroRulesVersion distroRulesVersion) {
+        return mSystemRulesVersion.compareTo(distroRulesVersion.getRulesVersion()) > 0;
     }
 
     public static final Parcelable.Creator<RulesState> CREATOR =
diff --git a/core/java/android/appwidget/AppWidgetHost.java b/core/java/android/appwidget/AppWidgetHost.java
index c1ff580..37360ba 100644
--- a/core/java/android/appwidget/AppWidgetHost.java
+++ b/core/java/android/appwidget/AppWidgetHost.java
@@ -16,15 +16,13 @@
 
 package android.appwidget;
 
-import java.lang.ref.WeakReference;
-import java.util.List;
-
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.Activity;
 import android.content.ActivityNotFoundException;
 import android.content.Context;
 import android.content.IntentSender;
+import android.content.pm.PackageManager;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
@@ -42,6 +40,9 @@
 import com.android.internal.appwidget.IAppWidgetHost;
 import com.android.internal.appwidget.IAppWidgetService;
 
+import java.lang.ref.WeakReference;
+import java.util.List;
+
 /**
  * AppWidgetHost provides the interaction with the AppWidget service for apps,
  * like the home screen, that want to embed AppWidgets in their UI.
@@ -55,6 +56,7 @@
 
     final static Object sServiceLock = new Object();
     static IAppWidgetService sService;
+    static boolean sServiceInitialized = false;
     private DisplayMetrics mDisplayMetrics;
 
     private String mContextOpPackageName;
@@ -160,15 +162,21 @@
         mHandler = new UpdateHandler(looper);
         mCallbacks = new Callbacks(mHandler);
         mDisplayMetrics = context.getResources().getDisplayMetrics();
-        bindService();
+        bindService(context);
     }
 
-    private static void bindService() {
+    private static void bindService(Context context) {
         synchronized (sServiceLock) {
-            if (sService == null) {
-                IBinder b = ServiceManager.getService(Context.APPWIDGET_SERVICE);
-                sService = IAppWidgetService.Stub.asInterface(b);
+            if (sServiceInitialized) {
+                return;
             }
+            sServiceInitialized = true;
+            if (!context.getPackageManager().hasSystemFeature(
+                    PackageManager.FEATURE_APP_WIDGETS)) {
+                return;
+            }
+            IBinder b = ServiceManager.getService(Context.APPWIDGET_SERVICE);
+            sService = IAppWidgetService.Stub.asInterface(b);
         }
     }
 
@@ -177,6 +185,9 @@
      * becomes visible, i.e. from onStart() in your Activity.
      */
     public void startListening() {
+        if (sService == null) {
+            return;
+        }
         final int[] idsToUpdate;
         synchronized (mViews) {
             int N = mViews.size();
@@ -215,6 +226,9 @@
      * no longer visible, i.e. from onStop() in your Activity.
      */
     public void stopListening() {
+        if (sService == null) {
+            return;
+        }
         try {
             sService.stopListening(mContextOpPackageName, mHostId);
         }
@@ -229,6 +243,9 @@
      * @return a appWidgetId
      */
     public int allocateAppWidgetId() {
+        if (sService == null) {
+            return -1;
+        }
         try {
             return sService.allocateAppWidgetId(mContextOpPackageName, mHostId);
         }
@@ -258,6 +275,9 @@
      */
     public final void startAppWidgetConfigureActivityForResult(@NonNull Activity activity,
             int appWidgetId, int intentFlags, int requestCode, @Nullable Bundle options) {
+        if (sService == null) {
+            return;
+        }
         try {
             IntentSender intentSender = sService.createAppWidgetConfigIntentSender(
                     mContextOpPackageName, appWidgetId, intentFlags);
@@ -278,10 +298,10 @@
      * Gets a list of all the appWidgetIds that are bound to the current host
      */
     public int[] getAppWidgetIds() {
+        if (sService == null) {
+            return new int[0];
+        }
         try {
-            if (sService == null) {
-                bindService();
-            }
             return sService.getAppWidgetIdsForHost(mContextOpPackageName, mHostId);
         } catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
@@ -292,6 +312,9 @@
      * Stop listening to changes for this AppWidget.
      */
     public void deleteAppWidgetId(int appWidgetId) {
+        if (sService == null) {
+            return;
+        }
         synchronized (mViews) {
             mViews.remove(appWidgetId);
             try {
@@ -312,6 +335,9 @@
      * </ul>
      */
     public void deleteHost() {
+        if (sService == null) {
+            return;
+        }
         try {
             sService.deleteHost(mContextOpPackageName, mHostId);
         }
@@ -329,6 +355,9 @@
      * </ul>
      */
     public static void deleteAllHosts() {
+        if (sService == null) {
+            return;
+        }
         try {
             sService.deleteAllHosts();
         }
@@ -343,6 +372,9 @@
      */
     public final AppWidgetHostView createView(Context context, int appWidgetId,
             AppWidgetProviderInfo appWidget) {
+        if (sService == null) {
+            return null;
+        }
         AppWidgetHostView view = onCreateView(context, appWidgetId, appWidget);
         view.setOnClickHandler(mOnClickHandler);
         view.setAppWidget(appWidgetId, appWidget);
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 64c0f31..fc3a724 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -70,9 +70,10 @@
  * devices, and start a scan for Bluetooth LE devices.
  *
  * <p>To get a {@link BluetoothAdapter} representing the local Bluetooth
- * adapter, when running on JELLY_BEAN_MR1 and below, call the
- * static {@link #getDefaultAdapter} method; when running on JELLY_BEAN_MR2 and
- * higher, call {@link BluetoothManager#getAdapter}.
+ * adapter, call the {@link BluetoothManager#getAdapter} function on {@link BluetoothManager}.
+ * On JELLY_BEAN_MR1 and below you will need to use the static {@link #getDefaultAdapter}
+ * method instead.
+ * </p><p>
  * Fundamentally, this is your starting point for all
  * Bluetooth actions. Once you have the local adapter, you can get a set of
  * {@link BluetoothDevice} objects representing all paired devices with
@@ -81,14 +82,13 @@
  * listen for incoming connection requests with
  * {@link #listenUsingRfcommWithServiceRecord(String,UUID)}; or start a scan for
  * Bluetooth LE devices with {@link #startLeScan(LeScanCallback callback)}.
- *
- * <p>This class is thread safe.
- *
+ * </p>
+ * <p>This class is thread safe.</p>
  * <p class="note"><strong>Note:</strong>
  * Most methods require the {@link android.Manifest.permission#BLUETOOTH}
  * permission and some also require the
  * {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
- *
+ * </p>
  * <div class="special reference">
  * <h3>Developer Guides</h3>
  * <p>
@@ -565,6 +565,7 @@
      * <p>Currently Android only supports one Bluetooth adapter, but the API
      * could be extended to support more. This will always return the default
      * adapter.
+     * </p>
      * @return the default local adapter, or null if Bluetooth is not supported
      *         on this hardware platform
      */
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 7ff37d2..27b802e 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -203,6 +203,34 @@
             "android.bluetooth.device.action.BOND_STATE_CHANGED";
 
     /**
+     * Broadcast Action: Indicates the battery level of a remote device has
+     * been retrieved for the first time, or changed since the last retrieval
+     * <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link
+     * #EXTRA_BATTERY_LEVEL}.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_BATTERY_LEVEL_CHANGED =
+            "android.bluetooth.device.action.BATTERY_LEVEL_CHANGED";
+
+    /**
+     * Used as an Integer extra field in {@link #ACTION_BATTERY_LEVEL_CHANGED}
+     * intent. It contains the most recently retrieved battery level information
+     * ranging from 0% to 100% for a remote device, {@link #BATTERY_LEVEL_UNKNOWN}
+     * when the valid is unknown or there is an error
+     * @hide
+     */
+    public static final String EXTRA_BATTERY_LEVEL =
+            "android.bluetooth.device.extra.BATTERY_LEVEL";
+
+    /**
+     * Used as the unknown value for {@link #EXTRA_BATTERY_LEVEL} and {@link #getBatteryLevel()}
+     * @hide
+     */
+    public static final int BATTERY_LEVEL_UNKNOWN = -1;
+
+    /**
      * Used as a Parcelable {@link BluetoothDevice} extra field in every intent
      * broadcast by this class. It contains the {@link BluetoothDevice} that
      * the intent applies to.
@@ -861,6 +889,27 @@
     }
 
     /**
+     * Get the most recent identified battery level of this Bluetooth device
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
+     *
+     * @return Battery level in percents from 0 to 100, or {@link #BATTERY_LEVEL_UNKNOWN} if
+     *         Bluetooth is disabled, or device is disconnected, or does not have any battery
+     *         reporting service, or return value is invalid
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.BLUETOOTH)
+    public int getBatteryLevel() {
+        if (sService == null) {
+            Log.e(TAG, "Bluetooth disabled. Cannot get remote device battery level");
+            return BATTERY_LEVEL_UNKNOWN;
+        }
+        try {
+            return sService.getBatteryLevel(this);
+        } catch (RemoteException e) {Log.e(TAG, "", e);}
+        return BATTERY_LEVEL_UNKNOWN;
+    }
+
+    /**
      * Start the bonding (pairing) process with the remote device.
      * <p>This is an asynchronous call, it will return immediately. Register
      * for {@link #ACTION_BOND_STATE_CHANGED} intents to be notified when
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index 57b954f..5b8d81d 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -227,14 +227,13 @@
      *
      * <p>This intent will have 3 extras:
      * <ul>
-     *   <li> {@link #EXTRA_IND_ID} - The Assigned number of headset Indicator which is supported by
-                                        the headset ( as indicated by AT+BIND
-                                        command in the SLC sequence).or whose value
-                                        is changed (indicated by AT+BIEV command)</li>
-     *   <li> {@link #EXTRA_IND_VALUE}- The updated value of headset indicator. </li>
+     *   <li> {@link #EXTRA_HF_INDICATORS_IND_ID} - The Assigned number of headset Indicator which
+     *              is supported by the headset ( as indicated by AT+BIND command in the SLC
+     *              sequence).or whose value is changed (indicated by AT+BIEV command) </li>
+     *   <li> {@link #EXTRA_HF_INDICATORS_IND_VALUE}- The updated value of headset indicator. </li>
      *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
      * </ul>
-     * <p>{@link #EXTRA_IND_ID} is defined by Bluetooth SIG and each of the indicators are
+     * <p>{@link #EXTRA_HF_INDICATORS_IND_ID} is defined by Bluetooth SIG and each of the indicators are
      * given an assigned number. Below shows the assigned number of Indicator added so far
      * - Enhanced Safety - 1
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
diff --git a/core/java/android/bluetooth/BluetoothManager.java b/core/java/android/bluetooth/BluetoothManager.java
index e2fa38a..bacce80 100644
--- a/core/java/android/bluetooth/BluetoothManager.java
+++ b/core/java/android/bluetooth/BluetoothManager.java
@@ -33,10 +33,7 @@
  * Use {@link android.content.Context#getSystemService(java.lang.String)}
  * with {@link Context#BLUETOOTH_SERVICE} to create an {@link BluetoothManager},
  * then call {@link #getAdapter} to obtain the {@link BluetoothAdapter}.
- * <p>
- * Alternately, you can just call the static helper
- * {@link BluetoothAdapter#getDefaultAdapter()}.
- *
+ * </p>
  * <div class="special reference">
  * <h3>Developer Guides</h3>
  * <p>
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index 43c5ae4..1d7cfc9 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -75,6 +75,7 @@
     ParcelUuid[] getRemoteUuids(in BluetoothDevice device);
     boolean fetchRemoteUuids(in BluetoothDevice device);
     boolean sdpSearch(in BluetoothDevice device, in ParcelUuid uuid);
+    int getBatteryLevel(in BluetoothDevice device);
 
     boolean setPin(in BluetoothDevice device, boolean accept, int len, in byte[] pinCode);
     boolean setPasskey(in BluetoothDevice device, boolean accept, int len, in byte[]
diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java
index f3f0ae5..1eac395 100644
--- a/core/java/android/bluetooth/le/BluetoothLeScanner.java
+++ b/core/java/android/bluetooth/le/BluetoothLeScanner.java
@@ -136,6 +136,11 @@
      * Start Bluetooth LE scan using a {@link PendingIntent}. The scan results will be delivered via
      * the PendingIntent. Use this method of scanning if your process is not always running and it
      * should be started when scan results are available.
+     * <p>
+     * When the PendingIntent is delivered, the Intent passed to the receiver or activity
+     * will contain one or more of the extras {@link #EXTRA_CALLBACK_TYPE},
+     * {@link #EXTRA_ERROR_CODE} and {@link #EXTRA_LIST_SCAN_RESULT} to indicate the result of
+     * the scan.
      *
      * @param filters Optional list of ScanFilters for finding exact BLE devices.
      * @param settings Optional settings for the scan.
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 5929aca..128d195 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3913,7 +3913,7 @@
      * @see #getSystemService
      * @hide
      */
-    public static final String RADIO_SERVICE = "radio";
+    public static final String RADIO_SERVICE = "broadcastradio";
 
     /**
      * Use with {@link #getSystemService} to retrieve a
@@ -4681,6 +4681,12 @@
     public abstract boolean isCredentialProtectedStorage();
 
     /**
+     * Returns true if the context can load unsafe resources, e.g. fonts.
+     * @hide
+     */
+    public abstract boolean canLoadUnsafeResources();
+
+    /**
      * @hide
      */
     public IBinder getActivityToken() {
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index c719c64..a9fd58b 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -925,6 +925,12 @@
         return mBase.isCredentialProtectedStorage();
     }
 
+    /** {@hide} */
+    @Override
+    public boolean canLoadUnsafeResources() {
+        return mBase.canLoadUnsafeResources();
+    }
+
     /**
      * @hide
      */
diff --git a/core/java/android/content/pm/LauncherActivityInfo.java b/core/java/android/content/pm/LauncherActivityInfo.java
index 358787e..e9c9588 100644
--- a/core/java/android/content/pm/LauncherActivityInfo.java
+++ b/core/java/android/content/pm/LauncherActivityInfo.java
@@ -20,12 +20,10 @@
 import android.content.Context;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Resources;
-import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.util.DisplayMetrics;
-import android.util.Log;
 
 /**
  * A representation of an activity that can belong to this user or a managed
@@ -173,12 +171,6 @@
     public Drawable getBadgedIcon(int density) {
         Drawable originalIcon = getIcon(density);
 
-        if (originalIcon instanceof BitmapDrawable) {
-            // TODO: Go through LauncherAppsService
-            return mPm.getUserBadgedIcon(originalIcon, mUser);
-        } else {
-            Log.e(TAG, "Unable to create badged icon for " + mActivityInfo);
-        }
-        return originalIcon;
+        return mPm.getUserBadgedIcon(originalIcon, mUser);
     }
 }
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 5eca57b..bdf0562 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -27,6 +27,7 @@
 import android.app.AppGlobals;
 import android.content.Intent;
 import android.content.IntentSender;
+import android.content.pm.PackageManager.DeleteFlags;
 import android.content.pm.PackageManager.InstallReason;
 import android.graphics.Bitmap;
 import android.net.Uri;
@@ -443,8 +444,24 @@
      * @param statusReceiver Where to deliver the result.
      */
     public void uninstall(@NonNull String packageName, @NonNull IntentSender statusReceiver) {
-       uninstall(new VersionedPackage(packageName, PackageManager.VERSION_CODE_HIGHEST),
-               statusReceiver);
+        uninstall(packageName, 0 /*flags*/, statusReceiver);
+    }
+
+    /**
+     * Uninstall the given package, removing it completely from the device. This
+     * method is only available to the current "installer of record" for the
+     * package.
+     *
+     * @param packageName The package to uninstall.
+     * @param flags Flags for uninstall.
+     * @param statusReceiver Where to deliver the result.
+     *
+     * @hide
+     */
+    public void uninstall(@NonNull String packageName, @DeleteFlags int flags,
+            @NonNull IntentSender statusReceiver) {
+        uninstall(new VersionedPackage(packageName, PackageManager.VERSION_CODE_HIGHEST),
+                flags, statusReceiver);
     }
 
     /**
@@ -458,15 +475,34 @@
      * @param versionedPackage The versioned package to uninstall.
      * @param statusReceiver Where to deliver the result.
      */
+    public void uninstall(@NonNull VersionedPackage versionedPackage,
+            @NonNull IntentSender statusReceiver) {
+        uninstall(versionedPackage, 0 /*flags*/, statusReceiver);
+    }
+
+    /**
+     * Uninstall the given package with a specific version code, removing it
+     * completely from the device. This method is only available to the current
+     * "installer of record" for the package. If the version code of the package
+     * does not match the one passed in the versioned package argument this
+     * method is a no-op. Use {@link PackageManager#VERSION_CODE_HIGHEST} to
+     * uninstall the latest version of the package.
+     *
+     * @param versionedPackage The versioned package to uninstall.
+     * @param flags Flags for uninstall.
+     * @param statusReceiver Where to deliver the result.
+     *
+     * @hide
+     */
     @RequiresPermission(anyOf = {
             Manifest.permission.DELETE_PACKAGES,
             Manifest.permission.REQUEST_DELETE_PACKAGES})
-    public void uninstall(@NonNull VersionedPackage versionedPackage,
+    public void uninstall(@NonNull VersionedPackage versionedPackage, @DeleteFlags int flags,
             @NonNull IntentSender statusReceiver) {
         Preconditions.checkNotNull(versionedPackage, "versionedPackage cannot be null");
         try {
             mInstaller.uninstall(versionedPackage, mInstallerPackageName,
-                    0, statusReceiver, mUserId);
+                    flags, statusReceiver, mUserId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 6bc7d42..712d37f 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1490,6 +1490,9 @@
      */
     public static final int MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL = -9;
 
+    /** @hide */
+    public static final int MOVE_FAILED_LOCKED_USER = -10;
+
     /**
      * Flag parameter for {@link #movePackage} to indicate that
      * the package should be moved to internal storage if its
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 2137f13..1b88ce7 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -6009,6 +6009,10 @@
             }
         }
 
+        public boolean isLibrary() {
+            return staticSharedLibName != null || !ArrayUtils.isEmpty(libraryNames);
+        }
+
         public List<String> getAllCodePaths() {
             ArrayList<String> paths = new ArrayList<>();
             paths.add(baseCodePath);
diff --git a/core/java/android/content/pm/permission/IRuntimePermissionPresenter.aidl b/core/java/android/content/pm/permission/IRuntimePermissionPresenter.aidl
index 3c3b84d..9490e27 100644
--- a/core/java/android/content/pm/permission/IRuntimePermissionPresenter.aidl
+++ b/core/java/android/content/pm/permission/IRuntimePermissionPresenter.aidl
@@ -25,4 +25,5 @@
  */
 oneway interface IRuntimePermissionPresenter {
     void getAppPermissions(String packageName, in RemoteCallback callback);
+    void revokeRuntimePermission(String packageName, String permissionName);
 }
diff --git a/core/java/android/content/pm/permission/RuntimePermissionPresenter.java b/core/java/android/content/pm/permission/RuntimePermissionPresenter.java
index 6d55d2f..02d0a6d 100644
--- a/core/java/android/content/pm/permission/RuntimePermissionPresenter.java
+++ b/core/java/android/content/pm/permission/RuntimePermissionPresenter.java
@@ -22,7 +22,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
-import android.content.pm.ApplicationInfo;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -31,6 +30,7 @@
 import android.os.RemoteException;
 import android.permissionpresenterservice.RuntimePermissionPresenterService;
 import android.util.Log;
+
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.SomeArgs;
 
@@ -118,6 +118,22 @@
         mRemoteService.processMessage(message);
     }
 
+    /**
+     * Revoke the permission {@code permissionName} for app {@code packageName}
+     *
+     * @param packageName The package for which to revoke
+     * @param permissionName The permission to revoke
+     */
+    public void revokeRuntimePermission(String packageName, String permissionName) {
+        SomeArgs args = SomeArgs.obtain();
+        args.arg1 = packageName;
+        args.arg2 = permissionName;
+
+        Message message = mRemoteService.obtainMessage(
+                RemoteService.MSG_REVOKE_APP_PERMISSIONS, args);
+        mRemoteService.processMessage(message);
+    }
+
     private static final class RemoteService
             extends Handler implements ServiceConnection {
         private static final long UNBIND_TIMEOUT_MILLIS = 10000;
@@ -125,6 +141,7 @@
         public static final int MSG_GET_APP_PERMISSIONS = 1;
         public static final int MSG_GET_APPS_USING_PERMISSIONS = 2;
         public static final int MSG_UNBIND = 3;
+        public static final int MSG_REVOKE_APP_PERMISSIONS = 4;
 
         private final Object mLock = new Object();
 
@@ -231,6 +248,25 @@
                         mRemoteInstance = null;
                     }
                 } break;
+
+                case MSG_REVOKE_APP_PERMISSIONS: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    final String packageName = (String) args.arg1;
+                    final String permissionName = (String) args.arg2;
+                    args.recycle();
+                    final IRuntimePermissionPresenter remoteInstance;
+                    synchronized (mLock) {
+                        remoteInstance = mRemoteInstance;
+                    }
+                    if (remoteInstance == null) {
+                        return;
+                    }
+                    try {
+                        remoteInstance.revokeRuntimePermission(packageName, permissionName);
+                    } catch (RemoteException re) {
+                        Log.e(TAG, "Error getting app permissions", re);
+                    }
+                } break;
             }
 
             synchronized (mLock) {
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index 6a02b6b..bda8039 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -256,6 +256,15 @@
      */
     public static final int VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH = 1 << 6;
 
+    /**
+     * Virtual display flag: Indicates that the orientation of this display device is coupled to
+     * the rotation of its associated logical display.
+     *
+     * @see #createVirtualDisplay
+     * @hide
+     */
+    public static final int VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT = 1 << 7;
+
     /** @hide */
     public DisplayManager(Context context) {
         mContext = context;
diff --git a/core/java/android/hardware/radio/ITuner.aidl b/core/java/android/hardware/radio/ITuner.aidl
index 1fc71e0..69e135d 100644
--- a/core/java/android/hardware/radio/ITuner.aidl
+++ b/core/java/android/hardware/radio/ITuner.aidl
@@ -22,6 +22,8 @@
 interface ITuner {
     void close();
 
+    boolean isClosed();
+
     /**
      * @throws IllegalArgumentException if config is not valid or null
      */
diff --git a/core/java/android/hardware/radio/RadioManager.java b/core/java/android/hardware/radio/RadioManager.java
index 434cf51..b6eaa5c 100644
--- a/core/java/android/hardware/radio/RadioManager.java
+++ b/core/java/android/hardware/radio/RadioManager.java
@@ -17,7 +17,6 @@
 package android.hardware.radio;
 
 import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.content.Context;
@@ -27,7 +26,6 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.ServiceManager.ServiceNotFoundException;
-import android.os.SystemProperties;
 import android.text.TextUtils;
 import android.util.Log;
 
@@ -1482,11 +1480,7 @@
             return STATUS_BAD_VALUE;
         }
 
-        if (mService == null) {
-            return nativeListModules(modules);
-        }
-
-        Log.v(TAG, "Listing available tuners...");
+        Log.d(TAG, "Listing available tuners...");
         List<ModuleProperties> returnedList;
         try {
             returnedList = mService.listModules();
@@ -1526,45 +1520,32 @@
             throw new IllegalArgumentException("callback must not be empty");
         }
 
-        if (mService != null) {
-            Log.d(TAG, "Opening tuner...");
+        Log.d(TAG, "Opening tuner " + moduleId + "...");
 
-            ITuner tuner;
-            ITunerCallback halCallback = new TunerCallbackAdapter(callback, handler);
-            try {
-                tuner = mService.openTuner(moduleId, config, withAudio, halCallback);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Failed to open tuner", e);
-                return null;
-            }
-            if (tuner == null) {
-                Log.e(TAG, "Failed to open tuner");
-                return null;
-            }
-            return new TunerAdapter(tuner);
+        ITuner tuner;
+        ITunerCallback halCallback = new TunerCallbackAdapter(callback, handler);
+        try {
+            tuner = mService.openTuner(moduleId, config, withAudio, halCallback);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to open tuner", e);
+            return null;
         }
-
-        RadioModule module = new RadioModule(moduleId, config, withAudio, callback, handler);
-        if (!module.initCheck()) {
+        if (tuner == null) {
             Log.e(TAG, "Failed to open tuner");
-            module = null;
+            return null;
         }
-
-        return (RadioTuner)module;
+        return new TunerAdapter(tuner);
     }
 
     @NonNull private final Context mContext;
-    // TODO(b/36863239): NonNull when transitioned from native service
-    @Nullable private final IRadioService mService;
+    @NonNull private final IRadioService mService;
 
     /**
      * @hide
      */
     public RadioManager(@NonNull Context context) throws ServiceNotFoundException {
         mContext = context;
-
-        boolean isServiceJava = SystemProperties.getBoolean("config.enable_java_radio", false);
-        mService = isServiceJava ? IRadioService.Stub.asInterface(
-                ServiceManager.getServiceOrThrow(Context.RADIO_SERVICE)) : null;
+        mService = IRadioService.Stub.asInterface(
+                ServiceManager.getServiceOrThrow(Context.RADIO_SERVICE));
     }
 }
diff --git a/core/java/android/hardware/radio/RadioMetadata.java b/core/java/android/hardware/radio/RadioMetadata.java
index d07b407..07dd5db 100644
--- a/core/java/android/hardware/radio/RadioMetadata.java
+++ b/core/java/android/hardware/radio/RadioMetadata.java
@@ -15,21 +15,16 @@
  */
 package android.hardware.radio;
 
-import android.annotation.NonNull;
 import android.annotation.SystemApi;
-import android.content.ContentResolver;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
-import android.net.Uri;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.SparseArray;
 
-import java.util.ArrayList;
 import java.util.Set;
 
 /**
@@ -540,7 +535,6 @@
     }
 
     int putClockFromNative(int nativeKey, long utcEpochSeconds, int timezoneOffsetInMinutes) {
-        Log.d(TAG, "putClockFromNative()");
         String key = getKeyFromNativeKey(nativeKey);
         if (!METADATA_KEYS_TYPE.containsKey(key) ||
                 METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_CLOCK) {
diff --git a/core/java/android/hardware/radio/RadioModule.java b/core/java/android/hardware/radio/RadioModule.java
deleted file mode 100644
index c0df0f3..0000000
--- a/core/java/android/hardware/radio/RadioModule.java
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.radio;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import java.lang.ref.WeakReference;
-import java.util.List;
-import java.util.UUID;
-
-/**
- * A RadioModule implements the RadioTuner interface for a broadcast radio tuner physically
- * present on the device and exposed by the radio HAL.
- *
- * @hide
- */
-public class RadioModule extends RadioTuner {
-    private long mNativeContext = 0;
-    private int mId;
-    private NativeEventHandlerDelegate mEventHandlerDelegate;
-
-    RadioModule(int moduleId, RadioManager.BandConfig config, boolean withAudio,
-            RadioTuner.Callback callback, Handler handler) {
-        mId = moduleId;
-        mEventHandlerDelegate = new NativeEventHandlerDelegate(callback, handler);
-        native_setup(new WeakReference<RadioModule>(this), config, withAudio);
-    }
-    private native void native_setup(Object module_this,
-            RadioManager.BandConfig config, boolean withAudio);
-
-    @Override
-    protected void finalize() {
-        native_finalize();
-    }
-    private native void native_finalize();
-
-    boolean initCheck() {
-        return mNativeContext != 0;
-    }
-
-    // RadioTuner implementation
-    public native void close();
-
-    public native int setConfiguration(RadioManager.BandConfig config);
-
-    public native int getConfiguration(RadioManager.BandConfig[] config);
-
-    public native int setMute(boolean mute);
-
-    public native boolean getMute();
-
-    public native int step(int direction, boolean skipSubChannel);
-
-    public native int scan(int direction, boolean skipSubChannel);
-
-    public native int tune(int channel, int subChannel);
-
-    public native int cancel();
-
-    public native int getProgramInformation(RadioManager.ProgramInfo[] info);
-
-    public native boolean startBackgroundScan();
-
-    public native @NonNull List<RadioManager.ProgramInfo> getProgramList(@Nullable String filter);
-
-    public native boolean isAnalogForced();
-
-    public native void setAnalogForced(boolean isForced);
-
-    public native boolean isAntennaConnected();
-
-    public native boolean hasControl();
-
-
-    /* keep in sync with radio_event_type_t in system/core/include/system/radio.h */
-    static final int EVENT_HW_FAILURE = 0;
-    static final int EVENT_CONFIG = 1;
-    static final int EVENT_ANTENNA = 2;
-    static final int EVENT_TUNED = 3;
-    static final int EVENT_METADATA = 4;
-    static final int EVENT_TA = 5;
-    static final int EVENT_AF_SWITCH = 6;
-    static final int EVENT_EA = 7;
-    static final int EVENT_CONTROL = 100;
-    static final int EVENT_SERVER_DIED = 101;
-
-    private class NativeEventHandlerDelegate {
-        private final Handler mHandler;
-
-        NativeEventHandlerDelegate(final RadioTuner.Callback callback,
-                                   Handler handler) {
-            // find the looper for our new event handler
-            Looper looper;
-            if (handler != null) {
-                looper = handler.getLooper();
-            } else {
-                looper = Looper.getMainLooper();
-            }
-
-            // construct the event handler with this looper
-            if (looper != null) {
-                // implement the event handler delegate
-                mHandler = new Handler(looper) {
-                    @Override
-                    public void handleMessage(Message msg) {
-                        switch (msg.what) {
-                        case EVENT_HW_FAILURE:
-                            if (callback != null) {
-                                callback.onError(RadioTuner.ERROR_HARDWARE_FAILURE);
-                            }
-                            break;
-                        case EVENT_CONFIG: {
-                            RadioManager.BandConfig config = (RadioManager.BandConfig)msg.obj;
-                            switch(msg.arg1) {
-                            case RadioManager.STATUS_OK:
-                                if (callback != null) {
-                                    callback.onConfigurationChanged(config);
-                                }
-                                break;
-                            default:
-                                if (callback != null) {
-                                    callback.onError(RadioTuner.ERROR_CONFIG);
-                                }
-                                break;
-                            }
-                        } break;
-                        case EVENT_ANTENNA:
-                            if (callback != null) {
-                                callback.onAntennaState(msg.arg2 == 1);
-                            }
-                            break;
-                        case EVENT_AF_SWITCH:
-                        case EVENT_TUNED: {
-                            RadioManager.ProgramInfo info = (RadioManager.ProgramInfo)msg.obj;
-                            switch (msg.arg1) {
-                            case RadioManager.STATUS_OK:
-                                if (callback != null) {
-                                    callback.onProgramInfoChanged(info);
-                                }
-                                break;
-                            case RadioManager.STATUS_TIMED_OUT:
-                                if (callback != null) {
-                                    callback.onError(RadioTuner.ERROR_SCAN_TIMEOUT);
-                                }
-                                break;
-                            case RadioManager.STATUS_INVALID_OPERATION:
-                            default:
-                                if (callback != null) {
-                                    callback.onError(RadioTuner.ERROR_CANCELLED);
-                                }
-                                break;
-                            }
-                        } break;
-                        case EVENT_METADATA: {
-                            RadioMetadata metadata = (RadioMetadata)msg.obj;
-                            if (callback != null) {
-                                callback.onMetadataChanged(metadata);
-                            }
-                        } break;
-                        case EVENT_TA:
-                            if (callback != null) {
-                                callback.onTrafficAnnouncement(msg.arg2 == 1);
-                            }
-                            break;
-                        case EVENT_EA:
-                            if (callback != null) {
-                                callback.onEmergencyAnnouncement(msg.arg2 == 1);
-                            }
-                        case EVENT_CONTROL:
-                            if (callback != null) {
-                                callback.onControlChanged(msg.arg2 == 1);
-                            }
-                            break;
-                        case EVENT_SERVER_DIED:
-                            if (callback != null) {
-                                callback.onError(RadioTuner.ERROR_SERVER_DIED);
-                            }
-                            break;
-                        default:
-                            // Should not happen
-                            break;
-                        }
-                    }
-                };
-            } else {
-                mHandler = null;
-            }
-        }
-
-        Handler handler() {
-            return mHandler;
-        }
-    }
-
-
-    @SuppressWarnings("unused")
-    private static void postEventFromNative(Object module_ref,
-                                            int what, int arg1, int arg2, Object obj) {
-        RadioModule module = (RadioModule)((WeakReference)module_ref).get();
-        if (module == null) {
-            return;
-        }
-
-        NativeEventHandlerDelegate delegate = module.mEventHandlerDelegate;
-        if (delegate != null) {
-            Handler handler = delegate.handler();
-            if (handler != null) {
-                Message m = handler.obtainMessage(what, arg1, arg2, obj);
-                handler.sendMessage(m);
-            }
-        }
-    }
-}
-
diff --git a/core/java/android/hardware/radio/TunerAdapter.java b/core/java/android/hardware/radio/TunerAdapter.java
index a457494..dbaca62 100644
--- a/core/java/android/hardware/radio/TunerAdapter.java
+++ b/core/java/android/hardware/radio/TunerAdapter.java
@@ -43,7 +43,7 @@
     public void close() {
         synchronized (mTuner) {
             if (mIsClosed) {
-                Log.d(TAG, "Tuner is already closed");
+                Log.v(TAG, "Tuner is already closed");
                 return;
             }
             mIsClosed = true;
@@ -227,7 +227,11 @@
 
     @Override
     public boolean hasControl() {
-        // TODO(b/36863239): forward to mTuner
-        throw new RuntimeException("Not implemented");
+        try {
+            // don't rely on mIsClosed, as tuner might get closed internally
+            return !mTuner.isClosed();
+        } catch (RemoteException e) {
+            return false;
+        }
     }
 }
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index 0045308..d73d3d8 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -654,6 +654,7 @@
         Preconditions.checkNotNull(port, "port must not be null");
         UsbPort.checkRoles(powerRole, dataRole);
 
+        Log.d(TAG, "setPortRoles Package:" + mContext.getPackageName());
         try {
             mService.setPortRoles(port.getId(), powerRole, dataRole);
         } catch (RemoteException e) {
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index f478071..5e9b02a 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -599,7 +599,7 @@
     /**
      * @hide
      */
-    public final static int REQUEST_ID_UNSET = 0;
+    public static final int REQUEST_ID_UNSET = 0;
 
     /**
      * Static unique request used as a tombstone for NetworkCallbacks that have been unregistered.
@@ -607,7 +607,7 @@
      * registered and those that were already unregistered.
      * @hide
      */
-    private final static NetworkRequest ALREADY_UNREGISTERED =
+    private static final NetworkRequest ALREADY_UNREGISTERED =
             new NetworkRequest.Builder().clearCapabilities().build();
 
     /**
@@ -1098,6 +1098,7 @@
      * @hide
      */
     @SystemApi
+    @RequiresPermission(android.Manifest.permission.LOCAL_MAC_ADDRESS)
     public String getCaptivePortalServerUrl() {
         try {
             return mService.getCaptivePortalServerUrl();
@@ -2061,10 +2062,11 @@
      * {@hide}
      */
     @SystemApi
-    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
+    @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
     public boolean isTetheringSupported() {
         try {
-            return mService.isTetheringSupported();
+            String pkgName = mContext.getOpPackageName();
+            return mService.isTetheringSupported(pkgName);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2094,6 +2096,7 @@
      * @hide
      */
     @SystemApi
+    @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
     public void startTethering(int type, boolean showProvisioningUi,
             final OnStartTetheringCallback callback) {
         startTethering(type, showProvisioningUi, callback, null);
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 27729dc..14cee36 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -75,7 +75,7 @@
 
     int getLastTetherError(String iface);
 
-    boolean isTetheringSupported();
+    boolean isTetheringSupported(String callerPkg);
 
     void startTethering(int type, in ResultReceiver receiver, boolean showProvisioningUi,
             String callerPkg);
diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java
index 0775bda..acd7b560 100644
--- a/core/java/android/net/NetworkIdentity.java
+++ b/core/java/android/net/NetworkIdentity.java
@@ -157,7 +157,7 @@
      * Scrub given IMSI on production builds.
      */
     public static String scrubSubscriberId(String subscriberId) {
-        if ("eng".equals(Build.TYPE)) {
+        if (Build.IS_ENG) {
             return subscriberId;
         } else if (subscriberId != null) {
             // TODO: parse this as MCC+MNC instead of hard-coding
diff --git a/core/java/android/net/TrafficStats.java b/core/java/android/net/TrafficStats.java
index f934616..1985707 100644
--- a/core/java/android/net/TrafficStats.java
+++ b/core/java/android/net/TrafficStats.java
@@ -109,25 +109,26 @@
      */
     public static final int TAG_SYSTEM_RESTORE = 0xFFFFFF04;
 
-    /** @hide */
-    public static final int TAG_SYSTEM_DHCP = 0xFFFFFF05;
-    /** @hide */
-    public static final int TAG_SYSTEM_NTP = 0xFFFFFF06;
-    /** @hide */
-    public static final int TAG_SYSTEM_PROBE = 0xFFFFFF07;
-    /** @hide */
-    public static final int TAG_SYSTEM_NEIGHBOR = 0xFFFFFF08;
-    /** @hide */
-    public static final int TAG_SYSTEM_GPS = 0xFFFFFF09;
-    /** @hide */
-    public static final int TAG_SYSTEM_PAC = 0xFFFFFF0A;
-
     /**
-     * Sockets that are strictly local on device; never hits network.
+     * Default tag value for code or resources downloaded by an app store on
+     * behalf of the app, such as app updates.
      *
      * @hide
      */
-    public static final int TAG_SYSTEM_LOCAL = 0xFFFFFFAA;
+    public static final int TAG_SYSTEM_CODE = 0xFFFFFF05;
+
+    /** @hide */
+    public static final int TAG_SYSTEM_DHCP = 0xFFFFFF40;
+    /** @hide */
+    public static final int TAG_SYSTEM_NTP = 0xFFFFFF41;
+    /** @hide */
+    public static final int TAG_SYSTEM_PROBE = 0xFFFFFF42;
+    /** @hide */
+    public static final int TAG_SYSTEM_NEIGHBOR = 0xFFFFFF43;
+    /** @hide */
+    public static final int TAG_SYSTEM_GPS = 0xFFFFFF44;
+    /** @hide */
+    public static final int TAG_SYSTEM_PAC = 0xFFFFFF45;
 
     private static INetworkStatsService sStatsService;
 
@@ -210,6 +211,19 @@
     }
 
     /**
+     * Set active tag to use when accounting {@link Socket} traffic originating
+     * from the current thread. The tag used internally is well-defined to
+     * distinguish all code-related traffic, such as updates performed by an app
+     * store.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static void setThreadStatsTagCode() {
+        setThreadStatsTag(TAG_SYSTEM_CODE);
+    }
+
+    /**
      * Get the active tag used when accounting {@link Socket} traffic originating
      * from the current thread. Only one active tag per thread is supported.
      * {@link #tagSocket(Socket)}.
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index b178d81..cf4fd99 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -5160,9 +5160,7 @@
                         Uid.Proc.ExcessivePower ew = ps.getExcessivePower(e);
                         if (ew != null) {
                             pw.print(prefix); pw.print("      * Killed for ");
-                                    if (ew.type == Uid.Proc.ExcessivePower.TYPE_WAKE) {
-                                        pw.print("wake lock");
-                                    } else if (ew.type == Uid.Proc.ExcessivePower.TYPE_CPU) {
+                                    if (ew.type == Uid.Proc.ExcessivePower.TYPE_CPU) {
                                         pw.print("cpu");
                                     } else {
                                         pw.print("unknown");
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index ff0bc69..44e6f1b 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -623,7 +623,7 @@
     
     protected void finalize() throws Throwable {
         try {
-            destroy();
+            destroyBinder();
         } finally {
             super.finalize();
         }
@@ -653,7 +653,7 @@
     }
 
     private native final void init();
-    private native final void destroy();
+    private native final void destroyBinder();
 
     // Entry point from android_util_Binder.cpp's onTransact
     private boolean execTransact(int code, long dataObj, long replyObj,
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index fa854b0..f243f37 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -699,6 +699,7 @@
             dest.writeInt(dalvikPrivateClean);
             dest.writeInt(dalvikSharedClean);
             dest.writeInt(dalvikSwappedOut);
+            dest.writeInt(dalvikSwappedOutPss);
             dest.writeInt(nativePss);
             dest.writeInt(nativeSwappablePss);
             dest.writeInt(nativePrivateDirty);
@@ -706,6 +707,7 @@
             dest.writeInt(nativePrivateClean);
             dest.writeInt(nativeSharedClean);
             dest.writeInt(nativeSwappedOut);
+            dest.writeInt(nativeSwappedOutPss);
             dest.writeInt(otherPss);
             dest.writeInt(otherSwappablePss);
             dest.writeInt(otherPrivateDirty);
@@ -726,6 +728,7 @@
             dalvikPrivateClean = source.readInt();
             dalvikSharedClean = source.readInt();
             dalvikSwappedOut = source.readInt();
+            dalvikSwappedOutPss = source.readInt();
             nativePss = source.readInt();
             nativeSwappablePss = source.readInt();
             nativePrivateDirty = source.readInt();
@@ -733,6 +736,7 @@
             nativePrivateClean = source.readInt();
             nativeSharedClean = source.readInt();
             nativeSwappedOut = source.readInt();
+            nativeSwappedOutPss = source.readInt();
             otherPss = source.readInt();
             otherSwappablePss = source.readInt();
             otherPrivateDirty = source.readInt();
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index 50b4f8c..56d6e0a 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -369,11 +369,11 @@
      * constraints remain.
      *
      * @param minCount Always keep at least this many files.
-     * @param minAge Always keep files younger than this age.
+     * @param minAgeMs Always keep files younger than this age, in milliseconds.
      * @return if any files were deleted.
      */
-    public static boolean deleteOlderFiles(File dir, int minCount, long minAge) {
-        if (minCount < 0 || minAge < 0) {
+    public static boolean deleteOlderFiles(File dir, int minCount, long minAgeMs) {
+        if (minCount < 0 || minAgeMs < 0) {
             throw new IllegalArgumentException("Constraints must be positive or 0");
         }
 
@@ -393,9 +393,9 @@
         for (int i = minCount; i < files.length; i++) {
             final File file = files[i];
 
-            // Keep files newer than minAge
+            // Keep files newer than minAgeMs
             final long age = System.currentTimeMillis() - file.lastModified();
-            if (age > minAge) {
+            if (age > minAgeMs) {
                 if (file.delete()) {
                     Log.d(TAG, "Deleted old file " + file);
                     deleted = true;
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index c34de15..92e78bc 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -97,6 +97,12 @@
     void enableIpv6(String iface);
 
     /**
+     * Set IPv6 autoconf address generation mode.
+     * This is a no-op if an unsupported mode is requested.
+     */
+    void setIPv6AddrGenMode(String iface, int mode);
+
+    /**
      * Enables or enables IPv6 ND offload.
      */
     void setInterfaceIpv6NdOffload(String iface, boolean enable);
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index db9f28b..6f458e0 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -22,20 +22,26 @@
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
+import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.os.UserManager;
+import android.provider.Settings;
+import android.telephony.euicc.EuiccManager;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.Display;
 import android.view.WindowManager;
 
+import com.android.internal.logging.MetricsLogger;
+
 import libcore.io.Streams;
 
-import java.io.ByteArrayInputStream;
 import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
@@ -46,22 +52,19 @@
 import java.io.RandomAccessFile;
 import java.security.GeneralSecurityException;
 import java.security.PublicKey;
-import java.security.Signature;
 import java.security.SignatureException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
 import java.util.Locale;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 import java.util.zip.ZipInputStream;
 
-import com.android.internal.logging.MetricsLogger;
-
 import sun.security.pkcs.PKCS7;
 import sun.security.pkcs.SignerInfo;
 
@@ -84,11 +87,19 @@
     /** Send progress to listeners no more often than this (in ms). */
     private static final long PUBLISH_PROGRESS_INTERVAL_MS = 500;
 
+    private static final long DEFAULT_EUICC_WIPING_TIMEOUT_MILLIS = 30000L; // 30 s
+
+    private static final long MIN_EUICC_WIPING_TIMEOUT_MILLIS = 5000L; // 5 s
+
+    private static final long MAX_EUICC_WIPING_TIMEOUT_MILLIS = 60000L; // 60 s
+
     /** Used to communicate with recovery.  See bootable/recovery/recovery.cpp. */
     private static final File RECOVERY_DIR = new File("/cache/recovery");
     private static final File LOG_FILE = new File(RECOVERY_DIR, "log");
     private static final File LAST_INSTALL_FILE = new File(RECOVERY_DIR, "last_install");
     private static final String LAST_PREFIX = "last_";
+    private static final String ACTION_WIPE_EUICC_DATA =
+            "com.android.internal.action.WIPE_EUICC_DATA";
 
     /**
      * The recovery image uses this file to identify the location (i.e. blocks)
@@ -673,18 +684,26 @@
      */
     public static void rebootWipeUserData(Context context) throws IOException {
         rebootWipeUserData(context, false /* shutdown */, context.getPackageName(),
-                false /* force */);
+                false /* force */, false /* wipeEuicc */);
     }
 
     /** {@hide} */
     public static void rebootWipeUserData(Context context, String reason) throws IOException {
-        rebootWipeUserData(context, false /* shutdown */, reason, false /* force */);
+        rebootWipeUserData(context, false /* shutdown */, reason, false /* force */,
+                false /* wipeEuicc */);
     }
 
     /** {@hide} */
     public static void rebootWipeUserData(Context context, boolean shutdown)
             throws IOException {
-        rebootWipeUserData(context, shutdown, context.getPackageName(), false /* force */);
+        rebootWipeUserData(context, shutdown, context.getPackageName(), false /* force */,
+                false /* wipeEuicc */);
+    }
+
+    /** {@hide} */
+    public static void rebootWipeUserData(Context context, boolean shutdown, String reason,
+            boolean force) throws IOException {
+        rebootWipeUserData(context, shutdown, reason, force, false /* wipeEuicc */);
     }
 
     /**
@@ -701,6 +720,7 @@
      * @param reason    the reason for the wipe that is visible in the logs
      * @param force     whether the {@link UserManager.DISALLOW_FACTORY_RESET} user restriction
      *                  should be ignored
+     * @param wipeEuicc whether wipe the euicc data
      *
      * @throws IOException  if writing the recovery command file
      * fails, or if the reboot itself fails.
@@ -709,7 +729,7 @@
      * @hide
      */
     public static void rebootWipeUserData(Context context, boolean shutdown, String reason,
-            boolean force) throws IOException {
+            boolean force, boolean wipeEuicc) throws IOException {
         UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
         if (!force && um.hasUserRestriction(UserManager.DISALLOW_FACTORY_RESET)) {
             throw new SecurityException("Wiping data is not allowed for this user.");
@@ -731,6 +751,10 @@
         // Block until the ordered broadcast has completed.
         condition.block();
 
+        if (wipeEuicc) {
+            wipeEuiccData(context);
+        }
+
         String shutdownArg = null;
         if (shutdown) {
             shutdownArg = "--shutdown_after";
@@ -745,6 +769,61 @@
         bootCommand(context, shutdownArg, "--wipe_data", reasonArg, localeArg);
     }
 
+    private static void wipeEuiccData(Context context) {
+        EuiccManager euiccManager = (EuiccManager) context.getSystemService(
+                Context.EUICC_SERVICE);
+        if (euiccManager != null && euiccManager.isEnabled()) {
+            CountDownLatch euiccFactoryResetLatch = new CountDownLatch(1);
+
+            BroadcastReceiver euiccWipeFinishReceiver = new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    if (ACTION_WIPE_EUICC_DATA.equals(intent.getAction())) {
+                        if (getResultCode() != EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK) {
+                            int detailedCode = intent.getIntExtra(
+                                    EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, 0);
+                            Log.e(TAG, "Error wiping euicc data, Detailed code = "
+                                    + detailedCode);
+                        } else {
+                            Log.d(TAG, "Successfully wiped euicc data.");
+                        }
+                        euiccFactoryResetLatch.countDown();
+                    }
+                }
+            };
+
+            Intent intent = new Intent(ACTION_WIPE_EUICC_DATA);
+            intent.setPackage("android");
+            PendingIntent callbackIntent = PendingIntent.getBroadcastAsUser(
+                    context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT, UserHandle.SYSTEM);
+            IntentFilter filterConsent = new IntentFilter();
+            filterConsent.addAction(ACTION_WIPE_EUICC_DATA);
+            HandlerThread euiccHandlerThread = new HandlerThread("euiccWipeFinishReceiverThread");
+            euiccHandlerThread.start();
+            Handler euiccHandler = new Handler(euiccHandlerThread.getLooper());
+            context.registerReceiver(euiccWipeFinishReceiver, filterConsent, null, euiccHandler);
+            euiccManager.eraseSubscriptions(callbackIntent);
+            try {
+                long waitingTimeMillis = Settings.Global.getLong(
+                        context.getContentResolver(),
+                        Settings.Global.EUICC_WIPING_TIMEOUT_MILLIS,
+                        DEFAULT_EUICC_WIPING_TIMEOUT_MILLIS);
+                if (waitingTimeMillis < MIN_EUICC_WIPING_TIMEOUT_MILLIS) {
+                    waitingTimeMillis = MIN_EUICC_WIPING_TIMEOUT_MILLIS;
+                } else if (waitingTimeMillis > MAX_EUICC_WIPING_TIMEOUT_MILLIS) {
+                    waitingTimeMillis = MAX_EUICC_WIPING_TIMEOUT_MILLIS;
+                }
+                if (!euiccFactoryResetLatch.await(waitingTimeMillis, TimeUnit.MILLISECONDS)) {
+                    Log.e(TAG, "Timeout wiping eUICC data.");
+                }
+                context.unregisterReceiver(euiccWipeFinishReceiver);
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                Log.e(TAG, "Wiping eUICC data interrupted", e);
+            }
+        }
+    }
+
     /** {@hide} */
     public static void rebootPromptAndWipeUserData(Context context, String reason)
             throws IOException {
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index 2b82c77..3e07143 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -16,6 +16,7 @@
 package android.os;
 
 import android.animation.ValueAnimator;
+import android.annotation.TestApi;
 import android.app.ActivityManager;
 import android.app.ActivityThread;
 import android.app.ApplicationErrorReport;
@@ -124,9 +125,6 @@
     private static final String TAG = "StrictMode";
     private static final boolean LOG_V = Log.isLoggable(TAG, Log.VERBOSE);
 
-    private static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
-    private static final boolean IS_ENG_BUILD = "eng".equals(Build.TYPE);
-
     /**
      * Boolean system property to disable strict mode checks outright.
      * Set this to 'true' to force disable; 'false' has no effect on other
@@ -343,6 +341,7 @@
     private static volatile VmPolicy sVmPolicy = VmPolicy.LAX;
 
     /** {@hide} */
+    @TestApi
     public interface ViolationListener {
         public void onViolation(String message);
     }
@@ -350,6 +349,7 @@
     private static volatile ViolationListener sListener;
 
     /** {@hide} */
+    @TestApi
     public static void setViolationListener(ViolationListener listener) {
         sListener = listener;
     }
@@ -1188,7 +1188,7 @@
 
         // For debug builds, log event loop stalls to dropbox for analysis.
         // Similar logic also appears in ActivityThread.java for system apps.
-        if (!doFlashes && (IS_USER_BUILD || suppress)) {
+        if (!doFlashes && (Build.IS_USER || suppress)) {
             setCloseGuardEnabled(false);
             return false;
         }
@@ -1196,7 +1196,7 @@
         // Eng builds have flashes on all the time.  The suppression property
         // overrides this, so we force the behavior only after the short-circuit
         // check above.
-        if (IS_ENG_BUILD) {
+        if (Build.IS_ENG) {
             doFlashes = true;
         }
 
@@ -1205,7 +1205,7 @@
                 StrictMode.DETECT_DISK_READ |
                 StrictMode.DETECT_NETWORK;
 
-        if (!IS_USER_BUILD) {
+        if (!Build.IS_USER) {
             threadPolicyMask |= StrictMode.PENALTY_DROPBOX;
         }
         if (doFlashes) {
@@ -1216,23 +1216,25 @@
 
         // VM Policy controls CloseGuard, detection of Activity leaks,
         // and instance counting.
-        if (IS_USER_BUILD) {
+        if (Build.IS_USER) {
             setCloseGuardEnabled(false);
         } else {
             VmPolicy.Builder policyBuilder = new VmPolicy.Builder().detectAll();
-            if (!IS_ENG_BUILD) {
+            if (!Build.IS_ENG) {
                 // Activity leak detection causes too much slowdown for userdebug because of the
                 // GCs.
                 policyBuilder = policyBuilder.disable(DETECT_VM_ACTIVITY_LEAKS);
             }
             policyBuilder = policyBuilder.penaltyDropBox();
-            if (IS_ENG_BUILD) {
+            if (Build.IS_ENG) {
                 policyBuilder.penaltyLog();
             }
             // All core system components need to tag their sockets to aid
             // system health investigations
             if (android.os.Process.myUid() < android.os.Process.FIRST_APPLICATION_UID) {
-                policyBuilder.detectUntaggedSockets();
+                policyBuilder.enable(DETECT_VM_UNTAGGED_SOCKET);
+            } else {
+                policyBuilder.disable(DETECT_VM_UNTAGGED_SOCKET);
             }
             setVmPolicy(policyBuilder.build());
             setCloseGuardEnabled(vmClosableObjectLeaksEnabled());
@@ -2291,7 +2293,7 @@
      * @hide
      */
     public static Span enterCriticalSpan(String name) {
-        if (IS_USER_BUILD) {
+        if (Build.IS_USER) {
             return NO_OP_SPAN;
         }
         if (name == null || name.isEmpty()) {
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index f2aa113..71f5ff7 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -118,6 +118,8 @@
     public static final String PROP_SDCARDFS = "persist.sys.sdcardfs";
     /** {@hide} */
     public static final String PROP_VIRTUAL_DISK = "persist.sys.virtual_disk";
+    /** {@hide} */
+    public static final String PROP_ADOPTABLE_FBE = "persist.sys.adoptable_fbe";
 
     /** {@hide} */
     public static final String UUID_PRIVATE_INTERNAL = null;
diff --git a/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java b/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java
index 344d947..2931627f 100644
--- a/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java
+++ b/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java
@@ -20,7 +20,6 @@
 import android.app.Service;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.ApplicationInfo;
 import android.content.pm.permission.IRuntimePermissionPresenter;
 import android.content.pm.permission.RuntimePermissionPresentationInfo;
 import android.content.pm.permission.RuntimePermissionPresenter;
@@ -30,6 +29,7 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteCallback;
+
 import com.android.internal.os.SomeArgs;
 
 import java.util.List;
@@ -72,6 +72,16 @@
      */
     public abstract List<RuntimePermissionPresentationInfo> onGetAppPermissions(String packageName);
 
+    /**
+     * Revoke the permission {@code permissionName} for app {@code packageName}
+     *
+     * @param packageName The package for which to revoke
+     * @param permissionName The permission to revoke
+     *
+     * @hide
+     */
+    public abstract void onRevokeRuntimePermission(String packageName, String permissionName);
+
     @Override
     public final IBinder onBind(Intent intent) {
         return new IRuntimePermissionPresenter.Stub() {
@@ -83,12 +93,22 @@
                 mHandler.obtainMessage(MyHandler.MSG_GET_APP_PERMISSIONS,
                         args).sendToTarget();
             }
+
+            @Override
+            public void revokeRuntimePermission(String packageName, String permissionName) {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = packageName;
+                args.arg2 = permissionName;
+                mHandler.obtainMessage(MyHandler.MSG_REVOKE_APP_PERMISSION,
+                        args).sendToTarget();
+            }
         };
     }
 
     private final class MyHandler extends Handler {
         public static final int MSG_GET_APP_PERMISSIONS = 1;
         public static final int MSG_GET_APPS_USING_PERMISSIONS = 2;
+        public static final int MSG_REVOKE_APP_PERMISSION = 3;
 
         public MyHandler(Looper looper) {
             super(looper, null, false);
@@ -113,6 +133,14 @@
                         callback.sendResult(null);
                     }
                 } break;
+                case MSG_REVOKE_APP_PERMISSION: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    String packageName = (String) args.arg1;
+                    String permissionName = (String) args.arg2;
+                    args.recycle();
+
+                    onRevokeRuntimePermission(packageName, permissionName);
+                } break;
             }
         }
     }
diff --git a/core/java/android/provider/AlarmClock.java b/core/java/android/provider/AlarmClock.java
index d921ed4..f903012 100644
--- a/core/java/android/provider/AlarmClock.java
+++ b/core/java/android/provider/AlarmClock.java
@@ -82,7 +82,8 @@
      * If neither of the above are given then:
      * <ul>
      * <li>If exactly one active alarm exists, it is dismissed.
-     * <li>If more than one active alarm exists, the user is prompted to choose the alarm to dismiss.
+     * <li>If more than one active alarm exists, the user is prompted to choose the alarm to
+     * dismiss.
      * </ul>
      * </p><p>
      * If the extra {@link #EXTRA_ALARM_SEARCH_MODE} is used, and the search results contain two or
@@ -104,8 +105,7 @@
      * @see #EXTRA_ALARM_SEARCH_MODE
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public static final String ACTION_DISMISS_ALARM =
-            "android.intent.action.DISMISS_ALARM";
+    public static final String ACTION_DISMISS_ALARM = "android.intent.action.DISMISS_ALARM";
 
     /**
      * Activity Action: Snooze a currently ringing alarm.
@@ -124,8 +124,7 @@
      * @see #EXTRA_ALARM_SNOOZE_DURATION
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public static final String ACTION_SNOOZE_ALARM =
-            "android.intent.action.SNOOZE_ALARM";
+    public static final String ACTION_SNOOZE_ALARM = "android.intent.action.SNOOZE_ALARM";
 
     /**
      * Activity Action: Set a timer.
@@ -155,6 +154,16 @@
     public static final String ACTION_SET_TIMER = "android.intent.action.SET_TIMER";
 
     /**
+     * Activity Action: Dismiss timers.
+     * <p>
+     * Dismiss all currently expired timers. If there are no expired timers, then this is a no-op.
+     * </p>
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_DISMISS_TIMER = "android.intent.action.DISMISS_TIMER";
+
+    /**
      * Activity Action: Show the timers.
      * <p>
      * This action opens the timers page.
@@ -200,8 +209,7 @@
      * @see #ALARM_SEARCH_MODE_LABEL
      * @see #ACTION_DISMISS_ALARM
      */
-    public static final String EXTRA_ALARM_SEARCH_MODE =
-        "android.intent.extra.alarm.SEARCH_MODE";
+    public static final String EXTRA_ALARM_SEARCH_MODE = "android.intent.extra.alarm.SEARCH_MODE";
 
     /**
      * Search for the alarm that is most closely matched by the search parameters
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 4726432..bc0534a 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -9185,9 +9185,11 @@
          * gc_min_interval                      (long)
          * full_pss_min_interval                (long)
          * full_pss_lowered_interval            (long)
-         * power_check_delay                    (long)
-         * wake_lock_min_check_duration         (long)
-         * cpu_min_check_duration               (long)
+         * power_check_interval                 (long)
+         * power_check_max_cpu_1                (int)
+         * power_check_max_cpu_2                (int)
+         * power_check_max_cpu_3                (int)
+         * power_check_max_cpu_4                (int)
          * service_usage_interaction_time       (long)
          * usage_stats_interaction_interval     (long)
          * service_restart_duration             (long)
@@ -10679,7 +10681,7 @@
         /**
          * The maximum allowed notification enqueue rate in Hertz.
          *
-         * Should be a float, and includes both posts and updates.
+         * Should be a float, and includes updates only.
          * @hide
          */
         public static final String MAX_NOTIFICATION_ENQUEUE_RATE = "max_notification_enqueue_rate";
diff --git a/core/java/android/service/autofill/AutofillService.java b/core/java/android/service/autofill/AutofillService.java
index 394bd0a..a80ef03 100644
--- a/core/java/android/service/autofill/AutofillService.java
+++ b/core/java/android/service/autofill/AutofillService.java
@@ -19,24 +19,230 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.os.RemoteException;
+import android.provider.Settings;
+
 import com.android.internal.os.HandlerCaller;
 import android.annotation.SdkConstant;
-import android.app.Activity;
-import android.app.Service;
-import android.content.Intent;
+import android.app.Service;import android.content.Intent;
 import android.os.CancellationSignal;
 import android.os.IBinder;
 import android.os.ICancellationSignal;
 import android.os.Looper;
 import android.util.Log;
+import android.view.View;
+import android.view.ViewStructure;
+import android.view.autofill.AutofillId;
 import android.view.autofill.AutofillManager;
+import android.view.autofill.AutofillValue;
 
 import com.android.internal.os.SomeArgs;
 
 /**
- * Top-level service of the current autofill service for a given user.
+ * An {@code AutofillService} is a service used to automatically fill the contents of the screen
+ * on behalf of a given user - for more information about autofill, read
+ * <a href="{@docRoot}preview/features/autofill.html">Autofill Framework</a>.
  *
- * <p>Apps providing autofill capabilities must extend this service.
+ * <p>An {@code AutofillService} is only bound to the Android System for autofill purposes if:
+ * <ol>
+ *   <li>It requires the {@code android.permission.BIND_AUTOFILL_SERVICE} permission in its
+ *       manifest.
+ *   <li>The user explicitly enables it using Android Settings (the
+ *       {@link Settings#ACTION_REQUEST_SET_AUTOFILL_SERVICE} intent can be used to launch such
+ *       Settings screen).
+ * </ol>
+ *
+ * <h3>Basic usage</h3>
+ *
+ * <p>The basic autofill process is defined by the workflow below:
+ * <ol>
+ *   <li>User focus an editable {@link View}.
+ *   <li>View calls {@link AutofillManager#notifyViewEntered(android.view.View)}.
+ *   <li>A {@link ViewStructure} representing all views in the screen is created.
+ *   <li>The Android System binds to the service and calls {@link #onConnected()}.
+ *   <li>The service receives the view structure through the
+ *       {@link #onFillRequest(FillRequest, CancellationSignal, FillCallback)}.
+ *   <li>The service replies through {@link FillCallback#onSuccess(FillResponse)}.
+ *   <li>The Android System calls {@link #onDisconnected()} and unbinds from the
+ *       {@code AutofillService}.
+ *   <li>The Android System displays an UI affordance with the options sent by the service.
+ *   <li>The user picks an option.
+ *   <li>The proper views are autofilled.
+ * </ol>
+ *
+ * <p>This workflow was designed to minimize the time the Android System is bound to the service;
+ * for each call, it: binds to service, waits for the reply, and unbinds right away. Furthermore,
+ * those calls are considered stateless: if the service needs to keep state between calls, it must
+ * do its own state management (keeping in mind that the service's process might be killed by the
+ * Android System when unbound; for example, if the device is running low in memory).
+ *
+ * <p>Typically, the
+ * {@link #onFillRequest(FillRequest, CancellationSignal, FillCallback)} will:
+ * <ol>
+ *   <li>Parse the view structure looking for autofillable views (for example, using
+ *       {@link android.app.assist.AssistStructure.ViewNode#getAutofillHints()}.
+ *   <li>Match the autofillable views with the user's data.
+ *   <li>Create a {@link Dataset} for each set of user's data that match those fields.
+ *   <li>Fill the dataset(s) with the proper {@link AutofillId}s and {@link AutofillValue}s.
+ *   <li>Add the dataset(s) to the {@link FillResponse} passed to
+ *       {@link FillCallback#onSuccess(FillResponse)}.
+ * </ol>
+ *
+ * <p>For example, for a login screen with username and password views where the user only has one
+ * account in the service, the response could be:
+ *
+ * <pre class="prettyprint">
+ * new FillResponse.Builder()
+ *     .addDataset(new Dataset.Builder()
+ *         .setValue(id1, AutofillValue.forText("homer"), createPresentation("homer"))
+ *         .setValue(id2, AutofillValue.forText("D'OH!"), createPresentation("password for homer"))
+ *         .build())
+ *     .build();
+ * </pre>
+ *
+ * <p>But if the user had 2 accounts instead, the response could be:
+ *
+ * <pre class="prettyprint">
+ * new FillResponse.Builder()
+ *     .addDataset(new Dataset.Builder()
+ *         .setValue(id1, AutofillValue.forText("homer"), createPresentation("homer"))
+ *         .setValue(id2, AutofillValue.forText("D'OH!"), createPresentation("password for homer"))
+ *         .build())
+ *     .addDataset(new Dataset.Builder()
+ *         .setValue(id1, AutofillValue.forText("flanders"), createPresentation("flanders"))
+ *         .setValue(id2, AutofillValue.forText("OkelyDokelyDo"), createPresentation("password for flanders"))
+ *         .build())
+ *     .build();
+ * </pre>
+ *
+ * <p>If the service does not find any autofillable view in the view structure, it should pass
+ * {@code null} to {@link FillCallback#onSuccess(FillResponse)}; if the service encountered an error
+ * processing the request, it should call {@link FillCallback#onFailure(CharSequence)}. For
+ * performance reasons, it's paramount that the service calls either
+ * {@link FillCallback#onSuccess(FillResponse)} or {@link FillCallback#onFailure(CharSequence)} for
+ * each {@link #onFillRequest(FillRequest, CancellationSignal, FillCallback)} received - if it
+ * doesn't, the request will eventually time out and be discarded by the Android System.
+ *
+ * <h3>Saving user data</h3>
+ *
+ * <p>If the service is also interested on saving the data filled by the user, it must set a
+ * {@link SaveInfo} object in the {@link FillResponse}. See {@link SaveInfo} for more details and
+ * examples.
+ *
+ * <h3>User authentication</h3>
+ *
+ * <p>The service can provide an extra degree of security by requiring the user to authenticate
+ * before an app can be autofilled. The authentication is typically required in 2 scenarios:
+ * <ul>
+ *   <li>To unlock the user data (for example, using a master password or fingerprint
+ *       authentication) - see
+ * {@link FillResponse.Builder#setAuthentication(AutofillId[], android.content.IntentSender, android.widget.RemoteViews)}.
+ *   <li>To unlock a specific dataset (for example, by providing a CVC for a credit card) - see
+ *       {@link Dataset.Builder#setAuthentication(android.content.IntentSender)}.
+ * </ul>
+ *
+ * <p>When using authentication, it is recommended to encrypt only the sensitive data and leave
+ * labels unencrypted, so they can be used on presentation views. For example, if the user has a
+ * home and a work address, the {@code Home} and {@code Work} labels should be stored unencrypted
+ * (since they don't have any sensitive data) while the address data per se could be stored in an
+ * encrypted storage. Then when the user chooses the {@code Home} dataset, the platform starts
+ * the authentication flow, and the service can decrypt the sensitive data.
+ *
+ * <p>The authentication mechanism can also be used in scenarios where the service needs multiple
+ * steps to determine the datasets that can fill a screen. For example, when autofilling a financial
+ * app where the user has accounts for multiple banks, the workflow could be:
+ *
+ * <ol>
+ *   <li>The first {@link FillResponse} contains datasets with the credentials for the financial
+ *       app, plus a "fake" dataset whose presentation says "Tap here for banking apps credentials".
+ *   <li>When the user selects the fake dataset, the service displays a dialog with available
+ *       banking apps.
+ *   <li>When the user select a banking app, the service replies with a new {@link FillResponse}
+ *       containing the datasets for that bank.
+ * </ol>
+ *
+ * <p>Another example of multiple-steps dataset selection is when the service stores the user
+ * credentials in "vaults": the first response would contain fake datasets with the vault names,
+ * and the subsequent response would contain the app credentials stored in that vault.
+ *
+ * <h3>Data partitioning</h3>
+ *
+ * <p>The autofillable views in a screen should be grouped in logical groups called "partitions".
+ * Typical partitions are:
+ * <ul>
+ *   <li>Credentials (username/email address, password).
+ *   <li>Address (street, city, state, zip code, etc).
+ *   <li>Payment info (credit card number, expiration date, and verification code).
+ * </ul>
+ * <p>For security reasons, when a screen has more than one partition, it's paramount that the
+ * contents of a dataset do not spawn multiple partitions, specially when one of the partitions
+ * contains data that is not specific to the application being autofilled. For example, a dataset
+ * should not contain fields for username, password, and credit card information. The reason for
+ * this rule is that a malicious app could draft a view structure where the credit card fields
+ * are not visible, so when the user selects a dataset from the username UI, the credit card info is
+ * released to the application without the user knowledge. Similar, it's recommended to always
+ * protect a dataset that contains sensitive information by requiring dataset authentication
+ * (see {@link Dataset.Builder#setAuthentication(android.content.IntentSender)}).
+ *
+ * <p>When the service detects that a screen have multiple partitions, it should return a
+ * {@link FillResponse} with just the datasets for the partition that originated the request (i.e.,
+ * the partition that has the {@link android.app.assist.AssistStructure.ViewNode} whose
+ * {@link android.app.assist.AssistStructure.ViewNode#isFocused()} returns {@code true}); then if
+ * the user selects a field from a different partition, the Android System will make another
+ * {@link #onFillRequest(FillRequest, CancellationSignal, FillCallback)} call for that partition,
+ * and so on.
+ *
+ * <p>Notice that when the user autofill a partition with the data provided by the service and the
+ * user did not change these fields, the autofilled value is sent back to the service in the
+ * subsequent calls (and can be obtained by calling
+ * {@link android.app.assist.AssistStructure.ViewNode#getAutofillValue()}). This is useful in the
+ * cases where the service must create datasets for a partition based on the choice made in a
+ * previous partition. For example, the 1st response for a screen that have credentials and address
+ * partitions could be:
+ *
+ * <pre class="prettyprint">
+ * new FillResponse.Builder()
+ *     .addDataset(new Dataset.Builder() // partition 1 (credentials)
+ *         .setValue(id1, AutofillValue.forText("homer"), createPresentation("homer"))
+ *         .setValue(id2, AutofillValue.forText("D'OH!"), createPresentation("password for homer"))
+ *         .build())
+ *     .addDataset(new Dataset.Builder() // partition 1 (credentials)
+ *         .setValue(id1, AutofillValue.forText("flanders"), createPresentation("flanders"))
+ *         .setValue(id2, AutofillValue.forText("OkelyDokelyDo"), createPresentation("password for flanders"))
+ *         .build())
+ *     .setSaveInfo(new SaveInfo.Builder(SaveInfo.SAVE_DATA_TYPE_PASSWORD,
+ *         new AutofillId[] { id1, id2 })
+ *             .build())
+ *     .build();
+ * </pre>
+ *
+ * <p>Then if the user selected {@code flanders}, the service would get a new
+ * {@link #onFillRequest(FillRequest, CancellationSignal, FillCallback)} call, with the values of
+ * the fields {@code id1} and {@code id2} prepopulated, so the service could then fetch the address
+ * for the Flanders account and return the following {@link FillResponse} for the address partition:
+ *
+ * <pre class="prettyprint">
+ * new FillResponse.Builder()
+ *     .addDataset(new Dataset.Builder() // partition 2 (address)
+ *         .setValue(id3, AutofillValue.forText("744 Evergreen Terrace"), createPresentation("744 Evergreen Terrace")) // street
+ *         .setValue(id4, AutofillValue.forText("Springfield"), createPresentation("Springfield")) // city
+ *         .build())
+ *     .setSaveInfo(new SaveInfo.Builder(SaveInfo.SAVE_DATA_TYPE_PASSWORD | SaveInfo.SAVE_DATA_TYPE_ADDRESS,
+ *         new AutofillId[] { id1, id2 }) // username and password
+ *              .setOptionalIds(new AutofillId[] { id3, id4 }) // state and zipcode
+ *             .build())
+ *     .build();
+ * </pre>
+ *
+ * <p>When the service returns multiple {@link FillResponse}, the last one overrides the previous;
+ * that's why the {@link SaveInfo} in the 2nd request above has the info for both partitions.
+ *
+ * <h3>Ignoring views</h3>
+ *
+ * <p>If the service find views that cannot be autofilled (for example, a text field representing
+ * the response to a Captcha challenge), it should mark those views as ignored by
+ * calling {@link FillResponse.Builder#setIgnoredIds(AutofillId...)} so the system does not trigger
+ * a new {@link #onFillRequest(FillRequest, CancellationSignal, FillCallback)} when these views are
+ * focused.
  */
 public abstract class AutofillService extends Service {
     private static final String TAG = "AutofillService";
@@ -132,11 +338,6 @@
 
     private HandlerCaller mHandlerCaller;
 
-    /**
-     * {@inheritDoc}
-     *
-     * <strong>NOTE: </strong>if overridden, it must call {@code super.onCreate()}.
-     */
     @CallSuper
     @Override
     public void onCreate() {
@@ -162,8 +363,7 @@
     }
 
     /**
-     * Called by the Android system do decide if an {@link Activity} can be autofilled by the
-     * service.
+     * Called by the Android system do decide if a screen can be autofilled by the service.
      *
      * <p>Service must call one of the {@link FillCallback} methods (like
      * {@link FillCallback#onSuccess(FillResponse)}
@@ -181,7 +381,7 @@
             @NonNull CancellationSignal cancellationSignal, @NonNull FillCallback callback);
 
     /**
-     * Called when user requests service to save the fields of an {@link Activity}.
+     * Called when user requests service to save the fields of a screen.
      *
      * <p>Service must call one of the {@link SaveCallback} methods (like
      * {@link SaveCallback#onSuccess()} or {@link SaveCallback#onFailure(CharSequence)})
@@ -226,7 +426,7 @@
      * @return The history or {@code null} if there are no events.
      */
     @Nullable public final FillEventHistory getFillEventHistory() {
-        AutofillManager afm = getSystemService(AutofillManager.class);
+        final AutofillManager afm = getSystemService(AutofillManager.class);
 
         if (afm == null) {
             return null;
diff --git a/core/java/android/service/autofill/Dataset.java b/core/java/android/service/autofill/Dataset.java
index af2eb34..a2ec099 100644
--- a/core/java/android/service/autofill/Dataset.java
+++ b/core/java/android/service/autofill/Dataset.java
@@ -31,17 +31,23 @@
 import java.util.ArrayList;
 
 /**
- * A set of data that can be used to autofill an {@link android.app.Activity}.
+ * A dataset object represents a group of key/value pairs used to autofill parts of a screen.
  *
- * <p>It contains:
+ * <p>In its simplest form, a dataset contains one or more key / value pairs (comprised of
+ * {@link AutofillId} and {@link AutofillValue} respectively); and one or more
+ * {@link RemoteViews presentation} for these pairs (a pair could have its own
+ * {@link RemoteViews presentation}, or use the default {@link RemoteViews presentation} associated
+ * with the whole dataset). When an autofill service returns datasets in a {@link FillResponse}
+ * and the screen input is focused in a view that is present in at least one of these datasets,
+ * the Android System displays a UI affordance containing the {@link RemoteViews presentation} of
+ * all datasets pairs that have that view's {@link AutofillId}. Then, when the user selects a
+ * dataset from the affordance, all views in that dataset are autofilled.
  *
- * <ol>
- *   <li>A list of values for input fields.
- *   <li>A presentation view to visualize.
- *   <li>An optional intent to authenticate.
- * </ol>
+ * <p>In a more sophisticated form, the dataset value can be protected until the user authenticates
+ * the dataset - see {@link Dataset.Builder#setAuthentication(IntentSender)}.
  *
- * @see android.service.autofill.FillResponse for examples.
+ * @see android.service.autofill.AutofillService for more information and examples about the
+ * role of datasets in the autofill workflow.
  */
 public final class Dataset implements Parcelable {
 
@@ -113,7 +119,7 @@
     }
 
     /**
-     * A builder for {@link Dataset} objects. You must to provide at least
+     * A builder for {@link Dataset} objects. You must provide at least
      * one value for a field or set an authentication intent.
      */
     public static final class Builder {
@@ -175,9 +181,9 @@
          * credit card information without the CVV for the data set in the {@link FillResponse
          * response} then the returned data set should contain the CVV entry.
          *
-         * <p></><strong>Note:</strong> Do not make the provided pending intent
+         * <p><b>NOTE:</b> Do not make the provided pending intent
          * immutable by using {@link android.app.PendingIntent#FLAG_IMMUTABLE} as the
-         * platform needs to fill in the authentication arguments.</p>
+         * platform needs to fill in the authentication arguments.
          *
          * @param authentication Intent to an activity with your authentication flow.
          * @return This builder.
@@ -191,7 +197,7 @@
         }
 
         /**
-         * Sets the id for the dataset.
+         * Sets the id for the dataset so its usage history can be retrieved later.
          *
          * <p>The id of the last selected dataset can be read from
          * {@link AutofillService#getFillEventHistory()}. If the id is not set it will not be clear
@@ -214,13 +220,12 @@
          *
          * @param id id returned by {@link
          *         android.app.assist.AssistStructure.ViewNode#getAutofillId()}.
-         * @param value value to be auto filled. Pass {@code null} if you do not have the value
+         * @param value value to be autofilled. Pass {@code null} if you do not have the value
          *        but the target view is a logical part of the dataset. For example, if
          *        the dataset needs an authentication and you have no access to the value.
-         *        Filtering matches any user typed string to {@code null} values.
          * @return This builder.
-         * @throws IllegalStateException if the builder was constructed without a presentation
-         * ({@link RemoteViews}).
+         * @throws IllegalStateException if the builder was constructed without a
+         * {@link RemoteViews presentation}.
          */
         public @NonNull Builder setValue(@NonNull AutofillId id, @Nullable AutofillValue value) {
             throwIfDestroyed();
@@ -232,7 +237,8 @@
         }
 
         /**
-         * Sets the value of a field, using a custom presentation to visualize it.
+         * Sets the value of a field, using a custom {@link RemoteViews presentation} to
+         * visualize it.
          *
          * @param id id returned by {@link
          *         android.app.assist.AssistStructure.ViewNode#getAutofillId()}.
@@ -272,10 +278,12 @@
         }
 
         /**
-         * Creates a new {@link Dataset} instance. You should not interact
-         * with this builder once this method is called. It is required
-         * that you specified at least one field. Also it is mandatory to
-         * provide a presentation view to visualize the data set in the UI.
+         * Creates a new {@link Dataset} instance.
+         *
+         * <p>You should not interact with this builder once this method is called.
+         *
+         * <p>It is required that you specify at least one field before calling this method. It's
+         * also mandatory to provide a presentation view to visualize the data set in the UI.
          *
          * @return The built dataset.
          */
diff --git a/core/java/android/service/autofill/FillContext.java b/core/java/android/service/autofill/FillContext.java
index f8a8751..cda2f4a 100644
--- a/core/java/android/service/autofill/FillContext.java
+++ b/core/java/android/service/autofill/FillContext.java
@@ -30,7 +30,6 @@
 import android.util.SparseIntArray;
 import android.view.autofill.AutofillId;
 
-import java.util.ArrayList;
 import java.util.LinkedList;
 
 /**
diff --git a/core/java/android/service/autofill/FillRequest.java b/core/java/android/service/autofill/FillRequest.java
index b1145ee..fd6da05 100644
--- a/core/java/android/service/autofill/FillRequest.java
+++ b/core/java/android/service/autofill/FillRequest.java
@@ -23,6 +23,7 @@
 import android.os.CancellationSignal;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.view.View;
 
 import com.android.internal.util.Preconditions;
 
@@ -32,7 +33,7 @@
 import java.util.List;
 
 /**
- * This class represents a request to an {@link AutofillService autofill provider}
+ * This class represents a request to an autofill service
  * to interpret the screen and provide information to the system which views are
  * interesting for saving and what are the possible ways to fill the inputs on
  * the screen if applicable.
@@ -40,8 +41,29 @@
  * @see AutofillService#onFillRequest(FillRequest, CancellationSignal, FillCallback)
  */
 public final class FillRequest implements Parcelable {
+
     /**
      * Indicates autofill was explicitly requested by the user.
+     *
+     * <p>Users typically make an explicit request to autofill a screen in two situations:
+     * <ul>
+     *   <li>The app disabled autofill (using {@link View#setImportantForAutofill(int)}.
+     *   <li>The service could not figure out how to autofill a screen (but the user knows the
+     *       service has data for that app).
+     * </ul>
+     *
+     * <p>This flag is particularly useful for the second case. For example, the service could offer
+     * a complex UI where the user can map which screen views belong to each user data, or it could
+     * offer a simpler UI where the user picks the data for just the view used to trigger the
+     * request (that would be the view whose
+     * {@link android.app.assist.AssistStructure.ViewNode#isFocused()} method returns {@code true}).
+     *
+     * <p>An explicit autofill request is triggered when the
+     * {@link android.view.autofill.AutofillManager#requestAutofill(View)} or
+     * {@link android.view.autofill.AutofillManager#requestAutofill(View, int, android.graphics.Rect)}
+     * is called. For example, standard {@link android.widget.TextView} views that use
+     * an {@link android.widget.Editor} shows an {@code AUTOFILL} option in the overflow menu that
+     * triggers such request.
      */
     public static final int FLAG_MANUAL_REQUEST = 0x1;
 
@@ -79,14 +101,14 @@
     }
 
     /**
-     * @return The unique id of this request.
+     * Gets the unique id of this request.
      */
     public int getId() {
         return mId;
     }
 
     /**
-     * @return The flags associated with this request.
+     * Gets the flags associated with this request.
      *
      * @see #FLAG_MANUAL_REQUEST
      */
@@ -95,7 +117,7 @@
     }
 
     /**
-     * @return The contexts associated with each previous fill request.
+     * Gets the contexts associated with each previous fill request.
      */
     public @NonNull List<FillContext> getFillContexts() {
         return mContexts;
@@ -104,10 +126,10 @@
     /**
      * Gets the extra client state returned from the last {@link
      * AutofillService#onFillRequest(FillRequest, CancellationSignal, FillCallback)
-     * fill request}.
-     * <p>
-     * Once a {@link AutofillService#onSaveRequest(SaveRequest, SaveCallback)
-     * save request} is made the client state is cleared.
+     * fill request}, so the service can use it for state management.
+     *
+     * <p>Once a {@link AutofillService#onSaveRequest(SaveRequest, SaveCallback)
+     * save request} is made, the client state is cleared.
      *
      * @return The client state.
      */
diff --git a/core/java/android/service/autofill/FillResponse.java b/core/java/android/service/autofill/FillResponse.java
index fcf18eb..e13fdf6 100644
--- a/core/java/android/service/autofill/FillResponse.java
+++ b/core/java/android/service/autofill/FillResponse.java
@@ -21,6 +21,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.Activity;
 import android.content.IntentSender;
 import android.os.Bundle;
 import android.os.Parcel;
@@ -36,100 +37,7 @@
  * Response for a {@link
  * AutofillService#onFillRequest(FillRequest, android.os.CancellationSignal, FillCallback)}.
  *
- * <p>The response typically contains one or more {@link Dataset}s, each representing a set of
- * fields that can be autofilled together, and the Android system displays a dataset picker UI
- * affordance that the user must use before the {@link android.app.Activity} is filled with
- * the dataset.
- *
- * <p>For example, for a login page with username/password where the user only has one account in
- * the response could be:
- *
- * <pre class="prettyprint">
- *  new FillResponse.Builder()
- *      .add(new Dataset.Builder(createPresentation())
- *          .setValue(id1, AutofillValue.forText("homer"))
- *          .setValue(id2, AutofillValue.forText("D'OH!"))
- *          .build())
- *      .build();
- * </pre>
- *
- * <p>If the user had 2 accounts, each with its own user-provided names, the response could be:
- *
- * <pre class="prettyprint">
- *  new FillResponse.Builder()
- *      .add(new Dataset.Builder(createFirstPresentation())
- *          .setValue(id1, AutofillValue.forText("homer"))
- *          .setValue(id2, AutofillValue.forText("D'OH!"))
- *          .build())
- *      .add(new Dataset.Builder(createSecondPresentation())
- *          .setValue(id1, AutofillValue.forText("elbarto")
- *          .setValue(id2, AutofillValue.forText("cowabonga")
- *          .build())
- *      .build();
- * </pre>
- *
- * If the service is interested on saving the user-edited data back, it must set a {@link SaveInfo}
- * in the {@link FillResponse}. Typically, the {@link SaveInfo} contains the same ids as the
- * {@link Dataset}, but other combinations are possible - see {@link SaveInfo} for more details
- *
- * <p>If the service has multiple {@link Dataset}s for different sections of the activity,
- * for example, a user section for which there are two datasets followed by an address
- * section for which there are two datasets for each user user, then it should "partition"
- * the activity in sections and populate the response with just a subset of the data that would
- * fulfill the first section (the name in our example); then once the user fills the first
- * section and taps a field from the next section (the address in our example), the Android
- * system would issue another request for that section, and so on. Note that if the user
- * chooses to populate the first section with a service provided dataset, the subsequent request
- * would contain the populated values so you don't try to provide suggestions for the first
- * section but ony for the second one based on the context of what was already filled. For
- * example, the first response could be:
- *
- * <pre class="prettyprint">
- *  new FillResponse.Builder()
- *      .add(new Dataset.Builder(createFirstPresentation())
- *          .setValue(id1, AutofillValue.forText("Homer"))
- *          .setValue(id2, AutofillValue.forText("Simpson"))
- *          .build())
- *      .add(new Dataset.Builder(createSecondPresentation())
- *          .setValue(id1, AutofillValue.forText("Bart"))
- *          .setValue(id2, AutofillValue.forText("Simpson"))
- *          .build())
- *      .build();
- * </pre>
- *
- * <p>Then after the user picks the second dataset and taps the street field to
- * trigger another autofill request, the second response could be:
- *
- * <pre class="prettyprint">
- *  new FillResponse.Builder()
- *      .add(new Dataset.Builder(createThirdPresentation())
- *          .setValue(id3, AutofillValue.forText("742 Evergreen Terrace"))
- *          .setValue(id4, AutofillValue.forText("Springfield"))
- *          .build())
- *      .add(new Dataset.Builder(createFourthPresentation())
- *          .setValue(id3, AutofillValue.forText("Springfield Power Plant"))
- *          .setValue(id4, AutofillValue.forText("Springfield"))
- *          .build())
- *      .build();
- * </pre>
- *
- * <p>The service could require user authentication at the {@link FillResponse} or the
- * {@link Dataset} level, prior to autofilling an activity - see
- * {@link FillResponse.Builder#setAuthentication(AutofillId[], IntentSender, RemoteViews)} and
- * {@link Dataset.Builder#setAuthentication(IntentSender)}.
- *
- * <p>It is recommended that you encrypt only the sensitive data but leave the labels unencrypted
- * which would allow you to provide a dataset presentation views with labels and if the user
- * chooses one of them challenge the user to authenticate. For example, if the user has a
- * home and a work address the Home and Work labels could be stored unencrypted as they don't
- * have any sensitive data while the address data is in an encrypted storage. If the user
- * chooses Home, then the platform will start your authentication flow. If you encrypt all
- * data and require auth at the response level the user will have to interact with the fill
- * UI to trigger a request for the datasets (as they don't see the presentation views for the
- * possible options) which will start your auth flow and after successfully authenticating
- * the user will be presented with the Home and Work options to pick one. Hence, you have
- * flexibility how to implement your auth while storing labels non-encrypted and data
- * encrypted provides a better user experience.
+ * <p>See the main {@link AutofillService} documentation for more details and examples.
  */
 public final class FillResponse implements Parcelable {
 
@@ -221,7 +129,7 @@
         private boolean mDestroyed;
 
         /**
-         * Requires a fill response authentication before autofilling the activity with
+         * Requires a fill response authentication before autofilling the screen with
          * any data set in this response.
          *
          * <p>This is typically useful when a user interaction is required to unlock their
@@ -230,16 +138,16 @@
          * auth on the data set level leading to a better user experience. Note that if you
          * use sensitive data as a label, for example an email address, then it should also
          * be encrypted. The provided {@link android.app.PendingIntent intent} must be an
-         * activity which implements your authentication flow. Also if you provide an auth
+         * {@link Activity} which implements your authentication flow. Also if you provide an auth
          * intent you also need to specify the presentation view to be shown in the fill UI
          * for the user to trigger your authentication flow.
          *
          * <p>When a user triggers autofill, the system launches the provided intent
          * whose extras will have the {@link AutofillManager#EXTRA_ASSIST_STRUCTURE screen
          * content} and your {@link android.view.autofill.AutofillManager#EXTRA_CLIENT_STATE
-         * client state}. Once you complete your authentication flow you should set the activity
-         * result to {@link android.app.Activity#RESULT_OK} and provide the fully populated
-         * {@link FillResponse response} by setting it to the {@link
+         * client state}. Once you complete your authentication flow you should set the
+         * {@link Activity} result to {@link android.app.Activity#RESULT_OK} and provide the fully
+         * populated {@link FillResponse response} by setting it to the {@link
          * AutofillManager#EXTRA_AUTHENTICATION_RESULT} extra.
          * For example, if you provided an empty {@link FillResponse resppnse} because the
          * user's data was locked and marked that the response needs an authentication then
@@ -286,8 +194,8 @@
          * {@link AutofillService#onFillRequest(FillRequest, android.os.CancellationSignal,
          * FillCallback)} requests.
          *
-         * <p>This is typically used when the service cannot autofill the view; for example, an
-         * {@code EditText} representing a captcha.
+         * <p>This is typically used when the service cannot autofill the view; for example, a
+         * text field representing the result of a Captcha challenge.
          */
         public Builder setIgnoredIds(AutofillId...ids) {
             mIgnoredIds = ids;
@@ -316,8 +224,6 @@
         /**
          * Sets the {@link SaveInfo} associated with this response.
          *
-         * <p>See {@link FillResponse} for more info.
-         *
          * @return This builder.
          */
         public @NonNull Builder setSaveInfo(@NonNull SaveInfo saveInfo) {
@@ -335,7 +241,7 @@
          * fill requests and the subsequent save request.
          *
          * <p>If this method is called on multiple {@link FillResponse} objects for the same
-         * activity, just the latest bundle is passed back to the service.
+         * screen, just the latest bundle is passed back to the service.
          *
          * <p>Once a {@link AutofillService#onSaveRequest(SaveRequest, SaveCallback)
          * save request} is made the client state is cleared.
@@ -350,9 +256,10 @@
         }
 
         /**
-         * Builds a new {@link FillResponse} instance. You must provide at least
-         * one dataset or some savable ids or an authentication with a presentation
-         * view.
+         * Builds a new {@link FillResponse} instance.
+         *
+         * <p>You must provide at least one dataset or some savable ids or an authentication with a
+         * presentation view.
          *
          * @return A built response.
          */
diff --git a/core/java/android/service/autofill/SaveInfo.java b/core/java/android/service/autofill/SaveInfo.java
index 6ea7d5e..95d393b 100644
--- a/core/java/android/service/autofill/SaveInfo.java
+++ b/core/java/android/service/autofill/SaveInfo.java
@@ -21,6 +21,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.Activity;
 import android.content.IntentSender;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -45,70 +46,91 @@
  * two pieces of information:
  *
  * <ol>
- *   <li>The type of user data that would be saved (like passoword or credit card info).
+ *   <li>The type(s) of user data (like password or credit card info) that would be saved.
  *   <li>The minimum set of views (represented by their {@link AutofillId}) that need to be changed
  *       to trigger a save request.
  * </ol>
  *
- *  Typically, the {@link SaveInfo} contains the same {@code id}s as the {@link Dataset}:
+ * <p>Typically, the {@link SaveInfo} contains the same {@code id}s as the {@link Dataset}:
  *
  * <pre class="prettyprint">
- *  new FillResponse.Builder()
- *      .add(new Dataset.Builder(createPresentation())
- *          .setValue(id1, AutofillValue.forText("homer"))
- *          .setValue(id2, AutofillValue.forText("D'OH!"))
- *          .build())
- *      .setSaveInfo(new SaveInfo.Builder(SaveInfo.SAVE_INFO_TYPE_PASSWORD, new int[] {id1, id2})
- *                  .build())
- *      .build();
+ *   new FillResponse.Builder()
+ *       .addDataset(new Dataset.Builder()
+ *           .setValue(id1, AutofillValue.forText("homer"), createPresentation("homer")) // username
+ *           .setValue(id2, AutofillValue.forText("D'OH!"), createPresentation("password for homer")) // password
+ *           .build())
+ *       .setSaveInfo(new SaveInfo.Builder(
+ *           SaveInfo.SAVE_DATA_TYPE_USERNAME | SaveInfo.SAVE_DATA_TYPE_PASSWORD,
+ *           new AutofillId[] { id1, id2 }).build())
+ *       .build();
  * </pre>
  *
- * There might be cases where the {@link AutofillService} knows how to fill the
- * {@link android.app.Activity}, but the user has no data for it. In that case, the
- * {@link FillResponse} should contain just the {@link SaveInfo}, but no {@link Dataset}s:
+ * <p>The save type flags are used to display the appropriate strings in the save UI affordance.
+ * You can pass multiple values, but try to keep it short if possible. In the above example, just
+ * {@code SaveInfo.SAVE_DATA_TYPE_PASSWORD} would be enough.
+ *
+ * <p>There might be cases where the {@link AutofillService} knows how to fill the screen,
+ * but the user has no data for it. In that case, the {@link FillResponse} should contain just the
+ * {@link SaveInfo}, but no {@link Dataset Datasets}:
  *
  * <pre class="prettyprint">
- *  new FillResponse.Builder()
- *      .setSaveInfo(new SaveInfo.Builder(SaveInfo.SAVE_INFO_TYPE_PASSWORD, new int[] {id1, id2})
- *                  .build())
- *      .build();
+ *   new FillResponse.Builder()
+ *       .setSaveInfo(new SaveInfo.Builder(SaveInfo.SAVE_DATA_TYPE_PASSWORD,
+ *           new AutofillId[] { id1, id2 }).build())
+ *       .build();
  * </pre>
  *
  * <p>There might be cases where the user data in the {@link AutofillService} is enough
  * to populate some fields but not all, and the service would still be interested on saving the
- * other fields. In this scenario, the service could set the
+ * other fields. In that case, the service could set the
  * {@link SaveInfo.Builder#setOptionalIds(AutofillId[])} as well:
  *
  * <pre class="prettyprint">
  *   new FillResponse.Builder()
- *       .add(new Dataset.Builder(createPresentation())
- *          .setValue(id1, AutofillValue.forText("742 Evergreen Terrace"))  // street
- *          .setValue(id2, AutofillValue.forText("Springfield"))            // city
- *          .build())
- *       .setSaveInfo(new SaveInfo.Builder(SaveInfo.SAVE_INFO_TYPE_ADDRESS, new int[] {id1, id2})
- *                   .setOptionalIds(new int[] {id3, id4}) // state and zipcode
- *                   .build())
+ *       .addDataset(new Dataset.Builder()
+ *           .setValue(id1, AutofillValue.forText("742 Evergreen Terrace"),
+ *               createPresentation("742 Evergreen Terrace")) // street
+ *           .setValue(id2, AutofillValue.forText("Springfield"),
+ *               createPresentation("Springfield")) // city
+ *           .build())
+ *       .setSaveInfo(new SaveInfo.Builder(SaveInfo.SAVE_DATA_TYPE_ADDRESS,
+ *           new AutofillId[] { id1, id2 }) // street and  city
+ *           .setOptionalIds(new AutofillId[] { id3, id4 }) // state and zipcode
+ *           .build())
  *       .build();
  * </pre>
  *
- * The
- * {@link AutofillService#onSaveRequest(SaveRequest, SaveCallback)}
- * is triggered after a call to {@link AutofillManager#commit()}, but only when all conditions
- * below are met:
+ * <p>The {@link AutofillService#onSaveRequest(SaveRequest, SaveCallback)} can be triggered after
+ * any of the following events:
+ * <ul>
+ *   <li>The {@link Activity} finishes.
+ *   <li>The app explicitly called {@link AutofillManager#commit()}.
+ *   <li>All required views became invisible (if the {@link SaveInfo} was created with the
+ *       {@link #FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE} flag).
+ * </ul>
  *
- * <ol>
+ * <p>But it is only triggered when all conditions below are met:
+ * <ul>
  *   <li>The {@link SaveInfo} associated with the {@link FillResponse} is not {@code null}.
- *   <li>The {@link AutofillValue} of all required views (as set by the {@code requiredIds} passed
- *       to {@link SaveInfo.Builder} constructor are not empty.
+ *   <li>The {@link AutofillValue}s of all required views (as set by the {@code requiredIds} passed
+ *       to the {@link SaveInfo.Builder} constructor are not empty.
  *   <li>The {@link AutofillValue} of at least one view (be it required or optional) has changed
- *       (i.e., it's not the same value passed in a {@link Dataset}).
- *   <li>The user explicitly tapped the affordance asking to save data for autofill.
- * </ol>
+ *       (i.e., it's neither the same value passed in a {@link Dataset}, nor the initial value
+ *       presented in the view).
+ *   <li>The user explicitly tapped the UI affordance asking to save data for autofill.
+ * </ul>
+ *
+ * <p>The service can also customize some aspects of the save UI affordance:
+ * <ul>
+ *   <li>Add a subtitle by calling {@link Builder#setDescription(CharSequence)}.
+ *   <li>Customize the button used to reject the save request by calling
+ *       {@link Builder#setNegativeAction(int, IntentSender)}.
+ * </ul>
  */
 public final class SaveInfo implements Parcelable {
 
     /**
-     * Type used on when the service can save the contents of an activity, but cannot describe what
+     * Type used when the service can save the contents of a screen, but cannot describe what
      * the content is for.
      */
     public static final int SAVE_DATA_TYPE_GENERIC = 0x0;
@@ -181,8 +203,8 @@
 
     /**
      * Usually {@link AutofillService#onSaveRequest(SaveRequest, SaveCallback)}
-     * is called once the activity finishes. If this flag is set it is called once all saved views
-     * become invisible.
+     * is called once the {@link Activity} finishes. If this flag is set it is called once all
+     * saved views become invisible.
      */
     public static final int FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE = 0x1;
 
@@ -294,9 +316,9 @@
         }
 
         /**
-         * Set flags changing the save behavior.
+         * Sets flags changing the save behavior.
          *
-         * @param flags {@link #FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE} or 0.
+         * @param flags {@link #FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE} or {@code 0}.
          * @return This builder.
          */
         public @NonNull Builder setFlags(@SaveInfoFlags int flags) {
diff --git a/core/java/android/service/euicc/EuiccService.java b/core/java/android/service/euicc/EuiccService.java
index 875f286..0c2e4b7 100644
--- a/core/java/android/service/euicc/EuiccService.java
+++ b/core/java/android/service/euicc/EuiccService.java
@@ -97,6 +97,10 @@
     public static final String ACTION_RESOLVE_NO_PRIVILEGES =
             "android.service.euicc.action.RESOLVE_NO_PRIVILEGES";
 
+    /** Intent extra set for resolution requests containing the package name of the calling app. */
+    public static final String EXTRA_RESOLUTION_CALLING_PACKAGE =
+            "android.service.euicc.extra.RESOLUTION_CALLING_PACKAGE";
+
     /** Result code for a successful operation. */
     public static final int RESULT_OK = 0;
     /** Result code indicating that an active SIM must be deactivated to perform the operation. */
@@ -313,6 +317,21 @@
     public abstract int onEraseSubscriptions(int slotId);
 
     /**
+     * Ensure that subscriptions will be retained on the next factory reset.
+     *
+     * <p>Called directly before a factory reset. Assumes that a normal factory reset will lead to
+     * profiles being erased on first boot (to cover fastboot/recovery wipes), so the implementation
+     * should persist some bit that will remain accessible after the factory reset to bypass this
+     * flow when this method is called.
+     *
+     * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
+     *     but is here to future-proof the APIs.
+     * @return the result of the operation. May be one of the predefined {@code RESULT_} constants
+     *     or any implementation-specific code starting with {@link #RESULT_FIRST_USER}.
+     */
+    public abstract int onRetainSubscriptionsForFactoryReset(int slotId);
+
+    /**
      * Wrapper around IEuiccService that forwards calls to implementations of {@link EuiccService}.
      */
     private class IEuiccServiceWrapper extends IEuiccService.Stub {
@@ -484,5 +503,21 @@
                 }
             });
         }
+
+        @Override
+        public void retainSubscriptionsForFactoryReset(int slotId,
+                IRetainSubscriptionsForFactoryResetCallback callback) {
+            mExecutor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    int result = EuiccService.this.onRetainSubscriptionsForFactoryReset(slotId);
+                    try {
+                        callback.onComplete(result);
+                    } catch (RemoteException e) {
+                        // Can't communicate with the phone process; ignore.
+                    }
+                }
+            });
+        }
     }
 }
diff --git a/core/java/android/service/euicc/IEuiccService.aidl b/core/java/android/service/euicc/IEuiccService.aidl
index 18ea915..e10dd8c 100644
--- a/core/java/android/service/euicc/IEuiccService.aidl
+++ b/core/java/android/service/euicc/IEuiccService.aidl
@@ -24,6 +24,7 @@
 import android.service.euicc.IGetEidCallback;
 import android.service.euicc.IGetEuiccInfoCallback;
 import android.service.euicc.IGetEuiccProfileInfoListCallback;
+import android.service.euicc.IRetainSubscriptionsForFactoryResetCallback;
 import android.service.euicc.ISwitchToSubscriptionCallback;
 import android.service.euicc.IUpdateSubscriptionNicknameCallback;
 import android.telephony.euicc.DownloadableSubscription;
@@ -46,4 +47,6 @@
     void updateSubscriptionNickname(int slotId, String iccid, String nickname,
             in IUpdateSubscriptionNicknameCallback callback);
     void eraseSubscriptions(int slotId, in IEraseSubscriptionsCallback callback);
+    void retainSubscriptionsForFactoryReset(
+            int slotId, in IRetainSubscriptionsForFactoryResetCallback callback);
 }
\ No newline at end of file
diff --git a/services/core/java/com/android/server/timezone/FileDescriptorHelper.java b/core/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl
similarity index 63%
rename from services/core/java/com/android/server/timezone/FileDescriptorHelper.java
rename to core/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl
index c3b1101..1276830 100644
--- a/services/core/java/com/android/server/timezone/FileDescriptorHelper.java
+++ b/core/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl
@@ -14,17 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.server.timezone;
+package android.service.euicc;
 
-import android.os.ParcelFileDescriptor;
-
-import java.io.IOException;
-
-/**
- * An easy-to-mock interface around use of {@link ParcelFileDescriptor} for use by
- * {@link RulesManagerService}.
- */
-interface FileDescriptorHelper {
-
-    byte[] readFully(ParcelFileDescriptor parcelFileDescriptor) throws IOException;
-}
+/** @hide */
+oneway interface IRetainSubscriptionsForFactoryResetCallback {
+    void onComplete(int result);
+}
\ No newline at end of file
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 74ff6dc..a8c6aa6 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -18,6 +18,7 @@
 
 import android.annotation.Nullable;
 import android.graphics.Paint;
+import android.os.LocaleList;
 import android.text.style.LeadingMarginSpan;
 import android.text.style.LeadingMarginSpan.LeadingMarginSpan2;
 import android.text.style.LineHeightSpan;
@@ -333,6 +334,16 @@
             return this;
         }
 
+        private long[] getHyphenators(LocaleList locales) {
+            final int length = locales.size();
+            final long[] result = new long[length];
+            for (int i = 0; i < length; i++) {
+                final Locale locale = locales.get(i);
+                result[i] = Hyphenator.get(locale).getNativePtr();
+            }
+            return result;
+        }
+
         /**
          * Measurement and break iteration is done in native code. The protocol for using
          * the native code is as follows.
@@ -342,7 +353,7 @@
          * future).
          *
          * Then, for each run within the paragraph:
-         *  - setLocale (this must be done at least for the first run, optional afterwards)
+         *  - setLocales (this must be done at least for the first run, optional afterwards)
          *  - one of the following, depending on the type of run:
          *    + addStyleRun (a text run, to be measured in native code)
          *    + addMeasuredRun (a run already measured in Java, passed into native code)
@@ -354,15 +365,15 @@
          * After all paragraphs, call finish() to release expensive buffers.
          */
 
-        private void setLocale(Locale locale) {
-            if (!locale.equals(mLocale)) {
-                nSetLocale(mNativePtr, locale.toLanguageTag(),
-                        Hyphenator.get(locale).getNativePtr());
-                mLocale = locale;
+        private void setLocales(LocaleList locales) {
+            if (!locales.equals(mLocales)) {
+                nSetLocales(mNativePtr, locales.toLanguageTags(), getHyphenators(locales));
+                mLocales = locales;
             }
         }
 
         /* package */ float addStyleRun(TextPaint paint, int start, int end, boolean isRtl) {
+            setLocales(paint.getTextLocales());
             return nAddStyleRun(mNativePtr, paint.getNativeInstance(), paint.mNativeTypeface,
                     start, end, isRtl);
         }
@@ -425,7 +436,7 @@
         // This will go away and be subsumed by native builder code
         MeasuredText mMeasuredText;
 
-        Locale mLocale;
+        LocaleList mLocales;
 
         private static final SynchronizedPool<Builder> sPool = new SynchronizedPool<Builder>(3);
     }
@@ -594,7 +605,7 @@
         // store fontMetrics per span range
         // must be a multiple of 4 (and > 0) (store top, bottom, ascent, and descent per range)
         int[] fmCache = new int[4 * 4];
-        b.setLocale(paint.getTextLocale());  // TODO: also respect LocaleSpan within the text
+        b.setLocales(paint.getTextLocales());
 
         mLineCount = 0;
 
@@ -1308,7 +1319,8 @@
     /* package */ static native long nLoadHyphenator(ByteBuffer buf, int offset,
             int minPrefix, int minSuffix);
 
-    private static native void nSetLocale(long nativePtr, String locale, long nativeHyphenator);
+    private static native void nSetLocales(long nativePtr, String locales,
+            long[] nativeHyphenators);
 
     private static native void nSetIndents(long nativePtr, int[] indents);
 
diff --git a/core/java/android/text/format/Formatter.java b/core/java/android/text/format/Formatter.java
index b67ac98..e5bc32bb 100644
--- a/core/java/android/text/format/Formatter.java
+++ b/core/java/android/text/format/Formatter.java
@@ -20,6 +20,9 @@
 import android.annotation.Nullable;
 import android.content.Context;
 import android.content.res.Resources;
+import android.icu.text.MeasureFormat;
+import android.icu.util.Measure;
+import android.icu.util.MeasureUnit;
 import android.net.NetworkUtils;
 import android.text.BidiFormatter;
 import android.text.TextUtils;
@@ -51,9 +54,13 @@
         }
     }
 
+    private static Locale localeFromContext(@NonNull Context context) {
+        return context.getResources().getConfiguration().getLocales().get(0);
+    }
+
     /* Wraps the source string in bidi formatting characters in RTL locales */
     private static String bidiWrap(@NonNull Context context, String source) {
-        final Locale locale = context.getResources().getConfiguration().locale;
+        final Locale locale = localeFromContext(context);
         if (TextUtils.getLayoutDirectionFromLocale(locale) == View.LAYOUT_DIRECTION_RTL) {
             return BidiFormatter.getInstance(true /* RTL*/).unicodeWrap(source);
         } else {
@@ -197,7 +204,7 @@
 
     /**
      * Returns elapsed time for the given millis, in the following format:
-     * 1 day 5 hrs; will include at most two units, can go down to seconds precision.
+     * 1 day, 5 hr; will include at most two units, can go down to seconds precision.
      * @param context the application context
      * @param millis the elapsed time in milli seconds
      * @return the formatted elapsed time
@@ -221,44 +228,38 @@
         }
         int seconds = (int)secondsLong;
 
+        final Locale locale = localeFromContext(context);
+        final MeasureFormat measureFormat = MeasureFormat.getInstance(
+                locale, MeasureFormat.FormatWidth.SHORT);
         if (days >= 2) {
             days += (hours+12)/24;
-            return context.getString(com.android.internal.R.string.durationDays, days);
+            return measureFormat.format(new Measure(days, MeasureUnit.DAY));
         } else if (days > 0) {
-            if (hours == 1) {
-                return context.getString(com.android.internal.R.string.durationDayHour, days, hours);
-            }
-            return context.getString(com.android.internal.R.string.durationDayHours, days, hours);
+            return measureFormat.formatMeasures(
+                    new Measure(days, MeasureUnit.DAY),
+                    new Measure(hours, MeasureUnit.HOUR));
         } else if (hours >= 2) {
             hours += (minutes+30)/60;
-            return context.getString(com.android.internal.R.string.durationHours, hours);
+            return measureFormat.format(new Measure(hours, MeasureUnit.HOUR));
         } else if (hours > 0) {
-            if (minutes == 1) {
-                return context.getString(com.android.internal.R.string.durationHourMinute, hours,
-                        minutes);
-            }
-            return context.getString(com.android.internal.R.string.durationHourMinutes, hours,
-                    minutes);
+            return measureFormat.formatMeasures(
+                    new Measure(hours, MeasureUnit.HOUR),
+                    new Measure(minutes, MeasureUnit.MINUTE));
         } else if (minutes >= 2) {
             minutes += (seconds+30)/60;
-            return context.getString(com.android.internal.R.string.durationMinutes, minutes);
+            return measureFormat.format(new Measure(minutes, MeasureUnit.MINUTE));
         } else if (minutes > 0) {
-            if (seconds == 1) {
-                return context.getString(com.android.internal.R.string.durationMinuteSecond, minutes,
-                        seconds);
-            }
-            return context.getString(com.android.internal.R.string.durationMinuteSeconds, minutes,
-                    seconds);
-        } else if (seconds == 1) {
-            return context.getString(com.android.internal.R.string.durationSecond, seconds);
+            return measureFormat.formatMeasures(
+                    new Measure(minutes, MeasureUnit.MINUTE),
+                    new Measure(seconds, MeasureUnit.SECOND));
         } else {
-            return context.getString(com.android.internal.R.string.durationSeconds, seconds);
+            return measureFormat.format(new Measure(seconds, MeasureUnit.SECOND));
         }
     }
 
     /**
      * Returns elapsed time for the given millis, in the following format:
-     * 1 day 5 hrs; will include at most two units, can go down to minutes precision.
+     * 1 day, 5 hr; will include at most two units, can go down to minutes precision.
      * @param context the application context
      * @param millis the elapsed time in milli seconds
      * @return the formatted elapsed time
@@ -267,10 +268,11 @@
     public static String formatShortElapsedTimeRoundingUpToMinutes(Context context, long millis) {
         long minutesRoundedUp = (millis + MILLIS_PER_MINUTE - 1) / MILLIS_PER_MINUTE;
 
-        if (minutesRoundedUp == 0) {
-            return context.getString(com.android.internal.R.string.durationMinutes, 0);
-        } else if (minutesRoundedUp == 1) {
-            return context.getString(com.android.internal.R.string.durationMinute, 1);
+        if (minutesRoundedUp == 0 || minutesRoundedUp == 1) {
+            final Locale locale = localeFromContext(context);
+            final MeasureFormat measureFormat = MeasureFormat.getInstance(
+                    locale, MeasureFormat.FormatWidth.SHORT);
+            return measureFormat.format(new Measure(minutesRoundedUp, MeasureUnit.MINUTE));
         }
 
         return formatShortElapsedTime(context, minutesRoundedUp * MILLIS_PER_MINUTE);
diff --git a/core/java/android/util/BootTimingsTraceLog.java b/core/java/android/util/BootTimingsTraceLog.java
index 2e4319c..7a702a9 100644
--- a/core/java/android/util/BootTimingsTraceLog.java
+++ b/core/java/android/util/BootTimingsTraceLog.java
@@ -29,7 +29,7 @@
  */
 public class BootTimingsTraceLog {
     // Debug boot time for every step if it's non-user build.
-    private static final boolean DEBUG_BOOT_TIME = !"user".equals(Build.TYPE);
+    private static final boolean DEBUG_BOOT_TIME = !Build.IS_USER;
     private final Deque<Pair<String, Long>> mStartTimes
             = DEBUG_BOOT_TIME ? new ArrayDeque<>() : null;
     private final String mTag;
diff --git a/core/java/android/view/InputEventConsistencyVerifier.java b/core/java/android/view/InputEventConsistencyVerifier.java
index 46ef379..7e8ec04 100644
--- a/core/java/android/view/InputEventConsistencyVerifier.java
+++ b/core/java/android/view/InputEventConsistencyVerifier.java
@@ -30,7 +30,7 @@
  * @hide
  */
 public final class InputEventConsistencyVerifier {
-    private static final boolean IS_ENG_BUILD = "eng".equals(Build.TYPE);
+    private static final boolean IS_ENG_BUILD = Build.IS_ENG;
 
     private static final String EVENT_TYPE_KEY = "KeyEvent";
     private static final String EVENT_TYPE_TRACKBALL = "TrackballEvent";
diff --git a/core/java/android/view/accessibility/AccessibilityCache.java b/core/java/android/view/accessibility/AccessibilityCache.java
index 604e985..0f21c5c 100644
--- a/core/java/android/view/accessibility/AccessibilityCache.java
+++ b/core/java/android/view/accessibility/AccessibilityCache.java
@@ -40,7 +40,7 @@
 
     private static final boolean DEBUG = false;
 
-    private static final boolean CHECK_INTEGRITY = "eng".equals(Build.TYPE);
+    private static final boolean CHECK_INTEGRITY = Build.IS_ENG;
 
     /**
      * {@link AccessibilityEvent} types that are critical for the cache to stay up to date
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index e2f7979..92d1de8 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -97,7 +97,7 @@
  * that manages the interaction across all processes.
  * <li> An <strong>input method (IME)</strong> implements a particular
  * interaction model allowing the user to generate text.  The system binds
- * to the current input method that is use, causing it to be created and run,
+ * to the current input method that is in use, causing it to be created and run,
  * and tells it when to hide and show its UI.  Only one IME is running at a time.
  * <li> Multiple <strong>client applications</strong> arbitrate with the input
  * method manager for input focus and control over the state of the IME.  Only
diff --git a/core/java/android/webkit/WebViewLibraryLoader.java b/core/java/android/webkit/WebViewLibraryLoader.java
index e385a48..6f9e8ec 100644
--- a/core/java/android/webkit/WebViewLibraryLoader.java
+++ b/core/java/android/webkit/WebViewLibraryLoader.java
@@ -215,12 +215,10 @@
             return WebViewFactory.LIBLOAD_ADDRESS_SPACE_NOT_RESERVED;
         }
 
-        String[] args = getWebViewNativeLibraryPaths(packageInfo);
-        int result = nativeLoadWithRelroFile(args[0] /* path32 */,
-                                             args[1] /* path64 */,
-                                             CHROMIUM_WEBVIEW_NATIVE_RELRO_32,
-                                             CHROMIUM_WEBVIEW_NATIVE_RELRO_64,
-                                             clazzLoader);
+        final String libraryFileName =
+                WebViewFactory.getWebViewLibrary(packageInfo.applicationInfo);
+        int result = nativeLoadWithRelroFile(libraryFileName, CHROMIUM_WEBVIEW_NATIVE_RELRO_32,
+                                             CHROMIUM_WEBVIEW_NATIVE_RELRO_64, clazzLoader);
         if (result != WebViewFactory.LIBLOAD_SUCCESS) {
             Log.w(LOGTAG, "failed to load with relro file, proceeding without");
         } else if (DEBUG) {
@@ -317,7 +315,6 @@
     static native boolean nativeReserveAddressSpace(long addressSpaceToReserve);
     static native boolean nativeCreateRelroFile(String lib32, String lib64,
                                                         String relro32, String relro64);
-    static native int nativeLoadWithRelroFile(String lib32, String lib64,
-                                                      String relro32, String relro64,
+    static native int nativeLoadWithRelroFile(String lib, String relro32, String relro64,
                                                       ClassLoader clazzLoader);
 }
diff --git a/core/java/android/widget/ArrayAdapter.java b/core/java/android/widget/ArrayAdapter.java
index 74f22b3..690067b 100644
--- a/core/java/android/widget/ArrayAdapter.java
+++ b/core/java/android/widget/ArrayAdapter.java
@@ -526,6 +526,13 @@
      */
     @Override
     public CharSequence[] getAutofillOptions() {
+        // First check if app developer explicitly set them.
+        final CharSequence[] explicitOptions = super.getAutofillOptions();
+        if (explicitOptions != null) {
+            return explicitOptions;
+        }
+
+        // Otherwise, only return options that came from static resources.
         if (!mObjectsFromResources || mObjects == null || mObjects.isEmpty()) {
             return null;
         }
diff --git a/core/java/android/widget/BaseAdapter.java b/core/java/android/widget/BaseAdapter.java
index c960342..5838cc1 100644
--- a/core/java/android/widget/BaseAdapter.java
+++ b/core/java/android/widget/BaseAdapter.java
@@ -16,6 +16,7 @@
 
 package android.widget;
 
+import android.annotation.Nullable;
 import android.database.DataSetObservable;
 import android.database.DataSetObserver;
 import android.view.View;
@@ -29,6 +30,7 @@
  */
 public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter {
     private final DataSetObservable mDataSetObservable = new DataSetObservable();
+    private CharSequence[] mAutofillOptions;
 
     public boolean hasStableIds() {
         return false;
@@ -82,4 +84,16 @@
     public boolean isEmpty() {
         return getCount() == 0;
     }
+
+    @Override
+    public CharSequence[] getAutofillOptions() {
+        return mAutofillOptions;
+    }
+
+    /**
+     * Sets the value returned by {@link #getAutofillOptions()}
+     */
+    public void setAutofillOptions(@Nullable CharSequence... options) {
+        mAutofillOptions = options;
+    }
 }
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index fa1bd91..1f2e3d0 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -2664,7 +2664,7 @@
                 .setEnabled(mTextView.canSelectAllText())
                 .setOnMenuItemClickListener(mOnContextMenuItemClickListener);
         menu.add(Menu.NONE, TextView.ID_AUTOFILL, MENU_ITEM_ORDER_AUTOFILL,
-                com.android.internal.R.string.autofill)
+                android.R.string.autofill)
                 .setEnabled(mTextView.canRequestAutofill())
                 .setOnMenuItemClickListener(mOnContextMenuItemClickListener);
 
diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java
index 2e8faee..0d67615 100644
--- a/core/java/android/widget/ListPopupWindow.java
+++ b/core/java/android/widget/ListPopupWindow.java
@@ -25,6 +25,7 @@
 import android.database.DataSetObserver;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
+import android.os.Build;
 import android.os.Handler;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -532,8 +533,14 @@
     public void setHeight(int height) {
         if (height < 0 && ViewGroup.LayoutParams.WRAP_CONTENT != height
                 && ViewGroup.LayoutParams.MATCH_PARENT != height) {
-            throw new IllegalArgumentException(
-                   "Invalid height. Must be a positive value, MATCH_PARENT, or WRAP_CONTENT.");
+            if (mContext.getApplicationInfo().targetSdkVersion
+                    < Build.VERSION_CODES.O) {
+                Log.e(TAG, "Negative value " + height + " passed to ListPopupWindow#setHeight"
+                        + " produces undefined results");
+            } else {
+                throw new IllegalArgumentException(
+                        "Invalid height. Must be a positive value, MATCH_PARENT, or WRAP_CONTENT.");
+            }
         }
         mDropDownHeight = height;
     }
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index f6653fb..bf25915 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -208,9 +208,6 @@
 
     private int mGravity = Gravity.NO_GRAVITY;
 
-    // Title provided to accessibility services
-    private CharSequence mAccessibilityTitle;
-
     private static final int[] ABOVE_ANCHOR_STATE_SET = new int[] {
             com.android.internal.R.attr.state_above_anchor
     };
@@ -1134,31 +1131,6 @@
         return mIsShowing;
     }
 
-    /**
-     * Set the title for this window to be reported to accessibility services. If no title is set,
-     * a generic default will be reported.
-     *
-     * @param accessibilityTitle The new title, or {@code null} to specify that the default should
-     * be used.
-     * @hide
-     */
-    public void setAccessibilityTitle(@Nullable CharSequence accessibilityTitle) {
-        mAccessibilityTitle = accessibilityTitle;
-    }
-
-    /**
-     * Get the title for this window to be reported to accessibility services.
-     *
-     * @return The current title.
-     * @hide
-     */
-    public @NonNull CharSequence getAccessibilityTitle() {
-        if (mAccessibilityTitle == null) {
-            mAccessibilityTitle = mContext.getString(R.string.popup_window_default_title);
-        }
-        return mAccessibilityTitle;
-    }
-
     /** @hide */
     protected final void setShowing(boolean isShowing) {
         mIsShowing = isShowing;
@@ -1362,6 +1334,10 @@
                     + "calling setContentView() before attempting to show the popup.");
         }
 
+        if (p.accessibilityTitle == null) {
+            p.accessibilityTitle = mContext.getString(R.string.popup_window_default_title);
+        }
+
         // The old decor view may be transitioning out. Make sure it finishes
         // and cleans up before we try to create another one.
         if (mDecorView != null) {
@@ -1524,7 +1500,6 @@
 
         // Used for debugging.
         p.setTitle("PopupWindow:" + Integer.toHexString(hashCode()));
-        p.accessibilityTitle = getAccessibilityTitle();
 
         return p;
     }
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 6b328ea..9a92489 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -913,7 +913,7 @@
                         break;
 
                     case com.android.internal.R.styleable.TextAppearance_fontFamily:
-                        if (!context.isRestricted()) {
+                        if (!context.isRestricted() && context.canLoadUnsafeResources()) {
                             try {
                                 fontTypeface = appearance.getFont(attr);
                             } catch (UnsupportedOperationException
@@ -1233,7 +1233,7 @@
                     break;
 
                 case com.android.internal.R.styleable.TextView_fontFamily:
-                    if (!context.isRestricted()) {
+                    if (!context.isRestricted() && context.canLoadUnsafeResources()) {
                         try {
                             fontTypeface = a.getFont(attr);
                         } catch (UnsupportedOperationException | Resources.NotFoundException e) {
@@ -3417,7 +3417,7 @@
 
         Typeface fontTypeface = null;
         String fontFamily = null;
-        if (!context.isRestricted()) {
+        if (!context.isRestricted() && context.canLoadUnsafeResources()) {
             try {
                 fontTypeface = ta.getFont(R.styleable.TextAppearance_fontFamily);
             } catch (UnsupportedOperationException | Resources.NotFoundException e) {
diff --git a/core/java/com/android/internal/app/procstats/ProcessState.java b/core/java/com/android/internal/app/procstats/ProcessState.java
index 9470668..e0a4053 100644
--- a/core/java/com/android/internal/app/procstats/ProcessState.java
+++ b/core/java/com/android/internal/app/procstats/ProcessState.java
@@ -196,7 +196,6 @@
         ProcessState pnew = new ProcessState(this, mPackage, mUid, mVersion, mName, now);
         pnew.mDurations.addDurations(mDurations);
         pnew.mPssTable.copyFrom(mPssTable, PSS_COUNT);
-        pnew.mNumExcessiveWake = mNumExcessiveWake;
         pnew.mNumExcessiveCpu = mNumExcessiveCpu;
         pnew.mNumCachedKill = mNumCachedKill;
         pnew.mMinCachedKillPss = mMinCachedKillPss;
@@ -250,7 +249,6 @@
     public void add(ProcessState other) {
         mDurations.addDurations(other.mDurations);
         mPssTable.mergeStats(other.mPssTable);
-        mNumExcessiveWake += other.mNumExcessiveWake;
         mNumExcessiveCpu += other.mNumExcessiveCpu;
         if (other.mNumCachedKill > 0) {
             addCachedKill(other.mNumCachedKill, other.mMinCachedKillPss,
@@ -264,7 +262,6 @@
         mStartTime = now;
         mLastPssState = STATE_NOTHING;
         mLastPssTime = 0;
-        mNumExcessiveWake = 0;
         mNumExcessiveCpu = 0;
         mNumCachedKill = 0;
         mMinCachedKillPss = mAvgCachedKillPss = mMaxCachedKillPss = 0;
@@ -286,7 +283,7 @@
         out.writeInt(mMultiPackage ? 1 : 0);
         mDurations.writeToParcel(out);
         mPssTable.writeToParcel(out);
-        out.writeInt(mNumExcessiveWake);
+        out.writeInt(0);  // was mNumExcessiveWake
         out.writeInt(mNumExcessiveCpu);
         out.writeInt(mNumCachedKill);
         if (mNumCachedKill > 0) {
@@ -309,7 +306,7 @@
         if (!mPssTable.readFromParcel(in)) {
             return false;
         }
-        mNumExcessiveWake = in.readInt();
+        in.readInt(); // was mNumExcessiveWake
         mNumExcessiveCpu = in.readInt();
         mNumCachedKill = in.readInt();
         if (mNumCachedKill > 0) {
@@ -493,18 +490,6 @@
         }
     }
 
-    public void reportExcessiveWake(ArrayMap<String, ProcessStateHolder> pkgList) {
-        ensureNotDead();
-        mCommonProcess.mNumExcessiveWake++;
-        if (!mCommonProcess.mMultiPackage) {
-            return;
-        }
-
-        for (int ip=pkgList.size()-1; ip>=0; ip--) {
-            pullFixedProc(pkgList, ip).mNumExcessiveWake++;
-        }
-    }
-
     public void reportExcessiveCpu(ArrayMap<String, ProcessStateHolder> pkgList) {
         ensureNotDead();
         mCommonProcess.mNumExcessiveCpu++;
@@ -895,10 +880,6 @@
                 }
             }
         }
-        if (mNumExcessiveWake != 0) {
-            pw.print(prefix); pw.print("Killed for excessive wake locks: ");
-                    pw.print(mNumExcessiveWake); pw.println(" times");
-        }
         if (mNumExcessiveCpu != 0) {
             pw.print(prefix); pw.print("Killed for excessive CPU use: ");
                     pw.print(mNumExcessiveCpu); pw.println(" times");
@@ -1072,7 +1053,7 @@
             dumpAllPssCheckin(pw);
             pw.println();
         }
-        if (mNumExcessiveWake > 0 || mNumExcessiveCpu > 0 || mNumCachedKill > 0) {
+        if (mNumExcessiveCpu > 0 || mNumCachedKill > 0) {
             pw.print("pkgkills,");
             pw.print(pkgName);
             pw.print(",");
@@ -1082,7 +1063,7 @@
             pw.print(",");
             pw.print(DumpUtils.collapseString(pkgName, itemName));
             pw.print(",");
-            pw.print(mNumExcessiveWake);
+            pw.print("0"); // was mNumExcessiveWake
             pw.print(",");
             pw.print(mNumExcessiveCpu);
             pw.print(",");
@@ -1114,13 +1095,13 @@
             dumpAllPssCheckin(pw);
             pw.println();
         }
-        if (mNumExcessiveWake > 0 || mNumExcessiveCpu > 0 || mNumCachedKill > 0) {
+        if (mNumExcessiveCpu > 0 || mNumCachedKill > 0) {
             pw.print("kills,");
             pw.print(procName);
             pw.print(",");
             pw.print(uid);
             pw.print(",");
-            pw.print(mNumExcessiveWake);
+            pw.print("0"); // was mNumExcessiveWake
             pw.print(",");
             pw.print(mNumExcessiveCpu);
             pw.print(",");
diff --git a/core/java/com/android/internal/app/procstats/SparseMappingTable.java b/core/java/com/android/internal/app/procstats/SparseMappingTable.java
index f941836..956ce99 100644
--- a/core/java/com/android/internal/app/procstats/SparseMappingTable.java
+++ b/core/java/com/android/internal/app/procstats/SparseMappingTable.java
@@ -646,7 +646,7 @@
      */
     private static void logOrThrow(String message, Throwable th) {
         Slog.e(TAG, message, th);
-        if (Build.TYPE.equals("eng")) {
+        if (Build.IS_ENG) {
             throw new RuntimeException(message, th);
         }
     }
diff --git a/core/java/com/android/internal/backup/LocalTransport.java b/core/java/com/android/internal/backup/LocalTransport.java
index f76b702..543bd0c 100644
--- a/core/java/com/android/internal/backup/LocalTransport.java
+++ b/core/java/com/android/internal/backup/LocalTransport.java
@@ -30,6 +30,7 @@
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.StructStat;
+import android.util.ArrayMap;
 import android.util.Log;
 
 import com.android.org.bouncycastle.util.encoders.Base64;
@@ -44,7 +45,6 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
-import static android.system.OsConstants.SEEK_CUR;
 
 /**
  * Backup transport for stashing stuff into a known location on disk, and
@@ -70,9 +70,8 @@
     // The currently-active restore set always has the same (nonzero!) token
     private static final long CURRENT_SET_TOKEN = 1;
 
-    // Full backup size quota is set to reasonable value.
+    // Size quotas at reasonable values, similar to the current cloud-storage limits
     private static final long FULL_BACKUP_SIZE_QUOTA = 25 * 1024 * 1024;
-
     private static final long KEY_VALUE_BACKUP_SIZE_QUOTA = 5 * 1024 * 1024;
 
     private Context mContext;
@@ -157,6 +156,17 @@
         return TRANSPORT_OK;
     }
 
+    // Encapsulation of a single k/v element change
+    private class KVOperation {
+        final String key;     // Element filename, not the raw key, for efficiency
+        final byte[] value;   // null when this is a deletion operation
+
+        KVOperation(String k, byte[] v) {
+            key = k;
+            value = v;
+        }
+    }
+
     @Override
     public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor data) {
         if (DEBUG) {
@@ -175,62 +185,135 @@
 
         // Each 'record' in the restore set is kept in its own file, named by
         // the record key.  Wind through the data file, extracting individual
-        // record operations and building a set of all the updates to apply
+        // record operations and building a list of all the updates to apply
         // in this update.
-        BackupDataInput changeSet = new BackupDataInput(data.getFileDescriptor());
+        final ArrayList<KVOperation> changeOps;
         try {
-            int bufSize = 512;
-            byte[] buf = new byte[bufSize];
-            while (changeSet.readNextHeader()) {
-                String key = changeSet.getKey();
-                String base64Key = new String(Base64.encode(key.getBytes()));
-                File entityFile = new File(packageDir, base64Key);
-
-                int dataSize = changeSet.getDataSize();
-
-                if (DEBUG) Log.v(TAG, "Got change set key=" + key + " size=" + dataSize
-                        + " key64=" + base64Key);
-
-                if (dataSize >= 0) {
-                    if (entityFile.exists()) {
-                        entityFile.delete();
-                    }
-                    FileOutputStream entity = new FileOutputStream(entityFile);
-
-                    if (dataSize > bufSize) {
-                        bufSize = dataSize;
-                        buf = new byte[bufSize];
-                    }
-                    changeSet.readEntityData(buf, 0, dataSize);
-                    if (DEBUG) {
-                        try {
-                            long cur = Os.lseek(data.getFileDescriptor(), 0, SEEK_CUR);
-                            Log.v(TAG, "  read entity data; new pos=" + cur);
-                        }
-                        catch (ErrnoException e) {
-                            Log.w(TAG, "Unable to stat input file in performBackup() on "
-                                    + packageInfo.packageName);
-                        }
-                    }
-
-                    try {
-                        entity.write(buf, 0, dataSize);
-                    } catch (IOException e) {
-                        Log.e(TAG, "Unable to update key file " + entityFile.getAbsolutePath());
-                        return TRANSPORT_ERROR;
-                    } finally {
-                        entity.close();
-                    }
-                } else {
-                    entityFile.delete();
-                }
-            }
-            return TRANSPORT_OK;
+            changeOps = parseBackupStream(data);
         } catch (IOException e) {
             // oops, something went wrong.  abort the operation and return error.
-            Log.v(TAG, "Exception reading backup input:", e);
+            Log.v(TAG, "Exception reading backup input", e);
             return TRANSPORT_ERROR;
         }
+
+        // Okay, now we've parsed out the delta's individual operations.  We need to measure
+        // the effect against what we already have in the datastore to detect quota overrun.
+        // So, we first need to tally up the current in-datastore size per key.
+        final ArrayMap<String, Integer> datastore = new ArrayMap<>();
+        int totalSize = parseKeySizes(packageDir, datastore);
+
+        // ... and now figure out the datastore size that will result from applying the
+        // sequence of delta operations
+        if (DEBUG) {
+            if (changeOps.size() > 0) {
+                Log.v(TAG, "Calculating delta size impact");
+            } else {
+                Log.v(TAG, "No operations in backup stream, so no size change");
+            }
+        }
+        int updatedSize = totalSize;
+        for (KVOperation op : changeOps) {
+            // Deduct the size of the key we're about to replace, if any
+            final Integer curSize = datastore.get(op.key);
+            if (curSize != null) {
+                updatedSize -= curSize.intValue();
+                if (DEBUG && op.value == null) {
+                    Log.v(TAG, "  delete " + op.key + ", updated total " + updatedSize);
+                }
+            }
+
+            // And add back the size of the value we're about to store, if any
+            if (op.value != null) {
+                updatedSize += op.value.length;
+                if (DEBUG) {
+                    Log.v(TAG, ((curSize == null) ? "  new " : "  replace ")
+                            +  op.key + ", updated total " + updatedSize);
+                }
+            }
+        }
+
+        // If our final size is over quota, report the failure
+        if (updatedSize > KEY_VALUE_BACKUP_SIZE_QUOTA) {
+            if (DEBUG) {
+                Log.i(TAG, "New datastore size " + updatedSize
+                        + " exceeds quota " + KEY_VALUE_BACKUP_SIZE_QUOTA);
+            }
+            return TRANSPORT_QUOTA_EXCEEDED;
+        }
+
+        // No problem with storage size, so go ahead and apply the delta operations
+        // (in the order that the app provided them)
+        for (KVOperation op : changeOps) {
+            File element = new File(packageDir, op.key);
+
+            // this is either a deletion or a rewrite-from-zero, so we can just remove
+            // the existing file and proceed in either case.
+            element.delete();
+
+            // if this wasn't a deletion, put the new data in place
+            if (op.value != null) {
+                try (FileOutputStream out = new FileOutputStream(element)) {
+                    out.write(op.value, 0, op.value.length);
+                } catch (IOException e) {
+                    Log.e(TAG, "Unable to update key file " + element);
+                    return TRANSPORT_ERROR;
+                }
+            }
+        }
+        return TRANSPORT_OK;
+    }
+
+    // Parses a backup stream into individual key/value operations
+    private ArrayList<KVOperation> parseBackupStream(ParcelFileDescriptor data)
+            throws IOException {
+        ArrayList<KVOperation> changeOps = new ArrayList<>();
+        BackupDataInput changeSet = new BackupDataInput(data.getFileDescriptor());
+        while (changeSet.readNextHeader()) {
+            String key = changeSet.getKey();
+            String base64Key = new String(Base64.encode(key.getBytes()));
+            int dataSize = changeSet.getDataSize();
+            if (DEBUG) {
+                Log.v(TAG, "  Delta operation key " + key + "   size " + dataSize
+                        + "   key64 " + base64Key);
+            }
+
+            byte[] buf = (dataSize >= 0) ? new byte[dataSize] : null;
+            if (dataSize >= 0) {
+                changeSet.readEntityData(buf, 0, dataSize);
+            }
+            changeOps.add(new KVOperation(base64Key, buf));
+        }
+        return changeOps;
+    }
+
+    // Reads the given datastore directory, building a table of the value size of each
+    // keyed element, and returning the summed total.
+    private int parseKeySizes(File packageDir, ArrayMap<String, Integer> datastore) {
+        int totalSize = 0;
+        final String[] elements = packageDir.list();
+        if (elements != null) {
+            if (DEBUG) {
+                Log.v(TAG, "Existing datastore contents:");
+            }
+            for (String file : elements) {
+                File element = new File(packageDir, file);
+                String key = file;  // filename
+                int size = (int) element.length();
+                totalSize += size;
+                if (DEBUG) {
+                    Log.v(TAG, "  key " + key + "   size " + size);
+                }
+                datastore.put(key, size);
+            }
+            if (DEBUG) {
+                Log.v(TAG, "  TOTAL: " + totalSize);
+            }
+        } else {
+            if (DEBUG) {
+                Log.v(TAG, "No existing data for this package");
+            }
+        }
+        return totalSize;
     }
 
     // Deletes the contents but not the given directory
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 696dbda..cb00c5e 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -3987,14 +3987,6 @@
         return 0;
     }
 
-    public void reportExcessiveWakeLocked(int uid, String proc, long overTime, long usedTime) {
-        uid = mapUid(uid);
-        Uid u = mUidStats.get(uid);
-        if (u != null) {
-            u.reportExcessiveWakeLocked(proc, overTime, usedTime);
-        }
-    }
-
     public void reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime) {
         uid = mapUid(uid);
         Uid u = mUidStats.get(uid);
@@ -7745,17 +7737,6 @@
                 return null;
             }
 
-            public void addExcessiveWake(long overTime, long usedTime) {
-                if (mExcessivePower == null) {
-                    mExcessivePower = new ArrayList<ExcessivePower>();
-                }
-                ExcessivePower ew = new ExcessivePower();
-                ew.type = ExcessivePower.TYPE_WAKE;
-                ew.overTime = overTime;
-                ew.usedTime = usedTime;
-                mExcessivePower.add(ew);
-            }
-
             public void addExcessiveCpu(long overTime, long usedTime) {
                 if (mExcessivePower == null) {
                     mExcessivePower = new ArrayList<ExcessivePower>();
@@ -8570,13 +8551,6 @@
             }
         }
 
-        public void reportExcessiveWakeLocked(String proc, long overTime, long usedTime) {
-            Proc p = getProcessStatsLocked(proc);
-            if (p != null) {
-                p.addExcessiveWake(overTime, usedTime);
-            }
-        }
-
         public void reportExcessiveCpuLocked(String proc, long overTime, long usedTime) {
             Proc p = getProcessStatsLocked(proc);
             if (p != null) {
diff --git a/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java b/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java
index ff521c2..ce5e73a 100644
--- a/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java
+++ b/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java
@@ -104,13 +104,15 @@
             return;
         }
         final long[] deltaUidTimeMs = new long[size];
+        boolean notify = false;
         for (int i = 0; i < size; ++i) {
             // Times read will be in units of 10ms
             final long totalTimeMs = Long.parseLong(timesStr[i], 10) * 10;
             deltaUidTimeMs[i] = totalTimeMs - uidTimeMs[i];
             uidTimeMs[i] = totalTimeMs;
+            notify = notify || (deltaUidTimeMs[i] > 0);
         }
-        if (callback != null) {
+        if (callback != null && notify) {
             callback.onUidCpuFreqTime(uid, deltaUidTimeMs);
         }
     }
diff --git a/core/java/com/android/internal/os/WrapperInit.java b/core/java/com/android/internal/os/WrapperInit.java
index b245678..608bc9f 100644
--- a/core/java/com/android/internal/os/WrapperInit.java
+++ b/core/java/com/android/internal/os/WrapperInit.java
@@ -163,6 +163,8 @@
             argv = removedArgs;
         }
 
+        // Perform the same initialization that would happen after the Zygote forks.
+        Zygote.nativePreApplicationInit();
         RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
     }
 
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 5eca496..0106b81 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -121,6 +121,11 @@
           int[] fdsToIgnore, String instructionSet, String appDataDir);
 
     /**
+     * Called to do any initialization before starting an application.
+     */
+    native static void nativePreApplicationInit();
+
+    /**
      * Special method to start the system server process. In addition to the
      * common actions performed in forkAndSpecialize, the pid of the child
      * process is recorded such that the death of the child process will cause
diff --git a/core/java/com/android/internal/util/NotificationColorUtil.java b/core/java/com/android/internal/util/NotificationColorUtil.java
index 5c9f1c6..2778d93 100644
--- a/core/java/com/android/internal/util/NotificationColorUtil.java
+++ b/core/java/com/android/internal/util/NotificationColorUtil.java
@@ -557,7 +557,7 @@
     }
 
     public static boolean satisfiesTextContrast(int backgroundColor, int foregroundColor) {
-        return NotificationColorUtil.calculateContrast(backgroundColor, foregroundColor) >= 4.5;
+        return NotificationColorUtil.calculateContrast(foregroundColor, backgroundColor) >= 4.5;
     }
 
     /**
@@ -636,7 +636,7 @@
          */
         public static double calculateContrast(@ColorInt int foreground, @ColorInt int background) {
             if (Color.alpha(background) != 255) {
-                throw new IllegalArgumentException("background can not be translucent: #"
+                Log.wtf(TAG, "background can not be translucent: #"
                         + Integer.toHexString(background));
             }
             if (Color.alpha(foreground) < 255) {
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 7e71ce9..5185169 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -162,7 +162,6 @@
         "android_hardware_camera2_DngCreator.cpp",
         "android_hardware_display_DisplayViewport.cpp",
         "android_hardware_HardwareBuffer.cpp",
-        "android_hardware_Radio.cpp",
         "android_hardware_SensorManager.cpp",
         "android_hardware_SerialPort.cpp",
         "android_hardware_SoundTrigger.cpp",
@@ -215,7 +214,6 @@
         "libgif",
         "libseccomp_policy",
         "libselinux",
-        "libcrypto",
         "libgrallocusage",
     ],
 
@@ -224,6 +222,7 @@
         "libandroidfw",
         "libappfuse",
         "libbase",
+        "libcrypto",
         "libnativehelper",
         "liblog",
         "libcutils",
@@ -258,12 +257,10 @@
         "libpdfium",
         "libimg_utils",
         "libnetd_client",
-        "libradio",
         "libsoundtrigger",
         "libminikin",
         "libprocessgroup",
         "libnativebridge",
-        "libradio_metadata",
         "libnativeloader",
         "libmemunreachable",
         "libhidlbase",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 659f47d..92bc160 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -88,7 +88,6 @@
 extern int register_android_hardware_camera2_legacy_PerfMeasurement(JNIEnv *env);
 extern int register_android_hardware_camera2_DngCreator(JNIEnv *env);
 extern int register_android_hardware_HardwareBuffer(JNIEnv *env);
-extern int register_android_hardware_Radio(JNIEnv *env);
 extern int register_android_hardware_SensorManager(JNIEnv *env);
 extern int register_android_hardware_SerialPort(JNIEnv *env);
 extern int register_android_hardware_SoundTrigger(JNIEnv *env);
@@ -1402,7 +1401,6 @@
     REG_JNI(register_android_hardware_camera2_legacy_PerfMeasurement),
     REG_JNI(register_android_hardware_camera2_DngCreator),
     REG_JNI(register_android_hardware_HardwareBuffer),
-    REG_JNI(register_android_hardware_Radio),
     REG_JNI(register_android_hardware_SensorManager),
     REG_JNI(register_android_hardware_SerialPort),
     REG_JNI(register_android_hardware_SoundTrigger),
diff --git a/core/jni/android/graphics/ColorFilter.cpp b/core/jni/android/graphics/ColorFilter.cpp
index 5553a3e..4b6578b 100644
--- a/core/jni/android/graphics/ColorFilter.cpp
+++ b/core/jni/android/graphics/ColorFilter.cpp
@@ -30,9 +30,12 @@
 
 class SkColorFilterGlue {
 public:
-    static void SafeUnref(JNIEnv* env, jobject clazz, jlong skFilterHandle) {
-        SkColorFilter* filter = reinterpret_cast<SkColorFilter *>(skFilterHandle);
-        SkSafeUnref(filter);
+    static void SafeUnref(SkShader* shader) {
+        SkSafeUnref(shader);
+    }
+
+    static jlong GetNativeFinalizer(JNIEnv*, jobject) {
+        return static_cast<jlong>(reinterpret_cast<uintptr_t>(&SafeUnref));
     }
 
     static jlong CreatePorterDuffFilter(JNIEnv* env, jobject, jint srcColor, jint modeHandle) {
@@ -57,7 +60,7 @@
 };
 
 static const JNINativeMethod colorfilter_methods[] = {
-    {"nSafeUnref", "(J)V", (void*) SkColorFilterGlue::SafeUnref}
+    {"nativeGetFinalizer", "()J", (void*) SkColorFilterGlue::GetNativeFinalizer }
 };
 
 static const JNINativeMethod porterduff_methods[] = {
diff --git a/core/jni/android/opengl/util.cpp b/core/jni/android/opengl/util.cpp
index 1370e61..7c1ca81 100644
--- a/core/jni/android/opengl/util.cpp
+++ b/core/jni/android/opengl/util.cpp
@@ -49,27 +49,6 @@
     pDest[3] = pM[3 + 4 * 0] * x + pM[3 + 4 * 1] * y + pM[3 + 4 * 2] * z + pM[3 + 4 * 3] * w;
 }
 
-class MallocHelper {
-public:
-    MallocHelper() {
-        mData = 0;
-    }
-
-    ~MallocHelper() {
-        if (mData != 0) {
-            free(mData);
-        }
-    }
-
-    void* alloc(size_t size) {
-        mData = malloc(size);
-        return mData;
-    }
-
-private:
-    void* mData;
-};
-
 #if 0
 static
 void
@@ -85,10 +64,7 @@
 static
 int visibilityTest(float* pWS, float* pPositions, int positionsLength,
         unsigned short* pIndices, int indexCount) {
-    MallocHelper mallocHelper;
     int result = POLY_CLIP_OUT;
-    float* pTransformed = 0;
-    int transformedIndexCount = 0;
 
     if ( indexCount < 3 ) {
         return POLY_CLIP_OUT;
@@ -116,8 +92,9 @@
         return -1;
     }
 
-    transformedIndexCount = maxIndex - minIndex + 1;
-    pTransformed = (float*) mallocHelper.alloc(transformedIndexCount * 4 * sizeof(float));
+    int transformedIndexCount = maxIndex - minIndex + 1;
+    std::unique_ptr<float[]> holder{new float[transformedIndexCount * 4]};
+    float* pTransformed = holder.get();
 
     if (pTransformed == 0 ) {
         return -2;
diff --git a/core/jni/android_hardware_Radio.cpp b/core/jni/android_hardware_Radio.cpp
deleted file mode 100644
index 8b9be68..0000000
--- a/core/jni/android_hardware_Radio.cpp
+++ /dev/null
@@ -1,969 +0,0 @@
-/*
-**
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#define LOG_NDEBUG 1
-#define LOG_TAG "Radio-JNI"
-#include <utils/Log.h>
-
-#include "jni.h"
-#include "JNIHelp.h"
-#include "core_jni_helpers.h"
-#include <system/radio.h>
-#include <system/RadioMetadataWrapper.h>
-#include <radio/RadioCallback.h>
-#include <radio/Radio.h>
-#include <utils/RefBase.h>
-#include <utils/Vector.h>
-#include <binder/IMemory.h>
-#include <binder/MemoryDealer.h>
-
-using namespace android;
-
-static jclass gArrayListClass;
-static struct {
-    jmethodID    add;
-} gArrayListMethods;
-
-static const char* const kRadioManagerClassPathName = "android/hardware/radio/RadioManager";
-static jclass gRadioManagerClass;
-
-static const char* const kRadioModuleClassPathName = "android/hardware/radio/RadioModule";
-static jclass gRadioModuleClass;
-static struct {
-    jfieldID    mNativeContext;
-    jfieldID    mId;
-} gModuleFields;
-static jmethodID gPostEventFromNative;
-
-static const char* const kModulePropertiesClassPathName =
-                                     "android/hardware/radio/RadioManager$ModuleProperties";
-static jclass gModulePropertiesClass;
-static jmethodID gModulePropertiesCstor;
-
-
-static const char* const kRadioBandDescriptorClassPathName =
-                             "android/hardware/radio/RadioManager$BandDescriptor";
-static jclass gRadioBandDescriptorClass;
-static struct {
-    jfieldID mRegion;
-    jfieldID mType;
-    jfieldID mLowerLimit;
-    jfieldID mUpperLimit;
-    jfieldID mSpacing;
-} gRadioBandDescriptorFields;
-
-static const char* const kRadioFmBandDescriptorClassPathName =
-                             "android/hardware/radio/RadioManager$FmBandDescriptor";
-static jclass gRadioFmBandDescriptorClass;
-static jmethodID gRadioFmBandDescriptorCstor;
-
-static const char* const kRadioAmBandDescriptorClassPathName =
-                             "android/hardware/radio/RadioManager$AmBandDescriptor";
-static jclass gRadioAmBandDescriptorClass;
-static jmethodID gRadioAmBandDescriptorCstor;
-
-static const char* const kRadioBandConfigClassPathName =
-                             "android/hardware/radio/RadioManager$BandConfig";
-static jclass gRadioBandConfigClass;
-static struct {
-    jfieldID mDescriptor;
-} gRadioBandConfigFields;
-
-
-static const char* const kRadioFmBandConfigClassPathName =
-                             "android/hardware/radio/RadioManager$FmBandConfig";
-static jclass gRadioFmBandConfigClass;
-static jmethodID gRadioFmBandConfigCstor;
-static struct {
-    jfieldID mStereo;
-    jfieldID mRds;
-    jfieldID mTa;
-    jfieldID mAf;
-    jfieldID mEa;
-} gRadioFmBandConfigFields;
-
-static const char* const kRadioAmBandConfigClassPathName =
-                             "android/hardware/radio/RadioManager$AmBandConfig";
-static jclass gRadioAmBandConfigClass;
-static jmethodID gRadioAmBandConfigCstor;
-static struct {
-    jfieldID mStereo;
-} gRadioAmBandConfigFields;
-
-
-static const char* const kRadioProgramInfoClassPathName =
-                             "android/hardware/radio/RadioManager$ProgramInfo";
-static jclass gRadioProgramInfoClass;
-static jmethodID gRadioProgramInfoCstor;
-
-static const char* const kRadioMetadataClassPathName =
-                             "android/hardware/radio/RadioMetadata";
-static jclass gRadioMetadataClass;
-static jmethodID gRadioMetadataCstor;
-static struct {
-    jmethodID putIntFromNative;
-    jmethodID putStringFromNative;
-    jmethodID putBitmapFromNative;
-    jmethodID putClockFromNative;
-} gRadioMetadataMethods;
-
-static Mutex gLock;
-
-enum {
-    RADIO_STATUS_OK = 0,
-    RADIO_STATUS_ERROR = INT_MIN,
-    RADIO_PERMISSION_DENIED = -1,
-    RADIO_STATUS_NO_INIT = -19,
-    RADIO_STATUS_BAD_VALUE = -22,
-    RADIO_STATUS_DEAD_OBJECT = -32,
-    RADIO_STATUS_INVALID_OPERATION = -38,
-    RADIO_STATUS_TIMED_OUT = -110,
-};
-
-
-// ----------------------------------------------------------------------------
-
-static sp<Radio> getRadio(JNIEnv* env, jobject thiz)
-{
-    Mutex::Autolock l(gLock);
-    Radio* const radio = (Radio*)env->GetLongField(thiz, gModuleFields.mNativeContext);
-    return sp<Radio>(radio);
-}
-
-static sp<Radio> setRadio(JNIEnv* env, jobject thiz, const sp<Radio>& module)
-{
-    Mutex::Autolock l(gLock);
-    sp<Radio> old = (Radio*)env->GetLongField(thiz, gModuleFields.mNativeContext);
-    if (module.get()) {
-        module->incStrong((void*)setRadio);
-    }
-    if (old != 0) {
-        old->decStrong((void*)setRadio);
-    }
-    env->SetLongField(thiz, gModuleFields.mNativeContext, (jlong)module.get());
-    return old;
-}
-
-static jint convertBandDescriptorFromNative(JNIEnv *env,
-                                           jobject *jBandDescriptor,
-                                           const radio_band_config_t *nBandconfig)
-{
-    ALOGV("%s type %d region %d", __FUNCTION__, nBandconfig->band.type, nBandconfig->region);
-
-    if (nBandconfig->band.type == RADIO_BAND_FM ||
-            nBandconfig->band.type == RADIO_BAND_FM_HD) {
-        *jBandDescriptor = env->NewObject(gRadioFmBandDescriptorClass, gRadioFmBandDescriptorCstor,
-                                      nBandconfig->region, nBandconfig->band.type,
-                                      nBandconfig->band.lower_limit, nBandconfig->band.upper_limit,
-                                      nBandconfig->band.spacings[0],
-                                      nBandconfig->band.fm.stereo,
-                                      nBandconfig->band.fm.rds != RADIO_RDS_NONE,
-                                      nBandconfig->band.fm.ta,
-                                      nBandconfig->band.fm.af,
-                                      nBandconfig->band.fm.ea);
-    } else if (nBandconfig->band.type == RADIO_BAND_AM) {
-        *jBandDescriptor = env->NewObject(gRadioAmBandDescriptorClass, gRadioAmBandDescriptorCstor,
-                                      nBandconfig->region, nBandconfig->band.type,
-                                      nBandconfig->band.lower_limit, nBandconfig->band.upper_limit,
-                                      nBandconfig->band.spacings[0],
-                                      nBandconfig->band.am.stereo);
-    } else {
-        ALOGE("%s unknown band type %d", __FUNCTION__, nBandconfig->band.type);
-        return (jint)RADIO_STATUS_BAD_VALUE;
-    }
-
-    if (*jBandDescriptor == NULL) {
-        return (jint)RADIO_STATUS_NO_INIT;
-    }
-
-    return (jint)RADIO_STATUS_OK;
-}
-
-static jint convertBandConfigFromNative(JNIEnv *env,
-                                           jobject *jBandConfig,
-                                           const radio_band_config_t *nBandconfig)
-{
-    ALOGV("%s type %d region %d", __FUNCTION__, nBandconfig->band.type, nBandconfig->region);
-
-    if (nBandconfig->band.type == RADIO_BAND_FM ||
-            nBandconfig->band.type == RADIO_BAND_FM_HD) {
-        *jBandConfig = env->NewObject(gRadioFmBandConfigClass, gRadioFmBandConfigCstor,
-                                      nBandconfig->region, nBandconfig->band.type,
-                                      nBandconfig->band.lower_limit, nBandconfig->band.upper_limit,
-                                      nBandconfig->band.spacings[0],
-                                      nBandconfig->band.fm.stereo,
-                                      nBandconfig->band.fm.rds != RADIO_RDS_NONE,
-                                      nBandconfig->band.fm.ta,
-                                      nBandconfig->band.fm.af,
-                                      nBandconfig->band.fm.ea);
-    } else if (nBandconfig->band.type == RADIO_BAND_AM) {
-        *jBandConfig = env->NewObject(gRadioAmBandConfigClass, gRadioAmBandConfigCstor,
-                                      nBandconfig->region, nBandconfig->band.type,
-                                      nBandconfig->band.lower_limit, nBandconfig->band.upper_limit,
-                                      nBandconfig->band.spacings[0],
-                                      nBandconfig->band.am.stereo);
-    } else {
-        ALOGE("%s unknown band type %d", __FUNCTION__, nBandconfig->band.type);
-        return (jint)RADIO_STATUS_BAD_VALUE;
-    }
-
-    if (*jBandConfig == NULL) {
-        return (jint)RADIO_STATUS_NO_INIT;
-    }
-
-    return (jint)RADIO_STATUS_OK;
-}
-
-static jint convertMetadataFromNative(JNIEnv *env,
-                                           jobject *jMetadata,
-                                           const radio_metadata_t *nMetadata)
-{
-    ALOGV("%s", __FUNCTION__);
-    int count = radio_metadata_get_count(nMetadata);
-    if (count <= 0) {
-        return (jint)count;
-    }
-    *jMetadata = env->NewObject(gRadioMetadataClass, gRadioMetadataCstor);
-
-    jint jCount = 0;
-    jint jStatus = 0;
-    for (unsigned int i = 0; i < (unsigned int)count; i++) {
-        radio_metadata_key_t key;
-        radio_metadata_type_t type;
-        void *value;
-        size_t size;
-        if (radio_metadata_get_at_index(nMetadata, i , &key, &type, &value, &size) != 0) {
-            continue;
-        }
-        switch (type) {
-            case RADIO_METADATA_TYPE_INT: {
-                ALOGV("%s RADIO_METADATA_TYPE_INT %d", __FUNCTION__, key);
-                int32_t val = *(int32_t *)value;
-                jStatus = env->CallIntMethod(*jMetadata,
-                                   gRadioMetadataMethods.putIntFromNative,
-                                   key, (jint)val);
-                if (jStatus == 0) {
-                    jCount++;
-                }
-            } break;
-            case RADIO_METADATA_TYPE_TEXT: {
-                ALOGV("%s RADIO_METADATA_TYPE_TEXT %d", __FUNCTION__, key);
-                jstring jText = env->NewStringUTF((char *)value);
-                jStatus = env->CallIntMethod(*jMetadata,
-                                   gRadioMetadataMethods.putStringFromNative,
-                                   key, jText);
-                if (jStatus == 0) {
-                    jCount++;
-                }
-                env->DeleteLocalRef(jText);
-            } break;
-            case RADIO_METADATA_TYPE_RAW: {
-                ALOGV("%s RADIO_METADATA_TYPE_RAW %d size %zu", __FUNCTION__, key, size);
-                if (size == 0) {
-                    break;
-                }
-                jbyteArray jData = env->NewByteArray(size);
-                if (jData == NULL) {
-                    break;
-                }
-                env->SetByteArrayRegion(jData, 0, size, (jbyte *)value);
-                jStatus = env->CallIntMethod(*jMetadata,
-                                   gRadioMetadataMethods.putBitmapFromNative,
-                                   key, jData);
-                if (jStatus == 0) {
-                    jCount++;
-                }
-                env->DeleteLocalRef(jData);
-            } break;
-            case RADIO_METADATA_TYPE_CLOCK: {
-                  ALOGV("%s RADIO_METADATA_TYPE_CLOCK %d", __FUNCTION__, key);
-                  radio_metadata_clock_t *clock = (radio_metadata_clock_t *) value;
-                  jStatus =
-                      env->CallIntMethod(*jMetadata,
-                                         gRadioMetadataMethods.putClockFromNative,
-                                         key, (jint) clock->utc_seconds_since_epoch,
-                                         (jint) clock->timezone_offset_in_minutes);
-                  if (jStatus == 0) {
-                      jCount++;
-                  }
-            } break;
-        }
-    }
-    return jCount;
-}
-
-static jint convertProgramInfoFromNative(JNIEnv *env,
-                                           jobject *jProgramInfo,
-                                           const radio_program_info_t *nProgramInfo)
-{
-    ALOGV("%s", __FUNCTION__);
-    int jStatus;
-    jobject jMetadata = NULL;
-
-    if (nProgramInfo == nullptr || nProgramInfo->metadata == nullptr) {
-        return (jint)RADIO_STATUS_BAD_VALUE;
-    }
-
-    jStatus = convertMetadataFromNative(env, &jMetadata, nProgramInfo->metadata);
-    if (jStatus < 0) {
-        return jStatus;
-    }
-
-    ALOGV("%s channel %d tuned %d", __FUNCTION__, nProgramInfo->channel, nProgramInfo->tuned);
-
-    int flags = 0;  // TODO(b/32621193): pass from the HAL
-    jstring jVendorExension = env->NewStringUTF("");  // TODO(b/32621193): pass from the HAL
-    *jProgramInfo = env->NewObject(gRadioProgramInfoClass, gRadioProgramInfoCstor,
-                                  nProgramInfo->channel, nProgramInfo->sub_channel,
-                                  nProgramInfo->tuned, nProgramInfo->stereo,
-                                  nProgramInfo->digital, nProgramInfo->signal_strength,
-                                  jMetadata, flags, jVendorExension);
-
-    env->DeleteLocalRef(jMetadata);
-    env->DeleteLocalRef(jVendorExension);
-    return (jint)RADIO_STATUS_OK;
-}
-
-
-static jint convertBandConfigToNative(JNIEnv *env,
-                                      radio_band_config_t *nBandconfig,
-                                      jobject jBandConfig)
-{
-    ALOGV("%s", __FUNCTION__);
-
-    jobject jDescriptor = env->GetObjectField(jBandConfig, gRadioBandConfigFields.mDescriptor);
-
-    if (jDescriptor == NULL) {
-        return (jint)RADIO_STATUS_NO_INIT;
-    }
-
-    nBandconfig->region =
-            (radio_region_t)env->GetIntField(jDescriptor, gRadioBandDescriptorFields.mRegion);
-    nBandconfig->band.type =
-            (radio_band_t)env->GetIntField(jDescriptor, gRadioBandDescriptorFields.mType);
-    nBandconfig->band.lower_limit =
-            env->GetIntField(jDescriptor, gRadioBandDescriptorFields.mLowerLimit);
-    nBandconfig->band.upper_limit =
-            env->GetIntField(jDescriptor, gRadioBandDescriptorFields.mUpperLimit);
-    nBandconfig->band.num_spacings = 1;
-    nBandconfig->band.spacings[0] =
-            env->GetIntField(jDescriptor, gRadioBandDescriptorFields.mSpacing);
-
-    if (env->IsInstanceOf(jBandConfig, gRadioFmBandConfigClass)) {
-        nBandconfig->band.fm.deemphasis = radio_demephasis_for_region(nBandconfig->region);
-        nBandconfig->band.fm.stereo =
-                env->GetBooleanField(jBandConfig, gRadioFmBandConfigFields.mStereo);
-        nBandconfig->band.fm.rds =
-                radio_rds_for_region(env->GetBooleanField(jBandConfig,
-                                                          gRadioFmBandConfigFields.mRds),
-                                     nBandconfig->region);
-        nBandconfig->band.fm.ta = env->GetBooleanField(jBandConfig, gRadioFmBandConfigFields.mTa);
-        nBandconfig->band.fm.af = env->GetBooleanField(jBandConfig, gRadioFmBandConfigFields.mAf);
-        nBandconfig->band.fm.ea = env->GetBooleanField(jBandConfig, gRadioFmBandConfigFields.mEa);
-    } else if (env->IsInstanceOf(jBandConfig, gRadioAmBandConfigClass)) {
-        nBandconfig->band.am.stereo =
-                env->GetBooleanField(jBandConfig, gRadioAmBandConfigFields.mStereo);
-    } else {
-        return (jint)RADIO_STATUS_BAD_VALUE;
-    }
-
-    return (jint)RADIO_STATUS_OK;
-}
-
-static jint
-android_hardware_Radio_listModules(JNIEnv *env, jobject clazz,
-                                          jobject jModules)
-{
-    ALOGV("%s", __FUNCTION__);
-
-    if (jModules == NULL) {
-        ALOGE("listModules NULL ArrayList");
-        return RADIO_STATUS_BAD_VALUE;
-    }
-    if (!env->IsInstanceOf(jModules, gArrayListClass)) {
-        ALOGE("listModules not an arraylist");
-        return RADIO_STATUS_BAD_VALUE;
-    }
-
-    unsigned int numModules = 0;
-    radio_properties_t *nModules = NULL;
-
-    status_t status = Radio::listModules(nModules, &numModules);
-    if (status != NO_ERROR || numModules == 0) {
-        return (jint)status;
-    }
-
-    nModules = (radio_properties_t *)calloc(numModules, sizeof(radio_properties_t));
-
-    status = Radio::listModules(nModules, &numModules);
-    ALOGV("%s Radio::listModules status %d numModules %d", __FUNCTION__, status, numModules);
-
-    if (status != NO_ERROR) {
-        numModules = 0;
-    }
-
-    for (size_t i = 0; i < numModules; i++) {
-        if (nModules[i].num_bands == 0) {
-            continue;
-        }
-        ALOGV("%s module %zu id %d implementor %s product %s",
-              __FUNCTION__, i, nModules[i].handle, nModules[i].implementor,
-              nModules[i].product);
-
-
-        jobjectArray jBands = env->NewObjectArray(nModules[i].num_bands,
-                                                  gRadioBandDescriptorClass, NULL);
-
-        for (size_t j = 0; j < nModules[i].num_bands; j++) {
-            jobject jBandDescriptor;
-            int jStatus =
-                    convertBandDescriptorFromNative(env, &jBandDescriptor, &nModules[i].bands[j]);
-            if (jStatus != RADIO_STATUS_OK) {
-                continue;
-            }
-            env->SetObjectArrayElement(jBands, j, jBandDescriptor);
-            env->DeleteLocalRef(jBandDescriptor);
-        }
-
-        if (env->GetArrayLength(jBands) == 0) {
-            continue;
-        }
-        jstring jImplementor = env->NewStringUTF(nModules[i].implementor);
-        jstring jProduct = env->NewStringUTF(nModules[i].product);
-        jstring jVersion = env->NewStringUTF(nModules[i].version);
-        jstring jSerial = env->NewStringUTF(nModules[i].serial);
-        bool isBgscanSupported = false;  // TODO(b/32621193): pass from the HAL
-        jstring jVendorExension = env->NewStringUTF("");  // TODO(b/32621193): pass from the HAL
-        jobject jModule = env->NewObject(gModulePropertiesClass, gModulePropertiesCstor,
-                                               nModules[i].handle, nullptr, nModules[i].class_id,
-                                               jImplementor, jProduct, jVersion, jSerial,
-                                               nModules[i].num_tuners,
-                                               nModules[i].num_audio_sources,
-                                               nModules[i].supports_capture,
-                                               jBands, isBgscanSupported, jVendorExension);
-
-        env->DeleteLocalRef(jImplementor);
-        env->DeleteLocalRef(jProduct);
-        env->DeleteLocalRef(jVersion);
-        env->DeleteLocalRef(jSerial);
-        env->DeleteLocalRef(jBands);
-        env->DeleteLocalRef(jVendorExension);
-        if (jModule == NULL) {
-            continue;
-        }
-        env->CallBooleanMethod(jModules, gArrayListMethods.add, jModule);
-    }
-
-    free(nModules);
-    return (jint) status;
-}
-
-// ----------------------------------------------------------------------------
-
-class JNIRadioCallback: public RadioCallback
-{
-public:
-    JNIRadioCallback(JNIEnv* env, jobject thiz, jobject weak_thiz);
-    ~JNIRadioCallback();
-
-    virtual void onEvent(struct radio_event *event);
-
-private:
-    jclass      mClass;     // Reference to Radio class
-    jobject     mObject;    // Weak ref to Radio Java object to call on
-};
-
-JNIRadioCallback::JNIRadioCallback(JNIEnv* env, jobject thiz, jobject weak_thiz)
-{
-
-    // Hold onto the RadioModule class for use in calling the static method
-    // that posts events to the application thread.
-    jclass clazz = env->GetObjectClass(thiz);
-    if (clazz == NULL) {
-        ALOGE("Can't find class %s", kRadioModuleClassPathName);
-        return;
-    }
-    mClass = (jclass)env->NewGlobalRef(clazz);
-
-    // We use a weak reference so the RadioModule object can be garbage collected.
-    // The reference is only used as a proxy for callbacks.
-    mObject  = env->NewGlobalRef(weak_thiz);
-}
-
-JNIRadioCallback::~JNIRadioCallback()
-{
-    // remove global references
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
-    if (env == NULL) {
-        return;
-    }
-    env->DeleteGlobalRef(mObject);
-    env->DeleteGlobalRef(mClass);
-}
-
-void JNIRadioCallback::onEvent(struct radio_event *event)
-{
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
-    if (env == NULL) {
-        return;
-    }
-
-    ALOGV("%s", __FUNCTION__);
-
-    jobject jObj = NULL;
-    jint jArg2 = 0;
-    jint jStatus = RADIO_STATUS_OK;
-    switch (event->type) {
-        case RADIO_EVENT_CONFIG:
-            jStatus = convertBandConfigFromNative(env, &jObj, &event->config);
-            break;
-        case RADIO_EVENT_TUNED:
-        case RADIO_EVENT_AF_SWITCH:
-            ALOGV("%s RADIO_EVENT_TUNED channel %d", __FUNCTION__, event->info.channel);
-            jStatus = convertProgramInfoFromNative(env, &jObj, &event->info);
-            break;
-        case RADIO_EVENT_METADATA:
-            jStatus = convertMetadataFromNative(env, &jObj, event->metadata);
-            if (jStatus >= 0) {
-                jStatus = RADIO_STATUS_OK;
-            }
-            break;
-        case RADIO_EVENT_ANTENNA:
-        case RADIO_EVENT_TA:
-        case RADIO_EVENT_EA:
-        case RADIO_EVENT_CONTROL:
-            jArg2 = event->on ? 1 : 0;
-            break;
-    }
-
-    if (jStatus != RADIO_STATUS_OK) {
-        return;
-    }
-    env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject,
-                              event->type, event->status, jArg2, jObj);
-
-    env->DeleteLocalRef(jObj);
-    if (env->ExceptionCheck()) {
-        ALOGW("An exception occurred while notifying an event.");
-        env->ExceptionClear();
-    }
-}
-
-// ----------------------------------------------------------------------------
-
-static void
-android_hardware_Radio_setup(JNIEnv *env, jobject thiz,
-                             jobject weak_this, jobject jConfig, jboolean withAudio)
-{
-    ALOGV("%s", __FUNCTION__);
-
-    setRadio(env, thiz, 0);
-
-    sp<JNIRadioCallback> callback = new JNIRadioCallback(env, thiz, weak_this);
-
-    radio_handle_t handle = (radio_handle_t)env->GetIntField(thiz, gModuleFields.mId);
-
-    struct radio_band_config nConfig;
-    struct radio_band_config *configPtr = NULL;
-    if (jConfig != NULL) {
-        jint jStatus = convertBandConfigToNative(env, &nConfig, jConfig);
-        if (jStatus != RADIO_STATUS_OK) {
-            return;
-        }
-        configPtr = &nConfig;
-    }
-    sp<Radio> module = Radio::attach(handle, configPtr, (bool)withAudio, callback);
-    if (module == 0) {
-        return;
-    }
-
-    setRadio(env, thiz, module);
-}
-
-static void
-android_hardware_Radio_close(JNIEnv *env, jobject thiz)
-{
-    ALOGV("%s", __FUNCTION__);
-    sp<Radio> module = setRadio(env, thiz, 0);
-    ALOGV("detach module %p", module.get());
-    if (module != 0) {
-        ALOGV("detach module->detach()");
-        module->detach();
-    }
-}
-
-static void
-android_hardware_Radio_finalize(JNIEnv *env, jobject thiz)
-{
-    ALOGV("%s", __FUNCTION__);
-    sp<Radio> module = getRadio(env, thiz);
-    if (module != 0) {
-        ALOGW("Radio finalized without being detached");
-    }
-    android_hardware_Radio_close(env, thiz);
-}
-
-static jint
-android_hardware_Radio_setConfiguration(JNIEnv *env, jobject thiz, jobject jConfig)
-{
-    ALOGV("%s", __FUNCTION__);
-    sp<Radio> module = getRadio(env, thiz);
-    if (module == NULL) {
-        return RADIO_STATUS_NO_INIT;
-    }
-
-    if (!env->IsInstanceOf(jConfig, gRadioFmBandConfigClass) &&
-            !env->IsInstanceOf(jConfig, gRadioAmBandConfigClass)) {
-        return RADIO_STATUS_BAD_VALUE;
-    }
-
-    struct radio_band_config nConfig;
-    jint jStatus = convertBandConfigToNative(env, &nConfig, jConfig);
-    if (jStatus != RADIO_STATUS_OK) {
-        return jStatus;
-    }
-
-    status_t status = module->setConfiguration(&nConfig);
-    return (jint)status;
-}
-
-static jint
-android_hardware_Radio_getConfiguration(JNIEnv *env, jobject thiz, jobjectArray jConfigs)
-{
-    ALOGV("%s", __FUNCTION__);
-    sp<Radio> module = getRadio(env, thiz);
-    if (module == NULL) {
-        return RADIO_STATUS_NO_INIT;
-    }
-    if (env->GetArrayLength(jConfigs) != 1) {
-        return (jint)RADIO_STATUS_BAD_VALUE;
-    }
-
-    struct radio_band_config nConfig;
-
-    status_t status = module->getConfiguration(&nConfig);
-    if (status != NO_ERROR) {
-        return (jint)status;
-    }
-    jobject jConfig;
-    int jStatus = convertBandConfigFromNative(env, &jConfig, &nConfig);
-    if (jStatus != RADIO_STATUS_OK) {
-        return jStatus;
-    }
-    env->SetObjectArrayElement(jConfigs, 0, jConfig);
-    env->DeleteLocalRef(jConfig);
-    return RADIO_STATUS_OK;
-}
-
-static jint
-android_hardware_Radio_setMute(JNIEnv *env, jobject thiz, jboolean mute)
-{
-    ALOGV("%s", __FUNCTION__);
-    sp<Radio> module = getRadio(env, thiz);
-    if (module == NULL) {
-        return RADIO_STATUS_NO_INIT;
-    }
-    status_t status = module->setMute((bool)mute);
-    return (jint)status;
-}
-
-static jboolean
-android_hardware_Radio_getMute(JNIEnv *env, jobject thiz)
-{
-    ALOGV("%s", __FUNCTION__);
-    sp<Radio> module = getRadio(env, thiz);
-    if (module == NULL) {
-        return true;
-    }
-    bool mute = true;
-    status_t status = module->getMute(&mute);
-    if (status != NO_ERROR) {
-        return true;
-    }
-    return (jboolean)mute;
-}
-
-static jint
-android_hardware_Radio_step(JNIEnv *env, jobject thiz, jint direction, jboolean skipSubChannel)
-{
-    ALOGV("%s", __FUNCTION__);
-    sp<Radio> module = getRadio(env, thiz);
-    if (module == NULL) {
-        return RADIO_STATUS_NO_INIT;
-    }
-    status_t status = module->step((radio_direction_t)direction, (bool)skipSubChannel);
-    return (jint)status;
-}
-
-static jint
-android_hardware_Radio_scan(JNIEnv *env, jobject thiz, jint direction, jboolean skipSubChannel)
-{
-    ALOGV("%s", __FUNCTION__);
-    sp<Radio> module = getRadio(env, thiz);
-    if (module == NULL) {
-        return RADIO_STATUS_NO_INIT;
-    }
-    status_t status = module->scan((radio_direction_t)direction, (bool)skipSubChannel);
-    return (jint)status;
-}
-
-static jint
-android_hardware_Radio_tune(JNIEnv *env, jobject thiz, jint channel, jint subChannel)
-{
-    ALOGV("%s", __FUNCTION__);
-    sp<Radio> module = getRadio(env, thiz);
-    if (module == NULL) {
-        return RADIO_STATUS_NO_INIT;
-    }
-    status_t status = module->tune((uint32_t)channel, (uint32_t)subChannel);
-    return (jint)status;
-}
-
-static jint
-android_hardware_Radio_cancel(JNIEnv *env, jobject thiz)
-{
-    ALOGV("%s", __FUNCTION__);
-    sp<Radio> module = getRadio(env, thiz);
-    if (module == NULL) {
-        return RADIO_STATUS_NO_INIT;
-    }
-    status_t status = module->cancel();
-    return (jint)status;
-}
-
-static jint
-android_hardware_Radio_getProgramInformation(JNIEnv *env, jobject thiz, jobjectArray jInfos)
-{
-    ALOGV("%s", __FUNCTION__);
-    sp<Radio> module = getRadio(env, thiz);
-    if (module == NULL) {
-        return RADIO_STATUS_NO_INIT;
-    }
-    if (env->GetArrayLength(jInfos) != 1) {
-        return (jint)RADIO_STATUS_BAD_VALUE;
-    }
-
-    struct radio_program_info nInfo;
-    RadioMetadataWrapper metadataWrapper(&nInfo.metadata);
-    jobject jInfo = NULL;
-    int jStatus;
-
-    jStatus = (int)module->getProgramInformation(&nInfo);
-    if (jStatus != RADIO_STATUS_OK) {
-        goto exit;
-    }
-    jStatus = convertProgramInfoFromNative(env, &jInfo, &nInfo);
-    if (jStatus != RADIO_STATUS_OK) {
-        goto exit;
-    }
-    env->SetObjectArrayElement(jInfos, 0, jInfo);
-
-exit:
-    if (jInfo != NULL) {
-        env->DeleteLocalRef(jInfo);
-    }
-    return jStatus;
-}
-
-static jboolean
-android_hardware_Radio_isAntennaConnected(JNIEnv *env, jobject thiz)
-{
-    ALOGV("%s", __FUNCTION__);
-    sp<Radio> module = getRadio(env, thiz);
-    if (module == NULL) {
-        return false;
-    }
-
-    struct radio_band_config nConfig;
-
-    status_t status = module->getConfiguration(&nConfig);
-    if (status != NO_ERROR) {
-        return false;
-    }
-
-    return (jboolean)nConfig.band.antenna_connected;
-}
-
-
-static jboolean
-android_hardware_Radio_hasControl(JNIEnv *env, jobject thiz)
-{
-    ALOGV("%s", __FUNCTION__);
-    sp<Radio> module = getRadio(env, thiz);
-    if (module == NULL) {
-        return false;
-    }
-
-    bool hasControl;
-    status_t status = module->hasControl(&hasControl);
-    if (status != NO_ERROR) {
-        return false;
-    }
-
-    return (jboolean)hasControl;
-}
-
-
-static JNINativeMethod gMethods[] = {
-    {"nativeListModules",
-        "(Ljava/util/List;)I",
-        (void *)android_hardware_Radio_listModules},
-};
-
-static JNINativeMethod gModuleMethods[] = {
-    {"native_setup",
-        "(Ljava/lang/Object;Landroid/hardware/radio/RadioManager$BandConfig;Z)V",
-        (void *)android_hardware_Radio_setup},
-    {"native_finalize",
-        "()V",
-        (void *)android_hardware_Radio_finalize},
-    {"close",
-        "()V",
-        (void *)android_hardware_Radio_close},
-    {"setConfiguration",
-        "(Landroid/hardware/radio/RadioManager$BandConfig;)I",
-        (void *)android_hardware_Radio_setConfiguration},
-    {"getConfiguration",
-        "([Landroid/hardware/radio/RadioManager$BandConfig;)I",
-        (void *)android_hardware_Radio_getConfiguration},
-    {"setMute",
-        "(Z)I",
-        (void *)android_hardware_Radio_setMute},
-    {"getMute",
-        "()Z",
-        (void *)android_hardware_Radio_getMute},
-    {"step",
-        "(IZ)I",
-        (void *)android_hardware_Radio_step},
-    {"scan",
-        "(IZ)I",
-        (void *)android_hardware_Radio_scan},
-    {"tune",
-        "(II)I",
-        (void *)android_hardware_Radio_tune},
-    {"cancel",
-        "()I",
-        (void *)android_hardware_Radio_cancel},
-    {"getProgramInformation",
-        "([Landroid/hardware/radio/RadioManager$ProgramInfo;)I",
-        (void *)android_hardware_Radio_getProgramInformation},
-    {"isAntennaConnected",
-        "()Z",
-        (void *)android_hardware_Radio_isAntennaConnected},
-    {"hasControl",
-        "()Z",
-        (void *)android_hardware_Radio_hasControl},
-};
-
-int register_android_hardware_Radio(JNIEnv *env)
-{
-    jclass arrayListClass = FindClassOrDie(env, "java/util/ArrayList");
-    gArrayListClass = MakeGlobalRefOrDie(env, arrayListClass);
-    gArrayListMethods.add = GetMethodIDOrDie(env, arrayListClass, "add", "(Ljava/lang/Object;)Z");
-
-    jclass lClass = FindClassOrDie(env, kRadioManagerClassPathName);
-    gRadioManagerClass = MakeGlobalRefOrDie(env, lClass);
-
-    jclass moduleClass = FindClassOrDie(env, kRadioModuleClassPathName);
-    gRadioModuleClass = MakeGlobalRefOrDie(env, moduleClass);
-    gPostEventFromNative = GetStaticMethodIDOrDie(env, moduleClass, "postEventFromNative",
-                                                  "(Ljava/lang/Object;IIILjava/lang/Object;)V");
-    gModuleFields.mNativeContext = GetFieldIDOrDie(env, moduleClass, "mNativeContext", "J");
-    gModuleFields.mId = GetFieldIDOrDie(env, moduleClass, "mId", "I");
-
-    jclass modulePropertiesClass = FindClassOrDie(env, kModulePropertiesClassPathName);
-    gModulePropertiesClass = MakeGlobalRefOrDie(env, modulePropertiesClass);
-    gModulePropertiesCstor = GetMethodIDOrDie(env, modulePropertiesClass, "<init>",
-            "(ILjava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;"
-            "Ljava/lang/String;IIZ[Landroid/hardware/radio/RadioManager$BandDescriptor;Z"
-            "Ljava/lang/String;)V");
-
-    jclass bandDescriptorClass = FindClassOrDie(env, kRadioBandDescriptorClassPathName);
-    gRadioBandDescriptorClass = MakeGlobalRefOrDie(env, bandDescriptorClass);
-    gRadioBandDescriptorFields.mRegion = GetFieldIDOrDie(env, bandDescriptorClass, "mRegion", "I");
-    gRadioBandDescriptorFields.mType = GetFieldIDOrDie(env, bandDescriptorClass, "mType", "I");
-    gRadioBandDescriptorFields.mLowerLimit =
-            GetFieldIDOrDie(env, bandDescriptorClass, "mLowerLimit", "I");
-    gRadioBandDescriptorFields.mUpperLimit =
-            GetFieldIDOrDie(env, bandDescriptorClass, "mUpperLimit", "I");
-    gRadioBandDescriptorFields.mSpacing =
-            GetFieldIDOrDie(env, bandDescriptorClass, "mSpacing", "I");
-
-    jclass fmBandDescriptorClass = FindClassOrDie(env, kRadioFmBandDescriptorClassPathName);
-    gRadioFmBandDescriptorClass = MakeGlobalRefOrDie(env, fmBandDescriptorClass);
-    gRadioFmBandDescriptorCstor = GetMethodIDOrDie(env, fmBandDescriptorClass, "<init>",
-            "(IIIIIZZZZZ)V");
-
-    jclass amBandDescriptorClass = FindClassOrDie(env, kRadioAmBandDescriptorClassPathName);
-    gRadioAmBandDescriptorClass = MakeGlobalRefOrDie(env, amBandDescriptorClass);
-    gRadioAmBandDescriptorCstor = GetMethodIDOrDie(env, amBandDescriptorClass, "<init>",
-            "(IIIIIZ)V");
-
-    jclass bandConfigClass = FindClassOrDie(env, kRadioBandConfigClassPathName);
-    gRadioBandConfigClass = MakeGlobalRefOrDie(env, bandConfigClass);
-    gRadioBandConfigFields.mDescriptor =
-            GetFieldIDOrDie(env, bandConfigClass, "mDescriptor",
-                            "Landroid/hardware/radio/RadioManager$BandDescriptor;");
-
-    jclass fmBandConfigClass = FindClassOrDie(env, kRadioFmBandConfigClassPathName);
-    gRadioFmBandConfigClass = MakeGlobalRefOrDie(env, fmBandConfigClass);
-    gRadioFmBandConfigCstor = GetMethodIDOrDie(env, fmBandConfigClass, "<init>",
-            "(IIIIIZZZZZ)V");
-    gRadioFmBandConfigFields.mStereo = GetFieldIDOrDie(env, fmBandConfigClass, "mStereo", "Z");
-    gRadioFmBandConfigFields.mRds = GetFieldIDOrDie(env, fmBandConfigClass, "mRds", "Z");
-    gRadioFmBandConfigFields.mTa = GetFieldIDOrDie(env, fmBandConfigClass, "mTa", "Z");
-    gRadioFmBandConfigFields.mAf = GetFieldIDOrDie(env, fmBandConfigClass, "mAf", "Z");
-    gRadioFmBandConfigFields.mEa =
-        GetFieldIDOrDie(env, fmBandConfigClass, "mEa", "Z");
-
-
-    jclass amBandConfigClass = FindClassOrDie(env, kRadioAmBandConfigClassPathName);
-    gRadioAmBandConfigClass = MakeGlobalRefOrDie(env, amBandConfigClass);
-    gRadioAmBandConfigCstor = GetMethodIDOrDie(env, amBandConfigClass, "<init>",
-            "(IIIIIZ)V");
-    gRadioAmBandConfigFields.mStereo = GetFieldIDOrDie(env, amBandConfigClass, "mStereo", "Z");
-
-    jclass programInfoClass = FindClassOrDie(env, kRadioProgramInfoClassPathName);
-    gRadioProgramInfoClass = MakeGlobalRefOrDie(env, programInfoClass);
-    gRadioProgramInfoCstor = GetMethodIDOrDie(env, programInfoClass, "<init>",
-            "(IIZZZILandroid/hardware/radio/RadioMetadata;ILjava/lang/String;)V");
-
-    jclass metadataClass = FindClassOrDie(env, kRadioMetadataClassPathName);
-    gRadioMetadataClass = MakeGlobalRefOrDie(env, metadataClass);
-    gRadioMetadataCstor = GetMethodIDOrDie(env, metadataClass, "<init>", "()V");
-    gRadioMetadataMethods.putIntFromNative = GetMethodIDOrDie(env, metadataClass,
-                                                              "putIntFromNative",
-                                                              "(II)I");
-    gRadioMetadataMethods.putStringFromNative = GetMethodIDOrDie(env, metadataClass,
-                                                                 "putStringFromNative",
-                                                                 "(ILjava/lang/String;)I");
-    gRadioMetadataMethods.putBitmapFromNative = GetMethodIDOrDie(env, metadataClass,
-                                                                 "putBitmapFromNative",
-                                                                 "(I[B)I");
-    gRadioMetadataMethods.putClockFromNative = GetMethodIDOrDie(env, metadataClass,
-                                                                "putClockFromNative",
-                                                                "(IJI)I");
-
-
-    RegisterMethodsOrDie(env, kRadioManagerClassPathName, gMethods, NELEM(gMethods));
-
-    int ret = RegisterMethodsOrDie(env, kRadioModuleClassPathName, gModuleMethods, NELEM(gModuleMethods));
-
-    ALOGV("%s DONE", __FUNCTION__);
-
-    return ret;
-}
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 1779ada..e8f6074 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -396,7 +396,7 @@
 }
 
 static void
-android_media_AudioSystem_recording_callback(int event, audio_session_t session, int source,
+android_media_AudioSystem_recording_callback(int event, const record_client_info_t *clientInfo,
         const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig,
         audio_patch_handle_t patchHandle)
 {
@@ -404,8 +404,8 @@
     if (env == NULL) {
         return;
     }
-    if (clientConfig == NULL || deviceConfig == NULL) {
-        ALOGE("Unexpected null client/device configurations in recording callback");
+    if (clientInfo == NULL || clientConfig == NULL || deviceConfig == NULL) {
+        ALOGE("Unexpected null client/device info or configurations in recording callback");
         return;
     }
 
@@ -433,7 +433,7 @@
     jclass clazz = env->FindClass(kClassPathName);
     env->CallStaticVoidMethod(clazz,
             gAudioPolicyEventHandlerMethods.postRecordConfigEventFromNative,
-            event, session, source, recParamArray);
+            event, (jint) clientInfo->uid, clientInfo->session, clientInfo->source, recParamArray);
     env->DeleteLocalRef(clazz);
 
     env->DeleteLocalRef(recParamArray);
@@ -1930,7 +1930,7 @@
                     "dynamicPolicyCallbackFromNative", "(ILjava/lang/String;I)V");
     gAudioPolicyEventHandlerMethods.postRecordConfigEventFromNative =
             GetStaticMethodIDOrDie(env, env->FindClass(kClassPathName),
-                    "recordingCallbackFromNative", "(III[I)V");
+                    "recordingCallbackFromNative", "(IIII[I)V");
 
     jclass audioMixClass = FindClassOrDie(env, "android/media/audiopolicy/AudioMix");
     gAudioMixClass = MakeGlobalRefOrDie(env, audioMixClass);
diff --git a/core/jni/android_text_StaticLayout.cpp b/core/jni/android_text_StaticLayout.cpp
index 4a445d8..d81bc2f 100644
--- a/core/jni/android_text_StaticLayout.cpp
+++ b/core/jni/android_text_StaticLayout.cpp
@@ -137,15 +137,19 @@
     return reinterpret_cast<jlong>(hyphenator);
 }
 
-static void nSetLocale(JNIEnv* env, jclass, jlong nativePtr, jstring javaLocaleName,
-        jlong nativeHyphenator) {
-    ScopedIcuLocale icuLocale(env, javaLocaleName);
+static void nSetLocales(JNIEnv* env, jclass, jlong nativePtr, jstring javaLocaleNames,
+        jlongArray nativeHyphenators) {
     minikin::LineBreaker* b = reinterpret_cast<minikin::LineBreaker*>(nativePtr);
-    minikin::Hyphenator* hyphenator = reinterpret_cast<minikin::Hyphenator*>(nativeHyphenator);
 
-    if (icuLocale.valid()) {
-        b->setLocale(icuLocale.locale(), hyphenator);
+    ScopedUtfChars localeNames(env, javaLocaleNames);
+    ScopedLongArrayRO hyphArr(env, nativeHyphenators);
+    const size_t numLocales = hyphArr.size();
+    std::vector<minikin::Hyphenator*> hyphVec;
+    hyphVec.reserve(numLocales);
+    for (size_t i = 0; i < numLocales; i++) {
+        hyphVec.push_back(reinterpret_cast<minikin::Hyphenator*>(hyphArr[i]));
     }
+    b->setLocales(localeNames.c_str(), hyphVec);
 }
 
 static void nSetIndents(JNIEnv* env, jclass, jlong nativePtr, jintArray indents) {
@@ -194,7 +198,7 @@
     {"nFreeBuilder", "(J)V", (void*) nFreeBuilder},
     {"nFinishBuilder", "(J)V", (void*) nFinishBuilder},
     {"nLoadHyphenator", "(Ljava/nio/ByteBuffer;III)J", (void*) nLoadHyphenator},
-    {"nSetLocale", "(JLjava/lang/String;J)V", (void*) nSetLocale},
+    {"nSetLocales", "(JLjava/lang/String;[J)V", (void*) nSetLocales},
     {"nSetupParagraph", "(J[CIFIF[IIIIZ)V", (void*) nSetupParagraph},
     {"nSetIndents", "(J[I)V", (void*) nSetIndents},
     {"nAddStyleRun", "(JJJIIZ)F", (void*) nAddStyleRun},
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 26b0034..e2aa17b 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -836,7 +836,7 @@
     env->SetLongField(obj, gBinderOffsets.mObject, (jlong)jbh);
 }
 
-static void android_os_Binder_destroy(JNIEnv* env, jobject obj)
+static void android_os_Binder_destroyBinder(JNIEnv* env, jobject obj)
 {
     JavaBBinderHolder* jbh = (JavaBBinderHolder*)
         env->GetLongField(obj, gBinderOffsets.mObject);
@@ -847,7 +847,7 @@
     } else {
         // Encountering an uninitialized binder is harmless.  All it means is that
         // the Binder was only partially initialized when its finalizer ran and called
-        // destroy().  The Binder could be partially initialized for several reasons.
+        // destroyBinder().  The Binder could be partially initialized for several reasons.
         // For example, a Binder subclass constructor might have thrown an exception before
         // it could delegate to its superclass's constructor.  Consequently init() would
         // not have been called and the holder pointer would remain NULL.
@@ -872,7 +872,7 @@
     { "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
     { "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
     { "init", "()V", (void*)android_os_Binder_init },
-    { "destroy", "()V", (void*)android_os_Binder_destroy },
+    { "destroyBinder", "()V", (void*)android_os_Binder_destroyBinder },
     { "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable }
 };
 
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index d73e7dd..cb53106 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -221,6 +221,14 @@
 // The debug malloc library needs to know whether it's the zygote or a child.
 extern "C" int gMallocLeakZygoteChild;
 
+static void PreApplicationInit() {
+  // The child process sets this to indicate it's not the zygote.
+  gMallocLeakZygoteChild = 1;
+
+  // Set the jemalloc decay time to 1.
+  mallopt(M_DECAY_TIME, 1);
+}
+
 static void EnableKeepCapabilities(JNIEnv* env) {
   int rc = prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
   if (rc == -1) {
@@ -517,11 +525,7 @@
   pid_t pid = fork();
 
   if (pid == 0) {
-    // The child process.
-    gMallocLeakZygoteChild = 1;
-
-    // Set the jemalloc decay time to 1.
-    mallopt(M_DECAY_TIME, 1);
+    PreApplicationInit();
 
     // Clean up any descriptors which must be closed immediately
     DetachDescriptors(env, fdsToClose);
@@ -678,6 +682,10 @@
 
 namespace android {
 
+static void com_android_internal_os_Zygote_nativePreApplicationInit(JNIEnv*, jclass) {
+  PreApplicationInit();
+}
+
 static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
         JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,
         jint debug_flags, jobjectArray rlimits,
@@ -807,7 +815,9 @@
     { "nativeAllowFileAcrossFork", "(Ljava/lang/String;)V",
       (void *) com_android_internal_os_Zygote_nativeAllowFileAcrossFork },
     { "nativeUnmountStorageOnInit", "()V",
-      (void *) com_android_internal_os_Zygote_nativeUnmountStorageOnInit }
+      (void *) com_android_internal_os_Zygote_nativeUnmountStorageOnInit },
+    { "nativePreApplicationInit", "()V",
+      (void *) com_android_internal_os_Zygote_nativePreApplicationInit }
 };
 
 int register_com_android_internal_os_Zygote(JNIEnv* env) {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 395250c..be7934b 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -147,6 +147,7 @@
     <protected-broadcast android:name="android.bluetooth.device.action.CONNECTION_ACCESS_CANCEL" />
     <protected-broadcast android:name="android.bluetooth.device.action.CONNECTION_ACCESS_REQUEST" />
     <protected-broadcast android:name="android.bluetooth.device.action.SDP_RECORD" />
+    <protected-broadcast android:name="android.bluetooth.device.action.BATTERY_LEVEL_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.devicepicker.action.LAUNCH" />
     <protected-broadcast android:name="android.bluetooth.devicepicker.action.DEVICE_SELECTED" />
     <protected-broadcast
@@ -303,6 +304,7 @@
     <protected-broadcast android:name="com.android.server.WifiManager.action.DEVICE_IDLE" />
     <protected-broadcast android:name="com.android.server.action.REMOTE_BUGREPORT_SHARING_ACCEPTED" />
     <protected-broadcast android:name="com.android.server.action.REMOTE_BUGREPORT_SHARING_DECLINED" />
+    <protected-broadcast android:name="com.android.server.action.WIPE_EUICC_DATA" />
     <protected-broadcast android:name="com.android.server.usb.ACTION_OPEN_IN_APPS" />
     <protected-broadcast android:name="com.android.server.am.DELETE_DUMPHEAP" />
     <protected-broadcast android:name="com.android.server.net.action.SNOOZE_WARNING" />
diff --git a/core/res/res/layout-land/time_picker_material.xml b/core/res/res/layout-land/time_picker_material.xml
index 863efef..d83ccb2 100644
--- a/core/res/res/layout-land/time_picker_material.xml
+++ b/core/res/res/layout-land/time_picker_material.xml
@@ -17,6 +17,7 @@
 
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layoutDirection="ltr"
     android:layout_width="match_parent"
     android:layout_height="wrap_content">
 
@@ -30,6 +31,7 @@
 
         <LinearLayout
             android:id="@+id/time_layout"
+            android:layoutDirection="ltr"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:paddingTop="@dimen/timepicker_radial_picker_top_margin"
diff --git a/core/res/res/layout/notification_template_right_icon.xml b/core/res/res/layout/notification_template_right_icon.xml
index aa4e05b..fbf7538 100644
--- a/core/res/res/layout/notification_template_right_icon.xml
+++ b/core/res/res/layout/notification_template_right_icon.xml
@@ -26,8 +26,9 @@
                android:layout_gravity="top|end"
                android:layout_marginTop="36dp"
                android:layout_marginEnd="@dimen/notification_content_margin_end"
-               android:scaleType="centerCrop"/>
-    <ImageView android:id="@+id/reply_icon_action"
+               android:scaleType="centerCrop"
+               android:importantForAccessibility="no" />
+    <ImageButton android:id="@+id/reply_icon_action"
                android:layout_width="16dp"
                android:layout_height="16dp"
                android:layout_gravity="top|end"
@@ -36,6 +37,7 @@
                android:background="@drawable/notification_reply_background"
                android:src="@drawable/ic_reply_notification"
                android:scaleType="center"
+               android:contentDescription="@string/notification_reply_button_accessibility"
                visiblity="gone"/>
 </FrameLayout>
 
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index cfe87e7..907f895 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> dae"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> dag <xliff:g id="HOURS">%2$d</xliff:g> uur"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> dag <xliff:g id="HOURS">%2$d</xliff:g> uur"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> uur"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> u. <xliff:g id="MINUTES">%2$d</xliff:g> min."</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> u. <xliff:g id="MINUTES">%2$d</xliff:g> min."</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> minute"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min."</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min. <xliff:g id="SECONDS">%2$d</xliff:g> s."</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min. <xliff:g id="SECONDS">%2$d</xliff:g> s."</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> sekondes"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> sekonde"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Titelloos&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Geen foonnommer)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Onbekend"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Geen stem- of nooddiens nie"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Word tydelik nie deur die selnetwerk by jou ligging aangebied nie"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Kan netwerk nie bereik nie"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Om die opvangs te verbeter, probeer die tipe verander wat gekies is by Stelsel &gt; Netwerk en internet &gt; Mobiele netwerke &gt; Voorkeurnetwerktipe."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Om opvangs te verbeter, probeer die soort verander wat by Instellings &gt; Netwerk en internet &gt; Mobiele netwerke &gt; Voorkeurnetwerksoort gekies is."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Opletberigte"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Oproepaanstuur"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Noodterugbel-modus"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Soek vir diens"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi-oproepe"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Om oproepe te maak en boodskappe oor Wi-Fi te stuur, vra jou diensverskaffer eers om hierdie diens op te stel. Skakel Wi-Fi-oproepe dan weer in Instellings aan."</item>
+    <item msgid="3910386316304772394">"Om oproepe te maak en boodskappe oor Wi-Fi te stuur, vra eers jou diensverskaffer om hierdie diens op te stel. Skakel Wi-Fi-oproepe dan weer in Instellings aan. (Foutkode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Registreer by jou diensverskaffer"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">Oop Wi-Fi-netwerke beskikbaar</item>
       <item quantity="one">Oop Wi-Fi-netwerk beskikbaar</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Koppel aan oop Wi-Fi-netwerk"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Koppel tans aan oop Wi‑Fi-netwerk"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Aan Wi-Fi-netwerk gekoppel"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Kon nie aan Wi-Fi-netwerk koppel nie"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tik om alle netwerke te sien"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Koppel"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Alle netwerke"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Meld aan by Wi-Fi-netwerk"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Meld by netwerk aan"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 0e904ad..27ce84d 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> ቀኖች"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> ቀን <xliff:g id="HOURS">%2$d</xliff:g> ሰዓ"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> ቀን <xliff:g id="HOURS">%2$d</xliff:g> ሰዓ"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> ሰዓ"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ሰዓ <xliff:g id="MINUTES">%2$d</xliff:g> ደቂቃ"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> ሰዓ <xliff:g id="MINUTES">%2$d</xliff:g> ደቂቃ"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> ደቂቃዎች"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> ደቂቃዎች"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> ደቂቃ <xliff:g id="SECONDS">%2$d</xliff:g> ሴ"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> ደቂቃ <xliff:g id="SECONDS">%2$d</xliff:g> ሴ"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> ሴ"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> ሴ"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;ርዕስ አልባ&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(ምንም ስልክ ቁጥር የለም)"</string>
     <string name="unknownName" msgid="6867811765370350269">"አይታወቅም"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"ምንም የድምፅ እና የድንገተኛ አደጋ ጥሪ አገልግሎት የለም"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"ለጊዜው በአካባቢዎ ባለው የተንቀሳቃሽ ስልክ አውታረ መረብ አይቀርብም"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"አውታረ መረብ ላይ መድረስ አይቻልም"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"ቅበላን ለማሻሻል የተመረጠውን ዓይነት በሥርዓት &gt; አውታረ መረቦች እና በይነመረብ &gt; የተንቀሳቃሽ ስልክ አውታረ መረቦች &gt; ተመራጭ የአውታረ መረብ ዓይነት ላይ ለመለወጥ ይሞክሩ።"</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"ቅበላን ለማሻሻል የተመረጠውን ዓይነት በቅንብሮች &gt; አውታረ መረብ እና በይነመረብ &gt; የተንቀሳቃሽ ስልክ አውታረ መረቦች &gt; ተመራጭ የአውታረ መረብ ዓይነት ላይ ለመለወጥ ይሞክሩ።"</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"ማንቂያዎች"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"ጥሪ ማስተላለፍ"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"የአደጋ ጊዜ ጥሪ ሁነታ"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"አገልግሎት ፍለጋ"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"የWi-Fi ጥሪ ማድረጊያ"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"በWi-Fi ላይ ጥሪዎችን ለማድረግ እና መልዕክቶችን ለመላክ መጀመሪያ የአገልግሎት አቅራቢዎ ይህን አገልግሎት እንዲያዘጋጅልዎ መጠየቅ አለብዎት። ከዚያ ከቅንብሮች ሆነው እንደገና የWi-Fi ጥሪን ያብሩ።"</item>
+    <item msgid="3910386316304772394">"በWi-Fi ላይ ጥሪዎችን ለማድረግ እና መልዕክቶችን ለመላክ መጀመሪያ የአገልግሎት አቅራቢዎ ይህን አገልግሎት እንዲያዘጋጅልዎ መጠየቅ አለብዎት። ከዚያ ከቅንብሮች ሆነው እንደገና የWi-Fi ጥሪን ያብሩ። (የስህተት ኮድ፦ <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"የአገልግሎት አቅራቢዎ ጋር ይመዝገቡ"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="one">የሚገኙ የWi-Fi አውታረ መረቦችን ክፈት</item>
       <item quantity="other">የሚገኙ የWi-Fi አውታረ መረቦችን ክፈት</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"ከክፍት የWi‑Fi አውታረ መረብ ጋር ያገናኙ"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"ከክፍት የWi‑Fi አውታረ መረብ ጋር በመገናኘት ላይ"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"ከWi‑Fi አውታረ መረብ ጋር ተገናኝቷል"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"ከWi‑Fi አውታረ መረብ ጋር መገናኘት አልተቻለም"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ሁሉንም አውታረ መረቦችን ለማየት መታ ያድርጉ"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"አገናኝ"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"ሁሉም አውታረ መረቦች"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"ወደ Wi-Fi አውታረ መረብ በመለያ ግባ"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"ወደ አውታረ መረብ በመለያ ይግቡ"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 3483b68..d038a42 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"تيرابايت"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"بيتابايت"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> يوم"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> يوم <xliff:g id="HOURS">%2$d</xliff:g> ساعة"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> يوم <xliff:g id="HOURS">%2$d</xliff:g> ساعة"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> ساعة"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ساعة <xliff:g id="MINUTES">%2$d</xliff:g> دقيقة"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> ساعة <xliff:g id="MINUTES">%2$d</xliff:g> دقيقة"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> دقيقة"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> دقيقة"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> دقيقة <xliff:g id="SECONDS">%2$d</xliff:g> ثانية"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> دقيقة <xliff:g id="SECONDS">%2$d</xliff:g> ثانية"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> ثانية"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> ثانية"</string>
     <string name="untitled" msgid="4638956954852782576">"‏&lt;بلا عنوان&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(ليس هناك رقم هاتف)"</string>
     <string name="unknownName" msgid="6867811765370350269">"غير معروف"</string>
@@ -99,7 +87,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"لا تتوفر خدمة الصوت/الطوارئ"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"مؤقتا لا تقدمها شبكة الجوال في موقعك"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"يتعذر الوصول إلى الشبكة"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"‏لتحسين الاستقبال، يمكنك تجربة تغيير النوع المحدّد في النظام &gt; الشبكة والإنترنت &gt; شبكات الجوّال &gt; نوع الشبكة المفضّل."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"‏لتحسين الاستقبال، يمكنك محاولة تغيير النوع المحدّد من خلال الإعدادات &gt; الشبكة والإنترنت &gt; شبكات الجوّال &gt; نوع الشبكة المفضّل."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"التنبيهات"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"إعادة توجيه المكالمة"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"وضع معاودة الاتصال بالطوارئ"</string>
@@ -135,7 +123,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"البحث عن خدمة"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"‏الاتصال عبر Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"‏لإجراء مكالمات وإرسال رسائل عبر Wi-Fi، اطلب من مشغّل شبكة الجوّال أولاً إعداد هذا الجهاز، ثم شغّل الاتصال عبر Wi-Fi مرة أخرى من خلال الإعدادات."</item>
+    <item msgid="3910386316304772394">"‏لإجراء مكالمات وإرسال رسائل عبر Wi-Fi، اطلب من مشغّل شبكة الجوّال أولاً إعداد هذه الخدمة، ثم شغّل الاتصال عبر Wi-Fi مرة أخرى من خلال الإعدادات. (رمز الخطأ: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"التسجيل لدى مشغّل شبكة الجوّال"</item>
@@ -1194,6 +1182,13 @@
       <item quantity="other">‏تتوفر شبكات Wi-Fi مفتوحة</item>
       <item quantity="one">‏تتوفر شبكة Wi-Fi واحدة مفتوحة</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"‏الاتصال بشبكة Wi-Fi المفتوحة"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"‏جارٍ الاتصال بشبكة Wi-Fi المفتوحة"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"‏تم الاتصال بشبكة Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"‏تعذَّر الاتصال بشبكة Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"انقر للاطلاع على جميع الشبكات"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"اتصال"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"جميع الشبكات"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"‏تسجيل الدخول إلى شبكة Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"تسجيل الدخول إلى الشبكة"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 01e5452..76f7e2c 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> gün"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> gan <xliff:g id="HOURS">%2$d</xliff:g> saat"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> gün <xliff:g id="HOURS">%2$d</xliff:g> saat"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> saat"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> saat <xliff:g id="MINUTES">%2$d</xliff:g> dəq"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> saat <xliff:g id="MINUTES">%2$d</xliff:g> dəq"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> dəqiqə"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> dəq"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> dəq <xliff:g id="SECONDS">%2$d</xliff:g> san"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> dəq <xliff:g id="SECONDS">%2$d</xliff:g> san"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> saniyə"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> saniyə"</string>
     <string name="untitled" msgid="4638956954852782576">"Başlıqsız"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Telefon nömrəsi yoxdur)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Naməlum"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Səsli/təcili xidmət yoxdur"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Müvəqqəti olaraq məkanda mobil şəbəkə tərəfindən təklif edilmir"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Şəbəkəyə daxil olmaq mümkün deyil"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Qəbulu inkişaf etdirmək üçün seçilmiş növü Sistem &gt; Şəbəkə və İnternet &gt; Mobil şəbəkə &gt; Tərcih edilən şəbəkə növü bölməsində dəyişə bilərsiniz."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Qəbulu inkişaf etdirmək üçün seçilmiş növü Ayarlar &gt; Şəbəkə və İnternet &gt; Mobil şəbəkə &gt; Tərcih edilən şəbəkə növü bölməsində dəyişə bilərsiniz."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Siqnallar"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Zəng yönləndirmə"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Təcili geriyə zəng rejimi"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Xidmət axtarılır"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi zəngi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi üzərindən zəng etmək və mesaj göndərmək üçün ilk öncə operatordan bu xidməti ayarlamağı tələb edin. Sonra Ayarlardan Wi-Fi çağrısını aktivləşdirin."</item>
+    <item msgid="3910386316304772394">"Zəng etmək və Wi-Fi üzərindən mesaj göndərmək üçün əvvəlcə operatordan bu cihazı quraşdırmağı tələb edin. Sonra Ayarlardan Wi-Fi zəngini deaktiv edin. (Xəta kodu: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Operatorla qeydiyyatdan keçin"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">Əlçatan açıq Wi-Fi şəbəkələri</item>
       <item quantity="one">Əlçatan açıq Wi-Fi şəbəkəsi</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Açıq Wi‑Fi şəbəkəsinə qoşulun"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Açıq Wi‑Fi şəbəkəsinə qoşulur"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi şəbəkəsinə qoşuldu"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi şəbəkəsinə qoşulmaq mümkün deyil"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Bütün şəbəkələri görmək üçün klikləyin"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Qoşulun"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Bütün Şəbəkələr"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi şəbəkəsinə daxil ol"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Şəbəkəyə daxil olun"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index a4487a8..1b67cf7 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> dana"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> dan <xliff:g id="HOURS">%2$d</xliff:g> s"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> dan <xliff:g id="HOURS">%2$d</xliff:g> s"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> s"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> s <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> s <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> sek"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> sek"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> sek"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> sek"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Bez naslova&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Nema broja telefona)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Nepoznato"</string>
@@ -96,7 +84,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Nema glasovne usluge/usluge za hitne pozive"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Privremeno je onemogućeno na mobilnoj mreži na vašoj lokaciji"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Povezivanje sa mrežom nije uspelo"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Da biste poboljšali prijem, probajte da promenite izabrani tip u odeljku Sistem &gt; Mreža i internet &gt; Mobilne mreže &gt; Željeni tip mreže."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Da biste poboljšali prijem, probajte da promenite izabrani tip u odeljku Podešavanja &gt; Mreža i internet &gt; Mobilne mreže &gt; Željeni tip mreže."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Obaveštenja"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Preusmeravanje poziva"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Režim za hitan povratni poziv"</string>
@@ -132,7 +120,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Pretraživanje usluge"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Pozivanje preko Wi-Fi-ja"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Da biste upućivali pozive i slali poruke preko Wi-Fi-ja, prvo zatražite od mobilnog operatera da vam omogući ovu uslugu. Zatim u Podešavanjima ponovo uključite Pozivanje preko Wi-Fi-ja."</item>
+    <item msgid="3910386316304772394">"Da biste upućivali pozive i slali poruke preko Wi-Fi-ja, prvo zatražite od mobilnog operatera da vam omogući ovu uslugu. Zatim u Podešavanjima ponovo uključite Pozivanje preko Wi-Fi-ja. (kôd greške: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Registrujte se kod mobilnog operatera"</item>
@@ -1128,6 +1116,13 @@
       <item quantity="few">Otvorene Wi-Fi mreže su dostupne</item>
       <item quantity="other">Otvorene Wi-Fi mreže su dostupne</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Povežite se sa otvorenom Wi‑Fi mrežom"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Povezujete se sa otvorenom Wi‑Fi mrežom"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Povezali ste se sa Wi‑Fi mrežom"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Povezivanje sa Wi‑Fi mrežom nije uspelo"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Dodirnite da biste videli sve mreže"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Poveži"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Sve mreže"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Prijavljivanje na Wi-Fi mrežu"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Prijavite se na mrežu"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 483aa21..6ad22f6 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"Тб"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"Пб"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> сут"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> дз. <xliff:g id="HOURS">%2$d</xliff:g> гадз"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> дз. <xliff:g id="HOURS">%2$d</xliff:g> гадз"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> гадз"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> гадз <xliff:g id="MINUTES">%2$d</xliff:g> хв"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> гадз <xliff:g id="MINUTES">%2$d</xliff:g> хв"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> хв"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> хвіліна"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> хв <xliff:g id="SECONDS">%2$d</xliff:g> с"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> хв <xliff:g id="SECONDS">%2$d</xliff:g> с"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> с"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> секунда"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Без назвы&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Няма нумара тэлефона)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Невядома"</string>
@@ -97,7 +85,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Няма сэрвісу галасавых / экстранных выклікаў"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Часова не прапаноўваецца сеткай мабільнай сувязі ў вашым месцазанходжанні"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Немагчыма падключыцца да сеткі"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Каб палепшыць якасць прыёму, паспрабуйце змяніць тып, выбраны ў меню \"Сістэма &gt; Сетка і інтэрнэт &gt; Мабільныя сеткі &gt; Прыярытэтны тып сеткі\"."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Каб палепшыць якасць прыёму, паспрабуйце змяніць тып, выбраны ў меню \"Налады &gt; Сетка і інтэрнэт &gt; Мабільныя сеткі &gt; Прыярытэтны тып сеткі\"."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Абвесткі"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Пераадрасацыя выкліку"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Рэжым экстраннага зваротнага выкліку"</string>
@@ -133,7 +121,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Пошук службы"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi-тэлефанія"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Каб рабіць выклікі і адпраўляць паведамленні па Wi-Fi, спачатку папрасіце свайго аператара наладзіць гэту паслугу. Затым зноў уключыце Wi-Fi-тэлефанію ў меню Налады."</item>
+    <item msgid="3910386316304772394">"Каб рабіць выклікі і адпраўляць паведамленні па Wi-Fi, спачатку папрасіце свайго аператара наладзіць гэту паслугу. Затым зноў уключыце Wi-Fi-тэлефанію ў меню Налады. (Код памылкі: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Зарэгіструйцеся ў свайго аператара"</item>
@@ -1150,6 +1138,13 @@
       <item quantity="many">адкрытых сетак Wi-Fi даступна</item>
       <item quantity="other">адкрытай сеткі Wi-Fi даступна</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Падключыцеся да адкрытай сеткі Wi-Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Ідзе падключэнне да адкрытай сеткі Wi‑Fi"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Выканана падключэнне да адкрытай сеткі Wi‑Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Не атрымалася падключыцца да адкрытай сеткі Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Дакраніцеся, каб убачыць усе сеткі"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Падключыцца"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Усе сеткі"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Уваход у сетку Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Увайдзіце ў сетку"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 565b094..c9ed0ca 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"ТБ"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"ПБ"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> дни"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> ден <xliff:g id="HOURS">%2$d</xliff:g> ч"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> ден <xliff:g id="HOURS">%2$d</xliff:g> ч"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> ч"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ч <xliff:g id="MINUTES">%2$d</xliff:g> мин"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> ч <xliff:g id="MINUTES">%2$d</xliff:g> мин"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> мин"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> мин"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> мин <xliff:g id="SECONDS">%2$d</xliff:g> сек"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> мин <xliff:g id="SECONDS">%2$d</xliff:g> сек"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> сек"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> сек"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Без заглавие&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Няма телефонен номер)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Неизвестно"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Няма услуга за гласови/спешни обаждания"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Временно не се предлага от мобилната мрежа в местоположението ви"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Не може да се установи връзка с мрежата"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"За да подобрите сигнала, променете избрания тип мрежа от „Система“ &gt; „Мрежа и интернет“ &gt; „Мобилни мрежи“ &gt; „Предпочитан тип мрежа“."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"За да подобрите сигнала, променете избрания тип мрежа от „Настройки“ &gt; „Мрежа и интернет“ &gt; „Мобилни мрежи“ &gt; „Предпочитан тип мрежа“."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Сигнали"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Пренасочване на обаждания"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Режим на обратно обаждане при спешност"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Търси се покритие"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Обаждания през Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"За да извършвате обаждания и да изпращате съобщения през Wi-Fi, първо помолете оператора си да настрои тази услуга. След това включете отново функцията за обаждания през Wi-Fi от настройките."</item>
+    <item msgid="3910386316304772394">"За да извършвате обаждания и да изпращате съобщения през Wi-Fi, първо, помолете оператора си да настрои тази услуга. След това включете отново функцията за обаждания през Wi-Fi от настройките. (Код на грешката: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Регистриране с оператора ви"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">Има достъпни отворени Wi-Fi мрежи</item>
       <item quantity="one">Има достъпна отворена Wi-Fi мрежа</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Свързване с отворена Wi‑Fi мрежа"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Установява се връзка с отворена Wi‑Fi мрежа"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Установихте връзка с Wi-Fi мрежата"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Не можа да се установи връзка с Wi‑Fi мрежата"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Докоснете, за да видите всички мрежи"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Свързване"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Всички мрежи"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Влизане в Wi-Fi мрежа"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Вход в мрежата"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index ff3dc3d..86ff997 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> দিন"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> দিন <xliff:g id="HOURS">%2$d</xliff:g> ঘণ্টা"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> দিন <xliff:g id="HOURS">%2$d</xliff:g> ঘণ্টা"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> ঘণ্টা"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ঘণ্টা <xliff:g id="MINUTES">%2$d</xliff:g> মিনিট"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> ঘণ্টা <xliff:g id="MINUTES">%2$d</xliff:g> মিনিট"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> মিনিট"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> মিনিট"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> মিনিট <xliff:g id="SECONDS">%2$d</xliff:g> সেকেন্ড"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> মিনিট <xliff:g id="SECONDS">%2$d</xliff:g> সেকেন্ড"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> সেকেন্ড"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> সেকেন্ড"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;শিরোনামহীন&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(কোনো ফোন নম্বর নেই)"</string>
     <string name="unknownName" msgid="6867811765370350269">"অজানা"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"কোনো ভয়েস/জরুরী পরিষেবা নেই"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"সাময়িকভাবে মোবাইল নেটওয়ার্ক আপনার অবস্থানে এই পরিষেবা দিচ্ছে না"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"নেটওয়ার্কের সিগন্যাল নেই"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"রিসেপশন উন্নত করতে সিস্টেম &gt; নেটওয়ার্ক এবং ইন্টারনেট &gt; মোবাইল নেটওয়ার্ক &gt; পছন্দের নেটওয়ার্কের ধরণ এ গিয়ে নির্বাচিত নেটওয়ার্কের ধরণ পরিবর্তন করে দেখুন।"</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"রিসেপশন উন্নত করতে সেটিংস &gt; নেটওয়ার্ক এবং ইন্টারনেট &gt; মোবাইল নেটওয়ার্ক &gt; পছন্দের নেটওয়ার্কের ধরণ এ গিয়ে নির্বাচিত নেটওয়ার্কের ধরণ পরিবর্তন করে দেখুন।"</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"সতর্কবার্তা"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"কল ফরওয়ার্ড করা"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"জরুরি কলব্যাক মোড"</string>
@@ -130,9 +118,7 @@
     <string name="roamingText12" msgid="1189071119992726320">"রোমিং ব্যানার বন্ধ আছে"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"পরিষেবা অনুসন্ধান করা হচ্ছে"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"ওয়াই-ফাই কলিং"</string>
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"ওয়াই-ফাই এর মাধ্যমে কল করতে ও বার্তা পাঠাতে, প্রথমে আপনার পরিষেবা প্রদানকারীকে এই পরিষেবার সেট আপ করার বিষয়ে জিজ্ঞাসা করুন। তারপরে আবার সেটিংস থেকে ওয়াই-ফাই কলিং চালু করুন।"</item>
-  </string-array>
+    <!-- no translation found for wfcOperatorErrorAlertMessages:0 (3910386316304772394) -->
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"আপনার পরিষেবা প্রদানকারীকে নথিভুক্ত করুন"</item>
   </string-array>
@@ -1106,6 +1092,13 @@
       <item quantity="one">খোলা ওয়াই-ফাই নেটওয়ার্কগুলি উপলব্ধ রয়েছে</item>
       <item quantity="other">খোলা ওয়াই-ফাই নেটওয়ার্কগুলি উপলব্ধ রয়েছে</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"উন্মুক্ত ওয়াই-ফাই নেটওয়ার্কে সংযোগ করুন"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"উন্মুক্ত ওয়াই-ফাই নেটওয়ার্কে সংযোগ করা হচ্ছে"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"উন্মুক্ত ওয়াই-ফাই নেটওয়ার্কে সংযুক্ত করা হয়েছে"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"ওয়াই-ফাই নেটওয়ার্কে সংযোগ করা গেল না"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"সমস্ত নেটওয়ার্ক দেখতে ট্যাপ করুন"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"সংযুক্ত করুন"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"সমস্ত নেটওয়ার্ক"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"ওয়াই-ফাই নেটওয়ার্কে প্রবেশ করুন"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"নেটওয়ার্কে প্রবেশ করুন"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1780,6 +1773,5 @@
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"সিম প্রস্তুত নয়"</string>
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"সিম অনুমোদিত নয়"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"ফোন অনুমোদিত নয়"</string>
-    <!-- no translation found for popup_window_default_title (4874318849712115433) -->
-    <skip />
+    <string name="popup_window_default_title" msgid="4874318849712115433">"পপ-আপ উইন্ডো"</string>
 </resources>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 4f5ad4a..f1ec56f 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> dana"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> d i <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> d i <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> sati"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h i <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h i <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min i <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min i <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> sek"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> sek"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Bez naslova&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Nema broja telefona)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Nepoznato"</string>
@@ -96,7 +84,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Nema govornih/hitnih usluga"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Trenutno nije u ponudi mobilne mreže na vašoj lokaciji"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Nije moguće dosegnuti mrežu"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Za poboljšanje prijema, pokušajte promijeniti tip odabran u meniju Sistem &gt; Mreža i internet &gt; Mobilne mreže &gt; Preferirani tip mreže."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Da poboljšate prijem, pokušajte promijeniti odabrani tip u meniju Postavke &lt; Mreža i internet &lt; Mobilne mreže &lt; Preferirani tip mreže."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Upozorenja"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Preusmjeravanje poziva"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Način rada za hitni povratni poziv"</string>
@@ -132,7 +120,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Traženje usluge"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi pozivanje"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Da biste pozivali i slali poruke preko Wi-Fi-ja, prvo zatražite od operatera da postavi tu uslugu. Potom u Postavkama ponovo uključite Wi-Fi pozivanje."</item>
+    <item msgid="3910386316304772394">"Da biste pozivali i slali poruke koristeći Wi-Fi mrežu, prvo zatražite od operatera da postavi tu uslugu. Zatim ponovo uključite Wi-Fi pozivanje u Postavkama. (Kôd greške: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Registrirajte se kod svog operatera"</item>
@@ -1130,6 +1118,13 @@
       <item quantity="few">Otvorene Wi-Fi mreže su dostupne</item>
       <item quantity="other">Otvorene Wi-Fi mreže su dostupne</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Povežite se na otvorenu Wi‑Fi mrežu"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Povezivanje na otvorenu Wi‑Fi mrežu"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Povezani ste na Wi‑Fi mrežu"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Nije se moguće povezati na Wi‑Fi mrežu"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Dodirnite da vidite sve mreže"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Povežite se"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Sve mreže"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Prijavljivanje na Wi-Fi mrežu"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Prijava na mrežu"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 4d55282..dc769e6 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> dies"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> dia <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> dia <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> hores"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> minuts"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Sense títol&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Sense número de telèfon)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Desconegut"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Sense servei de veu/emergència"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"La xarxa de telefonia mòbil de la teva ubicació temporalment no ofereix aquest servei"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"No es pot accedir a la xarxa"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Per millorar la recepció, prova de canviar-ne el tipus a Sistema &gt; Xarxa i Internet &gt; Xarxes de telefonia mòbil &gt; Tipus de xarxa preferit."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Per millorar la recepció, prova de canviar el tipus de xarxa a Configuració &gt; Xarxa i Internet &gt; Xarxes de telefonia mòbil &gt; Tipus de xarxa preferit."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Alertes"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Desviació de trucades"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Mode de devolució de trucada d\'emergència"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"S\'està cercant el servei"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Trucades per Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Per fer trucades i enviar missatges per Wi-Fi, primer has de demanar a l\'operador de telefonia mòbil que configuri aquest servei. Després, torna a activar les trucades per Wi-Fi des de Configuració."</item>
+    <item msgid="3910386316304772394">"Per fer trucades i enviar missatges per Wi-Fi, primer has de demanar a l\'operador de telefonia mòbil que configuri aquest servei. Després, torna a activar les trucades per Wi-Fi a Configuració. (Codi d\'error: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Registra\'t amb el teu operador de telefonia mòbil"</item>
@@ -471,7 +459,7 @@
     <string name="permlab_nfc" msgid="4423351274757876953">"controlar Comunicació de camp proper (NFC)"</string>
     <string name="permdesc_nfc" msgid="7120611819401789907">"Permet que l\'aplicació es comuniqui amb les etiquetes, les targetes i els lectors de Comunicació de camp proper (NFC)."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"desactivació del bloqueig de pantalla"</string>
-    <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Permet que l\'aplicació desactivi el bloqueig del teclat i qualsevol element de seguretat de contrasenyes associat. Per exemple, el telèfon desactiva el bloqueig del teclat en rebre una trucada telefònica entrant i, a continuació, reactiva el bloqueig del teclat quan finalitza la trucada."</string>
+    <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Permet que l\'aplicació desactivi el bloqueig del teclat i qualsevol element de seguretat de contrasenyes associat. Per exemple, el telèfon desactiva el bloqueig del teclat en rebre una trucada entrant i, a continuació, reactiva el bloqueig del teclat quan finalitza la trucada."</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"Gestionar el maquinari d\'empremtes digitals"</string>
     <string name="permdesc_manageFingerprint" msgid="178208705828055464">"Permet que l\'aplicació invoqui mètodes per afegir i suprimir plantilles d\'empremtes digitals que es puguin fer servir."</string>
     <string name="permlab_useFingerprint" msgid="3150478619915124905">"Utilitzar el maquinari d\'empremtes digitals"</string>
@@ -788,13 +776,13 @@
     <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Ha finalitzat la reorganització del widget."</string>
     <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"S\'ha suprimit el widget de <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
     <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Desplega l\'àrea de desbloqueig."</string>
-    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Desbloqueig lliscant el dit"</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Desbloqueig lliscant"</string>
     <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Desbloqueig mitjançant patró"</string>
     <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Desbloqueig facial"</string>
     <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Desbloqueig mitjançant PIN"</string>
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Desbloqueig mitjançant contrasenya"</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Àrea de patró"</string>
-    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Àrea per lliscar el dit"</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Àrea per lliscar"</string>
     <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
     <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
     <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -1075,7 +1063,7 @@
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> ha superat el límit de memòria"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"S\'ha recopilat un procés \"heap dump\"; toca per compartir-lo"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Vols compartir el \"heap dump\"?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"El procés <xliff:g id="PROC">%1$s</xliff:g> ha superat el límit de <xliff:g id="SIZE">%2$s</xliff:g> de memòria del procés. Hi ha un procés \"heap dump\" disponible perquè el comparteixis amb el desenvolupador. Vés amb compte: aquest \"heap dump\" pot contenir les dades personals a les quals l\'aplicació tingui accés."</string>
+    <string name="dump_heap_text" msgid="4809417337240334941">"El procés <xliff:g id="PROC">%1$s</xliff:g> ha superat el límit de <xliff:g id="SIZE">%2$s</xliff:g> de memòria del procés. Hi ha un procés \"heap dump\" disponible perquè el comparteixis amb el desenvolupador. Ves amb compte: aquest \"heap dump\" pot contenir les dades personals a les quals l\'aplicació tingui accés."</string>
     <string name="sendText" msgid="5209874571959469142">"Tria una acció per al text"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Volum del timbre"</string>
     <string name="volume_music" msgid="5421651157138628171">"Volum de multimèdia"</string>
@@ -1106,6 +1094,13 @@
       <item quantity="other">Xarxes Wi-Fi obertes disponibles</item>
       <item quantity="one">Xarxa Wi-Fi oberta disponible</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Connecta\'t a una xarxa Wi-Fi oberta"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"S\'està connectant a una xarxa Wi-Fi oberta"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"S\'ha connectat a la xarxa Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"No s\'ha pogut connectar a una xarxa Wi-Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toca per veure totes les xarxes"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connecta"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Totes les xarxes"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Inicia la sessió a la xarxa Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Inicia la sessió a la xarxa"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1259,7 +1254,7 @@
     <string name="permdesc_requestIgnoreBatteryOptimizations" msgid="8359147856007447638">"Permet que una aplicació demani permís per ignorar les optimitzacions de bateria per a l\'aplicació."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="1311810005957319690">"Piqueu dos cops per controlar el zoom"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"No s\'ha pogut afegir el widget."</string>
-    <string name="ime_action_go" msgid="8320845651737369027">"Vés"</string>
+    <string name="ime_action_go" msgid="8320845651737369027">"Ves"</string>
     <string name="ime_action_search" msgid="658110271822807811">"Cerca"</string>
     <string name="ime_action_send" msgid="2316166556349314424">"Envia"</string>
     <string name="ime_action_next" msgid="3138843904009813834">"Següent"</string>
@@ -1617,9 +1612,9 @@
     <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"No es pot deixar de fixar aquesta aplicació"</string>
     <string name="lock_to_app_start" msgid="6643342070839862795">"Pantalla fixada"</string>
     <string name="lock_to_app_exit" msgid="8598219838213787430">"Fixació de la pantalla anul·lada"</string>
-    <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Sol·licita el codi PIN per anul·lar"</string>
-    <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Sol·licita el patró de desbloqueig per anul·lar"</string>
-    <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Demana la contrasenya per anul·lar"</string>
+    <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Sol·licita el codi PIN per deixar de fixar"</string>
+    <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Sol·licita el patró de desbloqueig per deixar de fixar"</string>
+    <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Demana la contrasenya per deixar de fixar"</string>
     <string name="package_installed_device_owner" msgid="6875717669960212648">"Instal·lat per l\'administrador"</string>
     <string name="package_updated_device_owner" msgid="1847154566357862089">"Actualitzat per l\'administrador"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"Suprimit per l\'administrador"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 5a5a943..f117982 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> d"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> d <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> d <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> h"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Bez názvu&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(žádné telefonní číslo)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Není známo"</string>
@@ -97,7 +85,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Hlasová ani tísňová volání nejsou k dispozici"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Mobilní síť ve vaší oblasti tuto službu dočasně nenabízí"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"K síti se nelze připojit"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Chcete-li zlepšit příjem, zkuste změnit vybraný typ sítě v nastavení Systém &gt; Síť a internet &gt; Mobilní sítě &gt; Preferovaný typ sítě."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Chcete-li zlepšit příjem, zkuste změnit vybraný typ sítě v Nastavení &gt; Síť a internet &gt; Mobilní sítě &gt; Preferovaný typ sítě."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Upozornění"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Přesměrování hovorů"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Režim tísňového zpětného volání"</string>
@@ -133,7 +121,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Vyhledávání služby"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Volání přes Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Chcete-li volat a odesílat textové zprávy přes síť Wi-Fi, nejprve požádejte operátora, aby vám tuto službu nastavil. Poté volání přes Wi-Fi opět zapněte v Nastavení."</item>
+    <item msgid="3910386316304772394">"Chcete-li volat a odesílat SMS přes síť Wi-Fi, nejprve požádejte operátora, aby vám tuto službu nastavil. Poté volání přes Wi-Fi opět zapněte v Nastavení. (Kód chyby: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Registrace u operátora"</item>
@@ -1150,6 +1138,13 @@
       <item quantity="other">K dispozici jsou veřejné sítě Wi-Fi</item>
       <item quantity="one">K dispozici je veřejná síť Wi-Fi</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Připojení k otevřené síti Wi-Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Připojování k otevřené síti Wi-Fi"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Připojeno k síti Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Připojení k síti Wi-Fi se nezdařilo"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Klepnutím zobrazíte všechny sítě"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Připojit"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Všechny sítě"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Přihlásit se k síti Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Přihlásit se k síti"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 4ff1f25..e7db8d5 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"Tb"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"Pb"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> dage"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> dag <xliff:g id="HOURS">%2$d</xliff:g> t."</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> dag <xliff:g id="HOURS">%2$d</xliff:g> t."</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> timer"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> t. <xliff:g id="MINUTES">%2$d</xliff:g> min."</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> t. <xliff:g id="MINUTES">%2$d</xliff:g> min."</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> min."</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min."</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min. <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min. <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> sek."</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> sek."</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Uden titel&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Intet telefonnummer)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Ukendt"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Ingen tale- og nødtjenester"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Tilbydes i øjeblikket ikke af mobilnetværket på din placering"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Der er ingen forbindelse til netværket"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Hvis du vil forbedre signalet, kan du prøve at ændre den valgte netværkstype i System &gt; Netværk og internet &gt; Mobilnetværk &gt; Foretrukken netværkstype."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Hvis du vil forbedre signalet, kan du prøve at ændre den valgte netværkstype i Indstillinger &gt; Netværk og internet &gt; Mobilnetværk &gt; Foretrukken netværkstype."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Underretninger"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Viderestilling af opkald"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Nødtilbagekaldstilstand"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Søger efter tjeneste"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Opkald via Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Hvis du vil foretage opkald og sende beskeder via Wi-Fi, skal du først anmode dit mobilselskab om at konfigurere denne tjeneste. Derefter skal du slå Wi-Fi-opkald til igen fra Indstillinger."</item>
+    <item msgid="3910386316304772394">"Hvis du vil foretage opkald og sende beskeder via Wi-Fi, skal du først anmode dit mobilselskab om at konfigurere denne tjeneste. Derefter skal du aktivere Wi-Fi-opkald igen fra Indstillinger. (Fejlkode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Registrer dig hos dit mobilselskab"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="one">Åbne Wi-Fi-netværk er tilgængelige</item>
       <item quantity="other">Åbne Wi-Fi-netværk er tilgængelige</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Opret forbindelse til et åbent Wi-Fi-netværk"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Opretter forbindelse til et åbent Wi‑Fi-netværk"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Forbundet til Wi-Fi-netværket"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Der kan ikke oprettes forbindelse til Wi-Fi-netværket"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tryk for at se alle netværk"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Opret forbindelse"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Alle netværk"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Log ind på Wi-Fi-netværk"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Log ind på netværk"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index b8f1b51..7ff623b 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> Tage"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> Tag <xliff:g id="HOURS">%2$d</xliff:g> Std."</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> Tag <xliff:g id="HOURS">%2$d</xliff:g> Std."</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> Std."</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> Std. <xliff:g id="MINUTES">%2$d</xliff:g> Min."</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> Std. <xliff:g id="MINUTES">%2$d</xliff:g> Min."</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> Min."</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> Min. <xliff:g id="SECONDS">%2$d</xliff:g> Sek."</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> Min. <xliff:g id="SECONDS">%2$d</xliff:g> Sek."</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> Sek."</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> Sek."</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Unbenannt&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Keine Telefonnummer)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Unbekannt"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Keine Anrufe/Notrufe"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Derzeit nicht im Mobilfunknetz in deiner Region verfügbar"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Netzwerk nicht erreichbar"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Der Empfang lässt sich möglicherweise verbessern, indem du unter \"System\" &gt; \"Netzwerk\" &amp; \"Internet\" &gt; \"Mobilfunknetze\" &gt; \"Bevorzugter Netzwerktyp\" einen anderen Typ auswählst."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Der Empfang lässt sich möglicherweise verbessern, indem du unter \"Einstellungen\" &gt; \"Netzwerk\" &amp; \"Internet\" &gt; \"Mobilfunknetze\" &gt; \"Bevorzugter Netzwerktyp\" einen anderen Typ auswählst."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Warnmeldungen"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Anrufweiterleitung"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Notfallrückrufmodus"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Suche nach Dienst"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Anrufe über WLAN"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Um über WLAN telefonieren und Nachrichten senden zu können, bitte zuerst deinen Mobilfunkanbieter, diesen Dienst einzurichten. Aktiviere die Option \"Anrufe über WLAN\" dann erneut über die Einstellungen."</item>
+    <item msgid="3910386316304772394">"Um über WLAN telefonieren und Nachrichten senden zu können, bitte zuerst deinen Mobilfunkanbieter, diesen Dienst einzurichten. Aktiviere die Option \"Anrufe über WLAN\" dann noch einmal über die Einstellungen. (Fehlercode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Registriere dich bei deinem Mobilfunkanbieter."</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">Verfügbare WLAN-Netzwerke öffnen</item>
       <item quantity="one">Verfügbares WLAN-Netzwerk öffnen</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Mit offenem WLAN verbinden"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Verbindung mit offenem WLAN wird hergestellt"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Mit WLAN verbunden"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"WLAN-Verbindung konnte nicht hergestellt werden"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tippen, um alle Netzwerke zu sehen"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Verbinden"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Alle Netzwerke"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"In WLAN-Netzwerk anmelden"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Im Netzwerk anmelden"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 2f105d9..def96a8 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> ημέρες"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> ημ. <xliff:g id="HOURS">%2$d</xliff:g> ώρες"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> ημ. <xliff:g id="HOURS">%2$d</xliff:g> ώρα"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> ώρες"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ώρα <xliff:g id="MINUTES">%2$d</xliff:g> λ"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> ώρα <xliff:g id="MINUTES">%2$d</xliff:g> λ"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> λεπτά"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> λεπτά"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> λ. <xliff:g id="SECONDS">%2$d</xliff:g> δευτ."</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> λ <xliff:g id="SECONDS">%2$d</xliff:g> δευτ."</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> δευτ."</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> δευτ."</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Χωρίς τίτλο&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Δεν υπάρχει τηλεφωνικός αριθμός)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Άγνωστο"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Δεν υπάρχει φωνητική υπηρεσία/υπηρεσία έκτακτης ανάγκης"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Δεν προσφέρεται προσωρινά από το δίκτυο κινητής τηλεφωνίας στην τοποθεσία σας"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Δεν είναι δυνατή η σύνδεση στο δίκτυο"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Για να βελτιώσετε τη λήψη, δοκιμάστε να αλλάξετε τον επιλεγμένο τύπο από το Σύστημα &gt; Δίκτυο και διαδίκτυο &gt; Δίκτυα κινητής τηλεφωνίας &gt; Προτιμώμενος τύπος δικτύου."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Για να βελτιώσετε τη λήψη, δοκιμάστε να αλλάξετε τον επιλεγμένο τύπο από τις Ρυθμίσεις &gt; Δίκτυο και διαδίκτυο &gt; Δίκτυα κινητής τηλεφωνίας &gt; Προτιμώμενος τύπος δικτύου."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Ειδοποιήσεις"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Προώθηση κλήσης"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Λειτουργία επιστροφής κλήσης έκτακτης ανάγκης"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Αναζήτηση υπηρεσιών"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Κλήση Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Για να κάνετε κλήσεις και να στέλνετε μηνύματα μέσω Wi-Fi, ζητήστε πρώτα από την εταιρεία κινητής τηλεφωνίας να ρυθμίσει την υπηρεσία. Στη συνέχεια, ενεργοποιήστε ξανά τη λειτουργία κλήσεων μέσω Wi-Fi από τις Ρυθμίσεις."</item>
+    <item msgid="3910386316304772394">"Για να κάνετε κλήσεις και να στέλνετε μηνύματα μέσω Wi-Fi, ζητήστε πρώτα από την εταιρεία κινητής τηλεφωνίας να ρυθμίσει την υπηρεσία. Στη συνέχεια, ενεργοποιήστε ξανά την Κλήση Wi-Fi από τις Ρυθμίσεις. (Κωδικός σφάλματος: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Εγγραφείτε μέσω της εταιρείας κινητής τηλεφωνίας"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">Υπάρχουν διαθέσιμα ανοικτά δίκτυα Wi-Fi</item>
       <item quantity="one">Υπάρχει διαθέσιμο ανοικτό δίκτυο Wi-Fi</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Σύνδεση σε ανοιχτό δίκτυο Wi‑Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Σύνδεση σε ανοιχτό δίκτυο Wi‑Fi"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Ολοκληρώθηκε η σύνδεση στο δίκτυο Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Δεν ήταν δυνατή η σύνδεση σε δίκτυο Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Πατήστε για να δείτε όλα τα δίκτυα"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Σύνδεση"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Όλα τα δίκτυα"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Συνδεθείτε στο δίκτυο Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Σύνδεση στο δίκτυο"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index fdbe301..5db79b8 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> days"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> day <xliff:g id="HOURS">%2$d</xliff:g> hrs"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> day <xliff:g id="HOURS">%2$d</xliff:g> hr"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> hrs"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> hr <xliff:g id="MINUTES">%2$d</xliff:g> mins"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> hr <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> mins"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> secs"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> sec"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> secs"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> sec"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Untitled&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(No phone number)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Unknown"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"No voice/emergency service"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Temporarily not offered by the mobile network at your location"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Can’t find network"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"To improve reception, try changing the type selected at System &gt; Network &amp; Internet &gt; Mobile networks &gt; Preferred network type."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"To improve reception, try changing the type selected at Settings &gt; Network &amp; Internet &gt; Mobile networks &gt; Preferred network type."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Alerts"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Call forwarding"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Emergency callback mode"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Searching for Service"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi Calling"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings."</item>
+    <item msgid="3910386316304772394">"To make calls and send messages over Wi-Fi, first ask your operator to set up this service. Then turn on Wi-Fi calling again from Settings. (Error code: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Register with your operator"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">Open Wi-Fi networks available</item>
       <item quantity="one">Open Wi-Fi network available</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Connect to open Wi‑Fi network"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Connecting to open Wi‑Fi network"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Connected to Wi‑Fi network"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Could not connect to Wi‑Fi network"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap to see all networks"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connect"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"All Networks"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Sign in to a Wi-Fi network"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Sign in to network"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index fdbe301..5db79b8 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> days"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> day <xliff:g id="HOURS">%2$d</xliff:g> hrs"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> day <xliff:g id="HOURS">%2$d</xliff:g> hr"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> hrs"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> hr <xliff:g id="MINUTES">%2$d</xliff:g> mins"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> hr <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> mins"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> secs"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> sec"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> secs"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> sec"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Untitled&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(No phone number)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Unknown"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"No voice/emergency service"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Temporarily not offered by the mobile network at your location"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Can’t find network"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"To improve reception, try changing the type selected at System &gt; Network &amp; Internet &gt; Mobile networks &gt; Preferred network type."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"To improve reception, try changing the type selected at Settings &gt; Network &amp; Internet &gt; Mobile networks &gt; Preferred network type."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Alerts"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Call forwarding"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Emergency callback mode"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Searching for Service"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi Calling"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings."</item>
+    <item msgid="3910386316304772394">"To make calls and send messages over Wi-Fi, first ask your operator to set up this service. Then turn on Wi-Fi calling again from Settings. (Error code: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Register with your operator"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">Open Wi-Fi networks available</item>
       <item quantity="one">Open Wi-Fi network available</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Connect to open Wi‑Fi network"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Connecting to open Wi‑Fi network"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Connected to Wi‑Fi network"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Could not connect to Wi‑Fi network"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap to see all networks"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connect"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"All Networks"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Sign in to a Wi-Fi network"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Sign in to network"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index fdbe301..5db79b8 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> days"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> day <xliff:g id="HOURS">%2$d</xliff:g> hrs"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> day <xliff:g id="HOURS">%2$d</xliff:g> hr"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> hrs"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> hr <xliff:g id="MINUTES">%2$d</xliff:g> mins"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> hr <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> mins"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> secs"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> sec"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> secs"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> sec"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Untitled&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(No phone number)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Unknown"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"No voice/emergency service"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Temporarily not offered by the mobile network at your location"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Can’t find network"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"To improve reception, try changing the type selected at System &gt; Network &amp; Internet &gt; Mobile networks &gt; Preferred network type."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"To improve reception, try changing the type selected at Settings &gt; Network &amp; Internet &gt; Mobile networks &gt; Preferred network type."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Alerts"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Call forwarding"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Emergency callback mode"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Searching for Service"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi Calling"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings."</item>
+    <item msgid="3910386316304772394">"To make calls and send messages over Wi-Fi, first ask your operator to set up this service. Then turn on Wi-Fi calling again from Settings. (Error code: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Register with your operator"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">Open Wi-Fi networks available</item>
       <item quantity="one">Open Wi-Fi network available</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Connect to open Wi‑Fi network"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Connecting to open Wi‑Fi network"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Connected to Wi‑Fi network"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Could not connect to Wi‑Fi network"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap to see all networks"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connect"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"All Networks"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Sign in to a Wi-Fi network"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Sign in to network"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 8dafd5f..2a828f7 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> días"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> día <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> día <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> h"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Sin título&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(No hay número de teléfono)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Desconocido"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Sin servicio de voz/emergencia"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"La red móvil de tu ubicación no ofrece este servicio de forma temporal"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"No se puede establecer conexión con la red"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Para mejorar la recepción, cambia el tipo de red. Selecciona Sistema &gt; Internet y red &gt; Redes móviles &gt; Tipo de red preferido."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Para mejorar la recepción, cambia el tipo de red. Selecciona Configuración &gt; Internet y red &gt; Redes móviles &gt; Tipo de red preferido."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Alertas"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Desvío de llamada"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Modo de devolución de llamada de emergencia"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Buscando servicio"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Llamada por Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Para realizar llamadas o enviar mensajes por Wi-Fi, primero solicítale al proveedor que instale el servicio. Luego, vuelve a activar las llamadas por Wi-Fi desde Configuración."</item>
+    <item msgid="3910386316304772394">"Para hacer llamadas y enviar mensajes mediante Wi-Fi, solicítale a tu proveedor que configure este servicio. Luego, vuelve a activar la Llamada con Wi-Fi en Configuración. (código de error: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Regístrate con tu proveedor."</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">Abrir redes de Wi-Fi disponibles</item>
       <item quantity="one">Abrir red de Wi-Fi disponible</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Conectarse a una red Wi-Fi abierta"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Conectándose a una red Wi-Fi abierta"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Se conectó a la red Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"No fue posible conectarse a la red Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Presiona para ver todas las redes"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectar"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Todas las redes"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Accede a una red Wi-Fi."</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Acceder a la red"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index a899f4b..9323e1f 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> días"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> día <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> día <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> h"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Sin título&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Sin número de teléfono)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Desconocido"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Sin servicio de emergencia ni de voz"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"La red móvil disponible en tu ubicación no ofrece esta opción de forma temporal"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"No se puede establecer conexión con la red"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Para mejorar la recepción, prueba a cambiar el tipo de red seleccionado en Sistema &gt; Red e Internet &gt; Redes móviles &gt; Tipo de red preferido."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Para mejorar la recepción, prueba a cambiar el tipo seleccionado en Ajustes &gt; Red e Internet &gt; Redes móviles &gt; Tipo de red preferido."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Alertas"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Desvío de llamada"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Modo de devolución de llamada de emergencia"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Buscando servicio"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Llamadas Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Para hacer llamadas y enviar mensajes por Wi-Fi, debes pedir antes a tu operador que configure este servicio. Una vez hecho esto, vuelva a activar las llamadas Wi-Fi en Ajustes."</item>
+    <item msgid="3910386316304772394">"Para hacer llamadas y enviar mensajes por Wi-Fi, pide antes a tu operador que configure este servicio. Una vez hecho esto, vuelva a activar la llamada por Wi-Fi en Ajustes. (Código de error: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Regístrate con tu operador"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">Redes Wi-Fi abiertas disponibles</item>
       <item quantity="one">Red Wi-Fi abierta disponible</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Conectarse a una red Wi-Fi abierta"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Conectándose a una red Wi-Fi abierta"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Conectado a la red Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"No se ha podido conectar a la red Wi-Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toca para ver todas las redes"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectarse"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Todas las redes"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Iniciar sesión en red Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Iniciar sesión en la red"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 277fefc..4ff5a6b 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> päeva"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> päev <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> päev <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> h"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Pealkirjata&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Telefoninumbrit pole)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Teadmata"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Häälkõned/hädaabiteenus pole saadaval"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Teie asukoha mobiilsidevõrk seda teenust ajutiselt ei paku"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Võrguga ei saa ühendust"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Vastuvõtu parandamiseks muutke valitud tüüpi jaotises Süsteem &gt; Võrk ja Internet &gt; Mobiilsidevõrgud &gt; Eelistatud võrgutüüp."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Vastuvõtu parandamiseks muutke valitud tüüpi jaotises Seaded &gt; Võrk ja Internet &gt; Mobiilsidevõrgud &gt; Eelistatud võrgutüüp."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Teatised"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Kõnede suunamine"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Hädaolukorra tagasihelistusrežiim"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Teenuse otsimine"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"WiFi-kõned"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Üle WiFi-võrgu helistamiseks ja sõnumite saatmiseks paluge operaatoril esmalt see teenus seadistada. Seejärel lülitage WiFi-kõned menüüs Seaded uuesti sisse."</item>
+    <item msgid="3910386316304772394">"WiFi-võrgu kaudu helistamiseks ja sõnumite saatmiseks paluge operaatoril esmalt see teenus seadistada. Seejärel lülitage WiFi-kõned menüüs Seaded uuesti sisse. (Veakood: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Registreeruge operaatori juures"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">Avatud WiFi-võrgud on saadaval</item>
       <item quantity="one">Avatud WiFi-võrk on saadaval</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Looge ühendus avatud WiFi-võrguga"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Ühenduse loomine avatud WiFi-võrguga"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Ühendatud WiFi-võrguga"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"WiFi-võrguga ei õnnestunud ühendust luua"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Puudutage kõikide võrkude nägemiseks"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Ühenda"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Kõik võrgud"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Logi sisse WiFi-võrku"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Võrku sisselogimine"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 42b4ce3..ca369c4 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> egun"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> egun <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> egun <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> h"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> m"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> m"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> m"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> m <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> m <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Izengabea&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Ez dago telefono-zenbakirik)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Ezezaguna"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Ez dago ahots- edo larrialdi-deien zerbitzurik"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Zauden tokiko sare mugikorrak ez du eskaintzen aukera hori une honetan"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Ezin da konektatu sarera"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Seinalea hobea izan dadin, aldatu hautatutako sare mota Sistema &gt; Sareak eta Internet &gt; Sare mugikorrak &gt; Sare mota hobetsia atalean."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Seinalea hobea izan dadin, aldatu sare mota Ezarpenak &gt; Sareak eta Internet &gt; Sare mugikorrak &gt; Sare mota hobetsia atalean."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Abisuak"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Dei-desbideratzea"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Larrialdi-deiak soilik jasotzeko modua"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Zerbitzu bila"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi bidezko deiak"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi bidez deiak egiteko eta mezuak bidaltzeko, eskatu operadoreari zerbitzu hori gaitzeko. Ondoren, aktibatu Wi-Fi bidezko deiak Ezarpenak atalean."</item>
+    <item msgid="3910386316304772394">"Wi-Fi bidez deiak egiteko eta mezuak bidaltzeko, eskatu operadoreari zerbitzu hori gaitzeko. Ondoren, aktibatu Wi-Fi bidezko deiak Ezarpenak atalean. (Errore-kodea: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Erregistratu operadorearekin"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">Wi-Fi sare irekiak erabilgarri</item>
       <item quantity="one">Wi-Fi sare irekia erabilgarri</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Konektatu Wi‑Fi sare irekira"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Wi‑Fi sare irekira konektatzen"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi sare irekira konektatuta"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Ezin izan da konektatu Wi‑Fi sare irekira"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Sakatu hau sare guztiak ikusteko"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Konektatu"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Sare guztiak"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Hasi saioa Wi-Fi sarean"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Hasi saioa sarean"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1138,7 +1133,7 @@
     <string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Gonbidapena bidali da"</string>
     <string name="wifi_p2p_invitation_to_connect_title" msgid="4958803948658533637">"Konektatzeko gonbidapena"</string>
     <string name="wifi_p2p_from_message" msgid="570389174731951769">"Igorlea:"</string>
-    <string name="wifi_p2p_to_message" msgid="248968974522044099">"Nori:"</string>
+    <string name="wifi_p2p_to_message" msgid="248968974522044099">"Hartzailea:"</string>
     <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"Idatzi beharrezko PINa:"</string>
     <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PINa:"</string>
     <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"Tableta Wi-Fi saretik deskonektatuko da <xliff:g id="DEVICE_NAME">%1$s</xliff:g> gailura konektatuta dagoen bitartean"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 1280b41..9d4cb6d 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"ترابایت"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"پتابایت"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> ‏<xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> روز"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> روز و <xliff:g id="HOURS">%2$d</xliff:g> ساعت"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> روز و <xliff:g id="HOURS">%2$d</xliff:g> ساعت"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> ساعت"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ساعت و <xliff:g id="MINUTES">%2$d</xliff:g> دقیقه"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> ساعت و <xliff:g id="MINUTES">%2$d</xliff:g> دقیقه"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> دقیقه"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> دقیقه"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> دقیقه و <xliff:g id="SECONDS">%2$d</xliff:g> ثانیه"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> دقیقه و <xliff:g id="SECONDS">%2$d</xliff:g> ثانیه"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> ثانیه"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> ثانیه"</string>
     <string name="untitled" msgid="4638956954852782576">"‏&lt;بدون عنوان&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(بدون شماره تلفن)"</string>
     <string name="unknownName" msgid="6867811765370350269">"نامشخص"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"سرویس صوتی/اضطراری دردسترس نیست"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"موقتاً توسط شبکه داده دستگاه همراه در مکان شما ارائه نمی‌شود"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"شبکه دردسترس نیست"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"برای بهبود دریافت، نوع شبکه‌ای را که انتخاب کرده‌اید در «سیستم» &gt; «شبکه‌ و اینترنت» &gt; «شبکه‌های تلفن همراه» &gt; «نوع شبکه ترجیحی» تغییر دهید."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"برای بهبود دریافت، نوع شبکه انتخاب‌شده را در «تنظیمات &gt; شبکه‌ و اینترنت &gt; شبکه‌های تلفن همراه &gt; نوع شبکه ترجیحی» تغییر دهید."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"هشدارها"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"بازارسال تماس"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"حالت پاسخ تماس اضطراری"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"جستجوی سرویس"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"‏تماس از طریق Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"‏برای برقراری تماس و ارسال پیام از طریق Wi-Fi، ابتدا از شرکت مخابراتی‌تان درخواست کنید این سرویس را راه‌اندازی کند. سپس دوباره از تنظیمات، تماس Wi-Fi را روشن کنید."</item>
+    <item msgid="3910386316304772394">"‏برای برقراری تماس و ارسال پیام ازطریق Wi-Fi، ابتدا از شرکت مخابراتی خود بخواهید این سرویس را تنظیم کند. سپس در «تنظیمات»۷ دوباره «تماس ازطریق Wi-Fi» را روشن کنید. (کد خطا: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"ثبت‌نام با شرکت مخابراتی شما"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="one">‏شبکه Wi-Fi باز در دسترس</item>
       <item quantity="other">‏شبکه‌ Wi-Fi باز در دسترس</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"‏اتصال به شبکه Wi‑Fi باز"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"‏درحال اتصال به شبکه Wi‑Fi باز"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"‏به شبکه Wi‑Fi متصل شد"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"‏به شبکه Wi-Fi متصل نشد"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"برای دیدن همه شبکه‌ها ضربه بزنید"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"اتصال"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"همه شبکه‌ها"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"‏ورود به شبکه Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"ورود به سیستم شبکه"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index df35b50..ffa6d67 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"Tt"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"Pt"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> päivää"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> päivä <xliff:g id="HOURS">%2$d</xliff:g> t"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> päivä <xliff:g id="HOURS">%2$d</xliff:g> t"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> t"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> t <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> t <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Nimetön&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Ei puhelinnumeroa)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Tuntematon"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Ei ääni- tai hätäpuheluja"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Sijaintisi mobiiliverkko ei tarjoa tätä tilapäisesti."</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Ei yhteyttä verkkoon"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Voit yrittää parantaa kuuluvuutta vaihtamalla tyypin asetusta. Valitse Järjestelmä &gt; Verkko &gt; Internet &gt; Mobiiliverkot &gt; Ensisijainen verkko."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Voit yrittää parantaa kuuluvuutta vaihtamalla tyypin asetusta. Valitse Asetukset &gt; Verkko &gt; Internet &gt; Mobiiliverkot &gt; Ensisijainen verkko."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Ilmoitukset"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Soitonsiirto"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Hätäpuhelujen takaisinsoittotila"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Etsitään signaalia"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi-puhelut"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Jos haluat soittaa puheluita ja lähettää viestejä Wi-Fin kautta, pyydä ensin operaattoriasi ottamaan tämä palvelu käyttöön. Ota sitten Wi-Fi-puhelut käyttöön asetuksissa."</item>
+    <item msgid="3910386316304772394">"Jos haluat soittaa puheluita ja lähettää viestejä Wi-Fin kautta, pyydä ensin operaattoriasi ottamaan tämä palvelu käyttöön. Ota sitten Wi-Fi-puhelut käyttöön asetuksissa. (Virhekoodi: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Rekisteröidy operaattorisi asiakkaaksi."</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">Avoimia Wi-Fi-verkkoja käytettävissä</item>
       <item quantity="one">Avoin Wi-Fi-verkko käytettävissä</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Yhdistä avoimeen Wi‑Fi-verkkoon"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Yhdistetään avoimeen Wi‑Fi-verkkoon"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Yhdistetty Wi-Fi-verkkoon"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi-verkkoon yhdistäminen epäonnistui"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Napauta, niin näet kaikki verkot."</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Yhdistä"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Kaikki verkot"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Kirjaudu Wi-Fi-verkkoon"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Kirjaudu verkkoon"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index a211d64..d4bac7c 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"To"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"Po"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> jours"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> j et <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> j et <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> h"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h et <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h et <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min et <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min et <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Sans_titre&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Aucun numéro de téléphone)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Inconnu"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Aucun service vocal ou d\'urgence"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Ce service est temporairement non offert par le réseau cellulaire à l\'endroit où vous êtes"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Impossible de joindre le réseau"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Pour améliorer la réception, essayez de changer le type de réseau sélectionné, sous Système &gt; Réseaux et Internet &gt; Réseaux cellulaires &gt; Type de réseau préféré."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Pour améliorer la réception, essayez de changer le type de réseau sélectionné, sous Paramètres &gt; Réseaux et Internet &gt; Réseaux cellulaires &gt; Type de réseau préféré."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Alertes"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Transfert d\'appel"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Mode de rappel d\'urgence"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Recherche des services disponibles"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Appels Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Pour effectuer des appels et envoyer des messages par Wi-Fi, demandez tout d\'abord à votre fournisseur de services de configurer ce service. Réactivez ensuite les appels Wi-Fi dans les paramètres."</item>
+    <item msgid="3910386316304772394">"Pour effectuer des appels et envoyer des messages par Wi-Fi, demandez tout d\'abord à votre fournisseur de services de configurer ce service. Réactivez ensuite les appels Wi-Fi dans les paramètres. (Code d\'erreur : <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Inscrivez-vous auprès de votre fournisseur de services"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="one">Réseau Wi-Fi ouvert à proximité</item>
       <item quantity="other">Réseaux Wi-Fi ouverts à proximité</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Connectez-vous pour ouvrir un réseau Wi-Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Connexion en cours au réseau Wi-Fi ouvert…"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Connecté au réseau Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Impossible de se connecter au réseau Wi-Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Touchez pour afficher tous les réseaux"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connexion"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Tous les réseaux"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Connectez-vous au réseau Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Connectez-vous au réseau"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index e1683d6..f1e693d 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"To"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"Po"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> jours"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> j et <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> j et <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> h"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h et <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h et <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min et <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min et <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Sans nom&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Aucun numéro de téléphone)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Inconnu"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Aucun service vocal/d\'urgence"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Momentanément non proposé par le réseau mobile à votre position"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Impossible d\'accéder au réseau"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Pour améliorer la réception, essayez de modifier le type sélectionné sous Système &gt; Réseau et Internet &gt; Réseaux mobiles &gt; Type de réseau préféré."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Pour améliorer la réception, essayez de modifier le type sélectionné sous Paramètres &gt; Réseau et Internet &gt; Réseaux mobiles &gt; Type de réseau préféré."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Alertes"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Transfert d\'appel"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Mode de rappel d\'urgence"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Recherche des services disponibles"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Appels Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Pour effectuer des appels et envoyer des messages via le Wi-Fi, demandez tout d\'abord à votre opérateur de configurer ce service. Réactivez ensuite les appels Wi-Fi dans les paramètres."</item>
+    <item msgid="3910386316304772394">"Pour passer des appels et envoyer des messages via le Wi-Fi, demandez d\'abord à votre opérateur de configurer ce service. Ensuite, réactivez les appels Wi-Fi dans les paramètres. (Code d\'erreur : <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Inscrivez-vous auprès de votre opérateur."</item>
@@ -1106,6 +1094,13 @@
       <item quantity="one">Réseau Wi-Fi ouvert disponible</item>
       <item quantity="other">Réseaux Wi-Fi ouverts disponibles</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Se connecter pour ouvrir le réseau Wi-Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Connexion pour ouvrir un réseau Wi-Fi…"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Connecté au réseau Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Impossible de se connecter au réseau Wi-Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Appuyer pour afficher tous les réseaux"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Se connecter"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Tous les réseaux"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Connectez-vous au réseau Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Se connecter au réseau"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index ec891e9..c45b7a9 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> días"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> día <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> día <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> h"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> minuto"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> seg"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> seg"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> segundos"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> segundo"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Sen título&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Sen número de teléfono)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Descoñecido"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Non hai servizo de chamadas de emerxencia nin de voz"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"A rede de telefonía móbil non ofrece o servizo na túa localización temporalmente"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Non se pode conectar coa rede"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Para mellorar a recepción, proba a cambiar o tipo seleccionado en Sistema &gt; Rede e Internet &gt; Redes de telefonía móbil &gt; Tipo de rede preferido."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Para mellorar a recepción, proba a cambiar o tipo seleccionado en Configuración &gt; Rede e Internet &gt; Redes de telefonía móbil &gt; Tipo de rede preferido."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Alertas"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Desvío de chamadas"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Modo de devolución de chamadas de emerxencia"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Buscando servizo"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Chamadas por wifi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Para facer chamadas e enviar mensaxes a través da wifi, primeiro pídelle ao teu operador que configure este servizo. A continuación, activa de novo as chamadas wifi en Configuración."</item>
+    <item msgid="3910386316304772394">"Para facer chamadas e enviar mensaxes a través da wifi, primeiro solicítalle ao operador que configure este servizo. Despois, activa de novo as chamadas por wifi en Configuración. (Código de erro: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Rexístrate co teu operador"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">Abrir redes wifi dispoñibles</item>
       <item quantity="one">Abrir rede wifi dispoñible</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Conéctate a unha rede wifi aberta"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Conectándose á rede wifi aberta"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Conectouse á rede wifi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Non se puido conectar á rede wifi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toca para ver todas as redes"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectarse"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Todas as redes"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Inicia sesión na rede wifi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Inicia sesión na rede"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 30516dc..bd4789a 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> દિવસ"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> દિવસ <xliff:g id="HOURS">%2$d</xliff:g> કલાક"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> દિવસ <xliff:g id="HOURS">%2$d</xliff:g> કલાક"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> કલાક"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> કલાક <xliff:g id="MINUTES">%2$d</xliff:g> મિનિટ"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> કલાક <xliff:g id="MINUTES">%2$d</xliff:g> મિનિટ"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> મિનિટ"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> મિનિટ"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> મિનિટ <xliff:g id="SECONDS">%2$d</xliff:g> સેકંડ"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> મિ <xliff:g id="SECONDS">%2$d</xliff:g> સે"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> સેકંડ"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> સેકંડ"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;અનામાંકિત&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(કોઈ ફોન નંબર નથી)"</string>
     <string name="unknownName" msgid="6867811765370350269">"અજાણ્યું"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"કોઈ વૉઇસ/કટોકટીની સેવા નથી"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"તમારા સ્થળે મોબાઇલ નેટવર્ક દ્વારા અસ્થાયીરૂપે ઑફર કરવામાં આવતી નથી"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"નેટવર્ક પર પહોંચી શકાતું નથી"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"રિસેપ્શનને બહેતર બનાવવા માટે, સિસ્ટમ &gt; નેટવર્ક અને ઇન્ટરનેટ &gt; મોબાઇલ નેટવર્ક &gt; પસંદગીનો નેટવર્ક પ્રકારમાં પસંદ કરેલો પ્રકાર બદલવાનો પ્રયાસ કરો."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"રિસેપ્શનને બહેતર બનાવવા માટે, સેટિંગ્સ &gt; નેટવર્ક અને ઇન્ટરનેટ &gt; મોબાઇલ નેટવર્ક &gt; પસંદગીના નેટવર્ક પ્રકાર પર પસંદ કરેલ પ્રકાર બદલવાનો પ્રયાસ કરો."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"ચેતવણીઓ"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"કૉલ ફૉર્વર્ડિંગ"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"કટોકટી કૉલબૅક મોડ"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"સેવા શોધી રહ્યું છે"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi કૉલિંગ"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi પર કૉલ્સ કરવા અને સંદેશા મોકલવા માટે, પહેલા તમારા કેરીઅરને આ સેવા સેટ કરવા માટે કહો. પછી સેટિંગ્સમાંથી Wi-Fi કૉલિંગ ચાલુ કરો."</item>
+    <item msgid="3910386316304772394">"Wi-Fi પરથી કૉલ કરવા અને સંદેશા મોકલવા માટે પહેલા તમારા કૅરિઅરને આ સેવા સેટ કરવા માટે કહો. પછી સેટિંગ્સમાંથી Wi-Fi કૉલિંગ ફરીથી ચાલુ કરો. (ભૂલ કોડ: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"તમારા કેરીઅર સાથે નોંધણી કરો"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="one">ખુલ્લા Wi-Fi નેટવર્ક્સ ઉપલબ્ધ છે</item>
       <item quantity="other">ખુલ્લા Wi-Fi નેટવર્ક્સ ઉપલબ્ધ છે</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"ખુલ્લા Wi‑Fi નેટવર્ક સાથે કનેક્ટ કરો"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"ખુલ્લા Wi‑Fi નેટવર્ક સાથે કનેક્ટ કરી રહ્યાં છીએ"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi નેટવર્ક સાથે કનેક્ટ કર્યુ"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi નેટવર્ક સાથે કનેક્ટ કરી શકાયું નથી"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"બધા નેટવર્ક જોવા ટૅપ કરો"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"કનેક્ટ કરો"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"બધા નેટવર્ક"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi નેટવર્ક પર સાઇન ઇન કરો"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"નેટવર્ક પર સાઇન ઇન કરો"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 2af0256..7baa83b 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> दिन"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> दिन <xliff:g id="HOURS">%2$d</xliff:g> घंटे"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> दिन <xliff:g id="HOURS">%2$d</xliff:g> घंटा"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> घंटे"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> घं. <xliff:g id="MINUTES">%2$d</xliff:g> मि."</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> घं. <xliff:g id="MINUTES">%2$d</xliff:g> मि."</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> मिनट"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> मिनट"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> मि. <xliff:g id="SECONDS">%2$d</xliff:g> से."</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> मि. <xliff:g id="SECONDS">%2$d</xliff:g> से."</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> सेकंड"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> सेकंड"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;शीर्षक-रहित&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(कोई फ़ोन नंबर नहीं)"</string>
     <string name="unknownName" msgid="6867811765370350269">"अज्ञात"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"कोई वॉइस/आपातकालीन सेवा नहीं है"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"आपके स्थान के मोबाइल नेटवर्क की ओर से इस समय ऑफ़र नहीं किया जा रहा है"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"नेटवर्क तक नहीं पहुंच पा रहे हैं"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"रिसेप्शन बेहतर करने के लिए, सिस्टम &gt; नेटवर्क और इंटरनेट &gt; मोबाइल नेटवर्क &gt; पसंदीदा नेटवर्क प्रकार पर जाकर, चुना गया प्रकार बदलकर देखें."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"रिसेप्शन बेहतर करने के लिए, सेटिंग &gt; नेटवर्क और इंटरनेट &gt; मोबाइल नेटवर्क &gt; पसंदीदा नेटवर्क प्रकार पर जाकर, चुना गया प्रकार बदलकर देखें."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"सूचनाएं"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"कॉल अग्रेषण"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"आपातकालीन कॉलबैक मोड"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"सेवा खोज रहा है"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"वाई-फ़ाई कॉलिंग"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"वाई-फ़ाई से कॉल करने और संदेश भेजने के लिए, सबसे पहले अपने वाहक से इस सेवा को सेट करने के लिए कहें. उसके बाद सेटिंग से पुन: वाई-फ़ाई कॉलिंग चालू करें."</item>
+    <item msgid="3910386316304772394">"वाई-फ़ाई से कॉल करने और संदेश भेजने के लिए, सबसे पहले अपने वाहक से इस सेवा को सेट करने के लिए कहें. उसके बाद सेटिंग से वाई-फ़ाई कॉलिंग को दोबारा चालू करें. (गड़बड़ी कोड: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"अपने वाहक के साथ पंजीकृत करें"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="one">खुले वाई-फ़ाई नेटवर्क उपलब्‍ध</item>
       <item quantity="other">खुले वाई-फ़ाई नेटवर्क उपलब्‍ध</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"खुले वाई-फ़ाई नेटवर्क से कनेक्ट करें"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"खुले वाई-फ़ाई नेटवर्क से कनेक्ट हो रहा है"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"वाई-फ़ाई नेटवर्क से कनेक्‍ट हो गया है"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"वाई-फ़ाई  नेटवर्क से कनेक्‍ट नहीं हो सका"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"सभी नेटवर्क देखने के लिए यहां पर टैप करें"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"कनेक्ट करें"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"सभी नेटवर्क"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"वाई-फ़ाई  नेटवर्क में प्रवेश करें"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"नेटवर्क में प्रवेश करें"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 6719b2c..92d4651 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> d"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> d <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> d <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> h"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Bez naslova&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Nema telefonskog broja)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Nepoznato"</string>
@@ -96,7 +84,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Nema glasovnih i hitnih usluga"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Trenutačno nije u ponudi mobilne mreže na vašoj lokaciji"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Pristup mreži nije moguć"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Za bolji prijem pokušajte odabrati drugu vrstu mreže u odjeljku Sustav &gt; Mreža i internet &gt; Mobilne mreže &gt; Željena vrsta mreže."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Za bolji prijem pokušajte promijeniti vrstu odabranu u odjeljku Postavke &gt; Mreža i internet &gt; Mobilne mreže &gt; Preferirana vrsta mreže."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Upozorenja"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Preusmjeravanje poziva"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Način hitnog povratnog poziva"</string>
@@ -132,7 +120,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Pretraživanje usluge"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi pozivi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Da biste telefonirali i slali pozive putem Wi-Fi-ja, morate tražiti od mobilnog operatera da vam postavi tu uslugu. Zatim ponovo uključite Wi-Fi pozive u Postavkama."</item>
+    <item msgid="3910386316304772394">"Da biste telefonirali i slali poruke putem Wi-Fi-ja, od mobilnog operatera morate tražiti da postavi tu uslugu. Zatim ponovo uključite Wi-Fi pozive u postavkama. (Kôd pogreške: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Registrirajte se kod mobilnog operatera"</item>
@@ -1128,6 +1116,13 @@
       <item quantity="few">Dostupne su otvorene Wi-Fi mreže</item>
       <item quantity="other">Dostupne su otvorene Wi-Fi mreže</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Povezivanje s otvorenom Wi‑Fi mrežom"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Povezivanje s otvorenom Wi‑Fi mrežom"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Povezano s Wi-Fi mrežom"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Nije uspjelo povezivanje s Wi-Fi mrežom"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Dodirnite za prikaz svih mreža"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Poveži"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Sve mreže"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Prijava na Wi-Fi mrežu"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Prijava na mrežu"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 942e478..107581c 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> nap"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> nap <xliff:g id="HOURS">%2$d</xliff:g> óra"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> nap <xliff:g id="HOURS">%2$d</xliff:g> óra"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> óra"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> óra <xliff:g id="MINUTES">%2$d</xliff:g> perc"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> óra <xliff:g id="MINUTES">%2$d</xliff:g> perc"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> perc"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> perc"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> perc <xliff:g id="SECONDS">%2$d</xliff:g> mp"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> perc <xliff:g id="SECONDS">%2$d</xliff:g> mp"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> másodperc"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> másodperc"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Névtelen&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Nincs telefonszám)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Ismeretlen"</string>
@@ -90,12 +78,12 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"A szolgáltatás nincs biztosítva."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Nem tudja módosítani a hívó fél azonosítója beállítást."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Adatszolgáltatás letiltva"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Nincs vészhívás"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Nincs segélyhívás"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Hangszolgáltatás letiltva"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Hang- és segélyszolgáltatás letiltva"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Az Ön tartózkodási helyén ideiglenesen nem áll rendelkezésre a mobilhálózaton"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"A hálózat nem érhető el"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"A vétel javítása érdekében próbálja módosítani a kiválasztott hálózattípust a Rendszer &gt; Hálózat és internet &gt; Mobilhálózatok &gt; Preferált hálózattípus menüben."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"A vétel javítása érdekében próbálja módosítani a kiválasztott hálózattípust a Beállítások &gt; Hálózat és internet &gt; Mobilhálózatok &gt; Preferált hálózattípus menüpontban."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Értesítések"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Hívásátirányítás"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Sürgősségi visszahívás mód"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Szolgáltatás keresése"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi-hívás"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Ha Wi-Fi-n szeretne telefonálni és üzenetet küldeni, kérje meg szolgáltatóját, hogy állítsa be ezt a szolgáltatást. Ezután a Beállítások menüben kapcsolhatja be újra a Wi-Fi-hívást."</item>
+    <item msgid="3910386316304772394">"Ha Wi-Fi-hálózaton szeretne telefonálni és üzenetet küldeni, kérje meg szolgáltatóját, hogy állítsa be ezt a szolgáltatást. Ezután kapcsolja be újra a Wi-Fi-hívást a Beállításokban. (Hibakód: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Regisztráljon a szolgáltatójánál"</item>
@@ -223,7 +211,7 @@
     <string name="global_actions" product="default" msgid="2406416831541615258">"Telefonbeállítások"</string>
     <string name="global_action_lock" msgid="2844945191792119712">"Képernyő lezárása"</string>
     <string name="global_action_power_off" msgid="4471879440839879722">"Kikapcsolás"</string>
-    <string name="global_action_emergency" msgid="7112311161137421166">"Vészhívás"</string>
+    <string name="global_action_emergency" msgid="7112311161137421166">"Segélyhívás"</string>
     <string name="global_action_bug_report" msgid="7934010578922304799">"Programhiba bejelentése"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Hibajelentés készítése"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Ezzel információt fog gyűjteni az eszköz jelenlegi állapotáról, amelyet a rendszer e-mailben fog elküldeni. Kérjük, legyen türelemmel, amíg a hibajelentés elkészül, és küldhető állapotba kerül."</string>
@@ -714,7 +702,7 @@
     <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"A feloldáshoz vagy segélyhívás kezdeményezéséhez nyomja meg a Menü gombot."</string>
     <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"A feloldáshoz nyomja meg a Menü gombot."</string>
     <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Rajzolja le a mintát a feloldáshoz"</string>
-    <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Vészhívás"</string>
+    <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Segélyhívás"</string>
     <string name="lockscreen_return_to_call" msgid="5244259785500040021">"Hívás folytatása"</string>
     <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Helyes!"</string>
     <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Próbálja újra"</string>
@@ -1106,6 +1094,13 @@
       <item quantity="other">Nyílt Wi-Fi hálózatok érhetők el</item>
       <item quantity="one">Nyílt Wi-Fi hálózat érhető el</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Nyílt Wi-Fi-hálózathoz kapcsolódhat"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Kapcsolódás nyílt Wi‑Fi-hálózathoz…"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Sikeres kapcsolódás a Wi-Fi-hálózathoz"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Nem sikerült kapcsolódni a Wi‑Fi-hálózathoz"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Koppintással megjelenítheti az összes hálózatot"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Kapcsolódás"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Összes hálózat"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Bejelentkezés Wi-Fi hálózatba"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Bejelentkezés a hálózatba"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 2aa7571..9c5b1e0 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"ՏԲ"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"Պբ"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> օր"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> օր <xliff:g id="HOURS">%2$d</xliff:g> ժ"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> օր <xliff:g id="HOURS">%2$d</xliff:g> ժ"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> ժ"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ժ <xliff:g id="MINUTES">%2$d</xliff:g> ր"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> ժ <xliff:g id="MINUTES">%2$d</xliff:g> ր"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> րոպե"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> րոպե"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> ր <xliff:g id="SECONDS">%2$d</xliff:g> վ"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> ր <xliff:g id="SECONDS">%2$d</xliff:g> վ"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> վ"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> վ"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Անանուն&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Հեռախոսահամար չկա)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Անհայտ"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Ձայնային/արտակարգ իրավիճակների ծառայությունն անհասանելի է"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Ձեր գտնվելու վայրում ծառայությունը ժամանակավորապես չի տրամադրվում բջջային ցանցի կողմից"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Ցանցն անհասանելի է"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Ազդանշանի ընդունման որակը բարելավելու համար փոխեք ցանցի տեսակը՝ անցնելով Համակարգ &gt; Ցանց և ինտերնետ &gt; Բջջային ցանցեր &gt; Ցանկալի ցանցի տեսակը։"</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Ազդանշանի ընդունման որակը բարելավելու համար փոխեք ցանցի տեսակը՝ անցնելով Համակարգ &gt; Ցանց և ինտերնետ &gt; Բջջային ցանցեր &gt; Ցանկալի ցանցի տեսակը։"</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Ծանուցումներ"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Զանգի վերահասցեավորում"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Շտապ հետկանչի ռեժիմ"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Ծառայության որոնում..."</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Զանգեր Wi-Fi-ի միջոցով"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi-ի միջոցով զանգեր կատարելու և հաղորդագրություններ ուղարկելու համար նախ դիմեք ձեր օպերատորին՝ ծառայությունը կարգավորելու համար: Ապա նորից միացրեք Wi-Fi զանգերը Կարգավորումներում:"</item>
+    <item msgid="3910386316304772394">"Wi-Fi-ի միջոցով զանգեր կատարելու և հաղորդագրություններ ուղարկելու համար նախ դիմեք ձեր օպերատորին՝ այս ծառայությունը կարգավորելու համար: Այնուհետև նորից միացրեք «Զանգեր Wi-Fi-ի միջոցով» ընտրանքը Կարգավորումներից: (Սխալի կոդ՝ <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Գրանցվեք օպերատորի մոտ"</item>
@@ -398,7 +386,7 @@
     <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Այս հավելվածը կարող է ստանալ ձեր տեղադրության տվյալները ցանցային տարբեր աղբյուրներից, օրինակ՝ բջջային աշտարակներից և Wi-Fi ցանցերից: Այս տեղորոշման ծառայությունները պետք է միացված և հասանելի լինեն ձեր հեռախոսում, որպեսզի հավելվածը կարողանա օգտագործել դրանք:"</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"փոխել ձեր աուդիո կարգավորումները"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Թույլ է տալիս հավելվածին փոփոխել ձայնանյութի գլոբալ կարգավորումները, ինչպես օրինակ` ձայնը և թե որ խոսափողն է օգտագործված արտածման համար:"</string>
-    <string name="permlab_recordAudio" msgid="3876049771427466323">"ձայնագրել ձայնանյութ"</string>
+    <string name="permlab_recordAudio" msgid="3876049771427466323">"ձայնագրել աուդիո ֆայլ"</string>
     <string name="permdesc_recordAudio" msgid="4245930455135321433">"Այս հավելվածը ցանկացած պահի կարող է ձայնագրել խոսափողի օգնությամբ:"</string>
     <string name="permlab_sim_communication" msgid="2935852302216852065">"ուղարկել հրամաններ SIM քարտին"</string>
     <string name="permdesc_sim_communication" msgid="5725159654279639498">"Թույլ է տալիս հավելվածին հրամաններ ուղարկել SIM-ին: Սա շատ վտանգավոր է:"</string>
@@ -1106,6 +1094,13 @@
       <item quantity="one">Հասանելի են չպաշտպանված Wi-Fi ցանցեր</item>
       <item quantity="other">Հասանելի են չպաշտպանված Wi-Fi ցանցեր</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Միացեք բաց Wi‑Fi ցանցին"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Միացում բաց Wi‑Fi ցանցին"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Միացել է Wi‑Fi ցանցին"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Չհաջողվեց միանալ Wi‑Fi ցանցին"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Հպեք՝ բոլոր ցանցերը տեսնելու համար"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Միանալ"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Բոլոր ցանցերը"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Մուտք գործեք Wi-Fi ցանց"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Մուտք գործեք ցանց"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1420,7 +1415,7 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Համակցված բարձրախոսներ"</string>
     <string name="default_media_route_name_hdmi" msgid="2450970399023478055">"HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Համակարգ"</string>
-    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-ի ձայնանյութ"</string>
+    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-ի աուդիո ֆայլ"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"Անլար էկրան"</string>
     <string name="media_route_button_content_description" msgid="591703006349356016">"Հեռարձակում"</string>
     <string name="media_route_chooser_title" msgid="1751618554539087622">"Միանալ սարքին"</string>
@@ -1779,5 +1774,5 @@
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM քարտը նախապատրաստված չէ"</string>
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM քարտի օգտագործումն արգելված է"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Հեռախոսի օգտագործումն արգելված է"</string>
-    <string name="popup_window_default_title" msgid="4874318849712115433">"Նոր պատուհան"</string>
+    <string name="popup_window_default_title" msgid="4874318849712115433">"Հայտնվող պատուհան"</string>
 </resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 02c6cac..f6fcef7 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> hari"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> hari <xliff:g id="HOURS">%2$d</xliff:g> jam"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> hari <xliff:g id="HOURS">%2$d</xliff:g> jam"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> jam"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> jam <xliff:g id="MINUTES">%2$d</xliff:g> mnt"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> jam <xliff:g id="MINUTES">%2$d</xliff:g> mnt"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> mnt"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> menit"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> mnt <xliff:g id="SECONDS">%2$d</xliff:g> dtk"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> mnt <xliff:g id="SECONDS">%2$d</xliff:g> dtk"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> dtk"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> dtk"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Tanpa judul&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Tidak ada nomor telepon)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Tidak diketahui"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Tidak ada layanan panggilan suara/darurat"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Untuk sementara tidak ditawarkan oleh jaringan seluler di lokasi Anda"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Tidak dapat menjangkau jaringan"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Untuk meningkatkan penerimaan sinyal, coba ubah jenis yang dipilih di Sistem &gt; Jaringan &amp; Internet &gt; Jaringan seluler &gt; Jenis jaringan pilihan."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Untuk menyempurnakan penerimaan sinyal, coba ubah jenis yang dipilih di Setelan &gt; Jaringan &amp; Internet &gt; Jaringan seluler &gt; Jenis jaringan pilihan."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Notifikasi"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Penerusan panggilan"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Mode panggilan balik darurat"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Mencari layanan"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Panggilan Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Untuk melakukan panggilan telepon dan mengirim pesan melalui Wi-Fi, terlebih dahulu minta operator untuk menyiapkan layanan ini. Lalu, aktifkan lagi panggilan telepon Wi-Fi dari Setelan."</item>
+    <item msgid="3910386316304772394">"Untuk menelepon dan mengirim pesan melalui Wi-Fi, tanyalah ke operator Anda terlebih dahulu untuk menyiapkan layanan ini. Kemudian, aktifkan kembali panggilan Wi-Fi dari Setelan. (Kode error: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Harap daftarkan ke operator"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">Jaringan Wi-Fi terbuka tersedia</item>
       <item quantity="one">Jaringan Wi-Fi terbuka tersedia</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Hubungkan ke jaringan Wi-Fi terbuka"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Menghubungkan ke jaringan Wi-Fi terbuka"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Terhubung ke jaringan Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Tidak dapat menghubungkan ke jaringan Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap untuk melihat semua jaringan"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Hubungkan"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Semua Jaringan"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Masuk ke jaringan Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Masuk ke jaringan"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1779,5 +1774,5 @@
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM tidak di-provisioning"</string>
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM tidak diizinkan"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Ponsel tidak diizinkan"</string>
-    <string name="popup_window_default_title" msgid="4874318849712115433">"Jendela Popup"</string>
+    <string name="popup_window_default_title" msgid="4874318849712115433">"Jendela Pop-up"</string>
 </resources>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 0917def..2c0fb3b 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> dagar"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> d. <xliff:g id="HOURS">%2$d</xliff:g> klst."</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> d. <xliff:g id="HOURS">%2$d</xliff:g> klst."</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> klst."</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> k. <xliff:g id="MINUTES">%2$d</xliff:g> mín."</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> k. <xliff:g id="MINUTES">%2$d</xliff:g> mín."</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> mín."</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> mín."</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> m. <xliff:g id="SECONDS">%2$d</xliff:g> sek."</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> m. <xliff:g id="SECONDS">%2$d</xliff:g> sek."</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> sek."</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> sek."</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Ónefnt&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Ekkert símanúmer)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Óþekkt"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Símtöl/neyðarsímtöl eru ekki í boði"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Ekki í boði á farsímakerfinu á þínum stað eins og er"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Ekki næst samband við símkerfi"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Reyndu að breyta valinni gerð í Kerfi &gt; Netkerfi og internet > Farsímakerfi &gt; Valin símkerfistegund til að bæta móttökuskilyrðin."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Reyndu að breyta valinni gerð í Stillingar &gt; Netkerfi og internet > Farsímakerfi &gt; Valin símkerfistegund til að bæta móttökuskilyrðin."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Tilkynningar"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Símtalsflutningur"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Stilling fyrir svarhringingu neyðarsímtala"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Leitar að þjónustu"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi símtöl"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Til að hringja og senda skilaboð yfir Wi-Fi þarftu fyrst að biðja símafyrirtækið þitt um að setja þá þjónustu upp. Kveiktu síðan á Wi-Fi símtölum í stillingunum."</item>
+    <item msgid="3910386316304772394">"Til að hringja og senda skilaboð yfir Wi-Fi þarftu fyrst að biðja símafyrirtækið þitt um að setja þá þjónustu upp. Kveiktu síðan á Wi-Fi símtölum í stillingunum. (Villukóði: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Skráðu þig hjá símafyrirtækinu"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="one">Opin Wi-Fi net í boði</item>
       <item quantity="other">Opin Wi-Fi net í boði</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Tengjast opnu Wi-Fi neti"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Tengist opnu Wi‑Fi neti"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Tengt við Wi‑Fi net"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Ekki hægt að tengjast Wi-Fi neti"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Ýttu til að sjá öll netkerfi"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Tengjast"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Öll netkerfi"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Skrá inn á Wi-Fi net"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Skrá inn á net"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 5e8b57d..f14b65b 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> giorni"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> giorno <xliff:g id="HOURS">%2$d</xliff:g> ore"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> giorno <xliff:g id="HOURS">%2$d</xliff:g> ora"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> ore"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ora <xliff:g id="MINUTES">%2$d</xliff:g> minuti"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> ora <xliff:g id="MINUTES">%2$d</xliff:g> minuto"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> minuti"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> minuto <xliff:g id="SECONDS">%2$d</xliff:g> secondi"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> minuto <xliff:g id="SECONDS">%2$d</xliff:g> secondo"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> secondi"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> secondo"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Senza nome&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Nessun numero di telefono)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Sconosciuto"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Nessun servizio di telefonia/emergenza"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Servizio temporaneamente non offerto dalla rete mobile nella tua località"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Impossibile raggiungere la rete"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Per migliorare la ricezione, prova a modificare il tipo selezionato in Sistema &gt; Rete e Internet &gt; Reti mobili &gt; Tipo di rete preferito."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Per migliorare la ricezione, prova a modificare il tipo selezionato in Impostazioni &gt; Rete e Internet &gt; Reti mobili &gt; Tipo di rete preferito."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Avvisi"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Deviazione chiamate"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Modalità di richiamata di emergenza"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Ricerca servizio"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Chiamate Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Per effettuare chiamate e inviare messaggi tramite Wi-Fi, è necessario prima chiedere all\'operatore telefonico di attivare il servizio. Successivamente, riattiva le chiamate Wi-Fi dalle Impostazioni."</item>
+    <item msgid="3910386316304772394">"Per effettuare chiamate e inviare messaggi tramite Wi-Fi, chiedi prima al tuo operatore di impostare questo servizio. Dopodiché, attiva di nuovo la funzione Chiamate Wi-Fi nelle impostazioni. (Codice di errore: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Registrati con il tuo operatore"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">Apri reti Wi-Fi disponibili</item>
       <item quantity="one">Apri rete Wi-Fi disponibile</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Stabilisci la connessione per aprire la rete Wi‑Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Connessione per aprire la rete Wi‑Fi"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Connessione alla rete Wi-Fi stabilita"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Impossibile connettersi alla rete Wi-Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tocca per vedere tutte le reti"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connetti"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Tutte le reti"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Accedi a rete Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Accedi alla rete"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1369,7 +1364,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Altre opzioni"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <string name="storage_internal" msgid="3570990907910199483">"Archivio condiviso interno"</string>
+    <string name="storage_internal" msgid="3570990907910199483">"Memoria condivisa interna"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Scheda SD"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"Scheda SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"Unità USB"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 5818e7b..5a3de37 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> ימים"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"יום <xliff:g id="DAYS">%1$d</xliff:g> ‏<xliff:g id="HOURS">%2$d</xliff:g> שע\'"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"יום <xliff:g id="DAYS">%1$d</xliff:g> שעה <xliff:g id="HOURS">%2$d</xliff:g>"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> שעות"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"שעה <xliff:g id="HOURS">%1$d</xliff:g> ‏<xliff:g id="MINUTES">%2$d</xliff:g> דק\'"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> שעות <xliff:g id="MINUTES">%2$d</xliff:g> דק\'"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> דקות"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> דקות"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"דקה <xliff:g id="MINUTES">%1$d</xliff:g> ‏<xliff:g id="SECONDS">%2$d</xliff:g> שנ\'"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"דקה <xliff:g id="MINUTES">%1$d</xliff:g> שנ\' <xliff:g id="SECONDS">%2$d</xliff:g>"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> שניות"</string>
-    <string name="durationSecond" msgid="985669622276420331">"שנייה <xliff:g id="SECONDS">%1$d</xliff:g>"</string>
     <string name="untitled" msgid="4638956954852782576">"‏&gt;ללא כותרת&lt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(אין מספר טלפון)"</string>
     <string name="unknownName" msgid="6867811765370350269">"לא ידוע"</string>
@@ -97,7 +85,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"אין אפשרות לבצע שיחות חירום ושיחות קוליות רגילות"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"הרשת הסלולרית במיקום הזה חסמה את השירות באופן זמני"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"לא ניתן להתחבר לרשת"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"‏כדי לשפר את הקליטה, נסה לשנות את הסוג הנבחר ב\'מערכת\' &gt; \'רשת ואינטרנט\' &gt; \'רשתות סלולריות\' &gt; \'סוג רשת מועדף\'."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"כדי לשפר את הקליטה, כדאי לנסות לשנות את סוג הרשת ב\'הגדרות\' &gt; \'רשת ואינטרנט\' &gt; \'רשתות סלולריות\' &gt; \'סוג רשת מועדף\'."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"התראות"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"העברת שיחות"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"מצב \'התקשרות חזרה בחירום\'"</string>
@@ -133,7 +121,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"מחפש שירות"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"‏שיחות ב-Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"‏כדי להתקשר ולשלוח הודעות ברשת Wi-Fi, תחילה יש לבקש מהספק להגדיר את השירות. לאחר מכן, יש להפעיל שוב התקשרות Wi-Fi מ\'הגדרות\'."</item>
+    <item msgid="3910386316304772394">"‏כדי להתקשר ולשלוח הודעות ברשת Wi-Fi, תחילה יש לבקש מהספק להגדיר את השירות. לאחר מכן, יש להפעיל שוב שיחות Wi-Fi ב\'הגדרות\'. (קוד שגיאה: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"הירשם אצל הספק"</item>
@@ -1150,6 +1138,13 @@
       <item quantity="other">‏יש רשתות Wi-Fi פתוחות וזמינות</item>
       <item quantity="one">‏יש רשת Wi-Fi פתוחה וזמינה</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"‏התחברות לרשת Wi‑Fi פתוחה"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"‏מתחבר לרשת Wi‑Fi פתוחה"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"‏מחובר לרשת Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"‏לא ניתן היה להתחבר לרשת Wi-Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"יש להקיש כדי לראות את כל הרשתות"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"התחבר"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"כל הרשתות"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"‏היכנס לרשת Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"היכנס לרשת"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1847,6 +1842,5 @@
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"‏כרטיס ה-SIM לא מזוהה"</string>
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"‏כרטיס ה-SIM לא מורשה"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"הטלפון לא מורשה"</string>
-    <!-- no translation found for popup_window_default_title (4874318849712115433) -->
-    <skip />
+    <string name="popup_window_default_title" msgid="4874318849712115433">"חלון קופץ"</string>
 </resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index c60b401..b237439 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g>日"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g>日<xliff:g id="HOURS">%2$d</xliff:g>時間"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g>日<xliff:g id="HOURS">%2$d</xliff:g>時間"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g>時間"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g>時間<xliff:g id="MINUTES">%2$d</xliff:g>分"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g>時間<xliff:g id="MINUTES">%2$d</xliff:g>分"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g>分"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g>分"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g>分<xliff:g id="SECONDS">%2$d</xliff:g>秒"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g>分<xliff:g id="SECONDS">%2$d</xliff:g>秒"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g>秒"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g>秒"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;新規&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(電話番号なし)"</string>
     <string name="unknownName" msgid="6867811765370350269">"不明"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"音声通話 / 緊急通報サービス停止"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"現在地のモバイル ネットワークでは一時的に提供されていません"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"ネットワークにアクセスできません"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"受信状態を改善するには、[システム] &gt; [ネットワークとインターネット] &gt; [モバイル ネットワーク] &gt; [優先ネットワーク タイプ] で選択したタイプを変更してみてください。"</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"受信状態を改善するには、[設定] &gt; [ネットワークとインターネット] &gt; [モバイル ネットワーク] &gt; [優先ネットワーク タイプ] で選択したタイプを変更してみてください。"</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"通知"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"電話の転送"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"緊急通報待機モード"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"サービスを検索中"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi通話"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi経由で音声通話の発信やメッセージの送信を行うには、携帯通信会社にWi-Fiサービスを申し込んだ上で、設定画面でWi-Fi発信を再度ONにしてください。"</item>
+    <item msgid="3910386316304772394">"Wi-Fi 経由で音声通話の発信やメッセージの送信を行うには、携帯通信会社に Wi-Fi サービスを申し込んだ上で、設定画面で Wi-Fi 発信を再度 ON にしてください(エラーコード: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"携帯通信会社に登録してください"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">複数のWi-Fiオープンネットワークが利用できます</item>
       <item quantity="one">Wi-Fiオープンネットワークが利用できます</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Wi-Fi オープン ネットワークに接続"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Wi-Fi オープン ネットワークに接続しています"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi-Fi ネットワークに接続しました"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi ネットワークに接続できませんでした"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"すべてのネットワークを表示するにはタップします"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"接続"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"すべてのネットワーク"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fiネットワークにログイン"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"ネットワークにログインしてください"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 67ee958..af653bd 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"ტბაიტი"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> დღე"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> დღე <xliff:g id="HOURS">%2$d</xliff:g> სთ"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> დღე <xliff:g id="HOURS">%2$d</xliff:g> სთ"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> სთ"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> სთ <xliff:g id="MINUTES">%2$d</xliff:g> წთ"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> სთ <xliff:g id="MINUTES">%2$d</xliff:g> წთ"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> წთ"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> წთ"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> წთ <xliff:g id="SECONDS">%2$d</xliff:g> წმ"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> წთ <xliff:g id="SECONDS">%2$d</xliff:g> წმ"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> წმ"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> წმ"</string>
     <string name="untitled" msgid="4638956954852782576">"უსათაურო"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(ტელეფონის ნომრის გარეშე)"</string>
     <string name="unknownName" msgid="6867811765370350269">"უცნობი"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"ხმოვანი/გადაუდებელი ზარების სერვისი არ არის"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"დროებით არ არის შემოთავაზებული მობილური ქსელის მიერ თქვენს მდებარეობაზე"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"ქსელთან დაკავშირება ვერ ხერხდება"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"მიღების გასაუმჯობესებლად ცადეთ არჩეული ტიპის შეცვლა აქ: სისტემა &gt; ქსელი და ინტერნეტი &gt; მობილური ქსელები &gt; ქსელის სასურველი ტიპი."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"მიღების გასაუმჯობესებლად ცადეთ არჩეული ტიპის შეცვლა აქ: პარამეტრები &gt; ქსელი და ინტერნეტი &gt; მობილური ქსელები &gt; ქსელის სასურველი ტიპი."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"გაფრთხილებები"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"ზარის გადამისამართება"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"გადაუდებელი გადმორეკვის რეჟიმი"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"სერვისის ძიება"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"დარეკვა Wi-Fi-ს მეშვეობით"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi-ს მეშვეობით ზარების განხორციელების ან შეტყობინების გაგზავნისათვის, პირველ რიგში დაეკითხეთ თქვენს ოპერატორს აღნიშნულ მომსახურებაზე. შემდეგ ხელახლა ჩართეთ Wi-Fi ზარები პარამეტრებიდან."</item>
+    <item msgid="3910386316304772394">"Wi-Fi-ს მეშვეობით ზარების განსახორციელებლად ან შეტყობინებების გასაგზავნად, პირველ რიგში, ამ სერვისის გააქტიურება თქვენს ოპერატორს უნდა თხოვოთ. შემდეგ კი ხელახლა ჩართეთ Wi-Fi დარეკვა პარამეტრებიდან.. (შეცდომის კოდი: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"დაარეგისტრირეთ თქვენი ოპერატორი"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">ხელმისაწვდომია ღია Wi-Fi ქსელები</item>
       <item quantity="one">ხელმისაწვდომია ღია Wi-Fi ქსელი</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"დაუკავშირდით ღია Wi‑Fi ქსელს"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"მიმდინარეობს ღია Wi‑Fi ქსელთან დაკავშირება"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi ქსელთან დაკავშირება წარმატებით მოხერხდა"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi ქსელთან დაკავშირება ვერ მოხერხდა"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"შეეხეთ ყველა ქსელის სანახავად"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"დაკავშირება"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"ყველა ქსელი"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi ქსელთან დაკავშირება"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"ქსელში შესვლა"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 28e950f..e185552 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TБ"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"ПБ"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> күн"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> күн <xliff:g id="HOURS">%2$d</xliff:g> сағ."</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> күн <xliff:g id="HOURS">%2$d</xliff:g> сағ."</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> сағ."</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> сағ. <xliff:g id="MINUTES">%2$d</xliff:g> м."</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> сағ. <xliff:g id="MINUTES">%2$d</xliff:g> м."</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> мин."</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> мин"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> мин. <xliff:g id="SECONDS">%2$d</xliff:g> с."</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> мин. <xliff:g id="SECONDS">%2$d</xliff:g> с."</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> сек."</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> сек."</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Атаусыз&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Телефон нөмірі жоқ)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Белгісіз"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Дауыстық/жедел қызметке қоңыраулар қызметі жоқ"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Орналасқан аймағыңызда мобильдік желі уақытша ұсынбады"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Желіге қосылу мүмкін емес"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Қабылдауды жақсарту үшін \"Жүйе &gt; Желі және интернет &gt; Мобильдік желілер &gt; Қалаған желі түрі\" тармағынан түрді өзгертіп көріңіз."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Қабылдауды жақсарту үшін \"Параметрлер &gt; Желі және интернет &gt; Мобильді желілер және қалаулы желі түрі\" тармағынан түрді өзгертіп көріңіз."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Дабылдар"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Қоңырауды басқа нөмірге бағыттау"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Шұғыл кері қоңырау шалу режимі"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Қызметті іздеу"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi қоңыраулары"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi арқылы қоңырау шалу және хабарларды жіберу үшін алдымен жабдықтаушыңыздан осы қызметті орнатуды сұраңыз. Содан кейін Параметрлерден Wi-Fi қоңырау шалуын іске қосыңыз."</item>
+    <item msgid="3910386316304772394">"Wi-Fi арқылы қоңырау шалу немесе хабарлар жіберу үшін, алдымен операторыңыздан құрылғыны реттеуді сұраңыз. Содан кейін \"Параметрлер\" бөлімінен Wi-Fi қоңырауларын қайта қосыңыз. (Қате коды: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Жабдықтаушыңыз арқылы тіркелу"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">Ашық Wi-Fi желілері қол жетімді</item>
       <item quantity="one">Ашық Wi-Fi желісі қол жетімді</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Ашық Wi‑Fi желісіне қосылу"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Ашық Wi‑Fi желісіне қосылуда"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi желісіне қосылды"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi желісіне қосылмады"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Барлық желілерді көру үшін түртіңіз"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Қосылу"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Барлық желілер"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi желісіне кіру"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Желіге кіру"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index a72446d..3843daa 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"តេរ៉ាបៃ"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> ថ្ងៃ"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> ថ្ងៃ <xliff:g id="HOURS">%2$d</xliff:g> ម៉ោង"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> ថ្ងៃ <xliff:g id="HOURS">%2$d</xliff:g> ម៉ោង"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> ម៉ោង"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ម៉ោង <xliff:g id="MINUTES">%2$d</xliff:g> នាទី"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> ម៉ោង <xliff:g id="MINUTES">%2$d</xliff:g> នាទី"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> នាទី"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> នាទី"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g>នាទី <xliff:g id="SECONDS">%2$d</xliff:g>វិនាទី"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g>នាទី <xliff:g id="SECONDS">%2$d</xliff:g>វិនាទី"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> វិនាទី"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> វិនាទី"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;គ្មាន​ចំណង​ជើង&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(គ្មាន​លេខ​ទូរស័ព្ទ)"</string>
     <string name="unknownName" msgid="6867811765370350269">"មិន​ស្គាល់"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"គ្មាន​សេវាកម្ម​សំឡេង/សង្រ្គោះបន្ទាន់​ទេ"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"​មិន​បាន​ផ្តល់​ជូន​ដោយ​បណ្តាញចល័តនៅ​ទីកន្លែងរបស់អ្នកជា​បណ្តោះ​អាសន្ន"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"មិន​អាច​ភ្ជាប់​ទៅ​បណ្តាញ​បានទេ​"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"ដើម្បីកែលម្អការទទួលយក សាកល្បងប្តូរប្រភេទដែលបានជ្រើសរើសនៅ ប្រព័ន្ធ &gt; បណ្តាញ និងអ៊ីនធឺណិត &gt; បណ្តាញទូរសព្ទចល័ត &gt; ប្រភេទបណ្តាញដែលចង់ប្រើ។"</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"ដើម្បី​ធ្វើ​ឲ្យ​ការ​ទទួល​​រលក​សញ្ញា​​ប្រសើរ​ជាងមុន សូមសាកល្បងប្តូរប្រភេទដែលបានជ្រើសរើសនៅ ការកំណត់ &gt; បណ្តាញ និងអ៊ីនធឺណិត &gt; បណ្តាញទូរសព្ទចល័ត &gt; ប្រភេទបណ្តាញដែលចង់ប្រើ។"</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"ការជូនដំណឹង"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"ការបញ្ជូន​ការហៅ​ទូរសព្ទ​បន្ត"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"មុខងារ​ហៅត្រឡប់​វិញ​បន្ទាន់"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"​ស្វែង​រក​សេវាកម្ម"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"ការហៅតាម Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"ដើម្បីធ្វើការហៅ និងផ្ញើសារតាម Wi-Fi ដំបូងឡើយអ្នកត្រូវស្នើឲ្យក្រុមហ៊ុនរបស់អ្នកដំឡើងសេវាកម្មនេះសិន។ បន្ទាប់មកបើកការហៅតាម Wi-Fi ម្តងទៀតចេញពីការកំណត់។"</item>
+    <item msgid="3910386316304772394">"ដើម្បីធ្វើការហៅ និងផ្ញើសារតាម Wi-Fi អ្នកត្រូវស្នើឲ្យក្រុមហ៊ុនបម្រើសេវាទូរសព្ទរបស់អ្នកដំឡើងសេវាកម្មនេះជាមុនសិន។ បន្ទាប់មកបើកការហៅតាម Wi-Fi ម្តងទៀតនៅក្នុងការកំណត់។ (លេខកូដបញ្ហា៖ <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"ចុះឈ្មោះជាមួយក្រុមហ៊ុនរបស់អ្នក"</item>
@@ -1108,6 +1096,13 @@
       <item quantity="other">បើកបណ្តាញ Wi-Fi ដែលមាន</item>
       <item quantity="one">បើកបណ្តាញ Wi-Fi ដែលមាន</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"ភ្ជាប់ទៅបណ្តាញ Wi‑Fi ចំហ"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"កំពុងភ្ជាប់ទៅបណ្តាញ Wi‑Fi ចំហ"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"បានភ្ជាប់ទៅបណ្តាញ Wi‑Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"មិនអាចភ្ជាប់ទៅបណ្តាញ Wi‑Fi បានទេ"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ចុចដើម្បីមើលបណ្តាញទាំងអស់"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"ភ្ជាប់"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"បណ្តាញទាំងអស់"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"ចូល​បណ្ដាញ​វ៉ាយហ្វាយ"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"ចូលទៅបណ្តាញ"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 8d8065b..8d3db20 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> ದಿನಗಳು"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> ದಿನ <xliff:g id="HOURS">%2$d</xliff:g> ಗಂಟೆಗಳು"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> ದಿನ <xliff:g id="HOURS">%2$d</xliff:g> ಗಂ"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> ಗಂಟೆಗಳು"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ಗಂಟೆ <xliff:g id="MINUTES">%2$d</xliff:g> ನಿಮಿಷಗಳು"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> ಗಂಟೆ <xliff:g id="MINUTES">%2$d</xliff:g> ನಿಮಿಷ"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> ನಿಮಿಷಗಳು"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> ನಿಮಿಷ"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> ನಿಮಿ <xliff:g id="SECONDS">%2$d</xliff:g> ಸೆಕೆಂಡುಗಳು"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> ನಿಮಿ <xliff:g id="SECONDS">%2$d</xliff:g> ಸೆ"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> ಸೆಕೆಂಡುಗಳು"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> ಸೆಕೆಂಡುಗಳು"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;ಶೀರ್ಷಿಕೆ ರಹಿತ&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(ಯಾವುದೇ ಫೋನ್ ಸಂಖ್ಯೆಯಿಲ್ಲ)"</string>
     <string name="unknownName" msgid="6867811765370350269">"ಅಪರಿಚಿತ"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"ಧ್ವನಿ/ತುರ್ತು ಸೇವೆ ಇಲ್ಲ"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"ತಾತ್ಕಾಲಿಕವಾಗಿ ಮೊಬೈಲ್ ನೆಟ್‌ವರ್ಕ್‌ನಿಂದ ನಿಮ್ಮ ಸ್ಥಳದಲ್ಲಿ ಒದಗಿಸುತ್ತಿಲ್ಲ"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"ನೆಟ್‌ವರ್ಕ್ ತಲುಪಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"ನೆಟ್‌ವರ್ಕ್ ಸಂಪರ್ಕ ಪಡೆಯುವುದನ್ನು ಸುಧಾರಿಸಲು, ಆಯ್ಕೆ ಮಾಡಿರುವ ವಿಧವನ್ನು ಸಿಸ್ಟಂ &gt; ನೆಟ್‌ವರ್ಕ್ ಮತ್ತು ಇಂಟರ್ನೆಟ್ &gt; ಮೊಬೈಲ್ ನೆಟ್‌ವರ್ಕ್‌ಗಳು &gt; ಆದ್ಯತೆಯ ನೆಟ್‌ವರ್ಕ್ ವಿಧದಲ್ಲಿ ಬದಲಿಸಿ ನೋಡಿ."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"ನೆಟ್‌ವರ್ಕ್ ಸಂಪರ್ಕ ಪಡೆಯುವುದನ್ನು ಸುಧಾರಿಸಲು, ಆಯ್ಕೆ ಮಾಡಿರುವ ವಿಧವನ್ನು ಸೆಟ್ಟಿಂಗ್‌ಗಳು &gt; ನೆಟ್‌ವರ್ಕ್ ಮತ್ತು ಇಂಟರ್ನೆಟ್ &gt; ಮೊಬೈಲ್ ನೆಟ್‌ವರ್ಕ್‌ಗಳು &gt; ಆದ್ಯತೆಯ ನೆಟ್‌ವರ್ಕ್ ವಿಧದಲ್ಲಿ ಬದಲಿಸಿ ನೋಡಿ."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"ಎಚ್ಚರಿಕೆಗಳು"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"ಕರೆ ಫಾರ್ವರ್ಡ್‌ ಮಾಡುವಿಕೆ"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"ತುರ್ತು ಕಾಲ್‌ಬ್ಯಾಕ್‌ ಮೋಡ್‌"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"ಸೇವೆ ಹುಡುಕಲಾಗುತ್ತಿದೆ"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"ವೈ-ಫೈ ಕರೆ ಮಾಡುವಿಕೆ"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"ವೈ-ಫೈ ಬಳಸಿಕೊಂಡು ಕರೆ ಮಾಡಲು ಮತ್ತು ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಲು, ಮೊದಲು ಈ ಸಾಧನವನ್ನು ಹೊಂದಿಸಲು ನಿಮ್ಮ ವಾಹಕವನ್ನು ಕೇಳಿ. ತದನಂತರ ಸೆಟ್ಟಿಂಗ್‌ಗಳಲ್ಲಿ ಮತ್ತೆ ವೈ-ಫೈ ಆನ್‌ ಮಾಡಿ."</item>
+    <item msgid="3910386316304772394">"ವೈ-ಫೈ ಮೂಲಕ ಕರೆಗಳನ್ನು ಮಾಡಲು ಮತ್ತು ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಲು, ಈ ಸೇವೆಯನ್ನು ಹೊಂದಿಸಲು ಮೊದಲು ನಿಮ್ಮ ವಾಹಕವನ್ನು ಕೇಳಿ. ಆ ನಂತರ ಸೆಟ್ಟಿಂಗ್‌ಗಳಿಂದ ವೈ-ಫೈ ಕರೆಮಾಡುವಿಕೆಯನ್ನು ಅನ್ನು ಆನ್ ಮಾಡಿ. (ದೋಷ ಕೋಡ್: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"ನಿಮ್ಮ ವಾಹಕದಲ್ಲಿ ನೋಂದಾಯಿಸಿಕೊಳ್ಳಿ"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="one">ಮುಕ್ತ ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ಗಳು ಲಭ್ಯವಿವೆ</item>
       <item quantity="other">ಮುಕ್ತ ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ಗಳು ಲಭ್ಯವಿವೆ</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"ಮುಕ್ತ ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸಂಪರ್ಕಪಡಿಸಿ"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"ಮುಕ್ತ ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗುತ್ತಿದೆ"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸಂಪರ್ಕಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ಎಲ್ಲಾ ನೆಟ್‌ವರ್ಕ್‌ಗಳನ್ನು ನೋಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"ಸಂಪರ್ಕಿಸಿ"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"ಎಲ್ಲಾ ನೆಟ್‌ವರ್ಕ್‌ಗಳು"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"ವೈ-ಫೈ ನೆಟ್‍ವರ್ಕ್‌ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1780,6 +1775,5 @@
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"ಸಿಮ್ ಸಿದ್ಧವಾಗಿಲ್ಲ"</string>
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"ಸಿಮ್‌ಗೆ ಅನುಮತಿಯಿಲ್ಲ"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"ಫೋನ್‌ಗೆ ಅನುಮತಿಯಿಲ್ಲ"</string>
-    <!-- no translation found for popup_window_default_title (4874318849712115433) -->
-    <skip />
+    <string name="popup_window_default_title" msgid="4874318849712115433">"ಪಾಪ್‌ಅಪ್ ವಿಂಡೋ"</string>
 </resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 89b305b..497cfe9 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g>일"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g>일 <xliff:g id="HOURS">%2$d</xliff:g>시간"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g>일 <xliff:g id="HOURS">%2$d</xliff:g>시간"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g>시간"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g>시간 <xliff:g id="MINUTES">%2$d</xliff:g>분"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g>시간 <xliff:g id="MINUTES">%2$d</xliff:g>분"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g>분"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g>분"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g>분 <xliff:g id="SECONDS">%2$d</xliff:g>초"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g>분 <xliff:g id="SECONDS">%2$d</xliff:g>초"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g>초"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g>초"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;제목 없음&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(전화번호 없음)"</string>
     <string name="unknownName" msgid="6867811765370350269">"알 수 없음"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"음성/긴급 서비스를 이용할 수 없음"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"현재 위치에서 모바일 네트워크가 서비스 제공을 일시적으로 중단했습니다."</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"네트워크에 연결할 수 없습니다."</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"수신 상태를 개선하려면 시스템 &gt; 네트워크 및 인터넷 &gt; 모바일 네트워크 &gt; 기본 네트워크 유형에서 선택된 유형을 변경해 보세요."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"수신 상태를 개선하려면 설정 &gt; 네트워크 및 인터넷 &gt; 모바일 네트워크 &gt; 기본 네트워크 유형에서 선택된 유형을 변경해 보세요."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"알림"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"착신전환"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"긴급 콜백 모드"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"서비스 검색 중"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi 통화"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi를 사용하여 전화를 걸고 메시지를 보내려면 먼저 이동통신사에 문의하여 이 기능을 설정해야 합니다. 그런 다음 설정에서 Wi-Fi 통화를 사용 설정하시기 바랍니다."</item>
+    <item msgid="3910386316304772394">"Wi-Fi를 사용하여 전화를 걸고 메시지를 보내려면 먼저 이동통신사에 문의하여 서비스를 설정해야 합니다. 그런 다음 설정에서 Wi-Fi 통화를 사용 설정하시기 바랍니다. (오류 코드: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"이동통신사에 등록"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">개방형 Wi-Fi 네트워크 사용 가능</item>
       <item quantity="one">개방형 Wi-Fi 네트워크 사용 가능</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"공개 Wi‑Fi 네트워크에 연결"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"공개 Wi‑Fi 네트워크에 연결 중"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi 네트워크에 연결됨"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi 네트워크에 연결할 수 없음"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"모든 네트워크를 보려면 탭하세요."</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"연결"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"모든 네트워크"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi 네트워크에 로그인"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"네트워크에 로그인"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 14cda50..ea01218 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"ТБ"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"ПБ"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> күн"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> күн <xliff:g id="HOURS">%2$d</xliff:g> с"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> күн <xliff:g id="HOURS">%2$d</xliff:g> с"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> с"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> с. <xliff:g id="MINUTES">%2$d</xliff:g> мүн"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> саат <xliff:g id="MINUTES">%2$d</xliff:g> мүн"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> мүн"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> мүн."</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> мүн. <xliff:g id="SECONDS">%2$d</xliff:g> сек"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> мүн. <xliff:g id="SECONDS">%2$d</xliff:g> сек"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> сек"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> сек"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Баш аты жок&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Телефон номери жок)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Белгисиз"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Бардык чалуулар жана кызматтар бөгөттөлгөн"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Өзгөчө кырдаалдагы кызматтар сиз жайгашкан жердеги мобилдик тармак тарабынан убактылуу бөгөттөлгөн"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Тармакка туташпай жатат"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Кабыл алуу мүмкүнчүлүгүн жакшыртуу үчүн Тутум &gt; Тармак жана Интернет &gt; Мобилдик тармактар &gt; Тандалган тармак бөлүмүнөн тармактын түрүн өзгөртүп көрүңүз."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Кабыл алуу мүмкүнчүлүгүн жакшыртуу үчүн Жөндөөлөр &gt; Тармак жана Интернет &gt; Мобилдик тармактар &gt; Тандалган тармак бөлүмүнөн тармактын түрүн өзгөртүп көрүңүз."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Эскертүүлөр"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Чалууну башка номерге багыттоо"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Шашылыш кайра чалуу режими"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Кызмат изделүүдө"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi Чалуу"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi аркылуу чалууларды аткарып жана билдирүүлөрдү жөнөтүү үчүн адегенде операторуңуздан бул кызматты орнотушун сураныңыз. Андан соң, Жөндөөлөрдөн Wi-Fi чалууну кайра күйгүзүңүз."</item>
+    <item msgid="3910386316304772394">"Wi-Fi аркылуу чалууларды аткарып жана билдирүүлөрдү жөнөтүү үчүн адегенде байланыш операторуңуздан бул кызматты орнотушун сураныңыз. Андан соң, Жөндөөлөрдөн Wi-Fi чалууну кайра күйгүзүңүз. (Ката коду: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Операторуңузга катталыңыз"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">Ачык Wi-Fi тармагы жеткиликтүү</item>
       <item quantity="one">Ачык Wi-Fi тармагы жеткиликтүү</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Ачык Wi‑Fi тармагына туташуу"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Ачык Wi‑Fi тармагына туташууда"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Ачык Wi‑Fi тармагына туташты"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi-Fi тармагына туташпай калды"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Бардык тармактарды көрүү үчүн басыңыз"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Туташуу"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Бардык тармактар"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi түйүнүнө кирүү"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Тармакка кирүү"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index f3ea91b..9bdfd39 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> ມື້"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> ມື້ <xliff:g id="HOURS">%2$d</xliff:g> ຊມ"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> ມື້ <xliff:g id="HOURS">%2$d</xliff:g> ຊມ"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> ຊມ"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ຊມ <xliff:g id="MINUTES">%2$d</xliff:g> ນທ"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> ຊມ <xliff:g id="MINUTES">%2$d</xliff:g> ນທ"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> ນທ"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> ​ນ​ທ"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> ນທ <xliff:g id="SECONDS">%2$d</xliff:g> ວິ"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> ນທ <xliff:g id="SECONDS">%2$d</xliff:g> ວິ"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> ວິ"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> ວິ"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;ບໍ່ມີຊື່&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(ບໍ່ມີເບີໂທລະສັບ)"</string>
     <string name="unknownName" msgid="6867811765370350269">"​ບໍ່​ຮູ້​ຈັກ"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"ບໍ່ມີບໍລິການສຽງ/ສຸກເສີນ"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"ເຄືອຂ່າຍຂອງທ່ານບໍ່ໄດ້ໃຫ້ບໍລິການຢູ່ສະຖານທີ່ນີ້ເປັນການຊົ່ວຄາວ"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Can’t reach network"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"ເພື່ອປັບປຸງການຮັບສັນຍານ, ໃຫ້ລອງປ່ຽນປະເພດທີ່ເລືອກໄວ້ທີ່ ລະບົບ &gt; ເຄືອຂ່າຍ ແລະ ອິນເຕີເນັດ &gt; ເຄືອຂ່າຍມືຖື &gt; ປະເພດເຄືອຂ່າຍທີ່ຕ້ອງການ."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"ເພື່ອປັບປຸງການຮັບສັນຍານ, ໃຫ້ລອງປ່ຽນປະເພດທີ່ເລືອກໄວ້ຢູ່ທີ່ ການຕັ້ງຄ່າ &gt; ເຄືອຂ່າຍ ແລະ ອິນເຕີເນັດ &gt; ເຄືອຂ່າຍມືຖື &gt; ປະເພດເຄືອຂ່າຍທີ່ຕ້ອງການ."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"ການເຕືອນ"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"ການໂອນສາຍ"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"ໂໝດໂທກັບສຸກເສີນ"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"ຊອກຫາບໍລິການ"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"ການ​ໂທ Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"ເພື່ອ​ໂທ ແລະ​ສົ່ງ​ຂໍ້​ຄວາມ​ຢູ່​ເທິງ Wi-Fi, ກ່ອນ​ອື່ນ​ໝົດ​ໃຫ້​ຖ້າມ​ຜູ້​ໃຫ້​ບໍ​ລິ​ການ​ເຄືອ​ຂ່າຍ​ຂອງ​ທ່ານ ເພື່ອ​ຕັ້ງ​ການ​ບໍ​ລິ​ການ​ນີ້. ຈາກນັ້ນ​ເປີດການ​ໂທ Wi-Fi ອີກ​ຈາກ​ການ​ຕັ້ງ​ຄ່າ."</item>
+    <item msgid="3910386316304772394">"ເພື່ອໂທ ແລະ ສົ່ງຂໍ້ຄວາມຜ່ານ Wi-Fi, ໃຫ້ແຈ້ງໃຫ້ຜູ້ໃຫ້ບໍລິການຂອງທ່ານຕັ້ງບໍລິການນີ້. ຈາກນັ້ນເປີດໃຊ້ການໂທ Wi-Fi ອີກຄັ້ງຈາກການຕັ້ງຄ່າ. (ລະຫັດຂໍ້ຜິດພາດ: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"ລົງ​ທະ​ບຽນ​ກັບ​ຜູ້​ໃຫ້​ບໍ​ລິ​ການ​ເຄືອ​ຂ່າຍ​ຂອງ​ທ່ານ"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">ເປີດເຄືອຂ່າຍ Wi-Fi  ທີ່ມີໃຫ້</item>
       <item quantity="one">ເປີດເຄືອຂ່າຍ Wi-Fi  ທີ່ມີໃຫ້</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"ເຊື່ອມຕໍ່ຫາເຄືອຂ່າຍ Wi‑Fi ແບບເປີດ"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"ກຳລັງເຊື່ອມຕໍ່ຫາເຄືອຂ່າຍ Wi‑Fi"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"ເຊື່ອມຕໍ່ຫາເຄືອຂ່າຍ Wi‑Fi ແລ້ວ"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"ບໍ່ສາມາດເຊື່ອມຕໍ່ຫາເຄືອຂ່າຍ Wi‑Fi ໄດ້"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ແຕະເພື່ອເບິ່ງເຄືອຂ່າຍທັງໝົດ"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"ເຊື່ອມ​ຕໍ່"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"ເຄືອຂ່າຍທັງໝົດ"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"ເຂົ້າສູ່ລະບົບເຄືອຂ່າຍ Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"ລົງຊື່ເຂົ້າເຄືອຂ່າຍ"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index ec706ed..a6aa9c0 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> d."</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> d. <xliff:g id="HOURS">%2$d</xliff:g> val."</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> d. <xliff:g id="HOURS">%2$d</xliff:g> val."</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> val."</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> val. <xliff:g id="MINUTES">%2$d</xliff:g> min."</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> val. <xliff:g id="MINUTES">%2$d</xliff:g> min."</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> min."</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min."</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min. <xliff:g id="SECONDS">%2$d</xliff:g> sek."</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min. <xliff:g id="SECONDS">%2$d</xliff:g> sek."</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> sek."</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> sek."</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Be pavadinimo&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Nėra telefono numerio)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Nežinoma"</string>
@@ -97,7 +85,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Balso skambučių / skambučių pagalbos numeriais paslauga neteikiama"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Laikinai nesiūloma mobiliojo ryšio tinkle jūsų vietovėje"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Nepavyko pasiekti tinklo"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Kad pagerintumėte ryšį, pabandykite pakeisti tipą, pasirinktą skiltyje „Nustatymai“ &gt; „Tinklas ir internetas“ &gt; „Mobiliojo ryšio tinklai“ &gt; „Pageidaujamas tinklo tipas“."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Kad pagerintumėte ryšį, pabandykite pakeisti tipą, pasirinktą skiltyje „Nustatymai“ &gt; „Tinklas ir internetas“ &gt; „Mobiliojo ryšio tinklai“ &gt; „Pageidaujamas tinklo tipas“."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Įspėjimai"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Skambučio peradresavimas"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Atskambinimo pagalbos numeriu režimas"</string>
@@ -133,7 +121,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Ieškoma paslaugos"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"„Wi-Fi“ skambinimas"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Jei norite skambinti ir siųsti pranešimus „Wi-Fi“ ryšiu, pirmiausia paprašykite operatoriaus nustatyti šią paslaugą. Tada vėl įjunkite skambinimą „Wi-Fi“ ryšiu „Nustatymų“ skiltyje."</item>
+    <item msgid="3910386316304772394">"Jei norite skambinti ir siųsti pranešimus naudodami „Wi-Fi“, pirmiausia paprašykite operatoriaus nustatyti šią paslaugą. Tada vėl įjunkite „Wi-Fi“ skambinimą skiltyje „Nustatymai“. (Klaidos kodas: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Užregistruokite pas operatorių"</item>
@@ -1150,6 +1138,13 @@
       <item quantity="many">Pasiekiami atvirieji „Wi-Fi“ tinklai</item>
       <item quantity="other">Pasiekiami atvirieji „Wi-Fi“ tinklai</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Prisijunkite prie atviro „Wi‑Fi“ tinklo"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Prisijungiama prie atviro „Wi‑Fi“ tinklo"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Prisijungta prie „Wi-Fi“ tinklo"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Nepavyko prisijungti prie „Wi‑Fi“ tinklo"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Palieskite, jei norite matyti visus tinklus"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Prisijungti"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Visi tinklai"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Prisijungti prie „Wi-Fi“ tinklo"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Prisijungti prie tinklo"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index e8dff85..d96ea068 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> d."</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> d. <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> d. <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> h"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Bez nosaukuma&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Nav tālruņa numura)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Nezināms"</string>
@@ -96,7 +84,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Balss un ārkārtas izsaukumu pakalpojums nedarbojas"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Pagaidām netiek piedāvāts mobilajā tīklā jūsu atrašanās vietā"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Nevar sasniegt tīklu"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Lai uzlabotu uztveršanu, mainiet atlasīto veidu sadaļā Sistēma &gt; Tīkls un internets &gt; Mobilie tīkli &gt; Ieteicamais tīkla veids."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Lai uzlabotu uztveršanu, mainiet atlasīto veidu sadaļā Iestatījumi &gt; Tīkls un internets &gt; Mobilie tīkli &gt; Ieteicamais tīkla veids."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Brīdinājumi"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Zvanu pāradresācija"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Ārkārtas atzvana režīms"</string>
@@ -132,7 +120,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Pakalpojuma meklēšana"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi zvani"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Lai veiktu zvanus un sūtītu īsziņas Wi-Fi tīklā, vispirms lūdziet mobilo sakaru operatoru iestatīt šo pakalpojumu. Pēc tam iestatījumos vēlreiz ieslēdziet Wi-Fi zvanus."</item>
+    <item msgid="3910386316304772394">"Lai veiktu zvanus un sūtītu īsziņas Wi-Fi tīklā, vispirms lūdziet mobilo sakaru operatoram iestatīt šo pakalpojumu. Pēc tam iestatījumos vēlreiz ieslēdziet Wi-Fi zvanus. (Kļūdas kods: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Reģistrēt to pie sava mobilo sakaru operatora"</item>
@@ -1128,6 +1116,13 @@
       <item quantity="one">Ir pieejami atvērti Wi-Fi tīkli</item>
       <item quantity="other">Ir pieejami atvērti Wi-Fi tīkli</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Savienojuma izveide ar atvērtu Wi-Fi tīklu"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Notiek savienojuma izveide ar atvērtu Wi-Fi tīklu"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Ir izveidots savienojums ar Wi-Fi tīklu"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Nevarēja izveidot savienojumu ar Wi‑Fi tīklu"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Pieskarieties, lai skatītu visus tīklus"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Izveidot savienojumu"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Visi tīkli"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Pierakstieties Wi-Fi tīklā"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Pierakstīšanās tīklā"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-mcc302-mnc370-af/strings.xml b/core/res/res/values-mcc302-mnc370-af/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-af/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-am/strings.xml b/core/res/res/values-mcc302-mnc370-am/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-am/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ar/strings.xml b/core/res/res/values-mcc302-mnc370-ar/strings.xml
new file mode 100644
index 0000000..f1c8176
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ar/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"‏%s مع Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-az/strings.xml b/core/res/res/values-mcc302-mnc370-az/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-az/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-b+sr+Latn/strings.xml b/core/res/res/values-mcc302-mnc370-b+sr+Latn/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-b+sr+Latn/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-be/strings.xml b/core/res/res/values-mcc302-mnc370-be/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-be/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-bg/strings.xml b/core/res/res/values-mcc302-mnc370-bg/strings.xml
new file mode 100644
index 0000000..b3a9589
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-bg/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi от %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-bs/strings.xml b/core/res/res/values-mcc302-mnc370-bs/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-bs/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ca/strings.xml b/core/res/res/values-mcc302-mnc370-ca/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ca/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-cs/strings.xml b/core/res/res/values-mcc302-mnc370-cs/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-cs/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-da/strings.xml b/core/res/res/values-mcc302-mnc370-da/strings.xml
new file mode 100644
index 0000000..709530c
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-da/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi fra %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-de/strings.xml b/core/res/res/values-mcc302-mnc370-de/strings.xml
new file mode 100644
index 0000000..6aa7643
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-de/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"WLAN: %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-el/strings.xml b/core/res/res/values-mcc302-mnc370-el/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-el/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-en-rAU/strings.xml b/core/res/res/values-mcc302-mnc370-en-rAU/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-en-rAU/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-en-rGB/strings.xml b/core/res/res/values-mcc302-mnc370-en-rGB/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-en-rGB/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-en-rIN/strings.xml b/core/res/res/values-mcc302-mnc370-en-rIN/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-en-rIN/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-es-rUS/strings.xml b/core/res/res/values-mcc302-mnc370-es-rUS/strings.xml
new file mode 100644
index 0000000..5ba6413
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-es-rUS/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi de %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-es/strings.xml b/core/res/res/values-mcc302-mnc370-es/strings.xml
new file mode 100644
index 0000000..5ba6413
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-es/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi de %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-et/strings.xml b/core/res/res/values-mcc302-mnc370-et/strings.xml
new file mode 100644
index 0000000..648544d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-et/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s WiFi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-eu/strings.xml b/core/res/res/values-mcc302-mnc370-eu/strings.xml
new file mode 100644
index 0000000..960e1e5
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-eu/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi sarea"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-fa/strings.xml b/core/res/res/values-mcc302-mnc370-fa/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-fa/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-fi/strings.xml b/core/res/res/values-mcc302-mnc370-fi/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-fi/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-fr-rCA/strings.xml b/core/res/res/values-mcc302-mnc370-fr-rCA/strings.xml
new file mode 100644
index 0000000..5ba6413
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-fr-rCA/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi de %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-fr/strings.xml b/core/res/res/values-mcc302-mnc370-fr/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-fr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-gl/strings.xml b/core/res/res/values-mcc302-mnc370-gl/strings.xml
new file mode 100644
index 0000000..b644471
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-gl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wifi de %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-hi/strings.xml b/core/res/res/values-mcc302-mnc370-hi/strings.xml
new file mode 100644
index 0000000..3521dd4
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-hi/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s वाई-फ़ाई"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-hr/strings.xml b/core/res/res/values-mcc302-mnc370-hr/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-hr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-hu/strings.xml b/core/res/res/values-mcc302-mnc370-hu/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-hu/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-hy/strings.xml b/core/res/res/values-mcc302-mnc370-hy/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-hy/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-in/strings.xml b/core/res/res/values-mcc302-mnc370-in/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-in/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-is/strings.xml b/core/res/res/values-mcc302-mnc370-is/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-is/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-it/strings.xml b/core/res/res/values-mcc302-mnc370-it/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-it/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-iw/strings.xml b/core/res/res/values-mcc302-mnc370-iw/strings.xml
new file mode 100644
index 0000000..90b73ad
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-iw/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"‎%s‎"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ja/strings.xml b/core/res/res/values-mcc302-mnc370-ja/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ja/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ka/strings.xml b/core/res/res/values-mcc302-mnc370-ka/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ka/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-kk/strings.xml b/core/res/res/values-mcc302-mnc370-kk/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-kk/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-km/strings.xml b/core/res/res/values-mcc302-mnc370-km/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-km/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ko/strings.xml b/core/res/res/values-mcc302-mnc370-ko/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ko/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ky/strings.xml b/core/res/res/values-mcc302-mnc370-ky/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ky/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-lo/strings.xml b/core/res/res/values-mcc302-mnc370-lo/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-lo/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-lt/strings.xml b/core/res/res/values-mcc302-mnc370-lt/strings.xml
new file mode 100644
index 0000000..95746fb
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-lt/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"„%s“ „Wi-Fi“"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-lv/strings.xml b/core/res/res/values-mcc302-mnc370-lv/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-lv/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-mk/strings.xml b/core/res/res/values-mcc302-mnc370-mk/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-mk/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ml/strings.xml b/core/res/res/values-mcc302-mnc370-ml/strings.xml
new file mode 100644
index 0000000..810b72c
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ml/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s വൈഫൈ"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-mn/strings.xml b/core/res/res/values-mcc302-mnc370-mn/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-mn/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-mr/strings.xml b/core/res/res/values-mcc302-mnc370-mr/strings.xml
new file mode 100644
index 0000000..4b03333
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-mr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s वाय-फाय"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ms/strings.xml b/core/res/res/values-mcc302-mnc370-ms/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ms/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-my/strings.xml b/core/res/res/values-mcc302-mnc370-my/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-my/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-nb/strings.xml b/core/res/res/values-mcc302-mnc370-nb/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-nb/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-nl/strings.xml b/core/res/res/values-mcc302-mnc370-nl/strings.xml
new file mode 100644
index 0000000..0366335
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-nl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wifi via %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-pl/strings.xml b/core/res/res/values-mcc302-mnc370-pl/strings.xml
new file mode 100644
index 0000000..f359c03
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-pl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi – %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-pt-rBR/strings.xml b/core/res/res/values-mcc302-mnc370-pt-rBR/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-pt-rBR/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-pt-rPT/strings.xml b/core/res/res/values-mcc302-mnc370-pt-rPT/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-pt-rPT/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-pt/strings.xml b/core/res/res/values-mcc302-mnc370-pt/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-pt/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ro/strings.xml b/core/res/res/values-mcc302-mnc370-ro/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ro/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ru/strings.xml b/core/res/res/values-mcc302-mnc370-ru/strings.xml
new file mode 100644
index 0000000..5fdf802
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ru/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Сеть Wi-Fi \"%s\""</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-si/strings.xml b/core/res/res/values-mcc302-mnc370-si/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-si/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-sk/strings.xml b/core/res/res/values-mcc302-mnc370-sk/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-sk/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-sl/strings.xml b/core/res/res/values-mcc302-mnc370-sl/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-sl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-sq/strings.xml b/core/res/res/values-mcc302-mnc370-sq/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-sq/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-sr/strings.xml b/core/res/res/values-mcc302-mnc370-sr/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-sr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-sv/strings.xml b/core/res/res/values-mcc302-mnc370-sv/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-sv/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-sw/strings.xml b/core/res/res/values-mcc302-mnc370-sw/strings.xml
new file mode 100644
index 0000000..8c1c887
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-sw/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi ya %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ta/strings.xml b/core/res/res/values-mcc302-mnc370-ta/strings.xml
new file mode 100644
index 0000000..5807593
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ta/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s வைஃபை"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-te/strings.xml b/core/res/res/values-mcc302-mnc370-te/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-te/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-th/strings.xml b/core/res/res/values-mcc302-mnc370-th/strings.xml
new file mode 100644
index 0000000..fa5ff47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-th/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi ของ %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-tl/strings.xml b/core/res/res/values-mcc302-mnc370-tl/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-tl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-tr/strings.xml b/core/res/res/values-mcc302-mnc370-tr/strings.xml
new file mode 100644
index 0000000..2f9ff04
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-tr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s kablosuz"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-uk/strings.xml b/core/res/res/values-mcc302-mnc370-uk/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-uk/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-uz/strings.xml b/core/res/res/values-mcc302-mnc370-uz/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-uz/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-vi/strings.xml b/core/res/res/values-mcc302-mnc370-vi/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-vi/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-zh-rCN/strings.xml b/core/res/res/values-mcc302-mnc370-zh-rCN/strings.xml
new file mode 100644
index 0000000..a89f6a2
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-zh-rCN/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s WLAN"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-zh-rHK/strings.xml b/core/res/res/values-mcc302-mnc370-zh-rHK/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-zh-rHK/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-zh-rTW/strings.xml b/core/res/res/values-mcc302-mnc370-zh-rTW/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-zh-rTW/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-zu/strings.xml b/core/res/res/values-mcc302-mnc370-zu/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-zu/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370/strings.xml b/core/res/res/values-mcc302-mnc370/strings.xml
new file mode 100644
index 0000000..f5b8496
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Template for showing mobile network operator name while WFC is active -->
+    <string-array name="wfcSpnFormats">
+        <item>%s</item>
+        <item>%s Wi-Fi</item>
+    </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-af/strings.xml b/core/res/res/values-mcc302-mnc720-af/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-af/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-am/strings.xml b/core/res/res/values-mcc302-mnc720-am/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-am/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ar/strings.xml b/core/res/res/values-mcc302-mnc720-ar/strings.xml
new file mode 100644
index 0000000..869678f
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ar/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"‏%s مع Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-az/strings.xml b/core/res/res/values-mcc302-mnc720-az/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-az/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-b+sr+Latn/strings.xml b/core/res/res/values-mcc302-mnc720-b+sr+Latn/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-b+sr+Latn/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-be/strings.xml b/core/res/res/values-mcc302-mnc720-be/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-be/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-bg/strings.xml b/core/res/res/values-mcc302-mnc720-bg/strings.xml
new file mode 100644
index 0000000..890f19b
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-bg/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi от %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-bs/strings.xml b/core/res/res/values-mcc302-mnc720-bs/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-bs/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ca/strings.xml b/core/res/res/values-mcc302-mnc720-ca/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ca/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-cs/strings.xml b/core/res/res/values-mcc302-mnc720-cs/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-cs/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-da/strings.xml b/core/res/res/values-mcc302-mnc720-da/strings.xml
new file mode 100644
index 0000000..483dee5
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-da/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi fra %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-de/strings.xml b/core/res/res/values-mcc302-mnc720-de/strings.xml
new file mode 100644
index 0000000..825fa00
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-de/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"WLAN: %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-el/strings.xml b/core/res/res/values-mcc302-mnc720-el/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-el/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-en-rAU/strings.xml b/core/res/res/values-mcc302-mnc720-en-rAU/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-en-rAU/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-en-rGB/strings.xml b/core/res/res/values-mcc302-mnc720-en-rGB/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-en-rGB/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-en-rIN/strings.xml b/core/res/res/values-mcc302-mnc720-en-rIN/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-en-rIN/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-es-rUS/strings.xml b/core/res/res/values-mcc302-mnc720-es-rUS/strings.xml
new file mode 100644
index 0000000..c8c4c5e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-es-rUS/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi de %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-es/strings.xml b/core/res/res/values-mcc302-mnc720-es/strings.xml
new file mode 100644
index 0000000..c8c4c5e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-es/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi de %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-et/strings.xml b/core/res/res/values-mcc302-mnc720-et/strings.xml
new file mode 100644
index 0000000..3e5a7ef
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-et/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s WiFi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-eu/strings.xml b/core/res/res/values-mcc302-mnc720-eu/strings.xml
new file mode 100644
index 0000000..802df65
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-eu/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi sarea"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-fa/strings.xml b/core/res/res/values-mcc302-mnc720-fa/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-fa/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-fi/strings.xml b/core/res/res/values-mcc302-mnc720-fi/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-fi/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-fr-rCA/strings.xml b/core/res/res/values-mcc302-mnc720-fr-rCA/strings.xml
new file mode 100644
index 0000000..c8c4c5e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-fr-rCA/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi de %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-fr/strings.xml b/core/res/res/values-mcc302-mnc720-fr/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-fr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-gl/strings.xml b/core/res/res/values-mcc302-mnc720-gl/strings.xml
new file mode 100644
index 0000000..d3a9055
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-gl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wifi de %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-hi/strings.xml b/core/res/res/values-mcc302-mnc720-hi/strings.xml
new file mode 100644
index 0000000..9a10eed
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-hi/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s वाई-फ़ाई"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-hr/strings.xml b/core/res/res/values-mcc302-mnc720-hr/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-hr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-hu/strings.xml b/core/res/res/values-mcc302-mnc720-hu/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-hu/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-hy/strings.xml b/core/res/res/values-mcc302-mnc720-hy/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-hy/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-in/strings.xml b/core/res/res/values-mcc302-mnc720-in/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-in/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-is/strings.xml b/core/res/res/values-mcc302-mnc720-is/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-is/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-it/strings.xml b/core/res/res/values-mcc302-mnc720-it/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-it/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-iw/strings.xml b/core/res/res/values-mcc302-mnc720-iw/strings.xml
new file mode 100644
index 0000000..d0a799f
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-iw/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"‎%s‎"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ja/strings.xml b/core/res/res/values-mcc302-mnc720-ja/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ja/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ka/strings.xml b/core/res/res/values-mcc302-mnc720-ka/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ka/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-kk/strings.xml b/core/res/res/values-mcc302-mnc720-kk/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-kk/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-km/strings.xml b/core/res/res/values-mcc302-mnc720-km/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-km/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ko/strings.xml b/core/res/res/values-mcc302-mnc720-ko/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ko/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ky/strings.xml b/core/res/res/values-mcc302-mnc720-ky/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ky/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-lo/strings.xml b/core/res/res/values-mcc302-mnc720-lo/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-lo/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-lt/strings.xml b/core/res/res/values-mcc302-mnc720-lt/strings.xml
new file mode 100644
index 0000000..2d3b87a
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-lt/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"„%s“ „Wi-Fi“"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-lv/strings.xml b/core/res/res/values-mcc302-mnc720-lv/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-lv/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-mk/strings.xml b/core/res/res/values-mcc302-mnc720-mk/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-mk/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ml/strings.xml b/core/res/res/values-mcc302-mnc720-ml/strings.xml
new file mode 100644
index 0000000..325b5db
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ml/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s വൈഫൈ"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-mn/strings.xml b/core/res/res/values-mcc302-mnc720-mn/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-mn/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-mr/strings.xml b/core/res/res/values-mcc302-mnc720-mr/strings.xml
new file mode 100644
index 0000000..9708843
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-mr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s वाय-फाय"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ms/strings.xml b/core/res/res/values-mcc302-mnc720-ms/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ms/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-my/strings.xml b/core/res/res/values-mcc302-mnc720-my/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-my/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-nb/strings.xml b/core/res/res/values-mcc302-mnc720-nb/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-nb/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-nl/strings.xml b/core/res/res/values-mcc302-mnc720-nl/strings.xml
new file mode 100644
index 0000000..4c5cadd
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-nl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wifi via %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-pl/strings.xml b/core/res/res/values-mcc302-mnc720-pl/strings.xml
new file mode 100644
index 0000000..4e78857
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-pl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi – %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-pt-rBR/strings.xml b/core/res/res/values-mcc302-mnc720-pt-rBR/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-pt-rBR/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-pt-rPT/strings.xml b/core/res/res/values-mcc302-mnc720-pt-rPT/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-pt-rPT/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-pt/strings.xml b/core/res/res/values-mcc302-mnc720-pt/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-pt/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ro/strings.xml b/core/res/res/values-mcc302-mnc720-ro/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ro/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ru/strings.xml b/core/res/res/values-mcc302-mnc720-ru/strings.xml
new file mode 100644
index 0000000..b88013b
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ru/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Сеть Wi-Fi \"%s\""</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-si/strings.xml b/core/res/res/values-mcc302-mnc720-si/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-si/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-sk/strings.xml b/core/res/res/values-mcc302-mnc720-sk/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-sk/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-sl/strings.xml b/core/res/res/values-mcc302-mnc720-sl/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-sl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-sq/strings.xml b/core/res/res/values-mcc302-mnc720-sq/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-sq/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-sr/strings.xml b/core/res/res/values-mcc302-mnc720-sr/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-sr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-sv/strings.xml b/core/res/res/values-mcc302-mnc720-sv/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-sv/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-sw/strings.xml b/core/res/res/values-mcc302-mnc720-sw/strings.xml
new file mode 100644
index 0000000..ee780df
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-sw/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi ya %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ta/strings.xml b/core/res/res/values-mcc302-mnc720-ta/strings.xml
new file mode 100644
index 0000000..61c8b84
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ta/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s வைஃபை"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-te/strings.xml b/core/res/res/values-mcc302-mnc720-te/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-te/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-th/strings.xml b/core/res/res/values-mcc302-mnc720-th/strings.xml
new file mode 100644
index 0000000..d536f45
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-th/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi ของ %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-tl/strings.xml b/core/res/res/values-mcc302-mnc720-tl/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-tl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-tr/strings.xml b/core/res/res/values-mcc302-mnc720-tr/strings.xml
new file mode 100644
index 0000000..e41287a
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-tr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s kablosuz"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-uk/strings.xml b/core/res/res/values-mcc302-mnc720-uk/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-uk/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-uz/strings.xml b/core/res/res/values-mcc302-mnc720-uz/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-uz/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-vi/strings.xml b/core/res/res/values-mcc302-mnc720-vi/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-vi/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-zh-rCN/strings.xml b/core/res/res/values-mcc302-mnc720-zh-rCN/strings.xml
new file mode 100644
index 0000000..c5526b2
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-zh-rCN/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s WLAN"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-zh-rHK/strings.xml b/core/res/res/values-mcc302-mnc720-zh-rHK/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-zh-rHK/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-zh-rTW/strings.xml b/core/res/res/values-mcc302-mnc720-zh-rTW/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-zh-rTW/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-zu/strings.xml b/core/res/res/values-mcc302-mnc720-zu/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-zu/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source 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-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720/strings.xml b/core/res/res/values-mcc302-mnc720/strings.xml
new file mode 100644
index 0000000..f5b8496
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Template for showing mobile network operator name while WFC is active -->
+    <string-array name="wfcSpnFormats">
+        <item>%s</item>
+        <item>%s Wi-Fi</item>
+    </string-array>
+</resources>
diff --git a/core/res/res/values-mcc404/config.xml b/core/res/res/values-mcc404/config.xml
index 6b77e9c..4cadef7 100644
--- a/core/res/res/values-mcc404/config.xml
+++ b/core/res/res/values-mcc404/config.xml
@@ -20,4 +20,6 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <!-- Whether camera shutter sound is forced or not  (country specific). -->
     <bool name="config_camera_sound_forced">true</bool>
+    <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app -->
+    <bool name="config_showAreaUpdateInfoSettings">true</bool>
 </resources>
diff --git a/core/res/res/values-mcc724/config.xml b/core/res/res/values-mcc724/config.xml
new file mode 100644
index 0000000..98f70d5
--- /dev/null
+++ b/core/res/res/values-mcc724/config.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app -->
+    <bool name="config_showAreaUpdateInfoSettings">true</bool>
+</resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 45339c5..9ffc7ad 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"ТБ"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"ПБ"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> дена"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> ден <xliff:g id="HOURS">%2$d</xliff:g> ч."</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> ден <xliff:g id="HOURS">%2$d</xliff:g> ч."</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> ч."</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ч. <xliff:g id="MINUTES">%2$d</xliff:g> мин."</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> ч. <xliff:g id="MINUTES">%2$d</xliff:g> мин."</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> мин."</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> мин."</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> мин. <xliff:g id="SECONDS">%2$d</xliff:g> с."</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> мин. <xliff:g id="SECONDS">%2$d</xliff:g> с."</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> сек."</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> сек."</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Без наслов&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Нема телефонски број)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Непознато"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Нема услуга за говорни/итни повици"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Привремено не се нуди од мобилната мрежа на вашата локација"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Не може да се дојде до мрежата"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"За подобрување на приемот, обидете се да го промените избраниот тип во: Систем &gt; Мрежа и интернет &gt; Мобилни мрежи &gt; Претпочитан тип мрежа."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"За подобрување на приемот, обидете се да го промените избраниот тип во „Поставки &gt; Мрежа и интернет &gt; Мобилни мрежи &gt; Претпочитан тип мрежа“."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Предупредувања"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Проследување повик"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Режим на итен повратен повик"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Пребарување за услуга"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Повикување преку Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"За повикување и испраќање пораки преку Wi-Fi, прво побарајте од операторот да ви ја постави оваа услуга. Потоа повторно вклучете повикување преку Wi-Fi во Поставки."</item>
+    <item msgid="3910386316304772394">"За да воспоставувате повици и да испраќате пораки преку Wi-Fi, прво побарајте од операторот да ја постави услугава. Потоа, вклучете ја повторно „Повикување преку Wi-Fi“ во „Поставки“. (Код за грешка: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Регистрирајте се со операторот"</item>
@@ -1041,7 +1029,7 @@
     <string name="anr_application_process" msgid="6417199034861140083">"<xliff:g id="APPLICATION">%1$s</xliff:g> не реагира"</string>
     <string name="anr_process" msgid="6156880875555921105">"Процесот <xliff:g id="PROCESS">%1$s</xliff:g> не реагира"</string>
     <string name="force_close" msgid="8346072094521265605">"Во ред"</string>
-    <string name="report" msgid="4060218260984795706">"Извештај"</string>
+    <string name="report" msgid="4060218260984795706">"Пријави"</string>
     <string name="wait" msgid="7147118217226317732">"Почекај"</string>
     <string name="webpage_unresponsive" msgid="3272758351138122503">"Страницата не реагира.\n\nДали сакате да ја затворите?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Пренасочена апликација"</string>
@@ -1106,6 +1094,13 @@
       <item quantity="one">Отворени Wi-Fi мрежи се достапни</item>
       <item quantity="other">Отворени Wi-Fi мрежи се достапни</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Поврзете се на отворена Wi‑Fi-мрежа"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Поврзување на отворена Wi‑Fi-мрежа"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Се поврзавте на Wi‑Fi-мрежа"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Не можеше да се поврзе на Wi‑Fi-мрежа"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Допрете за да ги видите сите мрежи"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Поврзете се"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Сите мрежи"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Најавете се на мрежа на Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Најавете се на мрежа"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 1641534..cc19ec6 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> ദിവസം"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> ദിവസം <xliff:g id="HOURS">%2$d</xliff:g> മണിക്കൂർ"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> ദിവസം <xliff:g id="HOURS">%2$d</xliff:g> മണിക്കൂർ"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> മണിക്കൂർ"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> മണിക്കൂർ <xliff:g id="MINUTES">%2$d</xliff:g> മിനിറ്റ്"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> മണിക്കൂർ <xliff:g id="MINUTES">%2$d</xliff:g> മിനിറ്റ്"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> മിനിറ്റ്"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> മി."</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> മിനിറ്റ് <xliff:g id="SECONDS">%2$d</xliff:g> സെക്കൻഡ്"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> മിനിറ്റ് <xliff:g id="SECONDS">%2$d</xliff:g> സെക്കൻഡ്"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> സെക്കൻഡ്"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> സെക്കൻഡ്"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;ശീർഷകമില്ലാത്ത&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(ഫോൺ നമ്പറില്ല)"</string>
     <string name="unknownName" msgid="6867811765370350269">"അജ്ഞാതം"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"വോയ്സ്/അടിയന്തിര സേവനമില്ല"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"നിങ്ങളുടെ ലൊക്കേഷനിൽ മൊബൈൽ നെറ്റ്‌വര്‍ക്ക് താൽക്കാലികമായി ലഭ്യമല്ല"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"നെറ്റ്‌വർക്കിലേക്ക് കണക്റ്റുചെയ്യാനാവുന്നില്ല"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"സ്വീകരണം മെച്ചപ്പെടുത്തുന്നതിന് സിസ്റ്റം &gt; നെറ്റ്‌വർക്കും ഇന്റർനെറ്റും &gt; മൊബൈൽ നെറ്റ്‌വർക്കുകൾ &gt; തിരഞ്ഞെടുത്ത നെറ്റ്‌വർക്ക് തരം എന്നതിൽ തിരഞ്ഞെടുത്തിരിക്കുന്ന തരം മാറ്റിക്കൊണ്ട് ശ്രമിച്ചുനോക്കുക."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"സ്വീകരണം മെച്ചപ്പെടുത്തുന്നതിന് സിസ്‌റ്റം &gt; നെറ്റ്‌വർക്കും ഇ‌ന്റെർനെറ്റും &gt; മൊബൈൽ നെറ്റ്‌വർക്കുകൾ &gt; തിരഞ്ഞെടുത്ത നെറ്റ്‌വർക്ക് തരം എന്നതിൽ തിരഞ്ഞെടുത്തിരിക്കുന്ന തരം മാറ്റിക്കൊണ്ട് ശ്രമിച്ചുനോക്കുക."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"അലേർട്ടുകൾ"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"കോൾ ഫോർവേഡിംഗ്"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"അടിയന്തര കോൾബാക്ക് മോഡ്"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"സേവനത്തിനായി തിരയുന്നു"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"വൈഫൈ കോളിംഗ്"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"വൈഫൈ വഴി കോളുകൾ വിളിക്കാനും സന്ദേശങ്ങൾ അയയ്‌ക്കാനും ആദ്യം നിങ്ങളുടെ കാരിയറോട് ഈ സേവനം സജ്ജമാക്കാൻ ആവശ്യപ്പെടുക. ക്രമീകരണത്തിൽ നിന്ന് വീണ്ടും വൈഫൈ കോളിംഗ് ഓണാക്കുക."</item>
+    <item msgid="3910386316304772394">"വൈഫൈ വഴി കോളുകൾ ചെയ്യാനും സന്ദേശങ്ങൾ അയയ്‌ക്കാനും ആദ്യം നിങ്ങളുടെ കാരിയറോട് ഈ സേവനം സജ്ജമാക്കാൻ ആവശ്യപ്പെടുക. ക്രമീകരണത്തിൽ നിന്ന് വീണ്ടും വൈഫൈ കോളിംഗ് ഓണാക്കുക. (പിശക് കോഡ്: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"നിങ്ങളുടെ കാരിയറിൽ രജിസ്റ്റർ ചെയ്യുക"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">ലഭ്യമായ വൈഫൈ നെറ്റ്‌വർക്കുകൾ തുറക്കുക</item>
       <item quantity="one">ലഭ്യമായ വൈഫൈ നെറ്റ്‌വർക്ക് തുറക്കുക</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"ലഭ്യമായ വൈഫൈ നെറ്റ്‌വർക്കിലേക്ക് കണക്റ്റുചെയ്യുക"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"ലഭ്യമായ വൈഫൈ നെറ്റ്‌വർക്കിലേക്ക് കണക്റ്റുചെയ്യുന്നു"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"വൈഫൈ നെറ്റ്‌വർക്കിലേക്ക് കണക്റ്റു‌ചെയ്‌‌തു"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"വൈ-ഫൈ നെറ്റ്‌വർക്കിലേക്ക് കണക്‌റ്റുചെയ്യാനായില്ല"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"എല്ലാ നെറ്റ്‌വർക്കുകളും കാണാൻ ടാപ്പുചെയ്യുക"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"കണക്റ്റുചെയ്യുക"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"എല്ലാ നെറ്റ്‌വർക്കുകളും"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"വൈഫൈ നെറ്റ്‌വർക്കിലേക്ക് സൈൻ ഇൻ ചെയ്യുക"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"നെറ്റ്‌വർക്കിലേക്ക് സൈൻ ഇൻ ചെയ്യുക"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index ae3d21c..a2b08e0 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TБ"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"ПБ"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> өдөр"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> өдөр <xliff:g id="HOURS">%2$d</xliff:g> цаг"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> өдөр <xliff:g id="HOURS">%2$d</xliff:g> цаг"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> цаг"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> цаг <xliff:g id="MINUTES">%2$d</xliff:g> минут"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> цаг <xliff:g id="MINUTES">%2$d</xliff:g> мин"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> мин"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> минут"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> мин <xliff:g id="SECONDS">%2$d</xliff:g> секунд"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> мин <xliff:g id="SECONDS">%2$d</xliff:g> сек"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> сек"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> сек"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Гарчиггүй&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Утасны дугаар байхгүй)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Тодорхойгүй"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Дуу хоолой/яаралтай үйлчилгээ алга"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Таны байршилд таны мобайл сүлжээнээс түр хугацаанд блоклосон"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Сүлжээнд холбогдох боломжгүй байна"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Хүлээн авалтыг сайжруулахын тулд систем, сүлжээ, интернэт, мобайл сүлжээнд сонгосон сүлжээний төрлийг өөрчилнө үү."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Хүлээн авалтыг сайжруулахын тулд Тохиргоо &gt; Сүлжээ &amp; Интернэт &gt; Мобайл сүлжээ &gt; Сонгосон сүлжээний төрөл хэсгийг сонгон төрлөө өөрчилнө үү."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Сануулга"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Дуудлага шилжүүлэх"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Яаралтай дуудлага хийх горим"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Үйлчилгээг хайж байна…"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi Calling"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi-аар дуудлага хийх болон мессеж илгээхээр бол эхлээд оператороосоо энэ төхөөрөмжийг тохируулж өгөхийг хүсээрэй. Дараа нь Тохиргооноос Wi-Fi дуудлага хийх үйлдлийг асаагаарай."</item>
+    <item msgid="3910386316304772394">"Wi-Fi-аар дуудлага хийх, мессеж илгээх бол эхлээд оператор компаниасаа энэ үйлчилгээг тохируулж өгөхийг хүснэ үү. Дараа нь Тохиргооноос Wi-Fi дуудлага хийх үйлдлийг асаана уу. (Алдааны код: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Операторт бүртгүүлэх"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">Нээлттэй Wi-Fi сүлжээ ашиглах боломжтой</item>
       <item quantity="one">Нээлттэй Wi-Fi сүлжээ ашиглах боломжтой</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Нээлттэй Wi‑Fi сүлжээнд холбогдох"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Нээлттэй Wi‑Fi сүлжээнд холбогдож байна"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi сүлжээнд холбогдлоо"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi сүлжээнд холбогдож чадсангүй"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Бүх сүлжээг харахын тулд товшино уу"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Холбогдох"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Бүх сүлжээ"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi сүлжээнд нэвтэрнэ үү"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Сүлжээнд нэвтэрнэ үү"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 41b6350..12026d8 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> दिवस"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> दिवस <xliff:g id="HOURS">%2$d</xliff:g> तास"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> दिवस <xliff:g id="HOURS">%2$d</xliff:g> तास"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> तास"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ता <xliff:g id="MINUTES">%2$d</xliff:g> मि"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> ता <xliff:g id="MINUTES">%2$d</xliff:g> मि"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> मिनिटे"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> मिनिट"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> मि <xliff:g id="SECONDS">%2$d</xliff:g> से"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> मि <xliff:g id="SECONDS">%2$d</xliff:g> से"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> सेकंद"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> सेकंद"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;अशीर्षकांकित&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(कोणताही फोन नंबर नाही)"</string>
     <string name="unknownName" msgid="6867811765370350269">"अज्ञात"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"व्हॉइस/आणीबाणी सेवा नाही"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"तुम्‍ही असलेल्‍या स्‍थानी मोबाइल नेटवर्क तात्‍पुरते उपलब्‍ध नाही"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"नेटवर्कवर पोहोचूू शकत नाही"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"रिसेप्शन सुधारण्यासाठी प्रणाली &gt; नेटवर्क आणि इंटरनेट &gt; मोबाइल नेटवर्क &gt; प्राधान्य दिलेला नेटवर्क प्रकार येथे निवडलेला प्रकार बदलून पहा."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"रिसेप्शन सुधारण्यासाठी, सोटिंग्ज &gt; नेटवर्क आणि इंटरनेट &gt; मोबाइल नेटवर्क &gt; प्राधान्य दिलेला नेटवर्क प्रकार बदलून पहा."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"अलर्ट"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"कॉल फॉरवर्डिंग"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"इमर्जन्सी कॉलबॅक मोड"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"सेवा शोधत आहे"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"वाय-फाय कॉलिंग"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"वाय-फायवरून कॉल करण्यासाठी आणि संदेश पाठविण्यासाठी, प्रथम आपल्या वाहकास ही सेवा सेट करण्यास सांगा. नंतर सेटिंग्जमधून पुन्हा वाय-फाय कॉलिंग चालू करा."</item>
+    <item msgid="3910386316304772394">"वाय-फायवरून कॉल करण्यासाठी आणि संदेश पाठवण्यासाठी आधी तुमच्या कॅरियरला ही सेवा सेट अप करण्यास सांगा. नंतर सेटिंग्जमधून वाय-फाय वापरून कॉल करणे पुन्हा चालू करा. (एरर कोड <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"आपल्या वाहकासह नोंदणी करा"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="one">खुले वाय-फाय नेटवर्क उपलब्ध</item>
       <item quantity="other">खुले वाय-फाय नेटवर्क उपलब्ध</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"खुल्या वाय-फाय नेटवर्कशी कनेक्ट करा"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"खुल्या वाय-फाय नेटवर्कशी कनेक्ट करत आहे"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"वाय-फाय नेटवर्कशी कनेक्ट केले"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"वाय-फाय नेटवर्कशी कनेक्ट करू शकत नाही"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"सर्व नेटवर्क पाहण्यासाठी टॅप करा"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"कनेक्ट करा"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"सर्व नेटवर्क"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"वाय-फाय नेटवर्कमध्‍ये साइन इन करा"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"नेटवर्कवर साइन इन करा"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1780,6 +1775,5 @@
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"सिमसाठी तरतूद नाही"</string>
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"सिमला अनुमती नाही"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"फोनला अनुमती नाही"</string>
-    <!-- no translation found for popup_window_default_title (4874318849712115433) -->
-    <skip />
+    <string name="popup_window_default_title" msgid="4874318849712115433">"पॉपअप विंडो"</string>
 </resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 762eaa1..bd7e6ac 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> hari"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> hari <xliff:g id="HOURS">%2$d</xliff:g> jam"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> hari <xliff:g id="HOURS">%2$d</xliff:g> jam"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> jam"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> jam <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> jam <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> minit"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> minit"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> saat"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> saat"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> saat"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> saat"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Tidak bertajuk&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Tiada nombor telefon)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Tidak diketahui"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Tiada perkhidmatan suara/kecemasan"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Tidak ditawarkan oleh rangkaian mudah alih di lokasi anda untuk sementara waktu"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Tidak dapat mencapai rangkaian"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Untuk memperbaik penerimaan, cuba tukar jenis rangkaian yang dipilih di Sistem &gt; Rangkaian &amp; Internet &gt; Rangkaian mudah alih &gt; Jenis rangkaian pilihan."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Untuk memperbaik penerimaan, cuba tukar jenis rangkaian yang dipilih di Tetapan &gt; Rangkaian &amp; Internet &gt; Rangkaian mudah alih &gt; Jenis rangkaian pilihan."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Makluman"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Pemajuan panggilan"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Mod paggil balik kecemasan"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Mencari Perkhidmatan"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Panggilan Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Untuk membuat panggilan dan menghantar mesej melalui Wi-Fi, mula-mula minta pembawa anda untuk menyediakan perkhidmatan ini. Kemudian hidupkan panggilan Wi-Fi semula daripada Tetapan."</item>
+    <item msgid="3910386316304772394">"Untuk membuat panggilan dan menghantar mesej melalui Wi-Fi, minta pembawa anda menyediakan perkhidmatan ini terlebih dahulu. Kemudian, hidupkan panggilan Wi-Fi sekali lagi daripada Tetapan. (Kod ralat: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Daftar dengan pembawa anda"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">Rangkaian Wi-Fi terbuka tersedia</item>
       <item quantity="one">Rangkaian Wi-Fi terbuka tersedia</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Sambung ke rangkaian Wi-Fi terbuka"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Menyambung ke rangkaian Wi‑Fi terbuka"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Disambungkan ke rangkaian Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Tidak dapat menyambung ke rangkaian Wi-Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Ketik untuk melihat semua rangkaian"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Sambung"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Semua Rangkaian"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Log masuk ke rangkaian Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Log masuk ke rangkaian"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 9b5cea9..9832137 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> ရက်"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> ရက် <xliff:g id="HOURS">%2$d</xliff:g> နာရီ"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> ရက်<xliff:g id="HOURS">%2$d</xliff:g> နာရီ"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> နာရီ"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> နာရီ <xliff:g id="MINUTES">%2$d</xliff:g> မိနစ်"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> နာရီ <xliff:g id="MINUTES">%2$d</xliff:g> မိနစ်"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> မိနစ်"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> မိနစ်"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> မိနစ် <xliff:g id="SECONDS">%2$d</xliff:g> စက္ကန့်"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> မိနစ် <xliff:g id="SECONDS">%2$d</xliff:g> စက္ကန့်"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> စက္ကန့်"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> စက္ကန့်"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;ခေါင်းစဉ်မဲ့&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(ဖုန်းနံပါတ်မရှိပါ)"</string>
     <string name="unknownName" msgid="6867811765370350269">"မသိရ"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"ဖုန်း/အရေးပေါ် ဝန်ဆောင်မှုများမရရှိနိုင်ပါ"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"သင်၏ ဒေသတွင် မိုဘိုင်းကွန်ရက် ယာယီမရရှိနိုင်ပါ"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"ကွန်ရက်ကို ချိတ်ဆက်၍မရပါ"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"လိုင်းဖမ်းယူမှု ကောင်းမွန်စေရန် စနစ် &gt; ကွန်ရက်နှင့် အင်တာနက် &gt; မိုဘိုင်းကွန်ရက်များ &gt; အသုံးပြုလိုသည့် ကွန်ရက်အမျိုးအစားတွင် ရွေးချယ်ထားသည့် အမျိုးအစားကို ပြောင်းကြည့်ပါ။"</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"လိုင်းဖမ်းယူမှု ကောင်းမွန်စေရန် ဆက်တင်များ &gt; ကွန်ရက်နှင့် အင်တာနက် &gt; မိုဘိုင်းကွန်ရက်များ &gt; အသုံးပြုလိုသည့် ကွန်ရက်အမျိုးအစားတွင် ရွေးချယ်ထားသည့် အမျိုးအစားကို ပြောင်းကြည့်ပါ။"</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"သတိပေးချက်များ"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"အဝင်ခေါ်ဆိုမှုအား ထပ်ဆင့်ပို့ခြင်း"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"အရေးပေါ် ပြန်လည်ခေါ်ဆိုနိုင်သောမုဒ်"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"ဆားဗစ်အားရှာဖွေနေသည်"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi  ခေါ်ဆိုမှု"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi သုံး၍ ဖုန်းခေါ်ဆိုရန်နှင့် မက်ဆေ့ဂျ်များပို့ရန်၊ ဤဝန်ဆောင်မှုအား စတင်သုံးနိုင်ရန်အတွက် သင့် မိုဘိုင်းဝန်ဆောင်မှုအား ဦးစွာမေးမြန်းပါ။ ထို့နောက် ဆက်တင်မှတဆင့် Wi-Fi  ခေါ်ဆိုမှုအား ထပ်ဖွင့်ပါ။"</item>
+    <item msgid="3910386316304772394">"Wi-Fi အသုံးပြု၍ ဖုန်းခေါ်ရန်နှင့် မက်ဆေ့ဂျ်ပို့ရန်အတွက် သင့်ဝန်ဆောင်မှုပေးသူကို ဤဝန်ဆောင်မှုအား သတ်မှတ်ပေးရန် ဦးစွာတောင်းဆိုပါ။ ထို့နောက် ဆက်တင်ထဲသို့ သွား၍ Wi-Fi ဖြင့် ဖုန်းခေါ်ခြင်းကို ဖွင့်ရပါမည်။ (အမှားကုဒ်- <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"သင့် မိုဘိုင်းဝန်ဆောင်မှုဖြင့် မှတ်ပုံတင်ရန်"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">Wi-Fi ကွန်ယက်များရရှိနိုင်သည်အား ဖွင့်ပါ</item>
       <item quantity="one">Wi-Fi ကွန်ယက်ရရှိနိုင်သည်အား ဖွင့်ပါ</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"အများသုံး Wi‑Fi ကွန်ရက်သို့ ချိတ်ဆက်ပါ"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"အများသုံး Wi‑Fi ကွန်ရက်သို့ ချိတ်ဆက်နေသည်"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi ကွန်ရက်သို့ ချိတ်ဆက်ပြီးပါပြီ"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi ကွန်ရက်သို့ ချိတ်ဆက်၍ မရပါ"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ကွန်ရက်အားလုံးကို ကြည့်ရန် တို့ပါ"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"ချိတ်ဆက်ရန်"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"ကွန်ရက်အားလုံး"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"ဝိုင်ဖိုင်ကွန်ရက်သို့ လက်မှတ်ထိုးဝင်ပါ"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"ကွန်ယက်သို့ လက်မှတ်ထိုးဝင်ရန်"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1780,5 +1775,5 @@
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"ဆင်းမ်ကို ထောက်ပံ့မထားပါ"</string>
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"ဆင်းမ်ကို ခွင့်မပြုပါ"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"ဖုန်းကို ခွင့်မပြုပါ"</string>
-    <string name="popup_window_default_title" msgid="4874318849712115433">"ပေါ့ပ်အပ်ဝင်းဒိုး"</string>
+    <string name="popup_window_default_title" msgid="4874318849712115433">"ပေါ့ပ်အပ် ဝင်းဒိုး"</string>
 </resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index ee644e3..7103ea9 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> dager"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> dag <xliff:g id="HOURS">%2$d</xliff:g> t"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> dag <xliff:g id="HOURS">%2$d</xliff:g> t"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> t"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> t <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> t <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> sek"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> sek"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> sek"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> sek"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Uten navn&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Mangler telefonnummer)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Ukjent"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Ingen tale-/nødtjeneste"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Tilbys midlertidig ikke gjennom mobilnettverket der du er"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Får ikke kontakt med nettverket"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"For å forbedre signalet, prøv å endre valgt nettverkstype i System &gt; Nettverk og Internett &gt; Mobilnettverk &gt; Foretrukket nettverkstype."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"For å forbedre signalet, prøv å endre valgt nettverkstype i Innstillinger &gt; Nettverk og Internett &gt; Mobilnettverk &gt; Foretrukket nettverkstype."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Varsler"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Viderekobling"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Modusen nødsamtale-tilbakeringing"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Leter etter tjeneste"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi-anrop"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"For å ringe og sende meldinger over Wi-Fi må du først be operatøren om å konfigurere denne tjenesten. Deretter slår du på Wi-Fi-anrop igjen fra Innstillinger."</item>
+    <item msgid="3910386316304772394">"For å ringe og sende meldinger over Wi-Fi må du først be operatøren om å konfigurere denne tjenesten. Deretter slår du på Wi-Fi-anrop igjen fra Innstillinger. (Feilkode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Registrer deg hos operatøren din"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">Åpne Wi-Fi-nettverk er tilgjengelig</item>
       <item quantity="one">Åpent Wi-Fi-nettverk er tilgjengelig</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Koble til et åpent Wi‑Fi-nettverk"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Kobler til åpent Wi-Fi-nettverk"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Koblet til Wi-Fi-nettverk"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Kunne ikke koble til Wi-Fi-nettverket"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Trykk for å se alle nettverkene"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Koble til"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Alle nettverk"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Logg på Wi-Fi-nettverket"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Logg på nettverk"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 68d027d..717b91f 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> दिन"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> दिन<xliff:g id="HOURS">%2$d</xliff:g> घन्टा"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> दिन<xliff:g id="HOURS">%2$d</xliff:g> घन्टा"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> घन्टा"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> घन्टा <xliff:g id="MINUTES">%2$d</xliff:g> मि"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> घन्टा <xliff:g id="MINUTES">%2$d</xliff:g> मिनेट"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> मिनेट"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> मिनेट"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> मिनेट <xliff:g id="SECONDS">%2$d</xliff:g> से"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> मिनेट <xliff:g id="SECONDS">%2$d</xliff:g> से"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> सेकेन्ड"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> सेकेन्ड"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;बिना शीर्षक&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(कुनै फोन नम्बर छैन)"</string>
     <string name="unknownName" msgid="6867811765370350269">"अज्ञात"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"कुनै पनि भ्वाइस/आपतकालीन सेवा उपलब्ध छैन"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"तपाईंको स्थानमा सञ्चालन भइरहेको मोबाइल नेटवर्कले अस्थायी रूपमा यो सुविधा प्रदान गर्दैन"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"नेटवर्कमाथि पहुँच राख्न सकिँदैन"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"रिसेप्सनमा सुधार गर्न, प्रणाली &gt; नेटवर्क र इन्टरनेट &gt; मोबाइल नेटवर्कहरू &gt; रुचाइएको नेटवर्कको प्रकार मा गएर चयन गरिएको प्रकार परिवर्तन गरी हेर्नुहोस्।"</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"रिसेप्सनमा सुधार गर्न प्रणालीहरू &gt; नेटवर्क तथा इन्टरनेट &gt; मोबाइल नेटवर्कहरू &gt; रुचाइएको नेटवर्कको प्रकारमा गई चयन गरिएको प्रकार परिवर्तन गरी हेर्नुहोस्।"</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"अलर्टहरू"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"कल फर्वार्ड गर्ने सेवा"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"आपतकालीन कलब्याक मोड"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"सेवाको खोजी गर्दै…"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi कलिङ"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi बाट कल गर्न र सन्देशहरू पठाउन, सबभन्दा पहिला यो सेवा सेटअप गर्न तपाईँको वाहकलाई भन्नुहोस्। त्यसपछि फेरि सेटिङहरूबाट Wi-Fi कलिङ सक्रिय पार्नुहोस्।"</item>
+    <item msgid="3910386316304772394">"Wi-Fi मार्फत कलहरू गर्न र सन्देशहरू पठाउन सबभन्दा पहिला आफ्नो सेवा प्रदायकलाई यो सेवा सेट गर्न भन्नुहोस्। त्यसपछि सेटिङहरूबाट Wi-Fi कलिङलाई सक्रिय पार्नुहोस्। (त्रुटिसम्बन्धी कोड: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"तपाईँको वाहकसँग दर्ता गर्नुहोस्"</item>
@@ -1112,6 +1100,13 @@
       <item quantity="other"> खुल्ला Wi-Fi सञ्जालहरू उपलब्ध छन्</item>
       <item quantity="one">खुल्ला Wi-Fi सञ्जाल उपलब्ध छ</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"खुला Wi‑Fi नेटवर्कमा जडान गर्नुहोस्"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"खुला Wi‑Fi नेटवर्कमा जडान गर्दै"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi नेटवर्कमा जडान गरियो"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi नेटवर्कमा जडान गर्न सकिएन"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"सबै नेटवर्कहरू हेर्न ट्याप गर्नुहोस्"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"जडान गर्नुहोस्"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"सबै नेटवर्कहरू"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi नेटवर्कमा साइन इन गर्नुहोस्"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"सञ्जालमा साइन इन गर्नुहोस्"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1785,6 +1780,5 @@
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM को प्रावधान छैन"</string>
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM लाई अनुमति छैन"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"फोनलाई अनुमति छैन"</string>
-    <!-- no translation found for popup_window_default_title (4874318849712115433) -->
-    <skip />
+    <string name="popup_window_default_title" msgid="4874318849712115433">"पपअप विन्डो"</string>
 </resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 5f427f4..7207255 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> dagen"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> dag <xliff:g id="HOURS">%2$d</xliff:g> uur"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> dag <xliff:g id="HOURS">%2$d</xliff:g> uur"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> uur"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> uur <xliff:g id="MINUTES">%2$d</xliff:g> min."</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> uur <xliff:g id="MINUTES">%2$d</xliff:g> min."</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> minuten"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min."</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> sec"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> sec"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> seconden"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> seconde"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Naamloos&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Geen telefoonnummer)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Onbekend"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Geen service voor spraak-/noodoproepen"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Tijdelijk niet aangeboden door het mobiele netwerk op je locatie"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Kan netwerk niet bereiken"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Als je de ontvangst wilt verbeteren, kun je het netwerktype wijzigen dat is geselecteerd bij Systeem &gt; Netwerk en internet &gt; Mobiele netwerken &gt; Voorkeursnetwerktype."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Als je de ontvangst wilt verbeteren, kun je het netwerktype wijzigen dat is geselecteerd bij Instellingen &gt; Netwerk en internet &gt; Mobiele netwerken &gt; Voorkeursnetwerktype."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Meldingen"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Oproep doorschakelen"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Modus voor noodoproepen"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Service zoeken"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Bellen via wifi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Als je wilt bellen en berichten wilt verzenden via wifi, moet je eerst je provider vragen deze service in te stellen. Schakel bellen via wifi vervolgens opnieuw in via \'Instellingen\'."</item>
+    <item msgid="3910386316304772394">"Als je wilt bellen en berichten wilt verzenden via wifi, moet je eerst je provider vragen deze service in te stellen. Schakel bellen via wifi vervolgens opnieuw in via Instellingen. (Foutcode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Registreren bij je provider"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">Open wifi-netwerken beschikbaar</item>
       <item quantity="one">Open wifi-netwerk beschikbaar</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Verbinding maken met een open wifi-netwerk"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Verbinding maken met een open wifi-netwerk…"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Verbonden met een wifi-netwerk"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Kan geen verbinding maken met het wifi-netwerk"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tik om alle netwerken te bekijken"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Verbinding maken"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Alle netwerken"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Inloggen bij wifi-netwerk"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Inloggen bij netwerk"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 5888792..c779361 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> ਦਿਨ"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> ਦਿਨ <xliff:g id="HOURS">%2$d</xliff:g> ਘੰਟੇ"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> ਦਿਨ <xliff:g id="HOURS">%2$d</xliff:g> ਘੰਟਾ"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> ਘੰਟੇ"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ਘੰਟਾ <xliff:g id="MINUTES">%2$d</xliff:g> ਮਿੰਟ"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> ਘੰਟਾ <xliff:g id="MINUTES">%2$d</xliff:g> ਮਿੰਟ"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> ਮਿੰਟ"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> ਮਿੰਟ"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> ਮਿੰਟ <xliff:g id="SECONDS">%2$d</xliff:g> ਸਕਿੰਟ"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> ਮਿੰਟ <xliff:g id="SECONDS">%2$d</xliff:g> ਸਕਿੰਟ"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> ਸਕਿੰਟ"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> ਸਕਿੰਟ"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;ਬਿਨਾਂ ਸਿਰਲੇਖ&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(ਕੋਈ ਫ਼ੋਨ ਨੰਬਰ ਨਹੀਂ)"</string>
     <string name="unknownName" msgid="6867811765370350269">"ਅਗਿਆਤ"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"ਕੋਈ ਆਵਾਜ਼ੀ/ਸੰਕਟਕਾਲੀਨ ਸੇਵਾ ਨਹੀਂ"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"ਤੁਹਾਡੇ ਟਿਕਾਣੇ \'ਤੇ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਮੋਬਾਈਲ ਨੈੱਟਵਰਕ ਵੱਲੋਂ ਉਪਲਬਧ ਨਹੀਂ ਕਰਵਾਈ ਗਈ"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"ਨੈੱਟਵਰਕ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"ਸਿਗਨਲ ਪ੍ਰਾਪਤੀ ਨੂੰ ਬਿਹਤਰ ਬਣਾਉਣ ਲਈ, ਸਿਸਟਮ &gt; ਨੈੱਟਵਰਕ ਅਤੇ ਇੰਟਰਨੈੱਟ &gt; ਮੋਬਾਈਲ ਨੈੱਟਵਰਕ &gt; ਤਰਜੀਹੀ ਨੈੱਟਵਰਕ ਦੀ ਕਿਸਮ \'ਤੇ ਚੁਣੀ ਗਈ ਕਿਸਮ ਨੂੰ ਬਦਲਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"ਸਿਗਨਲ ਪ੍ਰਾਪਤੀ ਨੂੰ ਬਿਹਤਰ ਬਣਾਉਣ ਲਈ, ਸੈਟਿੰਗਾਂ &gt; ਨੈੱਟਵਰਕ ਅਤੇ ਇੰਟਰਨੈੱਟ &gt; ਮੋਬਾਈਲ ਨੈੱਟਵਰਕ &gt; ਤਰਜੀਹੀ ਨੈੱਟਵਰਕ ਦੀ ਕਿਸਮ \'ਤੇ ਚੁਣੀ ਗਈ ਕਿਸਮ ਨੂੰ ਬਦਲਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"ਸੁਚੇਤਨਾਵਾਂ"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"ਕਾਲ ਫਾਰਵਾਰਡਿੰਗ"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"ਸੰਕਟਕਾਲੀਨ ਕਾਲਬੈਕ ਮੋਡ"</string>
@@ -130,9 +118,7 @@
     <string name="roamingText12" msgid="1189071119992726320">"ਰੋਮਿੰਗ ਬੈਨਰ ਬੰਦ"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"ਸੇਵਾ ਦੀ ਖੋਜ ਕਰ ਰਿਹਾ ਹੈ"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi ਕਾਲਿੰਗ"</string>
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi ਤੇ ਕਾਲਾਂ ਕਰਨ ਅਤੇ ਸੁਨੇਹੇ ਭੇਜਣ ਲਈ, ਪਹਿਲਾਂ ਆਪਣੇ ਕੈਰੀਅਰ ਨੂੰ ਇਹ ਸੇਵਾ ਸੈਟ ਅਪ ਕਰਨ ਲਈ ਕਹੋ। ਫਿਰ ਸੈਟਿੰਗਾਂ ਵਿੱਚੋਂ Wi-Fi ਕਾਲਿੰਗ ਦੁਬਾਰਾ ਚਾਲੂ ਕਰੋ।"</item>
-  </string-array>
+    <!-- no translation found for wfcOperatorErrorAlertMessages:0 (3910386316304772394) -->
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"ਆਪਣੇ ਕੈਰੀਅਰ ਨਾਲ ਰਜਿਸਟਰ ਕਰੋ"</item>
   </string-array>
@@ -1106,6 +1092,13 @@
       <item quantity="one">ਉਪਲਬਧ Wi-Fi ਨੈੱਟਵਰਕ ਖੋਲ੍ਹੋ</item>
       <item quantity="other">ਉਪਲਬਧ Wi-Fi ਨੈੱਟਵਰਕ ਖੋਲ੍ਹੋ</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"ਖੁੱਲ੍ਹੇ Wi‑Fi ਨੈੱਟਵਰਕ ਨਾਲ ਕਨੈਕਟ ਹੋਵੋ"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"ਖੁੱਲ੍ਹੇ Wi‑Fi ਨੈੱਟਵਰਕ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi ਨੈੱਟਵਰਕ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi ਨੈੱਟਵਰਕ ਨਾਲ ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ਸਾਰੇ ਨੈੱਟਵਰਕਾਂ ਨੂੰ ਦੇਖਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"ਕਨੈਕਟ ਕਰੋ"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"ਸਾਰੇ ਨੈੱਟਵਰਕ"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi ਨੈੱਟਵਰਕ ਵਿੱਚ ਸਾਈਨ ਇਨ ਕਰੋ"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"ਨੈੱਟਵਰਕ ਤੇ ਸਾਈਨ ਇਨ ਕਰੋ"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1780,6 +1773,5 @@
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM ਦੀ ਵਿਵਸਥਾ ਨਹੀਂ ਹੈ"</string>
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"ਫ਼ੋਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ"</string>
-    <!-- no translation found for popup_window_default_title (4874318849712115433) -->
-    <skip />
+    <string name="popup_window_default_title" msgid="4874318849712115433">"ਪੌਪਅੱਪ ਵਿੰਡੋ"</string>
 </resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 2edd371..e36eaf3 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> dni"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> dzień <xliff:g id="HOURS">%2$d</xliff:g> godz."</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> dzień <xliff:g id="HOURS">%2$d</xliff:g> godz."</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> godz."</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> godz. <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> godz. <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Bez nazwy&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Brak numeru telefonu)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Nieznana"</string>
@@ -97,7 +85,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Brak usługi połączeń głosowych/alarmowych"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Usługa tymczasowo nieoferowana przez sieć komórkową w Twojej lokalizacji"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Brak zasięgu sieci"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Aby poprawić odbiór, zmień typ sieci – wybierz System &gt; Sieć i internet &gt; Sieci komórkowe &gt; Preferowany typ sieci."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Aby poprawić odbiór, zmień typ sieci: wybierz Ustawienia &gt; Sieć i internet &gt; Sieci komórkowe &gt; Preferowany typ sieci."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Alerty"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Przekierowanie połączeń"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Tryb alarmowego połączenia zwrotnego"</string>
@@ -133,7 +121,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Wyszukiwanie usługi"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Połączenia przez Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Aby dzwonić i wysyłać wiadomości przez Wi-Fi, poproś swojego operatora o skonfigurowanie tej usługi. Potem ponownie włącz połączenia przez Wi-Fi w Ustawieniach."</item>
+    <item msgid="3910386316304772394">"Aby dzwonić i wysyłać wiadomości przez Wi-Fi, poproś swojego operatora o skonfigurowanie tej usługi. Potem ponownie włącz połączenia przez Wi-Fi w Ustawieniach. (Kod błędu: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Zarejestruj u operatora"</item>
@@ -1150,6 +1138,13 @@
       <item quantity="other">Dostępne są otwarte sieci Wi-Fi</item>
       <item quantity="one">Dostępna jest otwarta sieć Wi-Fi</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Połącz się z otwartą siecią Wi-Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Łączę się z otwartą siecią Wi-Fi"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Połączono z siecią Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Nie udało się połączyć z siecią Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Kliknij, by zobaczyć wszystkie sieci"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Połącz"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Wszystkie sieci"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Zaloguj się w sieci Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Zaloguj się do sieci"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 4e62130..acaafd6 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> dias"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> dia <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> dia <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> h"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> m"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Sem título&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Nenhum número de telefone)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Desconhecido"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Sem serviço de voz/emergência"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Serviço temporariamente bloqueado pela rede móvel no seu local"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Não foi possível acessar a rede"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Para melhorar a recepção, tente alterar o tipo selecionado em Sistema &gt; Rede &amp; Internet &gt; Redes móveis &gt; Tipo de rede preferencial."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Para melhorar a recepção, tente alterar o tipo selecionado em Configurações &gt; Rede &amp; Internet &gt; Redes móveis &gt; Tipo de rede preferencial."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Alertas"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Encaminhamento de chamada"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Modo de retorno de chamada de emergência"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Pesquisando serviço"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Chamadas por Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Para fazer chamadas e enviar mensagens por Wi-Fi, primeiro peça à sua operadora para configurar esse serviço. Depois ative novamente as chamadas por Wi-Fi nas configurações."</item>
+    <item msgid="3910386316304772394">"Para fazer chamadas e enviar mensagens por Wi-Fi, primeiro peça à sua operadora para configurar esse serviço. Depois, ative novamente a chamada no Wi-Fi nas configurações. Código de erro: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Faça registro na sua operadora"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="one">Abrir redes Wi-Fi disponíveis</item>
       <item quantity="other">Abrir redes Wi-Fi disponíveis</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Conectar-se a uma rede Wi‑Fi aberta"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Conectando-se a uma rede Wi‑Fi aberta"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Conectado a uma rede Wi‑Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Não foi possível conectar-se à rede Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toque para ver todas as redes"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectar"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Todas as redes"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Fazer login na rede Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Fazer login na rede"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1623,7 +1618,7 @@
     <string name="package_installed_device_owner" msgid="6875717669960212648">"Instalado pelo seu administrador"</string>
     <string name="package_updated_device_owner" msgid="1847154566357862089">"Atualizado pelo seu administrador"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"Excluído pelo seu administrador"</string>
-    <string name="battery_saver_description" msgid="1960431123816253034">"A economia de bateria reduz o desempenho e os limites de vibração do dispositivo, os serviços de localização e a maioria dos dados em segundo plano para aumentar a duração da bateria. E-mails, mensagens e outros aplicativos que dependem de sincronização não serão atualizados, a não ser que você os abra.\n\nA economia de bateria é desligada automaticamente quando o dispositivo está sendo carregado."</string>
+    <string name="battery_saver_description" msgid="1960431123816253034">"A economia de bateria reduz o desempenho do dispositivo e limita a vibração, os serviços de localização e a maioria dos dados em segundo plano para aumentar a duração da bateria. E-mails, mensagens e outros apps que dependem de sincronização não serão atualizados, a não ser que você os abra.\n\nA economia de bateria é desligada automaticamente quando o dispositivo está sendo carregado."</string>
     <string name="data_saver_description" msgid="6015391409098303235">"Para ajudar a reduzir o uso de dados, a Economia de dados impede que alguns apps enviem ou recebam dados em segundo plano. Um app que você esteja usando no momento pode acessar dados, mas com menos frequência. Isso pode significar que as imagens não serão exibidas até que você toque nelas."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"Ativar Economia de dados?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"Ativar"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 2f6e3dd..3c1011b 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> dias"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> dia <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> dia <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> horas"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min."</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> seg"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> seg"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> seg"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> seg"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Sem nome&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Nenhum número de telefone)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Desconhecido"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Sem serviço de voz/emergência"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Serviço temporariamente não disponibilizado pela rede móvel na sua localização"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Não é possível ligar à rede"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Para melhorar a receção, experimente alterar o tipo selecionado em Sistema &gt; Rede e Internet &gt; Redes móveis &gt; Tipo de rede preferido."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Para melhorar a receção, experimente alterar o tipo selecionado em Definições &gt; Rede e Internet &gt; Redes móveis &gt; Tipo de rede preferido."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Alertas"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Reencaminhamento de chamadas"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Modo de chamada de retorno de emergência"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"A procurar Serviço"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Chamadas Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Para fazer chamadas e enviar mensagens por Wi-Fi, comece por pedir ao seu operador para configurar este serviço. Em seguida, nas Definições, ative novamente as chamadas por Wi-Fi."</item>
+    <item msgid="3910386316304772394">"Para fazer chamadas e enviar mensagens por Wi-Fi, comece por pedir ao seu operador para configurar este serviço. De seguida, nas Definições, ative novamente as Chamadas Wi-Fi. (Código de erro: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Registar-se junto do seu operador"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="one">Open Wi-Fi networks available</item>
       <item quantity="other">Redes Wi-Fi abertas disponíveis</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Ligar à rede Wi-Fi aberta"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"A ligar à rede Wi-Fi aberta…"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Ligado à rede Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Não foi possível ligar à rede Wi-Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toque para ver todas as redes"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Ligar"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Todas as redes"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Iniciar sessão na rede Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Início de sessão na rede"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 4e62130..acaafd6 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> dias"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> dia <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> dia <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> h"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> m"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Sem título&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Nenhum número de telefone)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Desconhecido"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Sem serviço de voz/emergência"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Serviço temporariamente bloqueado pela rede móvel no seu local"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Não foi possível acessar a rede"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Para melhorar a recepção, tente alterar o tipo selecionado em Sistema &gt; Rede &amp; Internet &gt; Redes móveis &gt; Tipo de rede preferencial."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Para melhorar a recepção, tente alterar o tipo selecionado em Configurações &gt; Rede &amp; Internet &gt; Redes móveis &gt; Tipo de rede preferencial."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Alertas"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Encaminhamento de chamada"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Modo de retorno de chamada de emergência"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Pesquisando serviço"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Chamadas por Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Para fazer chamadas e enviar mensagens por Wi-Fi, primeiro peça à sua operadora para configurar esse serviço. Depois ative novamente as chamadas por Wi-Fi nas configurações."</item>
+    <item msgid="3910386316304772394">"Para fazer chamadas e enviar mensagens por Wi-Fi, primeiro peça à sua operadora para configurar esse serviço. Depois, ative novamente a chamada no Wi-Fi nas configurações. Código de erro: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Faça registro na sua operadora"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="one">Abrir redes Wi-Fi disponíveis</item>
       <item quantity="other">Abrir redes Wi-Fi disponíveis</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Conectar-se a uma rede Wi‑Fi aberta"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Conectando-se a uma rede Wi‑Fi aberta"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Conectado a uma rede Wi‑Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Não foi possível conectar-se à rede Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toque para ver todas as redes"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectar"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Todas as redes"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Fazer login na rede Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Fazer login na rede"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1623,7 +1618,7 @@
     <string name="package_installed_device_owner" msgid="6875717669960212648">"Instalado pelo seu administrador"</string>
     <string name="package_updated_device_owner" msgid="1847154566357862089">"Atualizado pelo seu administrador"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"Excluído pelo seu administrador"</string>
-    <string name="battery_saver_description" msgid="1960431123816253034">"A economia de bateria reduz o desempenho e os limites de vibração do dispositivo, os serviços de localização e a maioria dos dados em segundo plano para aumentar a duração da bateria. E-mails, mensagens e outros aplicativos que dependem de sincronização não serão atualizados, a não ser que você os abra.\n\nA economia de bateria é desligada automaticamente quando o dispositivo está sendo carregado."</string>
+    <string name="battery_saver_description" msgid="1960431123816253034">"A economia de bateria reduz o desempenho do dispositivo e limita a vibração, os serviços de localização e a maioria dos dados em segundo plano para aumentar a duração da bateria. E-mails, mensagens e outros apps que dependem de sincronização não serão atualizados, a não ser que você os abra.\n\nA economia de bateria é desligada automaticamente quando o dispositivo está sendo carregado."</string>
     <string name="data_saver_description" msgid="6015391409098303235">"Para ajudar a reduzir o uso de dados, a Economia de dados impede que alguns apps enviem ou recebam dados em segundo plano. Um app que você esteja usando no momento pode acessar dados, mas com menos frequência. Isso pode significar que as imagens não serão exibidas até que você toque nelas."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"Ativar Economia de dados?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"Ativar"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 8bf321e..33c36d8 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TO"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PO"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g>   zile"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> zile <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> zi <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> h"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g>   min"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min."</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> sec"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> sec"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> sec"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> sec"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Fără titlu&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Niciun număr de telefon)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Necunoscut"</string>
@@ -96,7 +84,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Fără servicii vocale/de urgență"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Momentan nu este oferit de rețeaua mobilă în locația dvs."</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Nu se poate stabili conexiunea la rețea"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Pentru o recepție mai bună, încercați să schimbați tipul selectat în Sistem &gt; Rețea și internet &gt; Rețele mobile &gt; Tip preferat de rețea."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Pentru o recepție mai bună, încercați să schimbați tipul selectat în Setări &gt; Rețea și internet &gt; Rețele mobile &gt; Tip preferat de rețea."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Alerte"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Redirecționarea apelurilor"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Mod de apelare inversă de urgență"</string>
@@ -132,7 +120,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Se caută serviciul"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Apelare prin Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Pentru a apela și a trimite mesaje prin Wi-Fi, mai întâi solicitați configurarea acestui serviciu la operator. Apoi, activați din nou apelarea prin Wi-Fi din Setări."</item>
+    <item msgid="3910386316304772394">"Pentru a efectua apeluri și a trimite mesaje prin Wi-Fi, mai întâi solicitați configurarea acestui serviciu la operator. Apoi, activați din nou apelarea prin Wi-Fi din Setări. (Cod de eroare: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Înregistrați-vă la operatorul dvs."</item>
@@ -1128,6 +1116,13 @@
       <item quantity="other">Rețele Wi-Fi deschise disponibile</item>
       <item quantity="one">Rețea Wi-Fi deschisă disponibilă</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Conectați-vă la o rețea Wi‑Fi deschisă"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Se stabilește conexiunea la o rețea Wi‑Fi deschisă"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"S-a realizat conexiunea la rețeaua Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Nu s-a putut stabili conexiunea la rețeaua Wi-Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Atingeți pentru a vedea toate rețelele"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectați-vă"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Toate rețelele"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Conectați-vă la rețeaua Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Conectați-vă la rețea"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 694105f..853586f 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TБ"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"ПБ"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> дн."</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> день <xliff:g id="HOURS">%2$d</xliff:g> ч."</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> день <xliff:g id="HOURS">%2$d</xliff:g> ч."</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> ч."</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ч. <xliff:g id="MINUTES">%2$d</xliff:g> мин."</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> ч. <xliff:g id="MINUTES">%2$d</xliff:g> мин."</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> мин."</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> мин."</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> мин. <xliff:g id="SECONDS">%2$d</xliff:g> с"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> мин. <xliff:g id="SECONDS">%2$d</xliff:g> с"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> с"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> с"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Без названия&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Нет номера телефона)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Неизвестно"</string>
@@ -97,7 +85,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Голосовые и экстренные вызовы недоступны"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Местная мобильная сеть временно не поддерживает эту функцию."</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Сеть недоступна"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Чтобы улучшить сигнал, попробуйте выбрать другой тип сети в настройках (раздел \"Мобильные сети\")."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Чтобы улучшить сигнал, попробуйте выбрать другой тип сети в настройках (раздел \"Мобильные сети\")."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Оповещения"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Переадресация вызовов"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Режим экстренных обратных вызовов"</string>
@@ -133,7 +121,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Поиск службы"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Звонки по Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Чтобы совершать звонки и отправлять сообщения по Wi-Fi, необходимо сначала обратиться к оператору связи и подключить эту услугу. После этого вы сможете снова выбрать этот параметр в настройках."</item>
+    <item msgid="3910386316304772394">"Чтобы совершать звонки и отправлять сообщения по Wi-Fi, необходимо подключить эту услугу через оператора связи. После этого вы сможете выбрать этот параметр в настройках. Код ошибки: <xliff:g id="CODE">%1$s</xliff:g>."</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Укажите оператора и зарегистрируйтесь"</item>
@@ -210,7 +198,7 @@
     <string name="reboot_to_update_prepare" msgid="6305853831955310890">"Подготовка обновлений…"</string>
     <string name="reboot_to_update_package" msgid="3871302324500927291">"Обработка обновлений…"</string>
     <string name="reboot_to_update_reboot" msgid="6428441000951565185">"Перезагрузка…"</string>
-    <string name="reboot_to_reset_title" msgid="4142355915340627490">"Сброс к заводским настройкам"</string>
+    <string name="reboot_to_reset_title" msgid="4142355915340627490">"Сбросить к заводским настройкам"</string>
     <string name="reboot_to_reset_message" msgid="2432077491101416345">"Перезагрузка…"</string>
     <string name="shutdown_progress" msgid="2281079257329981203">"Выключение..."</string>
     <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Планшетный ПК будет отключен."</string>
@@ -1150,6 +1138,13 @@
       <item quantity="many">Есть открытые сети Wi-Fi</item>
       <item quantity="other">Есть открытые сети Wi-Fi</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Подключитесь к открытой сети Wi‑Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Подключение к открытой сети Wi‑Fi…"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Подключено к сети Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Не удалось подключиться к сети Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Нажмите, чтобы увидеть список сетей"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Подключиться"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Все сети"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Подключение к Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Регистрация в сети"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index fc3caf7..1f373fe 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"දින <xliff:g id="DAYS">%1$d</xliff:g>"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"දින <xliff:g id="DAYS">%1$d</xliff:g> පැය <xliff:g id="HOURS">%2$d</xliff:g>"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"දින <xliff:g id="DAYS">%1$d</xliff:g> පැය <xliff:g id="HOURS">%2$d</xliff:g>"</string>
-    <string name="durationHours" msgid="4266858287167358988">"පැය <xliff:g id="HOURS">%1$d</xliff:g>"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"පැය <xliff:g id="HOURS">%1$d</xliff:g> මිනි <xliff:g id="MINUTES">%2$d</xliff:g>"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"පැය <xliff:g id="HOURS">%1$d</xliff:g> මිනි <xliff:g id="MINUTES">%2$d</xliff:g>"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"මිනි <xliff:g id="MINUTES">%1$d</xliff:g>"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"මිනිත්තු <xliff:g id="MINUTES">%1$d</xliff:g>"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"මිනි <xliff:g id="MINUTES">%1$d</xliff:g> තත් <xliff:g id="SECONDS">%2$d</xliff:g>"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"මිනි <xliff:g id="MINUTES">%1$d</xliff:g> තත් <xliff:g id="SECONDS">%2$d</xliff:g>"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"තත් <xliff:g id="SECONDS">%1$d</xliff:g>"</string>
-    <string name="durationSecond" msgid="985669622276420331">"තත් <xliff:g id="SECONDS">%1$d</xliff:g>"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;නම් යොදා නැත&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(දුරකථන අංකයක් නොමැත)"</string>
     <string name="unknownName" msgid="6867811765370350269">"නොදනී"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"හඬ/හදිසි සේවාව නොමැත"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"ඔබේ ස්ථානයේ ජංගම ජාලය මගින් තාවකාලිකව පිරිනොනමයි"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"ජාලය වෙත ළඟා විය නොහැකිය"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"ප්‍රතිග්‍රහණය වැඩි දියුණු කිරීමට, පද්ධතිය &gt; ජාලය සහ අන්තර්ජාලය &gt; ජංගම ජාල &gt; වඩා කැමති ජාල වර්ගය තුළ තෝරන ලද වර්ගය වෙනස් කිරීම උත්සාහ කරන්න."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"ප්‍රතිග්‍රහණය වැඩි දියුණු කිරීමට, සැකසීම් &gt; ජාලය සහ අන්තර්ජාලය &gt; ජංගම ජාල &gt; වඩා කැමති ජාල වර්ගය තුළ තෝරන ලද වර්ගය වෙනස් කිරීම උත්සාහ කරන්න."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"ඇඟවීම්"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"ඇමතුම ප්‍රතියොමු කිරීම"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"හදිසි අවස්ථා පසු ඇමතුම් ප්‍රකාරය"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"සේවාව සඳහා සොයමින්"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi ඇමතීම"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi හරහා ඇමතුම් සිදු කිරීමට සහ පණිවිඩ යැවීමට, පළමුව මෙම සේවාව පිහිටුවන ලෙස ඔබේ වාහකයෙන් ඉල්ලන්න. අනතුරුව සැකසීම් වෙතින් Wi-Fi ඇමතුම නැවත ක්‍රියාත්මක කරන්න."</item>
+    <item msgid="3910386316304772394">"Wi-Fi හරහා ඇමතුම් සිදු කිරීමට සහ පණිවිඩ යැවීමට, පළමුව මෙම සේවාව පිහිටුවන ලෙස ඔබේ වාහකයෙන් ඉල්ලන්න. අනතුරුව සැකසීම් වෙතින් Wi-Fi ඇමතුම නැවත ක්‍රියාත්මක කරන්න. (දෝෂ කේතය <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"ඔබගේ වාහකය සමඟ ලියාපදිංචි වන්න"</item>
@@ -1108,6 +1096,13 @@
       <item quantity="one">විවෘත Wi-Fi ජාල තිබේ</item>
       <item quantity="other">විවෘත Wi-Fi ජාල තිබේ</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"විවෘත Wi-Fi ජාලය වෙත සම්බන්ධ වෙන්න"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"විවෘත Wi-Fi ජාලය වෙත සම්බන්ධ වෙමින්"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi-Fi ජාලයක් වෙත සම්බන්ධ විය"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi-Fi ජාලයක් වෙත සම්බන්ධ විය නොහැකි විය"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"සියලු ජාල බැලීමට තට්ටු කරන්න"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"සම්බන්ධ කරන්න"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"සියලු ජාල"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi ජාලයට පුරනය වන්න"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"ජාලයට පුරනය වන්න"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index aa912ec..47b0b85 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> d."</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> d. <xliff:g id="HOURS">%2$d</xliff:g> hod."</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> d. <xliff:g id="HOURS">%2$d</xliff:g> hod."</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> hod."</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> hod. <xliff:g id="MINUTES">%2$d</xliff:g> min."</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> hod. <xliff:g id="MINUTES">%2$d</xliff:g> min."</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min. <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min. <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Bez mena&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(žiadne telefónne číslo)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Bez názvu"</string>
@@ -97,7 +85,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Hlasové ani tiesňové volania nie sú k dispozícii"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Momentálne nie sú v ponuke mobilnej siete na vašom mieste"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Nepodarilo sa pripojiť k sieti"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Ak chcete vylepšiť príjem, skúste zmeniť vybratý typ siete v časti Systém &gt; Sieť a internet &gt; Mobilné siete &gt; Preferovaný typ siete."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Ak chcete vylepšiť príjem, skúste zmeniť vybraný typ v časti Nastavenia &gt; Sieť a internet &gt; Mobilné siete &gt; Preferovaný typ siete."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Upozornenia"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Presmerovanie hovorov"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Režim tiesňového spätného volania"</string>
@@ -133,7 +121,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Vyhľadávanie služby"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Volanie cez Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Ak chcete volať a odosielať správy prostredníctvom siete Wi-Fi, kontaktujte najskôr svojho operátora v súvislosti s nastavením tejto služby. Potom opäť zapnite v Nastaveniach volanie cez Wi-Fi."</item>
+    <item msgid="3910386316304772394">"Ak chcete volať a odosielať správy prostredníctvom siete Wi-Fi, kontaktujte najskôr svojho operátora v súvislosti s nastavením tejto služby. Potom opäť zapnite v Nastaveniach volanie cez Wi-Fi. (Kód chyby: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Registrujte sa so svojím operátorom"</item>
@@ -1150,6 +1138,13 @@
       <item quantity="other">K dispozícii sú verejné siete Wi-Fi</item>
       <item quantity="one">K dispozícii je verejná sieť Wi-Fi</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Pripojenie k otvorenej sieti Wi-Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Pripája sa k otvorenej sieti Wi-Fi"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Pripojenie k sieti Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"K sieti Wi‑Fi sa nepodarilo pripojiť"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Klepnutím zobrazíte všetky siete"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Pripojiť"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Všetky siete"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Prihlásiť sa do siete Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Prihlásenie do siete"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index c4f6d9c..457f324 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"Št. dni: <xliff:g id="DAYS">%1$d</xliff:g>"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> dan <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> dan <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> h"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Brez naslova&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Ni telefonske številke)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Neznano"</string>
@@ -97,7 +85,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Ni storitve za glasovne klice / klice v sili"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Ta storitev trenutno ni na voljo v mobilnem omrežju na vaši lokaciji"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Povezave z omrežjem ni mogoče vzpostaviti"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Če želite izboljšati sprejem, poskusite zamenjati vrsto omrežja v možnostih »Sistem« &gt; »Omrežje in internet« &gt; »Mobilna omrežja« &gt; »Prednostna vrsta omrežja«."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Če želite izboljšati sprejem, poskusite zamenjati vrsto omrežja v »Nastavitve« &gt; »Omrežje in internet« &gt; »Mobilna omrežja« &gt; »Prednostna vrsta omrežja«."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Opozorila"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Preusmerjanje klicev"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Način za povratni klic v sili"</string>
@@ -133,7 +121,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Iskanje storitve"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Klicanje prek Wi-Fi-ja"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Če želite klicati ali pošiljati sporočila prek omrežja Wi-Fi, se najprej obrnite na operaterja, da nastavi to storitev. Nato v nastavitvah znova vklopite klicanje prek omrežja Wi-Fi."</item>
+    <item msgid="3910386316304772394">"Če želite klicati ali pošiljati sporočila prek omrežja Wi-Fi, se najprej obrnite na operaterja, da nastavi to storitev. Nato v nastavitvah znova vklopite klicanje prek omrežja Wi-Fi. (Koda napake: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Registracija pri operaterju"</item>
@@ -286,7 +274,7 @@
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"dostop do koledarja"</string>
     <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="4656988620100940350">"pošiljanje in ogled sporočil SMS"</string>
-    <string name="permgrouplab_storage" msgid="1971118770546336966">"Prostor za shranjevanje"</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"Shramba"</string>
     <string name="permgroupdesc_storage" msgid="637758554581589203">"dostop do fotografij, predstavnosti in datotek v napravi"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"snemanje zvoka"</string>
@@ -1150,6 +1138,13 @@
       <item quantity="few">Na voljo so odprta omrežja Wi-Fi</item>
       <item quantity="other">Na voljo so odprta omrežja Wi-Fi</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Vzpostavite povezavo z odprtim omrežjem Wi‑Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Vzpostavljanje povezave z odprtim omrežjem Wi‑Fi"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Povezava z omrežjem Wi-Fi je vzpostavljena"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Povezave z omrežjem Wi-Fi ni bilo mogoče vzpostaviti"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Dotaknite se, če si želite ogledati vsa omrežja"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Vzpostavi povezavo"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Vsa omrežja"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Prijavite se v omrežje Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Prijava v omrežje"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1847,6 +1842,5 @@
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"Kartica SIM ni omogočena za uporabo"</string>
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"Kartica SIM ni dovoljena"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"Telefon ni dovoljen"</string>
-    <!-- no translation found for popup_window_default_title (4874318849712115433) -->
-    <skip />
+    <string name="popup_window_default_title" msgid="4874318849712115433">"Pojavno okno"</string>
 </resources>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 6b903ae..96f3ae6 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"terabajt"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"petabajt"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> ditë"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> ditë e <xliff:g id="HOURS">%2$d</xliff:g> orë"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> ditë e <xliff:g id="HOURS">%2$d</xliff:g> orë"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> orë"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> orë e <xliff:g id="MINUTES">%2$d</xliff:g> minuta"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> orë e <xliff:g id="MINUTES">%2$d</xliff:g> minuta"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> minuta"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> minuta"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> minuta e <xliff:g id="SECONDS">%2$d</xliff:g> sekonda"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> minuta e <xliff:g id="SECONDS">%2$d</xliff:g> sekonda"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> sekonda"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> sekonda"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Pa titull&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Nuk ka numër telefoni)"</string>
     <string name="unknownName" msgid="6867811765370350269">"E panjohur"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Nuk ka shërbim zanor/urgjence"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Përkohësisht nuk ofrohet nga rrjeti celular në vendndodhjen tënde"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Rrjeti i paarritshëm"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Për të përmirësuar marrjen e sinjalit, provo të ndryshosh llojin e zgjedhur te Sistemi &gt; Rrjeti dhe interneti &gt; Lloji i preferuar i rrjetit."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Për të përmirësuar marrjen e sinjalit, provo të ndryshosh llojin e zgjedhur te Cilësimet &gt; Rrjeti dhe interneti &gt; Lloji i preferuar i rrjetit."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Sinjalizimet"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Transferimi i telefonatave"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Modaliteti i \"Kthimit të telefonatës së urgjencës\""</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Po kërkon për shërbim"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Telefonatë me Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Për të bërë telefonata dhe për të dërguar mesazhe me Wi-Fi, në fillim kërkoji operatorit celular ta konfigurojë këtë shërbim. Më pas aktivizo përsëri telefonatat me Wi-Fi, nga Cilësimet."</item>
+    <item msgid="3910386316304772394">"Për të bërë telefonata dhe për të dërguar mesazhe nëpërmjet Wi-Fi, në fillim kërkoji operatorit celular të konfigurojë këtë shërbim. Më pas aktivizo përsëri telefonatat me Wi-Fi nga \"Cilësimet\". (Kodi i gabimit: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Regjistrohu me operatorin tënd celular"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">Rrjete të hapura Wi-Fi në përdorim</item>
       <item quantity="one">Rrjet i hapur Wi-Fi në përdorim</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Lidhu me rrjetin e hapur Wi‑Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Po lidhet me rrjetin e hapur Wi‑Fi"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Lidhur me rrjetin e hapur Wi‑Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Nuk mund të lidhet me rrjetin Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Trokit për të parë të gjitha rrjetet"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Lidhu"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Të gjitha rrjetet"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Identifikohu në rrjetin Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Identifikohu në rrjet"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 8d7f596..9d5963b 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> дана"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> дан <xliff:g id="HOURS">%2$d</xliff:g> с"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> дан <xliff:g id="HOURS">%2$d</xliff:g> с"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> с"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> с <xliff:g id="MINUTES">%2$d</xliff:g> мин"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> с <xliff:g id="MINUTES">%2$d</xliff:g> мин"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> мин"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> мин"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> мин <xliff:g id="SECONDS">%2$d</xliff:g> сек"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> мин <xliff:g id="SECONDS">%2$d</xliff:g> сек"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> сек"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> сек"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Без наслова&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Нема броја телефона)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Непознато"</string>
@@ -96,7 +84,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Нема гласовне услуге/услуге за хитне позиве"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Привремено је онемогућено на мобилној мрежи на вашој локацији"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Повезивање са мрежом није успело"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Да бисте побољшали пријем, пробајте да промените изабрани тип у одељку Систем &gt; Мрежа и интернет &gt; Мобилне мреже &gt; Жељени тип мреже."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Да бисте побољшали пријем, пробајте да промените изабрани тип у одељку Подешавања &gt; Мрежа и интернет &gt; Мобилне мреже &gt; Жељени тип мреже."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Обавештења"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Преусмеравање позива"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Режим за хитан повратни позив"</string>
@@ -132,7 +120,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Претраживање услуге"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Позивање преко Wi-Fi-ја"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Да бисте упућивали позиве и слали поруке преко Wi-Fi-ја, прво затражите од мобилног оператера да вам омогући ову услугу. Затим у Подешавањима поново укључите Позивање преко Wi-Fi-ја."</item>
+    <item msgid="3910386316304772394">"Да бисте упућивали позиве и слали поруке преко Wi-Fi-ја, прво затражите од мобилног оператера да вам омогући ову услугу. Затим у Подешавањима поново укључите Позивање преко Wi-Fi-ја. (кôд грешке: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Региструјте се код мобилног оператера"</item>
@@ -1128,6 +1116,13 @@
       <item quantity="few">Отворене Wi-Fi мреже су доступне</item>
       <item quantity="other">Отворене Wi-Fi мреже су доступне</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Повежите се са отвореном Wi‑Fi мрежом"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Повезујете се са отвореном Wi‑Fi мрежом"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Повезали сте се са Wi‑Fi мрежом"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Повезивање са Wi‑Fi мрежом није успело"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Додирните да бисте видели све мреже"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Повежи"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Све мреже"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Пријављивање на Wi-Fi мрежу"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Пријавите се на мрежу"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 172ae15..59f59c6 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> dagar"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> dag <xliff:g id="HOURS">%2$d</xliff:g> tim"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> dag <xliff:g id="HOURS">%2$d</xliff:g> tim"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> timmar"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> tim <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> tim <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> minuter"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> sek"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> sek"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> sekunder"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> sekund"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Okänd&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Inget telefonnummer)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Okänt"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Tjänster för röst- och nödsamtal har blockerats"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Detta erbjuds för tillfället inte på mobilnätverket där du befinner dig"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Det går inte att nå nätverket"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Testa om du får bättre mottagning genom att ändra till en annan typ under System &gt; Nätverk och internet &gt; Mobila nätverk &gt; Önskad nätverkstyp."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Testa om du får bättre mottagning genom att ändra till en annan typ under Inställningar &gt; Nätverk och internet &gt; Mobila nätverk &gt; Önskad nätverkstyp."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Aviseringar"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Vidarekoppla samtal"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Läget Återuppringning vid nödsamtal"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Söker efter tjänst"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi-samtal"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Om du vill ringa samtal och skicka meddelanden via Wi-Fi ber du först operatören att konfigurera tjänsten. Därefter kan du aktivera Wi-Fi-samtal på nytt från Inställningar."</item>
+    <item msgid="3910386316304772394">"Om du vill ringa samtal och skicka meddelanden via Wi-Fi ber du först operatören att konfigurera tjänsten. Därefter kan du aktivera Wi-Fi-samtal på nytt från Inställningar. (Felkod: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Registrera dig hos operatören"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">Öppna Wi-Fi-nätverk är tillgängliga</item>
       <item quantity="one">Öppet Wi-Fi-nätverk är tillgängligt</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Anslut till ett öppet Wi-Fi-nätverk"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Ansluter till ett öppet Wi-Fi-nätverk"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Ansluten till Wi-Fi-nätverket"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Det gick inte att ansluta till Wi‑Fi-nätverket"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tryck för att visa alla nätverk"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Anslut"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Alla nätverk"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Logga in på ett Wi-Fi-nätverk"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Logga in på nätverket"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 7786f2c..4728672 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"Siku <xliff:g id="DAYS">%1$d</xliff:g>"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"Siku <xliff:g id="DAYS">%1$d</xliff:g> saa <xliff:g id="HOURS">%2$d</xliff:g>"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"Siku <xliff:g id="DAYS">%1$d</xliff:g> saa <xliff:g id="HOURS">%2$d</xliff:g>"</string>
-    <string name="durationHours" msgid="4266858287167358988">"Saa <xliff:g id="HOURS">%1$d</xliff:g>"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"Saa <xliff:g id="HOURS">%1$d</xliff:g> dak <xliff:g id="MINUTES">%2$d</xliff:g>"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"Saa <xliff:g id="HOURS">%1$d</xliff:g> dak <xliff:g id="MINUTES">%2$d</xliff:g>"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"Dakika <xliff:g id="MINUTES">%1$d</xliff:g>"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"Dak <xliff:g id="MINUTES">%1$d</xliff:g>"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"Dak <xliff:g id="MINUTES">%1$d</xliff:g> sek <xliff:g id="SECONDS">%2$d</xliff:g>"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"Dak <xliff:g id="MINUTES">%1$d</xliff:g> sek <xliff:g id="SECONDS">%2$d</xliff:g>"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"Sekunde <xliff:g id="SECONDS">%1$d</xliff:g>"</string>
-    <string name="durationSecond" msgid="985669622276420331">"Sekunde <xliff:g id="SECONDS">%1$d</xliff:g>"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Haina jina&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Hakuna nambari ya simu)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Isiyojulikana"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Hakuna huduma ya simu za dharura au za sauti"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Kwa sasa, huduma hii haipatikani katika mtandao wa simu mahali ulipo"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Haiwezi kufikia mtandao"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Ili kupata mtandao thabiti, jaribu kubadilisha aina iliyochaguliwa katika Mfumo &gt; Mtandao na Intaneti &gt; Mitandao ya simu &gt; Aina ya mtandao unaopendelea."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Ili kupata mtandao thabiti, jaribu kubadilisha aina uliyochagua katika Mipangilio &gt; Mtandao na Intaneti &gt; Mitandao ya simu &gt; Aina ya mtandao unaopendelea."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Arifa"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Kupeleka simu kwenye nambari nyingine"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Hali ya kupiga simu za dharura"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Inatafuta Huduma"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Upigaji Simu kwa Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Ili upige simu na kutuma ujumbe kupitia Wi-Fi, mwambie mtoa huduma wako asanidi huduma hii kwanza. Kisha uwashe tena upigaji simu kwa Wi-Fi kutoka kwenye Mipangilio."</item>
+    <item msgid="3910386316304772394">"Ili upige simu na kutuma ujumbe kupitia Wi-Fi, mwambie mtoa huduma wako aweke mipangilio ya huduma hii kwanza. Kisha uwashe tena kipengele cha kupiga simu kupitia Wi-Fi kwenye Mipangilio. (Msimbo wa hitilafu: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Jisajili na mtoa huduma wako"</item>
@@ -1104,6 +1092,13 @@
       <item quantity="other">Fungua mitandao ya Wi-Fi inayopatikana</item>
       <item quantity="one">Fungua mtandao wa Wi-Fi unaopatikana</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Unganisha kwenye mtandao wa Wi‑Fi unaotumiwa na mtu yeyote"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Inaunganisha kwenye mtandao wa Wi‑Fi unaotumiwa na mtu yeyote"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Imeunganisha kwenye mtandao wa Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Imeshindwa kuunganisha kwenye mtandao wa Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Gonga ili uone mitandao yote"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Unganisha"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Mitandao Yote"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Ingia kwa mtandao wa Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Ingia katika mtandao"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 407cfa0..e9ced05 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"டெ.பை."</string>
     <string name="petabyteShort" msgid="5637816680144990219">"பெ.பை."</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> நாட்கள்"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> நாள் <xliff:g id="HOURS">%2$d</xliff:g> ம.நே."</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> நாள் <xliff:g id="HOURS">%2$d</xliff:g> ம.நே."</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> ம.நே."</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ம.நே. <xliff:g id="MINUTES">%2$d</xliff:g> நிமி."</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> மநே <xliff:g id="MINUTES">%2$d</xliff:g> நிமி"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> நிமிடங்கள்"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> நிமி."</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> நிமி <xliff:g id="SECONDS">%2$d</xliff:g> வி"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> நிமி <xliff:g id="SECONDS">%2$d</xliff:g> வி"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> வினாடிகள்"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> வினாடி"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;பெயரிடப்படாதது&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(தொலைபேசி எண் இல்லை)"</string>
     <string name="unknownName" msgid="6867811765370350269">"அறியப்படாதவர்"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"குரல்/அவசரச் சேவை இல்லை"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"தற்காலிகமாக உங்கள் இருப்பிடத்தில் மொபைல் நெட்வொர்க் வழங்கவில்லை"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"நெட்வொர்க்குடன் இணைக்க முடியவில்லை"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"பெறுதலை மேம்படுத்த, சாதனம் &gt; நெட்வொர்க் &amp; இணையம் &gt; மொபைல் நெட்வொர்க்குகள் &gt; விரும்பும் நெட்வொர்க் வகை என்பதற்குச் சென்று, தேர்ந்தெடுத்த வகையை மாற்றவும்."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"பெறுதலை மேம்படுத்த, அமைப்புகள் &gt; நெட்வொர்க் &amp; இணையம் &gt; மொபைல் நெட்வொர்க்குகள் &gt; விரும்பும் நெட்வொர்க் வகை என்பதற்குச் சென்று, தேர்ந்தெடுத்த வகையை மாற்றவும்."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"விழிப்பூட்டல்கள்"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"அழைப்புப் பகிர்வு"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"அவசரகாலத் திரும்ப அழைக்கும் பயன்முறை"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"சேவையைத் தேடுகிறது"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"வைஃபை அழைப்பு"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"வைஃபை மூலம் அழைக்க மற்றும் செய்திகள் அனுப்ப, முதலில் மொபைல் நிறுவனத்திடம் இந்தச் சேவையை அமைக்குமாறு கேட்கவும். பிறகு அமைப்புகளில் மீண்டும் வைஃபை அழைப்பை இயக்கவும்."</item>
+    <item msgid="3910386316304772394">"வைஃபை மூலம் அழைக்கவும் செய்திகளை அனுப்பவும், முதலில் தொலைத்தொடர்பு நிறுவனத்திடம் இந்தச் சேவையை அமைக்குமாறு கேட்கவும். பிறகு அமைப்புகளில் மீண்டும் வைஃபை அழைப்பை இயக்கவும். (பிழைக் குறியீடு <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"உங்கள் மொபைல் நிறுவனத்தில் பதிவுசெய்யவும்"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">பொது வைஃபை நெட்வொர்க்குகள் உள்ளன</item>
       <item quantity="one">பொது வைஃபை நெட்வொர்க் உள்ளது</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"திறந்த வைஃபை நெட்வொர்க்குடன் இணைக்கவும்"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"திறந்த வைஃபை நெட்வொர்க்குடன் இணைக்கிறது"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"வைஃபை நெட்வொர்க்குடன் இணைக்கப்பட்டது"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"வைஃபை நெட்வொர்க்குடன் இணைக்க முடியவில்லை"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"எல்லா நெட்வொர்க்குகளையும் பார்க்க, தட்டவும்"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"இணை"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"எல்லா நெட்வொர்க்குகளும்"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"வைஃபை நெட்வொர்க்கில் உள்நுழையவும்"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"நெட்வொர்க்கில் உள்நுழையவும்"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index eb5ff1e..375c82d 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> రోజులు"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> రో <xliff:g id="HOURS">%2$d</xliff:g> గం"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> రో <xliff:g id="HOURS">%2$d</xliff:g> గం"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> గంటలు"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> గం <xliff:g id="MINUTES">%2$d</xliff:g> నిమి"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> గం <xliff:g id="MINUTES">%2$d</xliff:g> నిమి"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> నిమిషాలు"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> నిమి"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> నిమి <xliff:g id="SECONDS">%2$d</xliff:g> సె"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> నిమి <xliff:g id="SECONDS">%2$d</xliff:g> సె"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> సెకన్లు"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> సెకను"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;శీర్షిక లేనిది&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(ఫోన్ నంబర్ లేదు)"</string>
     <string name="unknownName" msgid="6867811765370350269">"తెలియదు"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"వాయిస్/అత్యవసర సేవ లేదు"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"మీ స్థానంలో మొబైల్ నెట్‌వర్క్ ద్వారా తాత్కాలికంగా అందించబడదు"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"నెట్‌వర్క్‌ను చేరుకోలేరు"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"స్వీకరణను మెరుగుపరచాలంటే, సిస్టమ్ &gt; నెట్‌వర్క్ &amp; ఇంటర్నెట్ &gt; మొబైల్ నెట్‌వర్క్‌లు &gt; ప్రాధాన్య నెట్‌వర్క్ రకంలో మీరు ఎంచుకున్న రకాన్ని మార్చి ప్రయత్నించండి."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"స్వీకరణను మెరుగుపరచాలంటే, సెట్టింగ్‌లు &gt; నెట్‌వర్క్ &amp; ఇంటర్నెట్ &gt; మొబైల్ నెట్‌వర్క్‌లు &gt; ప్రాధాన్య నెట్‌వర్క్ రకంలో మీరు ఎంచుకున్న రకాన్ని మార్చి ప్రయత్నించండి."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"హెచ్చరికలు"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"కాల్ ఫార్వార్డింగ్"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"అత్యవసర కాల్‌బ్యాక్ మోడ్"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"సేవ కోసం శోధిస్తోంది"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi కాలింగ్"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fiలో కాల్‌లు చేయడం మరియు సందేశాలు పంపడం కోసం ముందుగా ఈ సేవను సెటప్ చేయడానికి మీ క్యారియర్‌ను అడగండి. ఆపై సెట్టింగ్‌ల నుండి మళ్లీ Wi-Fi కాలింగ్‌ను ఆన్ చేయండి."</item>
+    <item msgid="3910386316304772394">"Wi-Fiతో కాల్‌లను చేయడానికి మరియు సందేశాలను పంపించడానికి, మొదట ఈ సేవను సెటప్ చేయాల్సిందిగా మీ క్యారియర్‌‌కి చెప్పండి. ఆ తర్వాత సెట్టింగ్‌ల నుండి Wi-Fi కాలింగ్‌ని మళ్లీ ఆన్ చేయండి. (లోపం కోడ్: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"మీ క్యారియర్‌తో నమోదు చేయండి"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">ఓపెన్ Wi-Fi నెట్‌వర్క్‌లు అందుబాటులో ఉన్నాయి</item>
       <item quantity="one">ఓపెన్ Wi-Fi నెట్‌వర్క్ అందుబాటులో ఉంది</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"బహిరంగ Wi‑Fi నెట్‌వర్క్‌కు కనెక్ట్ చేయండి"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"బహిరంగ Wi‑Fi నెట్‌వర్క్‌కు కనెక్ట్ చేస్తోంది"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi నెట్‌వర్క్‌కు కనెక్ట్ చేయబడింది"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi నెట్‌వర్క్‌కు కనెక్ట్ చేయడం సాధ్యపడలేదు"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"అన్ని నెట్‌వర్క్‌లు చూడటానికి నొక్కండి"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"కనెక్ట్ చేయి"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"అన్ని నెట్‌వర్క్‌లు"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi నెట్‌వర్క్‌కి సైన్ ఇన్ చేయండి"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"నెట్‌వర్క్‌కి సైన్ ఇన్ చేయండి"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1780,6 +1775,5 @@
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM సక్రియం కాలేదు"</string>
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM అనుమతించబడదు"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"ఫోన్ అనుమతించబడదు"</string>
-    <!-- no translation found for popup_window_default_title (4874318849712115433) -->
-    <skip />
+    <string name="popup_window_default_title" msgid="4874318849712115433">"పాప్అప్ విండో"</string>
 </resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index c57fb07..9a58edd 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> วัน"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> วัน <xliff:g id="HOURS">%2$d</xliff:g> ชม."</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> วัน <xliff:g id="HOURS">%2$d</xliff:g> ชม."</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> ชม."</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ชม. <xliff:g id="MINUTES">%2$d</xliff:g> นาที"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> ชม. <xliff:g id="MINUTES">%2$d</xliff:g> นาที"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> นาที"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> นาที"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> นาที <xliff:g id="SECONDS">%2$d</xliff:g> วิ."</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> นาที <xliff:g id="SECONDS">%2$d</xliff:g> วิ."</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> วินาที"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> วินาที"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;ไม่มีชื่อ&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(ไม่มีหมายเลขโทรศัพท์)"</string>
     <string name="unknownName" msgid="6867811765370350269">"ไม่ทราบ"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"ไม่มีบริการเสียง/บริการฉุกเฉิน"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"งดให้บริการชั่วคราวโดยเครือข่ายมือถือในตำแหน่งของคุณ"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"เข้าถึงเครือข่ายไม่ได้"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"เพื่อให้การรับสัญญาณดีขึ้น ลองเปลี่ยนประเภทที่เลือกใน \"การตั้งค่า\" &gt; \"เครือข่ายและอินเทอร์เน็ต\" &gt; \"เครือข่ายมือถือ\" &gt; \"ประเภทเครือข่ายที่ต้องการ\""</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"ลองเปลี่ยนประเภทที่เลือกใน \"การตั้งค่า\" &gt; \"เครือข่ายและอินเทอร์เน็ต\" &gt; \"เครือข่ายมือถือ\" &gt; \"ประเภทเครือข่ายที่ต้องการ\" เพื่อให้การรับสัญญาณดีขึ้น"</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"การแจ้งเตือน"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"การโอนสาย"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"โหมดติดต่อกลับฉุกเฉิน"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"กำลังค้นหาบริการ"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"การโทรผ่าน Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"หากต้องการโทรออกและส่งข้อความผ่าน Wi-Fi โปรดสอบถามผู้ให้บริการของคุณก่อนเพื่อตั้งค่าบริการนี้ แล้วเปิดการโทรผ่าน Wi-Fi อีกครั้งจากการตั้งค่า"</item>
+    <item msgid="3910386316304772394">"หากต้องการโทรออกและส่งข้อความผ่าน Wi-Fi โปรดสอบถามผู้ให้บริการของคุณก่อนเพื่อตั้งค่าบริการนี้ แล้วเปิดการโทรผ่าน Wi-Fi อีกครั้งจากการตั้งค่า (รหัสข้อผิดพลาด: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"ลงทะเบียนกับผู้ให้บริการ"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">มีหลายเครือข่าย Wi-Fi สาธารณะที่ใช้งานได้</item>
       <item quantity="one">มี 1 เครือข่าย Wi-Fi สาธารณะที่ใช้งานได้</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"เชื่อมต่อเครือข่าย Wi‑Fi แบบเปิด"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"กำลังเชื่อมต่อเครือข่าย Wi‑Fi แบบเปิด"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"เชื่อมต่อเครือข่าย Wi-Fi แล้ว"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"ไม่สามารถเชื่อมต่อเครือข่าย Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"แตะเพื่อดูเครือข่ายทั้งหมด"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"เชื่อมต่อ"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"เครือข่ายทั้งหมด"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"ลงชื่อเข้าใช้เครือข่าย WiFi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"ลงชื่อเข้าใช้เครือข่าย"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 6f77f82..2c33a0f 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> (na) araw"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> day <xliff:g id="HOURS">%2$d</xliff:g> hr"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> day <xliff:g id="HOURS">%2$d</xliff:g> hr"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> (na) oras"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> oras <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> oras <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> (na) min"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> seg"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> seg"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> (na) seg"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> (na) seg"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Walang pamagat&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Walang numero ng telepono)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Hindi alam"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Walang serbisyo para sa voice/emergency"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Pansamantalang hindi inaalok ng mobile network sa iyong lokasyon"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Hindi maabot ang network"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Upang lumakas ang reception, subukang baguhin ang uring napili sa System &gt; Network at Internet &gt; Mga mobile network &gt; Gustong uri ng network."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Upang mapahusay ang reception, subukang baguhin ang uring napili sa Mga Setting &gt; Network at Internet &gt; Mga mobile network &gt; Gustong uri ng network."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Mga Alerto"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Pagpasa ng tawag"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Emergency callback mode"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Naghahanap ng Serbisyo"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Pagtawag sa pamamagitan ng Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Upang tumawag at magpadala ng mga mensahe sa pamamagitan ng Wi-Fi, hilingin muna sa iyong carrier na i-set up ang serbisyong ito. Pagkatapos ay muling i-on ang pagtawag sa Wi-Fi mula sa Mga Setting."</item>
+    <item msgid="3910386316304772394">"Upang makatawag at makapagpadala ng mga mensahe sa Wi-Fi, hilingin muna sa iyong carrier na i-set up ang serbisyong ito. Pagkatapos ay i-on muli ang pagtawag gamit ang Wi-Fi mula sa Mga Setting. (Error code: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Magparehistro sa iyong carrier"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="one">Available ang mga bukas na Wi-Fi network</item>
       <item quantity="other">Available ang mga bukas na Wi-Fi network</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Kumonekta sa bukas na Wi‑Fi network"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Kumokonekta sa bukas na Wi‑Fi network"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Nakakonekta sa Wi‑Fi network"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Hindi makakonekta sa Wi‑Fi network"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"I-tap upang makita ang lahat ng network"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Kumonekta"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Lahat ng Network"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Mag-sign in sa Wi-Fi network"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Mag-sign in sa network"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 76bee02..8c4c427 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> gün"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> gün <xliff:g id="HOURS">%2$d</xliff:g> sa."</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> gün <xliff:g id="HOURS">%2$d</xliff:g> sa."</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> sa."</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> sa. <xliff:g id="MINUTES">%2$d</xliff:g> dk."</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> sa. <xliff:g id="MINUTES">%2$d</xliff:g> dk."</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> dk."</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> dk."</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> dk. <xliff:g id="SECONDS">%2$d</xliff:g> sn."</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> dk. <xliff:g id="SECONDS">%2$d</xliff:g> sn."</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> sn."</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> sn."</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Adsız&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Telefon numarası yok)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Bilinmiyor"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Ses/acil durum hizmeti yok"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Bulunduğunuz yerdeki mobil ağ tarafından geçici olarak sunulmuyor"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Ağa erişilemiyor"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Sinyal gücünü iyileştirmek için Sistem &gt; Ağ ve İnternet &gt; Mobil ağlar &gt; Tercih edilen ağ türü\'nden seçili türü değiştirmeyi deneyin."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Sinyal gücünü iyileştirmek için Ayarlar &gt; Ağ ve İnternet &gt; Mobil ağlar &gt; Tercih edilen ağ türü bölümünde seçili türü değiştirmeyi deneyin."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Uyarılar"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Çağrı yönlendirme"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Acil geri arama modu"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Hizmet Aranıyor"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Kablosuz Çağrı"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Kablosuz ağ üzerinden telefon etmek ve ileti göndermek için ilk önce operatörünüzden bu hizmeti ayarlamasını isteyin. Sonra tekrar Ayarlar\'dan Kablosuz çağrı özelliğini açın."</item>
+    <item msgid="3910386316304772394">"Kablosuz ağ üzerinden telefon etmek ve mesaj göndermek için öncelikle operatörünüzden bu hizmeti ayarlamasını isteyin. Sonra, Ayarlar\'dan Kablosuz çağrı özelliğini tekrar açın. (Hata kodu: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Operatörünüze kaydolun"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">Kullanılabilir Kablosuz ağları aç</item>
       <item quantity="one">Kullanılabilir Kablosuz ağı aç</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Açık kablosuz ağa bağlanın"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Açık kablosuz ağa bağlandı"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Kablosuz ağa bağlanıldı"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Kablosuz ağa bağlanamadı"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tüm ağları görmek için dokunun"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Bağlan"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Tüm Ağlar"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Kablosuz ağda oturum açın"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Ağda oturum açın"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 1c51664..79bf1f9 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"Тб"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"Пб"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> дн."</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> день <xliff:g id="HOURS">%2$d</xliff:g> год"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> дн. <xliff:g id="HOURS">%2$d</xliff:g> год"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> год"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> год <xliff:g id="MINUTES">%2$d</xliff:g> хв"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> год <xliff:g id="MINUTES">%2$d</xliff:g> хв"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> хв"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> хв"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> хв <xliff:g id="SECONDS">%2$d</xliff:g> с"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> хв <xliff:g id="SECONDS">%2$d</xliff:g> с"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> с"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> с"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Без назви&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Немає номера тел.)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Невідомо"</string>
@@ -97,7 +85,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Немає голосової/екстреної служби"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Тимчасово не пропонується мобільною мережею у вашому місцезнаходженні"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Не вдається під’єднатися до мережі"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Щоб покращити якість сигналу, змініть тип у меню \"Система\" &gt; \"Мережа й Інтернет\" &gt; \"Мобільні мережі\" &gt; \"Тип мережі\"."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Щоб покращити прийняття сигналу, змініть тип у меню \"Налаштування\" &gt; \"Мережа й Інтернет\" &gt; \"Мобільні мережі\" &gt; \"Тип мережі\"."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Сповіщення"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Переадресація виклику"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Режим екстреного зворотного виклику"</string>
@@ -133,7 +121,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Пошук служби"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Дзвінок через Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Щоб телефонувати або надсилати повідомлення через Wi-Fi, спочатку попросіть свого оператора налаштувати цю послугу. Після цього ввімкніть дзвінки через Wi-Fi у налаштуваннях."</item>
+    <item msgid="3910386316304772394">"Щоб телефонувати або надсилати повідомлення через Wi-Fi, спершу попросіть свого оператора налаштувати цю послугу. Після цього знову ввімкніть дзвінки через Wi-Fi у налаштуваннях. (Код помилки: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Зареєструйтеся в оператора"</item>
@@ -1150,6 +1138,13 @@
       <item quantity="many">Відкриті мережі Wi-Fi доступні</item>
       <item quantity="other">Відкриті мережі Wi-Fi доступні</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Під’єднайтеся до відкритої мережі Wi-Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Під’єднання до відкритої мережі Wi-Fi"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Під’єднано до мережі Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Не вдалося під’єднатися до мережі Wi-Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Торкніться, щоб побачити всі мережі"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Під’єднатися"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Усі мережі"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Вхід у мережу Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Вхід у мережу"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index f3aad66..38353f1 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> دن"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> دن <xliff:g id="HOURS">%2$d</xliff:g> گھنٹے"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> دن <xliff:g id="HOURS">%2$d</xliff:g> گھنٹہ"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> گھنٹے"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> گھنٹہ <xliff:g id="MINUTES">%2$d</xliff:g> منٹ"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> گھنٹہ <xliff:g id="MINUTES">%2$d</xliff:g> منٹ"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> منٹ"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> منٹ"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> منٹ <xliff:g id="SECONDS">%2$d</xliff:g> سیکنڈ"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> منٹ <xliff:g id="SECONDS">%2$d</xliff:g> سیکنڈ"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> سیکنڈ"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> سیکنڈ"</string>
     <string name="untitled" msgid="4638956954852782576">"‏‎&gt;‎بلا عنوان‎&lt;‎"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(کوئی فون نمبر نہیں ہے)"</string>
     <string name="unknownName" msgid="6867811765370350269">"نامعلوم"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"کوئی صوتی/ہنگامی سروس نہیں"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"عارضی طور پر آپ کے مقام پر موبائل نیٹ ورک کی طرف سے پیش نہیں ہے"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"نیٹ ورک تک نہیں پہنچا جا سکتا"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"‏ریسپشن کو بہتر بنانے کیلئے، سسٹم ‎&gt; نیٹ ورک اور انٹرنیٹ ‎&gt; موبائل نیٹ ورکس ‎&gt; ترجیحی نیٹ ورک کی قسم تبدیل کرنے کی کوشش کریں۔"</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"‏ریسپشن کو بہتر بنانے کیلئے، ترتیبات ‎&gt; نیٹ ورک اور انٹرنیٹ ‎&gt; موبائل نیٹ ورکس ‎&gt; ترجیحی نیٹ ورک کی قسم تبدیل کرنے کی کوشش کریں۔"</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"الرٹس"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"کال آگے منتقل کرنا"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"ہنگامی کال بیک وضع"</string>
@@ -130,9 +118,7 @@
     <string name="roamingText12" msgid="1189071119992726320">"رومنگ بینر آف"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"سروس کی تلاش کر رہا ہے"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"‏Wi-Fi کالنگ"</string>
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"‏Wi-Fi سے کالز کرنے اور پیغامات بھیجنے کیلئے، پہلے اپنے کیریئر سے اس سروس کو ترتیب دینے کیلئے کہیں۔ پھر ترتیبات سے دوبارہ Wi-Fi کالنگ آن کریں۔"</item>
-  </string-array>
+    <!-- no translation found for wfcOperatorErrorAlertMessages:0 (3910386316304772394) -->
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"اپنے کیریئر کے ساتھ رجسٹر کریں"</item>
   </string-array>
@@ -1106,6 +1092,13 @@
       <item quantity="other">‏عوامی Wi-Fi نیٹ ورکس دستیاب ہیں</item>
       <item quantity="one">‏عوامی Wi-Fi نیٹ ورک دستیاب ہے</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"‏عوامی Wi‑Fi نیٹ ورک سے منسلک ہوں"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"‏عوامی Wi‑Fi نیٹ ورک سے منسلک ہو رہا ہے"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"‏عوامی Wi‑Fi نیٹ ورک سے منسلک ہو گيا"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"‏Wi‑Fi نیٹ ورک سے منسلک نہیں ہو سکا"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"تمام نیٹ ورکس دیکھنے کیلئے تھپتھپائيں"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"منسلک کریں"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"تمام نیٹ ورکس"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"‏Wi-Fi نیٹ ورک میں سائن ان کریں"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"نیٹ ورک میں سائن ان کریں"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1780,6 +1773,5 @@
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"‏SIM فراہم کردہ نہیں ہے"</string>
     <string name="mmcc_illegal_ms" msgid="2769452751852211112">"‏SIM کی اجازت نہیں ہے"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"فون کی اجازت نہیں ہے"</string>
-    <!-- no translation found for popup_window_default_title (4874318849712115433) -->
-    <skip />
+    <string name="popup_window_default_title" msgid="4874318849712115433">"پاپ اپ ونڈو"</string>
 </resources>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 7921b09..b204401 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> kun"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> kun <xliff:g id="HOURS">%2$d</xliff:g> soat"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> kun <xliff:g id="HOURS">%2$d</xliff:g> soat"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> soat"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> soat <xliff:g id="MINUTES">%2$d</xliff:g> daq"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> soat <xliff:g id="MINUTES">%2$d</xliff:g> daq"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> daqiqa"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> daqiqa"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> daq <xliff:g id="SECONDS">%2$d</xliff:g> son"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> daq <xliff:g id="SECONDS">%2$d</xliff:g> son"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> soniya"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> soniya"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Nomsiz&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Telefon raqami yo‘q)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Noma’lum"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Ovozli va favqulodda chaqiruvlar ishlamaydi"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Hududingizda mobil tarmoq tomonidan vaqtinchalik taklif etilmayapti"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Tarmoq bilan bog‘lanib bo‘lmadi"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Qabul qilish sifatini yaxshilash uchun Tizim &gt; Tarmoq va Internet &gt; Mobil tarmoqlar > Asosiy tarmoq turi orqali o‘zgartirib ko‘ring."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Qabul qilish sifatini yaxshilash uchun Sozlamalar &gt; Tarmoq va Internet &gt; Mobil tarmoqlar > Asosiy tarmoq turi orqali o‘zgartirib ko‘ring."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Ogohlantirishlar"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Chaqiruvlarni uzatish"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Favqulodda qaytarib chaqirish rejimi"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Xizmatlar qidirilmoqda"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi qo‘ng‘iroq"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi orqali qo‘ng‘iroqlarni amalga oshirish va xabarlar bilan almashinish uchun uyali aloqa operatoringizdan ushbu xizmatni yoqib qo‘yishni so‘rashingiz lozim. Keyin sozlamalarda Wi-Fi qo‘ng‘irog‘i imkoniyatini yoqib olishingiz mumkin."</item>
+    <item msgid="3910386316304772394">"Wi-Fi orqali qo‘ng‘iroqlarni amalga oshirish va xabarlar bilan almashinish uchun uyali aloqa operatoringizdan ushbu xizmatni yoqib qo‘yishni so‘rashingiz lozim. Keyin sozlamalarda Wi-Fi qo‘ng‘irog‘i imkoniyatini yoqib olishingiz mumkin. (Xato kodi: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Mobil operatoringiz yordamida ro‘yxatdan o‘ting"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">Ochiq Wi-Fi tarmoqlari aniqlandi</item>
       <item quantity="one">Ochiq Wi-Fi tarmog‘i aniqlandi</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Ochiq Wi‑Fi tarmoqqa ulaning"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Ochiq Wi‑Fi tarmoqqa ulanilmoqda"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi tarmoqqa ulanildi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi-Fi tarmoqqa ulanib bo‘lmadi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Barcha tarmoqlarni ko‘rish uchun bosing"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Ulanish"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Barcha tarmoqlar"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi tarmoqqa kirish"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Tarmoqqa kirish"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1440,7 +1435,7 @@
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", xavfsiz"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Grafik kalit esimdan chiqdi"</string>
-    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Grafik kalit noto‘g‘ri"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Grafik kalit xato"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Parol noto‘g‘ri"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN-kod noto‘g‘ri"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%1$d</xliff:g> soniyadan so‘ng qayta urinib ko‘ring."</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 614aca7..689c31f 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> ngày"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> ngày <xliff:g id="HOURS">%2$d</xliff:g> giờ"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> ngày <xliff:g id="HOURS">%2$d</xliff:g> giờ"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> giờ"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> giờ <xliff:g id="MINUTES">%2$d</xliff:g> phút"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> giờ <xliff:g id="MINUTES">%2$d</xliff:g> phút"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> phút"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> phút"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> phút <xliff:g id="SECONDS">%2$d</xliff:g> giây"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> phút <xliff:g id="SECONDS">%2$d</xliff:g> giây"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> giây"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> giây"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Không có tiêu đề&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Không có số điện thoại nào)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Không xác định"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Không có dịch vụ thoại/khẩn cấp"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Tạm thời không được cung cấp bởi mạng di động tại vị trí của bạn"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Không thể kết nối mạng"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Để cải thiện khả năng thu tín hiệu, hãy thử thay đổi loại mạng được chọn trong Hệ thống &gt; Mạng và Internet &gt; Mạng di động &gt; Loại mạng ưa thích."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Để cải thiện khả năng thu tín hiệu, hãy thử thay đổi loại mạng được chọn trong Cài đặt &gt; Mạng và Internet &gt; Mạng di động &gt; Loại mạng ưa thích."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Thông báo"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Chuyển tiếp cuộc gọi"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Chế độ gọi lại khẩn cấp"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Đang tìm kiếm Dịch vụ"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Gọi qua Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Để gọi điện và gửi tin nhắn qua Wi-Fi, trước tiên hãy yêu cầu nhà cung cấp dịch vụ của bạn thiết lập dịch vụ này. Sau đó, bật lại gọi qua Wi-Fi từ Cài đặt."</item>
+    <item msgid="3910386316304772394">"Để gọi điện và gửi tin nhắn qua Wi-Fi, trước tiên hãy yêu cầu nhà cung cấp dịch vụ của bạn thiết lập dịch vụ này. Sau đó, bật lại gọi qua Wi-Fi từ Cài đặt. (Mã lỗi: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Đăng ký với nhà cung cấp dịch vụ của bạn"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">Mở các mạng Wi-Fi khả dụng</item>
       <item quantity="one">Mở mạng Wi-Fi khả dụng</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Kết nối với mạng Wi-Fi đang mở"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Đang kết nối với mạng Wi‑Fi đang mở"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Đã kết nối với mạng Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Không thể kết nối với mạng Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Nhấn để xem tất cả các mạng"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Kết nối"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Tất cả các mạng"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Đăng nhập vào mạng Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Đăng nhập vào mạng"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 9738e23..d22c09c 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g>天"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g>天<xliff:g id="HOURS">%2$d</xliff:g>小时"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g>天<xliff:g id="HOURS">%2$d</xliff:g>小时"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g>小时"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g>小时<xliff:g id="MINUTES">%2$d</xliff:g>分钟"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g>小时<xliff:g id="MINUTES">%2$d</xliff:g>分钟"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g>分钟"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> 分钟"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g>分钟<xliff:g id="SECONDS">%2$d</xliff:g>秒"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g>分钟<xliff:g id="SECONDS">%2$d</xliff:g>秒"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g>秒"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g>秒"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;未命名&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(无电话号码)"</string>
     <string name="unknownName" msgid="6867811765370350269">"未知"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"无法使用语音通话/紧急呼救服务"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"您所在位置的移动网络暂时不提供这项服务"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"无法连接网络"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"要改善信号情况,请尝试更改在“系统”&gt;“网络和互联网”&gt;“移动网络”&gt;“首选网络类型”中选择的类型。"</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"要改善信号情况,请尝试更改在“设置”&gt;“网络和互联网”&gt;“移动网络”&gt;“首选网络类型”中选择的类型。"</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"提醒"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"来电转接"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"紧急回拨模式"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"正在搜索服务"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"WLAN 通话"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"要通过 WLAN 打电话和发信息,请先让您的运营商开通此服务,然后再到“设置”中重新开启 WLAN 通话功能。"</item>
+    <item msgid="3910386316304772394">"要通过 WLAN 打电话和发信息,请先让您的运营商开通此服务,然后再到“设置”中重新开启 WLAN 通话功能(错误代码:<xliff:g id="CODE">%1$s</xliff:g>)。"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"向您的运营商注册"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">有可用的开放 WLAN 网络</item>
       <item quantity="one">有可用的开放 WLAN 网络</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"连接到开放的 WLAN 网络"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"正在连接到开放的 WLAN 网络"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"已连接到 WLAN 网络"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"无法连接到 WLAN 网络"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"点按即可查看所有网络"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"连接"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"所有网络"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"登录到WLAN网络"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"登录到网络"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 47b43a7..76187d8 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> 天"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> 天 <xliff:g id="HOURS">%2$d</xliff:g> 小時"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> 天 <xliff:g id="HOURS">%2$d</xliff:g> 小時"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> 小時"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> 小時 <xliff:g id="MINUTES">%2$d</xliff:g> 分鐘"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> 小時 <xliff:g id="MINUTES">%2$d</xliff:g> 分鐘"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> 分鐘"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> 分鐘"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> 分鐘 <xliff:g id="SECONDS">%2$d</xliff:g> 秒"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> 分鐘 <xliff:g id="SECONDS">%2$d</xliff:g> 秒"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> 秒"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> 秒"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;未命名&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(沒有電話號碼)"</string>
     <string name="unknownName" msgid="6867811765370350269">"不明"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"沒有語音/緊急服務"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"您所在位置的流動網絡暫不提供這項服務"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"無法連接網絡"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"如要改善接收品質,請前往 [系統] &gt; [網絡與互聯網] &gt; [流動網絡] &gt; [偏好的網絡類型],然後變更所選的網絡類型。"</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"如要改善接收品質,請前往 [設定] &gt; [網絡與互聯網] &gt; [流動網絡] &gt; [偏好的網絡類型],然後選取其他網路類型。"</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"通知"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"來電轉駁"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"緊急回撥模式"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"正在搜尋服務"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi 通話"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"如要透過 Wi-Fi 撥打電話及傳送訊息,請先向您的流動網絡供應商要求設定此服務。然後再次在「設定」中開啟 Wi-Fi 通話。"</item>
+    <item msgid="3910386316304772394">"如要透過 Wi-Fi 撥打電話和傳送訊息,請先向流動網絡供應商要求設定此服務,然後再次在「設定」中開啟「Wi-Fi 通話」。(錯誤代碼:<xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"向您的流動網絡供應商註冊"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">有可用的公開 Wi-Fi 網絡</item>
       <item quantity="one">有可用的公開 Wi-Fi 網絡</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"連線至開放的 Wi-Fi 網絡"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"正在連線至開放的 Wi-Fi 網絡"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"已連線至 Wi-Fi 網絡"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"無法連線至 Wi-Fi 網絡"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"輕按即可查看所有網絡"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"連線"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"所有網絡"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"登入 Wi-Fi 網絡"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"登入網絡"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 1f047f94..3af7373 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> 天"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> 天 <xliff:g id="HOURS">%2$d</xliff:g> 小時"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> 天 <xliff:g id="HOURS">%2$d</xliff:g> 小時"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> 小時"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> 小時 <xliff:g id="MINUTES">%2$d</xliff:g> 分鐘"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> 小時 <xliff:g id="MINUTES">%2$d</xliff:g> 分鐘"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> 分鐘"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> 分鐘"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> 分鐘 <xliff:g id="SECONDS">%2$d</xliff:g> 秒"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> 分鐘 <xliff:g id="SECONDS">%2$d</xliff:g> 秒"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> 秒"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> 秒"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;未命名&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(沒有電話號碼)"</string>
     <string name="unknownName" msgid="6867811765370350269">"不明"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"無法使用語音/緊急通話服務"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"你所在位置的行動網路暫時不提供這項服務"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"無法連上網路"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"如要改善收訊狀況,請依序開啟 [系統] &gt; [網路與網際網路] &gt; [行動網路] &gt; [偏好的網路類型],然後選取其他網路類型。"</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"如要改善收訊狀況,請依序開啟 [設定] &gt; [網路與網際網路] &gt; [行動網路] &gt; [偏好的網路類型],然後選取其他網路類型。"</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"快訊"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"來電轉接"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"緊急回撥模式"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"正在搜尋服務"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi 通話"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"如要透過 Wi-FI 撥打電話及傳送訊息,請先要求你的電信業者開通這項服務,然後再到「設定」啟用 Wi-Fi 通話功能。"</item>
+    <item msgid="3910386316304772394">"如要透過 Wi-Fi 網路撥打電話及傳送訊息,請先要求電信業者為你設定這項服務,然後再次前往「設定」頁面啟用 Wi-Fi 通話功能。(錯誤代碼:<xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"向你的電信業者註冊"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="other">有多個可用的開放 Wi-Fi 網路</item>
       <item quantity="one">有多個可用的開放 Wi-Fi 網路</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"連線至開放的 Wi‑Fi 網路"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"正在連線至開放的 Wi‑Fi 網路"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"已連線至 Wi-Fi 網路"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"無法連線至 Wi‑Fi 網路"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"輕觸即可查看所有網路"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"連線"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"所有網路"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"登入 Wi-Fi 網路"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"登入網路"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1188,7 +1183,7 @@
     <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"不支援的音訊配件"</string>
     <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"輕觸即可瞭解詳情"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"已連接 USB 偵錯工具"</string>
-    <string name="adb_active_notification_message" msgid="4948470599328424059">"輕觸即可停用 USB 偵錯。"</string>
+    <string name="adb_active_notification_message" msgid="4948470599328424059">"輕觸即可停用 USB 偵錯功能。"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"選取以停用 USB 偵錯。"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"正在接收錯誤報告…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"要分享錯誤報告嗎?"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index e974bae..77bcd84 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -27,18 +27,6 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> izinsuku"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> usuku <xliff:g id="HOURS">%2$d</xliff:g> amahora"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> usuku <xliff:g id="HOURS">%2$d</xliff:g> ihora"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> amahora"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ihora <xliff:g id="MINUTES">%2$d</xliff:g> amaminithi"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> ihora <xliff:g id="MINUTES">%2$d</xliff:g> iminithi"</string>
-    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> amaminithi"</string>
-    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> iminithi"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> iminithi <xliff:g id="SECONDS">%2$d</xliff:g> amasekhondi"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> iminithi <xliff:g id="SECONDS">%2$d</xliff:g> isekhondi"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> amasekhondi"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> isekhondi"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Akunasihloko&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Ayikho inombolo yefoni)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Akwaziwa"</string>
@@ -95,7 +83,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Ayikho isevisi yezwi/yesimo esiphuthumayo"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Okwesikhashana akunikezwa inethiwekhi yeselula endaweni yakho"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Ayikwazi ukufinyelela inethiwekhi"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Ukuze kuthuthukiswe ukwamukelwa, zama ukushintsha uhlobo olukhethiwe kusistimu &gt; Inethiwekhi ne-inthanethi &gt; amanethiwekhi eselula &gt; uhlobo oluncanyelwayo lwenethiwekhi."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Ukuze uthuthukise ukwamukelwa, zama ukushintsha uhlobo olukhethiwe kuzilungiselelo &gt; Inethiwekhi ne-inthanethi &gt; amanethiwekhi eselula &gt; Uhlobo oluncanyelwayo lwenethiwekhi."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Izexwayiso"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Ukudlulisa ikholi"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Imodi yokushayela yesimo esiphuthumayo"</string>
@@ -131,7 +119,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Iseshela Isevisi"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Ukushaya kwe-Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Ukuze wenze amakholi uphinde uthumele imilayezo nge-Wi-FI, qala ucele inkampani yakho yenethiwekhi ukuthi isethe le divayisi. Bese uvula ukushaya kwe-Wi-FI futhi kusukela kuzilungiselelo."</item>
+    <item msgid="3910386316304772394">"Ukuze wenze amakholi uphinde uthumele imilayezo nge-Wi-Fi, qala ucele inkampani yakho yenethiwekhi ukuthi isethe le sevisi. Bese uvula ukushaya kwe-Wi-Fi futhi kusukela kuzilungiselelo (Ikhodi yephutha: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Bhalisa ngenkampani yakho yenethiwekhi"</item>
@@ -1106,6 +1094,13 @@
       <item quantity="one">Vula amanethiwekhi we-Wi-Fi atholakalayo</item>
       <item quantity="other">Vula amanethiwekhi we-Wi-Fi atholakalayo</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Xhuma kunethiwekhi evulekile ye-Wi‑Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Ixhuma kunethiwekhi evulekile ye-Wi‑Fi"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Kuxhumeke kunethiwekhi ye-Wi‑Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Ayikwazanga ukuxhumeka kunethiwekhi ye-Wi-Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Thepha ukuze ubone onke amanethiwekhi"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Xhuma"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Onke amanethiwekhi"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Ngena ngemvume kunethiwekhi ye-Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Ngena ngemvume kunethiwekhi"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index ffd88c3..3033f8c 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2972,4 +2972,7 @@
     <!-- Flag indicating that the actions buttons for a notification should be tinted with by the
          color supplied by the Notification.Builder if present. -->
     <bool name="config_tintNotificationActionButtons">true</bool>
+
+    <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app -->
+    <bool name="config_showAreaUpdateInfoSettings">false</bool>
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 4868774..48e667a 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2825,6 +2825,23 @@
 
     <public type="string" name="paste_as_plain_text" id="0x01040019" />
 
+  <!-- ===============================================================
+       Resources added in version O MR1 of the platform
+
+       NOTE: add <public> elements within a <public-group> like so:
+
+       <public-group type="attr" first-id="0x01010531">
+           <public name="exampleAttr1" />
+           <public name="exampleAttr2" />
+       </public-group>
+
+       To add a new public-group block, choose an id value that is 1 greater
+       than the last of that item above. For example, the last "attr" id
+       value above is 0x01010530, so the public-group of attrs below has
+       the id value of 0x01010531.
+       =============================================================== -->
+    <eat-comment />
+
     <public-group type="attr" first-id="0x01010569">
     </public-group>
 
@@ -2835,6 +2852,7 @@
     </public-group>
 
     <public-group type="string" first-id="0x0104001a">
+      <public name="autofill"/>
     </public-group>
 
   <!-- ===============================================================
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index f48e037..18e8af7 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -38,48 +38,6 @@
          the placeholders. -->
     <string name="fileSizeSuffix"><xliff:g id="number" example="123">%1$s</xliff:g> <xliff:g id="unit" example="MB">%2$s</xliff:g></string>
 
-    <!-- [CHAR_LIMIT=10] Suffix added to signify duration in days -->
-    <string name="durationDays"><xliff:g id="days">%1$d</xliff:g> days</string>
-
-    <!-- [CHAR_LIMIT=10] Suffix added to signify duration of one day with hours -->
-    <string name="durationDayHours"><xliff:g id="days">%1$d</xliff:g> day
-            <xliff:g id="hours">%2$d</xliff:g> hrs</string>
-
-    <!-- [CHAR_LIMIT=10] Suffix added to signify duration of one day with one hours -->
-    <string name="durationDayHour"><xliff:g id="days">%1$d</xliff:g> day
-            <xliff:g id="hours">%2$d</xliff:g> hr</string>
-
-    <!-- [CHAR_LIMIT=10] Suffix added to signify duration in hours -->
-    <string name="durationHours"><xliff:g id="hours">%1$d</xliff:g> hrs</string>
-
-    <!-- [CHAR_LIMIT=10] Suffix added to signify duration of one hour with minutes -->
-    <string name="durationHourMinutes"><xliff:g id="hours">%1$d</xliff:g> hr
-            <xliff:g id="minutes">%2$d</xliff:g> mins</string>
-
-    <!-- [CHAR_LIMIT=10] Suffix added to signify duration of one hour with one minute -->
-    <string name="durationHourMinute"><xliff:g id="hours">%1$d</xliff:g> hr
-            <xliff:g id="minutes">%2$d</xliff:g> min</string>
-
-    <!-- [CHAR_LIMIT=10] Suffix added to signify duration in minutes -->
-    <string name="durationMinutes"><xliff:g id="minutes">%1$d</xliff:g> mins</string>
-
-    <!-- [CHAR_LIMIT=10] Suffix added to signify duration of one minute -->
-    <string name="durationMinute"><xliff:g id="minutes">%1$d</xliff:g> min</string>
-
-    <!-- [CHAR_LIMIT=10] Suffix added to signify duration of one minute with seconds -->
-    <string name="durationMinuteSeconds"><xliff:g id="minutes">%1$d</xliff:g> min
-            <xliff:g id="seconds">%2$d</xliff:g> secs</string>
-
-    <!-- [CHAR_LIMIT=10] Suffix added to signify duration of one minute with one second -->
-    <string name="durationMinuteSecond"><xliff:g id="minutes">%1$d</xliff:g> min
-            <xliff:g id="seconds">%2$d</xliff:g> sec</string>
-
-    <!-- [CHAR_LIMIT=10] Suffix added to signify duration in seconds -->
-    <string name="durationSeconds"><xliff:g id="seconds">%1$d</xliff:g> secs</string>
-
-    <!-- [CHAR_LIMIT=10] Suffix added to signify duration of one second -->
-    <string name="durationSecond"><xliff:g id="seconds">%1$d</xliff:g> sec</string>
-
     <!-- Used in Contacts for a field that has no label and in Note Pad
          for a note with no name. -->
     <string name="untitled">&lt;Untitled&gt;</string>
@@ -204,7 +162,7 @@
     <!-- Displayed to tell the user that they should switch their network preference. -->
     <string name="NetworkPreferenceSwitchTitle">Can\u2019t reach network</string>
     <!-- Displayed to tell the user that they should switch their network preference. -->
-    <string name="NetworkPreferenceSwitchSummary">To improve reception, try changing the type selected at System &gt; Network &amp; Internet &gt; Mobile networks &gt; Preferred network type."</string>
+    <string name="NetworkPreferenceSwitchSummary">To improve reception, try changing the type selected at Settings &gt; Network &amp; Internet &gt; Mobile networks &gt; Preferred network type."</string>
 
     <!-- Telephony notification channel name for a channel containing network alert notifications. -->
     <string name="notification_channel_network_alert">Alerts</string>
@@ -266,7 +224,7 @@
     <string name="wfcRegErrorTitle">Wi-Fi Calling</string>
     <!-- WFC Operator Error Messages showed as alerts -->
     <string-array name="wfcOperatorErrorAlertMessages">
-        <item>To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings.</item>
+        <item>To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings. (Error code: <xliff:g id="code" example="REG09 - No 911 Address">%1$s</xliff:g>)</item>
     </string-array>
     <!-- WFC Operator Error Messages showed as notifications -->
     <string-array name="wfcOperatorErrorNotificationMessages">
@@ -3003,6 +2961,21 @@
         <item quantity="other">Open Wi-Fi networks available</item>
     </plurals>
 
+    <!-- Notification title for a nearby open wireless network.-->
+    <string name="wifi_available_title">Connect to open Wi\u2011Fi network</string>
+    <!-- Notification title when the system is connecting to the specified open network. The network name is specified in the notification content. -->
+    <string name="wifi_available_title_connecting">Connecting to open Wi\u2011Fi network</string>
+    <!-- Notification title when the system has connected to the open network. The network name is specified in the notification content. -->
+    <string name="wifi_available_title_connected">Connected to Wi\u2011Fi network</string>
+    <!-- Notification title when the system failed to connect to the specified open network. -->
+    <string name="wifi_available_title_failed_to_connect">Could not connect to Wi\u2011Fi network</string>
+    <!-- Notification content when the system failed to connect to the specified open network. This informs the user that tapping on this notification will open the wifi picker. -->
+    <string name="wifi_available_content_failed_to_connect">Tap to see all networks</string>
+    <!-- Notification action name for connecting to the network specified in the notification body. -->
+    <string name="wifi_available_action_connect">Connect</string>
+    <!-- Notification action name for opening the wifi picker, showing the user all the nearby networks. -->
+    <string name="wifi_available_action_all_networks">All Networks</string>
+
     <!-- A notification is shown when a wifi captive portal network is detected.  This is the notification's title. -->
     <string name="wifi_available_sign_in">Sign in to Wi-Fi network</string>
 
@@ -4698,6 +4671,9 @@
     <!-- Primary ETWS (Earthquake and Tsunami Warning System) default message for test -->
     <string name="etws_primary_default_message_test">Emergency messages test</string>
 
+    <!-- Content description for the reply button in the notification area [CHAR LIMIT=NONE]-->
+    <string name="notification_reply_button_accessibility">Reply</string>
+
     <!-- Primary ETWS (Earthquake and Tsunami Warning System) default message for others -->
     <string name="etws_primary_default_message_others"></string>
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 4e634b7..c4e43a3 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -656,18 +656,6 @@
   <java-symbol type="string" name="display_manager_overlay_display_secure_suffix" />
   <java-symbol type="string" name="display_manager_overlay_display_title" />
   <java-symbol type="string" name="double_tap_toast" />
-  <java-symbol type="string" name="durationDays" />
-  <java-symbol type="string" name="durationDayHours" />
-  <java-symbol type="string" name="durationDayHour" />
-  <java-symbol type="string" name="durationHours" />
-  <java-symbol type="string" name="durationHourMinutes" />
-  <java-symbol type="string" name="durationHourMinute" />
-  <java-symbol type="string" name="durationMinutes" />
-  <java-symbol type="string" name="durationMinute" />
-  <java-symbol type="string" name="durationMinuteSeconds" />
-  <java-symbol type="string" name="durationMinuteSecond" />
-  <java-symbol type="string" name="durationSeconds" />
-  <java-symbol type="string" name="durationSecond" />
   <java-symbol type="string" name="elapsed_time_short_format_h_mm_ss" />
   <java-symbol type="string" name="elapsed_time_short_format_mm_ss" />
   <java-symbol type="string" name="emailTypeCustom" />
@@ -1869,6 +1857,13 @@
   <java-symbol type="layout" name="app_error_dialog" />
   <java-symbol type="plurals" name="wifi_available" />
   <java-symbol type="plurals" name="wifi_available_detailed" />
+  <java-symbol type="string" name="wifi_available_title" />
+  <java-symbol type="string" name="wifi_available_title_connecting" />
+  <java-symbol type="string" name="wifi_available_title_connected" />
+  <java-symbol type="string" name="wifi_available_title_failed_to_connect" />
+  <java-symbol type="string" name="wifi_available_content_failed_to_connect" />
+  <java-symbol type="string" name="wifi_available_action_connect" />
+  <java-symbol type="string" name="wifi_available_action_all_networks" />
   <java-symbol type="string" name="accessibility_binding_label" />
   <java-symbol type="string" name="adb_active_notification_message" />
   <java-symbol type="string" name="adb_active_notification_title" />
@@ -3046,8 +3041,11 @@
 
   <java-symbol type="drawable" name="stat_sys_vitals" />
 
+  <java-symbol type="color" name="text_color_primary" />
+
   <java-symbol type="array" name="config_batteryPackageTypeSystem" />
   <java-symbol type="array" name="config_batteryPackageTypeService" />
 
   <java-symbol type="string" name="popup_window_default_title" />
+  <java-symbol type="bool" name="config_showAreaUpdateInfoSettings" />
 </resources>
diff --git a/core/tests/coretests/res/layout/activity_editor_cursor_test.xml b/core/tests/coretests/res/layout/activity_editor_cursor_test.xml
new file mode 100644
index 0000000..45a9318
--- /dev/null
+++ b/core/tests/coretests/res/layout/activity_editor_cursor_test.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2017 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+             android:layout_width="match_parent"
+             android:layout_height="match_parent">
+
+    <EditText
+        android:id="@+id/edittext"
+        android:layout_width="200px"
+        android:layout_height="wrap_content"
+        android:padding="15px"
+        android:lines="1"
+        android:singleLine="true"
+        android:textSize="30px"/>
+
+</FrameLayout>
diff --git a/core/tests/coretests/src/android/app/timezone/RulesStateTest.java b/core/tests/coretests/src/android/app/timezone/RulesStateTest.java
index a9357c9..7f4819b 100644
--- a/core/tests/coretests/src/android/app/timezone/RulesStateTest.java
+++ b/core/tests/coretests/src/android/app/timezone/RulesStateTest.java
@@ -107,7 +107,7 @@
                 "2016a", formatVersion(1, 1), true /* operationInProgress */,
                 RulesState.STAGED_OPERATION_UNKNOWN, null /* stagedDistroRulesVersion */,
                 RulesState.DISTRO_STATUS_UNKNOWN, null /* installedDistroRulesVersion */);
-        checkParcelableRoundTrip(rulesStateWithNulls);
+        checkParcelableRoundTrip(rulesStateWithUnknowns);
     }
 
     private static void checkParcelableRoundTrip(RulesState rulesState) {
@@ -121,55 +121,14 @@
     }
 
     @Test
-    public void isSystemVersionOlderThan() {
+    public void isSystemVersionNewerThan() {
         RulesState rulesState = new RulesState(
                 "2016b", formatVersion(1, 1), false /* operationInProgress */,
                 RulesState.STAGED_OPERATION_NONE, null /* stagedDistroRulesVersion */,
                 RulesState.DISTRO_STATUS_INSTALLED, rulesVersion("2016b", 3));
-        assertFalse(rulesState.isSystemVersionOlderThan(rulesVersion("2016a", 1)));
-        assertFalse(rulesState.isSystemVersionOlderThan(rulesVersion("2016b", 1)));
-        assertTrue(rulesState.isSystemVersionOlderThan(rulesVersion("2016c", 1)));
-    }
-
-    @Test
-    public void isInstalledDistroOlderThan() {
-        RulesState operationInProgress = new RulesState(
-                "2016b", formatVersion(1, 1), true /* operationInProgress */,
-                RulesState.STAGED_OPERATION_UNKNOWN, null /* stagedDistroRulesVersion */,
-                RulesState.STAGED_OPERATION_UNKNOWN, null /* installedDistroRulesVersion */);
-        try {
-            operationInProgress.isInstalledDistroOlderThan(rulesVersion("2016b", 1));
-            fail();
-        } catch (IllegalStateException expected) {
-        }
-
-        RulesState nothingInstalled = new RulesState(
-                "2016b", formatVersion(1, 1), false /* operationInProgress */,
-                RulesState.STAGED_OPERATION_NONE, null /* stagedDistroRulesVersion */,
-                RulesState.DISTRO_STATUS_NONE, null /* installedDistroRulesVersion */);
-        try {
-            nothingInstalled.isInstalledDistroOlderThan(rulesVersion("2016b", 1));
-            fail();
-        } catch (IllegalStateException expected) {
-        }
-
-        DistroRulesVersion installedVersion = rulesVersion("2016b", 3);
-        RulesState rulesStateWithInstalledVersion = new RulesState(
-                "2016b", formatVersion(1, 1), false /* operationInProgress */,
-                RulesState.STAGED_OPERATION_NONE, null /* stagedDistroRulesVersion */,
-                RulesState.DISTRO_STATUS_INSTALLED, installedVersion);
-
-        DistroRulesVersion olderRules = rulesVersion("2016a", 1);
-        assertEquals(installedVersion.isOlderThan(olderRules),
-                rulesStateWithInstalledVersion.isInstalledDistroOlderThan(olderRules));
-
-        DistroRulesVersion sameRules = rulesVersion("2016b", 1);
-        assertEquals(installedVersion.isOlderThan(sameRules),
-                rulesStateWithInstalledVersion.isInstalledDistroOlderThan(sameRules));
-
-        DistroRulesVersion newerRules = rulesVersion("2016c", 1);
-        assertEquals(installedVersion.isOlderThan(newerRules),
-                rulesStateWithInstalledVersion.isInstalledDistroOlderThan(newerRules));
+        assertTrue(rulesState.isSystemVersionNewerThan(rulesVersion("2016a", 1)));
+        assertFalse(rulesState.isSystemVersionNewerThan(rulesVersion("2016b", 1)));
+        assertFalse(rulesState.isSystemVersionNewerThan(rulesVersion("2016c", 1)));
     }
 
     private static void assertEqualsContract(RulesState one, RulesState two) {
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index 423d45ea..0a89b74 100644
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -25,11 +25,14 @@
 import static android.system.OsConstants.S_IXGRP;
 import static android.system.OsConstants.S_IXOTH;
 
-import android.app.PackageInstallObserver;
 import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.IIntentReceiver;
+import android.content.IIntentSender;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.IntentSender;
+import android.content.pm.PackageInstaller.SessionParams;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.PackageParser.PackageParserException;
 import android.content.res.Resources;
@@ -46,7 +49,6 @@
 import android.os.ServiceManager;
 import android.os.StatFs;
 import android.os.SystemClock;
-import android.os.UserManager;
 import android.os.storage.IStorageManager;
 import android.os.storage.StorageListener;
 import android.os.storage.StorageManager;
@@ -67,9 +69,13 @@
 
 import dalvik.system.VMRuntime;
 
+import libcore.io.IoUtils;
+
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
 import java.nio.file.Files;
 import java.nio.file.Paths;
 import java.nio.file.StandardCopyOption;
@@ -77,6 +83,7 @@
 import java.util.List;
 import java.util.Set;
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.SynchronousQueue;
 import java.util.concurrent.TimeUnit;
 
 public class PackageManagerTests extends AndroidTestCase {
@@ -130,29 +137,7 @@
         super.tearDown();
     }
 
-    private class TestInstallObserver extends PackageInstallObserver {
-        public int returnCode;
-
-        private boolean doneFlag = false;
-
-        @Override
-        public void onPackageInstalled(String basePackageName, int returnCode, String msg,
-                Bundle extras) {
-            Log.d(TAG, "onPackageInstalled: code=" + returnCode + ", msg=" + msg + ", extras="
-                    + extras);
-            synchronized (this) {
-                this.returnCode = returnCode;
-                doneFlag = true;
-                notifyAll();
-            }
-        }
-
-        public boolean isDone() {
-            return doneFlag;
-        }
-    }
-
-    abstract class GenericReceiver extends BroadcastReceiver {
+    private abstract static class GenericReceiver extends BroadcastReceiver {
         private boolean doneFlag = false;
 
         boolean received = false;
@@ -184,7 +169,7 @@
         }
     }
 
-    class InstallReceiver extends GenericReceiver {
+    private static class InstallReceiver extends GenericReceiver {
         String pkgName;
 
         InstallReceiver(String pkgName) {
@@ -208,100 +193,152 @@
         }
     }
 
+    private static class LocalIntentReceiver {
+        private final SynchronousQueue<Intent> mResult = new SynchronousQueue<>();
+
+        private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() {
+            @Override
+            public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken,
+                    IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
+                try {
+                    mResult.offer(intent, 5, TimeUnit.SECONDS);
+                } catch (InterruptedException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        };
+
+        public IntentSender getIntentSender() {
+            return new IntentSender((IIntentSender) mLocalSender);
+        }
+
+        public Intent getResult() {
+            try {
+                return mResult.take();
+            } catch (InterruptedException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
     private PackageManager getPm() {
         return mContext.getPackageManager();
     }
 
-    private IPackageManager getIPm() {
-        IPackageManager ipm  = IPackageManager.Stub.asInterface(
-                ServiceManager.getService("package"));
-        return ipm;
+    private PackageInstaller getPi() {
+        return getPm().getPackageInstaller();
     }
 
-    public void invokeInstallPackage(Uri packageURI, int flags, GenericReceiver receiver,
-            boolean shouldSucceed) {
-        TestInstallObserver observer = new TestInstallObserver();
-        mContext.registerReceiver(receiver, receiver.filter);
+    private void writeSplitToInstallSession(PackageInstaller.Session session, String inPath,
+            String splitName) throws RemoteException {
+        long sizeBytes = 0;
+        final File file = new File(inPath);
+        if (file.isFile()) {
+            sizeBytes = file.length();
+        } else {
+            return;
+        }
+
+        InputStream in = null;
+        OutputStream out = null;
         try {
-            // Wait on observer
-            synchronized (observer) {
-                synchronized (receiver) {
-                    getPm().installPackage(packageURI, observer, flags, null);
-                    long waitTime = 0;
-                    while ((!observer.isDone()) && (waitTime < MAX_WAIT_TIME)) {
-                        try {
-                            observer.wait(WAIT_TIME_INCR);
-                            waitTime += WAIT_TIME_INCR;
-                        } catch (InterruptedException e) {
-                            Log.i(TAG, "Interrupted during sleep", e);
-                        }
-                    }
-                    if (!observer.isDone()) {
-                        fail("Timed out waiting for packageInstalled callback");
-                    }
+            in = new FileInputStream(inPath);
+            out = session.openWrite(splitName, 0, sizeBytes);
 
-                    if (shouldSucceed) {
-                        if (observer.returnCode != PackageManager.INSTALL_SUCCEEDED) {
-                            fail("Package installation should have succeeded, but got code "
-                                    + observer.returnCode);
-                        }
-                    } else {
-                        if (observer.returnCode == PackageManager.INSTALL_SUCCEEDED) {
-                            fail("Package installation should fail");
-                        }
-
-                        /*
-                         * We'll never expect get a notification since we
-                         * shouldn't succeed.
-                         */
-                        return;
-                    }
-
-                    // Verify we received the broadcast
-                    waitTime = 0;
-                    while ((!receiver.isDone()) && (waitTime < MAX_WAIT_TIME)) {
-                        try {
-                            receiver.wait(WAIT_TIME_INCR);
-                            waitTime += WAIT_TIME_INCR;
-                        } catch (InterruptedException e) {
-                            Log.i(TAG, "Interrupted during sleep", e);
-                        }
-                    }
-                    if (!receiver.isDone()) {
-                        fail("Timed out waiting for PACKAGE_ADDED notification");
-                    }
-                }
+            int total = 0;
+            byte[] buffer = new byte[65536];
+            int c;
+            while ((c = in.read(buffer)) != -1) {
+                total += c;
+                out.write(buffer, 0, c);
             }
+            session.fsync(out);
+        } catch (IOException e) {
+            fail("Error: failed to write; " + e.getMessage());
         } finally {
-            mContext.unregisterReceiver(receiver);
+            IoUtils.closeQuietly(out);
+            IoUtils.closeQuietly(in);
+            IoUtils.closeQuietly(session);
         }
     }
 
-    public void invokeInstallPackageFail(Uri packageURI, int flags, int expectedResult) {
-        TestInstallObserver observer = new TestInstallObserver();
-        try {
-            // Wait on observer
-            synchronized (observer) {
-                getPm().installPackage(packageURI, observer, flags, null);
+    private void invokeInstallPackage(Uri packageUri, int flags, GenericReceiver receiver,
+            boolean shouldSucceed) {
+        mContext.registerReceiver(receiver, receiver.filter);
+        synchronized (receiver) {
+            final String inPath = packageUri.getPath();
+            PackageInstaller.Session session = null;
+            try {
+                final SessionParams sessionParams =
+                        new SessionParams(SessionParams.MODE_FULL_INSTALL);
+                sessionParams.installFlags = flags;
+                final int sessionId = getPi().createSession(sessionParams);
+                session = getPi().openSession(sessionId);
+                writeSplitToInstallSession(session, inPath, "base.apk");
+                final LocalIntentReceiver localReceiver = new LocalIntentReceiver();
+                session.commit(localReceiver.getIntentSender());
+                final Intent result = localReceiver.getResult();
+                final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
+                        PackageInstaller.STATUS_FAILURE);
+                if (shouldSucceed) {
+                    if (status != PackageInstaller.STATUS_SUCCESS) {
+                        fail("Installation should have succeeded, but got code " + status);
+                    }
+                } else {
+                    if (status == PackageInstaller.STATUS_SUCCESS) {
+                        fail("Installation should have failed");
+                    }
+                    // We'll never get a broadcast since the package failed to install
+                    return;
+                }
+                // Verify we received the broadcast
                 long waitTime = 0;
-                while ((!observer.isDone()) && (waitTime < MAX_WAIT_TIME)) {
+                while ((!receiver.isDone()) && (waitTime < MAX_WAIT_TIME)) {
                     try {
-                        observer.wait(WAIT_TIME_INCR);
+                        receiver.wait(WAIT_TIME_INCR);
                         waitTime += WAIT_TIME_INCR;
                     } catch (InterruptedException e) {
                         Log.i(TAG, "Interrupted during sleep", e);
                     }
                 }
-                if (!observer.isDone()) {
-                    fail("Timed out waiting for packageInstalled callback");
+                if (!receiver.isDone()) {
+                    fail("Timed out waiting for PACKAGE_ADDED notification");
                 }
-                assertEquals(expectedResult, observer.returnCode);
+            } catch (IllegalArgumentException | IOException | RemoteException e) {
+                Log.w(TAG, "Failed to install package; path=" + inPath, e);
+                fail("Failed to install package; path=" + inPath + ", e=" + e);
+            } finally {
+                IoUtils.closeQuietly(session);
+                mContext.unregisterReceiver(receiver);
             }
-        } finally {
         }
     }
 
-    Uri getInstallablePackage(int fileResId, File outFile) {
+    private void invokeInstallPackageFail(Uri packageUri, int flags, int expectedResult) {
+        final String inPath = packageUri.getPath();
+        PackageInstaller.Session session = null;
+        try {
+            final SessionParams sessionParams =
+                    new SessionParams(SessionParams.MODE_FULL_INSTALL);
+            sessionParams.installFlags = flags;
+            final int sessionId = getPi().createSession(sessionParams);
+            session = getPi().openSession(sessionId);
+            writeSplitToInstallSession(session, inPath, "base.apk");
+            final LocalIntentReceiver localReceiver = new LocalIntentReceiver();
+            session.commit(localReceiver.getIntentSender());
+            final Intent result = localReceiver.getResult();
+            final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
+                    PackageInstaller.STATUS_SUCCESS);
+            assertEquals(expectedResult, status);
+        } catch (IllegalArgumentException | IOException | RemoteException e) {
+            Log.w(TAG, "Failed to install package; path=" + inPath, e);
+            fail("Failed to install package; path=" + inPath + ", e=" + e);
+        } finally {
+            IoUtils.closeQuietly(session);
+        }
+    }
+
+    private Uri getInstallablePackage(int fileResId, File outFile) {
         Resources res = mContext.getResources();
         InputStream is = null;
         try {
@@ -430,28 +467,17 @@
 
             int rLoc = getInstallLoc(flags, expInstallLocation, pkgLen);
             if (rLoc == INSTALL_LOC_INT) {
-                if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) {
-                    assertTrue("The application should be installed forward locked",
-                            (info.privateFlags & ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK) != 0);
-                    assertStartsWith("The APK path should point to the ASEC",
-                            SECURE_CONTAINERS_PREFIX, srcPath);
-                    assertStartsWith("The public APK path should point to the ASEC",
-                            SECURE_CONTAINERS_PREFIX, publicSrcPath);
-                    assertStartsWith("The native library path should point to the ASEC",
-                            SECURE_CONTAINERS_PREFIX, info.nativeLibraryDir);
-                } else {
-                    assertFalse(
-                            (info.privateFlags & ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK) != 0);
-                    assertEquals(appInstallPath, srcPath);
-                    assertEquals(appInstallPath, publicSrcPath);
-                    assertStartsWith("Native library should point to shared lib directory",
-                            expectedLibPath, info.nativeLibraryDir);
-                    assertDirOwnerGroupPermsIfExists(
-                            "Native library directory should be owned by system:system and 0755",
-                            Process.SYSTEM_UID, Process.SYSTEM_UID,
-                            S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH,
-                            info.nativeLibraryDir);
-                }
+                assertFalse(
+                        (info.privateFlags & ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK) != 0);
+                assertEquals(appInstallPath, srcPath);
+                assertEquals(appInstallPath, publicSrcPath);
+                assertStartsWith("Native library should point to shared lib directory",
+                        expectedLibPath, info.nativeLibraryDir);
+                assertDirOwnerGroupPermsIfExists(
+                        "Native library directory should be owned by system:system and 0755",
+                        Process.SYSTEM_UID, Process.SYSTEM_UID,
+                        S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH,
+                        info.nativeLibraryDir);
                 assertFalse((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
 
                 // Make sure the native library dir is not a symlink
@@ -465,13 +491,8 @@
                     }
                 }
             } else if (rLoc == INSTALL_LOC_SD) {
-                if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) {
-                    assertTrue("The application should be installed forward locked",
-                            (info.privateFlags & ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK) != 0);
-                } else {
-                    assertFalse("The application should not be installed forward locked",
-                            (info.privateFlags & ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK) != 0);
-                }
+                assertFalse("The application should not be installed forward locked",
+                        (info.privateFlags & ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK) != 0);
                 assertTrue("Application flags (" + info.flags
                         + ") should contain FLAG_EXTERNAL_STORAGE",
                         (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
@@ -598,7 +619,8 @@
         }
     }
 
-    private InstallParams sampleInstallFromRawResource(int flags, boolean cleanUp) throws Exception {
+    private InstallParams sampleInstallFromRawResource(int flags, boolean cleanUp)
+            throws Exception {
         return installFromRawResource("install.apk", R.raw.install, flags, cleanUp, false, -1,
                 PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
     }
@@ -721,7 +743,7 @@
                         PackageManager.MATCH_UNINSTALLED_PACKAGES);
                 GenericReceiver receiver = new DeleteReceiver(pkg.packageName);
                 invokeDeletePackage(pkg.packageName, 0, receiver);
-            } catch (NameNotFoundException e) {
+            } catch (IllegalArgumentException | NameNotFoundException e) {
             }
         }
         try {
@@ -761,11 +783,6 @@
     }
 
     @LargeTest
-    public void testInstallFwdLockedInternal() throws Exception {
-        sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, true);
-    }
-
-    @LargeTest
     public void testInstallSdcard() throws Exception {
         // Do not run on devices with emulated external storage.
         if (Environment.isExternalStorageEmulated()) {
@@ -869,11 +886,6 @@
     }
 
     @LargeTest
-    public void testReplaceFailFwdLockedInternal() throws Exception {
-        sampleReplaceFromRawResource(PackageManager.INSTALL_FORWARD_LOCK);
-    }
-
-    @LargeTest
     public void testReplaceFailSdcard() throws Exception {
         // Do not run on devices with emulated external storage.
         if (Environment.isExternalStorageEmulated()) {
@@ -889,12 +901,6 @@
     }
 
     @LargeTest
-    public void testReplaceFwdLockedInternal() throws Exception {
-        sampleReplaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING
-                | PackageManager.INSTALL_FORWARD_LOCK);
-    }
-
-    @LargeTest
     public void testReplaceSdcard() throws Exception {
         // Do not run on devices with emulated external storage.
         if (Environment.isExternalStorageEmulated()) {
@@ -984,10 +990,11 @@
 
         mContext.registerReceiver(receiver, receiver.filter);
         try {
-            DeleteObserver observer = new DeleteObserver(pkgName);
-
-            getPm().deletePackage(pkgName, observer, flags | PackageManager.DELETE_ALL_USERS);
-            observer.waitForCompletion(MAX_WAIT_TIME);
+            final LocalIntentReceiver localReceiver = new LocalIntentReceiver();
+            getPi().uninstall(pkgName,
+                    flags | PackageManager.DELETE_ALL_USERS,
+                    localReceiver.getIntentSender());
+            localReceiver.getResult();
 
             assertUninstalled(info);
 
@@ -1050,11 +1057,6 @@
     }
 
     @LargeTest
-    public void testDeleteFwdLockedInternal() throws Exception {
-        deleteFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, 0);
-    }
-
-    @LargeTest
     public void testDeleteSdcard() throws Exception {
         // Do not run on devices with emulated external storage.
         if (Environment.isExternalStorageEmulated()) {
@@ -1070,11 +1072,6 @@
     }
 
     @LargeTest
-    public void testDeleteFwdLockedInternalRetainData() throws Exception {
-        deleteFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, PackageManager.DELETE_KEEP_DATA);
-    }
-
-    @LargeTest
     public void testDeleteSdcardRetainData() throws Exception {
         // Do not run on devices with emulated external storage.
         if (Environment.isExternalStorageEmulated()) {
@@ -1342,9 +1339,11 @@
             final ApplicationInfo info = getPm().getApplicationInfo(pkgName,
                     PackageManager.MATCH_UNINSTALLED_PACKAGES);
             if (info != null) {
-                DeleteObserver observer = new DeleteObserver(pkgName);
-                getPm().deletePackage(pkgName, observer, PackageManager.DELETE_ALL_USERS);
-                observer.waitForCompletion(MAX_WAIT_TIME);
+                final LocalIntentReceiver localReceiver = new LocalIntentReceiver();
+                getPi().uninstall(pkgName,
+                        PackageManager.DELETE_ALL_USERS,
+                        localReceiver.getIntentSender());
+                localReceiver.getResult();
                 assertUninstalled(info);
             }
         } catch (IllegalArgumentException | NameNotFoundException e) {
@@ -1380,31 +1379,6 @@
                 0, true, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
     }
 
-    @LargeTest
-    public void testManifestInstallLocationFwdLockedFlagSdcard() throws Exception {
-        // Do not run on devices with emulated external storage.
-        if (Environment.isExternalStorageEmulated()) {
-            return;
-        }
-
-        installFromRawResource("install.apk", R.raw.install_loc_unspecified,
-                PackageManager.INSTALL_FORWARD_LOCK |
-                PackageManager.INSTALL_EXTERNAL, true, false, -1,
-                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
-    }
-
-    @LargeTest
-    public void testManifestInstallLocationFwdLockedSdcard() throws Exception {
-        // Do not run on devices with emulated external storage.
-        if (Environment.isExternalStorageEmulated()) {
-            return;
-        }
-
-        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
-                PackageManager.INSTALL_FORWARD_LOCK, true, false, -1,
-                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
-    }
-
     /*
      * Install a package on internal flash via PackageManager install flag. Replace
      * the package via flag to install on sdcard. Make sure the new flag overrides
@@ -1704,20 +1678,6 @@
     }
 
     @LargeTest
-    public void testMoveAppForwardLocked() throws Exception {
-        // Do not run on devices with emulated external storage.
-        if (Environment.isExternalStorageEmulated()) {
-            return;
-        }
-
-        int installFlags = PackageManager.INSTALL_FORWARD_LOCK;
-        int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
-        boolean fail = false;
-        int result = PackageManager.MOVE_SUCCEEDED;
-        sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
-    }
-
-    @LargeTest
     public void testMoveAppFailInternalToExternalDelete() throws Exception {
         // Do not run on devices with emulated external storage.
         if (Environment.isExternalStorageEmulated()) {
@@ -1771,7 +1731,7 @@
             // Try to install and make sure an error code is returned.
             installFromRawResource("install.apk", R.raw.install,
                     PackageManager.INSTALL_EXTERNAL, false,
-                    true, PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE,
+                    true, PackageInstaller.STATUS_FAILURE_STORAGE,
                     PackageInfo.INSTALL_LOCATION_AUTO);
         } finally {
             // Restore original media state
@@ -1844,63 +1804,6 @@
     }
 
     /*
-     * Install an app forward-locked.
-     */
-    @LargeTest
-    public void testFlagF() throws Exception {
-        sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, true);
-    }
-
-    /*
-     * Install an app with both internal and external flags set. should fail
-     */
-    @LargeTest
-    public void testFlagIE() throws Exception {
-        installFromRawResource("install.apk", R.raw.install,
-                PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_INTERNAL,
-                false,
-                true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
-                PackageInfo.INSTALL_LOCATION_AUTO);
-    }
-
-    /*
-     * Install an app with both internal and forward-lock flags set.
-     */
-    @LargeTest
-    public void testFlagIF() throws Exception {
-        sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK
-                | PackageManager.INSTALL_INTERNAL, true);
-    }
-
-    /*
-     * Install an app with both external and forward-lock flags set.
-     */
-    @LargeTest
-    public void testFlagEF() throws Exception {
-        // Do not run on devices with emulated external storage.
-        if (Environment.isExternalStorageEmulated()) {
-            return;
-        }
-
-        sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK
-                | PackageManager.INSTALL_EXTERNAL, true);
-    }
-
-    /*
-     * Install an app with both internal and external flags set with forward
-     * lock. Should fail.
-     */
-    @LargeTest
-    public void testFlagIEF() throws Exception {
-        installFromRawResource("install.apk", R.raw.install,
-                PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_INTERNAL |
-                PackageManager.INSTALL_EXTERNAL,
-                false,
-                true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
-                PackageInfo.INSTALL_LOCATION_AUTO);
-    }
-
-    /*
      * Install an app with both internal and manifest option set.
      * should install on internal.
      */
@@ -1991,55 +1894,6 @@
     }
 
     /*
-     * Install an app with fwd locked flag set and install location set to
-     * internal. should install internally.
-     */
-    @LargeTest
-    public void testFlagFManifestI() throws Exception {
-        installFromRawResource("install.apk", R.raw.install_loc_internal,
-                PackageManager.INSTALL_FORWARD_LOCK,
-                true,
-                false, -1,
-                PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
-    }
-
-    /*
-     * Install an app with fwd locked flag set and install location set to
-     * preferExternal. Should install externally.
-     */
-    @LargeTest
-    public void testFlagFManifestE() throws Exception {
-        // Do not run on devices with emulated external storage.
-        if (Environment.isExternalStorageEmulated()) {
-            return;
-        }
-
-        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
-                PackageManager.INSTALL_FORWARD_LOCK,
-                true,
-                false, -1,
-                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
-    }
-
-    /*
-     * Install an app with fwd locked flag set and install location set to auto.
-     * should install externally.
-     */
-    @LargeTest
-    public void testFlagFManifestA() throws Exception {
-        // Do not run on devices with emulated external storage.
-        if (Environment.isExternalStorageEmulated()) {
-            return;
-        }
-
-        installFromRawResource("install.apk", R.raw.install_loc_auto,
-                PackageManager.INSTALL_FORWARD_LOCK,
-                true,
-                false, -1,
-                PackageInfo.INSTALL_LOCATION_AUTO);
-    }
-
-    /*
      * The following test functions verify install location for existing apps.
      * ie existing app can be installed internally or externally. If install
      * flag is explicitly set it should override current location. If manifest location
@@ -2134,48 +1988,6 @@
                 -1);
     }
 
-    @Suppress
-    @LargeTest
-    public void testFlagFExistingI() throws Exception {
-        int iFlags = PackageManager.INSTALL_INTERNAL;
-        int rFlags = PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_REPLACE_EXISTING;
-        // First install.
-        installFromRawResource("install.apk", R.raw.install,
-                iFlags,
-                false,
-                false, -1,
-                -1);
-        // Replace now
-        installFromRawResource("install.apk", R.raw.install,
-                rFlags,
-                true,
-                false, -1,
-                -1);
-    }
-
-    @LargeTest
-    public void testFlagFExistingE() throws Exception {
-        // Do not run on devices with emulated external storage.
-        if (Environment.isExternalStorageEmulated()) {
-            return;
-        }
-
-        int iFlags = PackageManager.INSTALL_EXTERNAL;
-        int rFlags = PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_REPLACE_EXISTING;
-        // First install.
-        installFromRawResource("install.apk", R.raw.install,
-                iFlags,
-                false,
-                false, -1,
-                -1);
-        // Replace now
-        installFromRawResource("install.apk", R.raw.install,
-                rFlags,
-                true,
-                false, -1,
-                -1);
-    }
-
     /*
      * The following set of tests verify the installation of apps with
      * install location attribute set to internalOnly, preferExternal and auto.
@@ -2905,7 +2717,7 @@
     @LargeTest
     public void testReplaceMatchNoCerts1() throws Exception {
         replaceCerts(APP1_CERT1_CERT2, APP1_CERT3, true, true,
-                PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
+                PackageInstaller.STATUS_FAILURE_CONFLICT);
     }
 
     /*
@@ -2915,7 +2727,7 @@
     @LargeTest
     public void testReplaceMatchNoCerts2() throws Exception {
         replaceCerts(APP1_CERT1_CERT2, APP1_CERT3_CERT4, true, true,
-                PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
+                PackageInstaller.STATUS_FAILURE_CONFLICT);
     }
 
     /*
@@ -2925,7 +2737,7 @@
     @LargeTest
     public void testReplaceMatchSomeCerts1() throws Exception {
         replaceCerts(APP1_CERT1_CERT2, APP1_CERT1, true, true,
-                PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
+                PackageInstaller.STATUS_FAILURE_CONFLICT);
     }
 
     /*
@@ -2935,7 +2747,7 @@
     @LargeTest
     public void testReplaceMatchSomeCerts2() throws Exception {
         replaceCerts(APP1_CERT1_CERT2, APP1_CERT2, true, true,
-                PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
+                PackageInstaller.STATUS_FAILURE_CONFLICT);
     }
 
     /*
@@ -2945,7 +2757,7 @@
     @LargeTest
     public void testReplaceMatchMoreCerts() throws Exception {
         replaceCerts(APP1_CERT1, APP1_CERT1_CERT2, true, true,
-                PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
+                PackageInstaller.STATUS_FAILURE_CONFLICT);
     }
 
     /*
@@ -2956,7 +2768,7 @@
     @LargeTest
     public void testReplaceMatchMoreCertsReplaceSomeCerts() throws Exception {
         InstallParams ip = replaceCerts(APP1_CERT1, APP1_CERT1_CERT2, false, true,
-                PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
+                PackageInstaller.STATUS_FAILURE_CONFLICT);
         try {
             int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
             installFromRawResource("install.apk", APP1_CERT1, rFlags, false,
@@ -2996,7 +2808,7 @@
      */
     public void testUpgradeKSWithWrongKey() throws Exception {
         replaceCerts(R.raw.keyset_sa_ua, R.raw.keyset_sb_ua, true, true,
-                PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
+                PackageInstaller.STATUS_FAILURE_CONFLICT);
     }
 
     /*
@@ -3005,7 +2817,7 @@
      */
     public void testUpgradeKSWithWrongSigningKey() throws Exception {
         replaceCerts(R.raw.keyset_sa_ub, R.raw.keyset_sa_ub, true, true,
-                PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
+                PackageInstaller.STATUS_FAILURE_CONFLICT);
     }
 
     /*
@@ -3037,7 +2849,7 @@
      */
     public void testMultipleUpgradeKSWithSigningKey() throws Exception {
         replaceCerts(R.raw.keyset_sau_ub, R.raw.keyset_sa_ua, true, true,
-                PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
+                PackageInstaller.STATUS_FAILURE_CONFLICT);
     }
 
     /*
@@ -3471,7 +3283,12 @@
             int rawResId = apk2;
             Uri packageURI = getInstallablePackage(rawResId, outFile);
             PackageParser.Package pkg = parsePackage(packageURI);
-            getPm().deletePackage(pkg.packageName, null, PackageManager.DELETE_ALL_USERS);
+            try {
+                getPi().uninstall(pkg.packageName,
+                        PackageManager.DELETE_ALL_USERS,
+                        null /*statusReceiver*/);
+            } catch (IllegalArgumentException ignore) {
+            }
             // Check signatures now
             int match = mContext.getPackageManager().checkSignatures(
                     ip.pkg.packageName, pkg.packageName);
@@ -3487,7 +3304,7 @@
         String apk1Name = "install1.apk";
 
         installFromRawResource(apk1Name, apk1, 0, false,
-                true, PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES,
+                true, PackageInstaller.STATUS_FAILURE_INVALID,
                 PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
     }
 
@@ -3557,7 +3374,7 @@
         int apk1 = SHARED1_CERT1;
         int apk2 = SHARED2_CERT2;
         boolean fail = true;
-        int retCode = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
+        int retCode = PackageInstaller.STATUS_FAILURE_CONFLICT;
         int expMatchResult = -1;
         checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
     }
@@ -3571,7 +3388,7 @@
         int apk1 = SHARED1_CERT1_CERT2;
         int apk2 = SHARED2_CERT1;
         boolean fail = true;
-        int retCode = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
+        int retCode = PackageInstaller.STATUS_FAILURE_CONFLICT;
         int expMatchResult = -1;
         checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
     }
@@ -3585,7 +3402,7 @@
         int apk1 = SHARED1_CERT1_CERT2;
         int apk2 = SHARED2_CERT2;
         boolean fail = true;
-        int retCode = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
+        int retCode = PackageInstaller.STATUS_FAILURE_CONFLICT;
         int expMatchResult = -1;
         checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
     }
@@ -3604,7 +3421,11 @@
             PackageManager pm = mContext.getPackageManager();
             // Delete app2
             PackageParser.Package pkg = getParsedPackage(apk2Name, apk2);
-            getPm().deletePackage(pkg.packageName, null, PackageManager.DELETE_ALL_USERS);
+            try {
+                getPi().uninstall(
+                        pkg.packageName, PackageManager.DELETE_ALL_USERS, null /*statusReceiver*/);
+            } catch (IllegalArgumentException ignore) {
+            }
             // Check signatures now
             int match = mContext.getPackageManager().checkSignatures(
                     ip1.pkg.packageName, pkg.packageName);
@@ -3640,7 +3461,7 @@
         int apk2 = SHARED2_CERT1_CERT2;
         int rapk1 = SHARED1_CERT1;
         boolean fail = true;
-        int retCode = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
+        int retCode = PackageInstaller.STATUS_FAILURE_CONFLICT;
         checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
         installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true,
                 fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
@@ -3652,7 +3473,7 @@
         int apk2 = SHARED2_CERT1_CERT2;
         int rapk2 = SHARED2_CERT1;
         boolean fail = true;
-        int retCode = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
+        int retCode = PackageInstaller.STATUS_FAILURE_CONFLICT;
         checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
         installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true,
                 fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
@@ -3664,7 +3485,7 @@
         int apk2 = SHARED2_CERT1;
         int rapk1 = SHARED1_CERT2;
         boolean fail = true;
-        int retCode = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
+        int retCode = PackageInstaller.STATUS_FAILURE_CONFLICT;
         checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
         installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true,
                 fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
@@ -3676,7 +3497,7 @@
         int apk2 = SHARED2_CERT1;
         int rapk2 = SHARED2_CERT2;
         boolean fail = true;
-        int retCode = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
+        int retCode = PackageInstaller.STATUS_FAILURE_CONFLICT;
         checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
         installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true,
                 fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
@@ -3688,7 +3509,7 @@
         int apk2 = SHARED2_CERT1;
         int rapk1 = SHARED1_CERT1_CERT2;
         boolean fail = true;
-        int retCode = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
+        int retCode = PackageInstaller.STATUS_FAILURE_CONFLICT;
         checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
         installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true,
                 fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
@@ -3700,7 +3521,7 @@
         int apk2 = SHARED2_CERT1;
         int rapk2 = SHARED2_CERT1_CERT2;
         boolean fail = true;
-        int retCode = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
+        int retCode = PackageInstaller.STATUS_FAILURE_CONFLICT;
         checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
         installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true,
                 fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
@@ -3724,7 +3545,7 @@
 
     @LargeTest
     public void testInstallNonexistentFile() throws Exception {
-        int retCode = PackageManager.INSTALL_FAILED_INVALID_URI;
+        int retCode = PackageInstaller.STATUS_FAILURE_INVALID;
         File invalidFile = new File("/nonexistent-file.apk");
         invokeInstallPackageFail(Uri.fromFile(invalidFile), 0, retCode);
     }
@@ -3845,7 +3666,7 @@
 
     @Suppress
     public void testInstall_BadDex_CleanUp() throws Exception {
-        int retCode = PackageManager.INSTALL_FAILED_DEXOPT;
+        int retCode = PackageInstaller.STATUS_FAILURE_INVALID;
         installFromRawResource("install.apk", R.raw.install_bad_dex, 0, true, true, retCode,
                 PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
     }
diff --git a/core/tests/coretests/src/android/database/DatabasePerformanceTests.java b/core/tests/coretests/src/android/database/DatabasePerformanceTests.java
deleted file mode 100644
index d0e739b..0000000
--- a/core/tests/coretests/src/android/database/DatabasePerformanceTests.java
+++ /dev/null
@@ -1,1354 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.database;
-
-import junit.framework.Assert;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.provider.Contacts;
-import android.provider.Contacts.People;
-import android.test.PerformanceTestCase;
-import android.test.TestCase;
-
-import java.io.File;
-import java.util.Random;
-
-/**
- * Database Performance Tests
- * 
- */
-
-@SuppressWarnings("deprecation")
-public class DatabasePerformanceTests {
-
-    public static String[] children() {
-        return new String[] {
-            ContactReadingTest1.class.getName(),
-            Perf1Test.class.getName(),
-            Perf2Test.class.getName(),
-            Perf3Test.class.getName(),
-            Perf4Test.class.getName(),
-            Perf5Test.class.getName(),
-            Perf6Test.class.getName(),
-            Perf7Test.class.getName(),
-            Perf8Test.class.getName(),
-            Perf9Test.class.getName(),
-            Perf10Test.class.getName(),
-            Perf11Test.class.getName(),
-            Perf12Test.class.getName(),
-            Perf13Test.class.getName(),
-            Perf14Test.class.getName(),
-            Perf15Test.class.getName(),
-            Perf16Test.class.getName(),
-            Perf17Test.class.getName(),
-            Perf18Test.class.getName(),
-            Perf19Test.class.getName(),
-            Perf20Test.class.getName(),
-            Perf21Test.class.getName(),
-            Perf22Test.class.getName(),
-            Perf23Test.class.getName(),
-            Perf24Test.class.getName(),
-            Perf25Test.class.getName(),
-            Perf26Test.class.getName(),
-            Perf27Test.class.getName(),
-            Perf28Test.class.getName(),
-            Perf29Test.class.getName(),
-            Perf30Test.class.getName(),
-            Perf31Test.class.getName(),
-            };
-    }
-       
-    public static abstract class PerformanceBase implements TestCase,
-            PerformanceTestCase {
-        protected static final int CURRENT_DATABASE_VERSION = 42;
-        protected SQLiteDatabase mDatabase;
-        protected File mDatabaseFile;
-        protected Context mContext;
-
-        public void setUp(Context c) {
-            mContext = c;
-            mDatabaseFile = new File("/tmp", "perf_database_test.db");
-            if (mDatabaseFile.exists()) {
-                mDatabaseFile.delete();
-            }
-            mDatabase = SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(), null);
-            Assert.assertTrue(mDatabase != null);
-            mDatabase.setVersion(CURRENT_DATABASE_VERSION);
-        }
-
-        public void tearDown() {
-            mDatabase.close();
-            mDatabaseFile.delete();
-        }
-
-        public boolean isPerformanceOnly() {
-            return true;
-        }
-
-        // These test can only be run once.
-        public int startPerformance(Intermediates intermediates) {
-            return 0;
-        }
-
-        public void run() {
-        }
-
-        public String numberName(int number) {
-            String result = "";
-
-            if (number >= 1000) {
-                result += numberName((number / 1000)) + " thousand";
-                number = (number % 1000);
-
-                if (number > 0) result += " ";
-            }
-
-            if (number >= 100) {
-                result += ONES[(number / 100)] + " hundred";
-                number = (number % 100);
-
-                if (number > 0) result += " ";
-            }
-
-            if (number >= 20) {
-                result += TENS[(number / 10)];
-                number = (number % 10);
-
-                if (number > 0) result += " ";
-            }
-
-            if (number > 0) {
-                result += ONES[number];
-            }
-
-            return result;
-        }
-    }
-
-    /**
-     * Test reading all contact data.
-     */
-    public static class ContactReadingTest1 implements TestCase, PerformanceTestCase {
-        private static final String[] PEOPLE_PROJECTION = new String[] {
-               Contacts.People._ID, // 0
-               Contacts.People.PRIMARY_PHONE_ID, // 1
-               Contacts.People.TYPE, // 2
-               Contacts.People.NUMBER, // 3
-               Contacts.People.LABEL, // 4
-               Contacts.People.NAME, // 5
-               Contacts.People.PRESENCE_STATUS, // 6
-        };
-
-        private Cursor mCursor;
-
-        public void setUp(Context c) {
-            mCursor = c.getContentResolver().query(People.CONTENT_URI, PEOPLE_PROJECTION, null,
-                    null, People.DEFAULT_SORT_ORDER);
-        }
-        
-        public void tearDown() {
-            mCursor.close();
-        }
-
-        public boolean isPerformanceOnly() {
-            return true;
-        }
-
-        public int startPerformance(Intermediates intermediates) {
-            // This test can only be run once.
-            return 0;
-        }
-
-        public void run() {
-            while (mCursor.moveToNext()) {
-                // Read out all of the data
-                mCursor.getLong(0);
-                mCursor.getLong(1);
-                mCursor.getLong(2);
-                mCursor.getString(3);
-                mCursor.getString(4);
-                mCursor.getString(5);
-                mCursor.getLong(6);
-            }
-        }
-    }
-    
-    /**
-     * Test 1000 inserts
-     */
-    
-    public static class Perf1Test extends PerformanceBase {
-        private static final int SIZE = 1000;
-
-        private String[] statements = new String[SIZE];
-
-        @Override
-        public void setUp(Context c) {
-            super.setUp(c);
-            Random random = new Random(42);
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                statements[i] =
-                        "INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-                                + numberName(r) + "')";
-            }
-
-            mDatabase
-              .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-        }
-
-        @Override
-        public void run() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.execSQL(statements[i]);
-            }
-        }
-    }
-
-    /**
-     * Test 1000 inserts into and indexed table
-     */
-    
-    public static class Perf2Test extends PerformanceBase {
-        private static final int SIZE = 1000;
-
-        private String[] statements = new String[SIZE];
-
-        @Override
-        public void setUp(Context c) {
-            super.setUp(c);
-            Random random = new Random(42);
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                statements[i] =
-                        "INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-                                + numberName(r) + "')";
-            }
-
-            mDatabase
-              .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-            mDatabase.execSQL("CREATE INDEX i1c ON t1(c)");
-        }
-
-        @Override
-        public void run() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.execSQL(statements[i]);
-            }
-        }
-    }
-
-    /**
-     * 100 SELECTs without an index
-     */
-      
-    public static class Perf3Test extends PerformanceBase {
-        private static final int SIZE = 100;
-        private static final String[] COLUMNS = {"count(*)", "avg(b)"};
-
-        private String[] where = new String[SIZE];
-
-        @Override
-        public void setUp(Context c) {
-            super.setUp(c);
-            Random random = new Random(42);
-
-            mDatabase
-              .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-                        + numberName(r) + "')");
-            }
-
-            for (int i = 0; i < SIZE; i++) {
-                int lower = i * 100;
-                int upper = (i + 10) * 100;
-                where[i] = "b >= " + lower + " AND b < " + upper;
-            }
-        }
-
-        @Override
-        public void run() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase
-                        .query("t1", COLUMNS, where[i], null, null, null, null);
-            }
-        }
-    }
-
-    /**
-     * 100 SELECTs on a string comparison
-     */
-    
-    public static class Perf4Test extends PerformanceBase {
-        private static final int SIZE = 100;
-        private static final String[] COLUMNS = {"count(*)", "avg(b)"};
-
-        private String[] where = new String[SIZE];
-
-        @Override
-        public void setUp(Context c) {
-            super.setUp(c);
-            Random random = new Random(42);
-
-            mDatabase
-              .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-                        + numberName(r) + "')");
-            }
-
-            for (int i = 0; i < SIZE; i++) {
-                where[i] = "c LIKE '" + numberName(i) + "'";
-            }
-        }
-
-        @Override
-        public void run() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase
-                        .query("t1", COLUMNS, where[i], null, null, null, null);
-            }
-        }
-    }
-
-    /**
-     * 100 SELECTs with an index
-     */
-    
-    public static class Perf5Test extends PerformanceBase {
-        private static final int SIZE = 100;
-        private static final String[] COLUMNS = {"count(*)", "avg(b)"};
-
-        private String[] where = new String[SIZE];
-
-        @Override
-        public void setUp(Context c) {
-            super.setUp(c);
-            Random random = new Random(42);
-
-            mDatabase
-              .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-            mDatabase.execSQL("CREATE INDEX i1b ON t1(b)");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-                        + numberName(r) + "')");
-            }
-
-            for (int i = 0; i < SIZE; i++) {
-                int lower = i * 100;
-                int upper = (i + 10) * 100;
-                where[i] = "b >= " + lower + " AND b < " + upper;
-            }
-        }
-
-        @Override
-        public void run() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase
-                        .query("t1", COLUMNS, where[i], null, null, null, null);
-            }
-        }
-    }
-
-    /**
-     *  INNER JOIN without an index
-     */
-    
-    public static class Perf6Test extends PerformanceBase {
-        private static final int SIZE = 100;
-        private static final String[] COLUMNS = {"t1.a"};
-
-        @Override
-        public void setUp(Context c) {
-            super.setUp(c);
-            Random random = new Random(42);
-
-            mDatabase
-              .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-            mDatabase
-              .execSQL("CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100))");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-                        + numberName(r) + "')");
-            }
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t2 VALUES(" + i + "," + r + ",'"
-                        + numberName(r) + "')");
-            }
-        }
-
-        @Override
-        public void run() {
-            mDatabase.query("t1 INNER JOIN t2 ON t1.b = t2.b", COLUMNS, null,
-                    null, null, null, null);
-        }
-    }
-
-    /**
-     *  INNER JOIN without an index on one side
-     */
-    
-    public static class Perf7Test extends PerformanceBase {
-        private static final int SIZE = 100;
-        private static final String[] COLUMNS = {"t1.a"};
-
-        @Override
-        public void setUp(Context c) {
-            super.setUp(c);
-            Random random = new Random(42);
-
-            mDatabase
-              .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-            mDatabase
-              .execSQL("CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100))");
-
-            mDatabase.execSQL("CREATE INDEX i1b ON t1(b)");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-                        + numberName(r) + "')");
-            }
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t2 VALUES(" + i + "," + r + ",'"
-                        + numberName(r) + "')");
-            }
-        }
-
-        @Override
-        public void run() {
-            mDatabase.query("t1 INNER JOIN t2 ON t1.b = t2.b", COLUMNS, null,
-                    null, null, null, null);
-        }
-    }
-
-    /**
-     *  INNER JOIN without an index on one side
-     */
-    
-    public static class Perf8Test extends PerformanceBase {
-        private static final int SIZE = 100;
-        private static final String[] COLUMNS = {"t1.a"};
-
-        @Override
-        public void setUp(Context c) {
-            super.setUp(c);
-            Random random = new Random(42);
-
-            mDatabase
-              .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-            mDatabase
-              .execSQL("CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100))");
-
-            mDatabase.execSQL("CREATE INDEX i1b ON t1(b)");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-                        + numberName(r) + "')");
-            }
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t2 VALUES(" + i + "," + r + ",'"
-                        + numberName(r) + "')");
-            }
-        }
-
-        @Override
-        public void run() {
-            mDatabase.query("t1 INNER JOIN t2 ON t1.c = t2.c", COLUMNS, null,
-                    null, null, null, null);
-        }
-    }
-
-    /**
-     *  100 SELECTs with subqueries. Subquery is using an index
-     */
-    
-    public static class Perf9Test extends PerformanceBase {
-        private static final int SIZE = 100;
-        private static final String[] COLUMNS = {"t1.a"};
-
-        private String[] where = new String[SIZE];
-
-        @Override
-        public void setUp(Context c) {
-            super.setUp(c);
-            Random random = new Random(42);
-
-            mDatabase
-              .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-            mDatabase
-              .execSQL("CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100))");
-
-            mDatabase.execSQL("CREATE INDEX i2b ON t2(b)");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-                        + numberName(r) + "')");
-            }
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t2 VALUES(" + i + "," + r + ",'"
-                        + numberName(r) + "')");
-            }
-
-            for (int i = 0; i < SIZE; i++) {
-                int lower = i * 100;
-                int upper = (i + 10) * 100;
-                where[i] =
-                        "t1.b IN (SELECT t2.b FROM t2 WHERE t2.b >= " + lower
-                                + " AND t2.b < " + upper + ")";
-            }
-        }
-
-        @Override
-        public void run() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase
-                        .query("t1", COLUMNS, where[i], null, null, null, null);
-            }
-        }
-    }
-
-    /**
-     *  100 SELECTs on string comparison with Index
-     */
-
-    public static class Perf10Test extends PerformanceBase {
-        private static final int SIZE = 100;
-        private static final String[] COLUMNS = {"count(*)", "avg(b)"};
-
-        private String[] where = new String[SIZE];
-
-        @Override
-        public void setUp(Context c) {
-            super.setUp(c);
-            Random random = new Random(42);
-
-            mDatabase
-              .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-            mDatabase.execSQL("CREATE INDEX i3c ON t1(c)");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-                        + numberName(r) + "')");
-            }
-
-            for (int i = 0; i < SIZE; i++) {
-                where[i] = "c LIKE '" + numberName(i) + "'";
-            }
-        }
-
-        @Override
-        public void run() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase
-                        .query("t1", COLUMNS, where[i], null, null, null, null);
-            }
-        }
-    }
-
-    /**
-     *  100 SELECTs on integer 
-     */
-    
-    public static class Perf11Test extends PerformanceBase {
-        private static final int SIZE = 100;
-        private static final String[] COLUMNS = {"b"};
-
-        private String[] where = new String[SIZE];
-
-        @Override
-        public void setUp(Context c) {
-            super.setUp(c);
-            Random random = new Random(42);
-
-            mDatabase
-              .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-                        + numberName(r) + "')");
-            }
-
-        }
-
-        @Override
-        public void run() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.query("t1", COLUMNS, null, null, null, null, null);
-            }
-        }
-    }
-
-    /**
-     *  100 SELECTs on String
-     */
-
-    public static class Perf12Test extends PerformanceBase {
-        private static final int SIZE = 100;
-        private static final String[] COLUMNS = {"c"};
-
-        private String[] where = new String[SIZE];
-
-        @Override
-        public void setUp(Context c) {
-            super.setUp(c);
-            Random random = new Random(42);
-
-            mDatabase
-              .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-                        + numberName(r) + "')");
-            }
-
-        }
-
-        @Override
-        public void run() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.query("t1", COLUMNS, null, null, null, null, null);
-            }
-        }
-    }
-
-    /**
-     *  100 SELECTs on integer with index
-     */
-    
-    public static class Perf13Test extends PerformanceBase {
-        private static final int SIZE = 100;
-        private static final String[] COLUMNS = {"b"};
-
-        @Override
-        public void setUp(Context c) {
-            super.setUp(c);
-            Random random = new Random(42);
-
-            mDatabase
-              .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-            mDatabase.execSQL("CREATE INDEX i1b on t1(b)");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-                        + numberName(r) + "')");
-            }
-
-        }
-
-        @Override
-        public void run() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.query("t1", COLUMNS, null, null, null, null, null);
-            }
-        }
-    }
-
-    /**
-     *  100 SELECTs on String with index
-     */
-
-    public static class Perf14Test extends PerformanceBase {
-        private static final int SIZE = 100;
-        private static final String[] COLUMNS = {"c"};      
-
-        @Override
-        public void setUp(Context c) {
-            super.setUp(c);
-            Random random = new Random(42);
-
-            mDatabase
-              .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-            mDatabase.execSQL("CREATE INDEX i1c ON t1(c)");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-                        + numberName(r) + "')");
-            }
-
-        }
-
-        @Override
-        public void run() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.query("t1", COLUMNS, null, null, null, null, null);
-            }
-        }
-    }
-
-    /**
-     *  100 SELECTs on String with starts with
-     */
-
-    public static class Perf15Test extends PerformanceBase {
-        private static final int SIZE = 100;
-        private static final String[] COLUMNS = {"c"};
-        private String[] where = new String[SIZE];
-
-        @Override
-        public void setUp(Context c) {
-            super.setUp(c);
-            Random random = new Random(42);
-
-            mDatabase
-              .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-            mDatabase.execSQL("CREATE INDEX i1c ON t1(c)");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-                        + numberName(r) + "')");
-            }
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                where[i] = "c LIKE '" + numberName(r).substring(0, 1) + "*'";
-
-            }
-
-        }
-
-        @Override
-        public void run() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase
-                        .query("t1", COLUMNS, where[i], null, null, null, null);
-            }
-        }
-    }
-
-    /**
-     *  1000  Deletes on an indexed table
-     */
-    
-    public static class Perf16Test extends PerformanceBase {
-        private static final int SIZE = 1000;
-        private static final String[] COLUMNS = {"c"};
-        
-        @Override
-        public void setUp(Context c) {
-            super.setUp(c);
-            Random random = new Random(42);
-
-            mDatabase
-              .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-            mDatabase.execSQL("CREATE INDEX i3c ON t1(c)");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-                        + numberName(r) + "')");
-            }
-
-        }
-
-        @Override
-        public void run() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.delete("t1", null, null);
-            }
-        }
-    }
-
-    /**
-     *  1000  Deletes
-     */
-    
-    public static class Perf17Test extends PerformanceBase {
-        private static final int SIZE = 1000;
-        private static final String[] COLUMNS = {"c"};       
-
-        @Override
-        public void setUp(Context c) {
-            super.setUp(c);
-            Random random = new Random(42);
-
-            mDatabase
-              .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-                        + numberName(r) + "')");
-            }
-
-        }
-
-        @Override
-        public void run() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.delete("t1", null, null);
-            }
-        }
-    }
-
-    /**
-     *  1000 DELETE's without an index with where clause 
-     */
-    
-    public static class Perf18Test extends PerformanceBase {
-        private static final int SIZE = 1000;
-        private String[] where = new String[SIZE];
-
-        @Override
-        public void setUp(Context c) {
-            super.setUp(c);
-            Random random = new Random(42);
-
-            mDatabase
-              .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-                        + numberName(r) + "')");
-            }
-
-            for (int i = 0; i < SIZE; i++) {
-                int lower = i * 100;
-                int upper = (i + 10) * 100;
-                where[i] = "b >= " + lower + " AND b < " + upper;
-            }
-        }
-
-        @Override
-        public void run() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.delete("t1", where[i], null);
-            }
-        }
-    }
-
-    /**
-     *  1000 DELETE's with an index with where clause 
-     */
-    
-    public static class Perf19Test extends PerformanceBase {
-        private static final int SIZE = 1000;
-        private String[] where = new String[SIZE];
-
-        @Override
-        public void setUp(Context c) {
-            super.setUp(c);
-            Random random = new Random(42);
-
-            mDatabase
-              .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-            mDatabase.execSQL("CREATE INDEX i1b ON t1(b)");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-                        + numberName(r) + "')");
-            }
-
-            for (int i = 0; i < SIZE; i++) {
-                int lower = i * 100;
-                int upper = (i + 10) * 100;
-                where[i] = "b >= " + lower + " AND b < " + upper;
-            }
-        }
-
-        @Override
-        public void run() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.delete("t1", where[i], null);
-            }
-        }
-    }
-
-    /**
-     *  1000 update's with an index with where clause 
-     */
-    
-    public static class Perf20Test extends PerformanceBase {
-        private static final int SIZE = 1000;
-        private String[] where = new String[SIZE];
-        ContentValues[] mValues = new ContentValues[SIZE];
-
-        @Override
-        public void setUp(Context c) {
-            super.setUp(c);
-            Random random = new Random(42);
-
-            mDatabase
-              .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-            mDatabase.execSQL("CREATE INDEX i1b ON t1(b)");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-                        + numberName(r) + "')");
-            }
-
-            for (int i = 0; i < SIZE; i++) {
-
-                int lower = i * 100;
-                int upper = (i + 10) * 100;
-                where[i] = "b >= " + lower + " AND b < " + upper;
-                ContentValues b = new ContentValues(1);
-                b.put("b", upper);
-                mValues[i] = b;
-               
-            }
-        }
-
-        @Override
-        public void run() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.update("t1", mValues[i], where[i], null);
-            }
-        }
-    }
-
-    /**
-     *  1000 update's without an index with where clause 
-     */
-    
-    public static class Perf21Test extends PerformanceBase {
-        private static final int SIZE = 1000;       
-        private String[] where = new String[SIZE];
-        ContentValues[] mValues = new ContentValues[SIZE];
-
-        @Override
-        public void setUp(Context c) {
-            super.setUp(c);
-            Random random = new Random(42);
-
-            mDatabase
-              .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-           
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-                        + numberName(r) + "')");
-            }
-
-            for (int i = 0; i < SIZE; i++) {
-
-                int lower = i * 100;
-                int upper = (i + 10) * 100;
-                where[i] = "b >= " + lower + " AND b < " + upper;
-                ContentValues b = new ContentValues(1);
-                b.put("b", upper);
-                mValues[i] = b;
-            }
-        }
-
-        @Override
-        public void run() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.update("t1", mValues[i], where[i], null);
-            }
-        }
-    }
-    
-    /**
-     *  10000 inserts for an integer 
-     */
-    
-    public static class Perf22Test extends PerformanceBase {
-        private static final int SIZE = 10000;
-        ContentValues[] mValues = new ContentValues[SIZE];
-
-        @Override
-        public void setUp(Context c) {
-            super.setUp(c);
-            Random random = new Random(42);
-
-            mDatabase
-              .execSQL("CREATE TABLE t1(a INTEGER)");
-           
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                ContentValues b = new ContentValues(1);
-                b.put("a", r);
-                mValues[i] = b;
-            }
-        }        
-
-        @Override
-        public void run() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.insert("t1", null, mValues[i]);
-            }
-        }
-    }
-    
-    /**
-     *  10000 inserts for an integer -indexed table
-     */
-    
-    public static class Perf23Test extends PerformanceBase {
-        private static final int SIZE = 10000;
-        ContentValues[] mValues = new ContentValues[SIZE];
-
-        @Override
-        public void setUp(Context c) {
-            super.setUp(c);
-            Random random = new Random(42);
-
-            mDatabase
-              .execSQL("CREATE TABLE t1(a INTEGER)");
-            mDatabase.execSQL("CREATE INDEX i1a ON t1(a)");
-           
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                ContentValues b = new ContentValues(1);
-                b.put("a", r);
-                mValues[i] = b;
-            }
-        }        
-
-        @Override
-        public void run() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.insert("t1", null, mValues[i]);
-            }
-        }
-    }
-    
-    /**
-     *  10000 inserts for a String 
-     */
-    
-    public static class Perf24Test extends PerformanceBase {
-        private static final int SIZE = 10000;
-        ContentValues[] mValues = new ContentValues[SIZE];
-
-        @Override
-        public void setUp(Context c) {
-            super.setUp(c);
-            Random random = new Random(42);
-
-            mDatabase
-              .execSQL("CREATE TABLE t1(a VARCHAR(100))");
-           
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                ContentValues b = new ContentValues(1);
-                b.put("a", numberName(r));
-                mValues[i] = b;
-            }
-        }        
-
-        @Override
-        public void run() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.insert("t1", null, mValues[i]);
-            }
-        }
-    }
-    
-    /**
-     *  10000 inserts for a String - indexed table 
-     */
-    
-    public static class Perf25Test extends PerformanceBase {
-        private static final int SIZE = 10000;       
-        ContentValues[] mValues = new ContentValues[SIZE];
-
-        @Override
-        public void setUp(Context c) {
-            super.setUp(c);
-            Random random = new Random(42);
-
-            mDatabase
-              .execSQL("CREATE TABLE t1(a VARCHAR(100))");
-            mDatabase.execSQL("CREATE INDEX i1a ON t1(a)");
-                       
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                ContentValues b = new ContentValues(1);
-                b.put("a", numberName(r));
-                mValues[i] = b; 
-            }
-        }
-
-        @Override
-        public void run() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.insert("t1", null, mValues[i]);
-            }
-        }
-    }
-    
-    
-    /**
-     *  10000 selects for a String -starts with
-     */
-    
-    public static class Perf26Test extends PerformanceBase {
-        private static final int SIZE = 10000;
-        private static final String[] COLUMNS = {"t3.a"};
-        private String[] where = new String[SIZE];
-        
-        @Override
-        public void setUp(Context c) {
-            super.setUp(c);
-            Random random = new Random(42);
-
-            mDatabase
-              .execSQL("CREATE TABLE t3(a VARCHAR(100))");
-                                  
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t3 VALUES('"
-                        + numberName(r) + "')");
-            }
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                where[i] = "a LIKE '" + numberName(r).substring(0, 1) + "*'";
-
-            }
-        }        
-
-        @Override
-        public void run() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.query("t3", COLUMNS, where[i], null, null, null, null);
-            }
-        }
-    }
-    
-    /**
-     *  10000 selects for a String - indexed table -starts with
-     */
-    
-    public static class Perf27Test extends PerformanceBase {
-        private static final int SIZE = 10000;
-        private static final String[] COLUMNS = {"t3.a"};
-        private String[] where = new String[SIZE];
-        
-        @Override
-        public void setUp(Context c) {
-            super.setUp(c);
-            Random random = new Random(42);
-
-            mDatabase
-              .execSQL("CREATE TABLE t3(a VARCHAR(100))");
-            mDatabase.execSQL("CREATE INDEX i3a ON t3(a)");
-                       
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t3 VALUES('"
-                        + numberName(r) + "')");
-            }
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                where[i] = "a LIKE '" + numberName(r).substring(0, 1) + "*'";
-
-            }                              
-           }        
-
-        @Override
-        public void run() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.query("t3", COLUMNS, where[i], null, null, null, null);
-            }
-        }
-    }
-    
-    /**
-     *  10000 selects for an integer -
-     */
-    
-    public static class Perf28Test extends PerformanceBase {
-        private static final int SIZE = 10000;
-        private static final String[] COLUMNS = {"t4.a"};
-        private String[] where = new String[SIZE];
-        
-        @Override
-        public void setUp(Context c) {
-            super.setUp(c);
-            Random random = new Random(42);
-
-            mDatabase
-              .execSQL("CREATE TABLE t4(a INTEGER)");
-           
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t4 VALUES(" + r + ")");
-                int lower = i * 100;
-                int upper = (i + 10) * 100;
-                where[i] = "a >= " + lower + " AND a < " + upper;
-            }
-           }        
-
-        @Override
-        public void run() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.query("t4", COLUMNS, where[i], null, null, null, null);
-            }
-        }
-    }
-    
-    /**
-     *  10000 selects for an integer -indexed table
-     */
-    
-    public static class Perf29Test extends PerformanceBase {
-        private static final int SIZE = 10000;
-        private static final String[] COLUMNS = {"t4.a"};
-        private String[] where = new String[SIZE];
-       
-        @Override
-        public void setUp(Context c) {
-            super.setUp(c);
-            Random random = new Random(42);
-
-            mDatabase
-              .execSQL("CREATE TABLE t4(a INTEGER)");
-           mDatabase.execSQL("CREATE INDEX i4a ON t4(a)");
-           
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t4 VALUES(" + r + ")");
-                
-                int lower = i * 100;
-                int upper = (i + 10) * 100;
-                where[i] = "a >= " + lower + " AND a < " + upper;
-            }
-           
-           }        
-
-        @Override
-        public void run() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.query("t4", COLUMNS, where[i], null, null, null, null);
-            }
-        }
-    }
-    
-    
-    /**
-     *  10000 selects for a String - contains 'e'
-     */
-    
-    public static class Perf30Test extends PerformanceBase {
-        private static final int SIZE = 10000;
-        private static final String[] COLUMNS = {"t3.a"};
-        private String[] where = new String[SIZE];
-        
-        @Override
-        public void setUp(Context c) {
-            super.setUp(c);
-            Random random = new Random(42);
-
-            mDatabase
-              .execSQL("CREATE TABLE t3(a VARCHAR(100))");
-            
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t3 VALUES('"
-                        + numberName(r) + "')");
-            }
-
-            for (int i = 0; i < SIZE; i++) {
-                 where[i] = "a LIKE '*e*'";
-
-            }                              
-           }        
-
-        @Override
-        public void run() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.query("t3", COLUMNS, where[i], null, null, null, null);
-            }
-        }
-    }
-    
-    /**
-     *  10000 selects for a String - contains 'e'-indexed table
-     */
-    
-    public static class Perf31Test extends PerformanceBase {
-        private static final int SIZE = 10000;
-        private static final String[] COLUMNS = {"t3.a"};
-        private String[] where = new String[SIZE];
-        
-        @Override
-        public void setUp(Context c) {
-            super.setUp(c);
-            Random random = new Random(42);
-
-            mDatabase
-              .execSQL("CREATE TABLE t3(a VARCHAR(100))");
-            mDatabase.execSQL("CREATE INDEX i3a ON t3(a)");
-            
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t3 VALUES('"
-                        + numberName(r) + "')");
-            }
-
-            for (int i = 0; i < SIZE; i++) {
-                where[i] = "a LIKE '*e*'";
-
-            }                              
-            
-           }        
-
-        @Override
-        public void run() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.query("t3", COLUMNS, where[i], null, null, null, null);
-            }
-        }
-    }
-    
-    public static final String[] ONES =
-            {"zero", "one", "two", "three", "four", "five", "six", "seven",
-                "eight", "nine", "ten", "eleven", "twelve", "thirteen",
-                "fourteen", "fifteen", "sixteen", "seventeen", "eighteen",
-                "nineteen"};
-
-    public static final String[] TENS =
-            {"", "ten", "twenty", "thirty", "forty", "fifty", "sixty",
-                "seventy", "eighty", "ninety"};
-}
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 53ba9f7..1ebd429 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -448,6 +448,8 @@
                  Settings.Secure.MANAGED_PROFILE_CONTACT_REMOTE_SEARCH,
                  Settings.Secure.MULTI_PRESS_TIMEOUT,
                  Settings.Secure.NFC_PAYMENT_FOREGROUND,
+                 Settings.Secure.NIGHT_DISPLAY_ACTIVATED,
+                 Settings.Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME,
                  Settings.Secure.OVERVIEW_LAST_STACK_ACTIVE_TIME,
                  Settings.Secure.PACKAGE_VERIFIER_STATE,
                  Settings.Secure.PACKAGE_VERIFIER_USER_CONSENT,
diff --git a/core/tests/coretests/src/android/text/StaticLayoutTest.java b/core/tests/coretests/src/android/text/StaticLayoutTest.java
index 74a6cc6..fb60e38 100644
--- a/core/tests/coretests/src/android/text/StaticLayoutTest.java
+++ b/core/tests/coretests/src/android/text/StaticLayoutTest.java
@@ -22,10 +22,12 @@
 import static org.junit.Assert.assertTrue;
 
 import android.graphics.Paint.FontMetricsInt;
+import android.os.LocaleList;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.text.Layout.Alignment;
 import android.text.method.EditorState;
+import android.text.style.LocaleSpan;
 import android.util.Log;
 
 import org.junit.Before;
@@ -35,6 +37,7 @@
 import java.text.Normalizer;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Locale;
 
 /**
  * Tests StaticLayout vertical metrics behavior.
@@ -671,4 +674,76 @@
             assertEquals(testLabel, 4, layout.getOffsetToRightOf(5));
         }
     }
+
+    @Test
+    public void testLocaleSpanAffectsHyphenation() {
+        TextPaint paint = new TextPaint();
+        paint.setTextLocale(Locale.US);
+        // Private use language, with no hyphenation rules.
+        final Locale privateLocale = Locale.forLanguageTag("qaa");
+
+        final String longWord = "philanthropic";
+        final float wordWidth = paint.measureText(longWord);
+        // Wide enough that words get hyphenated by default.
+        final int paraWidth = Math.round(wordWidth * 1.8f);
+        final String sentence = longWord + " " + longWord + " " + longWord + " " + longWord + " "
+                + longWord + " " + longWord;
+
+        final int numEnglishLines = StaticLayout.Builder
+                .obtain(sentence, 0, sentence.length(), paint, paraWidth)
+                .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL)
+                .setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY)
+                .build()
+                .getLineCount();
+
+        {
+            final SpannableString text = new SpannableString(sentence);
+            text.setSpan(new LocaleSpan(privateLocale), 0, text.length(),
+                    Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+            final int numPrivateLocaleLines = StaticLayout.Builder
+                    .obtain(text, 0, text.length(), paint, paraWidth)
+                    .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL)
+                    .setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY)
+                    .build()
+                    .getLineCount();
+
+            // Since the paragraph set to English gets hyphenated, the number of lines would be
+            // smaller than the number of lines when there is a span setting a language that
+            // doesn't get hyphenated.
+            assertTrue(numEnglishLines < numPrivateLocaleLines);
+        }
+        {
+            // Same as the above test, except that the locale span now uses a locale list starting
+            // with the private non-hyphenating locale.
+            final SpannableString text = new SpannableString(sentence);
+            final LocaleList locales = new LocaleList(privateLocale, Locale.US);
+            text.setSpan(new LocaleSpan(locales), 0, text.length(),
+                    Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+            final int numPrivateLocaleLines = StaticLayout.Builder
+                    .obtain(text, 0, text.length(), paint, paraWidth)
+                    .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL)
+                    .setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY)
+                    .build()
+                    .getLineCount();
+
+            assertTrue(numEnglishLines < numPrivateLocaleLines);
+        }
+        {
+            final SpannableString text = new SpannableString(sentence);
+            // Apply the private LocaleSpan only to the first word, which is not getting hyphenated
+            // anyway.
+            text.setSpan(new LocaleSpan(privateLocale), 0, longWord.length(),
+                    Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+            final int numPrivateLocaleLines = StaticLayout.Builder
+                    .obtain(text, 0, text.length(), paint, paraWidth)
+                    .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL)
+                    .setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY)
+                    .build()
+                    .getLineCount();
+
+            // Since the first word is not hyphenated anyway (there's enough width), the LocaleSpan
+            // should not affect the layout.
+            assertEquals(numEnglishLines, numPrivateLocaleLines);
+        }
+    }
 }
diff --git a/core/tests/coretests/src/android/text/format/FormatterTest.java b/core/tests/coretests/src/android/text/format/FormatterTest.java
index a4ce911..ff75c29 100644
--- a/core/tests/coretests/src/android/text/format/FormatterTest.java
+++ b/core/tests/coretests/src/android/text/format/FormatterTest.java
@@ -26,12 +26,13 @@
 import android.support.test.runner.AndroidJUnit4;
 import android.text.format.Formatter.BytesResult;
 
-import java.util.Locale;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.Locale;
+
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class FormatterTest {
@@ -54,7 +55,7 @@
 
     @Test
     public void testFormatBytes() {
-        setLocale(Locale.ENGLISH);
+        setLocale(Locale.US);
 
         checkFormatBytes(0, true, "0", 0);
         checkFormatBytes(0, false, "0", 0);
@@ -99,6 +100,95 @@
         checkFormatBytes(9123000, false, "9,12", 9120000);
     }
 
+    private static final long SECOND = 1000;
+    private static final long MINUTE = 60 * SECOND;
+    private static final long HOUR = 60 * MINUTE;
+    private static final long DAY = 24 * HOUR;
+
+    @Test
+    public void testFormatShortElapsedTime() {
+        setLocale(Locale.US);
+        assertEquals("3 days", Formatter.formatShortElapsedTime(mContext, 2 * DAY + 12 * HOUR));
+        assertEquals("2 days", Formatter.formatShortElapsedTime(mContext, 2 * DAY + 11 * HOUR));
+        assertEquals("2 days", Formatter.formatShortElapsedTime(mContext, 2 * DAY));
+        assertEquals("1 day, 23 hr",
+                Formatter.formatShortElapsedTime(mContext, 1 * DAY + 23 * HOUR + 59 * MINUTE));
+        assertEquals("1 day, 0 hr",
+                Formatter.formatShortElapsedTime(mContext, 1 * DAY + 59 * MINUTE));
+        assertEquals("1 day, 0 hr", Formatter.formatShortElapsedTime(mContext, 1 * DAY));
+        assertEquals("24 hr", Formatter.formatShortElapsedTime(mContext, 23 * HOUR + 30 * MINUTE));
+        assertEquals("3 hr", Formatter.formatShortElapsedTime(mContext, 2 * HOUR + 30 * MINUTE));
+        assertEquals("2 hr", Formatter.formatShortElapsedTime(mContext, 2 * HOUR));
+        assertEquals("1 hr, 0 min", Formatter.formatShortElapsedTime(mContext, 1 * HOUR));
+        assertEquals("60 min",
+                Formatter.formatShortElapsedTime(mContext, 59 * MINUTE + 30 * SECOND));
+        assertEquals("59 min",
+                Formatter.formatShortElapsedTime(mContext, 59 * MINUTE));
+        assertEquals("3 min", Formatter.formatShortElapsedTime(mContext, 2 * MINUTE + 30 * SECOND));
+        assertEquals("2 min", Formatter.formatShortElapsedTime(mContext, 2 * MINUTE));
+        assertEquals("1 min, 59 sec",
+                Formatter.formatShortElapsedTime(mContext, 1 * MINUTE + 59 * SECOND + 999));
+        assertEquals("1 min, 0 sec", Formatter.formatShortElapsedTime(mContext, 1 * MINUTE));
+        assertEquals("59 sec", Formatter.formatShortElapsedTime(mContext, 59 * SECOND + 999));
+        assertEquals("1 sec", Formatter.formatShortElapsedTime(mContext, 1 * SECOND));
+        assertEquals("0 sec", Formatter.formatShortElapsedTime(mContext, 1));
+        assertEquals("0 sec", Formatter.formatShortElapsedTime(mContext, 0));
+
+        // Make sure it works on different locales.
+        setLocale(Locale.FRANCE);
+        assertEquals("2 j", Formatter.formatShortElapsedTime(mContext, 2 * DAY));
+    }
+
+    @Test
+    public void testFormatShortElapsedTimeRoundingUpToMinutes() {
+        setLocale(Locale.US);
+        assertEquals("3 days", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
+                mContext, 2 * DAY + 12 * HOUR));
+        assertEquals("2 days", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
+                mContext, 2 * DAY + 11 * HOUR));
+        assertEquals("2 days", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
+                mContext, 2 * DAY));
+        assertEquals("1 day, 23 hr", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
+                mContext, 1 * DAY + 23 * HOUR + 59 * MINUTE));
+        assertEquals("1 day, 0 hr", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
+                mContext, 1 * DAY + 59 * MINUTE));
+        assertEquals("1 day, 0 hr", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
+                mContext, 1 * DAY));
+        assertEquals("24 hr", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
+                mContext, 23 * HOUR + 30 * MINUTE));
+        assertEquals("3 hr", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
+                mContext, 2 * HOUR + 30 * MINUTE));
+        assertEquals("2 hr", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
+                mContext, 2 * HOUR));
+        assertEquals("1 hr, 0 min", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
+                mContext, 1 * HOUR));
+        assertEquals("1 hr, 0 min", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
+                mContext, 59 * MINUTE + 30 * SECOND));
+        assertEquals("59 min", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
+                mContext, 59 * MINUTE));
+        assertEquals("3 min", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
+                mContext, 2 * MINUTE + 30 * SECOND));
+        assertEquals("2 min", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
+                mContext, 2 * MINUTE));
+        assertEquals("2 min", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
+                mContext, 1 * MINUTE + 59 * SECOND + 999));
+        assertEquals("1 min", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
+                mContext, 1 * MINUTE));
+        assertEquals("1 min", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
+                mContext, 59 * SECOND + 999));
+        assertEquals("1 min", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
+                mContext, 1 * SECOND));
+        assertEquals("1 min", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
+                mContext, 1));
+        assertEquals("0 min", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
+                mContext, 0));
+
+        // Make sure it works on different locales.
+        setLocale(new Locale("ru", "RU"));
+        assertEquals("1 мин", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
+                mContext, 1 * SECOND));
+    }
+
     private void checkFormatBytes(long bytes, boolean useShort,
             String expectedString, long expectedRounded) {
         BytesResult r = Formatter.formatBytes(mContext.getResources(), bytes,
diff --git a/core/tests/coretests/src/android/widget/EditorCursorTest.java b/core/tests/coretests/src/android/widget/EditorCursorTest.java
index 6d650ff..9186827b 100644
--- a/core/tests/coretests/src/android/widget/EditorCursorTest.java
+++ b/core/tests/coretests/src/android/widget/EditorCursorTest.java
@@ -16,71 +16,68 @@
 
 package android.widget;
 
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.view.Choreographer;
-import android.view.ViewGroup;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
 import static android.support.test.espresso.Espresso.onView;
 import static android.support.test.espresso.action.ViewActions.click;
 import static android.widget.espresso.TextViewAssertions.hasInsertionPointerOnLeft;
 import static android.widget.espresso.TextViewAssertions.hasInsertionPointerOnRight;
+
+import static junit.framework.Assert.fail;
+
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.isEmptyString;
 import static org.hamcrest.Matchers.nullValue;
 import static org.hamcrest.Matchers.sameInstance;
 
-public class EditorCursorTest extends ActivityInstrumentationTestCase2<TextViewActivity> {
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.MediumTest;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
 
+import com.android.frameworks.coretests.R;
 
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+@MediumTest
+public class EditorCursorTest {
     private final static String LTR_STRING = "aaaaaaaaaaaaaaaaaaaaaa";
     private final static String LTR_HINT = "hint";
     private final static String RTL_STRING = "مرحبا الروبوت مرحبا الروبوت مرحبا الروبوت";
     private final static String RTL_HINT = "الروبوت";
     private final static int CURSOR_BLINK_MS = 500;
 
+    @Rule
+    public ActivityTestRule<TextViewActivity> mActivityRule = new ActivityTestRule<>(
+            TextViewActivity.class);
+
+    private Instrumentation mInstrumentation;
+    private Activity mActivity;
     private EditText mEditText;
 
-    public EditorCursorTest() {
-        super(TextViewActivity.class);
-    }
+    @Before
+    public void setUp() throws Throwable {
+        mActivity = mActivityRule.getActivity();
+        mInstrumentation = InstrumentationRegistry.getInstrumentation();
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mEditText = new EditText(getActivity());
-        mEditText.setTextSize(30);
-        mEditText.setSingleLine(true);
-        mEditText.setLines(1);
-        mEditText.setPadding(15, 15, 15, 15);
-        ViewGroup.LayoutParams editTextLayoutParams = new ViewGroup.LayoutParams(200,
-                ViewGroup.LayoutParams.WRAP_CONTENT);
-
-        mEditText.setLayoutParams(editTextLayoutParams);
-
-        final FrameLayout layout = new FrameLayout(getActivity());
-        ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT,
-                ViewGroup.LayoutParams.MATCH_PARENT);
-        layout.setLayoutParams(layoutParams);
-        layout.addView(mEditText);
-
-        getActivity().runOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                getActivity().setContentView(layout);
-            }
+        mActivityRule.runOnUiThread(() -> {
+            mActivity.setContentView(R.layout.activity_editor_cursor_test);
+            mEditText = mActivity.findViewById(R.id.edittext);
         });
-        getInstrumentation().waitForIdleSync();
+        mInstrumentation.waitForIdleSync();
         onView(sameInstance(mEditText)).perform(click());
     }
 
-    @SmallTest
-    public void testCursorIsInViewBoundariesWhenOnRightForLtr() {
+    @Test
+    public void testCursorIsInViewBoundariesWhenOnRightForLtr() throws Throwable {
         // Asserts that when an EditText has LTR text, and cursor is at the end (right),
         // cursor is drawn to the right edge of the view
         setEditTextText(LTR_STRING, LTR_STRING.length());
@@ -88,8 +85,8 @@
         onView(sameInstance(mEditText)).check(hasInsertionPointerOnRight());
     }
 
-    @SmallTest
-    public void testCursorIsInViewBoundariesWhenOnLeftForLtr() {
+    @Test
+    public void testCursorIsInViewBoundariesWhenOnLeftForLtr() throws Throwable {
         // Asserts that when an EditText has LTR text, and cursor is at the beginning,
         // cursor is drawn to the left edge of the view
         setEditTextText(LTR_STRING, 0);
@@ -97,8 +94,8 @@
         onView(sameInstance(mEditText)).check(hasInsertionPointerOnLeft());
     }
 
-    @SmallTest
-    public void testCursorIsInViewBoundariesWhenOnRightForRtl() {
+    @Test
+    public void testCursorIsInViewBoundariesWhenOnRightForRtl() throws Throwable {
         // Asserts that when an EditText has RTL text, and cursor is at the end,
         // cursor is drawn to the left edge of the view
         setEditTextText(RTL_STRING, 0);
@@ -106,8 +103,8 @@
         onView(sameInstance(mEditText)).check(hasInsertionPointerOnRight());
     }
 
-    @SmallTest
-    public void testCursorIsInViewBoundariesWhenOnLeftForRtl() {
+    @Test
+    public void testCursorIsInViewBoundariesWhenOnLeftForRtl() throws Throwable {
         // Asserts that when an EditText has RTL text, and cursor is at the beginning,
         // cursor is drawn to the right edge of the view
         setEditTextText(RTL_STRING, RTL_STRING.length());
@@ -116,8 +113,8 @@
     }
 
     /* Tests for cursor positioning with hint */
-    @SmallTest
-    public void testCursorIsOnLeft_withFirstStrongLtrAlgorithm() {
+    @Test
+    public void testCursorIsOnLeft_withFirstStrongLtrAlgorithm() throws Throwable {
         setEditTextHint(null, TextView.TEXT_DIRECTION_FIRST_STRONG_LTR, 0);
         assertThat(mEditText.getText().toString(), isEmptyString());
         assertThat(mEditText.getHint(), nullValue());
@@ -135,8 +132,8 @@
         onView(sameInstance(mEditText)).check(hasInsertionPointerOnLeft());
     }
 
-    @SmallTest
-    public void testCursorIsOnRight_withFirstStrongRtlAlgorithm() {
+    @Test
+    public void testCursorIsOnRight_withFirstStrongRtlAlgorithm() throws Throwable {
         setEditTextHint(null, TextView.TEXT_DIRECTION_FIRST_STRONG_RTL, 0);
         assertThat(mEditText.getText().toString(), isEmptyString());
         assertThat(mEditText.getHint(), nullValue());
@@ -154,8 +151,8 @@
         onView(sameInstance(mEditText)).check(hasInsertionPointerOnRight());
     }
 
-    @SmallTest
-    public void testCursorIsOnLeft_withLtrAlgorithm() {
+    @Test
+    public void testCursorIsOnLeft_withLtrAlgorithm() throws Throwable {
         setEditTextHint(null, TextView.TEXT_DIRECTION_LTR, 0);
         assertThat(mEditText.getText().toString(), isEmptyString());
         assertThat(mEditText.getHint(), nullValue());
@@ -173,8 +170,8 @@
         onView(sameInstance(mEditText)).check(hasInsertionPointerOnLeft());
     }
 
-    @SmallTest
-    public void testCursorIsOnRight_withRtlAlgorithm() {
+    @Test
+    public void testCursorIsOnRight_withRtlAlgorithm() throws Throwable {
         setEditTextHint(null, TextView.TEXT_DIRECTION_RTL, 0);
         assertThat(mEditText.getText().toString(), isEmptyString());
         assertThat(mEditText.getHint(), nullValue());
@@ -193,27 +190,19 @@
     }
 
     private void setEditTextProperties(final String text, final String hint,
-            final Integer textDirection, final Integer selection) {
-        getActivity().runOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                if (textDirection != null) mEditText.setTextDirection(textDirection);
-                if (text != null) mEditText.setText(text);
-                if (hint != null) mEditText.setHint(hint);
-                if (selection != null) mEditText.setSelection(selection);
-            }
+            final Integer textDirection, final Integer selection) throws Throwable {
+        mActivityRule.runOnUiThread(() -> {
+            if (textDirection != null) mEditText.setTextDirection(textDirection);
+            if (text != null) mEditText.setText(text);
+            if (hint != null) mEditText.setHint(hint);
+            if (selection != null) mEditText.setSelection(selection);
         });
-        getInstrumentation().waitForIdleSync();
+        mInstrumentation.waitForIdleSync();
 
         // wait for cursor to be drawn. updateCursorPositions function is called during draw() and
         // only when cursor is visible during blink.
         final CountDownLatch latch = new CountDownLatch(1);
-        mEditText.postOnAnimationDelayed(new Runnable() {
-            @Override
-            public void run() {
-                latch.countDown();
-            }
-        }, CURSOR_BLINK_MS);
+        mEditText.postOnAnimationDelayed(latch::countDown, CURSOR_BLINK_MS);
         try {
             assertThat("Problem while waiting for the cursor to blink",
                     latch.await(10, TimeUnit.SECONDS), equalTo(true));
@@ -222,11 +211,12 @@
         }
     }
 
-    private void setEditTextHint(final String hint, final int textDirection, final int selection) {
+    private void setEditTextHint(final String hint, final int textDirection, final int selection)
+            throws Throwable {
         setEditTextProperties(null, hint, textDirection, selection);
     }
 
-    private void setEditTextText(final String text, final Integer selection) {
+    private void setEditTextText(final String text, final Integer selection) throws Throwable {
         setEditTextProperties(text, null, null, selection);
     }
 }
diff --git a/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java b/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java
index 0483789..9124c94 100644
--- a/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java
@@ -42,32 +42,43 @@
 import static android.widget.espresso.TextViewAssertions.hasInsertionPointerAtIndex;
 import static android.widget.espresso.TextViewAssertions.hasSelection;
 
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.app.Activity;
+import android.support.test.filters.MediumTest;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
 import android.view.MotionEvent;
 import android.view.textclassifier.TextClassificationManager;
 import android.view.textclassifier.TextClassifier;
 
 import com.android.frameworks.coretests.R;
 
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 /**
  * Tests mouse interaction of the TextView widget from an Activity
  */
-public class TextViewActivityMouseTest extends ActivityInstrumentationTestCase2<TextViewActivity>{
+@RunWith(AndroidJUnit4.class)
+@MediumTest
+public class TextViewActivityMouseTest {
 
-    public TextViewActivityMouseTest() {
-        super(TextViewActivity.class);
-    }
+    @Rule
+    public ActivityTestRule<TextViewActivity> mActivityRule = new ActivityTestRule<>(
+            TextViewActivity.class);
 
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        getActivity().getSystemService(TextClassificationManager.class)
+    private Activity mActivity;
+
+    @Before
+    public void setUp() {
+        mActivity = mActivityRule.getActivity();
+        mActivity.getSystemService(TextClassificationManager.class)
                 .setTextClassifier(TextClassifier.NO_OP);
     }
 
-    @SmallTest
-    public void testSelectTextByDrag() throws Exception {
+    @Test
+    public void testSelectTextByDrag() {
         final String helloWorld = "Hello world!";
         onView(withId(R.id.textview)).perform(mouseClick());
         onView(withId(R.id.textview)).perform(replaceText(helloWorld));
@@ -90,8 +101,8 @@
         assertNoSelectionHandles();
     }
 
-    @SmallTest
-    public void testSelectTextByDrag_reverse() throws Exception {
+    @Test
+    public void testSelectTextByDrag_reverse() {
         final String helloWorld = "Hello world!";
         onView(withId(R.id.textview)).perform(mouseClick());
         onView(withId(R.id.textview)).perform(replaceText(helloWorld));
@@ -101,8 +112,8 @@
         onView(withId(R.id.textview)).check(hasSelection("llo wor"));
     }
 
-    @SmallTest
-    public void testContextMenu() throws Exception {
+    @Test
+    public void testContextMenu() {
         final String text = "abc def ghi.";
         onView(withId(R.id.textview)).perform(mouseClick());
         onView(withId(R.id.textview)).perform(replaceText(text));
@@ -113,9 +124,9 @@
                 mouseClickOnTextAtIndex(text.indexOf("d"), MotionEvent.BUTTON_SECONDARY));
 
         assertContextMenuContainsItemDisabled(
-                getActivity().getString(com.android.internal.R.string.copy));
+                mActivity.getString(com.android.internal.R.string.copy));
         assertContextMenuContainsItemDisabled(
-                getActivity().getString(com.android.internal.R.string.undo));
+                mActivity.getString(com.android.internal.R.string.undo));
 
         // Hide context menu.
         pressBack();
@@ -130,9 +141,9 @@
                 mouseClickOnTextAtIndex(text.indexOf("d"), MotionEvent.BUTTON_SECONDARY));
 
         assertContextMenuContainsItemDisabled(
-                getActivity().getString(com.android.internal.R.string.copy));
+                mActivity.getString(com.android.internal.R.string.copy));
         assertContextMenuContainsItemEnabled(
-                getActivity().getString(com.android.internal.R.string.undo));
+                mActivity.getString(com.android.internal.R.string.undo));
 
         // Hide context menu.
         pressBack();
@@ -144,9 +155,9 @@
                 mouseClickOnTextAtIndex(text.indexOf("d"), MotionEvent.BUTTON_SECONDARY));
 
         assertContextMenuContainsItemEnabled(
-                getActivity().getString(com.android.internal.R.string.copy));
+                mActivity.getString(com.android.internal.R.string.copy));
         assertContextMenuContainsItemEnabled(
-                getActivity().getString(com.android.internal.R.string.undo));
+                mActivity.getString(com.android.internal.R.string.undo));
 
         // Hide context menu.
         pressBack();
@@ -156,9 +167,9 @@
         onView(withId(R.id.textview)).perform(
                 mouseClickOnTextAtIndex(text.indexOf("i"), MotionEvent.BUTTON_SECONDARY));
         assertContextMenuContainsItemDisabled(
-                getActivity().getString(com.android.internal.R.string.copy));
+                mActivity.getString(com.android.internal.R.string.copy));
         assertContextMenuContainsItemEnabled(
-                getActivity().getString(com.android.internal.R.string.undo));
+                mActivity.getString(com.android.internal.R.string.undo));
 
         // Hide context menu.
         pressBack();
@@ -169,8 +180,8 @@
         // TODO: Add tests for suggestions
     }
 
-    @SmallTest
-    public void testDragAndDrop() throws Exception {
+    @Test
+    public void testDragAndDrop() {
         final String text = "abc def ghi.";
         onView(withId(R.id.textview)).perform(mouseClick());
         onView(withId(R.id.textview)).perform(replaceText(text));
@@ -186,8 +197,8 @@
         onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex("abc ghi.def".length()));
     }
 
-    @SmallTest
-    public void testDragAndDrop_longClick() throws Exception {
+    @Test
+    public void testDragAndDrop_longClick() {
         final String text = "abc def ghi.";
         onView(withId(R.id.textview)).perform(mouseClick());
         onView(withId(R.id.textview)).perform(replaceText(text));
@@ -203,8 +214,8 @@
         onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex("abc ghi.def".length()));
     }
 
-    @SmallTest
-    public void testSelectTextByLongClick() throws Exception {
+    @Test
+    public void testSelectTextByLongClick() {
         final String helloWorld = "Hello world!";
         onView(withId(R.id.textview)).perform(mouseClick());
         onView(withId(R.id.textview)).perform(replaceText(helloWorld));
@@ -228,8 +239,8 @@
         onView(withId(R.id.textview)).check(hasSelection("!"));
     }
 
-    @SmallTest
-    public void testSelectTextByDoubleClick() throws Exception {
+    @Test
+    public void testSelectTextByDoubleClick() {
         final String helloWorld = "hello world!";
 
         onView(withId(R.id.textview)).perform(mouseClick());
@@ -254,8 +265,8 @@
         onView(withId(R.id.textview)).check(hasSelection("!"));
     }
 
-    @SmallTest
-    public void testSelectTextByDoubleClickAndDrag() throws Exception {
+    @Test
+    public void testSelectTextByDoubleClickAndDrag() {
         final String text = "abcd efg hijk lmn";
         onView(withId(R.id.textview)).perform(mouseClick());
         onView(withId(R.id.textview)).perform(replaceText(text));
@@ -265,8 +276,8 @@
         onView(withId(R.id.textview)).check(hasSelection("efg hijk"));
     }
 
-    @SmallTest
-    public void testSelectTextByDoubleClickAndDrag_reverse() throws Exception {
+    @Test
+    public void testSelectTextByDoubleClickAndDrag_reverse() {
         final String text = "abcd efg hijk lmn";
         onView(withId(R.id.textview)).perform(mouseClick());
         onView(withId(R.id.textview)).perform(replaceText(text));
@@ -276,8 +287,8 @@
         onView(withId(R.id.textview)).check(hasSelection("efg hijk"));
     }
 
-    @SmallTest
-    public void testSelectTextByLongPressAndDrag() throws Exception {
+    @Test
+    public void testSelectTextByLongPressAndDrag() {
         final String text = "abcd efg hijk lmn";
         onView(withId(R.id.textview)).perform(mouseClick());
         onView(withId(R.id.textview)).perform(replaceText(text));
@@ -287,8 +298,8 @@
         onView(withId(R.id.textview)).check(hasSelection("efg hijk"));
     }
 
-    @SmallTest
-    public void testSelectTextByLongPressAndDrag_reverse() throws Exception {
+    @Test
+    public void testSelectTextByLongPressAndDrag_reverse() {
         final String text = "abcd efg hijk lmn";
         onView(withId(R.id.textview)).perform(mouseClick());
         onView(withId(R.id.textview)).perform(replaceText(text));
@@ -298,8 +309,8 @@
         onView(withId(R.id.textview)).check(hasSelection("efg hijk"));
     }
 
-    @SmallTest
-    public void testSelectTextByTripleClick() throws Exception {
+    @Test
+    public void testSelectTextByTripleClick() {
         final StringBuilder builder = new StringBuilder();
         builder.append("First paragraph.\n");
         builder.append("Second paragraph.");
@@ -332,8 +343,8 @@
                 text.substring(text.indexOf("Second"), text.indexOf("Third"))));
     }
 
-    @SmallTest
-    public void testSelectTextByTripleClickAndDrag() throws Exception {
+    @Test
+    public void testSelectTextByTripleClickAndDrag() {
         final StringBuilder builder = new StringBuilder();
         builder.append("First paragraph.\n");
         builder.append("Second paragraph.");
@@ -361,8 +372,8 @@
         onView(withId(R.id.textview)).check(hasSelection(text));
     }
 
-    @SmallTest
-    public void testSelectTextByTripleClickAndDrag_reverse() throws Exception {
+    @Test
+    public void testSelectTextByTripleClickAndDrag_reverse() {
         final StringBuilder builder = new StringBuilder();
         builder.append("First paragraph.\n");
         builder.append("Second paragraph.");
diff --git a/core/tests/coretests/src/android/widget/TextViewActivityTest.java b/core/tests/coretests/src/android/widget/TextViewActivityTest.java
index 5a7bca4..d69b1e4 100644
--- a/core/tests/coretests/src/android/widget/TextViewActivityTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewActivityTest.java
@@ -16,26 +16,6 @@
 
 package android.widget;
 
-import static android.widget.espresso.CustomViewActions.longPressAtRelativeCoordinates;
-import static android.widget.espresso.DragHandleUtils.assertNoSelectionHandles;
-import static android.widget.espresso.DragHandleUtils.onHandleView;
-import static android.widget.espresso.TextViewActions.clickOnTextAtIndex;
-import static android.widget.espresso.TextViewActions.doubleTapAndDragOnText;
-import static android.widget.espresso.TextViewActions.doubleClickOnTextAtIndex;
-import static android.widget.espresso.TextViewActions.dragHandle;
-import static android.widget.espresso.TextViewActions.Handle;
-import static android.widget.espresso.TextViewActions.longPressAndDragOnText;
-import static android.widget.espresso.TextViewActions.longPressOnTextAtIndex;
-import static android.widget.espresso.TextViewAssertions.hasInsertionPointerAtIndex;
-import static android.widget.espresso.TextViewAssertions.hasSelection;
-import static android.widget.espresso.TextViewAssertions.doesNotHaveStyledText;
-import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarItemIndex;
-import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarIsDisplayed;
-import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarIsNotDisplayed;
-import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarContainsItem;
-import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarDoesNotContainItem;
-import static android.widget.espresso.FloatingToolbarEspressoUtils.clickFloatingToolbarItem;
-import static android.widget.espresso.FloatingToolbarEspressoUtils.sleepForFloatingToolbarPopup;
 import static android.support.test.espresso.Espresso.onView;
 import static android.support.test.espresso.action.ViewActions.click;
 import static android.support.test.espresso.action.ViewActions.longClick;
@@ -45,48 +25,84 @@
 import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
 import static android.support.test.espresso.matcher.ViewMatchers.withId;
 import static android.support.test.espresso.matcher.ViewMatchers.withText;
+import static android.widget.espresso.CustomViewActions.longPressAtRelativeCoordinates;
+import static android.widget.espresso.DragHandleUtils.assertNoSelectionHandles;
+import static android.widget.espresso.DragHandleUtils.onHandleView;
+import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarContainsItem;
+import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarDoesNotContainItem;
+import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarIsDisplayed;
+import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarIsNotDisplayed;
+import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarItemIndex;
+import static android.widget.espresso.FloatingToolbarEspressoUtils.clickFloatingToolbarItem;
+import static android.widget.espresso.FloatingToolbarEspressoUtils.sleepForFloatingToolbarPopup;
+import static android.widget.espresso.TextViewActions.Handle;
+import static android.widget.espresso.TextViewActions.clickOnTextAtIndex;
+import static android.widget.espresso.TextViewActions.doubleClickOnTextAtIndex;
+import static android.widget.espresso.TextViewActions.doubleTapAndDragOnText;
+import static android.widget.espresso.TextViewActions.dragHandle;
+import static android.widget.espresso.TextViewActions.longPressAndDragOnText;
+import static android.widget.espresso.TextViewActions.longPressOnTextAtIndex;
+import static android.widget.espresso.TextViewAssertions.doesNotHaveStyledText;
+import static android.widget.espresso.TextViewAssertions.hasInsertionPointerAtIndex;
+import static android.widget.espresso.TextViewAssertions.hasSelection;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
 import static org.hamcrest.Matchers.anyOf;
 import static org.hamcrest.Matchers.is;
 
+import android.app.Activity;
+import android.app.Instrumentation;
 import android.content.ClipData;
 import android.content.ClipboardManager;
-import android.support.test.espresso.NoMatchingViewException;
-import android.support.test.espresso.ViewAssertion;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.espresso.action.EspressoKey;
+import android.support.test.filters.MediumTest;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.text.InputType;
+import android.text.Selection;
+import android.text.Spannable;
 import android.view.ActionMode;
+import android.view.KeyEvent;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.textclassifier.TextClassificationManager;
 import android.view.textclassifier.TextClassifier;
 import android.widget.espresso.CustomViewActions.RelativeCoordinatesProvider;
 
-import android.support.test.espresso.action.EspressoKey;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.text.Selection;
-import android.text.Spannable;
-import android.text.InputType;
-import android.view.KeyEvent;
-
 import com.android.frameworks.coretests.R;
 
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 /**
  * Tests the TextView widget from an Activity
  */
+@RunWith(AndroidJUnit4.class)
 @MediumTest
-public class TextViewActivityTest extends ActivityInstrumentationTestCase2<TextViewActivity>{
+public class TextViewActivityTest {
 
-    public TextViewActivityTest() {
-        super(TextViewActivity.class);
-    }
+    @Rule
+    public ActivityTestRule<TextViewActivity> mActivityRule = new ActivityTestRule<>(
+            TextViewActivity.class);
 
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        getActivity().getSystemService(TextClassificationManager.class)
+    private Activity mActivity;
+    private Instrumentation mInstrumentation;
+
+    @Before
+    public void setUp() {
+        mActivity = mActivityRule.getActivity();
+        mInstrumentation = InstrumentationRegistry.getInstrumentation();
+        mActivity.getSystemService(TextClassificationManager.class)
                 .setTextClassifier(TextClassifier.NO_OP);
     }
 
-    public void testTypedTextIsOnScreen() throws Exception {
+    @Test
+    public void testTypedTextIsOnScreen() {
         final String helloWorld = "Hello world!";
         // We use replaceText instead of typeTextIntoFocusedView to input text to avoid
         // unintentional interactions with software keyboard.
@@ -94,8 +110,8 @@
 
         onView(withId(R.id.textview)).check(matches(withText(helloWorld)));
     }
-
-    public void testPositionCursorAtTextAtIndex() throws Exception {
+    @Test
+    public void testPositionCursorAtTextAtIndex() {
         final String helloWorld = "Hello world!";
         onView(withId(R.id.textview)).perform(replaceText(helloWorld));
         onView(withId(R.id.textview)).perform(clickOnTextAtIndex(helloWorld.indexOf("world")));
@@ -105,7 +121,8 @@
         onView(withId(R.id.textview)).check(matches(withText("Hello orld!")));
     }
 
-    public void testPositionCursorAtTextAtIndex_arabic() throws Exception {
+    @Test
+    public void testPositionCursorAtTextAtIndex_arabic() {
         // Arabic text. The expected cursorable boundary is
         // | \u0623 \u064F | \u067A | \u0633 \u0652 |
         final String text = "\u0623\u064F\u067A\u0633\u0652";
@@ -125,7 +142,8 @@
         onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(5));
     }
 
-    public void testPositionCursorAtTextAtIndex_devanagari() throws Exception {
+    @Test
+    public void testPositionCursorAtTextAtIndex_devanagari() {
         // Devanagari text. The expected cursorable boundary is | \u0915 \u093E |
         final String text = "\u0915\u093E";
         onView(withId(R.id.textview)).perform(replaceText(text));
@@ -138,7 +156,8 @@
         onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(2));
     }
 
-    public void testLongPressToSelect() throws Exception {
+    @Test
+    public void testLongPressToSelect() {
         final String helloWorld = "Hello Kirk!";
         onView(withId(R.id.textview)).perform(click());
         onView(withId(R.id.textview)).perform(replaceText(helloWorld));
@@ -148,7 +167,8 @@
         onView(withId(R.id.textview)).check(hasSelection("Kirk"));
     }
 
-    public void testLongPressEmptySpace() throws Exception {
+    @Test
+    public void testLongPressEmptySpace() {
         final String helloWorld = "Hello big round sun!";
         onView(withId(R.id.textview)).perform(replaceText(helloWorld));
         // Move cursor somewhere else
@@ -161,7 +181,8 @@
         onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(helloWorld.length()));
     }
 
-    public void testLongPressAndDragToSelect() throws Exception {
+    @Test
+    public void testLongPressAndDragToSelect() {
         final String helloWorld = "Hello little handsome boy!";
         onView(withId(R.id.textview)).perform(replaceText(helloWorld));
         onView(withId(R.id.textview)).perform(
@@ -170,7 +191,8 @@
         onView(withId(R.id.textview)).check(hasSelection("little handsome"));
     }
 
-    public void testLongPressAndDragToSelect_emoji() throws Exception {
+    @Test
+    public void testLongPressAndDragToSelect_emoji() {
         final String text = "\uD83D\uDE00\uD83D\uDE01\uD83D\uDE02\uD83D\uDE03";
         onView(withId(R.id.textview)).perform(replaceText(text));
 
@@ -183,7 +205,8 @@
         onView(withId(R.id.textview)).check(hasSelection("\uD83D\uDE01"));
     }
 
-    public void testDragAndDrop() throws Exception {
+    @Test
+    public void testDragAndDrop() {
         final String text = "abc def ghi.";
         onView(withId(R.id.textview)).perform(replaceText(text));
         onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf("e")));
@@ -203,7 +226,8 @@
         onView(withId(R.id.textview)).check(matches(withText(text)));
     }
 
-    public void testDoubleTapToSelect() throws Exception {
+    @Test
+    public void testDoubleTapToSelect() {
         final String helloWorld = "Hello SuetYi!";
         onView(withId(R.id.textview)).perform(replaceText(helloWorld));
 
@@ -213,16 +237,18 @@
         onView(withId(R.id.textview)).check(hasSelection("SuetYi"));
     }
 
-    public void testDoubleTapAndDragToSelect() throws Exception {
-        final String helloWorld = "Hello young beautiful girl!";
+    @Test
+    public void testDoubleTapAndDragToSelect() {
+        final String helloWorld = "Hello young beautiful person!";
         onView(withId(R.id.textview)).perform(replaceText(helloWorld));
-        onView(withId(R.id.textview)).perform(
-                doubleTapAndDragOnText(helloWorld.indexOf("young"), helloWorld.indexOf(" girl!")));
+        onView(withId(R.id.textview)).perform(doubleTapAndDragOnText(helloWorld.indexOf("young"),
+                        helloWorld.indexOf(" person!")));
 
         onView(withId(R.id.textview)).check(hasSelection("young beautiful"));
     }
 
-    public void testDoubleTapAndDragToSelect_multiLine() throws Exception {
+    @Test
+    public void testDoubleTapAndDragToSelect_multiLine() {
         final String helloWorld = "abcd\n" + "efg\n" + "hijklm\n" + "nop";
         onView(withId(R.id.textview)).perform(replaceText(helloWorld));
         onView(withId(R.id.textview)).perform(
@@ -230,7 +256,8 @@
         onView(withId(R.id.textview)).check(hasSelection("abcd\nefg\nhijklm"));
     }
 
-    public void testSelectBackwordsByTouch() throws Exception {
+    @Test
+    public void testSelectBackwordsByTouch() {
         final String helloWorld = "Hello king of the Jungle!";
         onView(withId(R.id.textview)).perform(replaceText(helloWorld));
         onView(withId(R.id.textview)).perform(
@@ -239,7 +266,8 @@
         onView(withId(R.id.textview)).check(hasSelection("king of the"));
     }
 
-    public void testToolbarAppearsAfterSelection() throws Exception {
+    @Test
+    public void testToolbarAppearsAfterSelection() {
         final String text = "Toolbar appears after selection.";
         assertFloatingToolbarIsNotDisplayed();
         onView(withId(R.id.textview)).perform(replaceText(text));
@@ -255,34 +283,32 @@
         assertFloatingToolbarIsNotDisplayed();
     }
 
+    @Test
     public void testToolbarAppearsAfterSelection_withFirstStringLtrAlgorithmAndRtlHint()
-            throws Exception {
+            throws Throwable {
         // after the hint layout change, the floating toolbar was not visible in the case below
         // this test tests that the floating toolbar is displayed on the screen and is visible to
         // user.
-        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
-        textView.post(new Runnable() {
-            @Override
-            public void run() {
-                textView.setTextDirection(TextView.TEXT_DIRECTION_FIRST_STRONG_LTR);
-                textView.setInputType(InputType.TYPE_CLASS_TEXT);
-                textView.setSingleLine(true);
-                textView.setHint("الروبوت");
-            }
+        mActivityRule.runOnUiThread(() -> {
+            final TextView textView = mActivity.findViewById(R.id.textview);
+            textView.setTextDirection(TextView.TEXT_DIRECTION_FIRST_STRONG_LTR);
+            textView.setInputType(InputType.TYPE_CLASS_TEXT);
+            textView.setSingleLine(true);
+            textView.setHint("الروبوت");
         });
-        getInstrumentation().waitForIdleSync();
+        mInstrumentation.waitForIdleSync();
 
         onView(withId(R.id.textview)).perform(replaceText("test"));
         onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(1));
-        clickFloatingToolbarItem(
-                getActivity().getString(com.android.internal.R.string.cut));
+        clickFloatingToolbarItem(mActivity.getString(com.android.internal.R.string.cut));
         onView(withId(R.id.textview)).perform(longClick());
         sleepForFloatingToolbarPopup();
 
         assertFloatingToolbarIsDisplayed();
     }
 
-    public void testToolbarAndInsertionHandle() throws Exception {
+    @Test
+    public void testToolbarAndInsertionHandle() {
         final String text = "text";
         onView(withId(R.id.textview)).perform(replaceText(text));
         onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.length()));
@@ -293,14 +319,15 @@
         assertFloatingToolbarIsDisplayed();
 
         assertFloatingToolbarContainsItem(
-                getActivity().getString(com.android.internal.R.string.selectAll));
+                mActivity.getString(com.android.internal.R.string.selectAll));
         assertFloatingToolbarDoesNotContainItem(
-                getActivity().getString(com.android.internal.R.string.copy));
+                mActivity.getString(com.android.internal.R.string.copy));
         assertFloatingToolbarDoesNotContainItem(
-                getActivity().getString(com.android.internal.R.string.cut));
+                mActivity.getString(com.android.internal.R.string.cut));
     }
 
-    public void testToolbarAndSelectionHandle() throws Exception {
+    @Test
+    public void testToolbarAndSelectionHandle() {
         final String text = "abcd efg hijk";
         onView(withId(R.id.textview)).perform(replaceText(text));
 
@@ -309,13 +336,13 @@
         assertFloatingToolbarIsDisplayed();
 
         assertFloatingToolbarContainsItem(
-                getActivity().getString(com.android.internal.R.string.selectAll));
+                mActivity.getString(com.android.internal.R.string.selectAll));
         assertFloatingToolbarContainsItem(
-                getActivity().getString(com.android.internal.R.string.copy));
+                mActivity.getString(com.android.internal.R.string.copy));
         assertFloatingToolbarContainsItem(
-                getActivity().getString(com.android.internal.R.string.cut));
+                mActivity.getString(com.android.internal.R.string.cut));
 
-        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
+        final TextView textView = mActivity.findViewById(R.id.textview);
         onHandleView(com.android.internal.R.id.selection_start_handle)
                 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('a')));
         sleepForFloatingToolbarPopup();
@@ -327,21 +354,22 @@
         assertFloatingToolbarIsDisplayed();
 
         assertFloatingToolbarDoesNotContainItem(
-                getActivity().getString(com.android.internal.R.string.selectAll));
+                mActivity.getString(com.android.internal.R.string.selectAll));
         assertFloatingToolbarContainsItem(
-                getActivity().getString(com.android.internal.R.string.copy));
+                mActivity.getString(com.android.internal.R.string.copy));
         assertFloatingToolbarContainsItem(
-                getActivity().getString(com.android.internal.R.string.cut));
+                mActivity.getString(com.android.internal.R.string.cut));
     }
 
-    public void testInsertionHandle() throws Exception {
+    @Test
+    public void testInsertionHandle() {
         final String text = "abcd efg hijk ";
         onView(withId(R.id.textview)).perform(replaceText(text));
 
         onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.length()));
         onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.length()));
 
-        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
+        final TextView textView = mActivity.findViewById(R.id.textview);
 
         onHandleView(com.android.internal.R.id.insertion_handle)
                 .perform(dragHandle(textView, Handle.INSERTION, text.indexOf('a')));
@@ -352,14 +380,15 @@
         onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("f")));
     }
 
-    public void testInsertionHandle_multiLine() throws Exception {
+    @Test
+    public void testInsertionHandle_multiLine() {
         final String text = "abcd\n" + "efg\n" + "hijk\n";
         onView(withId(R.id.textview)).perform(replaceText(text));
 
         onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.length()));
         onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.length()));
 
-        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
+        final TextView textView = mActivity.findViewById(R.id.textview);
 
         onHandleView(com.android.internal.R.id.insertion_handle)
                 .perform(dragHandle(textView, Handle.INSERTION, text.indexOf('a')));
@@ -370,7 +399,8 @@
         onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("f")));
     }
 
-    public void testSelectionHandles() throws Exception {
+    @Test
+    public void testSelectionHandles() {
         final String text = "abcd efg hijk lmn";
         onView(withId(R.id.textview)).perform(replaceText(text));
 
@@ -383,7 +413,7 @@
         onHandleView(com.android.internal.R.id.selection_end_handle)
                 .check(matches(isDisplayed()));
 
-        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
+        final TextView textView = mActivity.findViewById(R.id.textview);
         onHandleView(com.android.internal.R.id.selection_start_handle)
                 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('a')));
         onView(withId(R.id.textview)).check(hasSelection("abcd efg"));
@@ -393,7 +423,8 @@
         onView(withId(R.id.textview)).check(hasSelection("abcd efg hijk"));
     }
 
-    public void testSelectionHandles_bidi() throws Exception {
+    @Test
+    public void testSelectionHandles_bidi() {
         final String text = "abc \u0621\u0622\u0623 def";
         onView(withId(R.id.textview)).perform(replaceText(text));
 
@@ -408,7 +439,7 @@
 
         onView(withId(R.id.textview)).check(hasSelection("\u0621\u0622\u0623"));
 
-        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
+        final TextView textView = mActivity.findViewById(R.id.textview);
         onHandleView(com.android.internal.R.id.selection_start_handle)
                 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('f')));
         onView(withId(R.id.textview)).check(hasSelection("\u0621\u0622\u0623"));
@@ -436,12 +467,13 @@
         onView(withId(R.id.textview)).check(hasSelection("abc \u0621\u0622\u0623 def"));
     }
 
-    public void testSelectionHandles_multiLine() throws Exception {
+    @Test
+    public void testSelectionHandles_multiLine() {
         final String text = "abcd\n" + "efg\n" + "hijk\n" + "lmn\n" + "opqr";
         onView(withId(R.id.textview)).perform(replaceText(text));
         onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('i')));
 
-        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
+        final TextView textView = mActivity.findViewById(R.id.textview);
         onHandleView(com.android.internal.R.id.selection_start_handle)
                 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('e')));
         onView(withId(R.id.textview)).check(hasSelection("efg\nhijk"));
@@ -459,7 +491,8 @@
         onView(withId(R.id.textview)).check(hasSelection("abcd\nefg\nhijk\nlmn\nopqr"));
     }
 
-    public void testSelectionHandles_multiLine_rtl() throws Exception {
+    @Test
+    public void testSelectionHandles_multiLine_rtl() {
         // Arabic text.
         final String text = "\u062A\u062B\u062C\n" + "\u062D\u062E\u062F\n"
                 + "\u0630\u0631\u0632\n" + "\u0633\u0634\u0635\n" + "\u0636\u0637\u0638\n"
@@ -467,7 +500,7 @@
         onView(withId(R.id.textview)).perform(replaceText(text));
         onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('\u0634')));
 
-        final TextView textView = (TextView)getActivity().findViewById(R.id.textview);
+        final TextView textView = mActivity.findViewById(R.id.textview);
         onHandleView(com.android.internal.R.id.selection_start_handle)
                 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('\u062E')));
         onView(withId(R.id.textview)).check(hasSelection(
@@ -488,13 +521,13 @@
         onView(withId(R.id.textview)).check(hasSelection(text));
     }
 
-
-    public void testSelectionHandles_doesNotPassAnotherHandle() throws Exception {
+    @Test
+    public void testSelectionHandles_doesNotPassAnotherHandle() {
         final String text = "abcd efg hijk lmn";
         onView(withId(R.id.textview)).perform(replaceText(text));
         onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('f')));
 
-        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
+        final TextView textView = mActivity.findViewById(R.id.textview);
         onHandleView(com.android.internal.R.id.selection_start_handle)
                 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('l')));
         onView(withId(R.id.textview)).check(hasSelection("g"));
@@ -505,12 +538,13 @@
         onView(withId(R.id.textview)).check(hasSelection("e"));
     }
 
-    public void testSelectionHandles_doesNotPassAnotherHandle_multiLine() throws Exception {
+    @Test
+    public void testSelectionHandles_doesNotPassAnotherHandle_multiLine() {
         final String text = "abcd\n" + "efg\n" + "hijk\n" + "lmn\n" + "opqr";
         onView(withId(R.id.textview)).perform(replaceText(text));
         onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('i')));
 
-        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
+        final TextView textView = mActivity.findViewById(R.id.textview);
         onHandleView(com.android.internal.R.id.selection_start_handle)
                 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('r') + 1));
         onView(withId(R.id.textview)).check(hasSelection("k"));
@@ -521,12 +555,13 @@
         onView(withId(R.id.textview)).check(hasSelection("h"));
     }
 
-    public void testSelectionHandles_snapToWordBoundary() throws Exception {
+    @Test
+    public void testSelectionHandles_snapToWordBoundary() {
         final String text = "abcd efg hijk lmn opqr";
         onView(withId(R.id.textview)).perform(replaceText(text));
         onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('i')));
 
-        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
+        final TextView textView = mActivity.findViewById(R.id.textview);
 
         onHandleView(com.android.internal.R.id.selection_start_handle)
                 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('f')));
@@ -573,12 +608,13 @@
         onView(withId(R.id.textview)).check(hasSelection("hijk lmn opq"));
     }
 
-    public void testSelectionHandles_snapToWordBoundary_multiLine() throws Exception {
+    @Test
+    public void testSelectionHandles_snapToWordBoundary_multiLine() {
         final String text = "abcd efg\n" + "hijk lmn\n" + "opqr stu";
         onView(withId(R.id.textview)).perform(replaceText(text));
         onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('m')));
 
-        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
+        final TextView textView = mActivity.findViewById(R.id.textview);
 
         onHandleView(com.android.internal.R.id.selection_start_handle)
                 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('c')));
@@ -607,14 +643,16 @@
         onView(withId(R.id.textview)).check(hasSelection("hijk"));
     }
 
-    public void testSetSelectionAndActionMode() throws Exception {
+    @Test
+    public void testSetSelectionAndActionMode() throws Throwable {
         final String text = "abc def";
         onView(withId(R.id.textview)).perform(replaceText(text));
 
-        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
+        final TextView textView = mActivity.findViewById(R.id.textview);
         assertFloatingToolbarIsNotDisplayed();
-        textView.post(() -> Selection.setSelection((Spannable) textView.getText(), 0, 3));
-        getInstrumentation().waitForIdleSync();
+        mActivityRule.runOnUiThread(
+                () -> Selection.setSelection((Spannable) textView.getText(), 0, 3));
+        mInstrumentation.waitForIdleSync();
         sleepForFloatingToolbarPopup();
         // Don't automatically start action mode.
         assertFloatingToolbarIsNotDisplayed();
@@ -624,25 +662,29 @@
         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();
+        mActivityRule.runOnUiThread(
+                () -> Selection.setSelection((Spannable) textView.getText(), 0, 3));
+        mInstrumentation.waitForIdleSync();
         sleepForFloatingToolbarPopup();
         assertFloatingToolbarIsDisplayed();
         assertFloatingToolbarContainsItem(
-                getActivity().getString(com.android.internal.R.string.selectAll));
+                mActivity.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(
+        mActivityRule.runOnUiThread(
                 () -> Selection.setSelection((Spannable) textView.getText(), 0, text.length()));
-        getInstrumentation().waitForIdleSync();
+        mInstrumentation.waitForIdleSync();
+
         sleepForFloatingToolbarPopup();
         assertFloatingToolbarIsDisplayed();
         assertFloatingToolbarDoesNotContainItem(
-                getActivity().getString(com.android.internal.R.string.selectAll));
+                mActivity.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();
+        mActivityRule.runOnUiThread(
+                () -> Selection.setSelection((Spannable) textView.getText(), 0));
+        mInstrumentation.waitForIdleSync();
+
         sleepForFloatingToolbarPopup();
         assertFloatingToolbarIsNotDisplayed();
         // Make sure that user click can trigger the insertion action mode.
@@ -652,28 +694,32 @@
         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();
+        mActivityRule.runOnUiThread(
+                () -> Selection.setSelection((Spannable) textView.getText(), 0));
+        mInstrumentation.waitForIdleSync();
+
         sleepForFloatingToolbarPopup();
         assertFloatingToolbarIsDisplayed();
         assertFloatingToolbarDoesNotContainItem(
-                getActivity().getString(com.android.internal.R.string.copy));
+                mActivity.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(
+        mActivityRule.runOnUiThread(
                 () -> Selection.setSelection((Spannable) textView.getText(), 1, text.length()));
-        getInstrumentation().waitForIdleSync();
+        mInstrumentation.waitForIdleSync();
+
         sleepForFloatingToolbarPopup();
         assertFloatingToolbarIsDisplayed();
         assertFloatingToolbarContainsItem(
-                getActivity().getString(com.android.internal.R.string.copy));
+                mActivity.getString(com.android.internal.R.string.copy));
     }
 
-    public void testTransientState() throws Exception {
+    @Test
+    public void testTransientState() throws Throwable {
         final String text = "abc def";
         onView(withId(R.id.textview)).perform(replaceText(text));
 
-        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
+        final TextView textView = mActivity.findViewById(R.id.textview);
         assertFalse(textView.hasTransientState());
 
         onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('b')));
@@ -682,22 +728,24 @@
         onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.indexOf('d')));
         // hasTransientState should return false as the selection has been cleared.
         assertFalse(textView.hasTransientState());
-        textView.post(
+        mActivityRule.runOnUiThread(
                 () -> Selection.setSelection((Spannable) textView.getText(), 0, text.length()));
-        getInstrumentation().waitForIdleSync();
+        mInstrumentation.waitForIdleSync();
+
         // hasTransientState should return false when selection is created by API.
         assertFalse(textView.hasTransientState());
     }
 
-    public void testResetMenuItemTitle() throws Exception {
-        getActivity().getSystemService(TextClassificationManager.class).setTextClassifier(null);
-        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
+    @Test
+    public void testResetMenuItemTitle() throws Throwable {
+        mActivity.getSystemService(TextClassificationManager.class).setTextClassifier(null);
+        final TextView textView = mActivity.findViewById(R.id.textview);
         final int itemId = 1;
         final String title1 = " AFIGBO";
         final int index = title1.indexOf('I');
         final String title2 = title1.substring(index);
         final String[] title = new String[]{title1};
-        textView.post(() -> textView.setCustomSelectionActionModeCallback(
+        mActivityRule.runOnUiThread(() -> textView.setCustomSelectionActionModeCallback(
                 new ActionMode.Callback() {
                     @Override
                     public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
@@ -720,6 +768,8 @@
                     public void onDestroyActionMode(ActionMode actionMode) {
                     }
                 }));
+        mInstrumentation.waitForIdleSync();
+
         onView(withId(R.id.textview)).perform(replaceText(title1));
         onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(index));
         sleepForFloatingToolbarPopup();
@@ -734,10 +784,11 @@
         assertFloatingToolbarContainsItem(title2);
     }
 
-    public void testAssistItemIsAtIndexZero() throws Exception {
-        getActivity().getSystemService(TextClassificationManager.class).setTextClassifier(null);
-        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
-        textView.post(() -> textView.setCustomSelectionActionModeCallback(
+    @Test
+    public void testAssistItemIsAtIndexZero() throws Throwable {
+        mActivity.getSystemService(TextClassificationManager.class).setTextClassifier(null);
+        final TextView textView = mActivity.findViewById(R.id.textview);
+        mActivityRule.runOnUiThread(() -> textView.setCustomSelectionActionModeCallback(
                 new ActionMode.Callback() {
                     @Override
                     public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
@@ -761,6 +812,7 @@
                     public void onDestroyActionMode(ActionMode actionMode) {
                     }
                 }));
+        mInstrumentation.waitForIdleSync();
         final String text = "droid@android.com";
 
         onView(withId(R.id.textview)).perform(replaceText(text));
@@ -769,20 +821,22 @@
         assertFloatingToolbarItemIndex(android.R.id.textAssist, 0);
     }
 
-    public void testPastePlainText_menuAction() throws Exception {
+    @Test
+    public void testPastePlainText_menuAction() {
         initializeClipboardWithText(TextStyle.STYLED);
 
         onView(withId(R.id.textview)).perform(replaceText(""));
         onView(withId(R.id.textview)).perform(longClick());
         sleepForFloatingToolbarPopup();
         clickFloatingToolbarItem(
-                getActivity().getString(com.android.internal.R.string.paste_as_plain_text));
-        getInstrumentation().waitForIdleSync();
+                mActivity.getString(com.android.internal.R.string.paste_as_plain_text));
+        mInstrumentation.waitForIdleSync();
 
         onView(withId(R.id.textview)).check(matches(withText("styledtext")));
         onView(withId(R.id.textview)).check(doesNotHaveStyledText());
     }
 
+    @Test
     public void testPastePlainText_noMenuItemForPlainText() {
         initializeClipboardWithText(TextStyle.PLAIN);
 
@@ -791,7 +845,7 @@
         sleepForFloatingToolbarPopup();
 
         assertFloatingToolbarDoesNotContainItem(
-                getActivity().getString(com.android.internal.R.string.paste_as_plain_text));
+                mActivity.getString(com.android.internal.R.string.paste_as_plain_text));
     }
 
     private void initializeClipboardWithText(TextStyle textStyle) {
@@ -806,9 +860,9 @@
             default:
                 throw new IllegalArgumentException("Invalid text style");
         }
-        getActivity().getWindow().getDecorView().post(() ->
-            getActivity().getSystemService(ClipboardManager.class).setPrimaryClip( clip));
-        getInstrumentation().waitForIdleSync();
+        mActivity.getWindow().getDecorView().post(() ->
+                mActivity.getSystemService(ClipboardManager.class).setPrimaryClip(clip));
+        mInstrumentation.waitForIdleSync();
     }
 
     private enum TextStyle {
diff --git a/core/tests/coretests/src/android/widget/TextViewPerformanceTest.java b/core/tests/coretests/src/android/widget/TextViewPerformanceTest.java
index c25df7c..cf173fb 100644
--- a/core/tests/coretests/src/android/widget/TextViewPerformanceTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewPerformanceTest.java
@@ -20,15 +20,20 @@
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Paint;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.MediumTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.text.SpannedString;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.TextView;
 
-public class TextViewPerformanceTest extends AndroidTestCase {
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class TextViewPerformanceTest {
 
     private String mString = "The quick brown fox";
     private Canvas mCanvas;
@@ -36,16 +41,16 @@
     private Paint mPaint;
     private PerformanceLabelView mLabelView;
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
+    @Before
+    public void setUp() {
         Bitmap mBitmap = Bitmap.createBitmap(320, 240, Bitmap.Config.RGB_565);
         mCanvas = new Canvas(mBitmap);
 
         ViewGroup.LayoutParams p = new ViewGroup.LayoutParams(320, 240);
 
-        mLabelView = new PerformanceLabelView(mContext);
+        final Context context = InstrumentationRegistry.getContext();
+
+        mLabelView = new PerformanceLabelView(context);
         mLabelView.setText(mString);
         mLabelView.measure(View.MeasureSpec.AT_MOST | 320, View.MeasureSpec.AT_MOST | 240);
         mLabelView.mySetFrame(320, 240);
@@ -54,7 +59,7 @@
 
         mPaint = new Paint();
         mCanvas.save();
-        mTextView = new PerformanceTextView(mContext);
+        mTextView = new PerformanceTextView(context);
         mTextView.setLayoutParams(p);
         mTextView.setText(mString);
         mTextView.mySetFrame(320, 240);
@@ -62,7 +67,8 @@
     }
 
     @MediumTest
-    public void testDrawTextViewLine() throws Exception {
+    @Test
+    public void testDrawTextViewLine() {
         mTextView.myDraw(mCanvas);
         mTextView.myDraw(mCanvas);
         mTextView.myDraw(mCanvas);
@@ -76,7 +82,8 @@
     }
 
     @SmallTest
-    public void testSpan() throws Exception {
+    @Test
+    public void testSpan() {
         CharSequence charSeq = new SpannedString(mString);
         mTextView.setText(charSeq);
 
@@ -93,12 +100,14 @@
     }
 
     @SmallTest
-    public void testCanvasDrawText() throws Exception {
+    @Test
+    public void testCanvasDrawText() {
         mCanvas.drawText(mString, 30, 30, mPaint);
     }
 
     @SmallTest
-    public void testLabelViewDraw() throws Exception {
+    @Test
+    public void testLabelViewDraw() {
         mLabelView.myDraw(mCanvas);
     }
 
diff --git a/core/tests/coretests/src/android/widget/TextViewTest.java b/core/tests/coretests/src/android/widget/TextViewTest.java
index 8989462..1a1244f 100644
--- a/core/tests/coretests/src/android/widget/TextViewTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewTest.java
@@ -16,41 +16,57 @@
 
 package android.widget;
 
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertTrue;
+
 import android.app.Activity;
+import android.app.Instrumentation;
 import android.content.Intent;
 import android.graphics.Paint;
 import android.platform.test.annotations.Presubmit;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.annotation.UiThreadTest;
+import android.support.test.filters.MediumTest;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
 import android.text.GetChars;
 import android.text.Layout;
 import android.text.Selection;
 import android.text.Spannable;
-import android.util.Log;
 import android.view.View;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import java.util.Locale;
 
 /**
  * TextViewTest tests {@link TextView}.
  */
-public class TextViewTest extends ActivityInstrumentationTestCase2<TextViewActivity> {
-    private static final String TAG = "TextViewTest";
+@RunWith(AndroidJUnit4.class)
+@MediumTest
+public class TextViewTest {
+    @Rule
+    public ActivityTestRule<TextViewActivity> mActivityRule = new ActivityTestRule<>(
+            TextViewActivity.class);
+    private Instrumentation mInstrumentation;
+    private Activity mActivity;
     private TextView mTextView;
 
-    public TextViewTest() {
-        super(TextViewActivity.class);
+    @Before
+    public void setup() {
+        mActivity = mActivityRule.getActivity();
+        mInstrumentation = InstrumentationRegistry.getInstrumentation();
     }
 
-    @SmallTest
     @Presubmit
-    public void testArray() throws Exception {
-        getActivity().runOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                mTextView = new TextView(getActivity());
-            }
-        });
-        getInstrumentation().waitForIdleSync();
+    @UiThreadTest
+    @Test
+    public void testArray() {
+        mTextView = new TextView(mActivity);
 
         char[] c = new char[] { 'H', 'e', 'l', 'l', 'o', ' ',
                                 'W', 'o', 'r', 'l', 'd', '!' };
@@ -78,15 +94,10 @@
         assertEquals('\0', c2[5]);
     }
 
-    @SmallTest
-    public void testProcessTextActivityResultNonEditable() {
-        getActivity().runOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                mTextView = new TextView(getActivity());
-            }
-        });
-        getInstrumentation().waitForIdleSync();
+    @Test
+    public void testProcessTextActivityResultNonEditable() throws Throwable {
+        mActivityRule.runOnUiThread(() -> mTextView = new TextView(mActivity));
+        mInstrumentation.waitForIdleSync();
         CharSequence originalText = "This is some text.";
         mTextView.setText(originalText, TextView.BufferType.SPANNABLE);
         assertEquals(originalText, mTextView.getText().toString());
@@ -94,30 +105,23 @@
         Selection.setSelection((Spannable) mTextView.getText(), 0, mTextView.getText().length());
 
         // We need to run this in the UI thread, as it will create a Toast.
-        getActivity().runOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                CharSequence newText = "Text is replaced.";
-                Intent data = new Intent();
-                data.putExtra(Intent.EXTRA_PROCESS_TEXT, newText);
-                mTextView.onActivityResult(TextView.PROCESS_TEXT_REQUEST_CODE, Activity.RESULT_OK, data);
-            }
+        mActivityRule.runOnUiThread(() -> {
+            CharSequence newText = "Text is replaced.";
+            Intent data = new Intent();
+            data.putExtra(Intent.EXTRA_PROCESS_TEXT, newText);
+            mTextView.onActivityResult(TextView.PROCESS_TEXT_REQUEST_CODE, Activity.RESULT_OK,
+                    data);
         });
-        getInstrumentation().waitForIdleSync();
+        mInstrumentation.waitForIdleSync();
 
         // This is a TextView, which can't be modified. Hence no change should have been made.
         assertEquals(originalText, mTextView.getText().toString());
     }
 
-    @SmallTest
-    public void testProcessTextActivityResultEditable() {
-        getActivity().runOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                mTextView = new EditText(getActivity());
-            }
-        });
-        getInstrumentation().waitForIdleSync();
+    @Test
+    public void testProcessTextActivityResultEditable() throws Throwable {
+        mActivityRule.runOnUiThread(() -> mTextView = new EditText(mActivity));
+        mInstrumentation.waitForIdleSync();
         CharSequence originalText = "This is some text.";
         mTextView.setText(originalText, TextView.BufferType.SPANNABLE);
         assertEquals(originalText, mTextView.getText().toString());
@@ -132,15 +136,10 @@
         assertEquals(newText, mTextView.getText().toString());
     }
 
-    @SmallTest
-    public void testProcessTextActivityResultCancel() {
-        getActivity().runOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                mTextView = new EditText(getActivity());
-            }
-        });
-        getInstrumentation().waitForIdleSync();
+    @Test
+    public void testProcessTextActivityResultCancel() throws Throwable {
+        mActivityRule.runOnUiThread(() -> mTextView = new EditText(mActivity));
+        mInstrumentation.waitForIdleSync();
         CharSequence originalText = "This is some text.";
         mTextView.setText(originalText, TextView.BufferType.SPANNABLE);
         assertEquals(originalText, mTextView.getText().toString());
@@ -156,15 +155,10 @@
         assertEquals(originalText, mTextView.getText().toString());
     }
 
-    @SmallTest
-    public void testProcessTextActivityNoData() {
-        getActivity().runOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                mTextView = new EditText(getActivity());
-            }
-        });
-        getInstrumentation().waitForIdleSync();
+    @Test
+    public void testProcessTextActivityNoData() throws Throwable {
+        mActivityRule.runOnUiThread(() -> mTextView = new EditText(mActivity));
+        mInstrumentation.waitForIdleSync();
         CharSequence originalText = "This is some text.";
         mTextView.setText(originalText, TextView.BufferType.SPANNABLE);
         assertEquals(originalText, mTextView.getText().toString());
@@ -176,13 +170,14 @@
         assertEquals(originalText, mTextView.getText().toString());
     }
 
-    @SmallTest
+    @Test
+    @UiThreadTest
     public void testHyphenationWidth() {
-        TextView textView = new TextView(getActivity());
-        textView.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL);
-        textView.setTextLocale(Locale.US);
+        mTextView = new TextView(mActivity);
+        mTextView.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL);
+        mTextView.setTextLocale(Locale.US);
 
-        Paint paint = textView.getPaint();
+        Paint paint = mTextView.getPaint();
 
         String word = "thisissuperlonglongword";
         float wordWidth = paint.measureText(word, 0, word.length());
@@ -192,17 +187,17 @@
             sb.append(word);
             sb.append(" ");
         }
-        textView.setText(sb.toString());
+        mTextView.setText(sb.toString());
 
         int width = (int)(wordWidth * 0.7);
         int height = 4096;  // enough for all text.
 
-        textView.measure(
+        mTextView.measure(
                 View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY),
                 View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY));
-        textView.layout(0, 0, width, height);
+        mTextView.layout(0, 0, width, height);
 
-        Layout layout = textView.getLayout();
+        Layout layout = mTextView.getLayout();
         assertNotNull(layout);
 
         int lineCount = layout.getLineCount();
diff --git a/core/tests/utiltests/Android.mk b/core/tests/utiltests/Android.mk
index f2e02e3..233d070 100644
--- a/core/tests/utiltests/Android.mk
+++ b/core/tests/utiltests/Android.mk
@@ -18,7 +18,6 @@
     android-support-test \
     frameworks-base-testutils \
     mockito-target-minus-junit4 \
-    legacy-android-tests
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
diff --git a/core/tests/utiltests/src/android/util/RemoteIntArray.java b/core/tests/utiltests/src/android/util/RemoteIntArray.java
index 7dc3400..11d0888 100644
--- a/core/tests/utiltests/src/android/util/RemoteIntArray.java
+++ b/core/tests/utiltests/src/android/util/RemoteIntArray.java
@@ -32,7 +32,7 @@
 
 final class RemoteIntArray implements ServiceConnection, Closeable {
     private static final long BIND_REMOTE_SERVICE_TIMEOUT =
-            ("eng".equals(Build.TYPE)) ? 120000 : 10000;
+            Build.IS_ENG ? 120000 : 10000;
 
     private final Object mLock = new Object();
 
diff --git a/graphics/java/android/graphics/ColorFilter.java b/graphics/java/android/graphics/ColorFilter.java
index 0ca3729..b24b988 100644
--- a/graphics/java/android/graphics/ColorFilter.java
+++ b/graphics/java/android/graphics/ColorFilter.java
@@ -14,19 +14,22 @@
  * limitations under the License.
  */
 
-// This file was generated from the C++ include file: SkColorFilter.h
-// Any changes made to this file will be discarded by the build.
-// To change this file, either edit the include, or device/tools/gluemaker/main.cpp, 
-// or one of the auxilary file specifications in device/tools/gluemaker.
-
 package android.graphics;
 
+import libcore.util.NativeAllocationRegistry;
+
 /**
  * A color filter can be used with a {@link Paint} to modify the color of
  * each pixel drawn with that paint. This is an abstract class that should
  * never be used directly.
  */
 public class ColorFilter {
+
+    private static class NoImagePreloadHolder {
+        public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
+                ColorFilter.class.getClassLoader(), nativeGetFinalizer(), 50);
+    }
+
     /**
      * @deprecated Use subclass constructors directly instead.
      */
@@ -34,9 +37,11 @@
     public ColorFilter() {}
 
     /**
-     * Holds the pointer to the native SkColorFilter instance.
+     * Current native SkColorFilter instance.
      */
     private long mNativeInstance;
+    // Runnable to do immediate destruction
+    private Runnable mCleaner;
 
     long createNativeInstance() {
         return 0;
@@ -44,35 +49,28 @@
 
     void discardNativeInstance() {
         if (mNativeInstance != 0) {
-            nSafeUnref(mNativeInstance);
+            mCleaner.run();
+            mCleaner = null;
             mNativeInstance = 0;
         }
     }
 
-    @Override
-    protected void finalize() throws Throwable {
-        try {
-            if (mNativeInstance != 0) {
-                nSafeUnref(mNativeInstance);
-            }
-            mNativeInstance = -1;
-        } finally {
-            super.finalize();
-        }
-    }
-
     /** @hide */
     public long getNativeInstance() {
-        if (mNativeInstance == -1) {
-            throw new IllegalStateException("attempting to use a finalized ColorFilter");
-        }
-
         if (mNativeInstance == 0) {
             mNativeInstance = createNativeInstance();
+
+            if (mNativeInstance != 0) {
+                // Note: we must check for null here, since it's possible for createNativeInstance()
+                // to return nullptr if the native SkColorFilter would be a no-op at draw time.
+                // See native implementations of subclass create methods for more info.
+                mCleaner = NoImagePreloadHolder.sRegistry.registerNativeAllocation(
+                        this, mNativeInstance);
+            }
         }
         return mNativeInstance;
 
     }
 
-    static native void nSafeUnref(long native_instance);
+    private static native long nativeGetFinalizer();
 }
diff --git a/legacy-test/Android.mk b/legacy-test/Android.mk
index 8efda2a..e683999 100644
--- a/legacy-test/Android.mk
+++ b/legacy-test/Android.mk
@@ -48,19 +48,6 @@
 
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
-# Build the legacy-android-tests library
-# ======================================
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-    $(call all-java-files-under, tests)
-LOCAL_MODULE := legacy-android-tests
-LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_JAVA_LIBRARIES := core-oj core-libart framework junit
-LOCAL_STATIC_JAVA_LIBRARIES := legacy-android-test
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
 ifeq ($(HOST_OS),linux)
 # Build the legacy-performance-test-hostdex library
 # =================================================
diff --git a/test-runner/src/android/test/suitebuilder/annotation/package.html b/legacy-test/src/android/test/suitebuilder/annotation/package.html
similarity index 100%
rename from test-runner/src/android/test/suitebuilder/annotation/package.html
rename to legacy-test/src/android/test/suitebuilder/annotation/package.html
diff --git a/legacy-test/src/com/android/internal/util/Predicates.java b/legacy-test/src/com/android/internal/util/Predicates.java
deleted file mode 100644
index fe1ff15..0000000
--- a/legacy-test/src/com/android/internal/util/Predicates.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.util;
-
-import java.util.Arrays;
-
-/**
- * Predicates contains static methods for creating the standard set of
- * {@code Predicate} objects.
- *
- * @hide
- */
-public class Predicates {
-
-    private Predicates() {
-    }
-
-    /**
-     * Returns a Predicate that evaluates to true iff each of its components
-     * evaluates to true.  The components are evaluated in order, and evaluation
-     * will be "short-circuited" as soon as the answer is determined.
-     */
-    public static <T> Predicate<T> and(Predicate<? super T>... components) {
-        return Predicates.<T>and(Arrays.asList(components));
-    }
-
-    /**
-     * Returns a Predicate that evaluates to true iff each of its components
-     * evaluates to true.  The components are evaluated in order, and evaluation
-     * will be "short-circuited" as soon as the answer is determined.  Does not
-     * defensively copy the iterable passed in, so future changes to it will alter
-     * the behavior of this Predicate. If components is empty, the returned
-     * Predicate will always evaluate to true.
-     */
-    public static <T> Predicate<T> and(Iterable<? extends Predicate<? super T>> components) {
-        return new AndPredicate(components);
-    }
-
-    /**
-     * Returns a Predicate that evaluates to true iff any one of its components
-     * evaluates to true.  The components are evaluated in order, and evaluation
-     * will be "short-circuited" as soon as the answer is determined.
-     */
-    public static <T> Predicate<T> or(Predicate<? super T>... components) {
-        return Predicates.<T>or(Arrays.asList(components));
-    }
-
-    /**
-     * Returns a Predicate that evaluates to true iff any one of its components
-     * evaluates to true.  The components are evaluated in order, and evaluation
-     * will be "short-circuited" as soon as the answer is determined.  Does not
-     * defensively copy the iterable passed in, so future changes to it will alter
-     * the behavior of this Predicate. If components is empty, the returned
-     * Predicate will always evaluate to false.
-     */
-    public static <T> Predicate<T> or(Iterable<? extends Predicate<? super T>> components) {
-        return new OrPredicate(components);
-    }
-
-    /**
-     * Returns a Predicate that evaluates to true iff the given Predicate
-     * evaluates to false.
-     */
-    public static <T> Predicate<T> not(Predicate<? super T> predicate) {
-        return new NotPredicate<T>(predicate);
-    }
-
-    private static class AndPredicate<T> implements Predicate<T> {
-        private final Iterable<? extends Predicate<? super T>> components;
-
-        private AndPredicate(Iterable<? extends Predicate<? super T>> components) {
-            this.components = components;
-        }
-
-        public boolean apply(T t) {
-            for (Predicate<? super T> predicate : components) {
-                if (!predicate.apply(t)) {
-                    return false;
-                }
-            }
-            return true;
-        }
-    }
-
-    private static class OrPredicate<T> implements Predicate<T> {
-        private final Iterable<? extends Predicate<? super T>> components;
-
-        private OrPredicate(Iterable<? extends Predicate<? super T>> components) {
-            this.components = components;
-        }
-
-        public boolean apply(T t) {
-            for (Predicate<? super T> predicate : components) {
-                if (predicate.apply(t)) {
-                    return true;
-                }
-            }
-            return false;
-        }
-    }
-
-    private static class NotPredicate<T> implements Predicate<T> {
-        private final Predicate<? super T> predicate;
-
-        private NotPredicate(Predicate<? super T> predicate) {
-            this.predicate = predicate;
-        }
-
-        public boolean apply(T t) {
-            return !predicate.apply(t);
-        }
-    }
-}
diff --git a/legacy-test/tests/com/android/internal/util/PredicatesTest.java b/legacy-test/tests/com/android/internal/util/PredicatesTest.java
deleted file mode 100644
index c46ff05..0000000
--- a/legacy-test/tests/com/android/internal/util/PredicatesTest.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.util;
-
-import junit.framework.TestCase;
-
-import java.util.ArrayList;
-import java.util.Collections;
-
-public class PredicatesTest extends TestCase {
-
-    private static final Predicate<Object> TRUE = new Predicate<Object>() {
-        public boolean apply(Object o) {
-            return true;
-        }
-    };
-
-    private static final Predicate<Object> FALSE = new Predicate<Object>() {
-        public boolean apply(Object o) {
-            return false;
-        }
-    };
-
-    public void testAndPredicate_AllConditionsTrue() throws Exception {
-        assertTrue(Predicates.and(newArrayList(TRUE)).apply(null));
-        assertTrue(Predicates.and(newArrayList(TRUE, TRUE)).apply(null));
-    }
-
-    public void testAndPredicate_AtLeastOneConditionIsFalse() throws Exception {
-        assertFalse(Predicates.and(newArrayList(FALSE, TRUE, TRUE)).apply(null));
-        assertFalse(Predicates.and(newArrayList(TRUE, FALSE, TRUE)).apply(null));
-        assertFalse(Predicates.and(newArrayList(TRUE, TRUE, FALSE)).apply(null));
-    }
-
-    public void testOrPredicate_AllConditionsTrue() throws Exception {
-        assertTrue(Predicates.or(newArrayList(TRUE, TRUE, TRUE)).apply(null));
-    }
-
-    public void testOrPredicate_AllConditionsFalse() throws Exception {
-        assertFalse(Predicates.or(newArrayList(FALSE, FALSE, FALSE)).apply(null));
-    }
-
-    public void testOrPredicate_AtLeastOneConditionIsTrue() throws Exception {
-        assertTrue(Predicates.or(newArrayList(TRUE, FALSE, FALSE)).apply(null));
-        assertTrue(Predicates.or(newArrayList(FALSE, TRUE, FALSE)).apply(null));
-        assertTrue(Predicates.or(newArrayList(FALSE, FALSE, TRUE)).apply(null));
-    }
-
-    public void testNotPredicate() throws Exception {
-        assertTrue(Predicates.not(FALSE).apply(null));
-        assertFalse(Predicates.not(TRUE).apply(null));
-    }
-
-    private static <E> ArrayList<E> newArrayList(E... elements) {
-        ArrayList<E> list = new ArrayList<E>();
-        Collections.addAll(list, elements);
-        return list;
-    }
-
-}
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index bab8883..0782269 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -3313,13 +3313,14 @@
         clearBagCache();
         const size_t numTypes = types.size();
         for (size_t i = 0; i < numTypes; i++) {
-            const TypeList& typeList = types[i];
+            TypeList& typeList = types.editItemAt(i);
             const size_t numInnerTypes = typeList.size();
             for (size_t j = 0; j < numInnerTypes; j++) {
                 if (typeList[j]->package->owner == owner) {
                     delete typeList[j];
                 }
             }
+            typeList.clear();
         }
 
         const size_t N = packages.size();
diff --git a/libs/hwui/tests/unit/SkiaBehaviorTests.cpp b/libs/hwui/tests/unit/SkiaBehaviorTests.cpp
index a3d5079..85b12ba 100644
--- a/libs/hwui/tests/unit/SkiaBehaviorTests.cpp
+++ b/libs/hwui/tests/unit/SkiaBehaviorTests.cpp
@@ -51,8 +51,6 @@
     SkShader::TileMode xy[2];
     ASSERT_TRUE(s->isABitmap(&bitmap, nullptr, xy))
         << "1x1 bitmap shader must query as bitmap shader";
-    EXPECT_EQ(SkShader::kClamp_TileMode, xy[0]);
-    EXPECT_EQ(SkShader::kRepeat_TileMode, xy[1]);
     EXPECT_EQ(origBitmap.pixelRef(), bitmap.pixelRef());
 }
 
diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java
index c1e81c5..f403988 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -218,6 +218,7 @@
         SUPPRESSIBLE_USAGES.put(USAGE_NOTIFICATION_COMMUNICATION_DELAYED,SUPPRESSIBLE_NOTIFICATION);
         SUPPRESSIBLE_USAGES.put(USAGE_NOTIFICATION_EVENT,                SUPPRESSIBLE_NOTIFICATION);
         SUPPRESSIBLE_USAGES.put(USAGE_ASSISTANCE_ACCESSIBILITY,          SUPPRESSIBLE_NEVER);
+        SUPPRESSIBLE_USAGES.put(USAGE_VOICE_COMMUNICATION,               SUPPRESSIBLE_NEVER);
     }
 
     /**
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index 81cc93d..93fc3da 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -267,6 +267,42 @@
      **/
     public static final int ENCODING_DOLBY_TRUEHD = 14;
 
+    /** @hide */
+    public static String toLogFriendlyEncoding(int enc) {
+        switch(enc) {
+            case ENCODING_INVALID:
+                return "ENCODING_INVALID";
+            case ENCODING_PCM_16BIT:
+                return "ENCODING_PCM_16BIT";
+            case ENCODING_PCM_8BIT:
+                return "ENCODING_PCM_8BIT";
+            case ENCODING_PCM_FLOAT:
+                return "ENCODING_PCM_FLOAT";
+            case ENCODING_AC3:
+                return "ENCODING_AC3";
+            case ENCODING_E_AC3:
+                return "ENCODING_E_AC3";
+            case ENCODING_DTS:
+                return "ENCODING_DTS";
+            case ENCODING_DTS_HD:
+                return "ENCODING_DTS_HD";
+            case ENCODING_MP3:
+                return "ENCODING_MP3";
+            case ENCODING_AAC_LC:
+                return "ENCODING_AAC_LC";
+            case ENCODING_AAC_HE_V1:
+                return "ENCODING_AAC_HE_V1";
+            case ENCODING_AAC_HE_V2:
+                return "ENCODING_AAC_HE_V2";
+            case ENCODING_IEC61937:
+                return "ENCODING_IEC61937";
+            case ENCODING_DOLBY_TRUEHD:
+                return "ENCODING_DOLBY_TRUEHD";
+            default :
+                return "invalid encoding " + enc;
+        }
+    }
+
     /** Invalid audio channel configuration */
     /** @deprecated Use {@link #CHANNEL_INVALID} instead.  */
     @Deprecated    public static final int CHANNEL_CONFIGURATION_INVALID   = 0;
@@ -693,6 +729,12 @@
         return mPropertySetMask;
     }
 
+    /** @hide */
+    public String toLogFriendlyString() {
+        return String.format("%dch %dHz %s",
+                getChannelCount(), mSampleRate, toLogFriendlyEncoding(mEncoding));
+    }
+
     /**
      * Builder class for {@link AudioFormat} objects.
      * Use this class to configure and create an AudioFormat instance. By setting format
diff --git a/media/java/android/media/AudioManagerInternal.java b/media/java/android/media/AudioManagerInternal.java
index 0a1de33..2b5ac5e 100644
--- a/media/java/android/media/AudioManagerInternal.java
+++ b/media/java/android/media/AudioManagerInternal.java
@@ -59,4 +59,15 @@
 
         int getRingerModeAffectedStreams(int streams);
     }
+
+    /**
+     * Disable or restore the ability to play audio for a given UID.
+     * When a UID isn't meant to be tracked anymore (e.g. client died), re-enable audio for this UID
+     * to prevent disabling audio for future UIDs that would reuse the same value.
+     * This operation is asynchronous.
+     * @param disable when true, prevents playback of audio streams from the given uid. If false,
+     *         restores the ability to play, or no-op if playback hadn't been disabled before.
+     * @param uid the client UID whose ability to play will be affected.
+     */
+    public abstract void disableAudioForUid(boolean disable, int uid);
 }
diff --git a/media/java/android/media/AudioRecordingConfiguration.java b/media/java/android/media/AudioRecordingConfiguration.java
index 50dbd03..984c554 100644
--- a/media/java/android/media/AudioRecordingConfiguration.java
+++ b/media/java/android/media/AudioRecordingConfiguration.java
@@ -17,10 +17,12 @@
 package android.media;
 
 import android.annotation.IntDef;
+import android.annotation.NonNull;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.Log;
 
+import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
@@ -52,18 +54,59 @@
     private final AudioFormat mDeviceFormat;
     private final AudioFormat mClientFormat;
 
+    @NonNull private final String mClientPackageName;
+    private final int mClientUid;
+
     private final int mPatchHandle;
 
     /**
      * @hide
      */
-    public AudioRecordingConfiguration(int session, int source, AudioFormat clientFormat,
-            AudioFormat devFormat, int patchHandle) {
+    public AudioRecordingConfiguration(int uid, int session, int source, AudioFormat clientFormat,
+            AudioFormat devFormat, int patchHandle, String packageName) {
+        mClientUid = uid;
         mSessionId = session;
         mClientSource = source;
         mClientFormat = clientFormat;
         mDeviceFormat = devFormat;
         mPatchHandle = patchHandle;
+        mClientPackageName = packageName;
+    }
+
+    /**
+     * @hide
+     * For AudioService dump
+     * @param pw
+     */
+    public void dump(PrintWriter pw) {
+        pw.println("  " + toLogFriendlyString(this));
+    }
+
+    /**
+     * @hide
+     */
+    public static String toLogFriendlyString(AudioRecordingConfiguration arc) {
+        return new String("session:" + arc.mSessionId
+                + " -- source:" + MediaRecorder.toLogFriendlyAudioSource(arc.mClientSource)
+                + " -- uid:" + arc.mClientUid
+                + " -- patch:" + arc.mPatchHandle
+                + " -- pack:" + arc.mClientPackageName
+                + " -- format client=" + arc.mClientFormat.toLogFriendlyString()
+                    + ", dev=" + arc.mDeviceFormat.toLogFriendlyString());
+    }
+
+    // Note that this method is called server side, so no "privileged" information is ever sent
+    // to a client that is not supposed to have access to it.
+    /**
+     * @hide
+     * Creates a copy of the recording configuration that is stripped of any data enabling
+     * identification of which application it is associated with ("anonymized").
+     * @param in
+     */
+    public static AudioRecordingConfiguration anonymizedCopy(AudioRecordingConfiguration in) {
+        return new AudioRecordingConfiguration( /*anonymized uid*/ -1,
+                in.mSessionId, in.mClientSource, in.mClientFormat,
+                in.mDeviceFormat, in.mPatchHandle, "" /*empty package name*/);
     }
 
     // matches the sources that return false in MediaRecorder.isSystemOnlyAudioSource(source)
@@ -120,6 +163,30 @@
     public AudioFormat getClientFormat() { return mClientFormat; }
 
     /**
+     * @pending for SystemApi
+     * Returns the package name of the application performing the recording.
+     * Where there are multiple packages sharing the same user id through the "sharedUserId"
+     * mechanism, only the first one with that id will be returned
+     * (see {@link PackageManager#getPackagesForUid(int)}).
+     * <p>This information is only available if the caller has the
+     * {@link android.Manifest.permission.MODIFY_AUDIO_ROUTING} permission.
+     * <br>When called without the permission, the result is an empty string.
+     * @return the package name
+     */
+    public String getClientPackageName() { return mClientPackageName; }
+
+    /**
+     * @pending for SystemApi
+     * Returns the user id of the application performing the recording.
+     * <p>This information is only available if the caller has the
+     * {@link android.Manifest.permission.MODIFY_AUDIO_ROUTING}
+     * permission.
+     * <br>The result is -1 without the permission.
+     * @return the user id
+     */
+    public int getClientUid() { return mClientUid; }
+
+    /**
      * Returns information about the audio input device used for this recording.
      * @return the audio recording device or null if this information cannot be retrieved
      */
@@ -185,6 +252,8 @@
         mClientFormat.writeToParcel(dest, 0);
         mDeviceFormat.writeToParcel(dest, 0);
         dest.writeInt(mPatchHandle);
+        dest.writeString(mClientPackageName);
+        dest.writeInt(mClientUid);
     }
 
     private AudioRecordingConfiguration(Parcel in) {
@@ -193,6 +262,8 @@
         mClientFormat = AudioFormat.CREATOR.createFromParcel(in);
         mDeviceFormat = AudioFormat.CREATOR.createFromParcel(in);
         mPatchHandle = in.readInt();
+        mClientPackageName = in.readString();
+        mClientUid = in.readInt();
     }
 
     @Override
@@ -202,10 +273,12 @@
 
         AudioRecordingConfiguration that = (AudioRecordingConfiguration) o;
 
-        return ((mSessionId == that.mSessionId)
+        return ((mClientUid == that.mClientUid)
+                && (mSessionId == that.mSessionId)
                 && (mClientSource == that.mClientSource)
                 && (mPatchHandle == that.mPatchHandle)
                 && (mClientFormat.equals(that.mClientFormat))
-                && (mDeviceFormat.equals(that.mDeviceFormat)));
+                && (mDeviceFormat.equals(that.mDeviceFormat))
+                && (mClientPackageName.equals(that.mClientPackageName)));
     }
 }
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 6ef3091..1dcd214 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -287,6 +287,7 @@
         /**
          * Callback for recording activity notifications events
          * @param event
+         * @param uid uid of the client app performing the recording
          * @param session
          * @param source
          * @param recordingFormat an array of ints containing respectively the client and device
@@ -298,9 +299,10 @@
          *          4: device channel mask
          *          5: device sample rate
          *          6: patch handle
+         * @param packName package name of the client app performing the recording. NOT SUPPORTED
          */
-        void onRecordingConfigurationChanged(int event, int session, int source,
-                int[] recordingFormat);
+        void onRecordingConfigurationChanged(int event, int uid, int session, int source,
+                int[] recordingFormat, String packName);
     }
 
     private static AudioRecordingCallback sRecordingCallback;
@@ -318,17 +320,18 @@
      * @param session
      * @param source
      * @param recordingFormat see
-     *     {@link AudioRecordingCallback#onRecordingConfigurationChanged(int, int, int, int[])} for
-     *     the description of the record format.
+     *     {@link AudioRecordingCallback#onRecordingConfigurationChanged(int, int, int, int, int[])}
+     *     for the description of the record format.
      */
-    private static void recordingCallbackFromNative(int event, int session, int source,
+    private static void recordingCallbackFromNative(int event, int uid, int session, int source,
             int[] recordingFormat) {
         AudioRecordingCallback cb = null;
         synchronized (AudioSystem.class) {
             cb = sRecordingCallback;
         }
         if (cb != null) {
-            cb.onRecordingConfigurationChanged(event, session, source, recordingFormat);
+            // TODO receive package name from native
+            cb.onRecordingConfigurationChanged(event, uid, session, source, recordingFormat, "");
         }
     }
 
@@ -424,7 +427,8 @@
                                                   DEVICE_OUT_BLUETOOTH_SCO_HEADSET |
                                                   DEVICE_OUT_BLUETOOTH_SCO_CARKIT);
     public static final int DEVICE_OUT_ALL_USB = (DEVICE_OUT_USB_ACCESSORY |
-                                                  DEVICE_OUT_USB_DEVICE);
+                                                  DEVICE_OUT_USB_DEVICE |
+                                                  DEVICE_OUT_USB_HEADSET);
     public static final int DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO = (DEVICE_OUT_AUX_LINE |
                                                                 DEVICE_OUT_HDMI_ARC |
                                                                 DEVICE_OUT_SPDIF);
@@ -486,7 +490,8 @@
                                              DEVICE_IN_DEFAULT);
     public static final int DEVICE_IN_ALL_SCO = DEVICE_IN_BLUETOOTH_SCO_HEADSET;
     public static final int DEVICE_IN_ALL_USB = (DEVICE_IN_USB_ACCESSORY |
-                                                 DEVICE_IN_USB_DEVICE);
+                                                 DEVICE_IN_USB_DEVICE |
+                                                 DEVICE_IN_USB_HEADSET);
 
     // device states, must match AudioSystem::device_connection_state
     public static final int DEVICE_STATE_UNAVAILABLE = 0;
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index bf5939f..50145f8 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -276,6 +276,9 @@
     private static final int AUDIO_OUTPUT_FLAG_FAST = 0x4;
     private static final int AUDIO_OUTPUT_FLAG_DEEP_BUFFER = 0x8;
 
+    // Size of HW_AV_SYNC track AV header.
+    private static final float HEADER_V2_SIZE_BYTES = 20.0f;
+
     //--------------------------------------------------------------------------
     // Member variables
     //--------------------
@@ -364,6 +367,10 @@
      * HW_AV_SYNC track audio data bytes remaining to write after current AV sync header
      */
     private int mAvSyncBytesRemaining = 0;
+    /**
+     * Offset of the first sample of the audio in byte from start of HW_AV_SYNC track AV header.
+     */
+    private int mOffset = 0;
 
     //--------------------------------
     // Used exclusively by native code
@@ -603,6 +610,16 @@
         mSampleRate = sampleRate[0];
         mSessionId = session[0];
 
+        if ((mAttributes.getFlags() & AudioAttributes.FLAG_HW_AV_SYNC) != 0) {
+            int frameSizeInBytes;
+            if (AudioFormat.isEncodingLinearFrames(mAudioFormat)) {
+                frameSizeInBytes = mChannelCount * AudioFormat.getBytesPerSample(mAudioFormat);
+            } else {
+                frameSizeInBytes = 1;
+            }
+            mOffset = ((int) Math.ceil(HEADER_V2_SIZE_BYTES / frameSizeInBytes)) * frameSizeInBytes;
+        }
+
         if (mDataLoadMode == MODE_STATIC) {
             mState = STATE_NO_STATIC_DATA;
         } else {
@@ -2520,14 +2537,15 @@
 
         // create timestamp header if none exists
         if (mAvSyncHeader == null) {
-            mAvSyncHeader = ByteBuffer.allocate(16);
+            mAvSyncHeader = ByteBuffer.allocate(mOffset);
             mAvSyncHeader.order(ByteOrder.BIG_ENDIAN);
-            mAvSyncHeader.putInt(0x55550001);
+            mAvSyncHeader.putInt(0x55550002);
         }
 
         if (mAvSyncBytesRemaining == 0) {
             mAvSyncHeader.putInt(4, sizeInBytes);
             mAvSyncHeader.putLong(8, timestamp);
+            mAvSyncHeader.putInt(16, mOffset);
             mAvSyncHeader.position(0);
             mAvSyncBytesRemaining = sizeInBytes;
         }
diff --git a/media/java/android/media/IMediaRouterClient.aidl b/media/java/android/media/IMediaRouterClient.aidl
index 9640dcb..08344f1 100644
--- a/media/java/android/media/IMediaRouterClient.aidl
+++ b/media/java/android/media/IMediaRouterClient.aidl
@@ -21,4 +21,5 @@
  */
 oneway interface IMediaRouterClient {
     void onStateChanged();
+    void onRestoreRoute();
 }
diff --git a/media/java/android/media/IMediaRouterService.aidl b/media/java/android/media/IMediaRouterService.aidl
index f8f5fdf..3308fc9 100644
--- a/media/java/android/media/IMediaRouterService.aidl
+++ b/media/java/android/media/IMediaRouterService.aidl
@@ -27,6 +27,7 @@
     void unregisterClient(IMediaRouterClient client);
 
     MediaRouterClientState getState(IMediaRouterClient client);
+    boolean isPlaybackActive(IMediaRouterClient client);
 
     void setDiscoveryRequest(IMediaRouterClient client, int routeTypes, boolean activeScan);
     void setSelectedRoute(IMediaRouterClient client, String routeId, boolean explicit);
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 33a7c83..59a124f 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -324,6 +324,40 @@
         }
     }
 
+    /** @hide */
+    public static final String toLogFriendlyAudioSource(int source) {
+        switch(source) {
+        case AudioSource.DEFAULT:
+            return "DEFAULT";
+        case AudioSource.MIC:
+            return "MIC";
+        case AudioSource.VOICE_UPLINK:
+            return "VOICE_UPLINK";
+        case AudioSource.VOICE_DOWNLINK:
+            return "VOICE_DOWNLINK";
+        case AudioSource.VOICE_CALL:
+            return "VOICE_CALL";
+        case AudioSource.CAMCORDER:
+            return "CAMCORDER";
+        case AudioSource.VOICE_RECOGNITION:
+            return "VOICE_RECOGNITION";
+        case AudioSource.VOICE_COMMUNICATION:
+            return "VOICE_COMMUNICATION";
+        case AudioSource.REMOTE_SUBMIX:
+            return "REMOTE_SUBMIX";
+        case AudioSource.UNPROCESSED:
+            return "UNPROCESSED";
+        case AudioSource.RADIO_TUNER:
+            return "RADIO_TUNER";
+        case AudioSource.HOTWORD:
+            return "HOTWORD";
+        case AudioSource.AUDIO_SOURCE_INVALID:
+            return "AUDIO_SOURCE_INVALID";
+        default:
+            return "unknown source " + source;
+        }
+    }
+
     /**
      * Defines the video source. These constants are used with
      * {@link MediaRecorder#setVideoSource(int)}.
diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java
index d5509c1..cff7043 100644
--- a/media/java/android/media/MediaRouter.java
+++ b/media/java/android/media/MediaRouter.java
@@ -88,6 +88,7 @@
         RouteInfo mBluetoothA2dpRoute;
 
         RouteInfo mSelectedRoute;
+        RouteInfo mSystemAudioRoute;
 
         final boolean mCanConfigureWifiDisplays;
         boolean mActivelyScanningWifiDisplays;
@@ -149,6 +150,7 @@
             }
 
             addRouteStatic(mDefaultAudioVideo);
+            mSystemAudioRoute = mDefaultAudioVideo;
 
             // This will select the active wifi display route if there is one.
             updateWifiDisplayStatus(mDisplayService.getWifiDisplayStatus());
@@ -197,8 +199,8 @@
                 } else {
                     name = com.android.internal.R.string.default_audio_route_name;
                 }
-                sStatic.mDefaultAudioVideo.mNameResId = name;
-                dispatchRouteChanged(sStatic.mDefaultAudioVideo);
+                mDefaultAudioVideo.mNameResId = name;
+                dispatchRouteChanged(mDefaultAudioVideo);
                 updated = true;
             }
 
@@ -207,22 +209,28 @@
             if (!TextUtils.equals(newRoutes.bluetoothName, mCurAudioRoutesInfo.bluetoothName)) {
                 mCurAudioRoutesInfo.bluetoothName = newRoutes.bluetoothName;
                 if (mCurAudioRoutesInfo.bluetoothName != null) {
-                    if (sStatic.mBluetoothA2dpRoute == null) {
-                        final RouteInfo info = new RouteInfo(sStatic.mSystemCategory);
+                    if (mBluetoothA2dpRoute == null) {
+                        // BT connected
+                        final RouteInfo info = new RouteInfo(mSystemCategory);
                         info.mName = mCurAudioRoutesInfo.bluetoothName;
-                        info.mDescription = sStatic.mResources.getText(
+                        info.mDescription = mResources.getText(
                                 com.android.internal.R.string.bluetooth_a2dp_audio_route_name);
                         info.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO;
                         info.mDeviceType = RouteInfo.DEVICE_TYPE_BLUETOOTH;
-                        sStatic.mBluetoothA2dpRoute = info;
-                        addRouteStatic(sStatic.mBluetoothA2dpRoute);
+                        mBluetoothA2dpRoute = info;
+                        addRouteStatic(mBluetoothA2dpRoute);
+                        mSystemAudioRoute = mBluetoothA2dpRoute;
+                        selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mSystemAudioRoute, false);
                     } else {
-                        sStatic.mBluetoothA2dpRoute.mName = mCurAudioRoutesInfo.bluetoothName;
-                        dispatchRouteChanged(sStatic.mBluetoothA2dpRoute);
+                        mBluetoothA2dpRoute.mName = mCurAudioRoutesInfo.bluetoothName;
+                        dispatchRouteChanged(mBluetoothA2dpRoute);
                     }
-                } else if (sStatic.mBluetoothA2dpRoute != null) {
-                    removeRouteStatic(sStatic.mBluetoothA2dpRoute);
-                    sStatic.mBluetoothA2dpRoute = null;
+                } else if (mBluetoothA2dpRoute != null) {
+                    // BT disconnected
+                    removeRouteStatic(mBluetoothA2dpRoute);
+                    mBluetoothA2dpRoute = null;
+                    mSystemAudioRoute = mDefaultAudioVideo;
+                    selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mSystemAudioRoute, false);
                 }
                 updated = true;
             }
@@ -230,11 +238,13 @@
             if (mBluetoothA2dpRoute != null) {
                 final boolean a2dpEnabled = isBluetoothA2dpOn();
                 if (mSelectedRoute == mBluetoothA2dpRoute && !a2dpEnabled) {
-                    selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mDefaultAudioVideo, false);
+                    // A2DP off
+                    mSystemAudioRoute = mDefaultAudioVideo;
                     updated = true;
                 } else if ((mSelectedRoute == mDefaultAudioVideo || mSelectedRoute == null) &&
                         a2dpEnabled) {
-                    selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mBluetoothA2dpRoute, false);
+                    // A2DP on or BT connected
+                    mSystemAudioRoute = mBluetoothA2dpRoute;
                     updated = true;
                 }
             }
@@ -471,7 +481,7 @@
         }
 
         RouteInfo makeGlobalRoute(MediaRouterClientState.RouteInfo globalRoute) {
-            RouteInfo route = new RouteInfo(sStatic.mSystemCategory);
+            RouteInfo route = new RouteInfo(mSystemCategory);
             route.mGlobalRouteId = globalRoute.id;
             route.mName = globalRoute.name;
             route.mDescription = globalRoute.description;
@@ -567,6 +577,17 @@
             return null;
         }
 
+        boolean isPlaybackActive() {
+            if (mClient != null) {
+                try {
+                    return mMediaRouterService.isPlaybackActive(mClient);
+                } catch (RemoteException ex) {
+                    Log.e(TAG, "Unable to retrieve playback active state.", ex);
+                }
+            }
+            return false;
+        }
+
         final class Client extends IMediaRouterClient.Stub {
             @Override
             public void onStateChanged() {
@@ -579,6 +600,19 @@
                     }
                 });
             }
+
+            @Override
+            public void onRestoreRoute() {
+                if ((mSelectedRoute != mDefaultAudioVideo && mSelectedRoute != mBluetoothA2dpRoute)
+                        || mSelectedRoute == mSystemAudioRoute) {
+                    return;
+                }
+                try {
+                    sStatic.mAudioService.setBluetoothA2dpOn(mSelectedRoute == mBluetoothA2dpRoute);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Error changing Bluetooth A2DP state", e);
+                }
+            }
         }
     }
 
@@ -900,7 +934,12 @@
         Log.v(TAG, "Selecting route: " + route);
         assert(route != null);
         final RouteInfo oldRoute = sStatic.mSelectedRoute;
-        if (oldRoute == route) return;
+        boolean wasDefaultOrBluetoothRoute = (oldRoute == sStatic.mDefaultAudioVideo
+                || oldRoute == sStatic.mBluetoothA2dpRoute);
+        if (oldRoute == route
+                && (!wasDefaultOrBluetoothRoute || oldRoute == sStatic.mSystemAudioRoute)) {
+            return;
+        }
         if (!route.matchesTypes(types)) {
             Log.w(TAG, "selectRoute ignored; cannot select route with supported types " +
                     typesToString(route.getSupportedTypes()) + " into route types " +
@@ -909,8 +948,8 @@
         }
 
         final RouteInfo btRoute = sStatic.mBluetoothA2dpRoute;
-        if (btRoute != null && (types & ROUTE_TYPE_LIVE_AUDIO) != 0 &&
-                (route == btRoute || route == sStatic.mDefaultAudioVideo)) {
+        if (sStatic.isPlaybackActive() && btRoute != null && (types & ROUTE_TYPE_LIVE_AUDIO) != 0
+                && (route == btRoute || route == sStatic.mDefaultAudioVideo)) {
             try {
                 sStatic.mAudioService.setBluetoothA2dpOn(route == btRoute);
             } catch (RemoteException e) {
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index dfd2bb3..44bd252 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -43,6 +43,7 @@
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.KeyEvent;
+import android.view.ViewConfiguration;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -200,8 +201,7 @@
                 return;
             }
             if (mCallback != null) {
-                // We're updating the callback, clear the session from the old
-                // one.
+                // We're updating the callback, clear the session from the old one.
                 mCallback.mCallback.mSession = null;
             }
             if (handler == null) {
@@ -735,6 +735,8 @@
      */
     public abstract static class Callback {
         private MediaSession mSession;
+        private CallbackMessageHandler mHandler;
+        private boolean mMediaPlayPauseKeyPending;
 
         public Callback() {
         }
@@ -766,13 +768,41 @@
          * @return True if the event was handled, false otherwise.
          */
         public boolean onMediaButtonEvent(@NonNull Intent mediaButtonIntent) {
-            if (mSession != null
+            if (mSession != null && mHandler != null
                     && Intent.ACTION_MEDIA_BUTTON.equals(mediaButtonIntent.getAction())) {
                 KeyEvent ke = mediaButtonIntent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
                 if (ke != null && ke.getAction() == KeyEvent.ACTION_DOWN) {
                     PlaybackState state = mSession.mPlaybackState;
                     long validActions = state == null ? 0 : state.getActions();
                     switch (ke.getKeyCode()) {
+                        case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
+                        case KeyEvent.KEYCODE_HEADSETHOOK:
+                            if (ke.getRepeatCount() > 0) {
+                                // Consider long-press as a single tap.
+                                handleMediaPlayPauseKeySingleTapIfPending();
+                            } else if (mMediaPlayPauseKeyPending) {
+                                // Consider double tap as the next.
+                                mHandler.removeMessages(CallbackMessageHandler
+                                        .MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT);
+                                mMediaPlayPauseKeyPending = false;
+                                if ((validActions & PlaybackState.ACTION_SKIP_TO_NEXT) != 0) {
+                                    onSkipToNext();
+                                }
+                            } else {
+                                mMediaPlayPauseKeyPending = true;
+                                mHandler.sendEmptyMessageDelayed(CallbackMessageHandler
+                                        .MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT,
+                                        ViewConfiguration.getDoubleTapTimeout());
+                            }
+                            return true;
+                        default:
+                            // If another key is pressed within double tap timeout, consider the
+                            // pending play/pause as a single tap to handle media keys in order.
+                            handleMediaPlayPauseKeySingleTapIfPending();
+                            break;
+                    }
+
+                    switch (ke.getKeyCode()) {
                         case KeyEvent.KEYCODE_MEDIA_PLAY:
                             if ((validActions & PlaybackState.ACTION_PLAY) != 0) {
                                 onPlay();
@@ -815,28 +845,33 @@
                                 return true;
                             }
                             break;
-                        case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
-                        case KeyEvent.KEYCODE_HEADSETHOOK:
-                            boolean isPlaying = state == null ? false
-                                    : state.getState() == PlaybackState.STATE_PLAYING;
-                            boolean canPlay = (validActions & (PlaybackState.ACTION_PLAY_PAUSE
-                                    | PlaybackState.ACTION_PLAY)) != 0;
-                            boolean canPause = (validActions & (PlaybackState.ACTION_PLAY_PAUSE
-                                    | PlaybackState.ACTION_PAUSE)) != 0;
-                            if (isPlaying && canPause) {
-                                onPause();
-                                return true;
-                            } else if (!isPlaying && canPlay) {
-                                onPlay();
-                                return true;
-                            }
-                            break;
                     }
                 }
             }
             return false;
         }
 
+        private void handleMediaPlayPauseKeySingleTapIfPending() {
+            if (!mMediaPlayPauseKeyPending) {
+                return;
+            }
+            mMediaPlayPauseKeyPending = false;
+            mHandler.removeMessages(CallbackMessageHandler.MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT);
+            PlaybackState state = mSession.mPlaybackState;
+            long validActions = state == null ? 0 : state.getActions();
+            boolean isPlaying = state != null
+                    && state.getState() == PlaybackState.STATE_PLAYING;
+            boolean canPlay = (validActions & (PlaybackState.ACTION_PLAY_PAUSE
+                        | PlaybackState.ACTION_PLAY)) != 0;
+            boolean canPause = (validActions & (PlaybackState.ACTION_PLAY_PAUSE
+                        | PlaybackState.ACTION_PAUSE)) != 0;
+            if (isPlaying && canPause) {
+                onPause();
+            } else if (!isPlaying && canPlay) {
+                onPlay();
+            }
+        }
+
         /**
          * Override to handle requests to prepare playback. During the preparation, a session should
          * not hold audio focus in order to allow other sessions play seamlessly. The state of
@@ -1294,12 +1329,14 @@
         private static final int MSG_CUSTOM_ACTION = 20;
         private static final int MSG_ADJUST_VOLUME = 21;
         private static final int MSG_SET_VOLUME = 22;
+        private static final int MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT = 23;
 
         private MediaSession.Callback mCallback;
 
         public CallbackMessageHandler(Looper looper, MediaSession.Callback callback) {
             super(looper, null, true);
             mCallback = callback;
+            mCallback.mHandler = this;
         }
 
         public void post(int what, Object obj, Bundle bundle) {
@@ -1401,6 +1438,9 @@
                         vp.onSetVolumeTo((int) msg.obj);
                     }
                     break;
+                case MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT:
+                    mCallback.handleMediaPlayPauseKeySingleTapIfPending();
+                    break;
             }
         }
     }
diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java
index e02a4dc..b215825 100644
--- a/media/java/android/media/session/MediaSessionManager.java
+++ b/media/java/android/media/session/MediaSessionManager.java
@@ -546,18 +546,23 @@
         private final IActiveSessionsListener.Stub mStub = new IActiveSessionsListener.Stub() {
             @Override
             public void onActiveSessionsChanged(final List<MediaSession.Token> tokens) {
-                if (mHandler != null) {
-                    mHandler.post(new Runnable() {
+                final Handler handler = mHandler;
+                if (handler != null) {
+                    handler.post(new Runnable() {
                         @Override
                         public void run() {
-                            if (mListener != null) {
+                            final Context context = mContext;
+                            if (context != null) {
                                 ArrayList<MediaController> controllers
                                         = new ArrayList<MediaController>();
                                 int size = tokens.size();
                                 for (int i = 0; i < size; i++) {
-                                    controllers.add(new MediaController(mContext, tokens.get(i)));
+                                    controllers.add(new MediaController(context, tokens.get(i)));
                                 }
-                                mListener.onActiveSessionsChanged(controllers);
+                                final OnActiveSessionsChangedListener listener = mListener;
+                                if (listener != null) {
+                                    listener.onActiveSessionsChanged(controllers);
+                                }
                             }
                         }
                     });
@@ -566,8 +571,8 @@
         };
 
         private void release() {
-            mContext = null;
             mListener = null;
+            mContext = null;
             mHandler = null;
         }
     }
diff --git a/media/jni/soundpool/SoundPoolThread.cpp b/media/jni/soundpool/SoundPoolThread.cpp
index 3d98877..ba3b482 100644
--- a/media/jni/soundpool/SoundPoolThread.cpp
+++ b/media/jni/soundpool/SoundPoolThread.cpp
@@ -20,8 +20,6 @@
 
 #include "SoundPoolThread.h"
 
-static const int kMaxWorkers = 3;
-
 namespace android {
 
 void SoundPoolThread::write(SoundPoolMsg msg) {
@@ -33,21 +31,14 @@
     // if thread is quitting, don't add to queue
     if (mRunning) {
         mMsgQueue.push(msg);
-        if (mNumWorkers < kMaxWorkers) {
-            if (createThreadEtc(beginThread, this, "SoundPoolThread")) {
-                mNumWorkers++;
-                ALOGV("created worker thread");
-            }
-        }
+        mCondition.signal();
     }
 }
 
 const SoundPoolMsg SoundPoolThread::read() {
     Mutex::Autolock lock(&mLock);
-    if (mMsgQueue.size() == 0) {
-        mNumWorkers--;
-        mCondition.signal();
-        return SoundPoolMsg(SoundPoolMsg::KILL, 0);
+    while (mMsgQueue.size() == 0) {
+        mCondition.wait(mLock);
     }
     SoundPoolMsg msg = mMsgQueue[0];
     mMsgQueue.removeAt(0);
@@ -60,20 +51,20 @@
     if (mRunning) {
         mRunning = false;
         mMsgQueue.clear();
-        mCondition.broadcast(); // wake up any blocked writers
-        while (mNumWorkers > 0) {
-            mCondition.wait(mLock);
-        }
+        mMsgQueue.push(SoundPoolMsg(SoundPoolMsg::KILL, 0));
+        mCondition.signal();
+        mCondition.wait(mLock);
     }
     ALOGV("return from quit");
 }
 
 SoundPoolThread::SoundPoolThread(SoundPool* soundPool) :
-    mSoundPool(soundPool),
-    mNumWorkers(0),
-    mRunning(true)
+    mSoundPool(soundPool)
 {
     mMsgQueue.setCapacity(maxMessages);
+    if (createThreadEtc(beginThread, this, "SoundPoolThread")) {
+        mRunning = true;
+    }
 }
 
 SoundPoolThread::~SoundPoolThread()
diff --git a/media/jni/soundpool/SoundPoolThread.h b/media/jni/soundpool/SoundPoolThread.h
index 5d7bf0c..7b3e1dd 100644
--- a/media/jni/soundpool/SoundPoolThread.h
+++ b/media/jni/soundpool/SoundPoolThread.h
@@ -58,7 +58,6 @@
     Condition               mCondition;
     Vector<SoundPoolMsg>    mMsgQueue;
     SoundPool*              mSoundPool;
-    int32_t                 mNumWorkers;
     bool                    mRunning;
 };
 
diff --git a/native/webview/Android.mk b/native/webview/Android.mk
new file mode 100644
index 0000000..a2a93d7
--- /dev/null
+++ b/native/webview/Android.mk
@@ -0,0 +1,19 @@
+#
+# Copyright (C) 2017 The Android Open Source 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 all the makefiles for subdirectories.
+include $(call all-subdir-makefiles)
+
diff --git a/native/webview/OWNERS b/native/webview/OWNERS
new file mode 100644
index 0000000..deee852
--- /dev/null
+++ b/native/webview/OWNERS
@@ -0,0 +1,4 @@
+boliu@google.com
+sgurun@google.com
+tobiasjs@google.com
+torne@google.com
diff --git a/native/webview/loader/Android.mk b/native/webview/loader/Android.mk
new file mode 100644
index 0000000..e8a7d97
--- /dev/null
+++ b/native/webview/loader/Android.mk
@@ -0,0 +1,40 @@
+#
+# Copyright (C) 2017 The Android Open Source 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.
+
+# This package provides the system interfaces required to load WebView.
+
+LOCAL_PATH := $(call my-dir)
+
+# Loader library which handles address space reservation and relro sharing.
+# Does NOT link any native chromium code.
+include $(CLEAR_VARS)
+
+LOCAL_MODULE:= libwebviewchromium_loader
+
+LOCAL_SRC_FILES := \
+        loader.cpp \
+
+LOCAL_CFLAGS := \
+        -Werror \
+
+LOCAL_SHARED_LIBRARIES += \
+        libdl \
+        liblog \
+        libnativeloader \
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/native/webview/loader/loader.cpp b/native/webview/loader/loader.cpp
new file mode 100644
index 0000000..376dbb8
--- /dev/null
+++ b/native/webview/loader/loader.cpp
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Uncomment for verbose logging.
+// #define LOG_NDEBUG 0
+#define LOG_TAG "webviewchromiumloader"
+
+#include <dlfcn.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <jni.h>
+#include <android/dlext.h>
+#include <nativeloader/native_loader.h>
+#include <utils/Log.h>
+
+#define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
+
+namespace android {
+namespace {
+
+void* gReservedAddress = NULL;
+size_t gReservedSize = 0;
+
+jint LIBLOAD_SUCCESS;
+jint LIBLOAD_FAILED_TO_OPEN_RELRO_FILE;
+jint LIBLOAD_FAILED_TO_LOAD_LIBRARY;
+jint LIBLOAD_FAILED_JNI_CALL;
+jint LIBLOAD_FAILED_TO_FIND_NAMESPACE;
+
+jboolean DoReserveAddressSpace(jlong size) {
+  size_t vsize = static_cast<size_t>(size);
+
+  void* addr = mmap(NULL, vsize, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  if (addr == MAP_FAILED) {
+    ALOGE("Failed to reserve %zd bytes of address space for future load of "
+          "libwebviewchromium.so: %s",
+          vsize, strerror(errno));
+    return JNI_FALSE;
+  }
+  gReservedAddress = addr;
+  gReservedSize = vsize;
+  ALOGV("Reserved %zd bytes at %p", vsize, addr);
+  return JNI_TRUE;
+}
+
+jboolean DoCreateRelroFile(const char* lib, const char* relro) {
+  // Try to unlink the old file, since if this is being called, the old one is
+  // obsolete.
+  if (unlink(relro) != 0 && errno != ENOENT) {
+    // If something went wrong other than the file not existing, log a warning
+    // but continue anyway in the hope that we can successfully overwrite the
+    // existing file with rename() later.
+    ALOGW("Failed to unlink old file %s: %s", relro, strerror(errno));
+  }
+  static const char tmpsuffix[] = ".XXXXXX";
+  char relro_tmp[strlen(relro) + sizeof(tmpsuffix)];
+  strlcpy(relro_tmp, relro, sizeof(relro_tmp));
+  strlcat(relro_tmp, tmpsuffix, sizeof(relro_tmp));
+  int tmp_fd = TEMP_FAILURE_RETRY(mkstemp(relro_tmp));
+  if (tmp_fd == -1) {
+    ALOGE("Failed to create temporary file %s: %s", relro_tmp, strerror(errno));
+    return JNI_FALSE;
+  }
+  android_dlextinfo extinfo;
+  extinfo.flags = ANDROID_DLEXT_RESERVED_ADDRESS | ANDROID_DLEXT_WRITE_RELRO;
+  extinfo.reserved_addr = gReservedAddress;
+  extinfo.reserved_size = gReservedSize;
+  extinfo.relro_fd = tmp_fd;
+  void* handle = android_dlopen_ext(lib, RTLD_NOW, &extinfo);
+  int close_result = close(tmp_fd);
+  if (handle == NULL) {
+    ALOGE("Failed to load library %s: %s", lib, dlerror());
+    unlink(relro_tmp);
+    return JNI_FALSE;
+  }
+  if (close_result != 0 ||
+      chmod(relro_tmp, S_IRUSR | S_IRGRP | S_IROTH) != 0 ||
+      rename(relro_tmp, relro) != 0) {
+    ALOGE("Failed to update relro file %s: %s", relro, strerror(errno));
+    unlink(relro_tmp);
+    return JNI_FALSE;
+  }
+  ALOGV("Created relro file %s for library %s", relro, lib);
+  return JNI_TRUE;
+}
+
+jint DoLoadWithRelroFile(JNIEnv* env, const char* lib, const char* relro,
+                         jobject clazzLoader) {
+  int relro_fd = TEMP_FAILURE_RETRY(open(relro, O_RDONLY));
+  if (relro_fd == -1) {
+    ALOGE("Failed to open relro file %s: %s", relro, strerror(errno));
+    return LIBLOAD_FAILED_TO_OPEN_RELRO_FILE;
+  }
+  android_namespace_t* ns =
+      android::FindNamespaceByClassLoader(env, clazzLoader);
+  if (ns == NULL) {
+    ALOGE("Failed to find classloader namespace");
+    return LIBLOAD_FAILED_TO_FIND_NAMESPACE;
+  }
+  android_dlextinfo extinfo;
+  extinfo.flags = ANDROID_DLEXT_RESERVED_ADDRESS | ANDROID_DLEXT_USE_RELRO |
+                  ANDROID_DLEXT_USE_NAMESPACE;
+  extinfo.reserved_addr = gReservedAddress;
+  extinfo.reserved_size = gReservedSize;
+  extinfo.relro_fd = relro_fd;
+  extinfo.library_namespace = ns;
+  void* handle = android_dlopen_ext(lib, RTLD_NOW, &extinfo);
+  close(relro_fd);
+  if (handle == NULL) {
+    ALOGE("Failed to load library %s: %s", lib, dlerror());
+    return LIBLOAD_FAILED_TO_LOAD_LIBRARY;
+  }
+  ALOGV("Loaded library %s with relro file %s", lib, relro);
+  return LIBLOAD_SUCCESS;
+}
+
+/******************************************************************************/
+/* JNI wrappers - handle string lifetimes and 32/64 ABI choice                */
+/******************************************************************************/
+
+jboolean ReserveAddressSpace(JNIEnv*, jclass, jlong size) {
+  return DoReserveAddressSpace(size);
+}
+
+jboolean CreateRelroFile(JNIEnv* env, jclass, jstring lib32, jstring lib64,
+                         jstring relro32, jstring relro64) {
+#ifdef __LP64__
+  jstring lib = lib64;
+  jstring relro = relro64;
+  (void)lib32; (void)relro32;
+#else
+  jstring lib = lib32;
+  jstring relro = relro32;
+  (void)lib64; (void)relro64;
+#endif
+  jboolean ret = JNI_FALSE;
+  const char* lib_utf8 = env->GetStringUTFChars(lib, NULL);
+  if (lib_utf8 != NULL) {
+    const char* relro_utf8 = env->GetStringUTFChars(relro, NULL);
+    if (relro_utf8 != NULL) {
+      ret = DoCreateRelroFile(lib_utf8, relro_utf8);
+      env->ReleaseStringUTFChars(relro, relro_utf8);
+    }
+    env->ReleaseStringUTFChars(lib, lib_utf8);
+  }
+  return ret;
+}
+
+jint LoadWithRelroFile(JNIEnv* env, jclass, jstring lib, jstring relro32,
+                       jstring relro64, jobject clazzLoader) {
+#ifdef __LP64__
+  jstring relro = relro64;
+  (void)relro32;
+#else
+  jstring relro = relro32;
+  (void)relro64;
+#endif
+  jint ret = LIBLOAD_FAILED_JNI_CALL;
+  const char* lib_utf8 = env->GetStringUTFChars(lib, NULL);
+  if (lib_utf8 != NULL) {
+    const char* relro_utf8 = env->GetStringUTFChars(relro, NULL);
+    if (relro_utf8 != NULL) {
+      ret = DoLoadWithRelroFile(env, lib_utf8, relro_utf8, clazzLoader);
+      env->ReleaseStringUTFChars(relro, relro_utf8);
+    }
+    env->ReleaseStringUTFChars(lib, lib_utf8);
+  }
+  return ret;
+}
+
+const char kWebViewFactoryClassName[] = "android/webkit/WebViewFactory";
+const char kWebViewLibraryLoaderClassName[] =
+    "android/webkit/WebViewLibraryLoader";
+const JNINativeMethod kJniMethods[] = {
+  { "nativeReserveAddressSpace", "(J)Z",
+      reinterpret_cast<void*>(ReserveAddressSpace) },
+  { "nativeCreateRelroFile",
+      "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z",
+      reinterpret_cast<void*>(CreateRelroFile) },
+  { "nativeLoadWithRelroFile",
+      "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)I",
+      reinterpret_cast<void*>(LoadWithRelroFile) },
+};
+
+}  // namespace
+
+void RegisterWebViewFactory(JNIEnv* env) {
+  // If either of these fail, it will set an exception that will be thrown on
+  // return, so no need to handle errors here.
+  jclass clazz = env->FindClass(kWebViewFactoryClassName);
+  if (clazz) {
+    LIBLOAD_SUCCESS = env->GetStaticIntField(
+        clazz,
+        env->GetStaticFieldID(clazz, "LIBLOAD_SUCCESS", "I"));
+
+    LIBLOAD_FAILED_TO_OPEN_RELRO_FILE = env->GetStaticIntField(
+        clazz,
+        env->GetStaticFieldID(clazz, "LIBLOAD_FAILED_TO_OPEN_RELRO_FILE", "I"));
+
+    LIBLOAD_FAILED_TO_LOAD_LIBRARY = env->GetStaticIntField(
+        clazz,
+        env->GetStaticFieldID(clazz, "LIBLOAD_FAILED_TO_LOAD_LIBRARY", "I"));
+
+    LIBLOAD_FAILED_JNI_CALL = env->GetStaticIntField(
+        clazz,
+        env->GetStaticFieldID(clazz, "LIBLOAD_FAILED_JNI_CALL", "I"));
+
+    LIBLOAD_FAILED_TO_FIND_NAMESPACE = env->GetStaticIntField(
+        clazz,
+        env->GetStaticFieldID(clazz, "LIBLOAD_FAILED_TO_FIND_NAMESPACE", "I"));
+  }
+}
+
+void RegisterWebViewLibraryLoader(JNIEnv* env) {
+  // If either of these fail, it will set an exception that will be thrown on
+  // return, so no need to handle errors here.
+  jclass clazz = env->FindClass(kWebViewLibraryLoaderClassName);
+  if (clazz) {
+    env->RegisterNatives(clazz, kJniMethods, NELEM(kJniMethods));
+  }
+}
+
+}  // namespace android
+
+JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) {
+  JNIEnv* env = NULL;
+  if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+    ALOGE("GetEnv failed");
+    return JNI_ERR;
+  }
+  android::RegisterWebViewFactory(env);
+  // Ensure there isn't a pending Java exception before registering methods from
+  // WebViewLibraryLoader
+  if (!env->ExceptionCheck()) {
+    android::RegisterWebViewLibraryLoader(env);
+  }
+  return JNI_VERSION_1_6;
+}
diff --git a/packages/BackupRestoreConfirmation/res/values-da/strings.xml b/packages/BackupRestoreConfirmation/res/values-da/strings.xml
index 28aea33..3a74915 100644
--- a/packages/BackupRestoreConfirmation/res/values-da/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-da/strings.xml
@@ -19,7 +19,7 @@
     <string name="backup_confirm_title" msgid="827563724209303345">"Fuld sikkerhedskopiering"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Fuld genoprettelse"</string>
     <string name="backup_confirm_text" msgid="1878021282758896593">"Der er anmodet om en fuld sikkerhedskopiering af alle data til en tilsluttet stationær computer. Vil du tillade dette?\n\nHvis du ikke har anmodet om sikkerhedskopiering, skal du ikke tillade denne handling."</string>
-    <string name="allow_backup_button_label" msgid="4217228747769644068">"Sikkerhedskopier mine data"</string>
+    <string name="allow_backup_button_label" msgid="4217228747769644068">"Sikkerhedskopiér mine data"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Undlad at sikkerhedskopiere"</string>
     <string name="restore_confirm_text" msgid="7499866728030461776">"Der er anmodet om en fuld sikkerhedskopiering af alle data til en tilsluttet stationær computer. Vil du tillade dette?\n\nHvis du ikke har anmodet om sikkerhedskopiering, skal du ikke tillade denne handling."</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Gendan mine data"</string>
diff --git a/packages/CaptivePortalLogin/res/values-eu/strings.xml b/packages/CaptivePortalLogin/res/values-eu/strings.xml
index fdadbaa..8925aac 100644
--- a/packages/CaptivePortalLogin/res/values-eu/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-eu/strings.xml
@@ -5,7 +5,7 @@
     <string name="action_use_network" msgid="6076184727448466030">"Erabili sare hau bere horretan"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Ez erabili sare hau"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Hasi saioa sarean"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Hasi saioa %1$s zerbitzuan"</string>
+    <string name="action_bar_title" msgid="5645564790486983117">"Hasi saioa %1$s sarean"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Erabili nahi duzun sareak segurtasun-arazoak ditu."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Adibidez, baliteke saioa hasteko orria adierazitako erakundearena ez izatea."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Jarraitu arakatzailearen bidez, halere"</string>
diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
index 20b12b4..3dc170f 100644
--- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
+++ b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
@@ -375,6 +375,9 @@
                 return;
             } else if (mPagesLoaded == 2) {
                 // Prevent going back to empty first page.
+                // Fix for missing focus, see b/62449959 for details. Remove it once we get a
+                // newer version of WebView (60.x.y).
+                view.requestFocus();
                 view.clearHistory();
             }
             testForCaptivePortal();
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index b4c8cec..438cbbb 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -376,6 +376,6 @@
     <string name="active_input_method_subtypes" msgid="3596398805424733238">"Mètodes d\'introducció actius"</string>
     <string name="use_system_language_to_select_input_method_subtypes" msgid="5747329075020379587">"Utilitza els idiomes del sistema"</string>
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"No s\'ha pogut obrir la configuració de: <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
-    <string name="ime_security_warning" msgid="4135828934735934248">"Pot ser que aquest mètode d\'entrada pugui recopilar tot el que escriviu, incloses dades personals, com ara contrasenyes i números de targetes de crèdit. Ve de l\'aplicació <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Voleu utilitzar aquest mètode d\'entrada?"</string>
+    <string name="ime_security_warning" msgid="4135828934735934248">"Pot ser que aquest mètode d\'introducció pugui recopilar tot el que escriviu, incloses dades personals, com ara contrasenyes i números de targetes de crèdit. Ve de l\'aplicació <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Voleu utilitzar aquest mètode d\'introducció?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Nota: després de reiniciar, l\'aplicació no s\'iniciarà fins que no desbloquegis el telèfon"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 0484645..7f2d85a 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -110,7 +110,7 @@
     <string name="unknown" msgid="1592123443519355854">"Sconosciuta"</string>
     <string name="running_process_item_user_label" msgid="3129887865552025943">"Utente: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
     <string name="launch_defaults_some" msgid="313159469856372621">"Alcune opzioni predefinite impostate"</string>
-    <string name="launch_defaults_none" msgid="4241129108140034876">"Nessuna app predefinita impostata"</string>
+    <string name="launch_defaults_none" msgid="4241129108140034876">"Nessuna impostazione predefinita"</string>
     <string name="tts_settings" msgid="8186971894801348327">"Impostazioni di sintesi vocale"</string>
     <string name="tts_settings_title" msgid="1237820681016639683">"Output sintesi vocale"</string>
     <string name="tts_default_rate_title" msgid="6030550998379310088">"Velocità voce"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 09dae27..eb20fdc 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -86,7 +86,7 @@
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"페어링"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"페어링"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"취소"</string>
-    <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"페어링하면 연결 시 주소록 및 통화 기록에 액세스할 수 있습니다."</string>
+    <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"페어링하면 연결 시 연락처 및 통화 기록에 액세스할 수 있습니다."</string>
     <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>와(과) 페어링하지 못했습니다."</string>
     <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"PIN 또는 패스키가 잘못되어 <xliff:g id="DEVICE_NAME">%1$s</xliff:g>와(과) 페어링하지 못했습니다."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>와(과) 통신할 수 없습니다."</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index f9d1930..675a6d09 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -90,7 +90,7 @@
     <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"Não foi possível parear com <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Não foi possível parear com <xliff:g id="DEVICE_NAME">%1$s</xliff:g> por causa de um PIN ou senha incorretos."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Não é possível se comunicar com <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
-    <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Emparelhamento rejeitado por <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+    <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Pareamento rejeitado por <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi desligado."</string>
     <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi desconectado"</string>
     <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Uma barra de Wi-Fi."</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index f9d1930..675a6d09 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -90,7 +90,7 @@
     <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"Não foi possível parear com <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Não foi possível parear com <xliff:g id="DEVICE_NAME">%1$s</xliff:g> por causa de um PIN ou senha incorretos."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Não é possível se comunicar com <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
-    <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Emparelhamento rejeitado por <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+    <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Pareamento rejeitado por <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi desligado."</string>
     <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi desconectado"</string>
     <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Uma barra de Wi-Fi."</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 61f280c..ff6c838 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -59,7 +59,7 @@
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Звонки"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Профиль OPP"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Профиль HID"</string>
-    <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Интернет-доступ"</string>
+    <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Доступ к Интернету"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Обмен контактами"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Использовать для обмена контактами"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Профиль PAN"</string>
@@ -83,12 +83,12 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Использовать для аудиоустройства телефона"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Используется для передачи файлов"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Использовать для ввода"</string>
-    <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Подключить"</string>
-    <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"ПОДКЛЮЧИТЬ"</string>
+    <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Добавить"</string>
+    <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"ДОБАВИТЬ"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Отмена"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"Сопряжение обеспечивает доступ к вашим контактам и журналу звонков при подключении."</string>
-    <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"Не удалось подключиться к устройству \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\"."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Не удалось подключиться к устройству \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\", так как введен неверный PIN-код или пароль."</string>
+    <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"Не удалось установить сопряжение с устройством \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\"."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Не удалось установить сопряжение с устройством \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\", так как введен неверный PIN-код или пароль."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Не удается установить соединение с устройством \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\"."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> не разрешает сопряжение."</string>
     <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi выключен"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 7e2e7d5..8ceb1d8 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -50,7 +50,7 @@
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Bağlantı kesiliyor…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Bağlanıyor…"</string>
     <string name="bluetooth_connected" msgid="6038755206916626419">"Bağlandı"</string>
-    <string name="bluetooth_pairing" msgid="1426882272690346242">"Eşleştiriliyor…"</string>
+    <string name="bluetooth_pairing" msgid="1426882272690346242">"Eşleniyor…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2866994875046035609">"Bağlandı (telefon yok)"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Bağlandı (medya yok)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Bağlı (mesaj erişimi yok)"</string>
@@ -83,14 +83,14 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Telefon sesi için kullan"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Dosya aktarımı için kullan"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Giriş için kullan"</string>
-    <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Eşleştir"</string>
-    <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"EŞLEŞTİR"</string>
+    <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Eşle"</string>
+    <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"EŞLE"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"İptal"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"Eşleme işlemi, bağlantı kurulduğunda kişilerinize ve çağrı geçmişine erişim izni verir."</string>
-    <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ile eşleştirilemedi."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"PIN veya parola yanlış olduğundan <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ile eşleştirilemedi"</string>
+    <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ile eşlenemedi."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"PIN veya parola yanlış olduğundan <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ile eşlenemedi"</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ile iletişim kurulamıyor."</string>
-    <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Eşleştirme <xliff:g id="DEVICE_NAME">%1$s</xliff:g> tarafından reddedildi."</string>
+    <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Eşleme <xliff:g id="DEVICE_NAME">%1$s</xliff:g> tarafından reddedildi."</string>
     <string name="accessibility_wifi_off" msgid="1166761729660614716">"Kablosuz kapalı."</string>
     <string name="accessibility_no_wifi" msgid="8834610636137374508">"Kablosuz bağlantı kesildi."</string>
     <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Kablosuz sinyal gücü tek çubuk."</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/CustomDialogPreference.java b/packages/SettingsLib/src/com/android/settingslib/CustomDialogPreference.java
new file mode 100644
index 0000000..9554e81
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/CustomDialogPreference.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settingslib;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.support.v14.preference.PreferenceDialogFragment;
+import android.support.v7.preference.DialogPreference;
+import android.util.AttributeSet;
+import android.view.View;
+
+public class CustomDialogPreference extends DialogPreference {
+
+    private CustomPreferenceDialogFragment mFragment;
+
+    public CustomDialogPreference(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    public CustomDialogPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    public CustomDialogPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public CustomDialogPreference(Context context) {
+        super(context);
+    }
+
+    public boolean isDialogOpen() {
+        return getDialog() != null && getDialog().isShowing();
+    }
+
+    public Dialog getDialog() {
+        return mFragment != null ? mFragment.getDialog() : null;
+    }
+
+    protected void onPrepareDialogBuilder(AlertDialog.Builder builder,
+            DialogInterface.OnClickListener listener) {
+    }
+
+    protected void onDialogClosed(boolean positiveResult) {
+    }
+
+    protected void onClick(DialogInterface dialog, int which) {
+    }
+
+    protected void onBindDialogView(View view) {
+    }
+
+    private void setFragment(CustomPreferenceDialogFragment fragment) {
+        mFragment = fragment;
+    }
+
+    public static class CustomPreferenceDialogFragment extends PreferenceDialogFragment {
+
+        public static CustomPreferenceDialogFragment newInstance(String key) {
+            final CustomPreferenceDialogFragment fragment = new CustomPreferenceDialogFragment();
+            final Bundle b = new Bundle(1);
+            b.putString(ARG_KEY, key);
+            fragment.setArguments(b);
+            return fragment;
+        }
+
+        private CustomDialogPreference getCustomizablePreference() {
+            return (CustomDialogPreference) getPreference();
+        }
+
+        @Override
+        protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
+            super.onPrepareDialogBuilder(builder);
+            getCustomizablePreference().setFragment(this);
+            getCustomizablePreference().onPrepareDialogBuilder(builder, this);
+        }
+
+        @Override
+        public void onDialogClosed(boolean positiveResult) {
+            getCustomizablePreference().onDialogClosed(positiveResult);
+        }
+
+        @Override
+        protected void onBindDialogView(View view) {
+            super.onBindDialogView(view);
+            getCustomizablePreference().onBindDialogView(view);
+        }
+
+        @Override
+        public void onClick(DialogInterface dialog, int which) {
+            super.onClick(dialog, which);
+            getCustomizablePreference().onClick(dialog, which);
+        }
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/CustomEditTextPreference.java b/packages/SettingsLib/src/com/android/settingslib/CustomEditTextPreference.java
new file mode 100644
index 0000000..253ca11
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/CustomEditTextPreference.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settingslib;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.support.v14.preference.EditTextPreferenceDialogFragment;
+import android.support.v7.preference.EditTextPreference;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.EditText;
+
+public class CustomEditTextPreference extends EditTextPreference {
+
+    private CustomPreferenceDialogFragment mFragment;
+
+    public CustomEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    public CustomEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    public CustomEditTextPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public CustomEditTextPreference(Context context) {
+        super(context);
+    }
+
+    public EditText getEditText() {
+        return mFragment != null ? (EditText) mFragment.getDialog().findViewById(android.R.id.edit)
+                : null;
+    }
+
+    public boolean isDialogOpen() {
+        return getDialog() != null && getDialog().isShowing();
+    }
+
+    public Dialog getDialog() {
+        return mFragment != null ? mFragment.getDialog() : null;
+    }
+
+    protected void onPrepareDialogBuilder(AlertDialog.Builder builder,
+            DialogInterface.OnClickListener listener) {
+    }
+
+    protected void onDialogClosed(boolean positiveResult) {
+    }
+
+    protected void onClick(DialogInterface dialog, int which) {
+    }
+
+    protected void onBindDialogView(View view) {
+    }
+
+    private void setFragment(CustomPreferenceDialogFragment fragment) {
+        mFragment = fragment;
+    }
+
+    public static class CustomPreferenceDialogFragment extends EditTextPreferenceDialogFragment {
+
+        public static CustomPreferenceDialogFragment newInstance(String key) {
+            final CustomPreferenceDialogFragment fragment = new CustomPreferenceDialogFragment();
+            final Bundle b = new Bundle(1);
+            b.putString(ARG_KEY, key);
+            fragment.setArguments(b);
+            return fragment;
+        }
+
+        private CustomEditTextPreference getCustomizablePreference() {
+            return (CustomEditTextPreference) getPreference();
+        }
+
+        @Override
+        protected void onBindDialogView(View view) {
+            super.onBindDialogView(view);
+            getCustomizablePreference().onBindDialogView(view);
+        }
+
+        @Override
+        protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
+            super.onPrepareDialogBuilder(builder);
+            getCustomizablePreference().setFragment(this);
+            getCustomizablePreference().onPrepareDialogBuilder(builder, this);
+        }
+
+        @Override
+        public void onDialogClosed(boolean positiveResult) {
+            super.onDialogClosed(positiveResult);
+            getCustomizablePreference().onDialogClosed(positiveResult);
+        }
+
+        @Override
+        public void onClick(DialogInterface dialog, int which) {
+            super.onClick(dialog, which);
+            getCustomizablePreference().onClick(dialog, which);
+        }
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java b/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java
index b06b032..7357fe6 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java
@@ -107,4 +107,20 @@
         return false;
     }
 
+    /** Returns the label for a given package. */
+    public static CharSequence getApplicationLabel(
+            PackageManager packageManager, String packageName) {
+        try {
+            final ApplicationInfo appInfo =
+                    packageManager.getApplicationInfo(
+                            packageName,
+                            PackageManager.MATCH_DISABLED_COMPONENTS
+                                    | PackageManager.MATCH_ANY_USER);
+            return appInfo.loadLabel(packageManager);
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.w(TAG, "Unable to find info for package: " + packageName);
+        }
+        return null;
+    }
+
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java b/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java
index a8f6f02..8fc9fa6 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java
@@ -54,6 +54,10 @@
                 mStorageStatsManager.queryStatsForPackage(volumeUuid, packageName, user));
     }
 
+    public long getCacheQuotaBytes(String volumeUuid, int uid) {
+        return mStorageStatsManager.getCacheQuotaBytes(volumeUuid, uid);
+    }
+
     /**
      * Static class that provides methods for querying the amount of external storage available as
      * well as breaking it up into several media types.
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java b/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java
index fc1a3a9..38fe879 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java
@@ -4,7 +4,6 @@
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.PreferenceGroup;
 import android.support.v7.preference.PreferenceScreen;
-import java.util.List;
 
 /**
  * A controller that manages event for preference.
@@ -40,17 +39,6 @@
   }
 
   /**
-   * Updates non-indexable keys for search provider.
-   *
-   * Called by SearchIndexProvider#getNonIndexableKeys
-   */
-  public void updateNonIndexableKeys(List<String> keys) {
-      if (!isAvailable()) {
-          keys.add(getPreferenceKey());
-      }
-  }
-
-  /**
    * Returns true if preference is available (should be displayed)
    */
   public abstract boolean isAvailable();
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java b/packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java
index 5a1e603..f1d43bf 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java
@@ -51,6 +51,12 @@
     public Icon icon;
 
     /**
+     * Whether the icon can be tinted. This should be set to true for monochrome (single-color)
+     * icons that can be tinted to match the design.
+     */
+    public boolean isIconTintable;
+
+    /**
      * Intent to launch when the preference is selected.
      */
     public Intent intent;
@@ -126,6 +132,7 @@
         dest.writeBundle(metaData);
         dest.writeString(key);
         dest.writeParcelable(remoteViews, flags);
+        dest.writeBoolean(isIconTintable);
     }
 
     public void readFromParcel(Parcel in) {
@@ -147,6 +154,7 @@
         metaData = in.readBundle();
         key = in.readString();
         remoteViews = in.readParcelable(RemoteViews.class.getClassLoader());
+        isIconTintable = in.readBoolean();
     }
 
     Tile(Parcel in) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java b/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
index 04a3d1f..9620a91 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
@@ -133,15 +133,25 @@
 
     /**
      * Name of the meta-data item that should be set in the AndroidManifest.xml
-     * to specify the title that should be displayed for the preference.
+     * to specify whether the icon is tintable. This should be a boolean value {@code true} or
+     * {@code false}, set using {@code android:value}
      */
-    @Deprecated
-    public static final String META_DATA_PREFERENCE_TITLE = "com.android.settings.title";
+    public static final String META_DATA_PREFERENCE_ICON_TINTABLE =
+            "com.android.settings.icon_tintable";
 
     /**
      * Name of the meta-data item that should be set in the AndroidManifest.xml
      * to specify the title that should be displayed for the preference.
+     *
+     * <p>Note: It is preferred to provide this value using {@code android:resource} with a string
+     * resource for localization.
      */
+    public static final String META_DATA_PREFERENCE_TITLE = "com.android.settings.title";
+
+    /**
+     * @deprecated Use {@link #META_DATA_PREFERENCE_TITLE} with {@code android:resource}
+     */
+    @Deprecated
     public static final String META_DATA_PREFERENCE_TITLE_RES_ID =
             "com.android.settings.title.resid";
 
@@ -309,12 +319,13 @@
             intent.setPackage(settingPkg);
         }
         getTilesForIntent(context, user, intent, addedCache, defaultCategory, outTiles,
-                usePriority, true);
+                usePriority, true, true);
     }
 
-    public static void getTilesForIntent(Context context, UserHandle user, Intent intent,
+    public static void getTilesForIntent(
+            Context context, UserHandle user, Intent intent,
             Map<Pair<String, String>, Tile> addedCache, String defaultCategory, List<Tile> outTiles,
-            boolean usePriority, boolean checkCategory) {
+            boolean usePriority, boolean checkCategory, boolean forceTintExternalIcon) {
         PackageManager pm = context.getPackageManager();
         List<ResolveInfo> results = pm.queryIntentActivitiesAsUser(intent,
                 PackageManager.GET_META_DATA, user.getIdentifier());
@@ -350,7 +361,7 @@
                 tile.priority = usePriority ? resolved.priority : 0;
                 tile.metaData = activityInfo.metaData;
                 updateTileData(context, tile, activityInfo, activityInfo.applicationInfo,
-                        pm, providerMap);
+                        pm, providerMap, forceTintExternalIcon);
                 if (DEBUG) Log.d(LOG_TAG, "Adding tile " + tile.title);
 
                 addedCache.put(key, tile);
@@ -366,25 +377,40 @@
 
     private static boolean updateTileData(Context context, Tile tile,
             ActivityInfo activityInfo, ApplicationInfo applicationInfo, PackageManager pm,
-            Map<String, IContentProvider> providerMap) {
+            Map<String, IContentProvider> providerMap, boolean forceTintExternalIcon) {
         if (applicationInfo.isSystemApp()) {
+            boolean forceTintIcon = false;
             int icon = 0;
             Pair<String, Integer> iconFromUri = null;
             CharSequence title = null;
             String summary = null;
             String keyHint = null;
+            boolean isIconTintable = false;
             RemoteViews remoteViews = null;
 
             // Get the activity's meta-data
             try {
-                Resources res = pm.getResourcesForApplication(
-                        applicationInfo.packageName);
+                Resources res = pm.getResourcesForApplication(applicationInfo.packageName);
                 Bundle metaData = activityInfo.metaData;
 
+                if (forceTintExternalIcon
+                        && !context.getPackageName().equals(applicationInfo.packageName)) {
+                    isIconTintable = true;
+                    forceTintIcon = true;
+                }
+
                 if (res != null && metaData != null) {
                     if (metaData.containsKey(META_DATA_PREFERENCE_ICON)) {
                         icon = metaData.getInt(META_DATA_PREFERENCE_ICON);
                     }
+                    if (metaData.containsKey(META_DATA_PREFERENCE_ICON_TINTABLE)) {
+                        if (forceTintIcon) {
+                            Log.w(LOG_TAG, "Ignoring icon tintable for " + activityInfo);
+                        } else {
+                            isIconTintable =
+                                    metaData.getBoolean(META_DATA_PREFERENCE_ICON_TINTABLE);
+                        }
+                    }
                     int resId = 0;
                     if (metaData.containsKey(META_DATA_PREFERENCE_TITLE_RES_ID)) {
                         resId = metaData.getInt(META_DATA_PREFERENCE_TITLE_RES_ID);
@@ -392,8 +418,6 @@
                             title = res.getString(resId);
                         }
                     }
-                    // Fallback to legacy title extraction if we couldn't get the title through
-                    // res id.
                     if ((resId == 0) && metaData.containsKey(META_DATA_PREFERENCE_TITLE)) {
                         if (metaData.get(META_DATA_PREFERENCE_TITLE) instanceof Integer) {
                             title = res.getString(metaData.getInt(META_DATA_PREFERENCE_TITLE));
@@ -457,6 +481,7 @@
                     activityInfo.name);
             // Suggest a key for this tile
             tile.key = keyHint;
+            tile.isIconTintable = isIconTintable;
             tile.remoteViews = remoteViews;
 
             return true;
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java b/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java
index 1bb1417..426dc7c 100755
--- a/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java
+++ b/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java
@@ -28,6 +28,7 @@
 import android.graphics.Path;
 import android.graphics.Path.Direction;
 import android.graphics.Path.FillType;
+import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.Typeface;
 import android.graphics.drawable.Drawable;
@@ -82,6 +83,7 @@
     private final float[] mPlusPoints;
     private final Path mPlusPath = new Path();
 
+    private final Rect mPadding = new Rect();
     private final RectF mFrame = new RectF();
     private final RectF mButtonFrame = new RectF();
     private final RectF mBoltFrame = new RectF();
@@ -219,12 +221,40 @@
     @Override
     public void setBounds(int left, int top, int right, int bottom) {
         super.setBounds(left, top, right, bottom);
-        mHeight = bottom - top;
-        mWidth = right - left;
+        updateSize();
+    }
+
+    private void updateSize() {
+        final Rect bounds = getBounds();
+
+        mHeight = (bounds.bottom - mPadding.bottom) - (bounds.top + mPadding.top);
+        mWidth = (bounds.right - mPadding.right) - (bounds.left + mPadding.left);
         mWarningTextPaint.setTextSize(mHeight * 0.75f);
         mWarningTextHeight = -mWarningTextPaint.getFontMetrics().ascent;
     }
 
+    @Override
+    public boolean getPadding(Rect padding) {
+        if (mPadding.left == 0
+            && mPadding.top == 0
+            && mPadding.right == 0
+            && mPadding.bottom == 0) {
+            return super.getPadding(padding);
+        }
+
+        padding.set(mPadding);
+        return true;
+    }
+
+    public void setPadding(int left, int top, int right, int bottom) {
+        mPadding.left = left;
+        mPadding.top = top;
+        mPadding.right = right;
+        mPadding.bottom = bottom;
+
+        updateSize();
+    }
+
     private int getColorForLevel(int percent) {
         // If we are in power save mode, always use the normal color.
         if (mPowerSaveEnabled) {
@@ -251,10 +281,15 @@
         mIconTint = fillColor;
         mFramePaint.setColor(backgroundColor);
         mBoltPaint.setColor(fillColor);
+        mPlusPaint.setColor(fillColor);
         mChargeColor = fillColor;
         invalidateSelf();
     }
 
+    protected int batteryColorForLevel(int level) {
+        return mCharging ? mChargeColor : getColorForLevel(level);
+    }
+
     @Override
     public void draw(Canvas c) {
         final int level = mLevel;
@@ -264,11 +299,10 @@
         float drawFrac = (float) level / 100f;
         final int height = mHeight;
         final int width = (int) (ASPECT_RATIO * mHeight);
-        int px = (mWidth - width) / 2;
-
+        final int px = (mWidth - width) / 2;
         final int buttonHeight = Math.round(height * mButtonHeightFraction);
 
-        mFrame.set(0, 0, width, height);
+        mFrame.set(mPadding.left, mPadding.top, width + mPadding.left, height + mPadding.top);
         mFrame.offset(px, 0);
 
         // button-frame: area above the battery body
@@ -282,7 +316,7 @@
         mFrame.top += buttonHeight;
 
         // set the battery charging color
-        mBatteryPaint.setColor(mCharging ? mChargeColor : getColorForLevel(level));
+        mBatteryPaint.setColor(batteryColorForLevel(level));
 
         if (level >= FULL) {
             drawFrac = 1f;
diff --git a/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java b/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java
index a28bece..167ffe6 100644
--- a/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java
+++ b/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java
@@ -208,7 +208,7 @@
             intent.setPackage(category.pkg);
         }
         TileUtils.getTilesForIntent(mContext, new UserHandle(UserHandle.myUserId()), intent,
-                mAddCache, null, suggestions, true, false);
+                mAddCache, null, suggestions, true, false, false);
         filterSuggestions(suggestions, countBefore, isSmartSuggestionEnabled);
         if (!category.multiple && suggestions.size() > (countBefore + 1)) {
             // If there are too many, remove them all and only re-add the one with the highest
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
index edb3226..d45ed19 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
@@ -703,6 +703,9 @@
                 case WifiConfiguration.NetworkSelectionStatus.DISABLED_AUTHENTICATION_FAILURE:
                     summary.append(mContext.getString(R.string.wifi_disabled_password_failure));
                     break;
+                case WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD:
+                    summary.append(mContext.getString(R.string.wifi_check_password_try_again));
+                    break;
                 case WifiConfiguration.NetworkSelectionStatus.DISABLED_DHCP_FAILURE:
                 case WifiConfiguration.NetworkSelectionStatus.DISABLED_DNS_FAILURE:
                     summary.append(mContext.getString(R.string.wifi_disabled_network_failure));
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java
index 83667ea..01df0ec 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java
@@ -3,6 +3,7 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Canvas;
+import android.graphics.Rect;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
@@ -12,6 +13,7 @@
 import org.junit.runner.RunWith;
 
 import static com.google.common.truth.Truth.assertThat;
+import static junit.framework.Assert.assertTrue;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyFloat;
 import static org.mockito.Matchers.anyString;
@@ -68,4 +70,49 @@
             }
         }
     }
+
+    @Test
+    public void testPadding_returnsCorrectValues() {
+        // different pads on each side to differentiate
+        final int left = 1;
+        final int top = 2;
+        final int right = 3;
+        final int bottom = 4;
+
+        final Rect expected = new Rect(left, top, right, bottom);
+        final Rect padding = new Rect();
+
+        mBatteryDrawable.setPadding(left, top, right, bottom);
+
+        assertThat(mBatteryDrawable.getPadding(padding)).isEqualTo(true);
+        assertThat(padding).isEqualTo(expected);
+    }
+
+    @Test
+    public void testPadding_falseIfUnsetOrZero() {
+        final Rect padding = new Rect();
+        assertThat(mBatteryDrawable.getPadding(padding)).isEqualTo(false);
+        assertThat(isRectZero(padding)).isEqualTo(true);
+
+        mBatteryDrawable.setPadding(0, 0, 0, 0);
+        assertThat(mBatteryDrawable.getPadding(padding)).isEqualTo(false);
+        assertThat(isRectZero(padding)).isEqualTo(true);
+    }
+
+    private boolean isRectZero(Rect r) {
+        return r.left == 0 && r.top == 0 && r.right == 0 && r.bottom == 0;
+    }
+
+    @Test
+    public void testPlusPaint_isEqualToBoltPaint() {
+        // Before setting color
+        assertTrue(mBatteryDrawable.mPlusPaint.hasEqualAttributes(mBatteryDrawable.mBoltPaint));
+
+        final int fakeFillColor = 123;
+        final int fakeBackgrundColor = 456;
+
+        // After
+        mBatteryDrawable.setColors(fakeFillColor, fakeBackgrundColor);
+        assertTrue(mBatteryDrawable.mPlusPaint.hasEqualAttributes(mBatteryDrawable.mBoltPaint));
+    }
 }
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/utils/ZoneGetterTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/utils/ZoneGetterTest.java
index a3345ee..0ec75ec 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/utils/ZoneGetterTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/utils/ZoneGetterTest.java
@@ -36,6 +36,8 @@
 public class ZoneGetterTest {
     private static final String TIME_ZONE_LONDON_ID = "Europe/London";
     private static final String TIME_ZONE_LA_ID = "America/Los_Angeles";
+    private static final String TIME_ZONE_ALGIERS_ID = "Africa/Algiers";
+    private static final String TIME_ZONE_CEUTA_ID = "Africa/Ceuta";
     private Locale mLocaleEnUs;
     private Calendar mCalendar;
 
@@ -59,6 +61,16 @@
     }
 
     @Test
+    public void getTimeZoneOffsetAndName_setAlgiers_returnCentralEuropeanStandardTime() {
+        testTimeZoneOffsetAndNameInner(TIME_ZONE_ALGIERS_ID, "Central European Standard Time");
+    }
+
+    @Test
+    public void getTimeZoneOffsetAndName_setCeuta_returnCentralEuropeanSummerTime() {
+        testTimeZoneOffsetAndNameInner(TIME_ZONE_CEUTA_ID, "Central European Summer Time");
+    }
+
+    @Test
     public void getZonesList_checkTypes() {
         final List<Map<String, Object>> zones =
                 ZoneGetter.getZonesList(InstrumentationRegistry.getContext());
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
index 72ac544..89328ee 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
@@ -417,6 +417,19 @@
         assertThat(ap.getSummary()).isEqualTo(expectedString);
     }
 
+    @Test
+    public void testSummaryString_showsWrongPasswordLabel() {
+        WifiConfiguration configuration = createWifiConfiguration();
+        configuration.getNetworkSelectionStatus().setNetworkSelectionStatus(
+                WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_PERMANENTLY_DISABLED);
+        configuration.getNetworkSelectionStatus().setNetworkSelectionDisableReason(
+                WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD);
+        AccessPoint ap = new AccessPoint(mContext, configuration);
+
+        assertThat(ap.getSummary()).isEqualTo(mContext.getString(
+                R.string.wifi_check_password_try_again));
+    }
+
     private ScoredNetwork buildScoredNetworkWithMockBadgeCurve() {
         Bundle attr1 = new Bundle();
         attr1.putParcelable(ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE, mockBadgeCurve);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TestConfig.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TestConfig.java
index 22fd83c..31abecd 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TestConfig.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TestConfig.java
@@ -19,5 +19,5 @@
 public class TestConfig {
     public static final int SDK_VERSION = 23;
     public static final String MANIFEST_PATH =
-            "frameworks/base/packages/SettingsLib/robotests/AndroidManifest.xml";
+            "frameworks/base/packages/SettingsLib/tests/robotests/AndroidManifest.xml";
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
index 7cfb32d..0364418 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
@@ -16,6 +16,19 @@
 
 package com.android.settingslib.drawer;
 
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.robolectric.RuntimeEnvironment.application;
+
 import android.app.ActivityManager;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -50,8 +63,9 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
 import org.robolectric.internal.ShadowExtractor;
 
 import java.util.ArrayList;
@@ -59,20 +73,6 @@
 import java.util.List;
 import java.util.Map;
 
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-
 @RunWith(RobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH,
         sdk = TestConfig.SDK_VERSION,
@@ -100,8 +100,11 @@
         MockitoAnnotations.initMocks(this);
         when(mContext.getPackageManager()).thenReturn(mPackageManager);
         when(mPackageManager.getResourcesForApplication(anyString())).thenReturn(mResources);
-        mContentResolver = spy(RuntimeEnvironment.application.getContentResolver());
+        when(mPackageManager.getApplicationInfo(eq("abc"), anyInt()))
+                .thenReturn(application.getApplicationInfo());
+        mContentResolver = spy(application.getContentResolver());
         when(mContext.getContentResolver()).thenReturn(mContentResolver);
+        when(mContext.getPackageName()).thenReturn("com.android.settings");
     }
 
     @Test
@@ -118,7 +121,7 @@
 
         TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */,
-                false /* checkCategory */);
+                false /* checkCategory */, true /* forceTintExternalIcon */);
 
         assertThat(outTiles.size()).isEqualTo(1);
         assertThat(outTiles.get(0).category).isEqualTo(testCategory);
@@ -139,7 +142,7 @@
 
         TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */,
-                false /* checkCategory */);
+                false /* checkCategory */, true /* forceTintExternalIcon */);
 
         assertThat(outTiles.size()).isEqualTo(1);
         assertThat(outTiles.get(0).key).isEqualTo(keyHint);
@@ -159,7 +162,7 @@
 
         TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */,
-                false /* checkCategory */);
+                false /* checkCategory */, true /* forceTintExternalIcon */);
 
         assertThat(outTiles.isEmpty()).isTrue();
     }
@@ -182,7 +185,7 @@
 
         TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */,
-                false /* checkCategory */);
+                false /* checkCategory */, true /* forceTintExternalIcon */);
 
         assertThat(outTiles.size()).isEqualTo(1);
         SuggestionParser parser = new SuggestionParser(
@@ -255,7 +258,7 @@
 
         TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */,
-                false /* checkCategory */);
+                false /* checkCategory */, true /* forceTintExternalIcon */);
 
         assertThat(outTiles.size()).isEqualTo(1);
         assertThat(outTiles.get(0).title).isEqualTo("my title");
@@ -279,10 +282,60 @@
 
         TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */,
-                false /* checkCategory */);
+                false /* checkCategory */, true /* forceTintExternalIcon */);
 
         assertThat(outTiles.size()).isEqualTo(1);
         assertThat(outTiles.get(0).title).isEqualTo("my localized title");
+
+        // Icon should be tintable because the tile is not from settings package, and
+        // "forceTintExternalIcon" is set
+        assertThat(outTiles.get(0).isIconTintable).isTrue();
+    }
+
+    @Test
+    public void getTilesForIntent_shouldNotTintIconIfInSettingsPackage() {
+        Intent intent = new Intent();
+        Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
+        List<Tile> outTiles = new ArrayList<>();
+        List<ResolveInfo> info = new ArrayList<>();
+        ResolveInfo resolveInfo = newInfo(true, null /* category */, null, URI_GET_ICON,
+                URI_GET_SUMMARY, null, 123);
+        resolveInfo.activityInfo.packageName = "com.android.settings";
+        resolveInfo.activityInfo.applicationInfo.packageName = "com.android.settings";
+        info.add(resolveInfo);
+
+        when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
+                .thenReturn(info);
+
+        TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
+                null /* defaultCategory */, outTiles, false /* usePriority */,
+                false /* checkCategory */, true /* forceTintExternalIcon */);
+
+        assertThat(outTiles.size()).isEqualTo(1);
+        assertThat(outTiles.get(0).isIconTintable).isFalse();
+    }
+
+    @Test
+    public void getTilesForIntent_shouldMarkIconTintableIfMetadataSet() {
+        Intent intent = new Intent();
+        Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
+        List<Tile> outTiles = new ArrayList<>();
+        List<ResolveInfo> info = new ArrayList<>();
+        ResolveInfo resolveInfo = newInfo(true, null /* category */, null, URI_GET_ICON,
+                URI_GET_SUMMARY, null, 123);
+        resolveInfo.activityInfo.metaData
+                .putBoolean(TileUtils.META_DATA_PREFERENCE_ICON_TINTABLE, true);
+        info.add(resolveInfo);
+
+        when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
+                .thenReturn(info);
+
+        TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
+                null /* defaultCategory */, outTiles, false /* usePriority */,
+                false /* checkCategory */, false /* forceTintExternalIcon */);
+
+        assertThat(outTiles.size()).isEqualTo(1);
+        assertThat(outTiles.get(0).isIconTintable).isTrue();
     }
 
     @Test
@@ -301,7 +354,7 @@
         // Case 1: No provider associated with the uri specified.
         TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */,
-                false /* checkCategory */);
+                false /* checkCategory */, true /* forceTintExternalIcon */);
 
         assertThat(outTiles.size()).isEqualTo(1);
         assertThat(outTiles.get(0).icon.getResId()).isEqualTo(314159);
@@ -319,7 +372,7 @@
 
         TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */,
-                false /* checkCategory */);
+                false /* checkCategory */, true /* forceTintExternalIcon */);
 
         assertThat(outTiles.size()).isEqualTo(1);
         assertThat(outTiles.get(0).icon.getResId()).isEqualTo(314159);
@@ -341,7 +394,7 @@
 
         TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */,
-                false /* checkCategory */);
+                false /* checkCategory */, true /* forceTintExternalIcon */);
 
         assertThat(outTiles.size()).isEqualTo(1);
     }
@@ -362,7 +415,7 @@
 
         TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */,
-                false /* checkCategory */);
+                false /* checkCategory */, true /* forceTintExternalIcon */);
 
         assertThat(outTiles.size()).isEqualTo(1);
         Tile tile = outTiles.get(0);
@@ -399,7 +452,7 @@
 
         TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */,
-                false /* checkCategory */);
+                false /* checkCategory */, true /* forceTintExternalIcon */);
 
         assertThat(outTiles.size()).isEqualTo(1);
         Tile tile = outTiles.get(0);
@@ -437,7 +490,7 @@
 
         TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */,
-                false /* checkCategory */);
+                false /* checkCategory */, true /* forceTintExternalIcon */);
 
         assertThat(outTiles.size()).isEqualTo(1);
         Tile tile = outTiles.get(0);
@@ -484,7 +537,9 @@
         if (summaryUri != null) {
             info.activityInfo.metaData.putString("com.android.settings.summary_uri", summaryUri);
         }
-        if (title != null) {
+        if (titleResId != 0) {
+            info.activityInfo.metaData.putString(TileUtils.META_DATA_PREFERENCE_TITLE, title);
+        } else if (title != null) {
             info.activityInfo.metaData.putString(TileUtils.META_DATA_PREFERENCE_TITLE, title);
         }
         if (titleResId != 0) {
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index 1e171d3..8abdc64 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -37,10 +37,12 @@
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.ArraySet;
+import android.util.Slog;
 
 import java.util.Locale;
 
 public class SettingsHelper {
+    private static final String TAG = "SettingsHelper";
     private static final String SILENT_RINGTONE = "_silent";
     private Context mContext;
     private AudioManager mAudioManager;
@@ -324,11 +326,17 @@
      */
     void setLocaleData(byte[] data, int size) {
         // Check if locale was set by the user:
-        Configuration conf = mContext.getResources().getConfiguration();
-        // TODO: The following is not working as intended because the network is forcing a locale
-        // change after registering. Need to find some other way to detect if the user manually
-        // changed the locale
-        if (conf.userSetLocale) return; // Don't change if user set it in the SetupWizard
+        final ContentResolver cr = mContext.getContentResolver();
+        final boolean userSetLocale = mContext.getResources().getConfiguration().userSetLocale;
+        final boolean provisioned = Settings.Global.getInt(cr,
+                Settings.Global.DEVICE_PROVISIONED, 0) != 0;
+        if (userSetLocale || provisioned) {
+            // Don't change if user set it in the SetupWizard, or if this is a post-setup
+            // deferred restore operation
+            Slog.i(TAG, "Not applying restored locale; "
+                    + (userSetLocale ? "user already specified" : "device already provisioned"));
+            return;
+        }
 
         final String[] availableLocales = mContext.getAssets().getLocales();
         // Replace "_" with "-" to deal with older backups.
diff --git a/packages/Shell/res/layout/dialog_bugreport_info.xml b/packages/Shell/res/layout/dialog_bugreport_info.xml
index bb3084f..4bd8711 100644
--- a/packages/Shell/res/layout/dialog_bugreport_info.xml
+++ b/packages/Shell/res/layout/dialog_bugreport_info.xml
@@ -19,39 +19,51 @@
     android:paddingTop="15dp"
     android:paddingStart="24dp"
     android:paddingEnd="24dp"
-    android:focusableInTouchMode="true"
+    android:focusableInTouchMode="false"
+    android:focusable="false"
+    android:importantForAutofill="noExcludeDescendants"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content">
     <TextView
+        android:focusableInTouchMode="false"
+        android:focusable="false"
         android:inputType="textNoSuggestions"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:text="@string/bugreport_info_name"/>
     <EditText
         android:id="@+id/name"
+        android:nextFocusDown="@+id/title"
         android:maxLength="30"
         android:singleLine="true"
         android:inputType="textNoSuggestions"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"/>
     <TextView
+        android:focusableInTouchMode="false"
+        android:focusable="false"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:text="@string/bugreport_info_title"/>
     <EditText
         android:id="@+id/title"
+        android:nextFocusUp="@+id/name"
+        android:nextFocusDown="@+id/description"
         android:maxLength="80"
         android:singleLine="true"
         android:inputType="textAutoCorrect|textCapSentences"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"/>
     <TextView
+        android:focusableInTouchMode="false"
+        android:focusable="false"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:editable="false"
         android:text="@string/bugreport_info_description"/>
     <EditText
         android:id="@+id/description"
+        android:nextFocusUp="@+id/title"
         android:singleLine="false"
         android:inputType="textMultiLine|textAutoCorrect|textCapSentences"
         android:layout_width="match_parent"
diff --git a/packages/Shell/src/com/android/shell/BugreportWarningActivity.java b/packages/Shell/src/com/android/shell/BugreportWarningActivity.java
index bdf4171..2191d93 100644
--- a/packages/Shell/src/com/android/shell/BugreportWarningActivity.java
+++ b/packages/Shell/src/com/android/shell/BugreportWarningActivity.java
@@ -64,7 +64,7 @@
 
         final int state = getWarningState(this, STATE_UNKNOWN);
         final boolean checked;
-        if (Build.TYPE.equals("user")) {
+        if (Build.IS_USER) {
             checked = state == STATE_HIDE; // Only checks if specifically set to.
         } else {
             checked = state != STATE_SHOW; // Checks by default.
diff --git a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
index 8bfcc74..e69b0a8 100644
--- a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
+++ b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
@@ -577,7 +577,7 @@
                 mUiBot.getVisibleObject(mContext.getString(R.string.bugreport_confirm_dont_repeat));
         final boolean firstTime = propertyState == null || propertyState == STATE_UNKNOWN;
         if (firstTime) {
-            if (Build.TYPE.equals("user")) {
+            if (Build.IS_USER) {
                 assertFalse("Checkbox should NOT be checked by default on user builds",
                         dontShowAgain.isChecked());
                 mUiBot.click(dontShowAgain, "dont-show-again");
diff --git a/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/types/Tonal.java b/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/types/Tonal.java
index 81bc831..f59c4a5 100644
--- a/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/types/Tonal.java
+++ b/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/types/Tonal.java
@@ -29,6 +29,7 @@
 
 import com.google.android.colorextraction.ColorExtractor.GradientColors;
 
+import java.util.Arrays;
 import java.util.List;
 
 /**
@@ -101,7 +102,7 @@
         hsl[0] /= 360f;
 
         // Find the palette that contains the closest color
-        TonalPalette palette = findTonalPalette(hsl[0]);
+        TonalPalette palette = findTonalPalette(hsl[0], hsl[1]);
         if (palette == null) {
             Log.w(TAG, "Could not find a tonal palette!");
             return false;
@@ -251,7 +252,13 @@
     }
 
     @Nullable
-    private static TonalPalette findTonalPalette(float h) {
+    private static TonalPalette findTonalPalette(float h, float s) {
+        // Fallback to a grey palette if the color is too desaturated.
+        // This avoids hue shifts.
+        if (s < 0.05f) {
+            return GREY_PALETTE;
+        }
+
         TonalPalette best = null;
         float error = Float.POSITIVE_INFINITY;
 
@@ -305,6 +312,12 @@
         final float maxHue;
 
         TonalPalette(float[] h, float[] s, float[] l) {
+            if (h.length != s.length || s.length != l.length) {
+                throw new IllegalArgumentException("All arrays should have the same size. h: "
+                        + Arrays.toString(h) + " s: " + Arrays.toString(s) + " l: "
+                        + Arrays.toString(l));
+            }
+
             this.h = h;
             this.s = s;
             this.l = l;
@@ -327,271 +340,280 @@
     // a best fit. Each palette is defined as 22 HSL colors
     private static final TonalPalette[] TONAL_PALETTES = {
             new TonalPalette(
-                    new float[]{0.991f, 0.9833333333333333f, 0f, 0f, 0f, 0.01134380453752181f,
-                            0.015625000000000003f, 0.024193548387096798f, 0.027397260273972573f,
-                            0.017543859649122865f},
-                    new float[]{1f, 1f, 1f, 1f, 0.8434782608695652f, 1f, 1f, 1f, 1f, 1f},
-                    new float[]{0.2f, 0.27450980392156865f, 0.34901960784313724f,
-                            0.4235294117647059f, 0.5490196078431373f, 0.6254901960784314f,
-                            0.6862745098039216f, 0.7568627450980392f, 0.8568627450980393f,
-                            0.9254901960784314f}
+                    new float[] {1f, 1f, 0.991f, 0.991f, 0.9833333333333333f, 0f, 0f, 0f,
+                            0.01134380453752181f, 0.015625000000000003f, 0.024193548387096798f,
+                            0.027397260273972573f, 0.017543859649122865f},
+                    new float[] {1f, 1f, 1f, 1f, 1f, 1f, 1f, 0.8434782608695652f, 1f, 1f, 1f, 1f,
+                            1f},
+                    new float[] {0.04f, 0.09f, 0.14f, 0.2f, 0.27450980392156865f,
+                            0.34901960784313724f, 0.4235294117647059f, 0.5490196078431373f,
+                            0.6254901960784314f, 0.6862745098039216f, 0.7568627450980392f,
+                            0.8568627450980393f, 0.9254901960784314f}
             ),
             new TonalPalette(
-                    new float[]{0.6385767790262171f, 0.6301169590643275f, 0.6223958333333334f,
-                            0.6151079136690647f, 0.6065400843881856f, 0.5986964618249534f,
-                            0.5910746812386157f, 0.5833333333333334f, 0.5748031496062993f,
-                            0.5582010582010583f},
-                    new float[]{1f, 1f, 0.9014084507042253f, 0.8128654970760234f,
-                            0.7979797979797981f, 0.7816593886462883f, 0.778723404255319f,
-                            1f, 1f, 1f},
-                    new float[]{0.17450980392156862f, 0.2235294117647059f, 0.2784313725490196f,
-                            0.3352941176470588f, 0.388235294117647f, 0.44901960784313727f,
-                            0.5392156862745098f, 0.6509803921568628f, 0.7509803921568627f,
-                            0.8764705882352941f}
+                    new float[] {0.638f, 0.638f, 0.6385767790262171f, 0.6301169590643275f,
+                            0.6223958333333334f, 0.6151079136690647f, 0.6065400843881856f,
+                            0.5986964618249534f, 0.5910746812386157f, 0.5833333333333334f,
+                            0.5748031496062993f, 0.5582010582010583f},
+                    new float[] {1f, 1f, 1f, 1f, 0.9014084507042253f, 0.8128654970760234f,
+                            0.7979797979797981f, 0.7816593886462883f, 0.778723404255319f, 1f, 1f,
+                            1f},
+                    new float[] {0.05f, 0.12f, 0.17450980392156862f, 0.2235294117647059f,
+                            0.2784313725490196f, 0.3352941176470588f, 0.388235294117647f,
+                            0.44901960784313727f, 0.5392156862745098f, 0.6509803921568628f,
+                            0.7509803921568627f, 0.8764705882352941f}
             ),
             new TonalPalette(
-                    new float[]{0.5669934640522876f, 0.5748031496062993f,
+                    new float[] {0.563f, 0.569f, 0.5666f, 0.5669934640522876f, 0.5748031496062993f,
                             0.5595238095238095f, 0.5473118279569893f, 0.5393258426966292f,
                             0.5315955766192734f, 0.524031007751938f, 0.5154711673699016f,
                             0.508080808080808f, 0.5f},
-                    new float[]{1f, 1f, 1f, 1f, 1f, 1f, 0.8847736625514403f, 1f, 1f, 1f},
-                    new float[]{0.2f, 0.24901960784313726f, 0.27450980392156865f,
-                            0.30392156862745096f, 0.34901960784313724f, 0.4137254901960784f,
-                            0.47647058823529415f, 0.5352941176470588f, 0.6764705882352942f, 0.8f}
+                    new float[] {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 0.8847736625514403f, 1f, 1f,
+                            1f},
+                    new float[] {0.07f, 0.12f, 0.16f, 0.2f, 0.24901960784313726f,
+                            0.27450980392156865f, 0.30392156862745096f, 0.34901960784313724f,
+                            0.4137254901960784f, 0.47647058823529415f, 0.5352941176470588f,
+                            0.6764705882352942f, 0.8f}
             ),
             new TonalPalette(
-                    new float[]{0.5082304526748972f, 0.5069444444444444f, 0.5f, 0.5f,
-                            0.5f, 0.48724954462659376f, 0.4800347222222222f,
-                            0.4755134281200632f, 0.4724409448818897f, 0.4671052631578947f},
-                    new float[]{1f, 0.8888888888888887f, 0.9242424242424242f, 1f, 1f,
-                            0.8133333333333332f, 0.7868852459016393f, 1f, 1f, 1f},
-                    new float[]{0.1588235294117647f, 0.21176470588235297f,
-                            0.25882352941176473f, 0.3f, 0.34901960784313724f,
+                    new float[] {0.508f, 0.511f, 0.508f, 0.508f, 0.5082304526748972f,
+                            0.5069444444444444f, 0.5f, 0.5f, 0.5f, 0.48724954462659376f,
+                            0.4800347222222222f, 0.4755134281200632f, 0.4724409448818897f,
+                            0.4671052631578947f},
+                    new float[] {1f, 1f, 1f, 1f, 1f, 0.8888888888888887f, 0.9242424242424242f, 1f,
+                            1f, 0.8133333333333332f, 0.7868852459016393f, 1f, 1f, 1f},
+                    new float[] {0.04f, 0.06f, 0.08f, 0.12f, 0.1588235294117647f,
+                            0.21176470588235297f, 0.25882352941176473f, 0.3f, 0.34901960784313724f,
                             0.44117647058823534f, 0.5215686274509804f, 0.5862745098039216f,
                             0.7509803921568627f, 0.8509803921568627f}
             ),
             new TonalPalette(
-                    new float[]{0.3333333333333333f, 0.3333333333333333f,
+                    new float[] {0.333f, 0.333f, 0.333f, 0.3333333333333333f, 0.3333333333333333f,
                             0.34006734006734f, 0.34006734006734f, 0.34006734006734f,
                             0.34259259259259256f, 0.3475783475783476f, 0.34767025089605735f,
                             0.3467741935483871f, 0.3703703703703704f},
-                    new float[]{0.6703296703296703f, 0.728813559322034f,
+                    new float[] {0.70f, 0.72f, 0.69f, 0.6703296703296703f, 0.728813559322034f,
                             0.5657142857142856f, 0.5076923076923077f, 0.3944223107569721f,
                             0.6206896551724138f, 0.8931297709923666f, 1f, 1f, 1f},
-                    new float[]{0.1784313725490196f, 0.23137254901960785f,
+                    new float[] {0.05f, 0.08f, 0.14f, 0.1784313725490196f, 0.23137254901960785f,
                             0.3431372549019608f, 0.38235294117647056f, 0.49215686274509807f,
                             0.6588235294117647f, 0.7431372549019608f, 0.8176470588235294f,
                             0.8784313725490196f, 0.9294117647058824f}
             ),
             new TonalPalette(
-                    new float[]{0.162280701754386f, 0.15032679738562088f,
+                    new float[] {0.161f, 0.163f, 0.163f, 0.162280701754386f, 0.15032679738562088f,
                             0.15879265091863518f, 0.16236559139784948f, 0.17443868739205526f,
-                            0.17824074074074076f, 0.18674698795180725f,
-                            0.18692449355432778f, 0.1946778711484594f, 0.18604651162790695f},
-                    new float[]{1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f},
-                    new float[]{0.14901960784313725f, 0.2f, 0.24901960784313726f,
-                            0.30392156862745096f, 0.3784313725490196f, 0.4235294117647059f,
-                            0.48823529411764705f, 0.6450980392156863f, 0.7666666666666666f,
-                            0.8313725490196078f}
+                            0.17824074074074076f, 0.18674698795180725f, 0.18692449355432778f,
+                            0.1946778711484594f, 0.18604651162790695f},
+                    new float[] {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f},
+                    new float[] {0.05f, 0.08f, 0.11f, 0.14901960784313725f, 0.2f,
+                            0.24901960784313726f, 0.30392156862745096f, 0.3784313725490196f,
+                            0.4235294117647059f, 0.48823529411764705f, 0.6450980392156863f,
+                            0.7666666666666666f, 0.8313725490196078f}
             ),
             new TonalPalette(
-                    new float[]{0.10619469026548674f, 0.11924686192468618f,
-                            0.13046448087431692f, 0.14248366013071895f, 0.1506024096385542f,
-                            0.16220238095238093f, 0.16666666666666666f,
+                    new float[] {0.108f, 0.105f, 0.105f, 0.105f, 0.10619469026548674f,
+                            0.11924686192468618f, 0.13046448087431692f, 0.14248366013071895f,
+                            0.1506024096385542f, 0.16220238095238093f, 0.16666666666666666f,
                             0.16666666666666666f, 0.162280701754386f, 0.15686274509803924f},
-                    new float[]{1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f},
-                    new float[]{0.44313725490196076f, 0.46862745098039216f,
-                            0.47843137254901963f, 0.5f, 0.5117647058823529f,
+                    new float[] {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f},
+                    new float[] {0.17f, 0.22f, 0.28f, 0.35f, 0.44313725490196076f,
+                            0.46862745098039216f, 0.47843137254901963f, 0.5f, 0.5117647058823529f,
                             0.5607843137254902f, 0.6509803921568628f, 0.7509803921568627f,
                             0.8509803921568627f, 0.9f}
             ),
             new TonalPalette(
-                    new float[]{0.03561253561253561f, 0.05098039215686275f,
-                            0.07516339869281045f, 0.09477124183006536f, 0.1150326797385621f,
-                            0.134640522875817f, 0.14640522875816991f, 0.1582397003745319f,
-                            0.15773809523809523f, 0.15359477124183002f},
-                    new float[]{1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f},
-                    new float[]{0.4588235294117647f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
-                            0.5f, 0.6509803921568628f, 0.7803921568627451f, 0.9f}
+                    new float[] {0.036f, 0.036f, 0.036f, 0.036f, 0.03561253561253561f,
+                            0.05098039215686275f, 0.07516339869281045f, 0.09477124183006536f,
+                            0.1150326797385621f, 0.134640522875817f, 0.14640522875816991f,
+                            0.1582397003745319f, 0.15773809523809523f, 0.15359477124183002f},
+                    new float[] {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f},
+                    new float[] {0.19f, 0.26f, 0.34f, 0.39f, 0.4588235294117647f, 0.5f, 0.5f, 0.5f,
+                            0.5f, 0.5f, 0.5f, 0.6509803921568628f, 0.7803921568627451f, 0.9f}
             ),
             new TonalPalette(
-                    new float[]{0.9596491228070175f, 0.9593837535014005f,
+                    new float[] {0.955f, 0.961f, 0.958f, 0.9596491228070175f, 0.9593837535014005f,
                             0.9514767932489452f, 0.943859649122807f, 0.9396825396825397f,
                             0.9395424836601307f, 0.9393939393939394f, 0.9362745098039216f,
                             0.9754098360655739f, 0.9824561403508771f},
-                    new float[]{0.84070796460177f, 0.8206896551724138f,
+                    new float[] {0.87f, 0.85f, 0.85f, 0.84070796460177f, 0.8206896551724138f,
                             0.7979797979797981f, 0.7661290322580644f, 0.9051724137931036f,
                             1f, 1f, 1f, 1f, 1f},
-                    new float[]{0.22156862745098038f, 0.2843137254901961f,
+                    new float[] {0.06f, 0.11f, 0.16f, 0.22156862745098038f, 0.2843137254901961f,
                             0.388235294117647f, 0.48627450980392156f, 0.5450980392156863f,
                             0.6f, 0.6764705882352942f, 0.8f, 0.8803921568627451f,
                             0.9254901960784314f}
             ),
             new TonalPalette(
-                    new float[]{0.841025641025641f, 0.8333333333333334f,
+                    new float[] {0.866f, 0.855f, 0.841025641025641f, 0.8333333333333334f,
                             0.8285256410256411f, 0.821522309711286f, 0.8083333333333333f,
                             0.8046594982078853f, 0.8005822416302766f, 0.7842377260981912f,
                             0.7771084337349398f, 0.7747747747747749f},
-                    new float[]{1f, 1f, 1f, 1f, 1f, 1f, 1f,
+                    new float[] {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f,
                             0.737142857142857f, 0.6434108527131781f, 0.46835443037974644f},
-                    new float[]{0.12745098039215685f, 0.15490196078431373f,
+                    new float[] {0.05f, 0.08f, 0.12745098039215685f, 0.15490196078431373f,
                             0.20392156862745098f, 0.24901960784313726f, 0.3137254901960784f,
-                            0.36470588235294116f, 0.44901960784313727f,
-                            0.6568627450980392f, 0.7470588235294118f, 0.8450980392156863f}
+                            0.36470588235294116f, 0.44901960784313727f, 0.6568627450980392f,
+                            0.7470588235294118f, 0.8450980392156863f}
             ),
             new TonalPalette(
-                    new float[]{0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f},
-                    new float[]{0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f},
-                    new float[]{0.14901960784313725f, 0.2f, 0.2980392156862745f, 0.4f,
-                            0.4980392156862745f, 0.6196078431372549f, 0.7176470588235294f,
-                            0.8196078431372549f, 0.9176470588235294f, 0.9490196078431372f}
-            ),
-            new TonalPalette(
-                    new float[]{0.955952380952381f, 0.9681069958847737f,
-                            0.9760479041916167f, 0.9873563218390804f, 0f, 0f,
+                    new float[] {0.925f, 0.93f, 0.938f, 0.947f, 0.955952380952381f,
+                            0.9681069958847737f, 0.9760479041916167f, 0.9873563218390804f, 0f, 0f,
                             0.009057971014492771f, 0.026748971193415648f,
                             0.041666666666666616f, 0.05303030303030304f},
-                    new float[]{1f, 0.8350515463917526f, 0.6929460580912863f,
+                    new float[] {1f, 1f, 1f, 1f, 1f, 0.8350515463917526f, 0.6929460580912863f,
                             0.6387665198237885f, 0.6914893617021276f, 0.7583892617449666f,
                             0.8070175438596495f, 0.9310344827586209f, 1f, 1f},
-                    new float[]{0.27450980392156865f, 0.3803921568627451f,
-                            0.4725490196078432f, 0.5549019607843138f, 0.6313725490196078f,
-                            0.707843137254902f, 0.7764705882352941f, 0.8294117647058823f,
-                            0.9058823529411765f, 0.9568627450980391f}
+                    new float[] {0.10f, 0.13f, 0.17f, 0.2f, 0.27450980392156865f,
+                            0.3803921568627451f, 0.4725490196078432f, 0.5549019607843138f,
+                            0.6313725490196078f, 0.707843137254902f, 0.7764705882352941f,
+                            0.8294117647058823f, 0.9058823529411765f, 0.9568627450980391f}
             ),
             new TonalPalette(
-                    new float[]{0.7514619883040936f, 0.7679738562091503f,
+                    new float[] {0.733f, 0.736f, 0.744f, 0.7514619883040936f, 0.7679738562091503f,
                             0.7802083333333333f, 0.7844311377245509f, 0.796875f,
                             0.8165618448637316f, 0.8487179487179487f, 0.8582375478927203f,
                             0.8562091503267975f, 0.8666666666666667f},
-                    new float[]{1f, 1f, 0.8163265306122449f, 0.6653386454183268f,
+                    new float[] {1f, 1f, 1f, 1f, 1f, 0.8163265306122449f, 0.6653386454183268f,
                             0.7547169811320753f, 0.929824561403509f, 0.9558823529411766f,
                             0.9560439560439562f, 1f, 1f},
-                    new float[]{0.2235294117647059f, 0.3f, 0.38431372549019605f,
-                            0.492156862745098f, 0.5843137254901961f, 0.6647058823529411f,
-                            0.7333333333333334f, 0.8215686274509804f, 0.9f,
+                    new float[] {0.07f, 0.12f, 0.17f, 0.2235294117647059f, 0.3f,
+                            0.38431372549019605f, 0.492156862745098f, 0.5843137254901961f,
+                            0.6647058823529411f, 0.7333333333333334f, 0.8215686274509804f, 0.9f,
                             0.9411764705882353f}
             ),
             new TonalPalette(
-                    new float[]{0.6666666666666666f, 0.6666666666666666f,
+                    new float[] {0.6666666666666666f, 0.6666666666666666f, 0.6666666666666666f,
                             0.6666666666666666f, 0.6666666666666666f, 0.6666666666666666f,
                             0.6666666666666666f, 0.6666666666666666f, 0.6666666666666666f,
                             0.6666666666666666f, 0.6666666666666666f},
-                    new float[]{0.24590163934426232f, 0.17880794701986752f,
+                    new float[] {0.25f, 0.24590163934426232f, 0.17880794701986752f,
                             0.14606741573033713f, 0.13761467889908252f, 0.14893617021276592f,
-                            0.16756756756756758f, 0.20312500000000017f,
-                            0.26086956521739135f, 0.29999999999999966f, 0.5000000000000004f},
-                    new float[]{0.2392156862745098f, 0.296078431372549f,
+                            0.16756756756756758f, 0.20312500000000017f, 0.26086956521739135f,
+                            0.29999999999999966f, 0.5000000000000004f},
+                    new float[] {0.18f, 0.2392156862745098f, 0.296078431372549f,
                             0.34901960784313724f, 0.4274509803921569f, 0.5392156862745098f,
                             0.6372549019607843f, 0.7490196078431373f, 0.8196078431372549f,
                             0.8823529411764706f, 0.9372549019607843f}
             ),
             new TonalPalette(
-                    new float[]{0.9678571428571429f, 0.9944812362030905f, 0f, 0f,
+                    new float[] {0.938f, 0.944f, 0.952f, 0.961f, 0.9678571428571429f,
+                            0.9944812362030905f, 0f, 0f,
                             0.0047348484848484815f, 0.00316455696202532f, 0f,
                             0.9980392156862745f, 0.9814814814814816f, 0.9722222222222221f},
-                    new float[]{1f, 0.7023255813953488f, 0.6638655462184874f,
+                    new float[] {1f, 1f, 1f, 1f, 1f, 0.7023255813953488f, 0.6638655462184874f,
                             0.6521739130434782f, 0.7719298245614035f, 0.8315789473684211f,
                             0.6867469879518071f, 0.7264957264957265f, 0.8181818181818182f,
                             0.8181818181818189f},
-                    new float[]{0.27450980392156865f, 0.4215686274509804f,
+                    new float[] {0.08f, 0.13f, 0.18f, 0.23f, 0.27450980392156865f,
+                            0.4215686274509804f,
                             0.4666666666666667f, 0.503921568627451f, 0.5529411764705883f,
                             0.6274509803921569f, 0.6745098039215687f, 0.7705882352941176f,
                             0.892156862745098f, 0.9568627450980391f}
             ),
             new TonalPalette(
-                    new float[]{0.9052287581699346f, 0.9112021857923498f, 0.9270152505446624f,
-                            0.9343137254901961f, 0.9391534391534391f, 0.9437984496124031f,
-                            0.943661971830986f, 0.9438943894389439f, 0.9426229508196722f,
-                            0.9444444444444444f},
-                    new float[]{1f, 0.8133333333333332f, 0.7927461139896375f, 0.7798165137614679f,
-                            0.7777777777777779f, 0.8190476190476191f, 0.8255813953488372f,
-                            0.8211382113821142f, 0.8133333333333336f, 0.8000000000000006f},
-                    new float[]{0.2f, 0.29411764705882354f, 0.3784313725490196f,
-                            0.42745098039215684f, 0.4764705882352941f, 0.5882352941176471f,
-                            0.6627450980392157f, 0.7588235294117647f, 0.8529411764705882f,
-                            0.9411764705882353f}
+                    new float[] {0.88f, 0.888f, 0.897f, 0.9052287581699346f, 0.9112021857923498f,
+                            0.9270152505446624f, 0.9343137254901961f, 0.9391534391534391f,
+                            0.9437984496124031f, 0.943661971830986f, 0.9438943894389439f,
+                            0.9426229508196722f, 0.9444444444444444f},
+                    new float[] {1f, 1f, 1f, 1f, 0.8133333333333332f, 0.7927461139896375f,
+                            0.7798165137614679f, 0.7777777777777779f, 0.8190476190476191f,
+                            0.8255813953488372f, 0.8211382113821142f, 0.8133333333333336f,
+                            0.8000000000000006f},
+                    new float[] {0.08f, 0.12f, 0.16f, 0.2f, 0.29411764705882354f,
+                            0.3784313725490196f, 0.42745098039215684f, 0.4764705882352941f,
+                            0.5882352941176471f, 0.6627450980392157f, 0.7588235294117647f,
+                            0.8529411764705882f, 0.9411764705882353f}
             ),
             new TonalPalette(
-                    new float[]{0.6884057971014492f, 0.6974789915966387f, 0.7079889807162534f,
-                            0.7154471544715447f, 0.7217741935483872f, 0.7274143302180687f,
-                            0.7272727272727273f, 0.7258064516129031f, 0.7252252252252251f,
-                            0.7333333333333333f},
-                    new float[]{0.8214285714285715f, 0.6878612716763006f, 0.6080402010050251f,
-                            0.5774647887323943f, 0.5391304347826086f, 0.46724890829694316f,
-                            0.4680851063829788f, 0.462686567164179f, 0.45679012345678977f,
-                            0.4545454545454551f},
-                    new float[]{0.2196078431372549f, 0.33921568627450976f, 0.39019607843137255f,
-                            0.4176470588235294f, 0.45098039215686275f,
+                    new float[] {0.669f, 0.680f, 0.6884057971014492f, 0.6974789915966387f,
+                            0.7079889807162534f, 0.7154471544715447f, 0.7217741935483872f,
+                            0.7274143302180687f, 0.7272727272727273f, 0.7258064516129031f,
+                            0.7252252252252251f, 0.7333333333333333f},
+                    new float[] {0.81f, 0.81f, 0.8214285714285715f, 0.6878612716763006f,
+                            0.6080402010050251f, 0.5774647887323943f, 0.5391304347826086f,
+                            0.46724890829694316f, 0.4680851063829788f, 0.462686567164179f,
+                            0.45679012345678977f, 0.4545454545454551f},
+                    new float[] {0.12f, 0.16f, 0.2196078431372549f, 0.33921568627450976f,
+                            0.39019607843137255f, 0.4176470588235294f, 0.45098039215686275f,
                             0.5509803921568628f, 0.6313725490196078f, 0.7372549019607844f,
                             0.8411764705882353f, 0.9352941176470588f}
             ),
             new TonalPalette(
-                    new float[]{0.6470588235294118f, 0.6516666666666667f, 0.6464174454828661f,
+                    new float[] {0.6470588235294118f, 0.6516666666666667f, 0.6464174454828661f,
                             0.6441441441441442f, 0.6432748538011696f, 0.6416666666666667f,
                             0.6402439024390243f, 0.6412429378531074f, 0.6435185185185186f,
                             0.6428571428571429f},
-                    new float[]{0.8095238095238095f, 0.6578947368421053f, 0.5721925133689839f,
+                    new float[] {0.8095238095238095f, 0.6578947368421053f, 0.5721925133689839f,
                             0.5362318840579711f, 0.5f, 0.4424778761061947f, 0.44086021505376327f,
-                            0.44360902255639095f,
-                            0.4499999999999997f, 0.4375000000000006f},
-                    new float[]{0.16470588235294117f, 0.2980392156862745f, 0.36666666666666664f,
+                            0.44360902255639095f, 0.4499999999999997f, 0.4375000000000006f},
+                    new float[] {0.16470588235294117f, 0.2980392156862745f, 0.36666666666666664f,
                             0.40588235294117647f, 0.44705882352941173f,
                             0.5568627450980392f, 0.6352941176470588f, 0.7392156862745098f,
                             0.8431372549019608f, 0.9372549019607843f}
             ),
             new TonalPalette(
-                    new float[]{0.46732026143790845f, 0.4718614718614719f, 0.4793650793650794f,
-                            0.48071625344352614f, 0.4829683698296837f, 0.484375f,
-                            0.4841269841269842f, 0.48444444444444457f, 0.48518518518518516f,
-                            0.4907407407407408f},
-                    new float[]{1f, 1f, 1f, 1f, 1f, 0.6274509803921569f, 0.41832669322709176f,
-                            0.41899441340782106f, 0.4128440366972478f,
-                            0.4090909090909088f},
-                    new float[]{0.1f, 0.15098039215686274f, 0.20588235294117646f,
+                    new float[] {0.469f, 0.46732026143790845f, 0.4718614718614719f,
+                            0.4793650793650794f, 0.48071625344352614f, 0.4829683698296837f,
+                            0.484375f, 0.4841269841269842f, 0.48444444444444457f,
+                            0.48518518518518516f, 0.4907407407407408f},
+                    new float[] {1f, 1f, 1f, 1f, 1f, 1f, 0.6274509803921569f, 0.41832669322709176f,
+                            0.41899441340782106f, 0.4128440366972478f, 0.4090909090909088f},
+                    new float[] {0.07f, 0.1f, 0.15098039215686274f, 0.20588235294117646f,
                             0.2372549019607843f, 0.26862745098039215f, 0.4f, 0.5078431372549019f,
                             0.6490196078431372f, 0.7862745098039216f, 0.9137254901960784f}
             ),
             new TonalPalette(
-                    new float[]{0.5444444444444444f, 0.5555555555555556f, 0.5555555555555556f,
-                            0.553763440860215f, 0.5526315789473684f, 0.5555555555555556f,
-                            0.5555555555555555f, 0.5555555555555556f, 0.5512820512820514f,
-                            0.5666666666666667f},
-                    new float[]{0.24590163934426232f, 0.19148936170212766f, 0.1791044776119403f,
-                            0.18343195266272191f, 0.18446601941747576f,
+                    new float[] {0.542f, 0.5444444444444444f, 0.5555555555555556f,
+                            0.5555555555555556f, 0.553763440860215f, 0.5526315789473684f,
+                            0.5555555555555556f, 0.5555555555555555f, 0.5555555555555556f,
+                            0.5512820512820514f, 0.5666666666666667f},
+                    new float[] {0.25f, 0.24590163934426232f, 0.19148936170212766f,
+                            0.1791044776119403f, 0.18343195266272191f, 0.18446601941747576f,
                             0.1538461538461539f, 0.15625000000000003f, 0.15328467153284678f,
                             0.15662650602409653f, 0.151515151515151f},
-                    new float[]{0.1196078431372549f, 0.1843137254901961f, 0.2627450980392157f,
+                    new float[] {0.05f, 0.1196078431372549f, 0.1843137254901961f,
+                            0.2627450980392157f,
                             0.33137254901960783f, 0.403921568627451f, 0.5411764705882354f,
                             0.6235294117647059f, 0.7313725490196079f, 0.8372549019607843f,
                             0.9352941176470588f}
             ),
             new TonalPalette(
-                    new float[]{0.022222222222222223f, 0.02469135802469136f, 0.031249999999999997f,
+                    new float[] {0.022222222222222223f, 0.02469135802469136f, 0.031249999999999997f,
                             0.03947368421052631f, 0.04166666666666668f,
                             0.043650793650793655f, 0.04411764705882352f, 0.04166666666666652f,
                             0.04444444444444459f, 0.05555555555555529f},
-                    new float[]{0.33333333333333337f, 0.2783505154639175f, 0.2580645161290323f,
+                    new float[] {0.33333333333333337f, 0.2783505154639175f, 0.2580645161290323f,
                             0.25675675675675674f, 0.2528735632183908f, 0.17500000000000002f,
                             0.15315315315315312f, 0.15189873417721522f,
                             0.15789473684210534f, 0.15789473684210542f},
-                    new float[]{0.08823529411764705f, 0.19019607843137254f, 0.2431372549019608f,
+                    new float[] {0.08823529411764705f, 0.19019607843137254f, 0.2431372549019608f,
                             0.2901960784313725f, 0.3411764705882353f, 0.47058823529411764f,
                             0.5647058823529412f, 0.6901960784313725f, 0.8137254901960784f,
                             0.9254901960784314f}
             ),
             new TonalPalette(
-                    new float[]{0.050884955752212385f, 0.07254901960784313f, 0.0934640522875817f,
+                    new float[] {0.027f, 0.03f, 0.038f, 0.044f, 0.050884955752212385f,
+                            0.07254901960784313f, 0.0934640522875817f,
                             0.10457516339869281f, 0.11699346405228758f,
                             0.1255813953488372f, 0.1268939393939394f, 0.12533333333333332f,
                             0.12500000000000003f, 0.12777777777777777f},
-                    new float[]{1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f},
-                    new float[]{0.44313725490196076f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5784313725490196f,
+                    new float[] {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f},
+                    new float[] {0.25f, 0.3f, 0.35f, 0.4f, 0.44313725490196076f, 0.5f, 0.5f, 0.5f,
+                            0.5f, 0.5784313725490196f,
                             0.6549019607843137f, 0.7549019607843137f, 0.8509803921568627f,
                             0.9411764705882353f}
             )
     };
 
+    private static final TonalPalette GREY_PALETTE = new TonalPalette(
+            new float[]{0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f},
+            new float[]{0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f},
+            new float[]{0.08f, 0.11f, 0.14901960784313725f, 0.2f, 0.2980392156862745f, 0.4f,
+                    0.4980392156862745f, 0.6196078431372549f, 0.7176470588235294f,
+                    0.8196078431372549f, 0.9176470588235294f, 0.9490196078431372f}
+    );
+
     @SuppressWarnings("WeakerAccess")
     @VisibleForTesting
     static final ColorRange[] BLACKLISTED_COLORS = new ColorRange[] {
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginActivity.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginActivity.java
new file mode 100644
index 0000000..925214e
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginActivity.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.plugins;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.Bundle;
+
+import com.android.systemui.plugins.annotations.ProvidesInterface;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * A PluginActivity is an activity that replaces another full activity (e.g. RecentsActivity)
+ * at runtime within the sysui process.
+ */
+@ProvidesInterface(version = PluginActivity.VERSION)
+public abstract class PluginActivity extends Activity implements Plugin {
+
+    public static final int VERSION = 1;
+
+    public static final String ACTION_RECENTS = "com.android.systemui.action.PLUGIN_RECENTS";
+
+    private Context mSysuiContext;
+    private boolean mSettingActionBar;
+
+    @Override
+    public final void onCreate(Context sysuiContext, Context pluginContext) {
+        mSysuiContext = sysuiContext;
+        super.attachBaseContext(pluginContext);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Theme theme = getClass().getDeclaredAnnotation(Theme.class);
+        if (theme != null && theme.value() != 0) {
+            setTheme(theme.value());
+        }
+        mSettingActionBar = true;
+        getActionBar();
+        mSettingActionBar = false;
+    }
+
+    @Override
+    public Resources getResources() {
+        return mSettingActionBar ? mSysuiContext.getResources() : super.getResources();
+    }
+
+    @Override
+    protected void attachBaseContext(Context newBase) {
+        mSysuiContext = newBase;
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+    }
+
+    public Context getSysuiContext() {
+        return mSysuiContext;
+    }
+
+    public Context getPluginContext() {
+        return getBaseContext();
+    }
+
+    /**
+     * Since PluginActivities are declared as services instead of activities (since they
+     * are plugins), they can't have a theme attached to them. Instead a PluginActivity
+     * can annotate itself with @Theme to specify the resource of the style it wants
+     * to be themed with.
+     */
+    @Retention(RetentionPolicy.RUNTIME)
+    public @interface Theme {
+        int value();
+    }
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginDependency.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginDependency.java
index 25ce3dd..db2e376 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginDependency.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginDependency.java
@@ -21,6 +21,11 @@
     public static final int VERSION = 1;
     static DependencyProvider sProvider;
 
+    /**
+     * Allows a plugin to get a hold of static dependencies if they have declared dependence
+     * on their interface. For one-shot plugins this will only work during onCreate and will
+     * not work afterwards.
+     */
     public static <T> T get(Plugin p, Class<T> cls) {
         return sProvider.get(p, cls);
     }
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationSwipeActionHelper.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationSwipeActionHelper.java
index 3cd5d89..f6cf035 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationSwipeActionHelper.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationSwipeActionHelper.java
@@ -22,6 +22,7 @@
 import android.service.notification.StatusBarNotification;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
 
 @ProvidesInterface(version = NotificationSwipeActionHelper.VERSION)
 @DependsOn(target = SnoozeOption.class)
@@ -56,19 +57,17 @@
     public boolean swipedFastEnough(float translation, float velocity);
 
     @ProvidesInterface(version = SnoozeOption.VERSION)
-    public static class SnoozeOption {
-        public static final int VERSION = 1;
-        public int snoozeForMinutes;
-        public SnoozeCriterion criterion;
-        public CharSequence description;
-        public CharSequence confirmation;
+    public interface SnoozeOption {
+        public static final int VERSION = 2;
 
-        public SnoozeOption(SnoozeCriterion crit, int minsToSnoozeFor, CharSequence desc,
-                CharSequence confirm) {
-            criterion = crit;
-            snoozeForMinutes = minsToSnoozeFor;
-            description = desc;
-            confirmation = confirm;
-        }
+        public SnoozeCriterion getSnoozeCriterion();
+
+        public CharSequence getDescription();
+
+        public CharSequence getConfirmation();
+
+        public int getMinutesToSnoozeFor();
+
+        public AccessibilityAction getAccessibilityAction();
     }
 }
diff --git a/packages/SystemUI/res/color/qs_background_dark.xml b/packages/SystemUI/res/color/qs_background_dark.xml
index 1aa732f..62e4959 100644
--- a/packages/SystemUI/res/color/qs_background_dark.xml
+++ b/packages/SystemUI/res/color/qs_background_dark.xml
@@ -16,5 +16,5 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:alpha="0.93"
-          android:color="?android:attr/colorPrimaryDark"/>
+          android:color="?android:attr/colorBackgroundFloating"/>
 </selector>
diff --git a/packages/SystemUI/res/drawable/ic_brightness_thumb.xml b/packages/SystemUI/res/drawable/ic_brightness_thumb.xml
index 604e918..beedcbb 100644
--- a/packages/SystemUI/res/drawable/ic_brightness_thumb.xml
+++ b/packages/SystemUI/res/drawable/ic_brightness_thumb.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2014 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -22,6 +22,6 @@
         android:pathData="m18.250000,12.000000a6.250000,6.250000 0.000000,1.000000 1.000000,-12.500000 0.000000,6.250000 6.250000,0.000000 1.000000,1.000000 12.500000,0.000000z"
         android:fillColor="?android:attr/colorPrimary" />
     <path
-        android:fillColor="?android:attr/colorControlNormal"
-        android:pathData="M20.000000,8.700000L20.000000,4.000000L15.300000,4.000000L12.000000,0.700000 8.700000,4.000000L4.000000,4.000000L4.000000,8.700000L0.700000,12.000000 4.000000,15.300000L4.000000,20.000000L8.700000,20.000000L12.000000,23.299999 15.300000,20.000000L20.000000,20.000000L20.000000,15.300000L23.299999,12.000000 20.000000,8.700000zM12.000000,18.000000C8.700000,18.000000 6.000000,15.300000 6.000000,12.000000 6.000000,8.700000 8.700000,6.000000 12.000000,6.000000c3.300000,0.000000 6.000000,2.700000 6.000000,6.000000 0.000000,3.300000 -2.700000,6.000000 -6.000000,6.000000zM12.000000,8.000000c-2.200000,0.000000 -4.000000,1.800000 -4.000000,4.000000 0.000000,2.200000 1.800000,4.000000 4.000000,4.000000 2.200000,0.000000 4.000000,-1.800000 4.000000,-4.000000 0.000000,-2.200000 -1.800000,-4.000000 -4.000000,-4.000000z"/>
+        android:pathData="M20,8.69L20,5c0,-0.55 -0.45,-1 -1,-1h-3.69l-2.6,-2.6a0.996,0.996 0,0 0,-1.41 0L8.69,4L5,4c-0.55,0 -1,0.45 -1,1v3.69l-2.6,2.6a0.996,0.996 0,0 0,0 1.41L4,15.3L4,19c0,0.55 0.45,1 1,1h3.69l2.6,2.6c0.39,0.39 1.02,0.39 1.41,0l2.6,-2.6L19,20c0.55,0 1,-0.45 1,-1v-3.69l2.6,-2.6a0.996,0.996 0,0 0,0 -1.41L20,8.69zM12,18.08c-3.36,0 -6.08,-2.73 -6.08,-6.08S8.64,5.92 12,5.92s6.08,2.73 6.08,6.08 -2.72,6.08 -6.08,6.08zM12,8c-2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4 -1.79,-4 -4,-4z"
+        android:fillColor="?android:attr/colorControlNormal" />
 </vector>
diff --git a/packages/SystemUI/res/drawable/pip_icon.xml b/packages/SystemUI/res/drawable/pip_icon.xml
new file mode 100644
index 0000000..bd92ccd
--- /dev/null
+++ b/packages/SystemUI/res/drawable/pip_icon.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2017 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="36dp"
+    android:height="36dp"
+    android:viewportWidth="25"
+    android:viewportHeight="25">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M19,7h-8v6h8L19,7zM21,3L3,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,1.98 2,1.98h18c1.1,0 2,-0.88 2,-1.98L23,5c0,-1.1 -0.9,-2 -2,-2zM21,19.01L3,19.01L3,4.98h18v14.03z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/qs_background_primary.xml b/packages/SystemUI/res/drawable/qs_background_primary.xml
index 4165830..03bba53 100644
--- a/packages/SystemUI/res/drawable/qs_background_primary.xml
+++ b/packages/SystemUI/res/drawable/qs_background_primary.xml
@@ -15,6 +15,6 @@
 -->
 <inset xmlns:android="http://schemas.android.com/apk/res/android">
     <shape>
-        <solid android:color="?android:attr/colorBackgroundFloating"/>
+        <solid android:color="@color/qs_background_dark"/>
     </shape>
 </inset>
diff --git a/packages/SystemUI/res/layout/back.xml b/packages/SystemUI/res/layout/back.xml
index 4e8726b..43bec91 100644
--- a/packages/SystemUI/res/layout/back.xml
+++ b/packages/SystemUI/res/layout/back.xml
@@ -22,8 +22,10 @@
     android:layout_height="match_parent"
     android:layout_weight="0"
     systemui:keyCode="4"
-    android:scaleType="center"
+    android:scaleType="fitCenter"
     android:contentDescription="@string/accessibility_back"
+    android:paddingTop="15dp"
+    android:paddingBottom="15dp"
     android:paddingStart="@dimen/navigation_key_padding"
     android:paddingEnd="@dimen/navigation_key_padding"
     />
diff --git a/packages/SystemUI/res/layout/home.xml b/packages/SystemUI/res/layout/home.xml
index 9586327..53ef2ab 100644
--- a/packages/SystemUI/res/layout/home.xml
+++ b/packages/SystemUI/res/layout/home.xml
@@ -21,8 +21,10 @@
     android:layout_height="match_parent"
     android:layout_weight="0"
     systemui:keyCode="3"
-    android:scaleType="center"
+    android:scaleType="fitCenter"
     android:contentDescription="@string/accessibility_home"
+    android:paddingTop="13dp"
+    android:paddingBottom="13dp"
     android:paddingStart="@dimen/navigation_key_padding"
     android:paddingEnd="@dimen/navigation_key_padding"
     />
diff --git a/packages/SystemUI/res/layout/navigation_layout.xml b/packages/SystemUI/res/layout/navigation_layout.xml
index 2bf4d9c..a621c7c 100644
--- a/packages/SystemUI/res/layout/navigation_layout.xml
+++ b/packages/SystemUI/res/layout/navigation_layout.xml
@@ -18,7 +18,11 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:layout_marginStart="@dimen/rounded_corner_content_padding"
+    android:layout_marginEnd="@dimen/rounded_corner_content_padding"
+    android:paddingStart="8dp"
+    android:paddingEnd="8dp">
 
     <FrameLayout
         android:id="@+id/nav_buttons"
diff --git a/packages/SystemUI/res/layout/navigation_layout_rot90.xml b/packages/SystemUI/res/layout/navigation_layout_rot90.xml
index 7601efc..bf48c7f 100644
--- a/packages/SystemUI/res/layout/navigation_layout_rot90.xml
+++ b/packages/SystemUI/res/layout/navigation_layout_rot90.xml
@@ -18,7 +18,11 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:layout_marginTop="@dimen/rounded_corner_content_padding"
+    android:layout_marginBottom="@dimen/rounded_corner_content_padding"
+    android:paddingTop="8dp"
+    android:paddingBottom="8dp">
 
     <FrameLayout
         android:id="@+id/nav_buttons"
diff --git a/packages/SystemUI/res/layout/notification_snooze.xml b/packages/SystemUI/res/layout/notification_snooze.xml
index b70f24b..3209f27 100644
--- a/packages/SystemUI/res/layout/notification_snooze.xml
+++ b/packages/SystemUI/res/layout/notification_snooze.xml
@@ -20,12 +20,13 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:orientation="vertical"
+    android:clickable="true"
     android:background="@color/notification_guts_bg_color"
     android:theme="@*android:style/Theme.DeviceDefault.Light">
 
     <RelativeLayout
-        android:layout_width="match_parent"
         android:id="@+id/notification_snooze"
+        android:layout_width="match_parent"
         android:layout_height="@dimen/snooze_snackbar_min_height">
 
         <TextView
diff --git a/packages/SystemUI/res/layout/recent_apps.xml b/packages/SystemUI/res/layout/recent_apps.xml
index 870bcf7..c84d280 100644
--- a/packages/SystemUI/res/layout/recent_apps.xml
+++ b/packages/SystemUI/res/layout/recent_apps.xml
@@ -21,8 +21,10 @@
     android:layout_width="@dimen/navigation_key_width"
     android:layout_height="match_parent"
     android:layout_weight="0"
-    android:scaleType="center"
+    android:scaleType="fitCenter"
     android:contentDescription="@string/accessibility_recent"
+    android:paddingTop="15dp"
+    android:paddingBottom="15dp"
     android:paddingStart="@dimen/navigation_key_padding"
     android:paddingEnd="@dimen/navigation_key_padding"
     />
diff --git a/packages/SystemUI/res/layout/recents_empty.xml b/packages/SystemUI/res/layout/recents_empty.xml
index 53d9cc5..8048c68 100644
--- a/packages/SystemUI/res/layout/recents_empty.xml
+++ b/packages/SystemUI/res/layout/recents_empty.xml
@@ -23,7 +23,8 @@
     android:drawableTop="@drawable/recents_empty"
     android:drawablePadding="25dp"
     android:textSize="16sp"
-    android:textColor="#ffffffff"
+    android:drawableTint="?attr/bgProtectTextColor"
+    android:textColor="?attr/bgProtectTextColor"
     android:text="@string/recents_empty_message"
     android:fontFamily="sans-serif"
     android:visibility="gone" />
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/recents_stack_action_button.xml b/packages/SystemUI/res/layout/recents_stack_action_button.xml
index 34b4e17..10b4316 100644
--- a/packages/SystemUI/res/layout/recents_stack_action_button.xml
+++ b/packages/SystemUI/res/layout/recents_stack_action_button.xml
@@ -24,7 +24,7 @@
     android:paddingBottom="12dp"
     android:text="@string/recents_stack_action_button_label"
     android:textSize="14sp"
-    android:textColor="#FFFFFF"
+    android:textColor="?attr/bgProtectTextColor"
     android:textAllCaps="true"
     android:shadowColor="#99000000"
     android:shadowDx="0"
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index 9076199..18ffd0f 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -16,12 +16,12 @@
 <RelativeLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/volume_dialog"
-    android:layout_width="@dimen/volume_dialog_panel_width"
+    android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:layout_marginBottom="@dimen/volume_dialog_margin_bottom"
-    android:layout_gravity="center_vertical|end"
+    android:background="@drawable/volume_dialog_background"
     android:paddingTop="@dimen/volume_dialog_padding_top"
-    android:translationZ="8dp" >
+    android:translationZ="4dp" >
 
     <LinearLayout
         android:id="@+id/volume_dialog_content"
@@ -57,7 +57,6 @@
             android:layout_height="wrap_content"
             android:ellipsize="end"
             android:maxLines="1"
-            android:visibility="gone"
             android:textAppearance="@style/TextAppearance.Volume.Header" />
         <com.android.keyguard.AlphaOptimizedImageButton
             xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/packages/SystemUI/res/layout/volume_dialog_wrapped.xml b/packages/SystemUI/res/layout/volume_dialog_wrapped.xml
deleted file mode 100644
index 57489fd..0000000
--- a/packages/SystemUI/res/layout/volume_dialog_wrapped.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<com.android.systemui.HardwareUiLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:layout_marginTop="@dimen/top_padding"
-    android:layout_marginBottom="@dimen/bottom_padding">
-
-    <include layout="@layout/volume_dialog"/>
-
-</com.android.systemui.HardwareUiLayout>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 1fed208..129d605 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -281,7 +281,7 @@
     <string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"Rotació bloquejada"</string>
     <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"Vertical"</string>
     <string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"Horitzontal"</string>
-    <string name="quick_settings_ime_label" msgid="7073463064369468429">"Mètode d\'entrada"</string>
+    <string name="quick_settings_ime_label" msgid="7073463064369468429">"Mètode d\'introducció"</string>
     <string name="quick_settings_location_label" msgid="5011327048748762257">"Ubicació"</string>
     <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Ubicació desactivada"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Dispositiu multimèdia"</string>
@@ -730,7 +730,7 @@
     <string name="pip_notification_message" msgid="5619512781514343311">"Si no vols que <xliff:g id="NAME">%s</xliff:g> utilitzi aquesta funció, toca per obrir la configuració i desactiva-la."</string>
     <string name="pip_play" msgid="1417176722760265888">"Reprodueix"</string>
     <string name="pip_pause" msgid="8881063404466476571">"Posa en pausa"</string>
-    <string name="pip_skip_to_next" msgid="1948440006726306284">"Vés al següent"</string>
+    <string name="pip_skip_to_next" msgid="1948440006726306284">"Ves al següent"</string>
     <string name="pip_skip_to_prev" msgid="1955311326688637914">"Torna a l\'anterior"</string>
     <string name="thermal_shutdown_title" msgid="4458304833443861111">"Telèfon apagat per la calor"</string>
     <string name="thermal_shutdown_message" msgid="9006456746902370523">"Ara el telèfon funciona de manera normal"</string>
@@ -759,7 +759,7 @@
     <string name="instant_apps" msgid="6647570248119804907">"Aplicacions instantànies"</string>
     <string name="instant_apps_message" msgid="8116608994995104836">"No cal instal·lar les aplicacions instantànies."</string>
     <string name="app_info" msgid="6856026610594615344">"Informació de l\'aplicació"</string>
-    <string name="go_to_web" msgid="1106022723459948514">"Vés al web"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Ves al web"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Dades mòbils"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"La Wi-Fi està desactivada"</string>
     <string name="bt_is_off" msgid="2640685272289706392">"El Bluetooth està desactivat"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 1e835f8..8db9281 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -356,10 +356,10 @@
     <string name="description_target_search" msgid="3091587249776033139">"Suche"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Zum <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach oben schieben"</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Zum <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach links schieben"</string>
-    <string name="zen_priority_introduction" msgid="1149025108714420281">"Klingeltöne und die Vibration werden deaktiviert, außer für Weckrufe, Erinnerungen, Termine sowie Anrufe von zuvor von dir festgelegten Personen. Du hörst jedoch weiterhin Sound, wenn du Musik und Videos wiedergibst oder Spiele spielst."</string>
-    <string name="zen_alarms_introduction" msgid="4934328096749380201">"Klingeltöne und die Vibration werden deaktiviert, außer für Weckrufe. Du hörst jedoch weiterhin Sound, wenn du Musik und Videos wiedergibst oder Spiele spielst."</string>
+    <string name="zen_priority_introduction" msgid="1149025108714420281">"Klingeltöne und die Vibration werden deaktiviert, außer für Weckrufe, Erinnerungen, Termine sowie Anrufe von zuvor von dir festgelegten Personen. Du hörst jedoch weiterhin Sound, wenn du dir Musik anhörst, Videos ansiehst oder Spiele spielst."</string>
+    <string name="zen_alarms_introduction" msgid="4934328096749380201">"Klingeltöne und die Vibration werden deaktiviert, außer für Weckrufe. Du hörst jedoch weiterhin Sound, wenn du dir Musik anhörst, Videos ansiehst oder Spiele spielst."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Anpassen"</string>
-    <string name="zen_silence_introduction_voice" msgid="3948778066295728085">"Hierdurch werden ALLE Klingeltöne und die Vibration deaktiviert, auch für Weckrufe, Musik, Videos und Spiele. Anrufe kannst du jedoch weiterhin tätigen."</string>
+    <string name="zen_silence_introduction_voice" msgid="3948778066295728085">"Hierdurch werden ALLE Klingeltöne und die Vibration deaktiviert, auch für Weckrufe, Musik, Videos und Spiele. Du kannst aber weiterhin selbst anrufen."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Hierdurch werden alle Klingeltöne und Vibrationsalarme stummgeschaltet, auch für Weckrufe, Musik, Videos und Spiele."</string>
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Weniger dringende Benachrichtigungen unten"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 6a65489..6419922 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -459,11 +459,11 @@
     <string name="monitoring_description_ca_cert_settings_separator" msgid="4987350385906393626">" "</string>
     <string name="monitoring_description_ca_cert_settings" msgid="5489969458872997092">"Άνοιγμα αξιόπιστων διαπιστευτηρίων"</string>
     <string name="monitoring_description_network_logging" msgid="7223505523384076027">"Ο διαχειριστής σας έχει ενεργοποιήσει την καταγραφή δικτύου, η οποία παρακολουθεί την επισκεψιμότητα στη συσκευή σας.\n\nΓια περισσότερες πληροφορίες, επικοινωνήστε με τον διαχειριστή σας."</string>
-    <string name="monitoring_description_vpn" msgid="4445150119515393526">"Παραχωρήσατε σε μια εφαρμογή άδεια για τη ρύθμιση σύνδεσης VPN.\n\nΑυτή η εφαρμογή μπορεί να παρακολουθεί τη δραστηριότητα της συσκευής και του δικτύου σας, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστότοπων."</string>
-    <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"Η διαχείριση του προφίλ εργασίας γίνεται από τον οργανισμό <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nΟ διαχειριστής έχει τη δυνατότητα παρακολούθησης της δραστηριότητας του δικτύου σας, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστότοπων.\n\nΓια περισσότερες πληροφορίες, επικοινωνήστε με τον διαχειριστή.\n\nΕπίσης, είστε συνδεδεμένοι σε VPN, το οποίο μπορεί να παρακολουθεί τη δραστηριότητα του δικτύου σας."</string>
+    <string name="monitoring_description_vpn" msgid="4445150119515393526">"Παραχωρήσατε σε μια εφαρμογή άδεια για τη ρύθμιση σύνδεσης VPN.\n\nΑυτή η εφαρμογή μπορεί να παρακολουθεί τη δραστηριότητα της συσκευής και του δικτύου σας, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων."</string>
+    <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"Η διαχείριση του προφίλ εργασίας γίνεται από τον οργανισμό <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nΟ διαχειριστής έχει τη δυνατότητα παρακολούθησης της δραστηριότητας του δικτύου σας, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων.\n\nΓια περισσότερες πληροφορίες, επικοινωνήστε με τον διαχειριστή.\n\nΕπίσης, είστε συνδεδεμένοι σε VPN, το οποίο μπορεί να παρακολουθεί τη δραστηριότητα του δικτύου σας."</string>
     <string name="legacy_vpn_name" msgid="6604123105765737830">"VPN"</string>
     <string name="monitoring_description_app" msgid="1828472472674709532">"Έχετε συνδεθεί στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g>, η οποία μπορεί να παρακολουθεί τη δραστηριότητα του δικτύου σας, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων."</string>
-    <string name="monitoring_description_app_personal" msgid="484599052118316268">"Έχετε συνδεθεί στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g>, η οποία μπορεί να παρακολουθεί τη δραστηριότητα του προσωπικού σας δικτύου, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστότοπων."</string>
+    <string name="monitoring_description_app_personal" msgid="484599052118316268">"Έχετε συνδεθεί στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g>, η οποία μπορεί να παρακολουθεί τη δραστηριότητα του προσωπικού σας δικτύου, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων."</string>
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Έχετε συνδεθεί στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g>, η οποία μπορεί να παρακολουθεί τη δραστηριότητα του προσωπικού σας δικτύου, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Ο οργανισμός <xliff:g id="ORGANIZATION">%1$s</xliff:g> διαχειρίζεται το προφίλ εργασίας σας. Το προφίλ είναι συνδεδεμένο στην εφαρμογή <xliff:g id="APPLICATION">%2$s</xliff:g>, η οποία μπορεί να παρακολουθήσει τη δραστηριότητα του δικτύου εργασίας σας, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων.\n\nΓια περισσότερες πληροφορίες, επικοινωνήστε με τον διαχειριστή σας."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Ο οργανισμός <xliff:g id="ORGANIZATION">%1$s</xliff:g> διαχειρίζεται το προφίλ εργασίας σας. Το προφίλ συνδέεται με την εφαρμογή <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, η οποία μπορεί να παρακολουθεί τη δραστηριότητα του δικτύου της εργασίας σας, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων.\n\nΕπίσης, είστε συνδεδεμένοι στην εφαρμογή <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, που έχει τη δυνατότητα παρακολούθησης της δραστηριότητας του προσωπικού σας δικτύου."</string>
diff --git a/packages/SystemUI/res/values-mcc311-mnc480/config.xml b/packages/SystemUI/res/values-mcc311-mnc480/config.xml
new file mode 100644
index 0000000..7dadae7
--- /dev/null
+++ b/packages/SystemUI/res/values-mcc311-mnc480/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2017, The Android Open Source 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources>
+    <!-- Enable 5 bar signal strength icon -->
+    <bool name="config_inflateSignalStrength">true</bool>
+</resources>
+
diff --git a/packages/SystemUI/res/values-sw372dp/config.xml b/packages/SystemUI/res/values-sw372dp/config.xml
new file mode 100644
index 0000000..07b797a
--- /dev/null
+++ b/packages/SystemUI/res/values-sw372dp/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2017, The Android Open Source 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources>
+    <!-- Nav bar button default ordering/layout -->
+    <string name="config_navBarLayout" translatable="false">left[.25W],back[.5WC];home;recent[.5WC],right[.25W]</string>
+</resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index f6b785a..caf4df7 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -489,7 +489,7 @@
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Keyingi safar sozlamalardan yoqilgan paydo bo‘ladi."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Berkitish"</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Siz ishchi profildan foydalanmoqdasiz"</string>
-    <string name="stream_voice_call" msgid="4410002696470423714">"Qo‘ng‘iroq qilish"</string>
+    <string name="stream_voice_call" msgid="4410002696470423714">"Chaqiruv"</string>
     <string name="stream_system" msgid="7493299064422163147">"Tizim"</string>
     <string name="stream_ring" msgid="8213049469184048338">"Jiringlatish"</string>
     <string name="stream_music" msgid="9086982948697544342">"Multimedia"</string>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 81ca230..2ad6f2d 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -293,7 +293,7 @@
     <string name="config_systemUIFactoryComponent" translatable="false">com.android.systemui.SystemUIFactory</string>
 
     <!-- Nav bar button default ordering/layout -->
-    <string name="config_navBarLayout" translatable="false">left,back;home;recent,right</string>
+    <string name="config_navBarLayout" translatable="false">left[.5W],back[1WC];home;recent[1WC],right[.5W]</string>
 
     <bool name="quick_settings_show_full_alarm">false</bool>
 
@@ -398,4 +398,8 @@
          it has been expanded to reveal its children. -->
     <bool name="config_showGroupNotificationBgWhenExpanded">false</bool>
 
+    <!-- Whether to artificially interpret all signal strengths as
+         one bar higher than they actually are -->
+    <bool name="config_inflateSignalStrength">false</bool>
+
 </resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 1b2de8d..93d2072 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -216,6 +216,8 @@
     <!-- The width of the panel that holds the quick settings. -->
     <dimen name="qs_panel_width">@dimen/notification_panel_width</dimen>
 
+    <dimen name="volume_dialog_panel_width">@dimen/standard_notification_panel_width</dimen>
+
     <!-- Gravity for the notification panel -->
     <integer name="notification_panel_layout_gravity">0x31</integer><!-- center_horizontal|top -->
 
@@ -800,7 +802,6 @@
 
     <dimen name="hwui_edge_margin">16dp</dimen>
 
-    <dimen name="volume_dialog_panel_width">315dp</dimen>
     <dimen name="global_actions_panel_width">125dp</dimen>
 
     <dimen name="global_actions_top_padding">100dp</dimen>
@@ -819,11 +820,14 @@
     <dimen name="edge_margin">16dp</dimen>
 
     <dimen name="rounded_corner_radius">0dp</dimen>
-    <dimen name="rounded_corner_content_padding">0dp</dimen>
+    <dimen name="rounded_corner_content_padding">8dp</dimen>
 
     <!-- Intended corner radius when drawing the mobile signal -->
     <dimen name="stat_sys_mobile_signal_corner_radius">0.75dp</dimen>
     <!-- How far to inset the rounded edges -->
     <dimen name="stat_sys_mobile_signal_circle_inset">0.9dp</dimen>
 
+    <!-- Width of the hollow triangle for empty signal state -->
+    <dimen name="mobile_signal_empty_strokewidth">2dp</dimen>
+
 </resources>
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 3c6ad23..b27dedd 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -78,5 +78,13 @@
     <item type="id" name="action_move_tl_50" />
     <item type="id" name="action_move_tl_30" />
     <item type="id" name="action_move_rb_full" />
+
+    <!-- Accessibility actions for the notification menu -->
+    <item type="id" name="action_snooze_undo"/>
+    <item type="id" name="action_snooze_15_min"/>
+    <item type="id" name="action_snooze_30_min"/>
+    <item type="id" name="action_snooze_1_hour"/>
+    <item type="id" name="action_snooze_2_hours"/>
+    <item type="id" name="action_snooze_assistant_suggestion_1"/>
 </resources>
 
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 5274b64..c67e49a 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -16,7 +16,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
 
-    <style name="RecentsTheme" parent="@android:style/Theme.Material">
+    <style name="RecentsTheme" parent="RecentsBase">
         <!-- NoTitle -->
         <item name="android:windowNoTitle">true</item>
         <!-- Misc -->
@@ -27,6 +27,12 @@
         <item name="android:ambientShadowAlpha">0.35</item>
     </style>
 
+    <!-- OverlayManager might replace this style entirely, use RecentsTheme to set a property
+    that should exist in both light and dark versions of Recents -->
+    <style name="RecentsBase" parent="@android:style/Theme.Material">
+        <item name="android:textColorPrimaryInverse">@*android:color/primary_text_material_dark</item>
+        <item name="android:textColorSecondaryInverse">@*android:color/secondary_text_material_dark</item>
+    </style>
 
     <!-- Recents theme -->
     <style name="RecentsTheme.Wallpaper">
@@ -35,6 +41,8 @@
         <item name="android:windowShowWallpaper">true</item>
         <item name="android:windowDisablePreview">true</item>
         <item name="clearAllStyle">@style/ClearAllButtonDefaultMargins</item>
+        <item name="bgProtectTextColor">?android:attr/textColorPrimaryInverse</item>
+        <item name="bgProtectSecondaryTextColor">?android:attr/textColorSecondaryInverse</item>
     </style>
 
     <style name="ClearAllButtonDefaultMargins">
@@ -47,6 +55,8 @@
     <!-- Performance optimized Recents theme (no wallpaper) -->
     <style name="RecentsTheme.NoWallpaper">
         <item name="android:windowBackground">@android:color/black</item>
+        <item name="bgProtectTextColor">@android:color/white</item>
+        <item name="bgProtectSecondaryTextColor">@android:color/white</item>
     </style>
 
     <!-- Theme used for the activity that shows when the system forced an app to be resizable -->
@@ -290,7 +300,11 @@
     <style name="Animation.StatusBar">
     </style>
 
-    <style name="systemui_theme" parent="@*android:style/Theme.DeviceDefault.QuickSettings">
+    <!-- Overlay styles will replace this theme -->
+    <style name="systemui_base" parent="@*android:style/Theme.DeviceDefault.QuickSettings">
+    </style>
+
+    <style name="systemui_theme" parent="systemui_base">
         <item name="lightIconTheme">@style/DualToneLightTheme</item>
         <item name="darkIconTheme">@style/DualToneDarkTheme</item>
         <item name="bgProtectTextColor">?android:attr/textColorPrimaryInverse</item>
diff --git a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
index d8bebab..12f75bb 100644
--- a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
+++ b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
@@ -29,10 +29,8 @@
 import android.graphics.Typeface;
 import android.os.PowerManager;
 import android.os.SystemClock;
-import android.os.UserHandle;
 import android.provider.Settings;
 import android.text.InputType;
-import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.Gravity;
 import android.view.View;
@@ -252,9 +250,9 @@
             mText = mText.substring(0, length - 1);
             CharState charState = mTextChars.get(length - 1);
             charState.startRemoveAnimation(0, 0);
+            sendAccessibilityEventTypeViewTextChanged(textbefore, textbefore.length() - 1, 1, 0);
         }
         userActivity();
-        sendAccessibilityEventTypeViewTextChanged(textbefore, textbefore.length() - 1, 1, 0);
     }
 
     public String getText() {
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 1b694b3..bb44123 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -31,6 +31,7 @@
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.fragments.FragmentService;
 import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.PluginActivityManager;
 import com.android.systemui.plugins.PluginDependencyProvider;
 import com.android.systemui.plugins.PluginManager;
 import com.android.systemui.plugins.PluginManagerImpl;
@@ -276,6 +277,9 @@
 
         mProviders.put(UiOffloadThread.class, UiOffloadThread::new);
 
+        mProviders.put(PluginActivityManager.class,
+                () -> new PluginActivityManager(mContext, getDependency(PluginManager.class)));
+
         // Put all dependencies above here so the factory can override them if it wants.
         SystemUIFactory.getInstance().injectDependencies(mProviders, mContext);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/RoundedCorners.java b/packages/SystemUI/src/com/android/systemui/RoundedCorners.java
index 7af4a90..73e0d7f 100644
--- a/packages/SystemUI/src/com/android/systemui/RoundedCorners.java
+++ b/packages/SystemUI/src/com/android/systemui/RoundedCorners.java
@@ -55,11 +55,17 @@
     public void start() {
         mRoundedDefault = mContext.getResources().getDimensionPixelSize(
                 R.dimen.rounded_corner_radius);
-        if (mRoundedDefault == 0) {
-            // No rounded corners on this device.
-            return;
+        if (mRoundedDefault != 0) {
+            setupRounding();
         }
+        int padding = mContext.getResources().getDimensionPixelSize(
+                R.dimen.rounded_corner_content_padding);
+        if (padding != 0) {
+            setupPadding(padding);
+        }
+    }
 
+    private void setupRounding() {
         mOverlay = LayoutInflater.from(mContext)
                 .inflate(R.layout.rounded_corners, null);
         mOverlay.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
@@ -82,20 +88,16 @@
         mDensity = metrics.density;
 
         Dependency.get(TunerService.class).addTunable(this, SIZE);
+    }
 
+    private void setupPadding(int padding) {
         // Add some padding to all the content near the edge of the screen.
-        int padding = mContext.getResources().getDimensionPixelSize(
-                R.dimen.rounded_corner_content_padding);
         StatusBar sb = getComponent(StatusBar.class);
         View statusBar = sb.getStatusBarWindow();
 
         TunablePadding.addTunablePadding(statusBar.findViewById(R.id.keyguard_header), PADDING,
                 padding, FLAG_END);
 
-        FragmentHostManager.get(sb.getNavigationBarWindow()).addTagListener(
-                NavigationBarFragment.TAG,
-                new TunablePaddingTagListener(padding, 0));
-
         FragmentHostManager fragmentHostManager = FragmentHostManager.get(statusBar);
         fragmentHostManager.addTagListener(CollapsedStatusBarFragment.TAG,
                 new TunablePaddingTagListener(padding, R.id.status_bar));
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 699fdef..6777ea2 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -25,6 +25,7 @@
 import android.content.res.Resources;
 import android.graphics.RectF;
 import android.os.Handler;
+import android.util.ArrayMap;
 import android.util.Log;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
@@ -37,8 +38,6 @@
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.FlingAnimationUtils;
 
-import java.util.HashMap;
-
 public class SwipeHelper implements Gefingerpoken {
     static final String TAG = "com.android.systemui.SwipeHelper";
     private static final boolean DEBUG = false;
@@ -51,10 +50,10 @@
     public static final int X = 0;
     public static final int Y = 1;
 
-    private float SWIPE_ESCAPE_VELOCITY = 500f; // dp/sec
-    private int DEFAULT_ESCAPE_ANIMATION_DURATION = 200; // ms
-    private int MAX_ESCAPE_ANIMATION_DURATION = 400; // ms
-    private int MAX_DISMISS_VELOCITY = 4000; // dp/sec
+    private static final float SWIPE_ESCAPE_VELOCITY = 500f; // dp/sec
+    private static final int DEFAULT_ESCAPE_ANIMATION_DURATION = 200; // ms
+    private static final int MAX_ESCAPE_ANIMATION_DURATION = 400; // ms
+    private static final int MAX_DISMISS_VELOCITY = 4000; // dp/sec
     private static final int SNAP_ANIM_LEN = SLOW_ANIMATIONS ? 1000 : 150; // ms
 
     static final float SWIPE_PROGRESS_FADE_END = 0.5f; // fraction of thumbnail width
@@ -65,13 +64,13 @@
     private float mMinSwipeProgress = 0f;
     private float mMaxSwipeProgress = 1f;
 
-    private FlingAnimationUtils mFlingAnimationUtils;
+    private final FlingAnimationUtils mFlingAnimationUtils;
     private float mPagingTouchSlop;
-    private Callback mCallback;
-    private Handler mHandler;
-    private int mSwipeDirection;
-    private VelocityTracker mVelocityTracker;
-    private FalsingManager mFalsingManager;
+    private final Callback mCallback;
+    private final Handler mHandler;
+    private final int mSwipeDirection;
+    private final VelocityTracker mVelocityTracker;
+    private final FalsingManager mFalsingManager;
 
     private float mInitialTouchPos;
     private float mPerpendicularInitialTouchPos;
@@ -86,16 +85,16 @@
     private boolean mLongPressSent;
     private LongPressListener mLongPressListener;
     private Runnable mWatchLongPress;
-    private long mLongPressTimeout;
+    private final long mLongPressTimeout;
 
     final private int[] mTmpPos = new int[2];
-    private int mFalsingThreshold;
+    private final int mFalsingThreshold;
     private boolean mTouchAboveFalsingThreshold;
     private boolean mDisableHwLayers;
-    private boolean mFadeDependingOnAmountSwiped;
-    private Context mContext;
+    private final boolean mFadeDependingOnAmountSwiped;
+    private final Context mContext;
 
-    private HashMap<View, Animator> mDismissPendingMap = new HashMap<>();
+    private final ArrayMap<View, Animator> mDismissPendingMap = new ArrayMap<>();
 
     public SwipeHelper(int swipeDirection, Callback callback, Context context) {
         mContext = context;
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index 4a45997..211f0c7 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui;
 
+import android.app.Activity;
 import android.app.ActivityThread;
 import android.app.Application;
 import android.content.BroadcastReceiver;
@@ -26,8 +27,10 @@
 import android.content.res.Configuration;
 import android.os.Process;
 import android.os.SystemProperties;
+import android.os.Trace;
 import android.os.UserHandle;
 import android.util.ArraySet;
+import android.util.BootTimingsTraceLog;
 import android.util.Log;
 
 import com.android.systemui.fragments.FragmentService;
@@ -39,6 +42,7 @@
 import com.android.systemui.plugins.GlobalActions;
 import com.android.systemui.plugins.OverlayPlugin;
 import com.android.systemui.plugins.Plugin;
+import com.android.systemui.plugins.PluginActivityManager;
 import com.android.systemui.plugins.PluginListener;
 import com.android.systemui.plugins.PluginManager;
 import com.android.systemui.power.PowerUI;
@@ -190,11 +194,17 @@
 
         Log.v(TAG, "Starting SystemUI services for user " +
                 Process.myUserHandle().getIdentifier() + ".");
+        BootTimingsTraceLog log = new BootTimingsTraceLog("SystemUIBootTiming",
+                Trace.TRACE_TAG_APP);
+        log.traceBegin("StartServices");
         final int N = services.length;
         for (int i = 0; i < N; i++) {
             Class<?> cl = services[i];
             if (DEBUG) Log.d(TAG, "loading: " + cl);
+            log.traceBegin("StartServices" + cl.getSimpleName());
+            long ti = System.currentTimeMillis();
             try {
+
                 Object newService = SystemUIFactory.getInstance().createInstance(cl);
                 mServices[i] = (SystemUI) ((newService == null) ? cl.newInstance() : newService);
             } catch (IllegalAccessException ex) {
@@ -207,11 +217,18 @@
             mServices[i].mComponents = mComponents;
             if (DEBUG) Log.d(TAG, "running: " + mServices[i]);
             mServices[i].start();
+            log.traceEnd();
 
+            // Warn if initialization of component takes too long
+            ti = System.currentTimeMillis() - ti;
+            if (ti > 1000) {
+                Log.w(TAG, "Initialization of " + cl.getName() + " took " + ti + " ms");
+            }
             if (mBootCompleted) {
                 mServices[i].onBootCompleted();
             }
         }
+        log.traceEnd();
         Dependency.get(PluginManager.class).addPluginListener(
                 new PluginListener<OverlayPlugin>() {
                     private ArraySet<OverlayPlugin> mOverlays;
@@ -266,4 +283,10 @@
     public SystemUI[] getServices() {
         return mServices;
     }
+
+    @Override
+    public Activity instantiateActivity(ClassLoader cl, String className, Intent intent) {
+        if (!mServicesStarted) return null;
+        return Dependency.get(PluginActivityManager.class).instantiate(cl, className, intent);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index ae936db..8d1d6e0 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -39,6 +39,7 @@
 import com.android.systemui.util.wakelock.WakeLock;
 
 import java.io.PrintWriter;
+import java.util.function.IntConsumer;
 
 /**
  * Handles triggers for ambient state changes.
@@ -98,18 +99,44 @@
         requestPulse(DozeLog.PULSE_REASON_NOTIFICATION, false /* performedProxCheck */);
     }
 
+    private void proximityCheckThenCall(IntConsumer callback,
+            boolean alreadyPerformedProxCheck,
+            int pulseReason) {
+        if (alreadyPerformedProxCheck) {
+            callback.accept(ProximityCheck.RESULT_NOT_CHECKED);
+        } else {
+            final long start = SystemClock.uptimeMillis();
+            new ProximityCheck() {
+                @Override
+                public void onProximityResult(int result) {
+                    final long end = SystemClock.uptimeMillis();
+                    DozeLog.traceProximityResult(mContext, result == RESULT_NEAR,
+                            end - start, pulseReason);
+                    callback.accept(result);
+                }
+            }.check();
+        }
+    }
+
     private void onSensor(int pulseReason, boolean sensorPerformedProxCheck,
             float screenX, float screenY) {
         boolean isDoubleTap = pulseReason == DozeLog.PULSE_REASON_SENSOR_DOUBLE_TAP;
         boolean isPickup = pulseReason == DozeLog.PULSE_REASON_SENSOR_PICKUP;
 
         if (mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT)) {
-            if (isDoubleTap) {
-                mDozeHost.onDoubleTap(screenX, screenY);
-                mMachine.wakeUp();
-            } else {
-                mDozeHost.extendPulse();
-            }
+            proximityCheckThenCall((result) -> {
+                if (result == ProximityCheck.RESULT_NEAR) {
+                    // In pocket, drop event.
+                    return;
+                }
+                if (isDoubleTap) {
+                    mDozeHost.onDoubleTap(screenX, screenY);
+                    mMachine.wakeUp();
+                } else {
+                    mDozeHost.extendPulse();
+                }
+            }, sensorPerformedProxCheck, pulseReason);
+            return;
         } else {
             requestPulse(pulseReason, sensorPerformedProxCheck);
         }
@@ -158,13 +185,16 @@
                 break;
             case DOZE:
             case DOZE_AOD:
-            case DOZE_AOD_PAUSED:
                 mDozeSensors.setProxListening(newState != DozeMachine.State.DOZE);
                 mDozeSensors.setListening(true);
                 if (oldState != DozeMachine.State.INITIALIZED) {
                     mDozeSensors.reregisterAllSensors();
                 }
                 break;
+            case DOZE_AOD_PAUSED:
+                mDozeSensors.setProxListening(true);
+                mDozeSensors.setListening(false);
+                break;
             case DOZE_PULSING:
                 mDozeSensors.setProxListening(true);
                 break;
@@ -199,33 +229,15 @@
         }
 
         mPulsePending = true;
-        if (!mDozeParameters.getProxCheckBeforePulse() || performedProxCheck) {
-            // skip proximity check
-            continuePulseRequest(reason);
-            return;
-        }
-
-        final long start = SystemClock.uptimeMillis();
-        new ProximityCheck() {
-            @Override
-            public void onProximityResult(int result) {
-                final long end = SystemClock.uptimeMillis();
-                DozeLog.traceProximityResult(mContext, result == RESULT_NEAR,
-                        end - start, reason);
-                if (performedProxCheck) {
-                    // we already continued
-                    return;
-                }
-                // avoid pulsing in pockets
-                if (result == RESULT_NEAR) {
-                    mPulsePending = false;
-                    return;
-                }
-
-                // not in-pocket, continue pulsing
+        proximityCheckThenCall((result) -> {
+            if (result == ProximityCheck.RESULT_NEAR) {
+                // in pocket, abort pulse
+                mPulsePending = false;
+            } else {
+                // not in pocket, continue pulsing
                 continuePulseRequest(reason);
             }
-        }.check();
+        }, !mDozeParameters.getProxCheckBeforePulse() || performedProxCheck, reason);
     }
 
     private boolean canPulse() {
@@ -259,6 +271,7 @@
         protected static final int RESULT_UNKNOWN = 0;
         protected static final int RESULT_NEAR = 1;
         protected static final int RESULT_FAR = 2;
+        protected static final int RESULT_NOT_CHECKED = 3;
 
         private boolean mRegistered;
         private boolean mFinished;
diff --git a/packages/SystemUI/src/com/android/systemui/fragments/ExtensionFragmentListener.java b/packages/SystemUI/src/com/android/systemui/fragments/ExtensionFragmentListener.java
index 8809510..4ff10e9 100644
--- a/packages/SystemUI/src/com/android/systemui/fragments/ExtensionFragmentListener.java
+++ b/packages/SystemUI/src/com/android/systemui/fragments/ExtensionFragmentListener.java
@@ -34,12 +34,14 @@
     private final FragmentHostManager mFragmentHostManager;
     private final String mTag;
     private final Extension<T> mExtension;
+    private final int mId;
     private String mOldClass;
 
     private ExtensionFragmentListener(View view, String tag, int id, Extension<T> extension) {
         mTag = tag;
         mFragmentHostManager = FragmentHostManager.get(view);
         mExtension = extension;
+        mId = id;
         mFragmentHostManager.getFragmentManager().beginTransaction()
                 .replace(id, (Fragment) mExtension.get(), mTag)
                 .commit();
@@ -49,7 +51,7 @@
     public void accept(T extension) {
         try {
             Fragment.class.cast(extension);
-            mFragmentHostManager.getExtensionManager().setCurrentExtension(mTag,
+            mFragmentHostManager.getExtensionManager().setCurrentExtension(mId, mTag,
                     mOldClass, extension.getClass().getName(), mExtension.getContext());
             mOldClass = extension.getClass().getName();
         } catch (ClassCastException e) {
diff --git a/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java b/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java
index 871f113..f8f364d 100644
--- a/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java
+++ b/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java
@@ -266,16 +266,14 @@
     class ExtensionFragmentManager {
         private final ArrayMap<String, Context> mExtensionLookup = new ArrayMap<>();
 
-        public void setCurrentExtension(@NonNull  String tag, @Nullable String oldClass,
+        public void setCurrentExtension(int id, @NonNull  String tag, @Nullable String oldClass,
                 @NonNull String currentClass, @Nullable Context context) {
-            Fragment fragment = getFragmentManager().findFragmentByTag(tag);
             if (oldClass != null) {
                 mExtensionLookup.remove(oldClass);
             }
             mExtensionLookup.put(currentClass, context);
             getFragmentManager().beginTransaction()
-                    .replace(((View) fragment.getView().getParent()).getId(),
-                            instantiate(context, currentClass, null), tag)
+                    .replace(id, instantiate(context, currentClass, null), tag)
                     .commit();
             reloadFragments();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index 80a6418..1a8a474 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -339,6 +339,7 @@
                     long id) {
                 final Action action = mAdapter.getItem(position);
                 if (action instanceof LongPressAction) {
+                    mDialog.dismiss();
                     return ((LongPressAction) action).onLongPress();
                 }
                 return false;
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java b/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java
index 32b5862..af2b767 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java
@@ -38,6 +38,7 @@
 import android.view.View;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.R;
 
 /**
  * Bouncer between work activities and the activity used to confirm credentials before unlocking
@@ -83,6 +84,7 @@
         // Blank out the activity. When it is on-screen it will look like a Recents thumbnail with
         // redaction switched on.
         final View blankView = new View(this);
+        blankView.setContentDescription(getString(R.string.accessibility_desc_work_lock));
         blankView.setBackgroundColor(getPrimaryColor());
         setContentView(blankView);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index 0373d77..ebf4b5d 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -93,6 +93,7 @@
             ComponentName topPipActivity = PipUtils.getTopPinnedActivity(mContext,
                     mActivityManager);
             mMenuController.hideMenu();
+            mTouchHandler.onActivityUnpinned(topPipActivity);
             mNotificationController.onActivityUnpinned(topPipActivity);
 
             SystemServicesProxy.getInstance(mContext).setPipVisibility(topPipActivity != null);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index ddaeb04..3682ae6 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -25,6 +25,7 @@
 import android.animation.ValueAnimator;
 import android.animation.ValueAnimator.AnimatorUpdateListener;
 import android.app.IActivityManager;
+import android.content.ComponentName;
 import android.content.Context;
 import android.graphics.Point;
 import android.graphics.PointF;
@@ -116,7 +117,7 @@
             };
 
     // Behaviour states
-    private int mMenuState;
+    private int mMenuState = MENU_STATE_NONE;
     private boolean mIsMinimized;
     private boolean mIsImeShowing;
     private int mImeHeight;
@@ -212,16 +213,17 @@
     }
 
     public void onActivityPinned() {
-        // Reset some states once we are pinned
-        mMenuState = MENU_STATE_NONE;
-
-        if (mIsMinimized) {
-            setMinimizedStateInternal(false);
-        }
-        cleanUpDismissTarget();
+        cleanUp();
         mShowPipMenuOnAnimationEnd = true;
     }
 
+    public void onActivityUnpinned(ComponentName topPipActivity) {
+        if (topPipActivity == null) {
+            // Clean up state after the last PiP activity is removed
+            cleanUp();
+        }
+    }
+
     public void onPinnedStackAnimationEnded() {
         // Always synchronize the motion helper bounds once PiP animations finish
         mMotionHelper.synchronizePinnedStackBounds();
@@ -729,6 +731,16 @@
         mDismissViewController.destroyDismissTarget();
     }
 
+    /**
+     * Resets some states related to the touch handling.
+     */
+    private void cleanUp() {
+        if (mIsMinimized) {
+            setMinimizedStateInternal(false);
+        }
+        cleanUpDismissTarget();
+    }
+
     public void dump(PrintWriter pw, String prefix) {
         final String innerPrefix = prefix + "  ";
         pw.println(prefix + TAG);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java
index f0745a0..ac41b75 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java
@@ -174,7 +174,7 @@
     void onConfigurationChanged(Context context) {
         Resources res = context.getResources();
         mDefaultTitle = res.getString(R.string.pip_notification_unknown_title);
-        mDefaultIconResId = R.drawable.pip_expand;
+        mDefaultIconResId = R.drawable.pip_icon;
         if (mNotified) {
             // update notification
             notifyPipNotification();
diff --git a/packages/SystemUI/src/com/android/systemui/plugins/PluginActivityManager.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginActivityManager.java
new file mode 100644
index 0000000..9becc38
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/plugins/PluginActivityManager.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.plugins;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+
+public class PluginActivityManager {
+
+    private final Context mContext;
+    private final PluginManager mPluginManager;
+    private final ArrayMap<String, String> mActionLookup = new ArrayMap<>();
+
+    public PluginActivityManager(Context context, PluginManager pluginManager) {
+        mContext = context;
+        mPluginManager = pluginManager;
+    }
+
+    public void addActivityPlugin(String className, String action) {
+        mActionLookup.put(className, action);
+    }
+
+    public Activity instantiate(ClassLoader cl, String className, Intent intent) {
+        String action = mActionLookup.get(className);
+        if (TextUtils.isEmpty(action)) return null;
+        return mPluginManager.getOneShotPlugin(action, PluginActivity.class);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java
index 493d244..a968399 100644
--- a/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java
@@ -42,7 +42,6 @@
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.systemui.Dependency;
 import com.android.systemui.plugins.PluginInstanceManager.PluginContextWrapper;
-import com.android.systemui.plugins.PluginInstanceManager.PluginInfo;
 import com.android.systemui.plugins.annotations.ProvidesInterface;
 
 import dalvik.system.PathClassLoader;
@@ -120,14 +119,21 @@
         }
         PluginInstanceManager<T> p = mFactory.createPluginInstanceManager(mContext, action, null,
                 false, mLooper, cls, this);
+        PluginListener<Plugin> listener = new PluginListener<Plugin>() {
+            @Override
+            public void onPluginConnected(Plugin plugin, Context pluginContext) { }
+        };
+        mPluginMap.put(listener, p);
         mPluginPrefs.addAction(action);
-        PluginInfo<T> info = p.getPlugin();
+        PluginInstanceManager.PluginInfo<T> info = p.getPlugin();
         if (info != null) {
             mOneShotPackages.add(info.mPackage);
             mHasOneShot = true;
             startListening();
+            mPluginMap.remove(listener);
             return info.mPlugin;
         }
+        mPluginMap.remove(listener);
         return null;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index 6b50764..8f18800 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -161,7 +161,8 @@
 
         QSTileLayout tileLayout = mQsPanel.getTileLayout();
         mAllViews.add((View) tileLayout);
-        int heightDiff = mQsPanel.getBottom() - mQs.getHeader().getBottom()
+        int height = mQs.getView() != null ? mQs.getView().getMeasuredHeight() : 0;
+        int heightDiff = height - mQs.getHeader().getBottom()
                 + mQs.getHeader().getPaddingBottom();
         firstPageBuilder.addFloat(tileLayout, "translationY", heightDiff, 0);
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index 90275c5..bb36725 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -253,7 +253,8 @@
         }
         mHeader.setExpansion(mKeyguardShowing ? 1 : expansion);
         mFooter.setExpansion(mKeyguardShowing ? 1 : expansion);
-        int heightDiff = mQSPanel.getBottom() - mHeader.getBottom() + mHeader.getPaddingBottom();
+        int heightDiff = mQSPanel.getBottom() - mHeader.getBottom() + mHeader.getPaddingBottom()
+                + mFooter.getHeight();
         mQSPanel.setTranslationY(translationScaleY * heightDiff);
         mQSDetail.setFullyExpanded(expansion == 1);
 
@@ -262,7 +263,7 @@
         }
 
         // Set bounds on the QS panel so it doesn't run over the header.
-        mQsBounds.top = (int) (mQSPanel.getHeight() * (1 - expansion));
+        mQsBounds.top = (int) -mQSPanel.getTranslationY();
         mQsBounds.right = mQSPanel.getWidth();
         mQsBounds.bottom = mQSPanel.getHeight();
         mQSPanel.setClipBounds(mQsBounds);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
index 918c00c..089d07a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
@@ -15,10 +15,13 @@
  */
 package com.android.systemui.qs.tiles;
 
+import android.content.Context;
 import android.content.Intent;
+import android.graphics.drawable.Drawable;
 import android.service.quicksettings.Tile;
 import android.widget.Switch;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settingslib.graph.BatteryMeterDrawableBase;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.plugins.qs.QSTile.BooleanState;
@@ -79,7 +82,9 @@
     protected void handleUpdateState(BooleanState state, Object arg) {
         state.state = mCharging ? Tile.STATE_UNAVAILABLE
                 : mPowerSave ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
-        state.icon = ResourceIcon.get(R.drawable.ic_qs_battery_saver);
+        BatterySaverIcon bsi = new BatterySaverIcon();
+        bsi.mState = state.state;
+        state.icon = bsi;
         state.label = mContext.getString(R.string.battery_detail_switch_title);
         state.contentDescription = state.label;
         state.value = mPowerSave;
@@ -99,4 +104,41 @@
         mPowerSave = isPowerSave;
         refreshState(null);
     }
-}
\ No newline at end of file
+
+    public static class BatterySaverIcon extends Icon {
+        private int mState;
+
+        @Override
+        public Drawable getDrawable(Context context) {
+            BatterySaverDrawable b = new BatterySaverDrawable(context, 0);
+            b.mState = mState;
+            final int pad = context.getResources()
+                    .getDimensionPixelSize(R.dimen.qs_tile_divider_height);
+            b.setPadding(pad, pad, pad, pad);
+            return b;
+        }
+    }
+
+    private static class BatterySaverDrawable extends BatteryMeterDrawableBase {
+        private int mState;
+        private static final int MAX_BATTERY = 100;
+
+        BatterySaverDrawable(Context context, int frameColor) {
+            super(context, frameColor);
+            // Show as full so it's always uniform color
+            super.setBatteryLevel(MAX_BATTERY);
+            setPowerSave(true);
+            setCharging(false);
+        }
+
+        @Override
+        protected int batteryColorForLevel(int level) {
+            return QSTileImpl.getColorForState(mContext, mState);
+        }
+
+        @Override
+        public void setBatteryLevel(int val) {
+            // Don't change the actual level, otherwise this won't draw correctly
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index e6c3520..81ec6a7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -141,7 +141,11 @@
                 && mDataController.isMobileDataEnabled();
 
         state.icon = new SignalIcon(cb.mobileSignalIconId);
-        state.state = Tile.STATE_ACTIVE;
+        if (cb.airplaneModeEnabled) {
+            state.state = Tile.STATE_INACTIVE;
+        } else {
+            state.state = Tile.STATE_ACTIVE;
+        }
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index 9ba32b3..6b85707 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -43,11 +43,14 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.Dependency;
 import com.android.systemui.EventLogConstants;
 import com.android.systemui.EventLogTags;
 import com.android.systemui.R;
 import com.android.systemui.RecentsComponent;
 import com.android.systemui.SystemUI;
+import com.android.systemui.plugins.PluginActivity;
+import com.android.systemui.plugins.PluginActivityManager;
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.events.activity.ConfigurationChangedEvent;
 import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
@@ -207,7 +210,7 @@
         mImpl = new RecentsImpl(mContext);
 
         // Check if there is a recents override package
-        if ("userdebug".equals(Build.TYPE) || "eng".equals(Build.TYPE)) {
+        if (Build.IS_USERDEBUG || Build.IS_ENG) {
             String cnStr = SystemProperties.get(RECENTS_OVERRIDE_SYSPROP_KEY);
             if (!cnStr.isEmpty()) {
                 mOverrideRecentsPackageName = cnStr;
@@ -234,6 +237,8 @@
             registerWithSystemUser();
         }
         putComponent(Recents.class, this);
+        Dependency.get(PluginActivityManager.class).addActivityPlugin(RecentsImpl.RECENTS_ACTIVITY,
+                PluginActivity.ACTION_RECENTS);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 4de1214..fa16f8e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -24,6 +24,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
 import android.net.Uri;
 import android.os.Bundle;
@@ -42,9 +43,9 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.keyguard.LatencyTracker;
 import com.android.systemui.DejankUtils;
 import com.android.systemui.Interpolators;
-import com.android.keyguard.LatencyTracker;
 import com.android.systemui.R;
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent;
@@ -110,11 +111,10 @@
     private RecentsPackageMonitor mPackageMonitor;
     private Handler mHandler = new Handler();
     private long mLastTabKeyEventTime;
-    private int mLastDeviceOrientation = Configuration.ORIENTATION_UNDEFINED;
-    private int mLastDisplayDensity;
     private boolean mFinishedOnStartup;
     private boolean mIgnoreAltTabRelease;
     private boolean mIsVisible;
+    private Configuration mLastConfig;
 
     // Top level views
     private RecentsView mRecentsView;
@@ -333,16 +333,11 @@
         setContentView(R.layout.recents);
         takeKeyEvents(true);
         mRecentsView = findViewById(R.id.recents_view);
-        mRecentsView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
-                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
-                View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
         mScrimViews = new SystemBarScrimViews(this);
         getWindow().getAttributes().privateFlags |=
                 WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY;
 
-        Configuration appConfiguration = Utilities.getAppConfiguration(this);
-        mLastDeviceOrientation = appConfiguration.orientation;
-        mLastDisplayDensity = appConfiguration.densityDpi;
+        mLastConfig = Utilities.getAppConfiguration(this);
         mFocusTimerDuration = getResources().getInteger(R.integer.recents_auto_advance_duration);
         mIterateTrigger = new DozeTrigger(mFocusTimerDuration, new Runnable() {
             @Override
@@ -485,10 +480,15 @@
         Configuration newDeviceConfiguration = Utilities.getAppConfiguration(this);
         int numStackTasks = mRecentsView.getStack().getStackTaskCount();
         EventBus.getDefault().send(new ConfigurationChangedEvent(false /* fromMultiWindow */,
-                mLastDeviceOrientation != newDeviceConfiguration.orientation,
-                mLastDisplayDensity != newDeviceConfiguration.densityDpi, numStackTasks > 0));
-        mLastDeviceOrientation = newDeviceConfiguration.orientation;
-        mLastDisplayDensity = newDeviceConfiguration.densityDpi;
+                mLastConfig.orientation != newDeviceConfiguration.orientation,
+                mLastConfig.densityDpi != newDeviceConfiguration.densityDpi, numStackTasks > 0));
+
+        int configDiff = mLastConfig.updateFrom(newDeviceConfiguration);
+
+        // Recreate activity if an overlay was enabled/disabled
+        if ((configDiff & ActivityInfo.CONFIG_ASSETS_PATHS) != 0) {
+            recreate();
+        }
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
index 93033ea..80c44a3 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
@@ -71,6 +71,7 @@
 
     Context mContext;
 
+    int mPreloadedUserId;
     List<ActivityManager.RecentTaskInfo> mRawTasks;
     TaskStack mStack;
     ArraySet<Integer> mCurrentQuietProfiles = new ArraySet<Integer>();
@@ -83,9 +84,6 @@
     private void updateCurrentQuietProfilesCache(int currentUserId) {
         mCurrentQuietProfiles.clear();
 
-        if (currentUserId == UserHandle.USER_CURRENT) {
-            currentUserId = SystemServicesProxy.getInstance(mContext).getCurrentUser();
-        }
         UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
         List<UserInfo> profiles = userManager.getProfiles(currentUserId);
         if (profiles != null) {
@@ -105,9 +103,10 @@
      * Note: Do not lock, callers should synchronize on the loader before making this call.
      */
     void preloadRawTasks(boolean includeFrontMostExcludedTask) {
-        int currentUserId = UserHandle.USER_CURRENT;
-        updateCurrentQuietProfilesCache(currentUserId);
         SystemServicesProxy ssp = Recents.getSystemServices();
+        int currentUserId = ssp.getCurrentUser();
+        updateCurrentQuietProfilesCache(currentUserId);
+        mPreloadedUserId = currentUserId;
         mRawTasks = ssp.getRecentTasks(ActivityManager.getMaxRecentTasksStatic(),
                 currentUserId, includeFrontMostExcludedTask, mCurrentQuietProfiles);
 
@@ -135,7 +134,6 @@
             preloadRawTasks(includeFrontMostExcludedTask);
         }
 
-        SystemServicesProxy ssp = SystemServicesProxy.getInstance(mContext);
         SparseArray<Task.TaskKey> affiliatedTasks = new SparseArray<>();
         SparseIntArray affiliatedTaskCounts = new SparseIntArray();
         SparseBooleanArray lockedUsers = new SparseBooleanArray();
@@ -143,7 +141,7 @@
                 R.string.accessibility_recents_item_will_be_dismissed);
         String appInfoDescFormat = mContext.getString(
                 R.string.accessibility_recents_item_open_app_info);
-        int currentUserId = ssp.getCurrentUser();
+        int currentUserId = mPreloadedUserId;
         long legacyLastStackActiveTime = migrateLegacyLastStackActiveTime(currentUserId);
         long lastStackActiveTime = Settings.Secure.getLongForUser(mContext.getContentResolver(),
                 Secure.OVERVIEW_LAST_STACK_ACTIVE_TIME, legacyLastStackActiveTime, currentUserId);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index dca4a8d..c1c41be0 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -151,6 +151,12 @@
         mColorExtractor = Dependency.get(SysuiColorExtractor.class);
 
         LayoutInflater inflater = LayoutInflater.from(context);
+
+        mEmptyView = (TextView) inflater.inflate(R.layout.recents_empty, this, false);
+        addView(mEmptyView);
+
+        boolean usingDarkText =
+                Color.luminance(mEmptyView.getTextColors().getDefaultColor()) < 0.5f;
         if (RecentsDebugFlags.Static.EnableStackActionButton) {
             mStackActionButton = (TextView) inflater.inflate(R.layout.recents_stack_action_button,
                     this, false);
@@ -160,10 +166,21 @@
                     EventBus.getDefault().send(new DismissAllTaskViewsEvent());
                 }
             });
+            // Disable black shadow if text color is already dark.
+            if (usingDarkText) {
+                mStackActionButton.setShadowLayer(0, 0, 0, 0);
+            }
             addView(mStackActionButton);
         }
-        mEmptyView = (TextView) inflater.inflate(R.layout.recents_empty, this, false);
-        addView(mEmptyView);
+
+        // Let's also require dark status and nav bars if the text is dark
+        int systemBarsStyle = usingDarkText ? View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR |
+                View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR : 0;
+
+        setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
+                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
+                View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
+                systemBarsStyle);
     }
 
     /**
@@ -878,7 +895,8 @@
             // Recents doesn't care about the wallpaper being visible or not, it always
             // wants to scrim with wallpaper colors
             mBackgroundScrim.setColors(
-                    mColorExtractor.getColors(WallpaperManager.FLAG_SYSTEM, true));
+                    mColorExtractor.getColors(WallpaperManager.FLAG_SYSTEM,
+                            ColorExtractor.TYPE_DARK, true));
         }
     }
 
@@ -886,7 +904,7 @@
         mColorExtractor.addOnColorsChangedListener(this);
         // Getting system scrim colors ignoring wallpaper visibility since it should never be grey.
         ColorExtractor.GradientColors systemColors = mColorExtractor.getColors(
-                WallpaperManager.FLAG_SYSTEM, true);
+                ColorExtractor.TYPE_DARK, WallpaperManager.FLAG_SYSTEM, true);
         // We don't want to interpolate colors because we're defining the initial state.
         // Gradient should be set/ready when you open "Recents".
         mBackgroundScrim.setColors(systemColors, false);
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 7b57483..a35310f 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -46,6 +46,7 @@
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.Environment;
+import android.os.PowerManager;
 import android.os.Process;
 import android.os.UserHandle;
 import android.provider.MediaStore;
@@ -61,6 +62,7 @@
 import android.view.WindowManager;
 import android.view.animation.Interpolator;
 import android.widget.ImageView;
+import android.widget.Toast;
 
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.systemui.R;
@@ -678,6 +680,13 @@
      */
     private void startAnimation(final Runnable finisher, int w, int h, boolean statusBarVisible,
             boolean navBarVisible) {
+        // If power save is on, show a toast so there is some visual indication that a screenshot
+        // has been taken.
+        PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+        if (powerManager.isPowerSaveMode()) {
+            Toast.makeText(mContext, R.string.screenshot_saved_title, Toast.LENGTH_SHORT).show();
+        }
+
         // Add the view for the animation
         mScreenshotView.setImageBitmap(mScreenBitmap);
         mScreenshotLayout.requestFocus();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index 5528bb9..7d76b9b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -312,7 +312,7 @@
 
     @Override
     public boolean performClick() {
-        if (mWasActivatedOnDown || !mNeedsDimming) {
+        if (mWasActivatedOnDown || !mNeedsDimming || isTouchExplorationEnabled()) {
             return super.performClick();
         }
         return false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index c0691c1..e5b1afe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -568,8 +568,6 @@
                 mTmpRanking.getImportance());
         pw.print(indent);
         pw.println("      notification=" + n.getNotification());
-        pw.print(indent);
-        pw.println("      tickerText=\"" + n.getNotification().tickerText + "\"");
     }
 
     private static boolean isSystemNotification(StatusBarNotification sbn) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
index 5a163d4..f859124 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
@@ -417,7 +417,7 @@
 
     @Override
     public void onHeightUpdate() {
-        if (mParent == null || mMenuItems.size() == 0) {
+        if (mParent == null || mMenuItems.size() == 0 || mMenuContainer == null) {
             return;
         }
         int parentHeight = mParent.getCollapsedHeight();
@@ -477,7 +477,7 @@
 
     private void setMenuLocation() {
         boolean showOnLeft = mTranslation > 0;
-        if ((mIconsPlaced && showOnLeft == mOnLeft) || mSnapping
+        if ((mIconsPlaced && showOnLeft == mOnLeft) || mSnapping || mMenuContainer == null
                 || !mMenuContainer.isAttachedToWindow()) {
             // Do nothing
             return;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 67ea258..7abceaf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -16,15 +16,18 @@
 
 package com.android.systemui.statusbar;
 
+import static com.android.systemui.statusbar.phone.NotificationIconContainer.IconState.NO_VALUE;
+import static com.android.systemui.statusbar.phone.NotificationIconContainer.OVERFLOW_EARLY_AMOUNT;
+
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.os.SystemProperties;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityNodeInfo;
+
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.ViewInvertHelper;
@@ -315,26 +318,65 @@
     private float updateIconAppearance(ExpandableNotificationRow row, float expandAmount,
             boolean scrolling, boolean scrollingFast, boolean expandingAnimated,
             boolean isLastChild) {
+        StatusBarIconView icon = row.getEntry().expandedIcon;
+        NotificationIconContainer.IconState iconState = getIconState(icon);
+        if (iconState == null) {
+            return 0.0f;
+        }
+
         // Let calculate how much the view is in the shelf
         float viewStart = row.getTranslationY();
         int fullHeight = row.getActualHeight() + mPaddingBetweenElements;
         float iconTransformDistance = getIntrinsicHeight() * 1.5f;
         iconTransformDistance *= NotificationUtils.interpolate(1.f, 1.5f, expandAmount);
+        iconTransformDistance = Math.min(iconTransformDistance, fullHeight);
         if (isLastChild) {
             fullHeight = Math.min(fullHeight, row.getMinHeight() - getIntrinsicHeight());
             iconTransformDistance = Math.min(iconTransformDistance, row.getMinHeight()
                     - getIntrinsicHeight());
         }
         float viewEnd = viewStart + fullHeight;
+        if (expandingAnimated && mAmbientState.getScrollY() == 0
+                && !mAmbientState.isOnKeyguard() && !iconState.isLastExpandIcon) {
+            // We are expanding animated. Because we switch to a linear interpolation in this case,
+            // the last icon may be stuck in between the shelf position and the notification
+            // position, which looks pretty bad. We therefore optimize this case by applying a
+            // shorter transition such that the icon is either fully in the notification or we clamp
+            // it into the shelf if it's close enough.
+            // We need to persist this, since after the expansion, the behavior should still be the
+            // same.
+            float position = mAmbientState.getIntrinsicPadding()
+                    + mHostLayout.getPositionInLinearLayout(row);
+            int maxShelfStart = mMaxLayoutHeight - getIntrinsicHeight();
+            if (position < maxShelfStart && position + row.getIntrinsicHeight() >= maxShelfStart
+                    && row.getTranslationY() < position) {
+                iconState.isLastExpandIcon = true;
+                iconState.customTransformHeight = NO_VALUE;
+                // Let's check if we're close enough to snap into the shelf
+                boolean forceInShelf = mMaxLayoutHeight - getIntrinsicHeight() - position
+                        < getIntrinsicHeight();
+                if (!forceInShelf) {
+                    // We are overlapping the shelf but not enough, so the icon needs to be
+                    // repositioned
+                    iconState.customTransformHeight = (int) (mMaxLayoutHeight
+                            - getIntrinsicHeight() - position);
+                }
+            }
+        }
         float fullTransitionAmount;
         float iconTransitionAmount;
         float shelfStart = getTranslationY();
+        if (iconState.hasCustomTransformHeight()) {
+            fullHeight = iconState.customTransformHeight;
+            iconTransformDistance = iconState.customTransformHeight;
+        }
+        boolean fullyInOrOut = true;
         if (viewEnd >= shelfStart && (!mAmbientState.isUnlockHintRunning() || row.isInShelf())
                 && (mAmbientState.isShadeExpanded()
                         || (!row.isPinned() && !row.isHeadsUpAnimatingAway()))) {
             if (viewStart < shelfStart) {
-
                 float fullAmount = (shelfStart - viewStart) / fullHeight;
+                fullAmount = Math.min(1.0f, fullAmount);
                 float interpolatedAmount =  Interpolators.ACCELERATE_DECELERATE.getInterpolation(
                         fullAmount);
                 interpolatedAmount = NotificationUtils.interpolate(
@@ -344,7 +386,7 @@
                 iconTransitionAmount = (shelfStart - viewStart) / iconTransformDistance;
                 iconTransitionAmount = Math.min(1.0f, iconTransitionAmount);
                 iconTransitionAmount = 1.0f - iconTransitionAmount;
-
+                fullyInOrOut = false;
             } else {
                 fullTransitionAmount = 1.0f;
                 iconTransitionAmount = 1.0f;
@@ -353,6 +395,10 @@
             fullTransitionAmount = 0.0f;
             iconTransitionAmount = 0.0f;
         }
+        if (fullyInOrOut && !expandingAnimated && iconState.isLastExpandIcon) {
+            iconState.isLastExpandIcon = false;
+            iconState.customTransformHeight = NO_VALUE;
+        }
         updateIconPositioning(row, iconTransitionAmount, fullTransitionAmount,
                 iconTransformDistance, scrolling, scrollingFast, expandingAnimated, isLastChild);
         return fullTransitionAmount;
@@ -366,9 +412,10 @@
         if (iconState == null) {
             return;
         }
+        boolean forceInShelf = iconState.isLastExpandIcon && !iconState.hasCustomTransformHeight();
         float clampedAmount = iconTransitionAmount > 0.5f ? 1.0f : 0.0f;
         if (clampedAmount == fullTransitionAmount) {
-            iconState.noAnimations = scrollingFast || expandingAnimated;
+            iconState.noAnimations = (scrollingFast || expandingAnimated) && !forceInShelf;
             iconState.useFullTransitionAmount = iconState.noAnimations
                 || (!ICON_ANMATIONS_WHILE_SCROLLING && fullTransitionAmount == 0.0f && scrolling);
             iconState.useLinearTransitionAmount = !ICON_ANMATIONS_WHILE_SCROLLING
@@ -376,12 +423,18 @@
             iconState.translateContent = mMaxLayoutHeight - getTranslationY()
                     - getIntrinsicHeight() > 0;
         }
-        if (scrollingFast || (expandingAnimated && iconState.useFullTransitionAmount
-                && !ViewState.isAnimatingY(icon))) {
+        if (!forceInShelf && (scrollingFast || (expandingAnimated
+                && iconState.useFullTransitionAmount && !ViewState.isAnimatingY(icon)))) {
             iconState.cancelAnimations(icon);
             iconState.useFullTransitionAmount = true;
             iconState.noAnimations = true;
         }
+        if (iconState.hasCustomTransformHeight()) {
+            iconState.useFullTransitionAmount = true;
+        }
+        if (iconState.isLastExpandIcon) {
+            iconState.translateContent = false;
+        }
         float transitionAmount;
         if (isLastChild || !USE_ANIMATIONS_WHEN_OPENING || iconState.useFullTransitionAmount
                 || iconState.useLinearTransitionAmount) {
@@ -465,7 +518,8 @@
                     || row.getTranslationZ() > mAmbientState.getBaseZHeight()))) {
                 iconState.hidden = true;
             }
-            int shelfColor = icon.getStaticDrawableColor();
+            int backgroundColor = getBackgroundColorWithoutTint();
+            int shelfColor = icon.getContrastedStaticDrawableColor(backgroundColor);
             if (!noIcon && shelfColor != StatusBarIconView.NO_COLOR) {
                 int iconColor = row.getVisibleNotificationHeader().getOriginalIconColor();
                 shelfColor = NotificationUtils.interpolateColors(iconColor, shelfColor,
@@ -547,8 +601,7 @@
         if (!hasOverflow) {
             // we have to ensure that adding the low priority notification won't lead to an
             // overflow
-            collapsedPadding -= (1.0f + NotificationIconContainer.OVERFLOW_EARLY_AMOUNT)
-                    * mCollapsedIcons.getIconSize();
+            collapsedPadding -= (1.0f + OVERFLOW_EARLY_AMOUNT) * mCollapsedIcons.getIconSize();
         }
         float padding = NotificationUtils.interpolate(collapsedPadding,
                 mShelfIcons.getPaddingEnd(),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java
index 0e5e416..c45ca54 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java
@@ -21,11 +21,14 @@
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Typeface;
+import android.os.Bundle;
 import android.service.notification.SnoozeCriterion;
 import android.service.notification.StatusBarNotification;
 import android.text.SpannableString;
@@ -35,6 +38,9 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
@@ -45,6 +51,10 @@
 public class NotificationSnooze extends LinearLayout
         implements NotificationGuts.GutsContent, View.OnClickListener {
 
+    /**
+     * If this changes more number increases, more assistant action resId's should be defined for
+     * accessibility purposes, see {@link #setSnoozeOptions(List)}
+     */
     private static final int MAX_ASSISTANT_SUGGESTIONS = 1;
     private NotificationGuts mGutsContainer;
     private NotificationSwipeActionHelper mSnoozeListener;
@@ -79,16 +89,60 @@
         mDivider = findViewById(R.id.divider);
         mDivider.setAlpha(0f);
         mSnoozeOptionContainer = (ViewGroup) findViewById(R.id.snooze_options);
+        mSnoozeOptionContainer.setVisibility(View.INVISIBLE);
         mSnoozeOptionContainer.setAlpha(0f);
 
         // Create the different options based on list
         mSnoozeOptions = getDefaultSnoozeOptions();
         createOptionViews();
 
-        // Default to first option in list
         setSelected(mDefaultOption);
     }
 
+    @Override
+    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+        super.onInitializeAccessibilityEvent(event);
+        if (mGutsContainer != null && mGutsContainer.isExposed()) {
+            if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
+                event.getText().add(mSelectedOptionText.getText());
+            }
+        }
+    }
+
+    @Override
+    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfo(info);
+        info.addAction(new AccessibilityAction(R.id.action_snooze_undo,
+                getResources().getString(R.string.snooze_undo)));
+        int count = mSnoozeOptions.size();
+        for (int i = 0; i < count; i++) {
+            AccessibilityAction action = mSnoozeOptions.get(i).getAccessibilityAction();
+            if (action != null) {
+                info.addAction(action);
+            }
+        }
+    }
+
+    @Override
+    public boolean performAccessibilityActionInternal(int action, Bundle arguments) {
+        if (super.performAccessibilityActionInternal(action, arguments)) {
+            return true;
+        }
+        if (action == R.id.action_snooze_undo) {
+            undoSnooze(mUndoButton);
+            return true;
+        }
+        for (int i = 0; i < mSnoozeOptions.size(); i++) {
+            SnoozeOption so = mSnoozeOptions.get(i);
+            if (so.getAccessibilityAction() != null
+                    && so.getAccessibilityAction().getId() == action) {
+                setSelected(so);
+                return true;
+            }
+        }
+        return false;
+    }
+
     public void setSnoozeOptions(final List<SnoozeCriterion> snoozeList) {
         if (snoozeList == null) {
             return;
@@ -98,7 +152,10 @@
         final int count = Math.min(MAX_ASSISTANT_SUGGESTIONS, snoozeList.size());
         for (int i = 0; i < count; i++) {
             SnoozeCriterion sc = snoozeList.get(i);
-            mSnoozeOptions.add(new SnoozeOption(sc, 0, sc.getExplanation(), sc.getConfirmation()));
+            AccessibilityAction action = new AccessibilityAction(
+                    R.id.action_snooze_assistant_suggestion_1, sc.getExplanation());
+            mSnoozeOptions.add(new NotificationSnoozeOption(sc, 0, sc.getExplanation(),
+                    sc.getConfirmation(), action));
         }
         createOptionViews();
     }
@@ -117,15 +174,16 @@
 
     private ArrayList<SnoozeOption> getDefaultSnoozeOptions() {
         ArrayList<SnoozeOption> options = new ArrayList<>();
-        options.add(createOption(15 /* minutes */));
-        options.add(createOption(30 /* minutes */));
-        mDefaultOption = createOption(60 /* minutes */);
+
+        options.add(createOption(15 /* minutes */, R.id.action_snooze_15_min));
+        options.add(createOption(30 /* minutes */, R.id.action_snooze_30_min));
+        mDefaultOption = createOption(60 /* minutes */, R.id.action_snooze_1_hour);
         options.add(mDefaultOption);
-        options.add(createOption(60 * 2 /* minutes */));
+        options.add(createOption(60 * 2 /* minutes */, R.id.action_snooze_2_hours));
         return options;
     }
 
-    private SnoozeOption createOption(int minutes) {
+    private SnoozeOption createOption(int minutes, int accessibilityActionId) {
         Resources res = getResources();
         boolean showInHours = minutes >= 60;
         int pluralResId = showInHours
@@ -137,7 +195,9 @@
         SpannableString string = new SpannableString(resultText);
         string.setSpan(new StyleSpan(Typeface.BOLD),
                 resultText.length() - description.length(), resultText.length(), 0 /* flags */);
-        return new SnoozeOption(null, minutes, description, string);
+        AccessibilityAction action = new AccessibilityAction(accessibilityActionId, description);
+        return new NotificationSnoozeOption(null, minutes, description, string,
+                action);
     }
 
     private void createOptionViews() {
@@ -149,7 +209,7 @@
             TextView tv = (TextView) inflater.inflate(R.layout.notification_snooze_option,
                     mSnoozeOptionContainer, false);
             mSnoozeOptionContainer.addView(tv);
-            tv.setText(option.description);
+            tv.setText(option.getDescription());
             tv.setTag(option);
             tv.setOnClickListener(this);
         }
@@ -184,18 +244,36 @@
                 mDivider.getAlpha(), show ? 1f : 0f);
         ObjectAnimator optionAnim = ObjectAnimator.ofFloat(mSnoozeOptionContainer, View.ALPHA,
                 mSnoozeOptionContainer.getAlpha(), show ? 1f : 0f);
+        mSnoozeOptionContainer.setVisibility(View.VISIBLE);
         mExpandAnimation = new AnimatorSet();
         mExpandAnimation.playTogether(dividerAnim, optionAnim);
         mExpandAnimation.setDuration(150);
         mExpandAnimation.setInterpolator(show ? Interpolators.ALPHA_IN : Interpolators.ALPHA_OUT);
+        mExpandAnimation.addListener(new AnimatorListenerAdapter() {
+            boolean cancelled = false;
+
+            @Override
+            public void onAnimationCancel(Animator animation) {
+                cancelled = true;
+            }
+
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                if (!show && !cancelled) {
+                    mSnoozeOptionContainer.setVisibility(View.INVISIBLE);
+                    mSnoozeOptionContainer.setAlpha(0f);
+                }
+            }
+        });
         mExpandAnimation.start();
     }
 
     private void setSelected(SnoozeOption option) {
         mSelectedOption = option;
-        mSelectedOptionText.setText(option.confirmation);
+        mSelectedOptionText.setText(option.getConfirmation());
         showSnoozeOptions(false);
         hideSelectedOption();
+        sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
     }
 
     @Override
@@ -212,20 +290,24 @@
             showSnoozeOptions(!mExpanded);
         } else {
             // Undo snooze was selected
-            mSelectedOption = null;
-            int[] parentLoc = new int[2];
-            int[] targetLoc = new int[2];
-            mGutsContainer.getLocationOnScreen(parentLoc);
-            v.getLocationOnScreen(targetLoc);
-            final int centerX = v.getWidth() / 2;
-            final int centerY = v.getHeight() / 2;
-            final int x = targetLoc[0] - parentLoc[0] + centerX;
-            final int y = targetLoc[1] - parentLoc[1] + centerY;
-            showSnoozeOptions(false);
-            mGutsContainer.closeControls(x, y, false /* save */, false /* force */);
+            undoSnooze(v);
         }
     }
 
+    private void undoSnooze(View v) {
+        mSelectedOption = null;
+        int[] parentLoc = new int[2];
+        int[] targetLoc = new int[2];
+        mGutsContainer.getLocationOnScreen(parentLoc);
+        v.getLocationOnScreen(targetLoc);
+        final int centerX = v.getWidth() / 2;
+        final int centerY = v.getHeight() / 2;
+        final int x = targetLoc[0] - parentLoc[0] + centerX;
+        final int y = targetLoc[1] - parentLoc[1] + centerY;
+        showSnoozeOptions(false);
+        mGutsContainer.closeControls(x, y, false /* save */, false /* force */);
+    }
+
     @Override
     public int getActualHeight() {
         return mExpanded ? getHeight() : mCollapsedHeight;
@@ -270,4 +352,48 @@
     public boolean isLeavebehind() {
         return true;
     }
+
+    public class NotificationSnoozeOption implements SnoozeOption {
+        private SnoozeCriterion mCriterion;
+        private int mMinutesToSnoozeFor;
+        private CharSequence mDescription;
+        private CharSequence mConfirmation;
+        private AccessibilityAction mAction;
+
+        public NotificationSnoozeOption(SnoozeCriterion sc, int minToSnoozeFor,
+                CharSequence description,
+                CharSequence confirmation, AccessibilityAction action) {
+            mCriterion = sc;
+            mMinutesToSnoozeFor = minToSnoozeFor;
+            mDescription = description;
+            mConfirmation = confirmation;
+            mAction = action;
+        }
+
+        @Override
+        public SnoozeCriterion getSnoozeCriterion() {
+            return mCriterion;
+        }
+
+        @Override
+        public CharSequence getDescription() {
+            return mDescription;
+        }
+
+        @Override
+        public CharSequence getConfirmation() {
+            return mConfirmation;
+        }
+
+        @Override
+        public int getMinutesToSnoozeFor() {
+            return mMinutesToSnoozeFor;
+        }
+
+        @Override
+        public AccessibilityAction getAccessibilityAction() {
+            return mAction;
+        }
+
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 3c7ddb5..89694b33 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -35,6 +35,7 @@
 import android.os.Parcelable;
 import android.os.UserHandle;
 import android.service.notification.StatusBarNotification;
+import android.support.v4.graphics.ColorUtils;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.FloatProperty;
@@ -46,6 +47,7 @@
 import android.view.animation.Interpolator;
 
 import com.android.internal.statusbar.StatusBarIcon;
+import com.android.internal.util.NotificationColorUtil;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.notification.NotificationIconDozeHelper;
@@ -127,6 +129,8 @@
         setColorInternal(newColor);
     };
     private final NotificationIconDozeHelper mDozer;
+    private int mContrastedDrawableColor;
+    private int mCachedContrastBackgroundColor = NO_COLOR;
 
     public StatusBarIconView(Context context, String slot, StatusBarNotification sbn) {
         this(context, slot, sbn, false);
@@ -528,6 +532,7 @@
     public void setStaticDrawableColor(int color) {
         mDrawableColor = color;
         setColorInternal(color);
+        updateContrastedStaticColor();
         mIconColor = color;
         mDozer.setColor(color);
     }
@@ -580,6 +585,43 @@
         return mDrawableColor;
     }
 
+    /**
+     * A drawable color that passes GAR on a specific background.
+     * This value is cached.
+     *
+     * @param backgroundColor Background to test against.
+     * @return GAR safe version of {@link StatusBarIconView#getStaticDrawableColor()}.
+     */
+    int getContrastedStaticDrawableColor(int backgroundColor) {
+        if (mCachedContrastBackgroundColor != backgroundColor) {
+            mCachedContrastBackgroundColor = backgroundColor;
+            updateContrastedStaticColor();
+        }
+        return mContrastedDrawableColor;
+    }
+
+    private void updateContrastedStaticColor() {
+        if (Color.alpha(mCachedContrastBackgroundColor) != 255) {
+            mContrastedDrawableColor = mDrawableColor;
+            return;
+        }
+        // We'll modify the color if it doesn't pass GAR
+        int contrastedColor = mDrawableColor;
+        if (!NotificationColorUtil.satisfiesTextContrast(mCachedContrastBackgroundColor,
+                contrastedColor)) {
+            float[] hsl = new float[3];
+            ColorUtils.colorToHSL(mDrawableColor, hsl);
+            // This is basically a light grey, pushing the color will only distort it.
+            // Best thing to do in here is to fallback to the default color.
+            if (hsl[1] < 0.2f) {
+                contrastedColor = Notification.COLOR_DEFAULT;
+            }
+            contrastedColor = NotificationColorUtil.resolveContrastColor(mContext,
+                    contrastedColor, mCachedContrastBackgroundColor);
+        }
+        mContrastedDrawableColor = contrastedColor;
+    }
+
     public void setVisibleState(int state) {
         setVisibleState(state, true /* animate */, null /* endRunnable */);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index c608a85..680f693 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -76,6 +76,7 @@
     private Drawable mNotificationPanelBackground;
 
     private ConnectedDeviceSignalController mConnectedDeviceSignalController;
+    private ViewGroup mNavigationBarWindow;
     private CarNavigationBarView mNavigationBarView;
 
     private final Object mQueueLock = new Object();
@@ -97,6 +98,11 @@
         mCarBatteryController.stopListening();
         mConnectedDeviceSignalController.stopListening();
 
+        if (mNavigationBarWindow != null) {
+            mWindowManager.removeViewImmediate(mNavigationBarWindow);
+            mNavigationBarView = null;
+        }
+
         super.destroy();
     }
 
@@ -153,10 +159,19 @@
         // SystemUI requires that the navigation bar view have a parent. Since the regular
         // StatusBar inflates navigation_bar_window as this parent view, use the same view for the
         // CarNavigationBarView.
-        ViewGroup navigationBarWindow = (ViewGroup) View.inflate(mContext,
+        mNavigationBarWindow = (ViewGroup) View.inflate(mContext,
                 R.layout.navigation_bar_window, null);
-        View.inflate(mContext, R.layout.car_navigation_bar, navigationBarWindow);
-        mNavigationBarView = (CarNavigationBarView) navigationBarWindow.getChildAt(0);
+        if (mNavigationBarWindow == null) {
+            Log.e(TAG, "CarStatusBar failed inflate for R.layout.navigation_bar_window");
+        }
+
+
+        View.inflate(mContext, R.layout.car_navigation_bar, mNavigationBarWindow);
+        mNavigationBarView = (CarNavigationBarView) mNavigationBarWindow.getChildAt(0);
+        if (mNavigationBarView == null) {
+            Log.e(TAG, "CarStatusBar failed inflate for R.layout.car_navigation_bar");
+        }
+
 
         mController = new CarNavigationBarController(mContext, mNavigationBarView,
                 this /* ActivityStarter*/);
@@ -173,7 +188,7 @@
         lp.setTitle("CarNavigationBar");
         lp.windowAnimations = 0;
 
-        mWindowManager.addView(navigationBarWindow, lp);
+        mWindowManager.addView(mNavigationBarWindow, lp);
     }
 
     @Override
@@ -219,6 +234,11 @@
     }
 
     @Override
+    public View getNavigationBarWindow() {
+        return mNavigationBarWindow;
+    }
+
+    @Override
     protected View.OnTouchListener getStatusBarWindowTouchListener() {
         // Usually, a touch on the background window will dismiss the notification shade. However,
         // for the car use-case, the shade should remain unless the user switches to a different
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
index 720ca14..09ae521 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
@@ -19,9 +19,11 @@
 import android.content.res.Configuration;
 import android.graphics.drawable.Icon;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.util.SparseArray;
 import android.view.Display;
 import android.view.Display.Mode;
+import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -35,6 +37,7 @@
 import com.android.systemui.plugins.PluginListener;
 import com.android.systemui.plugins.PluginManager;
 import com.android.systemui.plugins.statusbar.phone.NavBarButtonProvider;
+import com.android.systemui.statusbar.phone.ReverseLinearLayout.ReverseFrameLayout;
 import com.android.systemui.statusbar.policy.KeyButtonView;
 import com.android.systemui.tuner.TunerService;
 import com.android.systemui.tuner.TunerService.Tunable;
@@ -43,6 +46,8 @@
 import java.util.List;
 import java.util.Objects;
 
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+
 public class NavigationBarInflaterView extends FrameLayout
         implements Tunable, PluginListener<NavBarButtonProvider> {
 
@@ -71,6 +76,8 @@
     public static final String KEY_CODE_START = "(";
     public static final String KEY_IMAGE_DELIM = ":";
     public static final String KEY_CODE_END = ")";
+    private static final String WEIGHT_SUFFIX = "W";
+    private static final String WEIGHT_CENTERED_SUFFIX = "WC";
 
     private final List<NavBarButtonProvider> mPlugins = new ArrayList<>();
 
@@ -219,26 +226,27 @@
         String[] center = sets[1].split(BUTTON_SEPARATOR);
         String[] end = sets[2].split(BUTTON_SEPARATOR);
         // Inflate these in start to end order or accessibility traversal will be messed up.
-        inflateButtons(start, (ViewGroup) mRot0.findViewById(R.id.ends_group), isRot0Landscape);
-        inflateButtons(start, (ViewGroup) mRot90.findViewById(R.id.ends_group), !isRot0Landscape);
+        inflateButtons(start, mRot0.findViewById(R.id.ends_group), isRot0Landscape, true);
+        inflateButtons(start, mRot90.findViewById(R.id.ends_group), !isRot0Landscape, true);
 
-        inflateButtons(center, (ViewGroup) mRot0.findViewById(R.id.center_group), isRot0Landscape);
-        inflateButtons(center, (ViewGroup) mRot90.findViewById(R.id.center_group), !isRot0Landscape);
+        inflateButtons(center, mRot0.findViewById(R.id.center_group), isRot0Landscape, false);
+        inflateButtons(center, mRot90.findViewById(R.id.center_group), !isRot0Landscape, false);
 
-        addGravitySpacer((LinearLayout) mRot0.findViewById(R.id.ends_group));
-        addGravitySpacer((LinearLayout) mRot90.findViewById(R.id.ends_group));
+        addGravitySpacer(mRot0.findViewById(R.id.ends_group));
+        addGravitySpacer(mRot90.findViewById(R.id.ends_group));
 
-        inflateButtons(end, (ViewGroup) mRot0.findViewById(R.id.ends_group), isRot0Landscape);
-        inflateButtons(end, (ViewGroup) mRot90.findViewById(R.id.ends_group), !isRot0Landscape);
+        inflateButtons(end, mRot0.findViewById(R.id.ends_group), isRot0Landscape, false);
+        inflateButtons(end, mRot90.findViewById(R.id.ends_group), !isRot0Landscape, false);
     }
 
     private void addGravitySpacer(LinearLayout layout) {
         layout.addView(new Space(mContext), new LinearLayout.LayoutParams(0, 0, 1));
     }
 
-    private void inflateButtons(String[] buttons, ViewGroup parent, boolean landscape) {
+    private void inflateButtons(String[] buttons, ViewGroup parent, boolean landscape,
+            boolean start) {
         for (int i = 0; i < buttons.length; i++) {
-            inflateButton(buttons[i], parent, landscape);
+            inflateButton(buttons[i], parent, landscape, start);
         }
     }
 
@@ -251,16 +259,13 @@
     }
 
     @Nullable
-    protected View inflateButton(String buttonSpec, ViewGroup parent, boolean landscape) {
+    protected View inflateButton(String buttonSpec, ViewGroup parent, boolean landscape,
+            boolean start) {
         LayoutInflater inflater = landscape ? mLandscapeInflater : mLayoutInflater;
-        float size = extractSize(buttonSpec);
-        View v = createView(buttonSpec, parent, inflater, landscape);
+        View v = createView(buttonSpec, parent, inflater);
         if (v == null) return null;
 
-        if (size != 0) {
-            ViewGroup.LayoutParams params = v.getLayoutParams();
-            params.width = (int) (params.width * size);
-        }
+        v = applySize(v, buttonSpec, landscape, start);
         parent.addView(v);
         addToDispatchers(v);
         View lastView = landscape ? mLastLandscape : mLastPortrait;
@@ -275,16 +280,41 @@
         return v;
     }
 
-    private View createView(String buttonSpec, ViewGroup parent, LayoutInflater inflater,
-            boolean landscape) {
+    private View applySize(View v, String buttonSpec, boolean landscape, boolean start) {
+        String sizeStr = extractSize(buttonSpec);
+        if (sizeStr == null) return v;
+
+        if (sizeStr.contains(WEIGHT_SUFFIX)) {
+            float weight = Float.parseFloat(sizeStr.substring(0, sizeStr.indexOf(WEIGHT_SUFFIX)));
+            FrameLayout frame = new ReverseFrameLayout(mContext);
+            LayoutParams childParams = new LayoutParams(v.getLayoutParams());
+            if (sizeStr.endsWith(WEIGHT_CENTERED_SUFFIX)) {
+                childParams.gravity = Gravity.CENTER;
+            } else {
+                childParams.gravity = landscape ? (start ? Gravity.BOTTOM : Gravity.TOP)
+                        : (start ? Gravity.START : Gravity.END);
+            }
+            frame.addView(v, childParams);
+            frame.setLayoutParams(new LinearLayout.LayoutParams(0, MATCH_PARENT, weight));
+            frame.setClipChildren(false);
+            frame.setClipToPadding(false);
+            return frame;
+        }
+        float size = Float.parseFloat(sizeStr);
+        ViewGroup.LayoutParams params = v.getLayoutParams();
+        params.width = (int) (params.width * size);
+        return v;
+    }
+
+    private View createView(String buttonSpec, ViewGroup parent, LayoutInflater inflater) {
         View v = null;
         String button = extractButton(buttonSpec);
         if (LEFT.equals(button)) {
-            buttonSpec = Dependency.get(TunerService.class).getValue(NAV_BAR_LEFT, NAVSPACE);
-            button = extractButton(buttonSpec);
+            String s = Dependency.get(TunerService.class).getValue(NAV_BAR_LEFT, NAVSPACE);
+            button = extractButton(s);
         } else if (RIGHT.equals(button)) {
-            buttonSpec = Dependency.get(TunerService.class).getValue(NAV_BAR_RIGHT, MENU_IME);
-            button = extractButton(buttonSpec);
+            String s = Dependency.get(TunerService.class).getValue(NAV_BAR_RIGHT, MENU_IME);
+            button = extractButton(s);
         }
         // Let plugins go first so they can override a standard view if they want.
         for (NavBarButtonProvider provider : mPlugins) {
@@ -340,13 +370,12 @@
         return Integer.parseInt(subStr);
     }
 
-    public static float extractSize(String buttonSpec) {
+    public static String extractSize(String buttonSpec) {
         if (!buttonSpec.contains(SIZE_MOD_START)) {
-            return 1;
+            return null;
         }
         final int sizeStart = buttonSpec.indexOf(SIZE_MOD_START);
-        String sizeStr = buttonSpec.substring(sizeStart + 1, buttonSpec.indexOf(SIZE_MOD_END));
-        return Float.parseFloat(sizeStr);
+        return buttonSpec.substring(sizeStart + 1, buttonSpec.indexOf(SIZE_MOD_END));
     }
 
     public static String extractButton(String buttonSpec) {
@@ -379,8 +408,8 @@
                 mButtonDispatchers.valueAt(i).clear();
             }
         }
-        clearAllChildren((ViewGroup) mRot0.findViewById(R.id.nav_buttons));
-        clearAllChildren((ViewGroup) mRot90.findViewById(R.id.nav_buttons));
+        clearAllChildren(mRot0.findViewById(R.id.nav_buttons));
+        clearAllChildren(mRot90.findViewById(R.id.nav_buttons));
     }
 
     private void clearAllChildren(ViewGroup group) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index 3937dd3..38c8d31 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -526,6 +526,7 @@
     }
 
     public class IconState extends ViewState {
+        public static final int NO_VALUE = NotificationIconContainer.NO_VALUE;
         public float iconAppearAmount = 1.0f;
         public float clampedAppearAmount = 1.0f;
         public int visibleState;
@@ -538,6 +539,8 @@
         public boolean justUndarkened;
         public int iconColor = StatusBarIconView.NO_COLOR;
         public boolean noAnimations;
+        public boolean isLastExpandIcon;
+        public int customTransformHeight = NO_VALUE;
 
         @Override
         public void applyToView(View view) {
@@ -615,6 +618,10 @@
             justUndarkened = false;
         }
 
+        public boolean hasCustomTransformHeight() {
+            return isLastExpandIcon && customTransformHeight != NO_VALUE;
+        }
+
         @Override
         public void initFrom(View view) {
             super.initFrom(view);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 95c2fc8..16d85be 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -304,10 +304,10 @@
                 trackMovement(event);
                 if (!mGestureWaitForTouchSlop || (mHeightAnimator != null && !mHintAnimationRunning)
                         || mPeekAnimator != null) {
-                    cancelHeightAnimator();
-                    cancelPeek();
                     mTouchSlopExceeded = (mHeightAnimator != null && !mHintAnimationRunning)
                             || mPeekAnimator != null;
+                    cancelHeightAnimator();
+                    cancelPeek();
                     onTrackingStarted();
                 }
                 if (isFullyCollapsed() && !mHeadsUpManager.hasPinnedHeadsUp()) {
@@ -612,6 +612,9 @@
 
     protected void cancelHeightAnimator() {
         if (mHeightAnimator != null) {
+            if (mHeightAnimator.isRunning()) {
+                mPanelUpdateWhenAnimatorEnds = false;
+            }
             mHeightAnimator.cancel();
         }
         endClosing();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java
index f45967a..bcbc345 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java
@@ -16,10 +16,10 @@
 
 import android.annotation.Nullable;
 import android.content.Context;
-import android.content.res.Configuration;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.FrameLayout;
 import android.widget.LinearLayout;
 
 import java.util.ArrayList;
@@ -48,7 +48,7 @@
 
     @Override
     public void addView(View child) {
-        reversParams(child.getLayoutParams());
+        reverseParams(child.getLayoutParams(), child);
         if (mIsLayoutReverse) {
             super.addView(child, 0);
         } else {
@@ -58,7 +58,7 @@
 
     @Override
     public void addView(View child, ViewGroup.LayoutParams params) {
-        reversParams(params);
+        reverseParams(params, child);
         if (mIsLayoutReverse) {
             super.addView(child, 0, params);
         } else {
@@ -100,7 +100,15 @@
         }
     }
 
-    private void reversParams(ViewGroup.LayoutParams params) {
+    private static void reverseParams(ViewGroup.LayoutParams params, View child) {
+        if (child instanceof Reversable) {
+            ((Reversable) child).reverse();
+        }
+        if (child.getPaddingLeft() == child.getPaddingRight()
+                && child.getPaddingTop() == child.getPaddingBottom()) {
+            child.setPadding(child.getPaddingTop(), child.getPaddingLeft(),
+                    child.getPaddingTop(), child.getPaddingLeft());
+        }
         if (params == null) {
             return;
         }
@@ -109,4 +117,23 @@
         params.height = width;
     }
 
+    public interface Reversable {
+        void reverse();
+    }
+
+    public static class ReverseFrameLayout extends FrameLayout implements Reversable {
+
+        public ReverseFrameLayout(Context context) {
+            super(context);
+        }
+
+        @Override
+        public void reverse() {
+            for (int i = 0; i < getChildCount(); i++) {
+                View child = getChildAt(i);
+                reverseParams(child.getLayoutParams(), child);
+            }
+        }
+    }
+
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 9275358..754c344 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -61,11 +61,11 @@
     public static final float GRADIENT_SCRIM_ALPHA = 0.45f;
     // A scrim varies its opacity based on a busyness factor, for example
     // how many notifications are currently visible.
-    public static final float GRADIENT_SCRIM_ALPHA_BUSY = 0.90f;
+    public static final float GRADIENT_SCRIM_ALPHA_BUSY = 0.70f;
     protected static final float SCRIM_BEHIND_ALPHA_KEYGUARD = GRADIENT_SCRIM_ALPHA;
     protected static final float SCRIM_BEHIND_ALPHA_UNLOCKING = 0.2f;
-    private static final float SCRIM_IN_FRONT_ALPHA = GRADIENT_SCRIM_ALPHA;
-    private static final float SCRIM_IN_FRONT_ALPHA_LOCKED = GRADIENT_SCRIM_ALPHA;
+    private static final float SCRIM_IN_FRONT_ALPHA = GRADIENT_SCRIM_ALPHA_BUSY;
+    private static final float SCRIM_IN_FRONT_ALPHA_LOCKED = GRADIENT_SCRIM_ALPHA_BUSY;
     private static final int TAG_KEY_ANIM = R.id.scrim;
     private static final int TAG_KEY_ANIM_TARGET = R.id.scrim_target;
     private static final int TAG_START_ALPHA = R.id.scrim_alpha_start;
@@ -81,9 +81,7 @@
 
     private final SysuiColorExtractor mColorExtractor;
     private ColorExtractor.GradientColors mLockColors;
-    private ColorExtractor.GradientColors mLockColorsDark;
     private ColorExtractor.GradientColors mSystemColors;
-    private ColorExtractor.GradientColors mSystemColorsDark;
     private boolean mNeedsDrawableColorUpdate;
 
     protected float mScrimBehindAlpha;
@@ -135,13 +133,8 @@
         mColorExtractor = Dependency.get(SysuiColorExtractor.class);
         mColorExtractor.addOnColorsChangedListener(this);
         mLockColors = mColorExtractor.getColors(WallpaperManager.FLAG_LOCK,
-                ColorExtractor.TYPE_NORMAL, true /* ignoreVisibility */);
-        mSystemColors = mColorExtractor.getColors(WallpaperManager.FLAG_SYSTEM,
-                ColorExtractor.TYPE_NORMAL, true /* ignoreVisibility */);
-        // Darker gradient for the top scrim (mScrimInFront)
-        mLockColorsDark = mColorExtractor.getColors(WallpaperManager.FLAG_LOCK,
                 ColorExtractor.TYPE_DARK, true /* ignoreVisibility */);
-        mSystemColorsDark = mColorExtractor.getColors(WallpaperManager.FLAG_SYSTEM,
+        mSystemColors = mColorExtractor.getColors(WallpaperManager.FLAG_SYSTEM,
                 ColorExtractor.TYPE_DARK, true /* ignoreVisibility */);
         mNeedsDrawableColorUpdate = true;
 
@@ -311,13 +304,13 @@
             mNeedsDrawableColorUpdate = false;
             if (mKeyguardShowing) {
                 // Always animate color changes if we're seeing the keyguard
-                mScrimInFront.setColors(mLockColorsDark);
+                mScrimInFront.setColors(mLockColors);
                 mScrimBehind.setColors(mLockColors);
             } else {
                 // Only animate scrim color if the scrim view is actually visible
                 boolean animateScrimInFront = mScrimInFront.getViewAlpha() != 0;
                 boolean animateScrimBehind = mScrimBehind.getViewAlpha() != 0;
-                mScrimInFront.setColors(mSystemColorsDark, animateScrimInFront);
+                mScrimInFront.setColors(mSystemColors, animateScrimInFront);
                 mScrimBehind.setColors(mSystemColors, animateScrimBehind);
             }
         }
@@ -663,16 +656,12 @@
     public void onColorsChanged(ColorExtractor colorExtractor, int which) {
         if ((which & WallpaperManager.FLAG_LOCK) != 0) {
             mLockColors = mColorExtractor.getColors(WallpaperManager.FLAG_LOCK,
-                    ColorExtractor.TYPE_NORMAL, true /* ignoreVisibility */);
-            mLockColorsDark = mColorExtractor.getColors(WallpaperManager.FLAG_LOCK,
                     ColorExtractor.TYPE_DARK, true /* ignoreVisibility */);
             mNeedsDrawableColorUpdate = true;
             scheduleUpdate();
         }
         if ((which & WallpaperManager.FLAG_SYSTEM) != 0) {
             mSystemColors = mColorExtractor.getColors(WallpaperManager.FLAG_SYSTEM,
-                    ColorExtractor.TYPE_NORMAL, mKeyguardShowing);
-            mSystemColorsDark = mColorExtractor.getColors(WallpaperManager.FLAG_SYSTEM,
                     ColorExtractor.TYPE_DARK, mKeyguardShowing);
             mNeedsDrawableColorUpdate = true;
             scheduleUpdate();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java
index 083da51..deea521 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java
@@ -21,13 +21,15 @@
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
+import android.graphics.Matrix;
 import android.graphics.Paint;
-import android.graphics.Paint.Style;
 import android.graphics.Path;
 import android.graphics.Path.Direction;
 import android.graphics.Path.FillType;
 import android.graphics.Path.Op;
+import android.graphics.PointF;
 import android.graphics.Rect;
+import android.graphics.RectF;
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
 import android.util.LayoutDirection;
@@ -63,6 +65,7 @@
     private static final int STATE_EMPTY = 1;
     private static final int STATE_CUT = 2;
     private static final int STATE_CARRIER_CHANGE = 3;
+    private static final int STATE_AIRPLANE = 4;
 
     private static final long DOT_DELAY = 1000;
 
@@ -97,6 +100,17 @@
     // How far the circle defining the corners is inset from the edges
     private final float mAppliedCornerInset;
 
+    // The easiest way to understand this is as if we set Style.STROKE and draw the triangle,
+    // but that is only theoretically right. Instead, draw the triangle and clip out a smaller
+    // one inset by this amount.
+    private final float mEmptyStrokeWidth;
+    private static final float INV_TAN = 1f / (float) Math.tan(Math.PI / 8f);
+    private final float mEmptyDiagInset;  // == mEmptyStrokeWidth * INV_TAN
+
+    // Where the top and left points of the triangle would be if not for rounding
+    private final PointF mVirtualTop  = new PointF();
+    private final PointF mVirtualLeft = new PointF();
+
     private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
     private final Paint mForegroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
     private final int mDarkModeBackgroundColor;
@@ -106,6 +120,10 @@
     private final Path mFullPath = new Path();
     private final Path mForegroundPath = new Path();
     private final Path mXPath = new Path();
+    // Cut out when STATE_EMPTY
+    private final Path mCutPath = new Path();
+    // Draws the slash when in airplane mode
+    private final SlashArtist mSlash = new SlashArtist();
     private final Handler mHandler;
     private float mOldDarkIntensity = -1;
     private float mNumLevels = 1;
@@ -126,6 +144,12 @@
         mLightModeFillColor =
                 Utils.getDefaultColor(context, R.color.light_mode_icon_color_dual_tone_fill);
         mIntrinsicSize = context.getResources().getDimensionPixelSize(R.dimen.signal_icon_size);
+
+        // mCutPath parameters
+        mEmptyStrokeWidth = context.getResources()
+                .getDimensionPixelSize(R.dimen.mobile_signal_empty_strokewidth);
+        mEmptyDiagInset = mEmptyStrokeWidth * INV_TAN;
+
         mHandler = new Handler();
         setDarkIntensity(0);
 
@@ -224,9 +248,10 @@
         }
         mFullPath.reset();
         mFullPath.setFillType(FillType.WINDING);
+
         final float width = getBounds().width();
         final float height = getBounds().height();
-        final float padding = (int) (PAD * width);  // Stay on pixel boundary
+        final float padding = Math.round(PAD * width);
         final float cornerRadius = RADIUS_RATIO * height;
         // Offset from circle where the hypotenuse meets the circle
         final float diagOffset = DIAG_OFFSET_MULTIPLIER * cornerRadius;
@@ -292,10 +317,37 @@
             mFullPath.rLineTo(0, cut);
         }
 
-        mPaint.setStyle(mState == STATE_EMPTY ? Style.STROKE : Style.FILL);
-        mForegroundPaint.setStyle(mState == STATE_EMPTY ? Style.STROKE : Style.FILL);
+        if (mState == STATE_EMPTY) {
+            // Where the corners would be if this were a real triangle
+            mVirtualTop.set(
+                    width - padding,
+                    (padding + cornerRadius + mAppliedCornerInset) - (INV_TAN * cornerRadius));
+            mVirtualLeft.set(
+                    (padding + cornerRadius + mAppliedCornerInset) - (INV_TAN * cornerRadius),
+                    height - padding);
 
-        if (mState != STATE_CARRIER_CHANGE) {
+            // Cut out a smaller triangle from the center of mFullPath
+            mCutPath.reset();
+            mCutPath.setFillType(FillType.WINDING);
+            mCutPath.moveTo(width - padding - mEmptyStrokeWidth,
+                    height - padding - mEmptyStrokeWidth);
+            mCutPath.lineTo(width - padding - mEmptyStrokeWidth,
+                    mVirtualTop.y + mEmptyDiagInset);
+            mCutPath.lineTo(mVirtualLeft.x + mEmptyDiagInset,
+                    height - padding - mEmptyStrokeWidth);
+            mCutPath.lineTo(width - padding - mEmptyStrokeWidth,
+                    height - padding - mEmptyStrokeWidth);
+
+            // In empty state, draw the full path as the foreground paint
+            mForegroundPath.set(mFullPath);
+            mFullPath.reset();
+            mForegroundPath.op(mCutPath, Path.Op.DIFFERENCE);
+        } else if (mState == STATE_AIRPLANE) {
+            // Airplane mode is slashed, full-signal
+            mForegroundPath.set(mFullPath);
+            mFullPath.reset();
+            mSlash.draw((int) height, (int) width, canvas, mForegroundPaint);
+        } else if (mState != STATE_CARRIER_CHANGE) {
             mForegroundPath.reset();
             int sigWidth = Math.round(calcFit(mLevel / (mNumLevels - 1)) * (width - 2 * padding));
             mForegroundPath.addRect(padding, padding, padding + sigWidth, height - padding,
@@ -405,4 +457,65 @@
     public static int getEmptyState(int numLevels) {
         return (STATE_EMPTY << STATE_SHIFT) | (numLevels << NUM_LEVEL_SHIFT);
     }
+
+    public static int getAirplaneModeState(int numLevels) {
+        return (STATE_AIRPLANE << STATE_SHIFT) | (numLevels << NUM_LEVEL_SHIFT);
+    }
+
+    private final class SlashArtist {
+        // These values are derived in un-rotated (vertical) orientation
+        private static final float SLASH_WIDTH = 1.8384776f;
+        private static final float SLASH_HEIGHT = 22f;
+        private static final float CENTER_X = 10.65f;
+        private static final float CENTER_Y = 15.869239f;
+        private static final float SCALE = 24f;
+
+        // Bottom is derived during animation
+        private static final float LEFT = (CENTER_X - (SLASH_WIDTH / 2)) / SCALE;
+        private static final float TOP = (CENTER_Y - (SLASH_HEIGHT / 2)) / SCALE;
+        private static final float RIGHT = (CENTER_X + (SLASH_WIDTH / 2)) / SCALE;
+        private static final float BOTTOM = (CENTER_Y + (SLASH_HEIGHT / 2)) / SCALE;
+        // Draw the slash washington-monument style; rotate to no-u-turn style
+        private static final float ROTATION = -45f;
+
+        private final Path mPath = new Path();
+        private final RectF mSlashRect = new RectF();
+
+        void draw(int height, int width, @NonNull Canvas canvas, Paint paint) {
+            Matrix m = new Matrix();
+            updateRect(
+                    scale(LEFT, width),
+                    scale(TOP, height),
+                    scale(RIGHT, width),
+                    scale(BOTTOM, height));
+
+            mPath.reset();
+            // Draw the slash vertically
+            mPath.addRect(mSlashRect, Direction.CW);
+            m.setRotate(ROTATION, width / 2, height / 2);
+            mPath.transform(m);
+            canvas.drawPath(mPath, paint);
+
+            // Rotate back to vertical, and draw the cut-out rect next to this one
+            m.setRotate(-ROTATION, width / 2, height / 2);
+            mPath.transform(m);
+            m.setTranslate(mSlashRect.width(), 0);
+            mPath.transform(m);
+            mPath.addRect(mSlashRect, Direction.CW);
+            m.setRotate(ROTATION, width / 2, height / 2);
+            mPath.transform(m);
+            canvas.clipOutPath(mPath);
+        }
+
+        void updateRect(float left, float top, float right, float bottom) {
+            mSlashRect.left = left;
+            mSlashRect.top = top;
+            mSlashRect.right = right;
+            mSlashRect.bottom = bottom;
+        }
+
+        private float scale(float frac, int width) {
+            return frac * width;
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index e3b3c4c..4d6fd9c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -3465,7 +3465,9 @@
         pw.println(Settings.Global.zenModeToString(mZenMode));
         pw.print("  mUseHeadsUp=");
         pw.println(mUseHeadsUp);
-        dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions());
+        if (mStatusBarView != null) {
+            dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions());
+        }
 
         pw.print("  mMediaSessionManager=");
         pw.println(mMediaSessionManager);
@@ -3531,7 +3533,9 @@
             pw.println("  mGroupManager: null");
         }
 
-        mLightBarController.dump(fd, pw, args);
+        if (mLightBarController != null) {
+            mLightBarController.dump(fd, pw, args);
+        }
 
         if (KeyguardUpdateMonitor.getInstance(mContext) != null) {
             KeyguardUpdateMonitor.getInstance(mContext).dump(fd, pw, args);
@@ -6080,11 +6084,12 @@
     }
 
     public void setNotificationSnoozed(StatusBarNotification sbn, SnoozeOption snoozeOption) {
-        if (snoozeOption.criterion != null) {
-            mNotificationListener.snoozeNotification(sbn.getKey(), snoozeOption.criterion.getId());
+        if (snoozeOption.getSnoozeCriterion() != null) {
+            mNotificationListener.snoozeNotification(sbn.getKey(),
+                    snoozeOption.getSnoozeCriterion().getId());
         } else {
             mNotificationListener.snoozeNotification(sbn.getKey(),
-                    snoozeOption.snoozeForMinutes * 60 * 1000);
+                    snoozeOption.getMinutesToSnoozeFor() * 60 * 1000);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index d777961..2d3e0b6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -226,6 +226,9 @@
             case MotionEvent.ACTION_UP:
                 final boolean doIt = isPressed() && !mLongClicked;
                 setPressed(false);
+                // Always send a release ourselves because it doesn't seem to be sent elsewhere
+                // and it feels weird to sometimes get a release haptic and other times not.
+                performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY_RELEASE);
                 if (mCode != 0) {
                     if (doIt) {
                         sendEvent(KeyEvent.ACTION_UP, 0);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
index 3f5f5a0..874f0d9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
@@ -31,8 +31,10 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
+import android.support.annotation.VisibleForTesting;
 
 import com.android.systemui.R;
+import com.android.systemui.util.Utils;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -141,7 +143,8 @@
     /**
      * Returns true if there currently exist active high power location requests.
      */
-    private boolean areActiveHighPowerLocationRequests() {
+    @VisibleForTesting
+    protected boolean areActiveHighPowerLocationRequests() {
         List<AppOpsManager.PackageOps> packages
             = mAppOpsManager.getPackagesForOps(mHighPowerRequestAppOpArray);
         // AppOpsManager can return null when there is no requested data.
@@ -205,16 +208,14 @@
         }
 
         private void locationActiveChanged() {
-            for (LocationChangeCallback cb : mSettingsChangeCallbacks) {
-                cb.onLocationActiveChanged(mAreActiveLocationRequests);
-            }
+            Utils.safeForeach(mSettingsChangeCallbacks,
+                    cb -> cb.onLocationActiveChanged(mAreActiveLocationRequests));
         }
 
         private void locationSettingsChanged() {
             boolean isEnabled = isLocationEnabled();
-            for (LocationChangeCallback cb : mSettingsChangeCallbacks) {
-                cb.onLocationSettingsChanged(isEnabled);
-            }
+            Utils.safeForeach(mSettingsChangeCallbacks,
+                    cb -> cb.onLocationSettingsChanged(isEnabled));
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index 67b5596..b6c7655 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -235,6 +235,9 @@
     }
 
     private int getNumLevels() {
+        if (mConfig.inflateSignalStrengths) {
+            return SignalStrength.NUM_SIGNAL_STRENGTH_BINS + 1;
+        }
         return SignalStrength.NUM_SIGNAL_STRENGTH_BINS;
     }
 
@@ -243,7 +246,11 @@
         if (mCurrentState.iconGroup == TelephonyIcons.CARRIER_NETWORK_CHANGE) {
             return SignalDrawable.getCarrierChangeState(getNumLevels());
         } else if (mCurrentState.connected) {
-            return SignalDrawable.getState(mCurrentState.level, getNumLevels(),
+            int level = mCurrentState.level;
+            if (mConfig.inflateSignalStrengths) {
+                level++;
+            }
+            return SignalDrawable.getState(level, getNumLevels(),
                     mCurrentState.inetCondition == 0);
         } else if (mCurrentState.enabled) {
             return SignalDrawable.getEmptyState(getNumLevels());
@@ -254,6 +261,10 @@
 
     @Override
     public int getQsCurrentIconId() {
+        if (mCurrentState.airplaneMode) {
+            return SignalDrawable.getAirplaneModeState(getNumLevels());
+        }
+
         return getCurrentIconId();
     }
 
@@ -330,6 +341,10 @@
     }
 
     private boolean isRoaming() {
+        // During a carrier change, roaming indications need to be supressed.
+        if (isCarrierNetworkChangeActive()) {
+            return false;
+        }
         if (isCdma()) {
             final int iconMode = mServiceState.getCdmaEriIconMode();
             return mServiceState.getCdmaEriIconIndex() != EriInfo.ROAMING_INDICATOR_OFF
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 39f7d12..c217bda 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -958,6 +958,7 @@
         boolean show4gForLte = false;
         boolean hideLtePlus = false;
         boolean hspaDataDistinguishable;
+        boolean inflateSignalStrengths = false;
 
         static Config readConfig(Context context) {
             Config config = new Config();
@@ -970,6 +971,7 @@
             config.hspaDataDistinguishable =
                     res.getBoolean(R.bool.config_hspa_data_distinguishable);
             config.hideLtePlus = res.getBoolean(R.bool.config_hideLtePlus);
+            config.inflateSignalStrengths = res.getBoolean(R.bool.config_inflateSignalStrength);
             return config;
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
index b7b991e..ba1e7c2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
@@ -62,6 +62,7 @@
     private boolean mHasPulsingNotifications;
     private boolean mUnlockHintRunning;
     private boolean mQsCustomizerShowing;
+    private int mIntrinsicPadding;
 
     public AmbientState(Context context) {
         reload(context);
@@ -323,4 +324,12 @@
     public void setQsCustomizerShowing(boolean qsCustomizerShowing) {
         mQsCustomizerShowing = qsCustomizerShowing;
     }
+
+    public void setIntrinsicPadding(int intrinsicPadding) {
+        mIntrinsicPadding = intrinsicPadding;
+    }
+
+    public int getIntrinsicPadding() {
+        return mIntrinsicPadding;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index cbd315b..41cde9c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -2735,7 +2735,7 @@
         return view.getHeight();
     }
 
-    private int getPositionInLinearLayout(View requestedView) {
+    public int getPositionInLinearLayout(View requestedView) {
         ExpandableNotificationRow childInGroup = null;
         ExpandableNotificationRow requestedRow = null;
         if (isChildInGroup(requestedView)) {
@@ -3650,6 +3650,7 @@
 
     public void setIntrinsicPadding(int intrinsicPadding) {
         mIntrinsicPadding = intrinsicPadding;
+        mAmbientState.setIntrinsicPadding(intrinsicPadding);
     }
 
     public int getIntrinsicPadding() {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
index 5d51a33..eaad2f9 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
@@ -43,6 +43,7 @@
 import android.service.notification.Condition;
 import android.util.ArrayMap;
 import android.util.Log;
+import android.view.accessibility.AccessibilityManager;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.systemui.Dumpable;
@@ -122,6 +123,12 @@
         mReceiver.init();
         mVibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
         mHasVibrator = mVibrator != null && mVibrator.hasVibrator();
+
+        boolean accessibilityVolumeStreamActive = context.getSystemService(
+                AccessibilityManager.class).isAccessibilityVolumeStreamActive();
+        mVolumeController.setA11yMode(accessibilityVolumeStreamActive ?
+                    VolumePolicy.A11Y_MODE_INDEPENDENT_A11Y_VOLUME :
+                        VolumePolicy.A11Y_MODE_MEDIA_A11Y_VOLUME);
     }
 
     public AudioManager getAudioManager() {
@@ -210,6 +217,7 @@
 
     public void addCallback(Callbacks callback, Handler handler) {
         mCallbacks.add(callback, handler);
+        callback.onAccessibilityModeChanged(mShowA11yStream);
     }
 
     public void setUserActivityListener(UserActivityListener listener) {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 2742fdd..2b2ad69 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -18,7 +18,6 @@
 
 import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_ALL_MASK;
 import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_GENERIC;
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.animation.ObjectAnimator;
@@ -32,10 +31,12 @@
 import android.content.res.ColorStateList;
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.graphics.Color;
 import android.graphics.PixelFormat;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.drawable.AnimatedVectorDrawable;
+import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.media.AudioManager;
 import android.media.AudioSystem;
@@ -48,9 +49,11 @@
 import android.transition.AutoTransition;
 import android.transition.Transition;
 import android.transition.TransitionManager;
+import android.util.DisplayMetrics;
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseBooleanArray;
+import android.view.Gravity;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.View.AccessibilityDelegate;
@@ -71,7 +74,6 @@
 import android.widget.TextView;
 import com.android.settingslib.Utils;
 import com.android.systemui.Dependency;
-import com.android.systemui.HardwareUiLayout;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
@@ -96,8 +98,7 @@
  *
  * Methods ending in "H" must be called on the (ui) handler.
  */
-public class VolumeDialogImpl implements VolumeDialog, TunerService.Tunable,
-        ColorExtractor.OnColorsChangedListener {
+public class VolumeDialogImpl implements VolumeDialog, TunerService.Tunable {
     private static final String TAG = Util.logTag(VolumeDialogImpl.class);
 
     public static final String SHOW_FULL_ZEN = "sysui_show_full_zen";
@@ -107,8 +108,6 @@
 
     private final Context mContext;
     private final H mHandler = new H();
-    private final GradientDrawable mGradientDrawable;
-    private final ColorExtractor mColorExtractor;
     private final VolumeDialogController mController;
 
     private Window mWindow;
@@ -163,9 +162,6 @@
                 (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
         mActiveSliderTint = ColorStateList.valueOf(Utils.getColorAccent(mContext));
         mInactiveSliderTint = loadColorStateList(R.color.volume_slider_inactive);
-        mGradientDrawable = new GradientDrawable(mContext);
-        mGradientDrawable.setAlpha((int) (ScrimController.GRADIENT_SCRIM_ALPHA * 255));
-        mColorExtractor = Dependency.get(SysuiColorExtractor.class);
     }
 
     public void init(int windowType, Callback callback) {
@@ -187,7 +183,6 @@
     @Override
     public void destroy() {
         mController.removeCallback(mControllerCallbackH);
-        mColorExtractor.removeOnColorsChangedListener(this);
     }
 
     private void initDialog() {
@@ -198,52 +193,64 @@
         mShowing = false;
         mWindow = mDialog.getWindow();
         mWindow.requestFeature(Window.FEATURE_NO_TITLE);
-        mWindow.setBackgroundDrawable(mGradientDrawable);
+        mWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
         mWindow.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
         mWindow.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                 | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
-                | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
-        Point displaySize = new Point();
-        mContext.getDisplay().getRealSize(displaySize);
+                | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
+                | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
         mDialog.setCanceledOnTouchOutside(true);
         final Resources res = mContext.getResources();
+        final WindowManager.LayoutParams lp = mWindow.getAttributes();
+        lp.type = mWindowType;
+        lp.format = PixelFormat.TRANSLUCENT;
+        lp.setTitle(VolumeDialogImpl.class.getSimpleName());
+        lp.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
+        lp.y = res.getDimensionPixelSize(R.dimen.volume_offset_top);
+        lp.gravity = Gravity.TOP;
+        lp.windowAnimations = -1;
+        mWindow.setAttributes(lp);
         mWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
 
-        mDialog.setContentView(R.layout.volume_dialog_wrapped);
-        mDialogView = mDialog.findViewById(R.id.volume_dialog);
-        mDialogView.setOnHoverListener((v, event) -> {
-            int action = event.getActionMasked();
-            mHovering = (action == MotionEvent.ACTION_HOVER_ENTER)
-                    || (action == MotionEvent.ACTION_HOVER_MOVE);
-            rescheduleTimeoutH();
-            return true;
+        mDialog.setContentView(R.layout.volume_dialog);
+        mDialogView = (ViewGroup) mDialog.findViewById(R.id.volume_dialog);
+        mDialogView.setOnHoverListener(new View.OnHoverListener() {
+            @Override
+            public boolean onHover(View v, MotionEvent event) {
+                int action = event.getActionMasked();
+                mHovering = (action == MotionEvent.ACTION_HOVER_ENTER)
+                        || (action == MotionEvent.ACTION_HOVER_MOVE);
+                rescheduleTimeoutH();
+                return true;
+            }
         });
 
-        mColorExtractor.addOnColorsChangedListener(this);
-        mGradientDrawable.setScreenSize(displaySize.x, displaySize.y);
-
         mDialogContentView = mDialog.findViewById(R.id.volume_dialog_content);
         mDialogRowsView = mDialogContentView.findViewById(R.id.volume_dialog_rows);
         mExpanded = false;
-        mExpandButton = mDialogView.findViewById(R.id.volume_expand_button);
+        mExpandButton = (ImageButton) mDialogView.findViewById(R.id.volume_expand_button);
         mExpandButton.setOnClickListener(mClickExpand);
 
         mExpandButton.setVisibility(
                 AudioSystem.isSingleVolume(mContext) ? View.GONE : View.VISIBLE);
+        updateWindowWidthH();
         updateExpandButtonH();
 
-        mMotion = new VolumeDialogMotion(mDialog, (View) mDialogView.getParent(),
-                mDialogContentView, mExpandButton, mGradientDrawable, animating -> {
-                    if (animating) return;
-                    if (mPendingStateChanged) {
-                        mHandler.sendEmptyMessage(H.STATE_CHANGED);
-                        mPendingStateChanged = false;
-                    }
-                    if (mPendingRecheckAll) {
-                        mHandler.sendEmptyMessage(H.RECHECK_ALL);
-                        mPendingRecheckAll = false;
+        mMotion = new VolumeDialogMotion(mDialog, mDialogView, mDialogContentView, mExpandButton,
+                new VolumeDialogMotion.Callback() {
+                    @Override
+                    public void onAnimatingChanged(boolean animating) {
+                        if (animating) return;
+                        if (mPendingStateChanged) {
+                            mHandler.sendEmptyMessage(H.STATE_CHANGED);
+                            mPendingStateChanged = false;
+                        }
+                        if (mPendingRecheckAll) {
+                            mHandler.sendEmptyMessage(H.RECHECK_ALL);
+                            mPendingRecheckAll = false;
+                        }
                     }
                 });
 
@@ -268,20 +275,11 @@
             addExistingRows();
         }
         mExpandButtonAnimationDuration = res.getInteger(R.integer.volume_expand_animation_duration);
-        mZenFooter = mDialog.findViewById(R.id.volume_zen_footer);
+        mZenFooter = (ZenFooter) mDialog.findViewById(R.id.volume_zen_footer);
         mZenFooter.init(mZenModeController);
-        mZenPanel = mDialog.findViewById(R.id.tuner_zen_mode_panel);
+        mZenPanel = (TunerZenModePanel) mDialog.findViewById(R.id.tuner_zen_mode_panel);
         mZenPanel.init(mZenModeController);
         mZenPanel.setCallback(mZenPanelCallback);
-
-        final WindowManager.LayoutParams lp = mWindow.getAttributes();
-        lp.width = MATCH_PARENT;
-        lp.height = MATCH_PARENT;
-        lp.type = mWindowType;
-        lp.format = PixelFormat.TRANSLUCENT;
-        lp.setTitle(VolumeDialogImpl.class.getSimpleName());
-        lp.windowAnimations = -1;
-        mWindow.setAttributes(lp);
     }
 
     @Override
@@ -295,6 +293,20 @@
         return ColorStateList.valueOf(mContext.getColor(colorResId));
     }
 
+    private void updateWindowWidthH() {
+        final ViewGroup.LayoutParams lp = mDialogView.getLayoutParams();
+        final DisplayMetrics dm = mContext.getResources().getDisplayMetrics();
+        if (D.BUG) Log.d(TAG, "updateWindowWidth dm.w=" + dm.widthPixels);
+        int w = dm.widthPixels;
+        final int max = mContext.getResources()
+                .getDimensionPixelSize(R.dimen.volume_dialog_panel_width);
+        if (w > max) {
+            w = max;
+        }
+        lp.width = w;
+        mDialogView.setLayoutParams(lp);
+    }
+
     public void setStreamImportant(int stream, boolean important) {
         mHandler.obtainMessage(H.SET_STREAM_IMPORTANT, stream, important ? 1 : 0).sendToTarget();
     }
@@ -478,10 +490,6 @@
         rescheduleTimeoutH();
         if (mShowing) return;
         mShowing = true;
-        ColorExtractor.GradientColors colors = mColorExtractor.getColors(
-                mKeyguard.isKeyguardLocked() ? WallpaperManager.FLAG_LOCK
-                        : WallpaperManager.FLAG_SYSTEM);
-        mGradientDrawable.setColors(colors, false);
         mMotion.startShow();
         Events.writeEvent(mContext, Events.EVENT_SHOW_DIALOG, reason, mKeyguard.isKeyguardLocked());
         mController.notifyVisible(true);
@@ -539,8 +547,10 @@
     }
 
     private void updateDialogBottomMarginH() {
+        final long diff = System.currentTimeMillis() - mCollapseTime;
+        final boolean collapsing = mCollapseTime != 0 && diff < getConservativeCollapseDuration();
         final ViewGroup.MarginLayoutParams mlp = (MarginLayoutParams) mDialogView.getLayoutParams();
-        final int bottomMargin =
+        final int bottomMargin = collapsing ? mDialogContentView.getHeight() :
                 mContext.getResources().getDimensionPixelSize(R.dimen.volume_dialog_margin_bottom);
         if (bottomMargin != mlp.bottomMargin) {
             if (D.BUG) Log.d(TAG, "bottomMargin " + mlp.bottomMargin + " -> " + bottomMargin);
@@ -570,7 +580,7 @@
         TransitionManager.endTransitions(mDialogView);
         final VolumeRow activeRow = getActiveRow();
         if (!dismissing) {
-            mWindow.setLayout(mWindow.getAttributes().width, MATCH_PARENT);
+            mWindow.setLayout(mWindow.getAttributes().width, ViewGroup.LayoutParams.MATCH_PARENT);
             TransitionManager.beginDelayedTransition(mDialogView, getTransition());
         }
         updateRowsH(activeRow);
@@ -632,7 +642,7 @@
             final boolean isActive = row == activeRow;
             final boolean shouldBeVisible = shouldBeVisibleH(row, isActive);
             Util.setVisOrGone(row.view, shouldBeVisible);
-            Util.setVisOrGone(row.header, shouldBeVisible && mExpanded);
+            Util.setVisOrGone(row.header, shouldBeVisible);
             if (row.view.isShown()) {
                 updateVolumeRowSliderTintH(row, isActive);
             }
@@ -689,18 +699,12 @@
         final boolean visible = mState.zenMode != Global.ZEN_MODE_OFF
                 && (mAudioManager.isStreamAffectedByRingerMode(mActiveStream) || mExpanded)
                 && !mZenPanel.isEditing();
-
-        if (wasVisible != visible) {
-            mZenFooter.update();
-            if (visible) {
-                HardwareUiLayout.get(mZenFooter).setDivisionView(mZenFooter);
-            } else {
-                mHandler.postDelayed(() ->
-                                HardwareUiLayout.get(mZenFooter).setDivisionView(mZenFooter),
-                        mExpandButtonAnimationDuration);
-            }
-            Util.setVisOrGone(mZenFooter, visible);
+        TransitionManager.beginDelayedTransition(mDialogView, getTransition());
+        if (wasVisible != visible && !visible) {
+            prepareForCollapse();
         }
+        Util.setVisOrGone(mZenFooter, visible);
+        mZenFooter.update();
 
         final boolean fullWasVisible = mZenPanel.getVisibility() == View.VISIBLE;
         final boolean fullVisible = mShowFullZen && !visible;
@@ -960,7 +964,8 @@
 
             @Override
             public void onTransitionEnd(Transition transition) {
-                mWindow.setLayout(MATCH_PARENT, MATCH_PARENT);
+                mWindow.setLayout(
+                        mWindow.getAttributes().width, ViewGroup.LayoutParams.WRAP_CONTENT);
             }
 
             @Override
@@ -969,7 +974,8 @@
 
             @Override
             public void onTransitionPause(Transition transition) {
-                mWindow.setLayout(MATCH_PARENT, MATCH_PARENT);
+                mWindow.setLayout(
+                        mWindow.getAttributes().width, ViewGroup.LayoutParams.WRAP_CONTENT);
             }
 
             @Override
@@ -1021,6 +1027,7 @@
                 initDialog();
                 mDensity = density;
             }
+            updateWindowWidthH();
             mConfigurableTexts.update();
             mZenFooter.onConfigurationChanged();
         }
@@ -1076,26 +1083,10 @@
             if (mExpandButtonAnimationRunning) return;
             final boolean newExpand = !mExpanded;
             Events.writeEvent(mContext, Events.EVENT_EXPAND, newExpand);
-            if (!newExpand) {
-                HardwareUiLayout.get(mDialogContentView).setCollapse();
-            }
             updateExpandedH(newExpand, false /* dismissing */);
         }
     };
 
-    @Override
-    public void onColorsChanged(ColorExtractor extractor, int which) {
-        if (mKeyguard.isKeyguardLocked()) {
-            if ((WallpaperManager.FLAG_LOCK & which) != 0) {
-                mGradientDrawable.setColors(extractor.getColors(WallpaperManager.FLAG_LOCK));
-            }
-        } else {
-            if ((WallpaperManager.FLAG_SYSTEM & which) != 0) {
-                mGradientDrawable.setColors(extractor.getColors(WallpaperManager.FLAG_SYSTEM));
-            }
-        }
-    }
-
     private final class H extends Handler {
         private static final int SHOW = 1;
         private static final int DISMISS = 2;
@@ -1167,8 +1158,8 @@
             event.setPackageName(mContext.getPackageName());
 
             ViewGroup.LayoutParams params = getWindow().getAttributes();
-            boolean isFullScreen = (params.width == MATCH_PARENT) &&
-                    (params.height == MATCH_PARENT);
+            boolean isFullScreen = (params.width == ViewGroup.LayoutParams.MATCH_PARENT) &&
+                    (params.height == ViewGroup.LayoutParams.MATCH_PARENT);
             event.setFullScreen(isFullScreen);
 
             if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java
index 2df2227..01d31e2 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java
@@ -13,6 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package com.android.systemui.volume;
 
 import android.animation.Animator;
@@ -41,10 +42,8 @@
     private final View mDialogView;
     private final ViewGroup mContents;  // volume rows + zen footer
     private final View mChevron;
-    private final Drawable mBackground;
     private final Handler mHandler = new Handler();
     private final Callback mCallback;
-    private final int mBackgroundTargetAlpha;
 
     private boolean mAnimating;  // show or dismiss animation is running
     private boolean mShowing;  // show animation is running
@@ -53,14 +52,12 @@
     private ValueAnimator mContentsPositionAnimator;
 
     public VolumeDialogMotion(Dialog dialog, View dialogView, ViewGroup contents, View chevron,
-            Drawable background, Callback callback) {
+            Callback callback) {
         mDialog = dialog;
         mDialogView = dialogView;
         mContents = contents;
         mChevron = chevron;
         mCallback = callback;
-        mBackground = background;
-        mBackgroundTargetAlpha = mBackground.getAlpha();
         mDialog.setOnDismissListener(new OnDismissListener() {
             @Override
             public void onDismiss(DialogInterface dialog) {
@@ -71,9 +68,8 @@
             @Override
             public void onShow(DialogInterface dialog) {
                 if (D.BUG) Log.d(TAG, "mDialog.onShow");
-                final int w = mDialogView.getWidth() / 4;
-                mDialogView.setTranslationX(w);
-                mBackground.setAlpha(0);
+                final int h = mDialogView.getHeight();
+                mDialogView.setTranslationY(-h);
                 startShowAnimation();
             }
         });
@@ -122,7 +118,7 @@
     }
 
     private int chevronDistance() {
-        return 0;
+        return mChevron.getHeight() / 6;
     }
 
     private int chevronPosY() {
@@ -133,29 +129,26 @@
     private void startShowAnimation() {
         if (D.BUG) Log.d(TAG, "startShowAnimation");
         mDialogView.animate()
-                .translationX(0)
                 .translationY(0)
-                .alpha(1)
                 .setDuration(scaledDuration(300))
                 .setInterpolator(new LogDecelerateInterpolator())
                 .setListener(null)
                 .setUpdateListener(animation -> {
-                    mBackground.setAlpha(
-                            (int) (animation.getAnimatedFraction() * mBackgroundTargetAlpha));
                     if (mChevronPositionAnimator != null) {
                         final float v = (Float) mChevronPositionAnimator.getAnimatedValue();
                         if (mChevronPositionAnimator == null) return;
                         // reposition chevron
                         final int posY = chevronPosY();
+                        mChevron.setTranslationY(posY + v + -mDialogView.getTranslationY());
                     }
                 })
                 .withEndAction(new Runnable() {
                     @Override
                     public void run() {
-                        mBackground.setAlpha(mBackgroundTargetAlpha);
                         if (mChevronPositionAnimator == null) return;
                         // reposition chevron
                         final int posY = chevronPosY();
+                        mChevron.setTranslationY(posY + -mDialogView.getTranslationY());
                     }
                 })
                 .start();
@@ -171,13 +164,19 @@
                 if (D.BUG) Log.d(TAG, "show.onAnimationEnd");
                 setShowing(false);
             }
-
             @Override
             public void onAnimationCancel(Animator animation) {
                 if (D.BUG) Log.d(TAG, "show.onAnimationCancel");
                 mCancelled = true;
             }
         });
+        mContentsPositionAnimator.addUpdateListener(new AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator animation) {
+                float v = (Float) animation.getAnimatedValue();
+                mContents.setTranslationY(v + -mDialogView.getTranslationY());
+            }
+        });
         mContentsPositionAnimator.setInterpolator(new LogDecelerateInterpolator());
         mContentsPositionAnimator.start();
 
@@ -219,30 +218,34 @@
             setShowing(false);
         }
         mDialogView.animate()
-                .translationX(mDialogView.getWidth() / 4)
-                .alpha(0)
+                .translationY(-mDialogView.getHeight())
                 .setDuration(scaledDuration(250))
                 .setInterpolator(new LogAccelerateInterpolator())
-                .setUpdateListener(animation -> {
-                    final float v = 1 - mChevronPositionAnimator.getAnimatedFraction();
-                    mBackground.setAlpha((int) (v * mBackgroundTargetAlpha));
+                .setUpdateListener(new AnimatorUpdateListener() {
+                    @Override
+                    public void onAnimationUpdate(ValueAnimator animation) {
+                        mContents.setTranslationY(-mDialogView.getTranslationY());
+                        final int posY = chevronPosY();
+                        mChevron.setTranslationY(posY + -mDialogView.getTranslationY());
+                    }
                 })
                 .setListener(new AnimatorListenerAdapter() {
                     private boolean mCancelled;
-
                     @Override
                     public void onAnimationEnd(Animator animation) {
                         if (mCancelled) return;
                         if (D.BUG) Log.d(TAG, "dismiss.onAnimationEnd");
-                        mHandler.postDelayed(() -> {
-                            if (D.BUG) Log.d(TAG, "mDialog.dismiss()");
-                            mDialog.dismiss();
-                            onComplete.run();
-                            setDismissing(false);
+                        mHandler.postDelayed(new Runnable() {
+                            @Override
+                            public void run() {
+                                if (D.BUG) Log.d(TAG, "mDialog.dismiss()");
+                                mDialog.dismiss();
+                                onComplete.run();
+                                setDismissing(false);
+                            }
                         }, PRE_DISMISS_DELAY);
 
                     }
-
                     @Override
                     public void onAnimationCancel(Animator animation) {
                         if (D.BUG) Log.d(TAG, "dismiss.onAnimationCancel");
diff --git a/packages/SystemUI/tests/AndroidManifest.xml b/packages/SystemUI/tests/AndroidManifest.xml
index 612a54a..9bb2180 100644
--- a/packages/SystemUI/tests/AndroidManifest.xml
+++ b/packages/SystemUI/tests/AndroidManifest.xml
@@ -37,6 +37,7 @@
     <uses-permission android:name="android.permission.REQUEST_NETWORK_SCORES" />
     <uses-permission android:name="android.permission.CONTROL_VPN" />
     <uses-permission android:name="android.permission.WAKE_LOCK" />
+    <uses-permission android:name="android.permission.GET_APP_OPS_STATS" />
 
     <application>
         <uses-library android:name="android.test.runner" />
@@ -47,7 +48,7 @@
             android:process=":killable" />
     </application>
 
-    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+    <instrumentation android:name="android.testing.TestableInstrumentation"
         android:targetPackage="com.android.systemui.tests"
         android:label="Tests for SystemUI">
     </instrumentation>
diff --git a/packages/SystemUI/tests/src/com/android/systemui/RoundedCornersTest.java b/packages/SystemUI/tests/src/com/android/systemui/RoundedCornersTest.java
index 945af34..edad32c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/RoundedCornersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/RoundedCornersTest.java
@@ -21,7 +21,6 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
@@ -30,7 +29,6 @@
 import static org.mockito.Mockito.when;
 
 import android.app.Fragment;
-import android.support.test.filters.FlakyTest;
 import android.support.test.filters.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.view.Display;
@@ -48,12 +46,10 @@
 import com.android.systemui.tuner.TunerService;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 @RunWith(AndroidTestingRunner.class)
-@FlakyTest
 @SmallTest
 public class RoundedCornersTest extends SysuiTestCase {
 
@@ -72,6 +68,7 @@
         mWindowManager = mock(WindowManager.class);
         mView = spy(new StatusBarWindowView(mContext, null));
         when(mStatusBar.getStatusBarWindow()).thenReturn(mView);
+        when(mStatusBar.getNavigationBarWindow()).thenReturn(mView);
         mContext.putComponent(StatusBar.class, mStatusBar);
 
         Display display = mContext.getSystemService(WindowManager.class).getDefaultDisplay();
@@ -94,6 +91,8 @@
     @Test
     public void testNoRounding() {
         mContext.getOrCreateTestableResources().addOverride(dimen.rounded_corner_radius, 0);
+        mContext.getOrCreateTestableResources()
+                .addOverride(dimen.rounded_corner_content_padding, 0);
 
         mRoundedCorners.start();
         // No views added.
@@ -105,8 +104,11 @@
     }
 
     @Test
+    @Ignore
     public void testRounding() {
         mContext.getOrCreateTestableResources().addOverride(dimen.rounded_corner_radius, 20);
+        mContext.getOrCreateTestableResources()
+                .addOverride(dimen.rounded_corner_content_padding, 20);
 
         mRoundedCorners.start();
         // Add 2 windows for rounded corners (top and bottom).
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
index 361a20f..66d00dd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
@@ -31,6 +31,8 @@
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
 
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
@@ -56,10 +58,14 @@
 
         mRealInstrumentation = InstrumentationRegistry.getInstrumentation();
         Instrumentation inst = spy(mRealInstrumentation);
-        when(inst.getContext()).thenThrow(new RuntimeException(
-                "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext"));
-        when(inst.getTargetContext()).thenThrow(new RuntimeException(
-                "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext"));
+        when(inst.getContext()).thenAnswer(invocation -> {
+            throw new RuntimeException(
+                    "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext");
+        });
+        when(inst.getTargetContext()).thenAnswer(invocation -> {
+            throw new RuntimeException(
+                    "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext");
+        });
         InstrumentationRegistry.registerInstance(inst, InstrumentationRegistry.getArguments());
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
index 2363b2a..8641fac 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
@@ -27,7 +27,6 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.FlakyTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java
index b8e9fcd..bba982c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java
@@ -26,8 +26,6 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.net.Uri;
-import android.support.test.annotation.UiThreadTest;
-import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -36,11 +34,10 @@
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.systemui.Dependency;
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.plugins.annotations.ProvidesInterface;
 import com.android.systemui.plugins.PluginInstanceManager.PluginInfo;
+import com.android.systemui.plugins.annotations.ProvidesInterface;
 import com.android.systemui.plugins.PluginManagerImpl.PluginInstanceManagerFactory;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java
index 6a85511..ed47fbb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java
@@ -23,10 +23,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import org.junit.After;
-import org.junit.Ignore;
 import android.support.test.filters.SmallTest;
-import android.support.test.filters.FlakyTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
@@ -41,6 +38,7 @@
 import com.android.systemui.plugins.qs.DetailAdapter;
 
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterTest.java
index f4fda06..d25bbe1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterTest.java
@@ -21,7 +21,6 @@
 import static org.mockito.Mockito.when;
 
 import android.support.test.filters.SmallTest;
-import android.support.test.filters.FlakyTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
index 637b244..85cdfcc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
@@ -20,7 +20,6 @@
 import static org.mockito.Mockito.when;
 
 import android.support.test.filters.SmallTest;
-import android.support.test.filters.FlakyTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
@@ -31,7 +30,6 @@
 import com.android.systemui.qs.customize.QSCustomizer;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -40,7 +38,6 @@
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper
 @SmallTest
-@FlakyTest
 public class QSPanelTest extends SysuiTestCase {
 
     private MetricsLogger mMetricsLogger;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
index 664ea71..2f6511c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
@@ -21,27 +21,21 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.annotation.UiThreadTest;
-import android.support.test.filters.FlakyTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.view.View;
 
+import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.notification.AboveShelfChangedListener;
 import com.android.systemui.statusbar.stack.NotificationChildrenContainer;
-import com.android.systemui.SysuiTestCase;
 
 import org.junit.Assert;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-@FlakyTest
 public class ExpandableNotificationRowTest extends SysuiTestCase {
 
     private ExpandableNotificationRow mGroup;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java
index 4dce2f5..436849c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java
@@ -16,30 +16,25 @@
 
 package com.android.systemui.statusbar;
 
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.annotation.UiThreadTest;
-import android.support.test.filters.FlakyTest;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.view.View;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
 import static org.mockito.ArgumentMatchers.anyFloat;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 
+import android.support.test.annotation.UiThreadTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.View;
+
 import com.android.systemui.SysuiTestCase;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-@FlakyTest
 public class NotificationContentViewTest extends SysuiTestCase {
 
     NotificationContentView mView;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java
index d18e63b..6e59d10 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java
@@ -16,10 +16,7 @@
 
 package com.android.systemui.statusbar;
 
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.annotation.UiThreadTest;
-import android.support.test.filters.FlakyTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.view.View;
@@ -32,13 +29,11 @@
 
 import org.junit.Assert;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-@FlakyTest
 public class NotificationCustomViewWrapperTest extends SysuiTestCase {
 
     private ExpandableNotificationRow mRow;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java
index 630da2e..2a2acab 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java
@@ -57,4 +57,10 @@
         row.createMenu(null, null);
         assertTrue(row.getMenuView() != null);
     }
+
+    @Test
+    public void testResetUncreatedMenu() {
+        NotificationMenuRowPlugin row = new NotificationMenuRow(mContext);
+        row.resetMenu();
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
index 68f9cb05..7b2071c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
@@ -16,8 +16,10 @@
 
 package com.android.systemui.statusbar;
 
+import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertTrue;
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -33,12 +35,14 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
+import android.graphics.Color;
 import android.graphics.drawable.Icon;
 import android.os.UserHandle;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
 import com.android.internal.statusbar.StatusBarIcon;
+import com.android.internal.util.NotificationColorUtil;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 
@@ -100,4 +104,22 @@
 
         assertFalse(mIconView.set(mStatusBarIcon));
     }
+
+    @Test
+    public void testGetContrastedStaticDrawableColor() {
+        mIconView.setStaticDrawableColor(Color.DKGRAY);
+        int color = mIconView.getContrastedStaticDrawableColor(Color.WHITE);
+        assertEquals("Color should not change when we have enough contrast",
+                Color.DKGRAY, color);
+
+        mIconView.setStaticDrawableColor(Color.WHITE);
+        color = mIconView.getContrastedStaticDrawableColor(Color.WHITE);
+        assertTrue("Similar colors should be shifted to satisfy contrast",
+                NotificationColorUtil.satisfiesTextContrast(Color.WHITE, color));
+
+        mIconView.setStaticDrawableColor(Color.GREEN);
+        color = mIconView.getContrastedStaticDrawableColor(0xcc000000);
+        assertEquals("Transparent backgrounds should fallback to drawable color",
+                color, mIconView.getStaticDrawableColor());
+    }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 0e3ea7a..17ca924 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -38,6 +38,8 @@
 import static org.mockito.Mockito.verify;
 
 import android.app.Notification;
+import android.app.trust.TrustManager;
+import android.hardware.fingerprint.FingerprintManager;
 import android.metrics.LogMaker;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -55,6 +57,7 @@
 import android.testing.TestableLooper.MessageHandler;
 import android.testing.TestableLooper.RunWithLooper;
 import android.util.DisplayMetrics;
+import android.view.ViewGroup.LayoutParams;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -75,6 +78,8 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.io.ByteArrayOutputStream;
+import java.io.PrintWriter;
 import java.util.ArrayList;
 
 @SmallTest
@@ -99,6 +104,8 @@
 
     @Before
     public void setup() throws Exception {
+        mContext.addMockSystemService(TrustManager.class, mock(TrustManager.class));
+        mContext.addMockSystemService(FingerprintManager.class, mock(FingerprintManager.class));
         mStatusBarKeyguardViewManager = mock(StatusBarKeyguardViewManager.class);
         mUnlockMethodCache = mock(UnlockMethodCache.class);
         mKeyguardIndicationController = mock(KeyguardIndicationController.class);
@@ -108,6 +115,7 @@
         mNotificationData = mock(NotificationData.class);
         mSystemServicesProxy = mock(SystemServicesProxy.class);
         mNotificationPanelView = mock(NotificationPanelView.class);
+        when(mNotificationPanelView.getLayoutParams()).thenReturn(new LayoutParams(0, 0));
         mNotificationList = mock(ArrayList.class);
         IPowerManager powerManagerService = mock(IPowerManager.class);
         HandlerThread handlerThread = new HandlerThread("TestThread");
@@ -122,6 +130,7 @@
                 mKeyguardIndicationController, mStackScroller, mHeadsUpManager,
                 mNotificationData, mPowerManager, mSystemServicesProxy, mNotificationPanelView,
                 mBarService);
+        mStatusBar.mContext = mContext;
         doAnswer(invocation -> {
             OnDismissAction onDismissAction = (OnDismissAction) invocation.getArguments()[0];
             onDismissAction.onDismiss();
@@ -385,6 +394,11 @@
         TestableLooper.get(this).processAllMessages();
     }
 
+    @Test
+    public void testDump_DoesNotCrash() {
+        mStatusBar.dump(null, new PrintWriter(new ByteArrayOutputStream()), null);
+    }
+
     static class TestableStatusBar extends StatusBar {
         public TestableStatusBar(StatusBarKeyguardViewManager man,
                 UnlockMethodCache unlock, KeyguardIndicationController key,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/LocationControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/LocationControllerImplTest.java
new file mode 100644
index 0000000..a10bebf
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/LocationControllerImplTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.statusbar.policy;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Intent;
+import android.location.LocationManager;
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.testing.TestableLooper.RunWithLooper;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.policy.LocationController.LocationChangeCallback;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+@SmallTest
+public class LocationControllerImplTest extends SysuiTestCase {
+
+    private LocationControllerImpl mLocationController;
+
+    @Before
+    public void setup() {
+        mLocationController = spy(new LocationControllerImpl(mContext,
+                TestableLooper.get(this).getLooper()));
+    }
+
+    @Test
+    public void testRemoveSelfActive_DoesNotCrash() {
+        LocationController.LocationChangeCallback callback = new LocationChangeCallback() {
+            @Override
+            public void onLocationActiveChanged(boolean active) {
+                mLocationController.removeCallback(this);
+            }
+        };
+        mLocationController.addCallback(callback);
+        mLocationController.addCallback(mock(LocationChangeCallback.class));
+
+        when(mLocationController.areActiveHighPowerLocationRequests()).thenReturn(false);
+        mLocationController.onReceive(mContext, new Intent(
+                LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION));
+        when(mLocationController.areActiveHighPowerLocationRequests()).thenReturn(true);
+        mLocationController.onReceive(mContext, new Intent(
+                LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION));
+
+        TestableLooper.get(this).processAllMessages();
+    }
+
+    @Test
+    public void testRemoveSelfSettings_DoesNotCrash() {
+        LocationController.LocationChangeCallback callback = new LocationChangeCallback() {
+            @Override
+            public void onLocationSettingsChanged(boolean isEnabled) {
+                mLocationController.removeCallback(this);
+            }
+        };
+        mLocationController.addCallback(callback);
+        mLocationController.addCallback(mock(LocationChangeCallback.class));
+
+        TestableLooper.get(this).processAllMessages();
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
index be3802b..cba9f77 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
@@ -494,6 +494,79 @@
               DEFAULT_ICON /* typeIcon */);
     }
 
+    @Test
+    public void testCarrierNetworkChange_roamingBeforeNetworkChange() {
+      int strength = SignalStrength.SIGNAL_STRENGTH_GREAT;
+
+      setupDefaultSignal();
+      setLevel(strength);
+      setGsmRoaming(true);
+
+      // Verify baseline
+      verifyLastMobileDataIndicators(true /* visible */,
+              strength /* strengthIcon */,
+              DEFAULT_ICON /* typeIcon */,
+              true /* roaming */);
+
+      // API call is made
+      setCarrierNetworkChange(true /* enabled */);
+
+      // Carrier network change is true, show special indicator, no roaming.
+      verifyLastMobileDataIndicators(true /* visible */,
+              SignalDrawable.getCarrierChangeState(SignalStrength.NUM_SIGNAL_STRENGTH_BINS),
+              0 /* typeIcon */,
+              false /* roaming */);
+
+      // Revert back
+      setCarrierNetworkChange(false /* enabled */);
+
+      // Verify back in previous state
+      verifyLastMobileDataIndicators(true /* visible */,
+              strength /* strengthIcon */,
+              DEFAULT_ICON /* typeIcon */,
+              true /* roaming */);
+    }
+
+    @Test
+    public void testCarrierNetworkChange_roamingAfterNetworkChange() {
+      int strength = SignalStrength.SIGNAL_STRENGTH_GREAT;
+
+      setupDefaultSignal();
+      setLevel(strength);
+
+      // Verify baseline
+      verifyLastMobileDataIndicators(true /* visible */,
+              strength /* strengthIcon */,
+              DEFAULT_ICON /* typeIcon */,
+              false /* roaming */);
+
+      // API call is made
+      setCarrierNetworkChange(true /* enabled */);
+
+      // Carrier network change is true, show special indicator, no roaming.
+      verifyLastMobileDataIndicators(true /* visible */,
+              SignalDrawable.getCarrierChangeState(SignalStrength.NUM_SIGNAL_STRENGTH_BINS),
+              0 /* typeIcon */,
+              false /* roaming */);
+
+      setGsmRoaming(true);
+
+      // Roaming should not show.
+      verifyLastMobileDataIndicators(true /* visible */,
+              SignalDrawable.getCarrierChangeState(SignalStrength.NUM_SIGNAL_STRENGTH_BINS),
+              0 /* typeIcon */,
+              false /* roaming */);
+
+      // Revert back
+      setCarrierNetworkChange(false /* enabled */);
+
+      // Verify back in previous state
+      verifyLastMobileDataIndicators(true /* visible */,
+              strength /* strengthIcon */,
+              DEFAULT_ICON /* typeIcon */,
+              true /* roaming */);
+    }
+
     private void verifyEmergencyOnly(boolean isEmergencyOnly) {
         ArgumentCaptor<Boolean> emergencyOnly = ArgumentCaptor.forClass(Boolean.class);
         Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setEmergencyCallsOnly(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java
index bc6833d..5ac965c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java
@@ -16,10 +16,6 @@
 
 package com.android.systemui.statusbar.stack;
 
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.annotation.UiThreadTest;
-import android.support.test.filters.FlakyTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.view.NotificationHeaderView;
@@ -31,13 +27,11 @@
 
 import org.junit.Assert;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-@FlakyTest
 public class NotificationChildrenContainerTest extends SysuiTestCase {
 
     private ExpandableNotificationRow mGroup;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java
index 0a83a89..d1b1c5b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java
@@ -14,7 +14,6 @@
 
 package com.android.systemui.utils.leaks;
 
-import android.content.Context;
 import android.testing.LeakCheck;
 
 import com.android.systemui.plugins.Plugin;
diff --git a/packages/overlays/SysuiDarkThemeOverlay/AndroidManifest.xml b/packages/overlays/SysuiDarkThemeOverlay/AndroidManifest.xml
index ba1c91c..8b6ee2b 100644
--- a/packages/overlays/SysuiDarkThemeOverlay/AndroidManifest.xml
+++ b/packages/overlays/SysuiDarkThemeOverlay/AndroidManifest.xml
@@ -2,7 +2,7 @@
     package="com.android.systemui.theme.dark"
     android:versionCode="1"
     android:versionName="1.0">
-    <overlay android:targetPackage="android" android:priority="1"/>
+    <overlay android:targetPackage="com.android.systemui" android:priority="1"/>
 
     <application android:label="@string/sysui_overlay_dark" android:hasCode="false"/>
 </manifest>
diff --git a/packages/overlays/SysuiDarkThemeOverlay/res/values/themes_device_defaults.xml b/packages/overlays/SysuiDarkThemeOverlay/res/values/styles.xml
similarity index 84%
rename from packages/overlays/SysuiDarkThemeOverlay/res/values/themes_device_defaults.xml
rename to packages/overlays/SysuiDarkThemeOverlay/res/values/styles.xml
index 7e2b955..1b70413 100644
--- a/packages/overlays/SysuiDarkThemeOverlay/res/values/themes_device_defaults.xml
+++ b/packages/overlays/SysuiDarkThemeOverlay/res/values/styles.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
-    <style name="Theme.DeviceDefault.QuickSettings" parent="android:Theme.DeviceDefault">
+    <style name="DarkQuickSettings" parent="android:Theme.DeviceDefault">
         <item name="android:colorPrimary">@*android:color/primary_device_default_settings</item>
         <item name="android:colorPrimaryDark">@*android:color/primary_dark_device_default_settings</item>
         <!-- textColorPrimaryInverse is used on the lock screen and this means that we can't just
@@ -13,4 +13,7 @@
         <item name="android:colorControlNormal">?android:attr/textColorPrimary</item>
         <item name="android:colorBackgroundFloating">#000</item>
     </style>
+
+    <style name="systemui_base" parent="DarkQuickSettings" />
+    <style name="edit_theme" parent="DarkQuickSettings" />
 </resources>
\ No newline at end of file
diff --git a/packages/overlays/SysuiLightWallpaperThemeOverlay/AndroidManifest.xml b/packages/overlays/SysuiLightWallpaperThemeOverlay/AndroidManifest.xml
index 1745b4c..0a8749c 100644
--- a/packages/overlays/SysuiLightWallpaperThemeOverlay/AndroidManifest.xml
+++ b/packages/overlays/SysuiLightWallpaperThemeOverlay/AndroidManifest.xml
@@ -2,7 +2,7 @@
     package="com.android.systemui.theme.lightwallpaper"
     android:versionCode="1"
     android:versionName="1.0">
-    <overlay android:targetPackage="android" android:priority="2"/>
+    <overlay android:targetPackage="com.android.systemui" android:priority="2"/>
 
     <application android:label="@string/sysui_overlay_light" android:hasCode="false"/>
 </manifest>
diff --git a/packages/overlays/SysuiLightWallpaperThemeOverlay/res/values/styles.xml b/packages/overlays/SysuiLightWallpaperThemeOverlay/res/values/styles.xml
new file mode 100644
index 0000000..53912b5
--- /dev/null
+++ b/packages/overlays/SysuiLightWallpaperThemeOverlay/res/values/styles.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <style name="systemui_base" parent="@*android:style/Theme.DeviceDefault.QuickSettings">
+        <item name="android:textColorPrimaryInverse">@*android:color/primary_text_material_light</item>
+        <item name="android:textColorSecondaryInverse">@*android:color/secondary_text_material_light</item>
+    </style>
+
+    <style name="RecentsBase" parent="@android:style/Theme.Material">
+        <item name="android:textColorPrimaryInverse">@*android:color/primary_text_material_light</item>
+        <item name="android:textColorSecondaryInverse">@*android:color/secondary_text_material_light</item>
+    </style>
+</resources>
\ No newline at end of file
diff --git a/packages/overlays/SysuiLightWallpaperThemeOverlay/res/values/themes_device_defaults.xml b/packages/overlays/SysuiLightWallpaperThemeOverlay/res/values/themes_device_defaults.xml
deleted file mode 100644
index 877ebf8..0000000
--- a/packages/overlays/SysuiLightWallpaperThemeOverlay/res/values/themes_device_defaults.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <style name="Theme.DeviceDefault.QuickSettings" parent="android:Theme.DeviceDefault.Light">
-        <item name="android:textColorPrimaryInverse">@*android:color/primary_text_material_light</item>
-        <item name="android:textColorSecondaryInverse">@*android:color/secondary_text_material_light</item>
-    </style>
-</resources>
\ No newline at end of file
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 63e5cac..39ee6cf 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -3546,7 +3546,7 @@
     STORAGE_FILES = 841;
 
     // FIELD - Rank of the clicked Settings search result
-    FIELD_SETTINGS_SERACH_RESULT_RANK = 842;
+    FIELD_SETTINGS_SEARCH_RESULT_RANK = 842;
 
     // OPEN: Settings > Apps > Default Apps > Assist >  Default assist
     DEFAULT_ASSIST_PICKER = 843;
@@ -4039,10 +4039,10 @@
     ACTION_SETTINGS_UPDATE_DEFAULT_APP = 1000;
 
     // FIELD - Query length when Settings search result is clicked
-    FIELD_SETTINGS_SERACH_QUERY_LENGTH = 1001;
+    FIELD_SETTINGS_SEARCH_QUERY_LENGTH = 1001;
 
     // FIELD - Number of results when Settings search result is clicked
-    FIELD_SETTINGS_SERACH_RESULT_COUNT = 1002;
+    FIELD_SETTINGS_SEARCH_RESULT_COUNT = 1002;
 
     // OPEN: Settings > Display > Ambient Display
     // CATEGORY: SETTINGS
@@ -4119,6 +4119,46 @@
     // OS: O DR
     BLUETOOTH_PAIRING = 1018;
 
+    // ACTION: Collect PSD Signals
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    ACTION_PSD_LOADER = 1019;
+
+    // ACTION: Background check action on an app
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    ACTION_APP_BACKGROUND_CHECK = 1020;
+
+    // ACTION: Location check action on an app
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    ACTION_APP_LOCATION_CHECK = 1021;
+
+    // Device headset status
+    // CATEGORY: OTHER
+    //  SUBTYPE: 1 is DON, 2 is DOFF
+    // OS: O DR
+    ACTION_HEADSET_STATUS = 1022;
+
+    // Device Headset Plug status
+    // CATEGORY: OTHER
+    //  SUBTYPE: 1 is AC power, 2 is USB power, 3 is Unplug
+    // OS: O DR
+    ACTION_HEADSET_PLUG = 1023;
+
+    // Device Headset battery level on Plug
+    // CATEGORY: OTHER
+    // FIELD - The battery percentage when the user decided to plug in
+    // Type: integer
+    // OS: O DR
+    FIELD_PLUG_BATTERY_PERCENTAGE = 1024;
+
+    // Device Headset Pose status
+    // CATEGORY: OTHER
+    //  SUBTYPE: 1 is 6DOF, 2 is 3DOF
+    // OS: O DR
+    ACTION_HEADSET_POSE_STATUS = 1025;
+
     // Add new aosp constants above this line.
     // END OF AOSP CONSTANTS
   }
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index e85f96b..71f699c 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -270,6 +270,12 @@
     }
 
     @Override
+    public void onSwitchUser(int userHandle) {
+        if (sDebug) Slog.d(TAG, "Hiding UI when user switched");
+        mUi.hideAll(null);
+    }
+
+    @Override
     public void onCleanupUser(int userId) {
         synchronized (mLock) {
             removeCachedServiceLocked(userId);
@@ -458,6 +464,7 @@
     private void updateCachedServiceLocked(int userId, boolean disabled) {
         AutofillManagerServiceImpl service = getServiceForUserLocked(userId);
         if (service != null) {
+            service.destroySessionsLocked();
             service.updateLocked(disabled);
             if (!service.isEnabled()) {
                 removeCachedServiceLocked(userId);
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 1a02e8d..751c054 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -360,8 +360,7 @@
     }
 
     void disableOwnedAutofillServicesLocked(int uid) {
-        if (mInfo == null || mInfo.getServiceInfo().applicationInfo.uid
-                != UserHandle.getAppId(uid)) {
+        if (mInfo == null || mInfo.getServiceInfo().applicationInfo.uid != uid) {
             return;
         }
         final long identity = Binder.clearCallingIdentity();
diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
index d1fbbf9..c9e2a92 100644
--- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
@@ -191,6 +191,7 @@
                 | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
                 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                 | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
+        window.addPrivateFlags(WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS);
         window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
         window.setGravity(Gravity.BOTTOM | Gravity.CENTER);
         window.setCloseOnTouchOutside(true);
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 56a66eb..5c180f1 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -5685,13 +5685,15 @@
                 PerformFullTransportBackupTask pftbt = null;
                 synchronized (mQueueLock) {
                     if (mRunningFullBackupTask != null) {
-                        if (DEBUG_SCHEDULING) {
-                            Slog.i(TAG, "Telling running backup to stop");
-                        }
                         pftbt = mRunningFullBackupTask;
                     }
                 }
-                pftbt.handleCancel(true);
+                if (pftbt != null) {
+                    if (DEBUG_SCHEDULING) {
+                        Slog.i(TAG, "Telling running backup to stop");
+                    }
+                    pftbt.handleCancel(true);
+                }
             }
         };
         new Thread(endFullBackupRunnable, "end-full-backup").start();
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 224845c..98389a6 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -2973,12 +2973,16 @@
         return mTethering.getTetheredDhcpRanges();
     }
 
+    @Override
+    public boolean isTetheringSupported(String callerPkg) {
+        ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
+        return isTetheringSupported();
+    }
+
     // if ro.tether.denied = true we default to no tethering
     // gservices could set the secure setting to 1 though to enable it on a build where it
     // had previously been turned off.
-    @Override
-    public boolean isTetheringSupported() {
-        enforceTetherAccessPermission();
+    private boolean isTetheringSupported() {
         int defaultVal = encodeBool(!mSystemProperties.get("ro.tether.denied").equals("true"));
         boolean tetherSupported = toBool(Settings.Global.getInt(mContext.getContentResolver(),
                 Settings.Global.TETHER_SUPPORTED, defaultVal));
@@ -5380,6 +5384,7 @@
 
     @Override
     public String getCaptivePortalServerUrl() {
+        enforceConnectivityInternalPermission();
         return NetworkMonitor.getCaptivePortalServerHttpUrl(mContext);
     }
 
diff --git a/services/core/java/com/android/server/ContextHubSystemService.java b/services/core/java/com/android/server/ContextHubSystemService.java
index 5d4317c..110847d 100644
--- a/services/core/java/com/android/server/ContextHubSystemService.java
+++ b/services/core/java/com/android/server/ContextHubSystemService.java
@@ -16,17 +16,25 @@
 
 package com.android.server;
 
+import com.android.internal.util.ConcurrentUtils;
 import com.android.server.location.ContextHubService;
+import com.android.server.SystemServerInitThreadPool;
 import android.content.Context;
 import android.util.Log;
 
+import java.util.concurrent.Future;
+
 class ContextHubSystemService extends SystemService {
     private static final String TAG = "ContextHubSystemService";
-    private final ContextHubService mContextHubService;
+    private ContextHubService mContextHubService;
+
+    private Future<?> mInit;
 
     public ContextHubSystemService(Context context) {
         super(context);
-        mContextHubService = new ContextHubService(context);
+        mInit = SystemServerInitThreadPool.get().submit(() -> {
+            mContextHubService = new ContextHubService(context);
+        }, "Init ContextHubSystemService");
     }
 
     @Override
@@ -37,6 +45,9 @@
     public void onBootPhase(int phase) {
         if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
             Log.d(TAG, "onBootPhase: PHASE_SYSTEM_SERVICES_READY");
+            ConcurrentUtils.waitForFutureNoInterrupt(mInit,
+                    "Wait for ContextHubSystemService init");
+            mInit = null;
             publishBinderService(Context.CONTEXTHUB_SERVICE, mContextHubService);
         }
     }
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 7275461..eda283e 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -324,58 +324,13 @@
             ActivityManager.OnUidImportanceListener uidImportanceListener
                     = new ActivityManager.OnUidImportanceListener() {
                 @Override
-                public void onUidImportance(int uid, int importance) {
-                    boolean foreground = isImportanceForeground(importance);
-                    HashSet<String> affectedProviders = new HashSet<>(mRecordsByProvider.size());
-                    synchronized (mLock) {
-                        for (Entry<String, ArrayList<UpdateRecord>> entry
-                                : mRecordsByProvider.entrySet()) {
-                            String provider = entry.getKey();
-                            for (UpdateRecord record : entry.getValue()) {
-                                if (record.mReceiver.mIdentity.mUid == uid
-                                        && record.mIsForegroundUid != foreground) {
-                                    if (D) Log.d(TAG, "request from uid " + uid + " is now "
-                                            + (foreground ? "foreground" : "background)"));
-                                    record.mIsForegroundUid = foreground;
-
-                                    if (!isThrottlingExemptLocked(record.mReceiver.mIdentity)) {
-                                        affectedProviders.add(provider);
-                                    }
-                                }
-                            }
+                public void onUidImportance(final int uid, final int importance) {
+                    mLocationHandler.post(new Runnable() {
+                        @Override
+                        public void run() {
+                            onUidImportanceChanged(uid, importance);
                         }
-                        for (String provider : affectedProviders) {
-                            applyRequirementsLocked(provider);
-                        }
-
-                        for (Entry<IGnssMeasurementsListener, Identity> entry
-                                : mGnssMeasurementsListeners.entrySet()) {
-                            if (entry.getValue().mUid == uid) {
-                                if (D) Log.d(TAG, "gnss measurements listener from uid " + uid
-                                    + " is now " + (foreground ? "foreground" : "background)"));
-                                if (foreground || isThrottlingExemptLocked(entry.getValue())) {
-                                    mGnssMeasurementsProvider.addListener(entry.getKey());
-                                } else {
-                                    mGnssMeasurementsProvider.removeListener(entry.getKey());
-                                }
-                            }
-                        }
-
-                        for (Entry<IGnssNavigationMessageListener, Identity> entry
-                            : mGnssNavigationMessageListeners.entrySet()) {
-                            if (entry.getValue().mUid == uid) {
-                                if (D) Log.d(TAG, "gnss navigation message listener from uid "
-                                    + uid + " is now "
-                                    + (foreground ? "foreground" : "background)"));
-                                if (foreground || isThrottlingExemptLocked(entry.getValue())) {
-                                    mGnssNavigationMessageProvider.addListener(entry.getKey());
-                                } else {
-                                    mGnssNavigationMessageProvider.removeListener(entry.getKey());
-                                }
-                            }
-                        }
-                    }
-
+                    });
                 }
             };
             mActivityManager.addOnUidImportanceListener(uidImportanceListener,
@@ -455,6 +410,59 @@
         }, UserHandle.ALL, intentFilter, null, mLocationHandler);
     }
 
+    private void onUidImportanceChanged(int uid, int importance) {
+        boolean foreground = isImportanceForeground(importance);
+        HashSet<String> affectedProviders = new HashSet<>(mRecordsByProvider.size());
+        synchronized (mLock) {
+            for (Entry<String, ArrayList<UpdateRecord>> entry
+                : mRecordsByProvider.entrySet()) {
+                String provider = entry.getKey();
+                for (UpdateRecord record : entry.getValue()) {
+                    if (record.mReceiver.mIdentity.mUid == uid
+                        && record.mIsForegroundUid != foreground) {
+                        if (D) Log.d(TAG, "request from uid " + uid + " is now "
+                            + (foreground ? "foreground" : "background)"));
+                        record.mIsForegroundUid = foreground;
+
+                        if (!isThrottlingExemptLocked(record.mReceiver.mIdentity)) {
+                            affectedProviders.add(provider);
+                        }
+                    }
+                }
+            }
+            for (String provider : affectedProviders) {
+                applyRequirementsLocked(provider);
+            }
+
+            for (Entry<IGnssMeasurementsListener, Identity> entry
+                : mGnssMeasurementsListeners.entrySet()) {
+                if (entry.getValue().mUid == uid) {
+                    if (D) Log.d(TAG, "gnss measurements listener from uid " + uid
+                        + " is now " + (foreground ? "foreground" : "background)"));
+                    if (foreground || isThrottlingExemptLocked(entry.getValue())) {
+                        mGnssMeasurementsProvider.addListener(entry.getKey());
+                    } else {
+                        mGnssMeasurementsProvider.removeListener(entry.getKey());
+                    }
+                }
+            }
+
+            for (Entry<IGnssNavigationMessageListener, Identity> entry
+                : mGnssNavigationMessageListeners.entrySet()) {
+                if (entry.getValue().mUid == uid) {
+                    if (D) Log.d(TAG, "gnss navigation message listener from uid "
+                        + uid + " is now "
+                        + (foreground ? "foreground" : "background)"));
+                    if (foreground || isThrottlingExemptLocked(entry.getValue())) {
+                        mGnssNavigationMessageProvider.addListener(entry.getKey());
+                    } else {
+                        mGnssNavigationMessageProvider.removeListener(entry.getKey());
+                    }
+                }
+            }
+        }
+    }
+
     private static boolean isImportanceForeground(int importance) {
         return importance <= FOREGROUND_IMPORTANCE_CUTOFF;
     }
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 86c8909..8ea334d 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -1058,6 +1058,15 @@
     }
 
     @Override
+    public void setIPv6AddrGenMode(String iface, int mode) throws ServiceSpecificException {
+        try {
+            mNetdService.setIPv6AddrGenMode(iface, mode);
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    @Override
     public void disableIpv6(String iface) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
         try {
diff --git a/services/core/java/com/android/server/RescueParty.java b/services/core/java/com/android/server/RescueParty.java
index 3b36c3c..1924a86 100644
--- a/services/core/java/com/android/server/RescueParty.java
+++ b/services/core/java/com/android/server/RescueParty.java
@@ -55,6 +55,7 @@
     private static final String PROP_RESCUE_LEVEL = "sys.rescue_level";
     private static final String PROP_RESCUE_BOOT_COUNT = "sys.rescue_boot_count";
     private static final String PROP_RESCUE_BOOT_START = "sys.rescue_boot_start";
+    private static final String PROP_VIRTUAL_DEVICE = "ro.hardware.virtual_device";
 
     private static final int LEVEL_NONE = 0;
     private static final int LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS = 1;
@@ -336,6 +337,10 @@
      * a good proxy for someone doing local development work.
      */
     private static boolean isUsbActive() {
+        if (SystemProperties.getBoolean(PROP_VIRTUAL_DEVICE, false)) {
+            Slog.v(TAG, "Assuming virtual device is connected over USB");
+            return true;
+        }
         try {
             final String state = FileUtils
                     .readTextFile(new File("/sys/class/android_usb/android0/state"), 128, "");
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index f718e80..aa2ce1c 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -108,6 +108,7 @@
 import com.android.internal.widget.LockPatternUtils;
 import com.android.server.NativeDaemonConnector.Command;
 import com.android.server.NativeDaemonConnector.SensitiveArg;
+import com.android.server.pm.PackageManagerException;
 import com.android.server.pm.PackageManagerService;
 import com.android.server.storage.AppFuseBridge;
 
@@ -1078,7 +1079,8 @@
                     flags |= DiskInfo.FLAG_ADOPTABLE;
                 }
                 // Adoptable storage isn't currently supported on FBE devices
-                if (StorageManager.isFileEncryptedNativeOnly()) {
+                if (StorageManager.isFileEncryptedNativeOnly()
+                        && !SystemProperties.getBoolean(StorageManager.PROP_ADOPTABLE_FBE, false)) {
                     flags &= ~DiskInfo.FLAG_ADOPTABLE;
                 }
                 mDisks.put(id, new DiskInfo(id, flags));
@@ -2045,7 +2047,8 @@
         }
 
         if ((mask & StorageManager.DEBUG_FORCE_ADOPTABLE) != 0) {
-            if (StorageManager.isFileEncryptedNativeOnly()) {
+            if (StorageManager.isFileEncryptedNativeOnly()
+                    && !SystemProperties.getBoolean(StorageManager.PROP_ADOPTABLE_FBE, false)) {
                 throw new IllegalStateException(
                         "Adoptable storage not available on device with native FBE");
             }
@@ -2121,6 +2124,17 @@
             mMoveCallback = callback;
             mMoveTargetUuid = volumeUuid;
 
+            // We need all the users unlocked to move their primary storage
+            final List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
+            for (UserInfo user : users) {
+                if (StorageManager.isFileEncryptedNativeOrEmulated()
+                        && !isUserKeyUnlocked(user.id)) {
+                    Slog.w(TAG, "Failing move due to locked user " + user.id);
+                    onMoveStatusLocked(PackageManager.MOVE_FAILED_LOCKED_USER);
+                    return;
+                }
+            }
+
             // When moving to/from primary physical volume, we probably just nuked
             // the current storage location, so we have nothing to move.
             if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, mPrimaryStorageUuid)
diff --git a/services/core/java/com/android/server/TextServicesManagerService.java b/services/core/java/com/android/server/TextServicesManagerService.java
index 9068745..098b43c 100644
--- a/services/core/java/com/android/server/TextServicesManagerService.java
+++ b/services/core/java/com/android/server/TextServicesManagerService.java
@@ -49,6 +49,7 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.Process;
+import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -797,12 +798,13 @@
                     pw.println(
                             "        " + "mScLocale=" + req.mLocale + " mUid=" + req.mUserId);
                 }
-                final int N = grp.mListeners.size();
+                final int N = grp.mListeners.getRegisteredCallbackCount();
                 for (int i = 0; i < N; i++) {
-                    final InternalDeathRecipient listener = grp.mListeners.get(i);
+                    final ISpellCheckerSessionListener mScListener =
+                            grp.mListeners.getRegisteredCallbackItem(i);
                     pw.println("      " + "Listener #" + i + ":");
-                    pw.println("        " + "mScListener=" + listener.mScListener);
-                    pw.println("        " + "mGroup=" + listener.mGroup);
+                    pw.println("        " + "mScListener=" + mScListener);
+                    pw.println("        " + "mGroup=" + grp);
                 }
             }
             pw.println("");
@@ -840,7 +842,7 @@
     private final class SpellCheckerBindGroup {
         private final String TAG = SpellCheckerBindGroup.class.getSimpleName();
         private final InternalServiceConnection mInternalConnection;
-        private final ArrayList<InternalDeathRecipient> mListeners = new ArrayList<>();
+        private final InternalDeathRecipients mListeners;
         private boolean mUnbindCalled;
         private ISpellCheckerService mSpellChecker;
         private boolean mConnected;
@@ -849,6 +851,7 @@
 
         public SpellCheckerBindGroup(InternalServiceConnection connection) {
             mInternalConnection = connection;
+            mListeners = new InternalDeathRecipients(this);
         }
 
         public void onServiceConnected(ISpellCheckerService spellChecker) {
@@ -865,31 +868,23 @@
             }
         }
 
+        public void onServiceDisconnected() {
+            if (DBG) {
+                Slog.d(TAG, "onServiceDisconnected");
+            }
+
+            synchronized(mSpellCheckerMap) {
+                mSpellChecker = null;
+                mConnected = false;
+            }
+        }
+
         public void removeListener(ISpellCheckerSessionListener listener) {
             if (DBG) {
                 Slog.w(TAG, "remove listener: " + listener.hashCode());
             }
             synchronized(mSpellCheckerMap) {
-                final int size = mListeners.size();
-                final ArrayList<InternalDeathRecipient> removeList = new ArrayList<>();
-                for (int i = 0; i < size; ++i) {
-                    final InternalDeathRecipient tempRecipient = mListeners.get(i);
-                    if(tempRecipient.hasSpellCheckerListener(listener)) {
-                        if (DBG) {
-                            Slog.w(TAG, "found existing listener.");
-                        }
-                        removeList.add(tempRecipient);
-                    }
-                }
-                final int removeSize = removeList.size();
-                for (int i = 0; i < removeSize; ++i) {
-                    if (DBG) {
-                        Slog.w(TAG, "Remove " + removeList.get(i));
-                    }
-                    final InternalDeathRecipient idr = removeList.get(i);
-                    idr.mScListener.asBinder().unlinkToDeath(idr, 0);
-                    mListeners.remove(idr);
-                }
+                mListeners.unregister(listener);
                 cleanLocked();
             }
         }
@@ -903,7 +898,7 @@
                 return;
             }
             // If there are no more active listeners, clean up.  Only do this once.
-            if (!mListeners.isEmpty()) {
+            if (mListeners.getRegisteredCallbackCount() > 0) {
                 return;
             }
             if (!mPendingSessionRequests.isEmpty()) {
@@ -927,12 +922,10 @@
         public void removeAll() {
             Slog.e(TAG, "Remove the spell checker bind unexpectedly.");
             synchronized(mSpellCheckerMap) {
-                final int size = mListeners.size();
+                final int size = mListeners.getRegisteredCallbackCount();
                 for (int i = 0; i < size; ++i) {
-                    final InternalDeathRecipient idr = mListeners.get(i);
-                    idr.mScListener.asBinder().unlinkToDeath(idr, 0);
+                    mListeners.unregister(mListeners.getRegisteredCallbackItem(i));
                 }
-                mListeners.clear();
                 mPendingSessionRequests.clear();
                 mOnGoingSessionRequests.clear();
                 cleanLocked();
@@ -973,12 +966,9 @@
                     return;
                 }
                 if (mOnGoingSessionRequests.remove(request)) {
-                    final InternalDeathRecipient recipient =
-                            new InternalDeathRecipient(this, request.mScListener);
                     try {
                         request.mTsListener.onServiceConnected(newSession);
-                        request.mScListener.asBinder().linkToDeath(recipient, 0);
-                        mListeners.add(recipient);
+                        mListeners.register(request.mScListener);
                     } catch (RemoteException e) {
                         // Technically this can happen if the spell checker client app is already
                         // dead.  We can just forget about this request; the request is already
@@ -1019,31 +1009,32 @@
         @Override
         public void onServiceDisconnected(ComponentName name) {
             synchronized(mSpellCheckerMap) {
-                final SpellCheckerBindGroup group = mSpellCheckerBindGroups.get(mSciId);
-                if (group != null && this == group.mInternalConnection) {
-                    mSpellCheckerBindGroups.remove(mSciId);
-                }
+                onServiceDisconnectedInnerLocked(name);
+            }
+        }
+
+        private void onServiceDisconnectedInnerLocked(ComponentName name) {
+            if (DBG) {
+                Slog.w(TAG, "onServiceDisconnected: " + name);
+            }
+            final SpellCheckerBindGroup group = mSpellCheckerBindGroups.get(mSciId);
+            if (group != null && this == group.mInternalConnection) {
+                group.onServiceDisconnected();
             }
         }
     }
 
-    private static final class InternalDeathRecipient implements IBinder.DeathRecipient {
-        public final ISpellCheckerSessionListener mScListener;
+    private static final class InternalDeathRecipients extends
+            RemoteCallbackList<ISpellCheckerSessionListener> {
         private final SpellCheckerBindGroup mGroup;
 
-        public InternalDeathRecipient(SpellCheckerBindGroup group,
-                ISpellCheckerSessionListener scListener) {
-            mScListener = scListener;
+        public InternalDeathRecipients(SpellCheckerBindGroup group) {
             mGroup = group;
         }
 
-        public boolean hasSpellCheckerListener(ISpellCheckerSessionListener listener) {
-            return listener.asBinder().equals(mScListener.asBinder());
-        }
-
         @Override
-        public void binderDied() {
-            mGroup.removeListener(mScListener);
+        public void onCallbackDied(ISpellCheckerSessionListener listener) {
+            mGroup.removeListener(listener);
         }
     }
 
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 3948ee1..a54fe72 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -162,7 +162,8 @@
 
         @Override
         public void onStopUser(int userHandle) {
-            mService.onStopUser(userHandle);
+            Slog.i(TAG, "onStopUser " + userHandle);
+            mService.purgeUserData(userHandle);
         }
     }
 
@@ -314,6 +315,21 @@
 
         injector.addLocalService(new AccountManagerInternalImpl());
 
+        IntentFilter userFilter = new IntentFilter();
+        userFilter.addAction(Intent.ACTION_USER_REMOVED);
+        mContext.registerReceiverAsUser(new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                String action = intent.getAction();
+                if (Intent.ACTION_USER_REMOVED.equals(action)) {
+                    int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
+                    if (userId < 1) return;
+                    Slog.i(TAG, "User " + userId + " removed");
+                    purgeUserData(userId);
+                }
+            }
+        }, UserHandle.ALL, userFilter, null, null);
+
         // Need to cancel account request notifications if the update/install can access the account
         new PackageMonitor() {
             @Override
@@ -1360,9 +1376,7 @@
         }
     }
 
-
-    private void onStopUser(int userId) {
-        Log.i(TAG, "onStopUser " + userId);
+    private void purgeUserData(int userId) {
         UserAccounts accounts;
         synchronized (mUsers) {
             accounts = mUsers.get(userId);
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index 6c3fe91..2cd2603 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -48,9 +48,11 @@
     private static final String KEY_GC_MIN_INTERVAL = "gc_min_interval";
     private static final String KEY_FULL_PSS_MIN_INTERVAL = "full_pss_min_interval";
     private static final String KEY_FULL_PSS_LOWERED_INTERVAL = "full_pss_lowered_interval";
-    private static final String KEY_POWER_CHECK_DELAY = "power_check_delay";
-    private static final String KEY_WAKE_LOCK_MIN_CHECK_DURATION = "wake_lock_min_check_duration";
-    private static final String KEY_CPU_MIN_CHECK_DURATION = "cpu_min_check_duration";
+    private static final String KEY_POWER_CHECK_INTERVAL = "power_check_interval";
+    private static final String KEY_POWER_CHECK_MAX_CPU_1 = "power_check_max_cpu_1";
+    private static final String KEY_POWER_CHECK_MAX_CPU_2 = "power_check_max_cpu_2";
+    private static final String KEY_POWER_CHECK_MAX_CPU_3 = "power_check_max_cpu_3";
+    private static final String KEY_POWER_CHECK_MAX_CPU_4 = "power_check_max_cpu_4";
     private static final String KEY_SERVICE_USAGE_INTERACTION_TIME
             = "service_usage_interaction_time";
     private static final String KEY_USAGE_STATS_INTERACTION_INTERVAL
@@ -73,11 +75,11 @@
     private static final long DEFAULT_GC_MIN_INTERVAL = 60*1000;
     private static final long DEFAULT_FULL_PSS_MIN_INTERVAL = 10*60*1000;
     private static final long DEFAULT_FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
-    private static final long DEFAULT_POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
-    private static final long DEFAULT_WAKE_LOCK_MIN_CHECK_DURATION
-            = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
-    private static final long DEFAULT_CPU_MIN_CHECK_DURATION
-            = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
+    private static final long DEFAULT_POWER_CHECK_INTERVAL = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
+    private static final int DEFAULT_POWER_CHECK_MAX_CPU_1 = 25;
+    private static final int DEFAULT_POWER_CHECK_MAX_CPU_2 = 25;
+    private static final int DEFAULT_POWER_CHECK_MAX_CPU_3 = 10;
+    private static final int DEFAULT_POWER_CHECK_MAX_CPU_4 = 2;
     private static final long DEFAULT_SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
     private static final long DEFAULT_USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
     private static final long DEFAULT_SERVICE_RESTART_DURATION = 1*1000;
@@ -133,16 +135,26 @@
     // when the request is due to the memory state being lowered.
     long FULL_PSS_LOWERED_INTERVAL = DEFAULT_FULL_PSS_LOWERED_INTERVAL;
 
-    // The rate at which we check for apps using excessive power -- 15 mins.
-    long POWER_CHECK_DELAY = DEFAULT_POWER_CHECK_DELAY;
-
-    // The minimum sample duration we will allow before deciding we have
-    // enough data on wake locks to start killing things.
-    long WAKE_LOCK_MIN_CHECK_DURATION = DEFAULT_WAKE_LOCK_MIN_CHECK_DURATION;
-
     // The minimum sample duration we will allow before deciding we have
     // enough data on CPU usage to start killing things.
-    long CPU_MIN_CHECK_DURATION = DEFAULT_CPU_MIN_CHECK_DURATION;
+    long POWER_CHECK_INTERVAL = DEFAULT_POWER_CHECK_INTERVAL;
+
+    // The maximum CPU (as a percentage) a process is allowed to use over the first
+    // power check interval that it is cached.
+    int POWER_CHECK_MAX_CPU_1 = DEFAULT_POWER_CHECK_MAX_CPU_1;
+
+    // The maximum CPU (as a percentage) a process is allowed to use over the second
+    // power check interval that it is cached.  The home app will never check for less
+    // CPU than this (it will not test against the 3 or 4 levels).
+    int POWER_CHECK_MAX_CPU_2 = DEFAULT_POWER_CHECK_MAX_CPU_2;
+
+    // The maximum CPU (as a percentage) a process is allowed to use over the third
+    // power check interval that it is cached.
+    int POWER_CHECK_MAX_CPU_3 = DEFAULT_POWER_CHECK_MAX_CPU_3;
+
+    // The maximum CPU (as a percentage) a process is allowed to use over the fourth
+    // power check interval that it is cached.
+    int POWER_CHECK_MAX_CPU_4 = DEFAULT_POWER_CHECK_MAX_CPU_4;
 
     // This is the amount of time an app needs to be running a foreground service before
     // we will consider it to be doing interaction for usage stats.
@@ -270,12 +282,16 @@
                     DEFAULT_FULL_PSS_MIN_INTERVAL);
             FULL_PSS_LOWERED_INTERVAL = mParser.getLong(KEY_FULL_PSS_LOWERED_INTERVAL,
                     DEFAULT_FULL_PSS_LOWERED_INTERVAL);
-            POWER_CHECK_DELAY = mParser.getLong(KEY_POWER_CHECK_DELAY,
-                    DEFAULT_POWER_CHECK_DELAY);
-            WAKE_LOCK_MIN_CHECK_DURATION = mParser.getLong(KEY_WAKE_LOCK_MIN_CHECK_DURATION,
-                    DEFAULT_WAKE_LOCK_MIN_CHECK_DURATION);
-            CPU_MIN_CHECK_DURATION = mParser.getLong(KEY_CPU_MIN_CHECK_DURATION,
-                    DEFAULT_CPU_MIN_CHECK_DURATION);
+            POWER_CHECK_INTERVAL = mParser.getLong(KEY_POWER_CHECK_INTERVAL,
+                    DEFAULT_POWER_CHECK_INTERVAL);
+            POWER_CHECK_MAX_CPU_1 = mParser.getInt(KEY_POWER_CHECK_MAX_CPU_1,
+                    DEFAULT_POWER_CHECK_MAX_CPU_1);
+            POWER_CHECK_MAX_CPU_2 = mParser.getInt(KEY_POWER_CHECK_MAX_CPU_2,
+                    DEFAULT_POWER_CHECK_MAX_CPU_2);
+            POWER_CHECK_MAX_CPU_3 = mParser.getInt(KEY_POWER_CHECK_MAX_CPU_3,
+                    DEFAULT_POWER_CHECK_MAX_CPU_3);
+            POWER_CHECK_MAX_CPU_4 = mParser.getInt(KEY_POWER_CHECK_MAX_CPU_4,
+                    DEFAULT_POWER_CHECK_MAX_CPU_4);
             SERVICE_USAGE_INTERACTION_TIME = mParser.getLong(KEY_SERVICE_USAGE_INTERACTION_TIME,
                     DEFAULT_SERVICE_USAGE_INTERACTION_TIME);
             USAGE_STATS_INTERACTION_INTERVAL = mParser.getLong(KEY_USAGE_STATS_INTERACTION_INTERVAL,
@@ -335,12 +351,16 @@
         pw.println(FULL_PSS_MIN_INTERVAL);
         pw.print("  "); pw.print(KEY_FULL_PSS_LOWERED_INTERVAL); pw.print("=");
         pw.println(FULL_PSS_LOWERED_INTERVAL);
-        pw.print("  "); pw.print(KEY_POWER_CHECK_DELAY); pw.print("=");
-        pw.println(POWER_CHECK_DELAY);
-        pw.print("  "); pw.print(KEY_WAKE_LOCK_MIN_CHECK_DURATION); pw.print("=");
-        pw.println(WAKE_LOCK_MIN_CHECK_DURATION);
-        pw.print("  "); pw.print(KEY_CPU_MIN_CHECK_DURATION); pw.print("=");
-        pw.println(CPU_MIN_CHECK_DURATION);
+        pw.print("  "); pw.print(KEY_POWER_CHECK_INTERVAL); pw.print("=");
+        pw.println(POWER_CHECK_INTERVAL);
+        pw.print("  "); pw.print(KEY_POWER_CHECK_MAX_CPU_1); pw.print("=");
+        pw.println(POWER_CHECK_MAX_CPU_1);
+        pw.print("  "); pw.print(KEY_POWER_CHECK_MAX_CPU_2); pw.print("=");
+        pw.println(POWER_CHECK_MAX_CPU_2);
+        pw.print("  "); pw.print(KEY_POWER_CHECK_MAX_CPU_3); pw.print("=");
+        pw.println(POWER_CHECK_MAX_CPU_3);
+        pw.print("  "); pw.print(KEY_POWER_CHECK_MAX_CPU_4); pw.print("=");
+        pw.println(POWER_CHECK_MAX_CPU_4);
         pw.print("  "); pw.print(KEY_SERVICE_USAGE_INTERACTION_TIME); pw.print("=");
         pw.println(SERVICE_USAGE_INTERACTION_TIME);
         pw.print("  "); pw.print(KEY_USAGE_STATS_INTERACTION_INTERVAL); pw.print("=");
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 05c123d..f519478 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -255,7 +255,6 @@
 import android.content.IIntentSender;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.IntentSender;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ConfigurationInfo;
@@ -508,8 +507,6 @@
 
     static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
 
-    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
-
     // Amount of time after a call to stopAppSwitches() during which we will
     // prevent further untrusted switches from happening.
     static final long APP_SWITCH_DELAY_TIME = 5*1000;
@@ -1320,11 +1317,6 @@
     boolean mDidAppSwitch;
 
     /**
-     * Last time (in realtime) at which we checked for power usage.
-     */
-    long mLastPowerCheckRealtime;
-
-    /**
      * Last time (in uptime) at which we checked for power usage.
      */
     long mLastPowerCheckUptime;
@@ -1658,7 +1650,7 @@
     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
     static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
-    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
+    static final int CHECK_EXCESSIVE_POWER_USE_MSG = 27;
     static final int CLEAR_DNS_CACHE_MSG = 28;
     static final int UPDATE_HTTP_PROXY_MSG = 29;
     static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
@@ -2123,12 +2115,12 @@
                 } catch (RemoteException e) {
                 }
             } break;
-            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
+            case CHECK_EXCESSIVE_POWER_USE_MSG: {
                 synchronized (ActivityManagerService.this) {
-                    checkExcessivePowerUsageLocked(true);
-                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
-                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
-                    sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
+                    checkExcessivePowerUsageLocked();
+                    removeMessages(CHECK_EXCESSIVE_POWER_USE_MSG);
+                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
+                    sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
                 }
             } break;
             case REPORT_MEM_USAGE_MSG: {
@@ -3003,6 +2995,9 @@
                                     }
                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
                                     pr.curCpuTime += st.rel_utime + st.rel_stime;
+                                    if (pr.lastCpuTime == 0) {
+                                        pr.lastCpuTime = pr.curCpuTime;
+                                    }
                                 } else {
                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
                                     if (ps == null || !ps.isActive()) {
@@ -4047,7 +4042,11 @@
                     aInfo.applicationInfo.uid, true);
             if (app == null || app.instr == null) {
                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
-                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
+                final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
+                // For ANR debugging to verify if the user activity is the one that actually
+                // launched.
+                final String myReason = reason + ":" + userId + ":" + resolvedUserId;
+                mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
             }
         } else {
             Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
@@ -5729,7 +5728,7 @@
     }
 
     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
-        if (true || IS_USER_BUILD) {
+        if (true || Build.IS_USER) {
             return;
         }
         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
@@ -6718,10 +6717,6 @@
                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
             }
             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
-            if (app.isolated) {
-                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
-                getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
-            }
             boolean willRestart = false;
             if (app.persistent && !app.isolated) {
                 if (!callerWillRestart) {
@@ -6731,6 +6726,10 @@
                 }
             }
             app.kill(reason, true);
+            if (app.isolated) {
+                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
+                getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
+            }
             handleAppDiedLocked(app, willRestart, allowRestart);
             if (willRestart) {
                 removeLruProcessLocked(app);
@@ -6770,14 +6769,14 @@
                 mHeavyWeightProcess = null;
             }
             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
-            if (app.isolated) {
-                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
-            }
             // Take care of any launching providers waiting for this process.
             cleanupAppInLaunchingProvidersLocked(app, true);
             // Take care of any services that are waiting for the process.
             mServices.processStartTimedOutLocked(app);
             app.kill("start timeout", true);
+            if (app.isolated) {
+                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
+            }
             removeLruProcessLocked(app);
             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
                 Slog.w(TAG, "Unattached app died before backup, skipping");
@@ -7259,8 +7258,8 @@
 
             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
                 // Start looking for apps that are abusing wake locks.
-                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
-                mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
+                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
+                mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
                 // Tell anyone interested that we are done booting!
                 SystemProperties.set("sys.boot_completed", "1");
 
@@ -12451,12 +12450,6 @@
             mStackSupervisor.goingToSleepLocked();
             sendNotifyVrManagerOfSleepState(true);
             updateOomAdjLocked();
-
-            // Initialize the wake times of all processes.
-            checkExcessivePowerUsageLocked(false);
-            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
-            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
-            mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
         }
 
         // Also update state in a special way for running foreground services UI.
@@ -12597,7 +12590,6 @@
                 Binder.restoreCallingIdentity(ident);
             }
         }
-        closeSystemDialogs("setLockScreenShown");
     }
 
     @Override
@@ -14545,7 +14537,7 @@
         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
                 crashInfo);
 
-        final boolean isFatal = "eng".equals(Build.TYPE) || Settings.Global
+        final boolean isFatal = Build.IS_ENG || Settings.Global
                 .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
         final boolean isSystem = (r == null) || r.persistent;
 
@@ -15975,9 +15967,6 @@
                 pw.println("  mBooting=" + mBooting
                         + " mCallFinishBooting=" + mCallFinishBooting
                         + " mBootAnimationComplete=" + mBootAnimationComplete);
-                pw.print("  mLastPowerCheckRealtime=");
-                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
-                        pw.println("");
                 pw.print("  mLastPowerCheckUptime=");
                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
                         pw.println("");
@@ -16632,8 +16621,6 @@
 
         Collections.sort(list, comparator);
 
-        final long curRealtime = SystemClock.elapsedRealtime();
-        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
         final long curUptime = SystemClock.uptimeMillis();
         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
 
@@ -16730,24 +16717,6 @@
                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
 
                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
-                    if (r.lastWakeTime != 0) {
-                        long wtime;
-                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
-                        synchronized (stats) {
-                            wtime = stats.getProcessWakeTime(r.info.uid,
-                                    r.pid, curRealtime);
-                        }
-                        long timeUsed = wtime - r.lastWakeTime;
-                        pw.print(prefix);
-                        pw.print("    ");
-                        pw.print("keep awake over ");
-                        TimeUtils.formatDuration(realtimeSince, pw);
-                        pw.print(" used ");
-                        TimeUtils.formatDuration(timeUsed, pw);
-                        pw.print(" (");
-                        pw.print((timeUsed*100)/realtimeSince);
-                        pw.println("%)");
-                    }
                     if (r.lastCpuTime != 0) {
                         long timeUsed = r.curCpuTime - r.lastCpuTime;
                         pw.print(prefix);
@@ -20615,7 +20584,7 @@
                                    && config.navigation == Configuration.NAVIGATION_NONAV);
         int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
         final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
-                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE))
+                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
                 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
                 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
         return inputMethodExists && uiModeSupportsDialogs;
@@ -21886,58 +21855,28 @@
         }
     }
 
-    final void checkExcessivePowerUsageLocked(boolean doKills) {
+    final void checkExcessivePowerUsageLocked() {
         updateCpuStatsNow();
 
         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
-        boolean doWakeKills = doKills;
-        boolean doCpuKills = doKills;
-        if (mLastPowerCheckRealtime == 0) {
-            doWakeKills = false;
-        }
+        boolean doCpuKills = true;
         if (mLastPowerCheckUptime == 0) {
             doCpuKills = false;
         }
-        if (stats.isScreenOn()) {
-            doWakeKills = false;
-        }
-        final long curRealtime = SystemClock.elapsedRealtime();
-        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
         final long curUptime = SystemClock.uptimeMillis();
         final long uptimeSince = curUptime - mLastPowerCheckUptime;
-        mLastPowerCheckRealtime = curRealtime;
         mLastPowerCheckUptime = curUptime;
-        if (realtimeSince < mConstants.WAKE_LOCK_MIN_CHECK_DURATION) {
-            doWakeKills = false;
-        }
-        if (uptimeSince < mConstants.CPU_MIN_CHECK_DURATION) {
-            doCpuKills = false;
-        }
         int i = mLruProcesses.size();
         while (i > 0) {
             i--;
             ProcessRecord app = mLruProcesses.get(i);
             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
-                long wtime;
-                synchronized (stats) {
-                    wtime = stats.getProcessWakeTime(app.info.uid,
-                            app.pid, curRealtime);
+                if (app.lastCpuTime <= 0) {
+                    continue;
                 }
-                long wtimeUsed = wtime - app.lastWakeTime;
                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
                 if (DEBUG_POWER) {
                     StringBuilder sb = new StringBuilder(128);
-                    sb.append("Wake for ");
-                    app.toShortString(sb);
-                    sb.append(": over ");
-                    TimeUtils.formatDuration(realtimeSince, sb);
-                    sb.append(" used ");
-                    TimeUtils.formatDuration(wtimeUsed, sb);
-                    sb.append(" (");
-                    sb.append((wtimeUsed*100)/realtimeSince);
-                    sb.append("%)");
-                    Slog.i(TAG_POWER, sb.toString());
-                    sb.setLength(0);
                     sb.append("CPU for ");
                     app.toShortString(sb);
                     sb.append(": over ");
@@ -21949,29 +21888,33 @@
                     sb.append("%)");
                     Slog.i(TAG_POWER, sb.toString());
                 }
-                // If a process has held a wake lock for more
-                // than 50% of the time during this period,
-                // that sounds bad.  Kill!
-                if (doWakeKills && realtimeSince > 0
-                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
-                    synchronized (stats) {
-                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
-                                realtimeSince, wtimeUsed);
+                // If the process has used too much CPU over the last duration, the
+                // user probably doesn't want this, so kill!
+                if (doCpuKills && uptimeSince > 0) {
+                    // What is the limit for this process?
+                    int cpuLimit;
+                    long checkDur = curUptime - app.whenUnimportant;
+                    if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
+                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
+                    } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
+                            || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
+                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
+                    } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
+                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
+                    } else {
+                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
                     }
-                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
-                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
-                } else if (doCpuKills && uptimeSince > 0
-                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
-                    synchronized (stats) {
-                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
-                                uptimeSince, cputimeUsed);
+                    if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
+                        synchronized (stats) {
+                            stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
+                                    uptimeSince, cputimeUsed);
+                        }
+                        app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
+                                + " dur=" + checkDur + " limit=" + cpuLimit, true);
+                        app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
                     }
-                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
-                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
-                } else {
-                    app.lastWakeTime = wtime;
-                    app.lastCpuTime = app.curCpuTime;
                 }
+                app.lastCpuTime = app.curCpuTime;
             }
         }
     }
@@ -22145,15 +22088,10 @@
             if (setImportant && !curImportant) {
                 // This app is no longer something we consider important enough to allow to
                 // use arbitrary amounts of battery power.  Note
-                // its current wake lock time to later know to kill it if
+                // its current CPU time to later know to kill it if
                 // it is not behaving well.
-                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
-                synchronized (stats) {
-                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
-                            app.pid, nowElapsed);
-                }
-                app.lastCpuTime = app.curCpuTime;
-
+                app.whenUnimportant = now;
+                app.lastCpuTime = 0;
             }
             // Inform UsageStats of important process state change
             // Must be called before updating setProcState
@@ -24209,7 +24147,7 @@
                 record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
                 record.waitingForNetwork = false;
                 final long totalTime = SystemClock.uptimeMillis() - startTime;
-                if (totalTime >= mWaitForNetworkTimeoutMs) {
+                if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) {
                     Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
                             + totalTime + ". Uid: " + callingUid + " procStateSeq: "
                             + procStateSeq + " UidRec: " + record
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 68f4d0d..c7cac3b 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -91,7 +91,6 @@
 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.am.ActivityManagerService.IS_USER_BUILD;
 import static com.android.server.am.ActivityManagerService.TAKE_FULLSCREEN_SCREENSHOTS;
 import static com.android.server.am.ActivityStack.ActivityState.DESTROYED;
 import static com.android.server.am.ActivityStack.ActivityState.DESTROYING;
@@ -1801,7 +1800,7 @@
     }
 
     void startLaunchTickingLocked() {
-        if (IS_USER_BUILD) {
+        if (Build.IS_USER) {
             return;
         }
         if (launchTickTime == 0) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 1ccac1b..ead8f60 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -38,11 +38,13 @@
 import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.os.Process.SYSTEM_UID;
 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.FLAG_PRIVATE;
 import static android.view.Display.INVALID_DISPLAY;
 import static android.view.Display.REMOVE_MODE_DESTROY_CONTENT;
+import static android.view.Display.TYPE_VIRTUAL;
 
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_PICTURE_IN_PICTURE_EXPANDED_TO_FULLSCREEN;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
@@ -1670,7 +1672,8 @@
             // owner.
             final int launchDisplayId = options.getLaunchDisplayId();
             if (launchDisplayId != INVALID_DISPLAY
-                    && !isCallerAllowedToLaunchOnDisplay(callingPid, callingUid, launchDisplayId)) {
+                    && !isCallerAllowedToLaunchOnDisplay(callingPid, callingUid, launchDisplayId,
+                    aInfo)) {
                 final String msg = "Permission Denial: starting " + intent.toString()
                         + " from " + callerApp + " (pid=" + callingPid
                         + ", uid=" + callingUid + ") with launchDisplayId="
@@ -1684,7 +1687,8 @@
     }
 
     /** Check if caller is allowed to launch activities on specified display. */
-    boolean isCallerAllowedToLaunchOnDisplay(int callingPid, int callingUid, int launchDisplayId) {
+    boolean isCallerAllowedToLaunchOnDisplay(int callingPid, int callingUid, int launchDisplayId,
+            ActivityInfo aInfo) {
         if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check: displayId=" + launchDisplayId
                 + " callingPid=" + callingPid + " callingUid=" + callingUid);
 
@@ -1694,6 +1698,25 @@
             return false;
         }
 
+        // Check if the caller can manage activity stacks.
+        final int startAnyPerm = mService.checkPermission(MANAGE_ACTIVITY_STACKS, callingPid,
+                callingUid);
+        if (startAnyPerm == PERMISSION_GRANTED) {
+            if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
+                    + " allow launch any on display");
+            return true;
+        }
+
+        if (activityDisplay.mDisplay.getType() == TYPE_VIRTUAL
+                && activityDisplay.mDisplay.getOwnerUid() != SYSTEM_UID
+                && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) {
+            // Limit launching on virtual displays, because their contents can be read from Surface
+            // by apps that created them.
+            if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
+                    + " disallow launch on virtual display for not-embedded activity");
+            return false;
+        }
+
         if (!activityDisplay.isPrivate()) {
             // Anyone can launch on a public display.
             if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
@@ -1715,15 +1738,6 @@
             return true;
         }
 
-        // Check if the caller can manage activity stacks.
-        final int startAnyPerm = mService.checkPermission(MANAGE_ACTIVITY_STACKS, callingPid,
-                callingUid);
-        if (startAnyPerm == PERMISSION_GRANTED) {
-            if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
-                    + " allow launch any on display");
-            return true;
-        }
-
         Slog.w(TAG, "Launch on display check: denied");
         return false;
     }
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index be30d5a..a31c33e 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -17,6 +17,7 @@
 package com.android.server.am;
 
 import static android.app.Activity.RESULT_CANCELED;
+import static android.app.ActivityManager.START_ABORTED;
 import static android.app.ActivityManager.START_CANCELED;
 import static android.app.ActivityManager.START_CLASS_NOT_FOUND;
 import static android.app.ActivityManager.START_DELIVERED_TO_TOP;
@@ -279,7 +280,9 @@
             // mLastStartActivityRecord[0] is set in the call to startActivity above.
             outActivity[0] = mLastStartActivityRecord[0];
         }
-        return mLastStartActivityResult;
+
+        // Aborted results are treated as successes externally, but we must track them internally.
+        return mLastStartActivityResult != START_ABORTED ? mLastStartActivityResult : START_SUCCESS;
     }
 
     /** DO NOT call this method directly. Use {@link #startActivityLocked} instead. */
@@ -465,7 +468,7 @@
             // We pretend to the caller that it was really started, but
             // they will just get a cancel result.
             ActivityOptions.abort(options);
-            return START_SUCCESS;
+            return START_ABORTED;
         }
 
         // If permissions need a review before any of the app components can run, we
@@ -2308,6 +2311,7 @@
         pw.println(prefix + "ActivityStarter:");
         prefix = prefix + "  ";
 
+        pw.println(prefix + "mCurrentUser=" + mSupervisor.mCurrentUser);
         pw.println(prefix + "mLastStartReason=" + mLastStartReason);
         pw.println(prefix + "mLastStartActivityTimeMs="
                 + DateFormat.getDateTimeInstance().format(new Date(mLastStartActivityTimeMs)));
diff --git a/services/core/java/com/android/server/am/AppErrorDialog.java b/services/core/java/com/android/server/am/AppErrorDialog.java
index c9c1d00..51ce30e 100644
--- a/services/core/java/com/android/server/am/AppErrorDialog.java
+++ b/services/core/java/com/android/server/am/AppErrorDialog.java
@@ -21,6 +21,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.res.Resources;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
@@ -32,8 +33,6 @@
 import android.widget.FrameLayout;
 import android.widget.TextView;
 
-import static com.android.server.am.ActivityManagerService.IS_USER_BUILD;
-
 final class AppErrorDialog extends BaseErrorDialog implements View.OnClickListener {
 
     private final ActivityManagerService mService;
@@ -124,7 +123,7 @@
         close.setVisibility(!hasRestart ? View.VISIBLE : View.GONE);
         close.setOnClickListener(this);
 
-        boolean showMute = !IS_USER_BUILD && Settings.Global.getInt(context.getContentResolver(),
+        boolean showMute = !Build.IS_USER && Settings.Global.getInt(context.getContentResolver(),
                 Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
         final TextView mute = findViewById(com.android.internal.R.id.aerr_mute);
         mute.setOnClickListener(this);
diff --git a/services/core/java/com/android/server/am/AppNotRespondingDialog.java b/services/core/java/com/android/server/am/AppNotRespondingDialog.java
index a3a6778..d9c6a30 100644
--- a/services/core/java/com/android/server/am/AppNotRespondingDialog.java
+++ b/services/core/java/com/android/server/am/AppNotRespondingDialog.java
@@ -35,8 +35,6 @@
 import android.widget.FrameLayout;
 import android.widget.TextView;
 
-import static com.android.server.am.ActivityManagerService.IS_USER_BUILD;
-
 final class AppNotRespondingDialog extends BaseErrorDialog implements View.OnClickListener {
     private static final String TAG = "AppNotRespondingDialog";
 
diff --git a/services/core/java/com/android/server/am/KeyguardController.java b/services/core/java/com/android/server/am/KeyguardController.java
index 2e0ec0b..a46c851 100644
--- a/services/core/java/com/android/server/am/KeyguardController.java
+++ b/services/core/java/com/android/server/am/KeyguardController.java
@@ -17,6 +17,7 @@
 package com.android.server.am;
 
 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
+import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
 import static android.view.WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS;
 import static android.view.WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE;
 import static android.view.WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
@@ -34,6 +35,7 @@
 
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.Trace;
 import android.util.Slog;
 
 import com.android.internal.policy.IKeyguardDismissCallback;
@@ -111,22 +113,28 @@
      *              etc.
      */
     void keyguardGoingAway(int flags) {
-        if (mKeyguardShowing) {
-            mWindowManager.deferSurfaceLayout();
-            try {
-                setKeyguardGoingAway(true);
-                mWindowManager.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY,
-                        false /* alwaysKeepCurrent */, convertTransitFlags(flags),
-                        false /* forceOverride */);
-                mService.updateSleepIfNeededLocked();
+        if (!mKeyguardShowing) {
+            return;
+        }
+        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "keyguardGoingAway");
+        mWindowManager.deferSurfaceLayout();
+        try {
+            setKeyguardGoingAway(true);
+            mWindowManager.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY,
+                    false /* alwaysKeepCurrent */, convertTransitFlags(flags),
+                    false /* forceOverride */);
+            mService.updateSleepIfNeededLocked();
 
-                // Some stack visibility might change (e.g. docked stack)
-                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
-                mStackSupervisor.addStartingWindowsForVisibleActivities(true /* taskSwitch */);
-                mWindowManager.executeAppTransition();
-            } finally {
-                mWindowManager.continueSurfaceLayout();
-            }
+            // Some stack visibility might change (e.g. docked stack)
+            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
+            mStackSupervisor.addStartingWindowsForVisibleActivities(true /* taskSwitch */);
+            mWindowManager.executeAppTransition();
+        } finally {
+            Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "keyguardGoingAway: surfaceLayout");
+            mWindowManager.continueSurfaceLayout();
+            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
+
+            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
         }
     }
 
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 53c7f84..411e973 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -143,7 +143,7 @@
     ActiveInstrumentation instr;// Set to currently active instrumentation running in process
     boolean usingWrapper;       // Set to true when process was launched with a wrapper attached
     final ArraySet<BroadcastRecord> curReceivers = new ArraySet<BroadcastRecord>();// receivers currently running in the app
-    long lastWakeTime;          // How long proc held wake lock at last check
+    long whenUnimportant;       // When (uptime) the process last became unimportant
     long lastCpuTime;           // How long proc has run CPU at last check
     long curCpuTime;            // How long proc has run CPU most recently
     long lastRequestedGc;       // When we last asked the app to do a gc
@@ -204,7 +204,7 @@
     boolean whitelistManager;
 
     void dump(PrintWriter pw, String prefix) {
-        final long now = SystemClock.uptimeMillis();
+        final long nowUptime = SystemClock.uptimeMillis();
 
         pw.print(prefix); pw.print("user #"); pw.print(userId);
                 pw.print(" uid="); pw.print(info.uid);
@@ -254,11 +254,11 @@
         pw.print(prefix); pw.print("pid="); pw.print(pid); pw.print(" starting=");
                 pw.println(starting);
         pw.print(prefix); pw.print("lastActivityTime=");
-                TimeUtils.formatDuration(lastActivityTime, now, pw);
+                TimeUtils.formatDuration(lastActivityTime, nowUptime, pw);
                 pw.print(" lastPssTime=");
-                TimeUtils.formatDuration(lastPssTime, now, pw);
+                TimeUtils.formatDuration(lastPssTime, nowUptime, pw);
                 pw.print(" nextPssTime=");
-                TimeUtils.formatDuration(nextPssTime, now, pw);
+                TimeUtils.formatDuration(nextPssTime, nowUptime, pw);
                 pw.println();
         pw.print(prefix); pw.print("adjSeq="); pw.print(adjSeq);
                 pw.print(" lruSeq="); pw.print(lruSeq);
@@ -294,7 +294,7 @@
                 pw.print(" pssProcState="); pw.print(pssProcState);
                 pw.print(" setProcState="); pw.print(setProcState);
                 pw.print(" lastStateTime=");
-                TimeUtils.formatDuration(lastStateTime, now, pw);
+                TimeUtils.formatDuration(lastStateTime, nowUptime, pw);
                 pw.println();
         if (hasShownUi || pendingUiClean || hasAboveClient || treatLikeActivity) {
             pw.print(prefix); pw.print("hasShownUi="); pw.print(hasShownUi);
@@ -334,29 +334,26 @@
         }
         if (lastProviderTime > 0) {
             pw.print(prefix); pw.print("lastProviderTime=");
-            TimeUtils.formatDuration(lastProviderTime, now, pw);
+            TimeUtils.formatDuration(lastProviderTime, nowUptime, pw);
             pw.println();
         }
         if (hasStartedServices) {
             pw.print(prefix); pw.print("hasStartedServices="); pw.println(hasStartedServices);
         }
-        if (setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
-            long wtime;
-            synchronized (mBatteryStats) {
-                wtime = mBatteryStats.getProcessWakeTime(info.uid,
-                        pid, SystemClock.elapsedRealtime());
-            }
-            pw.print(prefix); pw.print("lastWakeTime="); pw.print(lastWakeTime);
-                    pw.print(" timeUsed=");
-                    TimeUtils.formatDuration(wtime-lastWakeTime, pw); pw.println("");
+        if (setProcState > ActivityManager.PROCESS_STATE_SERVICE) {
             pw.print(prefix); pw.print("lastCpuTime="); pw.print(lastCpuTime);
-                    pw.print(" timeUsed=");
-                    TimeUtils.formatDuration(curCpuTime-lastCpuTime, pw); pw.println("");
+                    if (lastCpuTime > 0) {
+                        pw.print(" timeUsed=");
+                        TimeUtils.formatDuration(curCpuTime - lastCpuTime, pw);
+                    }
+                    pw.print(" whenUnimportant=");
+                    TimeUtils.formatDuration(whenUnimportant - nowUptime, pw);
+                    pw.println();
         }
         pw.print(prefix); pw.print("lastRequestedGc=");
-                TimeUtils.formatDuration(lastRequestedGc, now, pw);
+                TimeUtils.formatDuration(lastRequestedGc, nowUptime, pw);
                 pw.print(" lastLowMemory=");
-                TimeUtils.formatDuration(lastLowMemory, now, pw);
+                TimeUtils.formatDuration(lastLowMemory, nowUptime, pw);
                 pw.print(" reportLowMemory="); pw.println(reportLowMemory);
         if (killed || killedByAm || waitingToKill != null) {
             pw.print(prefix); pw.print("killed="); pw.print(killed);
diff --git a/services/core/java/com/android/server/am/UriPermission.java b/services/core/java/com/android/server/am/UriPermission.java
index 0aa54d9..90577e3 100644
--- a/services/core/java/com/android/server/am/UriPermission.java
+++ b/services/core/java/com/android/server/am/UriPermission.java
@@ -17,6 +17,7 @@
 package com.android.server.am;
 
 import android.content.Intent;
+import android.os.Binder;
 import android.os.UserHandle;
 import android.util.ArraySet;
 import android.util.Log;
@@ -101,7 +102,8 @@
             Slog.d(TAG,
                     "Permission for " + targetPkg + " to " + uri + " is changing from 0x"
                             + Integer.toHexString(oldModeFlags) + " to 0x"
-                            + Integer.toHexString(modeFlags),
+                            + Integer.toHexString(modeFlags) + " via calling UID "
+                            + Binder.getCallingUid() + " PID " + Binder.getCallingPid(),
                     new Throwable());
         }
     }
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 2b8ac0d..405ee32 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -1499,8 +1499,7 @@
             }
         }
 
-        // One way or another, we're running!
-        return true;
+        return state.state != UserState.STATE_STOPPING && state.state != UserState.STATE_SHUTDOWN;
     }
 
     UserInfo getCurrentUser() {
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index e5ab784..7eee3e4 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -239,6 +239,7 @@
     private static final int MSG_SET_A2DP_SRC_CONNECTION_STATE = 101;
     private static final int MSG_SET_A2DP_SINK_CONNECTION_STATE = 102;
     private static final int MSG_A2DP_DEVICE_CONFIG_CHANGE = 103;
+    private static final int MSG_DISABLE_AUDIO_FOR_UID = 104;
     // end of messages handled under wakelock
 
     private static final int BTA2DP_DOCK_TIMEOUT_MILLIS = 8000;
@@ -706,6 +707,8 @@
 
         mMediaFocusControl = new MediaFocusControl(mContext, mPlaybackMonitor);
 
+        mRecordMonitor = new RecordingActivityMonitor(mContext);
+
         readAndSetLowRamDevice();
 
         // Call setRingerModeInt() to apply correct mute
@@ -4871,6 +4874,12 @@
                     mAudioEventWakeLock.release();
                     break;
 
+                case MSG_DISABLE_AUDIO_FOR_UID:
+                    mPlaybackMonitor.disableAudioForUid( msg.arg1 == 1 /* disable */,
+                            msg.arg2 /* uid */);
+                    mAudioEventWakeLock.release();
+                    break;
+
                 case MSG_REPORT_NEW_ROUTES: {
                     int N = mRoutesObservers.beginBroadcast();
                     if (N > 0) {
@@ -6309,6 +6318,8 @@
         dumpAudioPolicies(pw);
 
         mPlaybackMonitor.dump(pw);
+
+        mRecordMonitor.dump(pw);
     }
 
     private static String safeMediaVolumeStateToString(Integer state) {
@@ -6591,6 +6602,13 @@
                 }
             }
         }
+
+        @Override
+        public void disableAudioForUid(boolean disable, int uid) {
+            queueMsgUnderWakeLock(mAudioHandler, MSG_DISABLE_AUDIO_FOR_UID,
+                    disable ? 1 : 0 /* arg1 */,  uid /* arg2 */,
+                    null /* obj */,  0 /* delay */);
+        }
     }
 
     //==========================================================================================
@@ -6730,10 +6748,13 @@
     //======================
     // Audio policy callbacks from AudioSystem for recording configuration updates
     //======================
-    private final RecordingActivityMonitor mRecordMonitor = new RecordingActivityMonitor();
+    private final RecordingActivityMonitor mRecordMonitor;
 
     public void registerRecordingCallback(IRecordingConfigDispatcher rcdb) {
-        mRecordMonitor.registerRecordingCallback(rcdb);
+        final boolean isPrivileged =
+                (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
+                        android.Manifest.permission.MODIFY_AUDIO_ROUTING));
+        mRecordMonitor.registerRecordingCallback(rcdb, isPrivileged);
     }
 
     public void unregisterRecordingCallback(IRecordingConfigDispatcher rcdb) {
@@ -6741,7 +6762,10 @@
     }
 
     public List<AudioRecordingConfiguration> getActiveRecordingConfigurations() {
-        return mRecordMonitor.getActiveRecordingConfigurations();
+        final boolean isPrivileged =
+                (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
+                        android.Manifest.permission.MODIFY_AUDIO_ROUTING));
+        return mRecordMonitor.getActiveRecordingConfigurations(isPrivileged);
     }
 
     public void disableRingtoneSync(final int userId) {
diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
index 702cbbe..663559f 100644
--- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
@@ -29,6 +29,8 @@
 import android.os.RemoteException;
 import android.util.Log;
 
+import com.android.internal.util.ArrayUtils;
+
 import java.io.PrintWriter;
 import java.text.DateFormat;
 import java.util.ArrayList;
@@ -67,6 +69,12 @@
                     .createIfNeeded()
                     .build();
 
+    // TODO support VolumeShaper on those players
+    private static final int[] UNDUCKABLE_PLAYER_TYPES = {
+            AudioPlaybackConfiguration.PLAYER_TYPE_AAUDIO,
+            AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL,
+    };
+
     // like a PLAY_CREATE_IF_NEEDED operation but with a skip to the end of the ramp
     private static final VolumeShaper.Operation PLAY_SKIP_RAMP =
             new VolumeShaper.Operation.Builder(PLAY_CREATE_IF_NEEDED).setXOffset(1.0f).build();
@@ -87,6 +95,43 @@
     }
 
     //=================================================================
+    private final ArrayList<Integer> mBannedUids = new ArrayList<Integer>();
+
+    // see AudioManagerInternal.disableAudioForUid(boolean disable, int uid)
+    public void disableAudioForUid(boolean disable, int uid) {
+        synchronized(mPlayerLock) {
+            final int index = mBannedUids.indexOf(new Integer(uid));
+            if (index >= 0) {
+                if (!disable) {
+                    mBannedUids.remove(index);
+                    // nothing else to do, future playback requests from this uid are ok
+                } // no else to handle, uid already present, so disabling again is no-op
+            } else {
+                if (disable) {
+                    for (AudioPlaybackConfiguration apc : mPlayers.values()) {
+                        checkBanPlayer(apc, uid);
+                    }
+                    mBannedUids.add(new Integer(uid));
+                } // no else to handle, uid already not in list, so enabling again is no-op
+            }
+        }
+    }
+
+    private boolean checkBanPlayer(@NonNull AudioPlaybackConfiguration apc, int uid) {
+        final boolean toBan = (apc.getClientUid() == uid);
+        if (toBan) {
+            final int piid = apc.getPlayerInterfaceId();
+            try {
+                Log.v(TAG, "banning player " + piid + " uid:" + uid);
+                apc.getPlayerProxy().pause();
+            } catch (Exception e) {
+                Log.e(TAG, "error banning player " + piid + " uid:" + uid, e);
+            }
+        }
+        return toBan;
+    }
+
+    //=================================================================
     // Track players and their states
     // methods playerAttributes, playerEvent, releasePlayer are all oneway calls
     //  into AudioService. They trigger synchronous dispatchPlaybackChange() which updates
@@ -129,6 +174,14 @@
             if (apc == null) {
                 return;
             }
+            if (event == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) {
+                for (Integer uidInteger: mBannedUids) {
+                    if (checkBanPlayer(apc, uidInteger.intValue())) {
+                        // player was banned, do not update its state
+                        return;
+                    }
+                }
+            }
             if (apc.getPlayerType() == AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL) {
                 // FIXME SoundPool not ready for state reporting
                 return;
@@ -178,10 +231,17 @@
             pw.println("\n  ducked players:");
             mDuckingManager.dump(pw);
             // players muted due to the device ringing or being in a call
-            pw.println("\n  muted player piids:");
+            pw.print("\n  muted player piids:");
             for (int piid : mMutedPlayers) {
-                pw.println(" " + piid);
+                pw.print(" " + piid);
             }
+            pw.println();
+            // banned players:
+            pw.print("\n  banned uids:");
+            for (int uid : mBannedUids) {
+                pw.print(" " + uid);
+            }
+            pw.println();
         }
     }
 
@@ -298,12 +358,12 @@
                                 + " uid:" + apc.getClientUid() + " pid:" + apc.getClientPid()
                                 + " - SPEECH");
                         return false;
-                    } else if (apc.getPlayerType()
-                            == AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL) {
-                        // TODO support ducking of SoundPool players
+                    } else if (ArrayUtils.contains(UNDUCKABLE_PLAYER_TYPES, apc.getPlayerType())) {
                         Log.v(TAG, "not ducking player " + apc.getPlayerInterfaceId()
                                 + " uid:" + apc.getClientUid() + " pid:" + apc.getClientPid()
-                                + " - SoundPool");
+                                + " due to type:"
+                                + AudioPlaybackConfiguration.toLogFriendlyPlayerType(
+                                        apc.getPlayerType()));
                         return false;
                     }
                     apcsToDuck.add(apc);
diff --git a/services/core/java/com/android/server/audio/RecordingActivityMonitor.java b/services/core/java/com/android/server/audio/RecordingActivityMonitor.java
index 57d55de..34309b6 100644
--- a/services/core/java/com/android/server/audio/RecordingActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/RecordingActivityMonitor.java
@@ -16,8 +16,11 @@
 
 package com.android.server.audio;
 
+import android.content.Context;
+import android.content.pm.PackageManager;
 import android.media.AudioFormat;
 import android.media.AudioManager;
+import android.media.AudioPlaybackConfiguration;
 import android.media.AudioRecordingConfiguration;
 import android.media.AudioSystem;
 import android.media.IRecordingConfigDispatcher;
@@ -26,7 +29,10 @@
 import android.os.RemoteException;
 import android.util.Log;
 
+import java.io.PrintWriter;
+import java.text.DateFormat;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -39,31 +45,47 @@
     public final static String TAG = "AudioService.RecordingActivityMonitor";
 
     private ArrayList<RecMonitorClient> mClients = new ArrayList<RecMonitorClient>();
+    // a public client is one that needs an anonymized version of the playback configurations, we
+    // keep track of whether there is at least one to know when we need to create the list of
+    // playback configurations that do not contain uid/package name information.
+    private boolean mHasPublicClients = false;
 
     private HashMap<Integer, AudioRecordingConfiguration> mRecordConfigs =
             new HashMap<Integer, AudioRecordingConfiguration>();
 
-    RecordingActivityMonitor() {
+    private final PackageManager mPackMan;
+
+    RecordingActivityMonitor(Context ctxt) {
         RecMonitorClient.sMonitor = this;
+        mPackMan = ctxt.getPackageManager();
     }
 
     /**
      * Implementation of android.media.AudioSystem.AudioRecordingCallback
      */
-    public void onRecordingConfigurationChanged(int event, int session, int source,
-            int[] recordingInfo) {
+    public void onRecordingConfigurationChanged(int event, int uid, int session, int source,
+            int[] recordingInfo, String packName) {
         if (MediaRecorder.isSystemOnlyAudioSource(source)) {
             return;
         }
-        final List<AudioRecordingConfiguration> configs =
-                updateSnapshot(event, session, source, recordingInfo);
-        if (configs != null){
-            synchronized(mClients) {
+        final List<AudioRecordingConfiguration> configsSystem =
+                updateSnapshot(event, uid, session, source, recordingInfo);
+        if (configsSystem != null){
+            synchronized (mClients) {
+                // list of recording configurations for "public consumption". It is only computed if
+                // there are non-system recording activity listeners.
+                final List<AudioRecordingConfiguration> configsPublic = mHasPublicClients ?
+                        anonymizeForPublicConsumption(configsSystem) :
+                            new ArrayList<AudioRecordingConfiguration>();
                 final Iterator<RecMonitorClient> clientIterator = mClients.iterator();
                 while (clientIterator.hasNext()) {
+                    final RecMonitorClient rmc = clientIterator.next();
                     try {
-                        clientIterator.next().mDispatcherCb.dispatchRecordingConfigChange(
-                                configs);
+                        if (rmc.mIsPrivileged) {
+                            rmc.mDispatcherCb.dispatchRecordingConfigChange(configsSystem);
+                        } else {
+                            rmc.mDispatcherCb.dispatchRecordingConfigChange(configsPublic);
+                        }
                     } catch (RemoteException e) {
                         Log.w(TAG, "Could not call dispatchRecordingConfigChange() on client", e);
                     }
@@ -72,17 +94,42 @@
         }
     }
 
+    protected void dump(PrintWriter pw) {
+        // players
+        pw.println("\nRecordActivityMonitor dump time: "
+                + DateFormat.getTimeInstance().format(new Date()));
+        synchronized(mRecordConfigs) {
+            for (AudioRecordingConfiguration conf : mRecordConfigs.values()) {
+                conf.dump(pw);
+            }
+        }
+    }
+
+    private ArrayList<AudioRecordingConfiguration> anonymizeForPublicConsumption(
+            List<AudioRecordingConfiguration> sysConfigs) {
+        ArrayList<AudioRecordingConfiguration> publicConfigs =
+                new ArrayList<AudioRecordingConfiguration>();
+        // only add active anonymized configurations,
+        for (AudioRecordingConfiguration config : sysConfigs) {
+            publicConfigs.add(AudioRecordingConfiguration.anonymizedCopy(config));
+        }
+        return publicConfigs;
+    }
+
     void initMonitor() {
         AudioSystem.setRecordingCallback(this);
     }
 
-    void registerRecordingCallback(IRecordingConfigDispatcher rcdb) {
+    void registerRecordingCallback(IRecordingConfigDispatcher rcdb, boolean isPrivileged) {
         if (rcdb == null) {
             return;
         }
-        synchronized(mClients) {
-            final RecMonitorClient rmc = new RecMonitorClient(rcdb);
+        synchronized (mClients) {
+            final RecMonitorClient rmc = new RecMonitorClient(rcdb, isPrivileged);
             if (rmc.init()) {
+                if (!isPrivileged) {
+                    mHasPublicClients = true;
+                }
                 mClients.add(rmc);
             }
         }
@@ -92,22 +139,34 @@
         if (rcdb == null) {
             return;
         }
-        synchronized(mClients) {
+        synchronized (mClients) {
             final Iterator<RecMonitorClient> clientIterator = mClients.iterator();
+            boolean hasPublicClients = false;
             while (clientIterator.hasNext()) {
                 RecMonitorClient rmc = clientIterator.next();
                 if (rcdb.equals(rmc.mDispatcherCb)) {
                     rmc.release();
                     clientIterator.remove();
-                    break;
+                } else {
+                    if (!rmc.mIsPrivileged) {
+                        hasPublicClients = true;
+                    }
                 }
             }
+            mHasPublicClients = hasPublicClients;
         }
     }
 
-    List<AudioRecordingConfiguration> getActiveRecordingConfigurations() {
+    List<AudioRecordingConfiguration> getActiveRecordingConfigurations(boolean isPrivileged) {
         synchronized(mRecordConfigs) {
-            return new ArrayList<AudioRecordingConfiguration>(mRecordConfigs.values());
+            if (isPrivileged) {
+                return new ArrayList<AudioRecordingConfiguration>(mRecordConfigs.values());
+            } else {
+                final List<AudioRecordingConfiguration> configsPublic =
+                        anonymizeForPublicConsumption(
+                            new ArrayList<AudioRecordingConfiguration>(mRecordConfigs.values()));
+                return configsPublic;
+            }
         }
     }
 
@@ -122,8 +181,8 @@
      * @return null if the list of active recording sessions has not been modified, a list
      *     with the current active configurations otherwise.
      */
-    private List<AudioRecordingConfiguration> updateSnapshot(int event, int session, int source,
-            int[] recordingInfo) {
+    private List<AudioRecordingConfiguration> updateSnapshot(int event, int uid, int session,
+            int source, int[] recordingInfo) {
         final boolean configChanged;
         final ArrayList<AudioRecordingConfiguration> configs;
         synchronized(mRecordConfigs) {
@@ -147,10 +206,19 @@
                         .build();
                 final int patchHandle = recordingInfo[6];
                 final Integer sessionKey = new Integer(session);
+
+                final String[] packages = mPackMan.getPackagesForUid(uid);
+                final String packageName;
+                if (packages != null && packages.length > 0) {
+                    packageName = packages[0];
+                } else {
+                    packageName = "";
+                }
+                final AudioRecordingConfiguration updatedConfig =
+                        new AudioRecordingConfiguration(uid, session, source,
+                                clientFormat, deviceFormat, patchHandle, packageName);
+
                 if (mRecordConfigs.containsKey(sessionKey)) {
-                    final AudioRecordingConfiguration updatedConfig =
-                            new AudioRecordingConfiguration(session, source,
-                                    clientFormat, deviceFormat, patchHandle);
                     if (updatedConfig.equals(mRecordConfigs.get(sessionKey))) {
                         configChanged = false;
                     } else {
@@ -160,9 +228,7 @@
                         configChanged = true;
                     }
                 } else {
-                    mRecordConfigs.put(sessionKey,
-                            new AudioRecordingConfiguration(session, source,
-                                    clientFormat, deviceFormat, patchHandle));
+                    mRecordConfigs.put(sessionKey, updatedConfig);
                     configChanged = true;
                 }
                 break;
@@ -189,9 +255,11 @@
         static RecordingActivityMonitor sMonitor;
 
         final IRecordingConfigDispatcher mDispatcherCb;
+        final boolean mIsPrivileged;
 
-        RecMonitorClient(IRecordingConfigDispatcher rcdb) {
+        RecMonitorClient(IRecordingConfigDispatcher rcdb, boolean isPrivileged) {
             mDispatcherCb = rcdb;
+            mIsPrivileged = isPrivileged;
         }
 
         public void binderDied() {
diff --git a/services/core/java/com/android/server/audio/RotationHelper.java b/services/core/java/com/android/server/audio/RotationHelper.java
index 359cc36..ad20ed8 100644
--- a/services/core/java/com/android/server/audio/RotationHelper.java
+++ b/services/core/java/com/android/server/audio/RotationHelper.java
@@ -17,15 +17,13 @@
 package com.android.server.audio;
 
 import android.content.Context;
+import android.hardware.display.DisplayManager;
 import android.media.AudioSystem;
 import android.os.Handler;
 import android.util.Log;
-import android.view.OrientationEventListener;
 import android.view.Surface;
 import android.view.WindowManager;
 
-import com.android.server.policy.WindowOrientationListener;
-
 /**
  * Class to handle device rotation events for AudioService, and forward device rotation
  * to the audio HALs through AudioSystem.
@@ -42,18 +40,17 @@
 
     private static final String TAG = "AudioService.RotationHelper";
 
-    private static AudioOrientationListener sOrientationListener;
-    private static AudioWindowOrientationListener sWindowOrientationListener;
+    private static AudioDisplayListener sDisplayListener;
 
     private static final Object sRotationLock = new Object();
     private static int sDeviceRotation = Surface.ROTATION_0; // R/W synchronized on sRotationLock
 
     private static Context sContext;
+    private static Handler sHandler;
 
     /**
      * post conditions:
-     * - (sWindowOrientationListener != null) xor (sOrientationListener != null)
-     * - sWindowOrientationListener xor sOrientationListener is enabled
+     * - sDisplayListener != null
      * - sContext != null
      */
     static void init(Context context, Handler handler) {
@@ -61,34 +58,20 @@
             throw new IllegalArgumentException("Invalid null context");
         }
         sContext = context;
-        sWindowOrientationListener = new AudioWindowOrientationListener(context, handler);
-        sWindowOrientationListener.enable();
-        if (!sWindowOrientationListener.canDetectOrientation()) {
-            // cannot use com.android.server.policy.WindowOrientationListener, revert to public
-            // orientation API
-            Log.i(TAG, "Not using WindowOrientationListener, reverting to OrientationListener");
-            sWindowOrientationListener.disable();
-            sWindowOrientationListener = null;
-            sOrientationListener = new AudioOrientationListener(context);
-            sOrientationListener.enable();
-        }
+        sHandler = handler;
+        sDisplayListener = new AudioDisplayListener();
+        enable();
     }
 
     static void enable() {
-        if (sWindowOrientationListener != null) {
-            sWindowOrientationListener.enable();
-        } else {
-            sOrientationListener.enable();
-        }
+        ((DisplayManager) sContext.getSystemService(Context.DISPLAY_SERVICE))
+                .registerDisplayListener(sDisplayListener, sHandler);
         updateOrientation();
     }
 
     static void disable() {
-        if (sWindowOrientationListener != null) {
-            sWindowOrientationListener.disable();
-        } else {
-            sOrientationListener.disable();
-        }
+        ((DisplayManager) sContext.getSystemService(Context.DISPLAY_SERVICE))
+                .unregisterDisplayListener(sDisplayListener);
     }
 
     /**
@@ -128,84 +111,21 @@
     }
 
     /**
-     * Uses android.view.OrientationEventListener
+     * Uses android.hardware.display.DisplayManager.DisplayListener
      */
-    final static class AudioOrientationListener extends OrientationEventListener {
-        AudioOrientationListener(Context context) {
-            super(context);
+    final static class AudioDisplayListener implements DisplayManager.DisplayListener {
+
+        @Override
+        public void onDisplayAdded(int displayId) {
         }
 
         @Override
-        public void onOrientationChanged(int orientation) {
+        public void onDisplayRemoved(int displayId) {
+        }
+
+        @Override
+        public void onDisplayChanged(int displayId) {
             updateOrientation();
         }
     }
-
-    /**
-     * Uses com.android.server.policy.WindowOrientationListener
-     */
-    final static class AudioWindowOrientationListener extends WindowOrientationListener {
-        private static RotationCheckThread sRotationCheckThread;
-
-        AudioWindowOrientationListener(Context context, Handler handler) {
-            super(context, handler);
-        }
-
-        public void onProposedRotationChanged(int rotation) {
-            updateOrientation();
-            if (sRotationCheckThread != null) {
-                sRotationCheckThread.endCheck();
-            }
-            sRotationCheckThread = new RotationCheckThread();
-            sRotationCheckThread.beginCheck();
-        }
-    }
-
-    /**
-     * When com.android.server.policy.WindowOrientationListener report an orientation change,
-     * the UI may not have rotated yet. This thread polls with gradually increasing delays
-     * the new orientation.
-     */
-    final static class RotationCheckThread extends Thread {
-        // how long to wait between each rotation check
-        private final int[] WAIT_TIMES_MS = { 10, 20, 50, 100, 100, 200, 200, 500 };
-        private int mWaitCounter;
-        private final Object mCounterLock = new Object();
-
-        RotationCheckThread() {
-            super("RotationCheck");
-        }
-
-        void beginCheck() {
-            synchronized(mCounterLock) {
-                mWaitCounter = 0;
-            }
-            try {
-                start();
-            } catch (IllegalStateException e) { }
-        }
-
-        void endCheck() {
-            synchronized(mCounterLock) {
-                mWaitCounter = WAIT_TIMES_MS.length;
-            }
-        }
-
-        public void run() {
-            while (mWaitCounter < WAIT_TIMES_MS.length) {
-                int waitTimeMs;
-                synchronized(mCounterLock) {
-                    waitTimeMs = mWaitCounter < WAIT_TIMES_MS.length ?
-                            WAIT_TIMES_MS[mWaitCounter] : 0;
-                    mWaitCounter++;
-                }
-                try {
-                    if (waitTimeMs > 0) {
-                        sleep(waitTimeMs);
-                        updateOrientation();
-                    }
-                } catch (InterruptedException e) { }
-            }
-        }
-    }
 }
\ No newline at end of file
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index 13054a6..468cb29 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -60,6 +60,7 @@
 import android.util.SparseIntArray;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.LocalServices;
@@ -166,6 +167,8 @@
         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw_)) return;
         final IndentingPrintWriter pw = new IndentingPrintWriter(pw_, "  ");
 
+        final boolean dumpAll = ArrayUtils.contains(args, "-a");
+
         // 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.
         final long identityToken = clearCallingIdentity();
@@ -173,7 +176,7 @@
             if (mSyncManager == null) {
                 pw.println("No SyncManager created!  (Disk full?)");
             } else {
-                mSyncManager.dump(fd, pw);
+                mSyncManager.dump(fd, pw, dumpAll);
             }
             pw.println();
             pw.println("Observer tree:");
@@ -603,7 +606,7 @@
                 SyncStorageEngine.EndPoint info;
                 info = new SyncStorageEngine.EndPoint(account, authority, userId);
                 syncManager.clearScheduledSyncOperations(info);
-                syncManager.cancelActiveSync(info, null /* all syncs for this adapter */);
+                syncManager.cancelActiveSync(info, null /* all syncs for this adapter */, "API");
             }
         } finally {
             restoreCallingIdentity(identityToken);
@@ -631,7 +634,7 @@
             }
             // Cancel active syncs and clear pending syncs from the queue.
             syncManager.cancelScheduledSyncOperation(info, extras);
-            syncManager.cancelActiveSync(info, extras);
+            syncManager.cancelActiveSync(info, extras, "API");
         } finally {
             restoreCallingIdentity(identityToken);
         }
diff --git a/services/core/java/com/android/server/content/SyncJobService.java b/services/core/java/com/android/server/content/SyncJobService.java
index a621d73..1f02ebf 100644
--- a/services/core/java/com/android/server/content/SyncJobService.java
+++ b/services/core/java/com/android/server/content/SyncJobService.java
@@ -34,6 +34,8 @@
     private Messenger mMessenger;
     private SparseArray<JobParameters> jobParamsMap = new SparseArray<JobParameters>();
 
+    private final SyncLogger mLogger = SyncLogger.getInstance();
+
     /**
      * This service is started by the SyncManager which passes a messenger object to
      * communicate back with it. It never stops while the device is running.
@@ -63,6 +65,9 @@
 
     @Override
     public boolean onStartJob(JobParameters params) {
+
+        mLogger.purgeOldLogs();
+
         boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
         synchronized (jobParamsMap) {
             jobParamsMap.put(params.getJobId(), params);
@@ -70,6 +75,9 @@
         Message m = Message.obtain();
         m.what = SyncManager.SyncHandler.MESSAGE_START_SYNC;
         SyncOperation op = SyncOperation.maybeCreateFromJobExtras(params.getExtras());
+
+        mLogger.log("onStopJob() jobid=", params.getJobId(), " op=", op);
+
         if (op == null) {
             Slog.e(TAG, "Got invalid job " + params.getJobId());
             return false;
@@ -88,7 +96,7 @@
             Slog.v(TAG, "onStopJob called " + params.getJobId() + ", reason: "
                     + params.getStopReason());
         }
-
+        mLogger.log("onStopJob() ", mLogger.jobParametersToString(params));
         synchronized (jobParamsMap) {
             jobParamsMap.remove(params.getJobId());
         }
@@ -108,9 +116,13 @@
         return false;
     }
 
-    public void callJobFinished(int jobId, boolean needsReschedule) {
+    public void callJobFinished(int jobId, boolean needsReschedule, String why) {
         synchronized (jobParamsMap) {
             JobParameters params = jobParamsMap.get(jobId);
+            mLogger.log("callJobFinished()",
+                    " needsReschedule=", needsReschedule,
+                    " ", mLogger.jobParametersToString(params),
+                    " why=", why);
             if (params != null) {
                 jobFinished(params, needsReschedule);
                 jobParamsMap.remove(jobId);
diff --git a/services/core/java/com/android/server/content/SyncLogger.java b/services/core/java/com/android/server/content/SyncLogger.java
new file mode 100644
index 0000000..db79464
--- /dev/null
+++ b/services/core/java/com/android/server/content/SyncLogger.java
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2017 The Android Open Source 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.content;
+
+import android.app.job.JobParameters;
+import android.os.Build;
+import android.os.Environment;
+import android.os.FileUtils;
+import android.os.SystemProperties;
+import android.text.format.DateUtils;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+
+import libcore.io.IoUtils;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.io.Writer;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Implements a rotating file logger for the sync manager, which is enabled only on userdebug/eng
+ * builds (unless debug.synclog is set to 1).
+ *
+ * Note this class could be used for other purposes too, but in general we don't want various
+ * system components to log to files, so it's put in a local package here.
+ */
+public class SyncLogger {
+    private static final String TAG = "SyncLogger";
+
+    private static SyncLogger sInstance;
+
+    SyncLogger() {
+    }
+
+    /**
+     * @return the singleton instance.
+     */
+    public static synchronized SyncLogger getInstance() {
+        if (sInstance == null) {
+            final boolean enable = "1".equals(SystemProperties.get("debug.synclog",
+                    Build.IS_DEBUGGABLE ? "1" : "0"));
+            if (enable) {
+                sInstance = new RotatingFileLogger();
+            } else {
+                sInstance = new SyncLogger();
+            }
+        }
+        return sInstance;
+    }
+
+    /**
+     * Write strings to the log file.
+     */
+    public void log(Object... message) {
+    }
+
+    /**
+     * Remove old log files.
+     */
+    public void purgeOldLogs() {
+        // The default implementation is no-op.
+    }
+
+    public String jobParametersToString(JobParameters params) {
+        // The default implementation is no-op.
+        return "";
+    }
+
+    /**
+     * Dump all existing log files into a given writer.
+     */
+    public void dumpAll(PrintWriter pw) {
+    }
+
+    /**
+     * Actual implementation which is only used on userdebug/eng builds (by default).
+     */
+    private static class RotatingFileLogger extends SyncLogger {
+        private final Object mLock = new Object();
+
+        private final long mKeepAgeMs = TimeUnit.DAYS.toMillis(7);
+
+        private static final SimpleDateFormat sTimestampFormat
+                = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+
+        private static final SimpleDateFormat sFilenameDateFormat
+                = new SimpleDateFormat("yyyy-MM-dd");
+
+        @GuardedBy("mLock")
+        private final Date mCachedDate = new Date();
+
+        @GuardedBy("mLock")
+        private final StringBuilder mStringBuilder = new StringBuilder();
+
+        private final File mLogPath;
+
+        @GuardedBy("mLock")
+        private long mCurrentLogFileDayTimestamp;
+
+        @GuardedBy("mLock")
+        private Writer mLogWriter;
+
+        @GuardedBy("mLock")
+        private boolean mErrorShown;
+
+        RotatingFileLogger() {
+            mLogPath = new File(Environment.getDataSystemDirectory(), "syncmanager-log");
+        }
+
+        private void handleException(String message, Exception e) {
+            if (!mErrorShown) {
+                Slog.e(TAG, message, e);
+                mErrorShown = true;
+            }
+        }
+
+        @Override
+        public void log(Object... message) {
+            if (message == null) {
+                return;
+            }
+            synchronized (mLock) {
+                final long now = System.currentTimeMillis();
+                openLogLocked(now);
+                if (mLogWriter == null) {
+                    return; // Couldn't open log file?
+                }
+
+                mStringBuilder.setLength(0);
+                mCachedDate.setTime(now);
+                mStringBuilder.append(sTimestampFormat.format(mCachedDate));
+                mStringBuilder.append(' ');
+
+                mStringBuilder.append(android.os.Process.myTid());
+                mStringBuilder.append(' ');
+
+                for (Object o : message) {
+                    mStringBuilder.append(o);
+                }
+                mStringBuilder.append('\n');
+
+                try {
+                    mLogWriter.append(mStringBuilder);
+                    mLogWriter.flush();
+                } catch (IOException e) {
+                    handleException("Failed to write log", e);
+                }
+            }
+        }
+
+        private void openLogLocked(long now) {
+            // If we already have a log file opened and the date has't changed, just use it.
+            final long day = now % DateUtils.DAY_IN_MILLIS;
+            if ((mLogWriter != null) && (day == mCurrentLogFileDayTimestamp)) {
+                return;
+            }
+
+            // Otherwise create a new log file.
+            closeCurrentLogLocked();
+
+            mCurrentLogFileDayTimestamp = day;
+
+            mCachedDate.setTime(now);
+            final String filename = "synclog-" + sFilenameDateFormat.format(mCachedDate) + ".log";
+            final File file = new File(mLogPath, filename);
+
+            file.getParentFile().mkdirs();
+
+            try {
+                mLogWriter = new FileWriter(file, /* append= */ true);
+            } catch (IOException e) {
+                handleException("Failed to open log file: " + file, e);
+            }
+        }
+
+        private void closeCurrentLogLocked() {
+            IoUtils.closeQuietly(mLogWriter);
+            mLogWriter = null;
+        }
+
+        @Override
+        public void purgeOldLogs() {
+            synchronized (mLock) {
+                FileUtils.deleteOlderFiles(mLogPath, /* keepCount= */ 1, mKeepAgeMs);
+            }
+        }
+
+        @Override
+        public String jobParametersToString(JobParameters params) {
+            if (params == null) {
+                return "job:null";
+            } else {
+                return "job:#" + params.getJobId() + ":"
+                        + SyncOperation.maybeCreateFromJobExtras(params.getExtras());
+            }
+        }
+
+        @Override
+        public void dumpAll(PrintWriter pw) {
+            synchronized (mLock) {
+                final String[] files = mLogPath.list();
+                if (files == null || (files.length == 0)) {
+                    return;
+                }
+                Arrays.sort(files);
+
+                for (String file : files) {
+                    dumpFile(pw, new File(mLogPath, file));
+                }
+            }
+        }
+
+        private void dumpFile(PrintWriter pw, File file) {
+            Slog.w(TAG, "Dumping " + file);
+            final char[] buffer = new char[32 * 1024];
+
+            try (Reader in = new BufferedReader(new FileReader(file))) {
+                int read;
+                while ((read = in.read(buffer)) >= 0) {
+                    if (read > 0) {
+                        pw.write(buffer, 0, read);
+                    }
+                }
+            } catch (IOException e) {
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index e3e2658..3559142 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -241,6 +241,8 @@
 
     private final Random mRand;
 
+    private final SyncLogger mLogger;
+
     private boolean isJobIdInUseLockedH(int jobId, List<JobInfo> pendingJobs) {
         for (JobInfo job: pendingJobs) {
             if (job.getId() == jobId) {
@@ -289,13 +291,15 @@
                         mStorageIsLow = true;
                         cancelActiveSync(
                                 SyncStorageEngine.EndPoint.USER_ALL_PROVIDER_ALL_ACCOUNTS_ALL,
-                                null /* any sync */);
+                                null /* any sync */,
+                                "storage low");
                     } else if (Intent.ACTION_DEVICE_STORAGE_OK.equals(action)) {
                         if (Log.isLoggable(TAG, Log.VERBOSE)) {
                             Slog.v(TAG, "Internal storage is ok.");
                         }
                         mStorageIsLow = false;
-                        rescheduleSyncs(EndPoint.USER_ALL_PROVIDER_ALL_ACCOUNTS_ALL);
+                        rescheduleSyncs(EndPoint.USER_ALL_PROVIDER_ALL_ACCOUNTS_ALL,
+                                "storage ok");
                     }
                 }
             };
@@ -378,15 +382,16 @@
                             if (Log.isLoggable(TAG, Log.VERBOSE)) {
                                 Slog.v(TAG, "Reconnection detected: clearing all backoffs");
                             }
+                            // Note the location of this code was wrong from nyc to oc; fixed in DR.
+                            clearAllBackoffs("network reconnect");
                         }
-                        clearAllBackoffs();
                     }
                 }
             };
 
-    private void clearAllBackoffs() {
+    private void clearAllBackoffs(String why) {
         mSyncStorageEngine.clearAllBackoffsLocked();
-        rescheduleSyncs(EndPoint.USER_ALL_PROVIDER_ALL_ACCOUNTS_ALL);
+        rescheduleSyncs(EndPoint.USER_ALL_PROVIDER_ALL_ACCOUNTS_ALL, why);
     }
 
     private boolean readDataConnectionState() {
@@ -502,6 +507,8 @@
         // and creating threads and so on; it may fail if the disk is full.
         mContext = context;
 
+        mLogger = SyncLogger.getInstance();
+
         SyncStorageEngine.init(context);
         mSyncStorageEngine = SyncStorageEngine.getSingleton();
         mSyncStorageEngine.setOnSyncRequestListener(new OnSyncRequestListener() {
@@ -1145,8 +1152,12 @@
         mSyncHandler.sendMessage(msg);
     }
 
-    private void sendCancelSyncsMessage(final SyncStorageEngine.EndPoint info, Bundle extras) {
+    private void sendCancelSyncsMessage(final SyncStorageEngine.EndPoint info, Bundle extras,
+            String why) {
         if (Log.isLoggable(TAG, Log.VERBOSE)) Slog.v(TAG, "sending MESSAGE_CANCEL");
+
+        mLogger.log("sendCancelSyncsMessage() ep=", info, " why=", why);
+
         Message msg = mSyncHandler.obtainMessage();
         msg.what = SyncHandler.MESSAGE_CANCEL;
         msg.setData(extras);
@@ -1227,7 +1238,7 @@
         }
     }
 
-    private void clearBackoffSetting(EndPoint target) {
+    private void clearBackoffSetting(EndPoint target, String why) {
         Pair<Long, Long> backoff = mSyncStorageEngine.getBackoff(target);
         if (backoff != null && backoff.first == SyncStorageEngine.NOT_IN_BACKOFF_MODE &&
                 backoff.second == SyncStorageEngine.NOT_IN_BACKOFF_MODE) {
@@ -1240,7 +1251,7 @@
                 SyncStorageEngine.NOT_IN_BACKOFF_MODE,
                 SyncStorageEngine.NOT_IN_BACKOFF_MODE);
 
-        rescheduleSyncs(target);
+        rescheduleSyncs(target, why);
     }
 
     private void increaseBackoffSetting(EndPoint target) {
@@ -1281,14 +1292,16 @@
             Slog.v(TAG, "Backoff until: " + backoff + ", delayTime: " + newDelayInMs);
         }
         mSyncStorageEngine.setBackoff(target, backoff, newDelayInMs);
-        rescheduleSyncs(target);
+        rescheduleSyncs(target, "increaseBackoffSetting");
     }
 
     /**
      * Reschedule all scheduled syncs for this EndPoint. The syncs will be scheduled according
      * to current backoff and delayUntil values of this EndPoint.
      */
-    private void rescheduleSyncs(EndPoint target) {
+    private void rescheduleSyncs(EndPoint target, String why) {
+        mLogger.log("rescheduleSyncs() ep=", target, " why=", why);
+
         List<SyncOperation> ops = getAllPendingSyncs();
         int count = 0;
         for (SyncOperation op: ops) {
@@ -1316,7 +1329,7 @@
         if (Log.isLoggable(TAG, Log.VERBOSE)) {
             Slog.v(TAG, "Delay Until time set to " + newDelayUntilTime + " for " + target);
         }
-        rescheduleSyncs(target);
+        rescheduleSyncs(target, "delayUntil newDelayUntilTime: " + newDelayUntilTime);
     }
 
     private boolean isAdapterDelayed(EndPoint target) {
@@ -1338,8 +1351,8 @@
      * have null account/provider info to specify all accounts/providers.
      * @param extras if non-null, specifies the exact sync to remove.
      */
-    public void cancelActiveSync(SyncStorageEngine.EndPoint info, Bundle extras) {
-        sendCancelSyncsMessage(info, extras);
+    public void cancelActiveSync(SyncStorageEngine.EndPoint info, Bundle extras, String why) {
+        sendCancelSyncsMessage(info, extras, why);
     }
 
     /**
@@ -1599,7 +1612,8 @@
                         null /* any account */,
                         null /* any authority */,
                         userId),
-                null /* any sync. */
+                null /* any sync. */,
+                "onUserStopped"
         );
     }
 
@@ -1759,10 +1773,15 @@
         }
     }
 
-    protected void dump(FileDescriptor fd, PrintWriter pw) {
+    protected void dump(FileDescriptor fd, PrintWriter pw, boolean dumpAll) {
         final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
         dumpSyncState(ipw);
         dumpSyncAdapters(ipw);
+
+        if (dumpAll) {
+            ipw.println("Detailed Sync History");
+            mLogger.dumpAll(pw);
+        }
     }
 
     static String formatTime(long time) {
@@ -2644,7 +2663,7 @@
                             Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_CANCEL: "
                                     + endpoint + " bundle: " + extras);
                         }
-                        cancelActiveSyncH(endpoint, extras);
+                        cancelActiveSyncH(endpoint, extras, "MESSAGE_CANCEL");
                         break;
 
                     case SyncHandler.MESSAGE_SYNC_FINISHED:
@@ -2660,7 +2679,8 @@
                             Slog.v(TAG, "syncFinished" + payload.activeSyncContext.mSyncOperation);
                         }
                         mSyncJobService.callJobFinished(
-                                payload.activeSyncContext.mSyncOperation.jobId, false);
+                                payload.activeSyncContext.mSyncOperation.jobId, false,
+                                "sync finished");
                         runSyncFinishedOrCanceledH(payload.syncResult,
                                 payload.activeSyncContext);
                         break;
@@ -2704,7 +2724,8 @@
                             SyncResult syncResult = new SyncResult();
                             syncResult.stats.numIoExceptions++;
                             mSyncJobService.callJobFinished(
-                                    currentSyncContext.mSyncOperation.jobId, false);
+                                    currentSyncContext.mSyncOperation.jobId, false,
+                                    "service disconnected");
                             runSyncFinishedOrCanceledH(syncResult, currentSyncContext);
                         }
                         break;
@@ -2722,7 +2743,8 @@
                                     "Detected sync making no progress for %s. cancelling.",
                                     monitoredSyncContext));
                             mSyncJobService.callJobFinished(
-                                    monitoredSyncContext.mSyncOperation.jobId, false);
+                                    monitoredSyncContext.mSyncOperation.jobId, false,
+                                    "no network activity");
                             runSyncFinishedOrCanceledH(
                                     null /* cancel => no result */, monitoredSyncContext);
                         } else {
@@ -2754,8 +2776,10 @@
          * delay. This is equivalent to a failure. If this is a periodic sync, a delayed one-off
          * sync will be scheduled.
          */
-        private void deferSyncH(SyncOperation op, long delay) {
-            mSyncJobService.callJobFinished(op.jobId, false);
+        private void deferSyncH(SyncOperation op, long delay, String why) {
+            mLogger.log("deferSyncH() ", (op.isPeriodic ? "periodic " : ""),
+                    "sync.  op=", op, " delay=", delay, " why=", why);
+            mSyncJobService.callJobFinished(op.jobId, false, why);
             if (op.isPeriodic) {
                 scheduleSyncOperationH(op.createOneTimeSyncOperation(), delay);
             } else {
@@ -2779,10 +2803,10 @@
         /**
          * Cancel an active sync and reschedule it on the JobScheduler with some delay.
          */
-        private void deferActiveSyncH(ActiveSyncContext asc) {
+        private void deferActiveSyncH(ActiveSyncContext asc, String why) {
             SyncOperation op = asc.mSyncOperation;
             runSyncFinishedOrCanceledH(null, asc);
-            deferSyncH(op, SYNC_DELAY_ON_CONFLICT);
+            deferSyncH(op, SYNC_DELAY_ON_CONFLICT, why);
         }
 
         private void startSyncH(SyncOperation op) {
@@ -2790,7 +2814,7 @@
             if (isLoggable) Slog.v(TAG, op.toString());
 
             if (mStorageIsLow) {
-                deferSyncH(op, SYNC_DELAY_ON_LOW_STORAGE);
+                deferSyncH(op, SYNC_DELAY_ON_LOW_STORAGE, "storage low");
                 return;
             }
 
@@ -2800,7 +2824,8 @@
                 List<SyncOperation> ops = getAllPendingSyncs();
                 for (SyncOperation syncOperation: ops) {
                     if (syncOperation.sourcePeriodicId == op.jobId) {
-                        mSyncJobService.callJobFinished(op.jobId, false);
+                        mSyncJobService.callJobFinished(op.jobId, false,
+                                "periodic sync, pending");
                         return;
                     }
                 }
@@ -2808,13 +2833,14 @@
                 // executing according to some backoff criteria.
                 for (ActiveSyncContext asc: mActiveSyncContexts) {
                     if (asc.mSyncOperation.sourcePeriodicId == op.jobId) {
-                        mSyncJobService.callJobFinished(op.jobId, false);
+                        mSyncJobService.callJobFinished(op.jobId, false,
+                                "periodic sync, already running");
                         return;
                     }
                 }
                 // Check for adapter delays.
                 if (isAdapterDelayed(op.target)) {
-                    deferSyncH(op, 0 /* No minimum delay */);
+                    deferSyncH(op, 0 /* No minimum delay */, "backing off");
                     return;
                 }
             }
@@ -2828,13 +2854,13 @@
                         if (isLoggable) {
                             Slog.v(TAG, "Rescheduling sync due to conflict " + op.toString());
                         }
-                        deferSyncH(op, SYNC_DELAY_ON_CONFLICT);
+                        deferSyncH(op, SYNC_DELAY_ON_CONFLICT, "delay on conflict");
                         return;
                     } else {
                         if (isLoggable) {
                             Slog.v(TAG, "Pushing back running sync due to a higher priority sync");
                         }
-                        deferActiveSyncH(asc);
+                        deferActiveSyncH(asc, "preempted");
                         break;
                     }
                 }
@@ -2844,12 +2870,13 @@
             switch (syncOpState) {
                 case SYNC_OP_STATE_INVALID_NO_ACCOUNT_ACCESS:
                 case SYNC_OP_STATE_INVALID: {
-                    mSyncJobService.callJobFinished(op.jobId, false);
+                    mSyncJobService.callJobFinished(op.jobId, false,
+                            "invalid op state: " + syncOpState);
                 } return;
             }
 
             if (!dispatchSyncOperation(op)) {
-                mSyncJobService.callJobFinished(op.jobId, false);
+                mSyncJobService.callJobFinished(op.jobId, false, "dispatchSyncOperation() failed");
             }
 
             setAuthorityPendingState(op.target);
@@ -3019,7 +3046,8 @@
                 if (op.sourcePeriodicId == syncOperation.jobId || op.jobId == syncOperation.jobId) {
                     ActiveSyncContext asc = findActiveSyncContextH(syncOperation.jobId);
                     if (asc != null) {
-                        mSyncJobService.callJobFinished(syncOperation.jobId, false);
+                        mSyncJobService.callJobFinished(syncOperation.jobId, false,
+                                "removePeriodicSyncInternalH");
                         runSyncFinishedOrCanceledH(null, asc);
                     }
                     getJobScheduler().cancel(op.jobId);
@@ -3131,6 +3159,8 @@
             final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo;
             syncAdapterInfo = mSyncAdapters.getServiceInfo(syncAdapterType, info.userId);
             if (syncAdapterInfo == null) {
+                mLogger.log("dispatchSyncOperation() failed: no sync adapter info for ",
+                        syncAdapterType);
                 Log.d(TAG, "can't find a sync adapter for " + syncAdapterType
                         + ", removing settings for it");
                 mSyncStorageEngine.removeAuthority(info);
@@ -3151,6 +3181,8 @@
             postMonitorSyncProgressMessage(activeSyncContext);
 
             if (!activeSyncContext.bindToSyncAdapter(targetComponent, info.userId)) {
+                mLogger.log("dispatchSyncOperation() failed: bind failed. target: ",
+                        targetComponent);
                 Slog.e(TAG, "Bind attempt failed - target: " + targetComponent);
                 closeActiveSyncContext(activeSyncContext);
                 return false;
@@ -3166,16 +3198,25 @@
                 activeSyncContext.mIsLinkedToDeath = true;
                 syncAdapter.linkToDeath(activeSyncContext, 0);
 
+                mLogger.log("Sync start: account=" + syncOperation.target.account,
+                        " authority=", syncOperation.target.provider,
+                        " reason=", SyncOperation.reasonToString(null, syncOperation.reason),
+                        " extras=", SyncOperation.extrasToString(syncOperation.extras));
+
                 activeSyncContext.mSyncAdapter = ISyncAdapter.Stub.asInterface(syncAdapter);
                 activeSyncContext.mSyncAdapter
                         .startSync(activeSyncContext, syncOperation.target.provider,
                                 syncOperation.target.account, syncOperation.extras);
+
+                mLogger.log("Sync finish");
             } catch (RemoteException remoteExc) {
+                mLogger.log("Sync failed with RemoteException: ", remoteExc.toString());
                 Log.d(TAG, "maybeStartNextSync: caught a RemoteException, rescheduling", remoteExc);
                 closeActiveSyncContext(activeSyncContext);
                 increaseBackoffSetting(syncOperation.target);
                 scheduleSyncOperationH(syncOperation);
             } catch (RuntimeException exc) {
+                mLogger.log("Sync failed with RuntimeException: ", exc.toString());
                 closeActiveSyncContext(activeSyncContext);
                 Slog.e(TAG, "Caught RuntimeException while starting the sync " + syncOperation, exc);
             }
@@ -3186,7 +3227,8 @@
          * @param info Can have null fields to indicate all the active syncs for that field.
          * @param extras Can be null to indicate <strong>all</strong> syncs for the given endpoint.
          */
-        private void cancelActiveSyncH(SyncStorageEngine.EndPoint info, Bundle extras) {
+        private void cancelActiveSyncH(SyncStorageEngine.EndPoint info, Bundle extras,
+                String why) {
             ArrayList<ActiveSyncContext> activeSyncs =
                     new ArrayList<ActiveSyncContext>(mActiveSyncContexts);
             for (ActiveSyncContext activeSyncContext : activeSyncs) {
@@ -3202,7 +3244,8 @@
                                     false /* no config settings */)) {
                         continue;
                     }
-                    mSyncJobService.callJobFinished(activeSyncContext.mSyncOperation.jobId, false);
+                    mSyncJobService.callJobFinished(activeSyncContext.mSyncOperation.jobId, false,
+                            why);
                     runSyncFinishedOrCanceledH(null /* cancel => no result */, activeSyncContext);
                 }
             }
@@ -3250,6 +3293,7 @@
                 // potentially rescheduling all pending jobs to respect new backoff values.
                 getJobScheduler().cancel(syncOperation.jobId);
             }
+            mLogger.log("runSyncFinishedOrCanceledH() op=", syncOperation, " result=", syncResult);
 
             if (syncResult != null) {
                 if (isLoggable) {
@@ -3262,7 +3306,7 @@
                     // TODO: set these correctly when the SyncResult is extended to include it
                     downstreamActivity = 0;
                     upstreamActivity = 0;
-                    clearBackoffSetting(syncOperation.target);
+                    clearBackoffSetting(syncOperation.target, "sync success");
 
                     // If the operation completes successfully and it was scheduled due to
                     // a periodic operation failing, we reschedule the periodic operation to
diff --git a/services/core/java/com/android/server/content/SyncOperation.java b/services/core/java/com/android/server/content/SyncOperation.java
index b46426c..7d2cc00 100644
--- a/services/core/java/com/android/server/content/SyncOperation.java
+++ b/services/core/java/com/android/server/content/SyncOperation.java
@@ -237,6 +237,9 @@
      * contain a valid sync operation.
      */
     static SyncOperation maybeCreateFromJobExtras(PersistableBundle jobExtras) {
+        if (jobExtras == null) {
+            return null;
+        }
         String accountName, accountType;
         String provider;
         int userId, owningUid;
@@ -445,6 +448,10 @@
     }
 
     static void extrasToStringBuilder(Bundle bundle, StringBuilder sb) {
+        if (bundle == null) {
+            sb.append("null");
+            return;
+        }
         sb.append("[");
         for (String key : bundle.keySet()) {
             sb.append(key).append("=").append(bundle.get(key)).append(" ");
@@ -452,6 +459,12 @@
         sb.append("]");
     }
 
+    static String extrasToString(Bundle bundle) {
+        final StringBuilder sb = new StringBuilder();
+        extrasToStringBuilder(bundle, sb);
+        return sb.toString();
+    }
+
     String wakeLockName() {
         if (wakeLockName != null) {
             return wakeLockName;
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 8129f45..ab3aff9 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -1221,6 +1221,18 @@
         }
     }
 
+    @VisibleForTesting
+    DisplayDeviceInfo getDisplayDeviceInfoInternal(int displayId) {
+        synchronized (mSyncRoot) {
+            LogicalDisplay display = mLogicalDisplays.get(displayId);
+            if (display != null) {
+                DisplayDevice displayDevice = display.getPrimaryDisplayDeviceLocked();
+                return displayDevice.getDisplayDeviceInfoLocked();
+            }
+            return null;
+        }
+    }
+
     private final class DisplayManagerHandler extends Handler {
         public DisplayManagerHandler(Looper looper) {
             super(looper, null, true /*async*/);
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index 9d3021a..d6ab888 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -23,6 +23,7 @@
 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE;
 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH;
+import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT;
 
 import android.content.Context;
 import android.hardware.display.IVirtualDisplayCallback;
@@ -359,6 +360,10 @@
                 if ((mFlags & VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) {
                     mInfo.flags |= DisplayDeviceInfo.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
                 }
+                if ((mFlags & VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT) != 0) {
+                    mInfo.flags |= DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
+                }
+
                 mInfo.type = Display.TYPE_VIRTUAL;
                 mInfo.touch = ((mFlags & VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH) == 0) ?
                         DisplayDeviceInfo.TOUCH_NONE : DisplayDeviceInfo.TOUCH_VIRTUAL;
diff --git a/services/core/java/com/android/server/fingerprint/AuthenticationClient.java b/services/core/java/com/android/server/fingerprint/AuthenticationClient.java
index 5339bac..370e569 100644
--- a/services/core/java/com/android/server/fingerprint/AuthenticationClient.java
+++ b/services/core/java/com/android/server/fingerprint/AuthenticationClient.java
@@ -79,7 +79,7 @@
         }
         if (!authenticated) {
             if (receiver != null) {
-                FingerprintUtils.vibrateFingerprintError(getContext());
+                vibrateError();
             }
             // allow system-defined limit of number of attempts before giving up
             int lockoutMode =  handleFailedAttempt();
@@ -99,7 +99,7 @@
             result |= lockoutMode != LOCKOUT_NONE; // in a lockout mode
         } else {
             if (receiver != null) {
-                FingerprintUtils.vibrateFingerprintSuccess(getContext());
+                vibrateSuccess();
             }
             result |= true; // we have a valid fingerprint, done
             resetFailedAttempts();
diff --git a/services/core/java/com/android/server/fingerprint/ClientMonitor.java b/services/core/java/com/android/server/fingerprint/ClientMonitor.java
index 1a2e144..3eae157 100644
--- a/services/core/java/com/android/server/fingerprint/ClientMonitor.java
+++ b/services/core/java/com/android/server/fingerprint/ClientMonitor.java
@@ -23,6 +23,8 @@
 import android.hardware.fingerprint.IFingerprintServiceReceiver;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.VibrationEffect;
+import android.os.Vibrator;
 import android.util.Slog;
 
 import java.util.NoSuchElementException;
@@ -36,14 +38,18 @@
     protected static final String TAG = FingerprintService.TAG; // TODO: get specific name
     protected static final int ERROR_ESRCH = 3; // Likely fingerprint HAL is dead. See errno.h.
     protected static final boolean DEBUG = FingerprintService.DEBUG;
+    private static final long[] DEFAULT_SUCCESS_VIBRATION_PATTERN = new long[] {0, 30};
+    private final Context mContext;
+    private final long mHalDeviceId;
+    private final int mTargetUserId;
+    private final int mGroupId;
+    // True if client does not have MANAGE_FINGERPRINT permission
+    private final boolean mIsRestricted;
+    private final String mOwner;
+    private final VibrationEffect mSuccessVibrationEffect;
+    private final VibrationEffect mErrorVibrationEffect;
     private IBinder mToken;
     private IFingerprintServiceReceiver mReceiver;
-    private int mTargetUserId;
-    private int mGroupId;
-    private boolean mIsRestricted; // True if client does not have MANAGE_FINGERPRINT permission
-    private String mOwner;
-    private Context mContext;
-    private long mHalDeviceId;
     protected boolean mAlreadyCancelled;
 
     /**
@@ -68,6 +74,8 @@
         mGroupId = groupId;
         mIsRestricted = restricted;
         mOwner = owner;
+        mSuccessVibrationEffect = getSuccessVibrationEffect(context);
+        mErrorVibrationEffect = VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK);
         try {
             if (token != null) {
                 token.linkToDeath(this, 0);
@@ -79,7 +87,7 @@
 
     /**
      * Contacts fingerprint HAL to start the client.
-     * @return 0 on succes, errno from driver on failure
+     * @return 0 on success, errno from driver on failure
      */
     public abstract int start();
 
@@ -211,4 +219,39 @@
     public final IBinder getToken() {
         return mToken;
     }
+
+    public final void vibrateSuccess() {
+        Vibrator vibrator = mContext.getSystemService(Vibrator.class);
+        if (vibrator != null) {
+            vibrator.vibrate(mSuccessVibrationEffect);
+        }
+    }
+
+    public final void vibrateError() {
+        Vibrator vibrator = mContext.getSystemService(Vibrator.class);
+        if (vibrator != null) {
+            vibrator.vibrate(mErrorVibrationEffect);
+        }
+    }
+
+    private static VibrationEffect getSuccessVibrationEffect(Context ctx) {
+        int[] arr = ctx.getResources().getIntArray(
+                com.android.internal.R.array.config_longPressVibePattern);
+        final long[] vibePattern;
+        if (arr == null || arr.length == 0) {
+            vibePattern = DEFAULT_SUCCESS_VIBRATION_PATTERN;
+        } else {
+            vibePattern = new long[arr.length];
+            for (int i = 0; i < arr.length; i++) {
+                vibePattern[i] = arr[i];
+            }
+        }
+        if (vibePattern.length == 1) {
+            return VibrationEffect.createOneShot(
+                    vibePattern[0], VibrationEffect.DEFAULT_AMPLITUDE);
+        } else {
+            return VibrationEffect.createWaveform(vibePattern, -1);
+        }
+    }
+
 }
diff --git a/services/core/java/com/android/server/fingerprint/EnrollClient.java b/services/core/java/com/android/server/fingerprint/EnrollClient.java
index 6170894..c9efcf2 100644
--- a/services/core/java/com/android/server/fingerprint/EnrollClient.java
+++ b/services/core/java/com/android/server/fingerprint/EnrollClient.java
@@ -65,7 +65,7 @@
         if (receiver == null)
             return true; // client not listening
 
-        FingerprintUtils.vibrateFingerprintSuccess(getContext());
+        vibrateSuccess();
         MetricsLogger.action(getContext(), MetricsEvent.ACTION_FINGERPRINT_ENROLL);
         try {
             receiver.onEnrollResult(getHalDeviceId(), fpId, groupId, remaining);
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintUtils.java b/services/core/java/com/android/server/fingerprint/FingerprintUtils.java
index 49dc8e4..5fbd735 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintUtils.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintUtils.java
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.hardware.fingerprint.Fingerprint;
-import android.os.Vibrator;
 import android.text.TextUtils;
 import android.util.SparseArray;
 
@@ -31,9 +30,6 @@
  */
 public class FingerprintUtils {
 
-    private static final long[] FP_ERROR_VIBRATE_PATTERN = new long[] {0, 30, 100, 30};
-    private static final long[] FP_SUCCESS_VIBRATE_PATTERN = new long[] {0, 30};
-
     private static final Object sInstanceLock = new Object();
     private static FingerprintUtils sInstance;
 
@@ -72,20 +68,6 @@
         getStateForUser(ctx, userId).renameFingerprint(fingerId, name);
     }
 
-    public static void vibrateFingerprintError(Context context) {
-        Vibrator vibrator = context.getSystemService(Vibrator.class);
-        if (vibrator != null) {
-            vibrator.vibrate(FP_ERROR_VIBRATE_PATTERN, -1);
-        }
-    }
-
-    public static void vibrateFingerprintSuccess(Context context) {
-        Vibrator vibrator = context.getSystemService(Vibrator.class);
-        if (vibrator != null) {
-            vibrator.vibrate(FP_SUCCESS_VIBRATE_PATTERN, -1);
-        }
-    }
-
     private FingerprintsUserState getStateForUser(Context ctx, int userId) {
         synchronized (this) {
             FingerprintsUserState state = mUsers.get(userId);
diff --git a/services/core/java/com/android/server/hdmi/HdmiLogger.java b/services/core/java/com/android/server/hdmi/HdmiLogger.java
index 537df81..ebe52c0 100644
--- a/services/core/java/com/android/server/hdmi/HdmiLogger.java
+++ b/services/core/java/com/android/server/hdmi/HdmiLogger.java
@@ -44,7 +44,6 @@
     private static final long ERROR_LOG_DURATTION_MILLIS = 20 * 1000;  // 20s
 
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-    private static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
 
     private static final ThreadLocal<HdmiLogger> sLogger = new ThreadLocal<>();
 
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 4a45c07..4511aa9 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -466,6 +466,11 @@
             // Always on, notify HAL so it can get data it needs
             sendMessage(UPDATE_NETWORK_STATE, 0 /*arg*/, network);
         }
+
+        @Override
+        public void onLost(Network network) {
+            sendMessage(UPDATE_NETWORK_STATE, 0 /*arg*/, network);
+        }
     };
 
     /**
@@ -784,6 +789,18 @@
             }
         };
         mGnssMetrics = new GnssMetrics();
+
+        /*
+        * A cycle of native_init() and native_cleanup() is needed so that callbacks are registered
+        * after bootup even when location is disabled. This will allow Emergency SUPL to work even
+        * when location is disabled before device restart.
+        * */
+        boolean isInitialized = native_init();
+        if(!isInitialized) {
+            Log.d(TAG, "Failed to initialize at bootup");
+        } else {
+            native_cleanup();
+        }
     }
 
     /**
@@ -802,11 +819,21 @@
     private void handleUpdateNetworkState(Network network) {
         // retrieve NetworkInfo for this UID
         NetworkInfo info = mConnMgr.getNetworkInfo(network);
-        if (info == null) {
-            return;
+
+        boolean networkAvailable = false;
+        boolean isConnected = false;
+        int type = ConnectivityManager.TYPE_NONE;
+        boolean isRoaming = false;
+        String apnName = null;
+
+        if (info != null) {
+            networkAvailable = info.isAvailable() && TelephonyManager.getDefault().getDataEnabled();
+            isConnected = info.isConnected();
+            type = info.getType();
+            isRoaming = info.isRoaming();
+            apnName = info.getExtraInfo();
         }
 
-        boolean isConnected = info.isConnected();
         if (DEBUG) {
             String message = String.format(
                     "UpdateNetworkState, state=%s, connected=%s, info=%s, capabilities=%S",
@@ -818,8 +845,6 @@
         }
 
         if (native_is_agps_ril_supported()) {
-            boolean dataEnabled = TelephonyManager.getDefault().getDataEnabled();
-            boolean networkAvailable = info.isAvailable() && dataEnabled;
             String defaultApn = getSelectedApn();
             if (defaultApn == null) {
                 defaultApn = "dummy-apn";
@@ -827,10 +852,10 @@
 
             native_update_network_state(
                     isConnected,
-                    info.getType(),
-                    info.isRoaming(),
+                    type,
+                    isRoaming,
                     networkAvailable,
-                    info.getExtraInfo(),
+                    apnName,
                     defaultApn);
         } else if (DEBUG) {
             Log.d(TAG, "Skipped network state update because GPS HAL AGPS-RIL is not  supported");
@@ -838,7 +863,6 @@
 
         if (mAGpsDataConnectionState == AGPS_DATA_CONNECTION_OPENING) {
             if (isConnected) {
-                String apnName = info.getExtraInfo();
                 if (apnName == null) {
                     // assign a dummy value in the case of C2K as otherwise we will have a runtime
                     // exception in the following call to native_agps_data_conn_open
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index fe2c5bd..c1e820c 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -142,6 +142,7 @@
     private static final int SYNTHETIC_PASSWORD_ENABLED_BY_DEFAULT = 1;
 
     // Order of holding lock: mSeparateChallengeLock -> mSpManager -> this
+    // Do not call into ActivityManager while holding mSpManager lock.
     private final Object mSeparateChallengeLock = new Object();
 
     private final DeviceProvisionedObserver mDeviceProvisionedObserver =
@@ -1434,16 +1435,14 @@
             Slog.e(TAG, "FRP credential can only be verified prior to provisioning.");
             return VerifyCredentialResponse.ERROR;
         }
-        synchronized (mSpManager) {
-            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
-                VerifyCredentialResponse response = spBasedDoVerifyCredentialLocked(credential,
-                        credentialType, hasChallenge, challenge, userId, progressCallback);
-                if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
-                    mStrongAuth.reportSuccessfulStrongAuthUnlock(userId);
-                }
-                return response;
-            }
+        VerifyCredentialResponse response = null;
+        response = spBasedDoVerifyCredential(credential, credentialType, hasChallenge, challenge,
+                userId, progressCallback);
+        // The user employs synthetic password based credential.
+        if (response != null) {
+            return response;
         }
+
         final CredentialHash storedHash;
         if (userId == USER_FRP) {
             PersistentData data = mStorage.readPersistentDataBlock();
@@ -1472,7 +1471,7 @@
             credentialToVerify = credential;
         }
 
-        VerifyCredentialResponse response = verifyCredential(userId, storedHash, credentialToVerify,
+        response = verifyCredential(userId, storedHash, credentialToVerify,
                 hasChallenge, challenge, progressCallback);
 
         if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
@@ -1995,33 +1994,46 @@
         setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 1, UserHandle.USER_SYSTEM);
     }
 
-    private VerifyCredentialResponse spBasedDoVerifyCredentialLocked(String userCredential, int
+    private VerifyCredentialResponse spBasedDoVerifyCredential(String userCredential, int
             credentialType, boolean hasChallenge, long challenge, int userId,
             ICheckCredentialProgressCallback progressCallback) throws RemoteException {
-        if (DEBUG) Slog.d(TAG, "spBasedDoVerifyCredentialLocked: user=" + userId);
+        if (DEBUG) Slog.d(TAG, "spBasedDoVerifyCredential: user=" + userId);
         if (credentialType == LockPatternUtils.CREDENTIAL_TYPE_NONE) {
             userCredential = null;
         }
-        if (userId == USER_FRP) {
-            return mSpManager.verifyFrpCredential(getGateKeeperService(),
-                    userCredential, credentialType, progressCallback);
+
+        final AuthenticationResult authResult;
+        VerifyCredentialResponse response;
+        synchronized (mSpManager) {
+            if (!isSyntheticPasswordBasedCredentialLocked(userId)) {
+                return null;
+            }
+            if (userId == USER_FRP) {
+                return mSpManager.verifyFrpCredential(getGateKeeperService(),
+                        userCredential, credentialType, progressCallback);
+            }
+
+            long handle = getSyntheticPasswordHandleLocked(userId);
+            authResult = mSpManager.unwrapPasswordBasedSyntheticPassword(
+                    getGateKeeperService(), handle, userCredential, userId);
+
+            response = authResult.gkResponse;
+            // credential has matched
+            if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
+                // perform verifyChallenge with synthetic password which generates the real GK auth
+                // token and response for the current user
+                response = mSpManager.verifyChallenge(getGateKeeperService(), authResult.authToken,
+                        challenge, userId);
+                if (response.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
+                    // This shouldn't really happen: the unwrapping of SP succeeds, but SP doesn't
+                    // match the recorded GK password handle.
+                    Slog.wtf(TAG, "verifyChallenge with SP failed.");
+                    return VerifyCredentialResponse.ERROR;
+                }
+            }
         }
 
-        long handle = getSyntheticPasswordHandleLocked(userId);
-        AuthenticationResult authResult = mSpManager.unwrapPasswordBasedSyntheticPassword(
-                getGateKeeperService(), handle, userCredential, userId);
-
-        VerifyCredentialResponse response = authResult.gkResponse;
         if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
-            // credential has matched
-            // perform verifyChallenge with synthetic password which generates the real auth
-            // token for the current user
-            response = mSpManager.verifyChallenge(getGateKeeperService(), authResult.authToken,
-                    challenge, userId);
-            if (response.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
-                Slog.wtf(TAG, "verifyChallenge with SP failed.");
-                return VerifyCredentialResponse.ERROR;
-            }
             if (progressCallback != null) {
                 progressCallback.onCredentialVerified();
             }
@@ -2032,12 +2044,14 @@
             Slog.i(TAG, "Unlocking user " + userId + " with secret only, length " + secret.length);
             unlockUser(userId, null, secret);
 
+            activateEscrowTokens(authResult.authToken, userId);
+
             if (isManagedProfileWithSeparatedLock(userId)) {
                 TrustManager trustManager =
                         (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
                 trustManager.setDeviceLockedForUser(userId, false);
             }
-            activateEscrowTokens(authResult.authToken, userId);
+            mStrongAuth.reportSuccessfulStrongAuthUnlock(userId);
         } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
             if (response.getTimeout() > 0) {
                 requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, userId);
@@ -2184,8 +2198,8 @@
 
     private void activateEscrowTokens(AuthenticationToken auth, int userId) throws RemoteException {
         if (DEBUG) Slog.d(TAG, "activateEscrowTokens: user=" + userId);
-        disableEscrowTokenOnNonManagedDevicesIfNeeded(userId);
         synchronized (mSpManager) {
+            disableEscrowTokenOnNonManagedDevicesIfNeeded(userId);
             for (long handle : mSpManager.getPendingTokensForUser(userId)) {
                 Slog.i(TAG, String.format("activateEscrowTokens: %x %d ", handle, userId));
                 mSpManager.activateTokenBasedSyntheticPassword(handle, auth, userId);
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
index d730c56..67ead6f 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
@@ -36,6 +36,7 @@
     private static final String COMMAND_CLEAR = "clear";
     private static final String COMMAND_SP = "sp";
     private static final String COMMAND_SET_DISABLED = "set-disabled";
+    private static final String COMMAND_VERIFY = "verify";
 
     private int mCurrentUserId;
     private final LockPatternUtils mLockPatternUtils;
@@ -76,6 +77,9 @@
                 case COMMAND_SET_DISABLED:
                     runSetDisabled();
                     break;
+                case COMMAND_VERIFY:
+                    runVerify();
+                    break;
                 default:
                     getErrPrintWriter().println("Unknown command: " + cmd);
                     break;
@@ -88,6 +92,11 @@
         }
     }
 
+    private void runVerify() {
+        // The command is only run if the credential is correct.
+        getOutPrintWriter().println("Lock credential verified successfully");
+    }
+
     @Override
     public void onHelp() {
     }
diff --git a/services/core/java/com/android/server/media/AudioPlaybackMonitor.java b/services/core/java/com/android/server/media/AudioPlaybackMonitor.java
index c6dc11c..f6f7676 100644
--- a/services/core/java/com/android/server/media/AudioPlaybackMonitor.java
+++ b/services/core/java/com/android/server/media/AudioPlaybackMonitor.java
@@ -31,17 +31,22 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 /**
- * Monitors changes in audio playback and notify the newly started audio playback through the
- * {@link OnAudioPlaybackStartedListener}.
+ * Monitors changes in audio playback, and notify the newly started audio playback through the
+ * {@link OnAudioPlaybackStartedListener} and the activeness change through the
+ * {@link OnAudioPlaybackActiveStateListener}.
  */
 class AudioPlaybackMonitor extends IPlaybackConfigDispatcher.Stub {
     private static boolean DEBUG = MediaSessionService.DEBUG;
     private static String TAG = "AudioPlaybackMonitor";
 
+    private static AudioPlaybackMonitor sInstance;
+
     /**
      * Called when audio playback is started for a given UID.
      */
@@ -49,22 +54,36 @@
         void onAudioPlaybackStarted(int uid);
     }
 
+    /**
+     * Called when audio player state is changed.
+     */
+    interface OnAudioPlayerActiveStateChangedListener {
+        void onAudioPlayerActiveStateChanged(int uid, boolean active);
+    }
+
     private final Object mLock = new Object();
     private final Context mContext;
-    private final OnAudioPlaybackStartedListener mListener;
-
-    private Set<Integer> mActiveAudioPlaybackPlayerInterfaceIds = new HashSet<>();
-    private Set<Integer> mActiveAudioPlaybackClientUids = new HashSet<>();
+    private final List<OnAudioPlaybackStartedListener> mAudioPlaybackStartedListeners
+            = new ArrayList<>();
+    private final List<OnAudioPlayerActiveStateChangedListener>
+            mAudioPlayerActiveStateChangedListeners = new ArrayList<>();
+    private final Map<Integer, Integer> mAudioPlaybackStates = new HashMap<>();
+    private final Set<Integer> mActiveAudioPlaybackClientUids = new HashSet<>();
 
     // Sorted array of UIDs that had active audio playback. (i.e. playing an audio/video)
     // The UID whose audio playback becomes active at the last comes first.
     // TODO(b/35278867): Find and use unique identifier for apps because apps may share the UID.
     private final IntArray mSortedAudioPlaybackClientUids = new IntArray();
 
-    AudioPlaybackMonitor(Context context, IAudioService audioService,
-            OnAudioPlaybackStartedListener listener) {
+    static AudioPlaybackMonitor getInstance(Context context, IAudioService audioService) {
+        if (sInstance == null) {
+            sInstance = new AudioPlaybackMonitor(context, audioService);
+        }
+        return sInstance;
+    }
+
+    private AudioPlaybackMonitor(Context context, IAudioService audioService) {
         mContext = context;
-        mListener = listener;
         try {
             audioService.registerPlaybackCallback(this);
         } catch (RemoteException e) {
@@ -84,9 +103,12 @@
     public void dispatchPlaybackConfigChange(List<AudioPlaybackConfiguration> configs) {
         final long token = Binder.clearCallingIdentity();
         try {
-            Set<Integer> newActiveAudioPlaybackPlayerInterfaceIds = new HashSet<>();
             List<Integer> newActiveAudioPlaybackClientUids = new ArrayList<>();
+            List<OnAudioPlayerActiveStateChangedListener> audioPlayerActiveStateChangedListeners;
+            List<OnAudioPlaybackStartedListener> audioPlaybackStartedListeners;
             synchronized (mLock) {
+                // Update mActiveAudioPlaybackClientUids and mSortedAudioPlaybackClientUids,
+                // and find newly activated audio playbacks.
                 mActiveAudioPlaybackClientUids.clear();
                 for (AudioPlaybackConfiguration config : configs) {
                     // Ignore inactive (i.e. not playing) or PLAYER_TYPE_JAM_SOUNDPOOL
@@ -94,16 +116,14 @@
                     // playback.
                     // Note that we shouldn't ignore PLAYER_TYPE_UNKNOWN because it might be OEM
                     // specific audio/video players.
-                    if (!config.isActive()
-                            || config.getPlayerType()
+                    if (!config.isActive() || config.getPlayerType()
                             == AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL) {
                         continue;
                     }
-                    mActiveAudioPlaybackClientUids.add(config.getClientUid());
 
-                    newActiveAudioPlaybackPlayerInterfaceIds.add(config.getPlayerInterfaceId());
-                    if (!mActiveAudioPlaybackPlayerInterfaceIds.contains(
-                            config.getPlayerInterfaceId())) {
+                    mActiveAudioPlaybackClientUids.add(config.getClientUid());
+                    Integer oldState = mAudioPlaybackStates.get(config.getPlayerInterfaceId());
+                    if (!isActiveState(oldState)) {
                         if (DEBUG) {
                             Log.d(TAG, "Found a new active media playback. " +
                                     AudioPlaybackConfiguration.toLogFriendlyString(config));
@@ -120,11 +140,32 @@
                         mSortedAudioPlaybackClientUids.add(0, config.getClientUid());
                     }
                 }
-                mActiveAudioPlaybackPlayerInterfaceIds.clear();
-                mActiveAudioPlaybackPlayerInterfaceIds = newActiveAudioPlaybackPlayerInterfaceIds;
+                audioPlayerActiveStateChangedListeners = new ArrayList<>(
+                        mAudioPlayerActiveStateChangedListeners);
+                audioPlaybackStartedListeners = new ArrayList<>(mAudioPlaybackStartedListeners);
             }
+            // Notify the change of audio playback states.
+            for (AudioPlaybackConfiguration config : configs) {
+                boolean wasActive = isActiveState(
+                        mAudioPlaybackStates.get(config.getPlayerInterfaceId()));
+                boolean isActive = config.isActive();
+                if (wasActive != isActive) {
+                    for (OnAudioPlayerActiveStateChangedListener listener
+                            : audioPlayerActiveStateChangedListeners) {
+                        listener.onAudioPlayerActiveStateChanged(config.getClientUid(),
+                                isActive);
+                    }
+                }
+            }
+            // Notify the start of audio playback
             for (int uid : newActiveAudioPlaybackClientUids) {
-                mListener.onAudioPlaybackStarted(uid);
+                for (OnAudioPlaybackStartedListener listener : audioPlaybackStartedListeners) {
+                    listener.onAudioPlaybackStarted(uid);
+                }
+            }
+            mAudioPlaybackStates.clear();
+            for (AudioPlaybackConfiguration config : configs) {
+                mAudioPlaybackStates.put(config.getPlayerInterfaceId(), config.getPlayerState());
             }
         } finally {
             Binder.restoreCallingIdentity(token);
@@ -132,6 +173,44 @@
     }
 
     /**
+     * Registers OnAudioPlaybackStartedListener.
+     */
+    public void registerOnAudioPlaybackStartedListener(OnAudioPlaybackStartedListener listener) {
+        synchronized (mLock) {
+            mAudioPlaybackStartedListeners.add(listener);
+        }
+    }
+
+    /**
+     * Unregisters OnAudioPlaybackStartedListener.
+     */
+    public void unregisterOnAudioPlaybackStartedListener(OnAudioPlaybackStartedListener listener) {
+        synchronized (mLock) {
+            mAudioPlaybackStartedListeners.remove(listener);
+        }
+    }
+
+    /**
+     * Registers OnAudioPlayerActiveStateChangedListener.
+     */
+    public void registerOnAudioPlayerActiveStateChangedListener(
+            OnAudioPlayerActiveStateChangedListener listener) {
+        synchronized (mLock) {
+            mAudioPlayerActiveStateChangedListeners.add(listener);
+        }
+    }
+
+    /**
+     * Unregisters OnAudioPlayerActiveStateChangedListener.
+     */
+    public void unregisterOnAudioPlayerActiveStateChangedListener(
+            OnAudioPlayerActiveStateChangedListener listener) {
+        synchronized (mLock) {
+            mAudioPlayerActiveStateChangedListeners.remove(listener);
+        }
+    }
+
+    /**
      * Returns the sorted list of UIDs that have had active audio playback. (i.e. playing an
      * audio/video) The UID whose audio playback becomes active at the last comes first.
      */
@@ -167,7 +246,8 @@
                 if (mSortedAudioPlaybackClientUids.get(i) == mediaButtonSessionUid) {
                     break;
                 }
-                if (userId == UserHandle.getUserId(mSortedAudioPlaybackClientUids.get(i))) {
+                int uid = mSortedAudioPlaybackClientUids.get(i);
+                if (userId == UserHandle.getUserId(uid) && !isPlaybackActive(uid)) {
                     // Clean up unnecessary UIDs.
                     // It doesn't need to be managed profile aware because it's just to prevent
                     // the list from increasing indefinitely. The media button session updating
@@ -198,4 +278,8 @@
             }
         }
     }
+
+    private boolean isActiveState(Integer state) {
+        return state != null && state.equals(AudioPlaybackConfiguration.PLAYER_STATE_STARTED);
+    }
 }
diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java
index d1fa5ef..5ba8f48 100644
--- a/services/core/java/com/android/server/media/MediaRouterService.java
+++ b/services/core/java/com/android/server/media/MediaRouterService.java
@@ -18,6 +18,7 @@
 
 import com.android.internal.util.DumpUtils;
 import com.android.server.Watchdog;
+import com.android.server.media.AudioPlaybackMonitor.OnAudioPlayerActiveStateChangedListener;
 
 import android.Manifest;
 import android.app.ActivityManager;
@@ -26,7 +27,10 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
+import android.media.AudioRoutesInfo;
 import android.media.AudioSystem;
+import android.media.IAudioRoutesObserver;
+import android.media.IAudioService;
 import android.media.IMediaRouterClient;
 import android.media.IMediaRouterService;
 import android.media.MediaRouter;
@@ -39,9 +43,12 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.SystemClock;
+import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.ArrayMap;
+import android.util.IntArray;
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -89,10 +96,54 @@
     private final ArrayMap<IBinder, ClientRecord> mAllClientRecords =
             new ArrayMap<IBinder, ClientRecord>();
     private int mCurrentUserId = -1;
+    private boolean mHasBluetoothRoute = false;
+    private final IAudioService mAudioService;
+    private final AudioPlaybackMonitor mAudioPlaybackMonitor;
 
     public MediaRouterService(Context context) {
         mContext = context;
         Watchdog.getInstance().addMonitor(this);
+
+        mAudioService = IAudioService.Stub.asInterface(
+                ServiceManager.getService(Context.AUDIO_SERVICE));
+
+        mAudioPlaybackMonitor = AudioPlaybackMonitor.getInstance(context, mAudioService);
+        mAudioPlaybackMonitor.registerOnAudioPlayerActiveStateChangedListener(
+                new AudioPlaybackMonitor.OnAudioPlayerActiveStateChangedListener() {
+            @Override
+            public void onAudioPlayerActiveStateChanged(int uid, boolean active) {
+                if (active) {
+                    restoreRoute(uid);
+                } else {
+                    IntArray sortedAudioPlaybackClientUids =
+                            mAudioPlaybackMonitor.getSortedAudioPlaybackClientUids();
+                    boolean restored = false;
+                    for (int i = 0; i < sortedAudioPlaybackClientUids.size(); i++) {
+                        if (mAudioPlaybackMonitor.isPlaybackActive(
+                                sortedAudioPlaybackClientUids.get(i))) {
+                            restoreRoute(sortedAudioPlaybackClientUids.get(i));
+                            restored = true;
+                            break;
+                        }
+                    }
+                    if (!restored) {
+                        restoreBluetoothA2dp();
+                    }
+                }
+            }
+        });
+        AudioRoutesInfo audioRoutes = null;
+        try {
+            audioRoutes = mAudioService.startWatchingRoutes(new IAudioRoutesObserver.Stub() {
+                @Override
+                public void dispatchAudioRoutesChanged(final AudioRoutesInfo newRoutes) {
+                    mHasBluetoothRoute = newRoutes.bluetoothName != null;
+                }
+            });
+        } catch (RemoteException e) {
+            Slog.w(TAG, "RemoteException in the audio service.");
+        }
+        mHasBluetoothRoute = (audioRoutes != null && audioRoutes.bluetoothName != null);
     }
 
     public void systemRunning() {
@@ -135,7 +186,7 @@
         final long token = Binder.clearCallingIdentity();
         try {
             synchronized (mLock) {
-                registerClientLocked(client, pid, packageName, resolvedUserId, trusted);
+                registerClientLocked(client, uid, pid, packageName, resolvedUserId, trusted);
             }
         } finally {
             Binder.restoreCallingIdentity(token);
@@ -178,6 +229,23 @@
 
     // Binder call
     @Override
+    public boolean isPlaybackActive(IMediaRouterClient client) {
+        if (client == null) {
+            throw new IllegalArgumentException("client must not be null");
+        }
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                return isPlaybackActiveLocked(client);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    // Binder call
+    @Override
     public void setDiscoveryRequest(IMediaRouterClient client,
             int routeTypes, boolean activeScan) {
         if (client == null) {
@@ -276,6 +344,36 @@
         }
     }
 
+    void restoreBluetoothA2dp() {
+        try {
+            mAudioService.setBluetoothA2dpOn(mHasBluetoothRoute);
+        } catch (RemoteException e) {
+            Slog.w(TAG, "RemoteException while calling setBluetoothA2dpOn.");
+        }
+    }
+
+    void restoreRoute(int uid) {
+        ClientRecord clientRecord = null;
+        UserRecord userRecord = mUserRecords.get(UserHandle.getUserId(uid));
+        if (userRecord.mClientRecords != null) {
+            for (ClientRecord cr : userRecord.mClientRecords) {
+                if (validatePackageName(uid, cr.mPackageName)) {
+                    clientRecord = cr;
+                    break;
+                }
+            }
+        }
+        if (clientRecord != null) {
+            try {
+                clientRecord.mClient.onRestoreRoute();
+            } catch (RemoteException e) {
+                Slog.w(TAG, "Failed to call onRestoreRoute. Client probably died.");
+            }
+        } else {
+            restoreBluetoothA2dp();
+        }
+    }
+
     void switchUser() {
         synchronized (mLock) {
             int userId = ActivityManager.getCurrentUser();
@@ -304,7 +402,7 @@
     }
 
     private void registerClientLocked(IMediaRouterClient client,
-            int pid, String packageName, int userId, boolean trusted) {
+            int uid, int pid, String packageName, int userId, boolean trusted) {
         final IBinder binder = client.asBinder();
         ClientRecord clientRecord = mAllClientRecords.get(binder);
         if (clientRecord == null) {
@@ -314,7 +412,7 @@
                 userRecord = new UserRecord(userId);
                 newUser = true;
             }
-            clientRecord = new ClientRecord(userRecord, client, pid, packageName, trusted);
+            clientRecord = new ClientRecord(userRecord, client, uid, pid, packageName, trusted);
             try {
                 binder.linkToDeath(clientRecord, 0);
             } catch (RemoteException ex) {
@@ -350,6 +448,14 @@
         return null;
     }
 
+    private boolean isPlaybackActiveLocked(IMediaRouterClient client) {
+        ClientRecord clientRecord = mAllClientRecords.get(client.asBinder());
+        if (clientRecord != null) {
+            return mAudioPlaybackMonitor.isPlaybackActive(clientRecord.mUid);
+        }
+        return false;
+    }
+
     private void setDiscoveryRequestLocked(IMediaRouterClient client,
             int routeTypes, boolean activeScan) {
         final IBinder binder = client.asBinder();
@@ -489,6 +595,7 @@
     final class ClientRecord implements DeathRecipient {
         public final UserRecord mUserRecord;
         public final IMediaRouterClient mClient;
+        public final int mUid;
         public final int mPid;
         public final String mPackageName;
         public final boolean mTrusted;
@@ -498,9 +605,10 @@
         public String mSelectedRouteId;
 
         public ClientRecord(UserRecord userRecord, IMediaRouterClient client,
-                int pid, String packageName, boolean trusted) {
+                int uid, int pid, String packageName, boolean trusted) {
             mUserRecord = userRecord;
             mClient = client;
+            mUid = uid;
             mPid = pid;
             mPackageName = packageName;
             mTrusted = trusted;
@@ -997,7 +1105,7 @@
                     try {
                         mTempClients.get(i).onStateChanged();
                     } catch (RemoteException ex) {
-                        // ignore errors, client probably died
+                        Slog.w(TAG, "Failed to call onStateChanged. Client probably died.");
                     }
                 }
             } finally {
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 67920ed..a0487f9 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -136,19 +136,20 @@
         mKeyguardManager =
                 (KeyguardManager) getContext().getSystemService(Context.KEYGUARD_SERVICE);
         mAudioService = getAudioService();
-        mAudioPlaybackMonitor = new AudioPlaybackMonitor(getContext(), mAudioService,
+        mAudioPlaybackMonitor = AudioPlaybackMonitor.getInstance(getContext(), mAudioService);
+        mAudioPlaybackMonitor.registerOnAudioPlaybackStartedListener(
                 new AudioPlaybackMonitor.OnAudioPlaybackStartedListener() {
-                    @Override
-                    public void onAudioPlaybackStarted(int uid) {
-                        synchronized (mLock) {
-                            FullUserRecord user =
-                                    getFullUserRecordLocked(UserHandle.getUserId(uid));
-                            if (user != null) {
-                                user.mPriorityStack.updateMediaButtonSessionIfNeeded();
-                            }
-                        }
+            @Override
+            public void onAudioPlaybackStarted(int uid) {
+                synchronized (mLock) {
+                    FullUserRecord user =
+                            getFullUserRecordLocked(UserHandle.getUserId(uid));
+                    if (user != null) {
+                        user.mPriorityStack.updateMediaButtonSessionIfNeeded();
                     }
-                });
+                }
+            }
+        });
         mAudioManagerInternal = LocalServices.getService(AudioManagerInternal.class);
         mContentResolver = getContext().getContentResolver();
         mSettingsObserver = new SettingsObserver();
diff --git a/services/core/java/com/android/server/notification/AlertRateLimiter.java b/services/core/java/com/android/server/notification/AlertRateLimiter.java
new file mode 100644
index 0000000..e4a7934
--- /dev/null
+++ b/services/core/java/com/android/server/notification/AlertRateLimiter.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2017 The Android Open Source 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.notification;
+
+
+/**
+ * {@hide}
+ */
+public class AlertRateLimiter {
+    static final long ALLOWED_ALERT_INTERVAL = 1000;
+    private long mLastNotificationMillis = 0;
+
+    boolean isRateLimited(long now) {
+        final long millisSinceLast = now - mLastNotificationMillis;
+        if (millisSinceLast < 0 || millisSinceLast < ALLOWED_ALERT_INTERVAL) {
+            return true;
+        }
+        mLastNotificationMillis = now;
+        return false;
+    }
+}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index e7bfa2d..48b4c57 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -265,6 +265,7 @@
     private static final String EXTRA_KEY = "key";
 
     private IActivityManager mAm;
+    private ActivityManager mActivityManager;
     private IPackageManager mPackageManager;
     private PackageManager mPackageManagerClient;
     AudioManager mAudioManager;
@@ -450,9 +451,12 @@
         while (parser.next() != END_DOCUMENT) {
             mZenModeHelper.readXml(parser, forRestore);
             mRankingHelper.readXml(parser, forRestore);
-            saveXml |= mListeners.readXml(parser);
-            saveXml |= mNotificationAssistants.readXml(parser);
-            saveXml |= mConditionProviders.readXml(parser);
+            // No non-system managed services are allowed on low ram devices
+            if (!ActivityManager.isLowRamDeviceStatic()) {
+                saveXml |= mListeners.readXml(parser);
+                saveXml |= mNotificationAssistants.readXml(parser);
+                saveXml |= mConditionProviders.readXml(parser);
+            }
         }
 
         if (saveXml) {
@@ -1120,13 +1124,19 @@
         mIsTelevision = isTelevision;
     }
 
+    @VisibleForTesting
+    void setUsageStats(NotificationUsageStats us) {
+        mUsageStats = us;
+    }
+
     // TODO: Tests should call onStart instead once the methods above are removed.
     @VisibleForTesting
     void init(Looper looper, IPackageManager packageManager, PackageManager packageManagerClient,
             LightsManager lightsManager, NotificationListeners notificationListeners,
             NotificationAssistants notificationAssistants, ConditionProviders conditionProviders,
             ICompanionDeviceManager companionManager, SnoozeHelper snoozeHelper,
-            NotificationUsageStats usageStats, AtomicFile policyFile) {
+            NotificationUsageStats usageStats, AtomicFile policyFile,
+            ActivityManager activityManager, GroupHelper groupHelper) {
         Resources resources = getContext().getResources();
         mMaxPackageEnqueueRate = Settings.Global.getFloat(getContext().getContentResolver(),
                 Settings.Global.MAX_NOTIFICATION_ENQUEUE_RATE,
@@ -1140,6 +1150,7 @@
         mAppUsageStats = LocalServices.getService(UsageStatsManagerInternal.class);
         mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
         mCompanionManager = companionManager;
+        mActivityManager = activityManager;
 
         mHandler = new WorkerHandler(looper);
         mRankingThread.start();
@@ -1182,35 +1193,7 @@
             }
         });
         mSnoozeHelper = snoozeHelper;
-        mGroupHelper = new GroupHelper(new GroupHelper.Callback() {
-            @Override
-            public void addAutoGroup(String key) {
-                synchronized (mNotificationLock) {
-                    addAutogroupKeyLocked(key);
-                }
-                mRankingHandler.requestSort(false);
-            }
-
-            @Override
-            public void removeAutoGroup(String key) {
-                synchronized (mNotificationLock) {
-                    removeAutogroupKeyLocked(key);
-                }
-                mRankingHandler.requestSort(false);
-            }
-
-            @Override
-            public void addAutoGroupSummary(int userId, String pkg, String triggeringKey) {
-                createAutoGroupSummary(userId, pkg, triggeringKey);
-            }
-
-            @Override
-            public void removeAutoGroupSummary(int userId, String pkg) {
-                synchronized (mNotificationLock) {
-                    clearAutogroupSummaryLocked(userId, pkg);
-                }
-            }
-        });
+        mGroupHelper = groupHelper;
 
         // This is a ManagedServices object that keeps track of the listeners.
         mListeners = notificationListeners;
@@ -1325,11 +1308,45 @@
                 new NotificationAssistants(AppGlobals.getPackageManager()),
                 new ConditionProviders(getContext(), mUserProfiles, AppGlobals.getPackageManager()),
                 null, snoozeHelper, new NotificationUsageStats(getContext()),
-                new AtomicFile(new File(systemDir, "notification_policy.xml")));
+                new AtomicFile(new File(systemDir, "notification_policy.xml")),
+                (ActivityManager) getContext().getSystemService(Context.ACTIVITY_SERVICE),
+                getGroupHelper());
         publishBinderService(Context.NOTIFICATION_SERVICE, mService);
         publishLocalService(NotificationManagerInternal.class, mInternalService);
     }
 
+    private GroupHelper getGroupHelper() {
+        return new GroupHelper(new GroupHelper.Callback() {
+            @Override
+            public void addAutoGroup(String key) {
+                synchronized (mNotificationLock) {
+                    addAutogroupKeyLocked(key);
+                }
+                mRankingHandler.requestSort(false);
+            }
+
+            @Override
+            public void removeAutoGroup(String key) {
+                synchronized (mNotificationLock) {
+                    removeAutogroupKeyLocked(key);
+                }
+                mRankingHandler.requestSort(false);
+            }
+
+            @Override
+            public void addAutoGroupSummary(int userId, String pkg, String triggeringKey) {
+                createAutoGroupSummary(userId, pkg, triggeringKey);
+            }
+
+            @Override
+            public void removeAutoGroupSummary(int userId, String pkg) {
+                synchronized (mNotificationLock) {
+                    clearAutogroupSummaryLocked(userId, pkg);
+                }
+            }
+        });
+    }
+
     private void sendRegisteredOnlyBroadcast(String action) {
         getContext().sendBroadcastAsUser(new Intent(action)
                 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY), UserHandle.ALL, null);
@@ -2684,16 +2701,18 @@
         public void setNotificationPolicyAccessGranted(String pkg, boolean granted)
                 throws RemoteException {
             checkCallerIsSystemOrShell();
-            mConditionProviders.setPackageOrComponentEnabled(
-                    pkg, getCallingUserHandle().getIdentifier(), true, granted);
+            if (!mActivityManager.isLowRamDevice()) {
+                mConditionProviders.setPackageOrComponentEnabled(
+                        pkg, getCallingUserHandle().getIdentifier(), true, granted);
 
-            getContext().sendBroadcastAsUser(new Intent(NotificationManager
-                    .ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED)
-                    .setPackage(pkg)
-                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY),
-                    getCallingUserHandle(), null);
+                getContext().sendBroadcastAsUser(new Intent(
+                        NotificationManager.ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED)
+                                .setPackage(pkg)
+                                .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY),
+                        getCallingUserHandle(), null);
 
-            savePolicyFile();
+                savePolicyFile();
+            }
         }
 
         @Override
@@ -2774,17 +2793,20 @@
                 boolean granted) throws RemoteException {
             Preconditions.checkNotNull(listener);
             enforceSystemOrSystemUI("grant notification listener access");
-            mConditionProviders.setPackageOrComponentEnabled(listener.flattenToString(),
-                    userId, false, granted);
-            mListeners.setPackageOrComponentEnabled(listener.flattenToString(),
-                    userId, true, granted);
+            if (!mActivityManager.isLowRamDevice()) {
+                mConditionProviders.setPackageOrComponentEnabled(listener.flattenToString(),
+                        userId, false, granted);
+                mListeners.setPackageOrComponentEnabled(listener.flattenToString(),
+                        userId, true, granted);
 
-            getContext().sendBroadcastAsUser(new Intent(NotificationManager
-                    .ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED)
-                    .setPackage(listener.getPackageName())
-                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY), getCallingUserHandle(), null);
+                getContext().sendBroadcastAsUser(new Intent(
+                        NotificationManager.ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED)
+                                .setPackage(listener.getPackageName())
+                                .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY),
+                        getCallingUserHandle(), null);
 
-            savePolicyFile();
+                savePolicyFile();
+            }
         }
 
         @Override
@@ -2792,17 +2814,20 @@
                 int userId, boolean granted) throws RemoteException {
             Preconditions.checkNotNull(assistant);
             enforceSystemOrSystemUI("grant notification assistant access");
-            mConditionProviders.setPackageOrComponentEnabled(assistant.flattenToString(),
-                    userId, false, granted);
-            mNotificationAssistants.setPackageOrComponentEnabled(assistant.flattenToString(),
-                    userId, true, granted);
+            if (!mActivityManager.isLowRamDevice()) {
+                mConditionProviders.setPackageOrComponentEnabled(assistant.flattenToString(),
+                        userId, false, granted);
+                mNotificationAssistants.setPackageOrComponentEnabled(assistant.flattenToString(),
+                        userId, true, granted);
 
-            getContext().sendBroadcastAsUser(new Intent(NotificationManager
-                    .ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED)
-                    .setPackage(assistant.getPackageName())
-                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY), getCallingUserHandle(), null);
+                getContext().sendBroadcastAsUser(new Intent(
+                        NotificationManager.ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED)
+                                .setPackage(assistant.getPackageName())
+                                .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY),
+                        getCallingUserHandle(), null);
 
-            savePolicyFile();
+                savePolicyFile();
+            }
         }
 
         @Override
@@ -3303,7 +3328,6 @@
                     (r.mOriginalFlags & ~Notification.FLAG_FOREGROUND_SERVICE);
             mRankingHelper.sort(mNotificationList);
             mListeners.notifyPostedLocked(sbn, sbn /* oldSbn */);
-            mGroupHelper.onNotificationPosted(sbn);
         }
     };
 
@@ -3720,12 +3744,14 @@
                     if (notification.getSmallIcon() != null) {
                         StatusBarNotification oldSbn = (old != null) ? old.sbn : null;
                         mListeners.notifyPostedLocked(n, oldSbn);
-                        mHandler.post(new Runnable() {
-                            @Override
-                            public void run() {
-                                mGroupHelper.onNotificationPosted(n);
-                            }
-                        });
+                        if (oldSbn == null || !Objects.equals(oldSbn.getGroup(), n.getGroup())) {
+                            mHandler.post(new Runnable() {
+                                @Override
+                                public void run() {
+                                    mGroupHelper.onNotificationPosted(n);
+                                }
+                            });
+                        }
                     } else {
                         Slog.e(TAG, "Not posting notification without small icon: " + notification);
                         if (old != null && !old.isCanceled) {
@@ -3838,18 +3864,6 @@
         // Should this notification make noise, vibe, or use the LED?
         final boolean aboveThreshold =
                 record.getImportance() >= NotificationManager.IMPORTANCE_DEFAULT;
-        final boolean canInterrupt = aboveThreshold && !record.isIntercepted();
-        if (DBG)
-            Slog.v(TAG,
-                    "pkg=" + record.sbn.getPackageName() + " canInterrupt=" + canInterrupt +
-                            " intercept=" + record.isIntercepted()
-            );
-
-        // If we're not supposed to beep, vibrate, etc. then don't.
-        final String disableEffects = disableNotificationEffects(record);
-        if (disableEffects != null) {
-            ZenLog.traceDisableEffects(record, disableEffects);
-        }
 
         // Remember if this notification already owns the notification channels.
         boolean wasBeep = key != null && key.equals(mSoundNotificationKey);
@@ -3858,20 +3872,16 @@
         boolean hasValidVibrate = false;
         boolean hasValidSound = false;
 
-        if (isNotificationForCurrentUser(record)) {
+        if (aboveThreshold && isNotificationForCurrentUser(record)) {
             // If the notification will appear in the status bar, it should send an accessibility
             // event
             if (!record.isUpdate && record.getImportance() > IMPORTANCE_MIN) {
                 sendAccessibilityEvent(notification, record.sbn.getPackageName());
             }
-
-            if (disableEffects == null
-                    && canInterrupt
-                    && mSystemReady
-                    && mAudioManager != null) {
-                if (DBG) Slog.v(TAG, "Interrupting!");
+            if (mSystemReady && mAudioManager != null) {
                 Uri soundUri = record.getSound();
                 hasValidSound = soundUri != null && !Uri.EMPTY.equals(soundUri);
+
                 long[] vibration = record.getVibration();
                 // Demote sound to vibration if vibration missing & phone in vibration mode.
                 if (vibration == null
@@ -3882,7 +3892,10 @@
                 }
                 hasValidVibrate = vibration != null;
 
-                if (!shouldMuteNotificationLocked(record)) {
+                boolean hasAudibleAlert = hasValidSound || hasValidVibrate;
+
+                if (hasAudibleAlert && !shouldMuteNotificationLocked(record)) {
+                    if (DBG) Slog.v(TAG, "Interrupting!");
                     if (hasValidSound) {
                         mSoundNotificationKey = key;
                         if (mInCall) {
@@ -3939,14 +3952,37 @@
 
     @GuardedBy("mNotificationLock")
     boolean shouldMuteNotificationLocked(final NotificationRecord record) {
+        // Suppressed because it's a silent update
         final Notification notification = record.getNotification();
         if(record.isUpdate
                 && (notification.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0) {
             return true;
         }
+
+        // Suppressed for being too recently noisy
+        final String pkg = record.sbn.getPackageName();
+        if (mUsageStats.isAlertRateLimited(pkg)) {
+            Slog.e(TAG, "Muting recently noisy " + record.getKey());
+            return true;
+        }
+
+        // muted by listener
+        final String disableEffects = disableNotificationEffects(record);
+        if (disableEffects != null) {
+            ZenLog.traceDisableEffects(record, disableEffects);
+            return true;
+        }
+
+        // suppressed due to DND
+        if (record.isIntercepted()) {
+            return true;
+        }
+
+        // Suppressed because another notification in its group handles alerting
         if (record.sbn.isGroup()) {
             return notification.suppressAlertingDueToGrouping();
         }
+
         return false;
     }
 
@@ -4164,16 +4200,19 @@
             }
             int indexBefore = findNotificationRecordIndexLocked(record);
             boolean interceptBefore = record.isIntercepted();
+            float contactAffinityBefore = record.getContactAffinity();
             int visibilityBefore = record.getPackageVisibilityOverride();
             recon.applyChangesLocked(record);
             applyZenModeLocked(record);
             mRankingHelper.sort(mNotificationList);
             int indexAfter = findNotificationRecordIndexLocked(record);
             boolean interceptAfter = record.isIntercepted();
+            float contactAffinityAfter = record.getContactAffinity();
             int visibilityAfter = record.getPackageVisibilityOverride();
             changed = indexBefore != indexAfter || interceptBefore != interceptAfter
                     || visibilityBefore != visibilityAfter;
-            if (interceptBefore && !interceptAfter) {
+            if (interceptBefore && !interceptAfter
+                    && Float.compare(contactAffinityBefore, contactAffinityAfter) != 0) {
                 buzzBeepBlinkLocked(record);
             }
         }
@@ -5649,11 +5688,14 @@
 
     private class ShellCmd extends ShellCommand {
         public static final String USAGE = "help\n"
+                + "allow_listener COMPONENT\n"
+                + "disallow_listener COMPONENT\n"
                 + "allow_dnd PACKAGE\n"
                 + "disallow_dnd PACKAGE";
 
         @Override
         public int onCommand(String cmd) {
+            final PrintWriter pw = getOutPrintWriter();
             try {
                 switch (cmd) {
                     case "allow_dnd": {
@@ -5667,11 +5709,30 @@
                                 getNextArgRequired(), false);
                     }
                     break;
+                    case "allow_listener": {
+                        ComponentName cn = ComponentName.unflattenFromString(getNextArgRequired());
+                        if (cn == null) {
+                            pw.println("Invalid listener - must be a ComponentName");
+                            return -1;
+                        }
+                        getBinderService().setNotificationListenerAccessGranted(cn, true);
+                    }
+                    break;
+                    case "disallow_listener": {
+                        ComponentName cn = ComponentName.unflattenFromString(getNextArgRequired());
+                        if (cn == null) {
+                            pw.println("Invalid listener - must be a ComponentName");
+                            return -1;
+                        }
+                        getBinderService().setNotificationListenerAccessGranted(cn, false);
+                    }
+                    break;
 
                     default:
                         return handleDefaultCommands(cmd);
                 }
-            } catch (RemoteException e) {
+            } catch (Exception e) {
+                pw.println("Error occurred. Check logcat for details. " + e.getMessage());
                 Slog.e(TAG, "Error running shell command", e);
             }
             return 0;
diff --git a/services/core/java/com/android/server/notification/NotificationUsageStats.java b/services/core/java/com/android/server/notification/NotificationUsageStats.java
index e8cf6a1..3689cb1 100644
--- a/services/core/java/com/android/server/notification/NotificationUsageStats.java
+++ b/services/core/java/com/android/server/notification/NotificationUsageStats.java
@@ -114,6 +114,18 @@
     }
 
     /**
+     * Called when a notification wants to alert.
+     */
+    public synchronized boolean isAlertRateLimited(String packageName) {
+        AggregatedStats stats = getOrCreateAggregatedStatsLocked(packageName);
+        if (stats != null) {
+            return stats.isAlertRateLimited();
+        } else {
+            return false;
+        }
+    }
+
+    /**
      * Called when a notification is tentatively enqueued by an app, before rate checking.
      */
     public synchronized void registerEnqueuedByApp(String packageName) {
@@ -386,7 +398,9 @@
         public ImportanceHistogram quietImportance;
         public ImportanceHistogram finalImportance;
         public RateEstimator enqueueRate;
+        public AlertRateLimiter alertRate;
         public int numRateViolations;
+        public int numAlertViolations;
         public int numQuotaViolations;
         public long mLastAccessTime;
 
@@ -398,6 +412,7 @@
             quietImportance = new ImportanceHistogram(context, "note_imp_quiet_");
             finalImportance = new ImportanceHistogram(context, "note_importance_");
             enqueueRate = new RateEstimator();
+            alertRate = new AlertRateLimiter();
         }
 
         public AggregatedStats getPrevious() {
@@ -510,6 +525,7 @@
             maybeCount("note_sub_text", (numWithSubText - previous.numWithSubText));
             maybeCount("note_info_text", (numWithInfoText - previous.numWithInfoText));
             maybeCount("note_over_rate", (numRateViolations - previous.numRateViolations));
+            maybeCount("note_over_alert_rate", (numAlertViolations - previous.numAlertViolations));
             maybeCount("note_over_quota", (numQuotaViolations - previous.numQuotaViolations));
             noisyImportance.maybeCount(previous.noisyImportance);
             quietImportance.maybeCount(previous.quietImportance);
@@ -542,6 +558,7 @@
             previous.numWithSubText = numWithSubText;
             previous.numWithInfoText = numWithInfoText;
             previous.numRateViolations = numRateViolations;
+            previous.numAlertViolations = numAlertViolations;
             previous.numQuotaViolations = numQuotaViolations;
             noisyImportance.update(previous.noisyImportance);
             quietImportance.update(previous.quietImportance);
@@ -576,6 +593,14 @@
             enqueueRate.update(now);
         }
 
+        public boolean isAlertRateLimited() {
+            boolean limited = alertRate.isRateLimited(SystemClock.elapsedRealtime());
+            if (limited) {
+                numAlertViolations++;
+            }
+            return limited;
+        }
+
         private String toStringWithIndent(String indent) {
             StringBuilder output = new StringBuilder();
             output.append(indent).append("AggregatedStats{\n");
@@ -634,7 +659,11 @@
             output.append("numWithSubText=").append(numWithSubText).append("\n");
             output.append(indentPlusTwo);
             output.append("numWithInfoText=").append(numWithInfoText).append("\n");
+            output.append(indentPlusTwo);
             output.append("numRateViolations=").append(numRateViolations).append("\n");
+            output.append(indentPlusTwo);
+            output.append("numAlertViolations=").append(numAlertViolations).append("\n");
+            output.append(indentPlusTwo);
             output.append("numQuotaViolations=").append(numQuotaViolations).append("\n");
             output.append(indentPlusTwo).append(noisyImportance.toString()).append("\n");
             output.append(indentPlusTwo).append(quietImportance.toString()).append("\n");
@@ -677,6 +706,7 @@
             maybePut(dump, "numRateViolations", numRateViolations);
             maybePut(dump, "numQuotaLViolations", numQuotaViolations);
             maybePut(dump, "notificationEnqueueRate", getEnqueueRate());
+            maybePut(dump, "numAlertViolations", numAlertViolations);
             noisyImportance.maybePut(dump, previous.noisyImportance);
             quietImportance.maybePut(dump, previous.quietImportance);
             finalImportance.maybePut(dump, previous.finalImportance);
diff --git a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
index 562ab33..4600c32 100644
--- a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
+++ b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
@@ -56,9 +56,9 @@
     private static final String TAG = "PackageManager";
     // This is running in a critical section and the timeout must be sufficiently low
     private static final long BIND_SERVICE_TIMEOUT_MS =
-            ("eng".equals(Build.TYPE)) ? 500 : 300;
+            Build.IS_ENG ? 500 : 300;
     private static final long CALL_SERVICE_TIMEOUT_MS =
-            ("eng".equals(Build.TYPE)) ? 200 : 100;
+            Build.IS_ENG ? 200 : 100;
     private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE;
 
     private final Object mLock = new Object();
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 3dcffd7..92c5862 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -77,6 +77,7 @@
 import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN;
 import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
 import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
+import static android.content.pm.PackageManager.MOVE_FAILED_LOCKED_USER;
 import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
 import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
 import static android.content.pm.PackageManager.PERMISSION_DENIED;
@@ -86,6 +87,7 @@
 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
 import static android.system.OsConstants.O_CREAT;
 import static android.system.OsConstants.O_RDWR;
+
 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
 import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
@@ -101,6 +103,7 @@
 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE;
 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS;
 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
+
 import static dalvik.system.DexFile.getNonProfileGuidedCompilerFilter;
 
 import android.Manifest;
@@ -129,6 +132,7 @@
 import android.content.pm.AppsQueryHelper;
 import android.content.pm.AuxiliaryResolveInfo;
 import android.content.pm.ChangedPackages;
+import android.content.pm.ComponentInfo;
 import android.content.pm.FallbackCategoryProvider;
 import android.content.pm.FeatureInfo;
 import android.content.pm.IDexModuleRegisterCallback;
@@ -723,6 +727,9 @@
 
     final ProtectedPackages mProtectedPackages;
 
+    @GuardedBy("mLoadedVolumes")
+    final ArraySet<String> mLoadedVolumes = new ArraySet<>();
+
     boolean mFirstBoot;
 
     PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;
@@ -1056,14 +1063,12 @@
                         scheduleWriteSettingsLocked();
                     }
                 }
-                sendVerificationRequest(userId, verificationId, ivs);
+                sendVerificationRequest(verificationId, ivs);
             }
             mCurrentIntentFilterVerifications.clear();
         }
 
-        private void sendVerificationRequest(int userId, int verificationId,
-                IntentFilterVerificationState ivs) {
-
+        private void sendVerificationRequest(int verificationId, IntentFilterVerificationState ivs) {
             Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
             verificationIntent.putExtra(
                     PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
@@ -1083,10 +1088,9 @@
             DeviceIdleController.LocalService idleController = getDeviceIdleController();
             idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
                     mIntentFilterVerifierComponent.getPackageName(), getVerificationTimeout(),
-                    userId, false, "intent filter verifier");
+                    UserHandle.USER_SYSTEM, true, "intent filter verifier");
 
-            UserHandle user = new UserHandle(userId);
-            mContext.sendBroadcastAsUser(verificationIntent, user);
+            mContext.sendBroadcastAsUser(verificationIntent, UserHandle.SYSTEM);
             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
                     "Sending IntentFilter verification broadcast");
         }
@@ -3046,7 +3050,7 @@
         }
 
         // Disable package parsing on eng builds to allow for faster incremental development.
-        if ("eng".equals(Build.TYPE)) {
+        if (Build.IS_ENG) {
             return null;
         }
 
@@ -3081,7 +3085,7 @@
         // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
         // that starts with "eng." to signify that this is an engineering build and not
         // destined for release.
-        if ("userdebug".equals(Build.TYPE) && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
+        if (Build.IS_USERDEBUG && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
             Slog.w(TAG, "Wiping cache directory because the system partition changed.");
 
             // Heuristic: If the /system directory has been modified recently due to an "adb sync"
@@ -5529,7 +5533,7 @@
 
         if (eventIdIndex == -1) {
             if (AppOpsManager.permissionToOpCode(name) == AppOpsManager.OP_NONE
-                    || "user".equals(Build.TYPE)) {
+                    || Build.IS_USER) {
                 Log.i(TAG, "Unknown permission " + name);
 
                 return MetricsEvent.ACTION_PERMISSION_REQUEST_UNKNOWN;
@@ -7177,16 +7181,13 @@
      */
     private List<ResolveInfo> applyPostResolutionFilter(List<ResolveInfo> resolveInfos,
             String ephemeralPkgName) {
-        // TODO: When adding on-demand split support for non-instant apps, remove this check
-        // and always apply post filtering
-        if (ephemeralPkgName == null) {
-            return resolveInfos;
-        }
         for (int i = resolveInfos.size() - 1; i >= 0; i--) {
             final ResolveInfo info = resolveInfos.get(i);
             final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp();
+            // TODO: When adding on-demand split support for non-instant apps, remove this check
+            // and always apply post filtering
             // allow activities that are defined in the provided package
-            if (isEphemeralApp && ephemeralPkgName.equals(info.activityInfo.packageName)) {
+            if (isEphemeralApp) {
                 if (info.activityInfo.splitName != null
                         && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
                                 info.activityInfo.splitName)) {
@@ -7208,7 +7209,14 @@
                     // load resources from the correct package
                     installerInfo.resolvePackageName = info.getComponentInfo().packageName;
                     resolveInfos.set(i, installerInfo);
+                    continue;
                 }
+            }
+            // caller is a full app, don't need to apply any other filtering
+            if (ephemeralPkgName == null) {
+                continue;
+            } else if (ephemeralPkgName.equals(info.activityInfo.packageName)) {
+                // caller is same app; don't need to apply any other filtering
                 continue;
             }
             // allow activities that have been explicitly exposed to ephemeral apps
@@ -10489,8 +10497,9 @@
         if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
             if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0) {
                 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
-                derivePackageAbi(
-                        pkg, scanFile, cpuAbiOverride, true /*extractLibs*/, mAppLib32InstallDir);
+                final boolean extractNativeLibs = !pkg.isLibrary();
+                derivePackageAbi(pkg, scanFile, cpuAbiOverride, extractNativeLibs,
+                        mAppLib32InstallDir);
                 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
 
                 // Some system apps still use directory structure for native libraries
@@ -11520,6 +11529,12 @@
                     Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
                 }
 
+                // Shared library native code should be in the APK zip aligned
+                if (abi32 >= 0 && pkg.isLibrary() && extractLibs) {
+                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+                            "Shared library native lib extraction not supported");
+                }
+
                 maybeThrowExceptionForMultiArchCopy(
                         "Error unpackaging 32 bit native libs for multiarch app.", abi32);
 
@@ -11540,6 +11555,11 @@
                         "Error unpackaging 64 bit native libs for multiarch app.", abi64);
 
                 if (abi64 >= 0) {
+                    // Shared library native libs should be in the APK zip aligned
+                    if (extractLibs && pkg.isLibrary()) {
+                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+                                "Shared library native lib extraction not supported");
+                    }
                     pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
                 }
 
@@ -11556,7 +11576,6 @@
                         pkg.applicationInfo.primaryCpuAbi = abi;
                     }
                 }
-
             } else {
                 String[] abiList = (cpuAbiOverride != null) ?
                         new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
@@ -11589,6 +11608,11 @@
                 }
 
                 if (copyRet >= 0) {
+                    // Shared libraries that have native libs must be multi-architecture
+                    if (pkg.isLibrary()) {
+                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+                                "Shared library with native libs must be multiarch");
+                    }
                     pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
                 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
                     pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
@@ -16909,12 +16933,20 @@
         public void setError(String msg, PackageParserException e) {
             setReturnCode(e.error);
             setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
+            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
+            for (int i = 0; i < childCount; i++) {
+                addedChildPackages.valueAt(i).setError(msg, e);
+            }
             Slog.w(TAG, msg, e);
         }
 
         public void setError(String msg, PackageManagerException e) {
             returnCode = e.error;
             setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
+            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
+            for (int i = 0; i < childCount; i++) {
+                addedChildPackages.valueAt(i).setError(msg, e);
+            }
             Slog.w(TAG, msg, e);
         }
 
@@ -18143,8 +18175,9 @@
             try {
                 String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
                     args.abiOverride : pkg.cpuAbiOverride);
+                final boolean extractNativeLibs = !pkg.isLibrary();
                 derivePackageAbi(pkg, new File(pkg.codePath), abiOverride,
-                        true /*extractLibs*/, mAppLib32InstallDir);
+                        extractNativeLibs, mAppLib32InstallDir);
             } catch (PackageManagerException pme) {
                 Slog.e(TAG, "Error deriving application ABI", pme);
                 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
@@ -20013,7 +20046,7 @@
         // Queue up an async operation since the package deletion may take a little while.
         mHandler.post(new Runnable() {
             public void run() {
-                final PackageSetting ps = (PackageSetting) pkg.mExtras;
+                final PackageSetting ps = pkg == null ? null : (PackageSetting) pkg.mExtras;
                 boolean doClearData = true;
                 if (ps != null) {
                     final boolean targetIsInstantApp =
@@ -21657,6 +21690,7 @@
         public static final int DUMP_DEXOPT = 1 << 20;
         public static final int DUMP_COMPILER_STATS = 1 << 21;
         public static final int DUMP_CHANGES = 1 << 22;
+        public static final int DUMP_VOLUMES = 1 << 23;
 
         public static final int OPTION_SHOW_FILTERS = 1 << 0;
 
@@ -21896,6 +21930,8 @@
                 dumpState.setDump(DumpState.DUMP_INSTALLS);
             } else if ("frozen".equals(cmd)) {
                 dumpState.setDump(DumpState.DUMP_FROZEN);
+            } else if ("volumes".equals(cmd)) {
+                dumpState.setDump(DumpState.DUMP_VOLUMES);
             } else if ("dexopt".equals(cmd)) {
                 dumpState.setDump(DumpState.DUMP_DEXOPT);
             } else if ("compiler-stats".equals(cmd)) {
@@ -22280,6 +22316,23 @@
                 ipw.decreaseIndent();
             }
 
+            if (!checkin && dumpState.isDumping(DumpState.DUMP_VOLUMES) && packageName == null) {
+                if (dumpState.onTitlePrinted()) pw.println();
+
+                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
+                ipw.println();
+                ipw.println("Loaded volumes:");
+                ipw.increaseIndent();
+                if (mLoadedVolumes.size() == 0) {
+                    ipw.println("(none)");
+                } else {
+                    for (int i = 0; i < mLoadedVolumes.size(); i++) {
+                        ipw.println(mLoadedVolumes.valueAt(i));
+                    }
+                }
+                ipw.decreaseIndent();
+            }
+
             if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
                 if (dumpState.onTitlePrinted()) pw.println();
                 dumpDexoptStateLPr(pw, packageName);
@@ -22996,6 +23049,7 @@
 
         if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
         sendResourcesChangedBroadcast(true, false, loaded, null);
+        mLoadedVolumes.add(vol.getId());
     }
 
     private void unloadPrivatePackages(final VolumeInfo vol) {
@@ -23047,6 +23101,7 @@
 
         if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
         sendResourcesChangedBroadcast(false, false, unloaded, null);
+        mLoadedVolumes.remove(vol.getId());
 
         // Try very hard to release any references to this path so we don't risk
         // the system server being killed due to open FDs
@@ -23590,8 +23645,7 @@
                     movePackageInternal(packageName, volumeUuid, moveId, callingUid, user);
                 } catch (PackageManagerException e) {
                     Slog.w(TAG, "Failed to move " + packageName, e);
-                    mMoveCallbacks.notifyStatusChanged(moveId,
-                            PackageManager.MOVE_FAILED_INTERNAL_ERROR);
+                    mMoveCallbacks.notifyStatusChanged(moveId, e.error);
                 }
             }
         });
@@ -23714,6 +23768,17 @@
             measurePath = Environment.getDataAppDirectory(volumeUuid);
         }
 
+        // If we're moving app data around, we need all the users unlocked
+        if (moveCompleteApp) {
+            for (int userId : installedUserIds) {
+                if (StorageManager.isFileEncryptedNativeOrEmulated()
+                        && !StorageManager.isUserKeyUnlocked(userId)) {
+                    throw new PackageManagerException(MOVE_FAILED_LOCKED_USER,
+                            "User " + userId + " must be unlocked");
+                }
+            }
+        }
+
         final PackageStats stats = new PackageStats(null, -1);
         synchronized (mInstaller) {
             for (int userId : installedUserIds) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index f3a292b..20d7b28 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -1018,7 +1018,7 @@
             throw new RuntimeException(e.getMessage(), e);
         }
         try {
-            ResolveInfo ri = mInterface.resolveIntent(intent, null, 0, mTargetUser);
+            ResolveInfo ri = mInterface.resolveIntent(intent, intent.getType(), 0, mTargetUser);
             PrintWriter pw = getOutPrintWriter();
             if (ri == null) {
                 pw.println("No activity found");
@@ -1040,7 +1040,7 @@
             throw new RuntimeException(e.getMessage(), e);
         }
         try {
-            List<ResolveInfo> result = mInterface.queryIntentActivities(intent, null, 0,
+            List<ResolveInfo> result = mInterface.queryIntentActivities(intent, intent.getType(), 0,
                     mTargetUser).getList();
             PrintWriter pw = getOutPrintWriter();
             if (result == null || result.size() <= 0) {
@@ -1074,7 +1074,7 @@
             throw new RuntimeException(e.getMessage(), e);
         }
         try {
-            List<ResolveInfo> result = mInterface.queryIntentServices(intent, null, 0,
+            List<ResolveInfo> result = mInterface.queryIntentServices(intent, intent.getType(), 0,
                     mTargetUser).getList();
             PrintWriter pw = getOutPrintWriter();
             if (result == null || result.size() <= 0) {
@@ -1108,7 +1108,7 @@
             throw new RuntimeException(e.getMessage(), e);
         }
         try {
-            List<ResolveInfo> result = mInterface.queryIntentReceivers(intent, null, 0,
+            List<ResolveInfo> result = mInterface.queryIntentReceivers(intent, intent.getType(), 0,
                     mTargetUser).getList();
             PrintWriter pw = getOutPrintWriter();
             if (result == null || result.size() <= 0) {
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 5c6521b..89dbc2a 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -23,6 +23,7 @@
 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
 import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
 import static android.app.AppOpsManager.OP_TOAST_WINDOW;
+import static android.content.Context.CONTEXT_RESTRICTED;
 import static android.content.Context.DISPLAY_SERVICE;
 import static android.content.Context.WINDOW_SERVICE;
 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
@@ -2823,7 +2824,7 @@
 
             if (theme != context.getThemeResId() || labelRes != 0) {
                 try {
-                    context = context.createPackageContext(packageName, 0);
+                    context = context.createPackageContext(packageName, CONTEXT_RESTRICTED);
                     context.setTheme(theme);
                 } catch (PackageManager.NameNotFoundException e) {
                     // Ignore
diff --git a/services/core/java/com/android/server/radio/RadioService.java b/services/core/java/com/android/server/radio/RadioService.java
index 227ea6b..8b0d3aa 100644
--- a/services/core/java/com/android/server/radio/RadioService.java
+++ b/services/core/java/com/android/server/radio/RadioService.java
@@ -24,16 +24,12 @@
 import android.hardware.radio.ITunerCallback;
 import android.hardware.radio.RadioManager;
 import android.os.ParcelableException;
-import android.util.Slog;
 
 import com.android.server.SystemService;
 
 import java.util.List;
 
 public class RadioService extends SystemService {
-    // TODO(b/36863239): rename to RadioService when native service goes away
-    private static final String TAG = "RadioServiceJava";
-
     private final RadioServiceImpl mServiceImpl = new RadioServiceImpl();
 
     /**
@@ -63,7 +59,6 @@
     @Override
     public void onStart() {
         publishBinderService(Context.RADIO_SERVICE, mServiceImpl);
-        Slog.v(TAG, "RadioService started");
     }
 
     private class RadioServiceImpl extends IRadioService.Stub {
@@ -98,7 +93,6 @@
                 throw new IllegalArgumentException("Callback must not be empty");
             }
             synchronized (mLock) {
-                // TODO(b/36863239): add death monitoring for binder
                 return nativeOpenTuner(mNativeContext, moduleId, bandConfig, withAudio, callback);
             }
         }
diff --git a/services/core/java/com/android/server/radio/Tuner.java b/services/core/java/com/android/server/radio/Tuner.java
index 38f16d5..81128c2 100644
--- a/services/core/java/com/android/server/radio/Tuner.java
+++ b/services/core/java/com/android/server/radio/Tuner.java
@@ -20,31 +20,42 @@
 import android.hardware.radio.ITuner;
 import android.hardware.radio.ITunerCallback;
 import android.hardware.radio.RadioManager;
+import android.os.IBinder;
+import android.os.RemoteException;
 import android.util.Slog;
 
 import java.util.List;
 
 class Tuner extends ITuner.Stub {
-    // TODO(b/36863239): rename to RadioService.Tuner when native service goes away
-    private static final String TAG = "RadioServiceJava.Tuner";
+    private static final String TAG = "RadioService.Tuner";
 
     /**
      * This field is used by native code, do not access or modify.
      */
     private final long mNativeContext;
 
-    @NonNull private final TunerCallback mTunerCallback;
     private final Object mLock = new Object();
+    @NonNull private final TunerCallback mTunerCallback;
+    @NonNull private final ITunerCallback mClientCallback;
+    @NonNull private final IBinder.DeathRecipient mDeathRecipient;
+
     private boolean mIsClosed = false;
     private boolean mIsMuted = false;
     private int mRegion;  // TODO(b/62710330): find better solution to handle regions
     private final boolean mWithAudio;
 
     Tuner(@NonNull ITunerCallback clientCallback, int halRev, int region, boolean withAudio) {
+        mClientCallback = clientCallback;
         mTunerCallback = new TunerCallback(this, clientCallback, halRev);
         mRegion = region;
         mWithAudio = withAudio;
-        mNativeContext = nativeInit(halRev);
+        mNativeContext = nativeInit(halRev, withAudio);
+        mDeathRecipient = this::close;
+        try {
+            mClientCallback.asBinder().linkToDeath(mDeathRecipient, 0);
+        } catch (RemoteException ex) {
+            close();
+        }
     }
 
     @Override
@@ -53,7 +64,7 @@
         super.finalize();
     }
 
-    private native long nativeInit(int halRev);
+    private native long nativeInit(int halRev, boolean withAudio);
     private native void nativeFinalize(long nativeContext);
     private native void nativeClose(long nativeContext);
 
@@ -80,12 +91,18 @@
     public void close() {
         synchronized (mLock) {
             if (mIsClosed) return;
-            mTunerCallback.detach();
-            nativeClose(mNativeContext);
             mIsClosed = true;
+            mTunerCallback.detach();
+            mClientCallback.asBinder().unlinkToDeath(mDeathRecipient, 0);
+            nativeClose(mNativeContext);
         }
     }
 
+    @Override
+    public boolean isClosed() {
+        return mIsClosed;
+    }
+
     private void checkNotClosedLocked() {
         if (mIsClosed) {
             throw new IllegalStateException("Tuner is closed, no further operations are allowed");
@@ -122,7 +139,7 @@
             if (mIsMuted == mute) return;
             mIsMuted = mute;
 
-            // TODO(b/34348946): notifify audio policy manager of media activity on radio audio
+            // TODO(b/62713378): notifify audio policy manager of media activity on radio audio
             // device. This task is pulled directly from previous implementation of native service.
         }
     }
diff --git a/services/core/java/com/android/server/radio/TunerCallback.java b/services/core/java/com/android/server/radio/TunerCallback.java
index d10f2c6..9430dc9 100644
--- a/services/core/java/com/android/server/radio/TunerCallback.java
+++ b/services/core/java/com/android/server/radio/TunerCallback.java
@@ -27,8 +27,7 @@
 import android.util.Slog;
 
 class TunerCallback implements ITunerCallback {
-    // TODO(b/36863239): rename to RadioService.TunerCallback when native service goes away
-    private static final String TAG = "RadioServiceJava.TunerCallback";
+    private static final String TAG = "RadioService.TunerCallback";
 
     /**
      * This field is used by native code, do not access or modify.
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 5067071..5b6bf1f 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -795,7 +795,7 @@
             mHandler.post(() -> {
                 // ShutdownThread displays UI, so give it a UI context.
                 if (safeMode) {
-                    ShutdownThread.rebootSafeMode(getUiContext(), false);
+                    ShutdownThread.rebootSafeMode(getUiContext(), true);
                 } else {
                     ShutdownThread.reboot(getUiContext(),
                             PowerManager.SHUTDOWN_USER_REQUESTED, false);
diff --git a/services/core/java/com/android/server/timezone/PackageStatusStorage.java b/services/core/java/com/android/server/timezone/PackageStatusStorage.java
index 31f0e31..05e97c7 100644
--- a/services/core/java/com/android/server/timezone/PackageStatusStorage.java
+++ b/services/core/java/com/android/server/timezone/PackageStatusStorage.java
@@ -16,73 +16,83 @@
 
 package com.android.server.timezone;
 
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
+import com.android.internal.util.FastXmlSerializer;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import android.util.AtomicFile;
 import android.util.Slog;
+import android.util.Xml;
 
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.text.ParseException;
 
 import static com.android.server.timezone.PackageStatus.CHECK_COMPLETED_FAILURE;
 import static com.android.server.timezone.PackageStatus.CHECK_COMPLETED_SUCCESS;
 import static com.android.server.timezone.PackageStatus.CHECK_STARTED;
+import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
+import static org.xmlpull.v1.XmlPullParser.START_TAG;
 
 /**
  * Storage logic for accessing/mutating the Android system's persistent state related to time zone
- * update checking. There is expected to be a single instance and all methods synchronized on
- * {@code this} for thread safety.
+ * update checking. There is expected to be a single instance. All non-private methods are thread
+ * safe.
  */
 final class PackageStatusStorage {
 
-    private static final String TAG = "timezone.PackageStatusStorage";
+    private static final String LOG_TAG = "timezone.PackageStatusStorage";
 
-    private static final String DATABASE_NAME = "timezonepackagestatus.db";
-    private static final int DATABASE_VERSION = 1;
-
-    /** The table name. It will have a single row with _id == {@link #SINGLETON_ID} */
-    private static final String TABLE = "status";
-    private static final String COLUMN_ID = "_id";
+    private static final String TAG_PACKAGE_STATUS = "PackageStatus";
 
     /**
-     * Column that stores a monotonically increasing lock ID, used to detect concurrent update
+     * Attribute that stores a monotonically increasing lock ID, used to detect concurrent update
      * issues without on-line locks. Incremented on every write.
      */
-    private static final String COLUMN_OPTIMISTIC_LOCK_ID = "optimistic_lock_id";
+    private static final String ATTRIBUTE_OPTIMISTIC_LOCK_ID = "optimisticLockId";
 
     /**
-     * Column that stores the current "check status" of the time zone update application packages.
+     * Attribute that stores the current "check status" of the time zone update application
+     * packages.
      */
-    private static final String COLUMN_CHECK_STATUS = "check_status";
+    private static final String ATTRIBUTE_CHECK_STATUS = "checkStatus";
 
     /**
-     * Column that stores the version of the time zone rules update application being checked / last
-     * checked.
+     * Attribute that stores the version of the time zone rules update application being checked
+     * / last checked.
      */
-    private static final String COLUMN_UPDATE_APP_VERSION = "update_app_package_version";
+    private static final String ATTRIBUTE_UPDATE_APP_VERSION = "updateAppPackageVersion";
 
     /**
-     * Column that stores the version of the time zone rules data application being checked / last
-     * checked.
+     * Attribute that stores the version of the time zone rules data application being checked
+     * / last checked.
      */
-    private static final String COLUMN_DATA_APP_VERSION = "data_app_package_version";
-
-    /**
-     * The ID of the one row.
-     */
-    private static final int SINGLETON_ID = 1;
+    private static final String ATTRIBUTE_DATA_APP_VERSION = "dataAppPackageVersion";
 
     private static final int UNKNOWN_PACKAGE_VERSION = -1;
 
-    private final DatabaseHelper mDatabaseHelper;
+    private final AtomicFile mPackageStatusFile;
 
-    PackageStatusStorage(Context context) {
-        mDatabaseHelper = new DatabaseHelper(context);
+    PackageStatusStorage(File storageDir) {
+        mPackageStatusFile = new AtomicFile(new File(storageDir, "packageStatus.xml"));
+        if (!mPackageStatusFile.getBaseFile().exists()) {
+            try {
+                insertInitialPackageStatus();
+            } catch (IOException e) {
+                throw new IllegalStateException(e);
+            }
+        }
     }
 
-    void deleteDatabaseForTests() {
-        SQLiteDatabase.deleteDatabase(mDatabaseHelper.getDatabaseFile());
+    void deleteFileForTests() {
+        synchronized(this) {
+            mPackageStatusFile.delete();
+        }
     }
 
     /**
@@ -93,48 +103,60 @@
         synchronized (this) {
             try {
                 return getPackageStatusInternal();
-            } catch (IllegalArgumentException e) {
-                // This means that data exists in the table but it was bad.
-                Slog.e(TAG, "Package status invalid, resetting and retrying", e);
+            } catch (ParseException e) {
+                // This means that data exists in the file but it was bad.
+                Slog.e(LOG_TAG, "Package status invalid, resetting and retrying", e);
 
                 // Reset the storage so it is in a good state again.
-                mDatabaseHelper.recoverFromBadData();
-                return getPackageStatusInternal();
+                recoverFromBadData(e);
+                try {
+                    return getPackageStatusInternal();
+                } catch (ParseException e2) {
+                    throw new IllegalStateException("Recovery from bad file failed", e2);
+                }
             }
         }
     }
 
-    private PackageStatus getPackageStatusInternal() {
-        String[] columns = {
-                COLUMN_CHECK_STATUS, COLUMN_UPDATE_APP_VERSION, COLUMN_DATA_APP_VERSION
-        };
-        Cursor cursor = mDatabaseHelper.getReadableDatabase()
-                .query(TABLE, columns, COLUMN_ID + " = ?",
-                        new String[] { Integer.toString(SINGLETON_ID) },
-                        null /* groupBy */, null /* having */, null /* orderBy */);
-        if (cursor.getCount() != 1) {
-            Slog.e(TAG, "Unable to find package status from package status row. Rows returned: "
-                    + cursor.getCount());
-            return null;
+    private PackageStatus getPackageStatusInternal() throws ParseException {
+        try (FileInputStream fis = mPackageStatusFile.openRead()) {
+            XmlPullParser parser = parseToPackageStatusTag(fis);
+            Integer checkStatus = getNullableIntAttribute(parser, ATTRIBUTE_CHECK_STATUS);
+            if (checkStatus == null) {
+                return null;
+            }
+            int updateAppVersion = getIntAttribute(parser, ATTRIBUTE_UPDATE_APP_VERSION);
+            int dataAppVersion = getIntAttribute(parser, ATTRIBUTE_DATA_APP_VERSION);
+            return new PackageStatus(checkStatus,
+                    new PackageVersions(updateAppVersion, dataAppVersion));
+        } catch (IOException e) {
+            ParseException e2 = new ParseException("Error reading package status", 0);
+            e2.initCause(e);
+            throw e2;
         }
-        cursor.moveToFirst();
+    }
 
-        // Determine check status.
-        if (cursor.isNull(0)) {
-            // This is normal the first time getPackageStatus() is called, or after
-            // resetCheckState().
-            return null;
+    // Callers should be synchronized(this).
+    private int recoverFromBadData(Exception cause) {
+        mPackageStatusFile.delete();
+        try {
+            return insertInitialPackageStatus();
+        } catch (IOException e) {
+            IllegalStateException fatal = new IllegalStateException(e);
+            fatal.addSuppressed(cause);
+            throw fatal;
         }
-        int checkStatus = cursor.getInt(0);
+    }
 
-        // Determine package version.
-        if (cursor.isNull(1) || cursor.isNull(2)) {
-            Slog.e(TAG, "Package version information unexpectedly null");
-            return null;
-        }
-        PackageVersions packageVersions = new PackageVersions(cursor.getInt(1), cursor.getInt(2));
+    /** Insert the initial data, returning the optimistic lock ID */
+    private int insertInitialPackageStatus() throws IOException {
+        // Doesn't matter what it is, but we avoid the obvious starting value each time the data
+        // is reset to ensure that old tokens are unlikely to work.
+        final int initialOptimisticLockId = (int) System.currentTimeMillis();
 
-        return new PackageStatus(checkStatus, packageVersions);
+        writePackageStatusInternal(null /* status */, initialOptimisticLockId,
+                null /* packageVersions */);
+        return initialOptimisticLockId;
     }
 
     /**
@@ -147,23 +169,29 @@
         }
 
         synchronized (this) {
-            Integer optimisticLockId = getCurrentOptimisticLockId();
-            if (optimisticLockId == null) {
-                Slog.w(TAG, "Unable to find optimistic lock ID from package status row");
+            int optimisticLockId;
+            try {
+                optimisticLockId = getCurrentOptimisticLockId();
+            } catch (ParseException e) {
+                Slog.w(LOG_TAG, "Unable to find optimistic lock ID from package status");
 
                 // Recover.
-                optimisticLockId = mDatabaseHelper.recoverFromBadData();
+                optimisticLockId = recoverFromBadData(e);
             }
 
             int newOptimisticLockId = optimisticLockId + 1;
-            boolean statusRowUpdated = writeStatusRow(
-                    optimisticLockId, newOptimisticLockId, CHECK_STARTED, currentInstalledVersions);
-            if (!statusRowUpdated) {
-                Slog.e(TAG, "Unable to update status to CHECK_STARTED in package status row."
-                        + " synchronization failure?");
-                return null;
+            try {
+                boolean statusUpdated = writePackageStatusWithOptimisticLockCheck(
+                        optimisticLockId, newOptimisticLockId, CHECK_STARTED,
+                        currentInstalledVersions);
+                if (!statusUpdated) {
+                    throw new IllegalStateException("Unable to update status to CHECK_STARTED."
+                            + " synchronization failure?");
+                }
+                return new CheckToken(newOptimisticLockId, currentInstalledVersions);
+            } catch (IOException e) {
+                throw new IllegalStateException(e);
             }
-            return new CheckToken(newOptimisticLockId, currentInstalledVersions);
         }
     }
 
@@ -172,19 +200,25 @@
      */
     void resetCheckState() {
         synchronized(this) {
-            Integer optimisticLockId = getCurrentOptimisticLockId();
-            if (optimisticLockId == null) {
-                Slog.w(TAG, "resetCheckState: Unable to find optimistic lock ID from package"
-                        + " status row");
+            int optimisticLockId;
+            try {
+                optimisticLockId = getCurrentOptimisticLockId();
+            } catch (ParseException e) {
+                Slog.w(LOG_TAG, "resetCheckState: Unable to find optimistic lock ID from package"
+                        + " status");
                 // Attempt to recover the storage state.
-                optimisticLockId = mDatabaseHelper.recoverFromBadData();
+                optimisticLockId = recoverFromBadData(e);
             }
 
             int newOptimisticLockId = optimisticLockId + 1;
-            if (!writeStatusRow(optimisticLockId, newOptimisticLockId,
-                    null /* status */, null /* packageVersions */)) {
-                Slog.e(TAG, "resetCheckState: Unable to reset package status row,"
-                        + " newOptimisticLockId=" + newOptimisticLockId);
+            try {
+                if (!writePackageStatusWithOptimisticLockCheck(optimisticLockId,
+                        newOptimisticLockId, null /* status */, null /* packageVersions */)) {
+                    throw new IllegalStateException("resetCheckState: Unable to reset package"
+                            + " status, newOptimisticLockId=" + newOptimisticLockId);
+                }
+            } catch (IOException e) {
+                throw new IllegalStateException(e);
             }
         }
     }
@@ -199,138 +233,146 @@
             int optimisticLockId = checkToken.mOptimisticLockId;
             int newOptimisticLockId = optimisticLockId + 1;
             int status = succeeded ? CHECK_COMPLETED_SUCCESS : CHECK_COMPLETED_FAILURE;
-            return writeStatusRow(optimisticLockId, newOptimisticLockId,
-                    status, checkToken.mPackageVersions);
-        }
-    }
-
-    // Caller should be synchronized(this)
-    private Integer getCurrentOptimisticLockId() {
-        final String[] columns = { COLUMN_OPTIMISTIC_LOCK_ID };
-        final String querySelection = COLUMN_ID + " = ?";
-        final String[] querySelectionArgs = { Integer.toString(SINGLETON_ID) };
-
-        SQLiteDatabase database = mDatabaseHelper.getReadableDatabase();
-        try (Cursor cursor = database.query(TABLE, columns, querySelection, querySelectionArgs,
-                null /* groupBy */, null /* having */, null /* orderBy */)) {
-            if (cursor.getCount() != 1) {
-                Slog.w(TAG, cursor.getCount() + " rows returned, expected exactly one.");
-                return null;
+            try {
+                return writePackageStatusWithOptimisticLockCheck(optimisticLockId,
+                        newOptimisticLockId, status, checkToken.mPackageVersions);
+            } catch (IOException e) {
+                throw new IllegalStateException(e);
             }
-            cursor.moveToFirst();
-            return cursor.getInt(0);
         }
     }
 
-    // Caller should be synchronized(this)
-    private boolean writeStatusRow(int optimisticLockId, int newOptimisticLockId, Integer status,
-            PackageVersions packageVersions) {
+    // Caller should be synchronized(this).
+    private int getCurrentOptimisticLockId() throws ParseException {
+        try (FileInputStream fis = mPackageStatusFile.openRead()) {
+            XmlPullParser parser = parseToPackageStatusTag(fis);
+            return getIntAttribute(parser, ATTRIBUTE_OPTIMISTIC_LOCK_ID);
+        } catch (IOException e) {
+            ParseException e2 = new ParseException("Unable to read file", 0);
+            e2.initCause(e);
+            throw e2;
+        }
+    }
+
+    /** Returns a parser or throws ParseException, never returns null. */
+    private static XmlPullParser parseToPackageStatusTag(FileInputStream fis)
+            throws ParseException {
+        try {
+            XmlPullParser parser = Xml.newPullParser();
+            parser.setInput(fis, StandardCharsets.UTF_8.name());
+            int type;
+            while ((type = parser.next()) != END_DOCUMENT) {
+                final String tag = parser.getName();
+                if (type == START_TAG && TAG_PACKAGE_STATUS.equals(tag)) {
+                    return parser;
+                }
+            }
+            throw new ParseException("Unable to find " + TAG_PACKAGE_STATUS + " tag", 0);
+        } catch (XmlPullParserException e) {
+            throw new IllegalStateException("Unable to configure parser", e);
+        } catch (IOException e) {
+            ParseException e2 = new ParseException("Error reading XML", 0);
+            e.initCause(e);
+            throw e2;
+        }
+    }
+
+    // Caller should be synchronized(this).
+    private boolean writePackageStatusWithOptimisticLockCheck(int optimisticLockId,
+            int newOptimisticLockId, Integer status, PackageVersions packageVersions)
+            throws IOException {
+
+        int currentOptimisticLockId;
+        try {
+            currentOptimisticLockId = getCurrentOptimisticLockId();
+            if (currentOptimisticLockId != optimisticLockId) {
+                return false;
+            }
+        } catch (ParseException e) {
+            recoverFromBadData(e);
+            return false;
+        }
+
+        writePackageStatusInternal(status, newOptimisticLockId, packageVersions);
+        return true;
+    }
+
+    // Caller should be synchronized(this).
+    private void writePackageStatusInternal(Integer status, int optimisticLockId,
+            PackageVersions packageVersions) throws IOException {
         if ((status == null) != (packageVersions == null)) {
             throw new IllegalArgumentException(
                     "Provide both status and packageVersions, or neither.");
         }
 
-        SQLiteDatabase database = mDatabaseHelper.getWritableDatabase();
-        ContentValues values = new ContentValues();
-        values.put(COLUMN_OPTIMISTIC_LOCK_ID, newOptimisticLockId);
-        if (status == null) {
-            values.putNull(COLUMN_CHECK_STATUS);
-            values.put(COLUMN_UPDATE_APP_VERSION, UNKNOWN_PACKAGE_VERSION);
-            values.put(COLUMN_DATA_APP_VERSION, UNKNOWN_PACKAGE_VERSION);
-        } else {
-            values.put(COLUMN_CHECK_STATUS, status);
-            values.put(COLUMN_UPDATE_APP_VERSION, packageVersions.mUpdateAppVersion);
-            values.put(COLUMN_DATA_APP_VERSION, packageVersions.mDataAppVersion);
+        FileOutputStream fos = null;
+        try {
+            fos = mPackageStatusFile.startWrite();
+            XmlSerializer serializer = new FastXmlSerializer();
+            serializer.setOutput(fos, StandardCharsets.UTF_8.name());
+            serializer.startDocument(null /* encoding */, true /* standalone */);
+            final String namespace = null;
+            serializer.startTag(namespace, TAG_PACKAGE_STATUS);
+            String statusAttributeValue = status == null ? "" : Integer.toString(status);
+            serializer.attribute(namespace, ATTRIBUTE_CHECK_STATUS, statusAttributeValue);
+            serializer.attribute(namespace, ATTRIBUTE_OPTIMISTIC_LOCK_ID,
+                    Integer.toString(optimisticLockId));
+            int updateAppVersion = status == null
+                    ? UNKNOWN_PACKAGE_VERSION : packageVersions.mUpdateAppVersion;
+            serializer.attribute(namespace, ATTRIBUTE_UPDATE_APP_VERSION,
+                    Integer.toString(updateAppVersion));
+            int dataAppVersion = status == null
+                    ? UNKNOWN_PACKAGE_VERSION : packageVersions.mDataAppVersion;
+            serializer.attribute(namespace, ATTRIBUTE_DATA_APP_VERSION,
+                    Integer.toString(dataAppVersion));
+            serializer.endTag(namespace, TAG_PACKAGE_STATUS);
+            serializer.endDocument();
+            serializer.flush();
+            mPackageStatusFile.finishWrite(fos);
+        } catch (IOException e) {
+            if (fos != null) {
+                mPackageStatusFile.failWrite(fos);
+            }
+            throw e;
         }
 
-        String updateSelection = COLUMN_ID + " = ? AND " + COLUMN_OPTIMISTIC_LOCK_ID + " = ?";
-        String[] updateSelectionArgs = {
-                Integer.toString(SINGLETON_ID), Integer.toString(optimisticLockId)
-        };
-        int count = database.update(TABLE, values, updateSelection, updateSelectionArgs);
-        if (count > 1) {
-            // This has to be because of corruption: there should only ever be one row.
-            Slog.w(TAG, "writeStatusRow: " + count + " rows updated, expected exactly one.");
-            // Reset the table.
-            mDatabaseHelper.recoverFromBadData();
-        }
-
-        // 1 is the success case. 0 rows updated means the row is missing or the optimistic lock ID
-        // was not as expected, this could be because of corruption but is most likely due to an
-        // optimistic lock failure. Callers can decide on a case-by-case basis.
-        return count == 1;
-    }
-
-    /** Only used during tests to force an empty table. */
-    void deleteRowForTests() {
-        mDatabaseHelper.getWritableDatabase().delete(TABLE, null, null);
     }
 
     /** Only used during tests to force a known table state. */
     public void forceCheckStateForTests(int checkStatus, PackageVersions packageVersions) {
-        int optimisticLockId = getCurrentOptimisticLockId();
-        writeStatusRow(optimisticLockId, optimisticLockId, checkStatus, packageVersions);
+        synchronized (this) {
+            try {
+                int optimisticLockId = getCurrentOptimisticLockId();
+                writePackageStatusWithOptimisticLockCheck(optimisticLockId, optimisticLockId,
+                        checkStatus, packageVersions);
+            } catch (IOException | ParseException e) {
+                throw new IllegalStateException(e);
+            }
+        }
     }
 
-    static class DatabaseHelper extends SQLiteOpenHelper {
-
-        private final Context mContext;
-
-        public DatabaseHelper(Context context) {
-            super(context, DATABASE_NAME, null, DATABASE_VERSION);
-            mContext = context;
-        }
-
-        @Override
-        public void onCreate(SQLiteDatabase db) {
-            db.execSQL("CREATE TABLE " + TABLE + " (" +
-                    "_id INTEGER PRIMARY KEY," +
-                    COLUMN_OPTIMISTIC_LOCK_ID + " INTEGER NOT NULL," +
-                    COLUMN_CHECK_STATUS + " INTEGER," +
-                    COLUMN_UPDATE_APP_VERSION + " INTEGER NOT NULL," +
-                    COLUMN_DATA_APP_VERSION + " INTEGER NOT NULL" +
-                    ");");
-            insertInitialRowState(db);
-        }
-
-        @Override
-        public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) {
-            // no-op: nothing to upgrade
-        }
-
-        /** Recover the initial data row state, returning the new current optimistic lock ID */
-        int recoverFromBadData() {
-            // Delete the table content.
-            SQLiteDatabase writableDatabase = getWritableDatabase();
-            writableDatabase.delete(TABLE, null /* whereClause */, null /* whereArgs */);
-
-            // Insert the initial content.
-            return insertInitialRowState(writableDatabase);
-        }
-
-        /** Insert the initial data row, returning the optimistic lock ID */
-        private static int insertInitialRowState(SQLiteDatabase db) {
-            // Doesn't matter what it is, but we avoid the obvious starting value each time the row
-            // is reset to ensure that old tokens are unlikely to work.
-           final int initialOptimisticLockId = (int) System.currentTimeMillis();
-
-            // Insert the one row.
-            ContentValues values = new ContentValues();
-            values.put(COLUMN_ID, SINGLETON_ID);
-            values.put(COLUMN_OPTIMISTIC_LOCK_ID, initialOptimisticLockId);
-            values.putNull(COLUMN_CHECK_STATUS);
-            values.put(COLUMN_UPDATE_APP_VERSION, UNKNOWN_PACKAGE_VERSION);
-            values.put(COLUMN_DATA_APP_VERSION, UNKNOWN_PACKAGE_VERSION);
-            long id = db.insert(TABLE, null, values);
-            if (id == -1) {
-                Slog.w(TAG, "insertInitialRow: could not insert initial row, id=" + id);
-                return -1;
+    private static Integer getNullableIntAttribute(XmlPullParser parser, String attributeName)
+            throws ParseException {
+        String attributeValue = parser.getAttributeValue(null, attributeName);
+        try {
+            if (attributeValue == null) {
+                throw new ParseException("Attribute " + attributeName + " missing", 0);
+            } else if (attributeValue.isEmpty()) {
+                return null;
             }
-            return initialOptimisticLockId;
+            return Integer.parseInt(attributeValue);
+        } catch (NumberFormatException e) {
+            throw new ParseException(
+                    "Bad integer for attributeName=" + attributeName + ": " + attributeValue, 0);
         }
+    }
 
-        File getDatabaseFile() {
-            return mContext.getDatabasePath(DATABASE_NAME);
+    private static int getIntAttribute(XmlPullParser parser, String attributeName)
+            throws ParseException {
+        Integer value = getNullableIntAttribute(parser, attributeName);
+        if (value == null) {
+            throw new ParseException("Missing attribute " + attributeName, 0);
         }
+        return value;
     }
 }
diff --git a/services/core/java/com/android/server/timezone/PackageTracker.java b/services/core/java/com/android/server/timezone/PackageTracker.java
index 8abf7df..f9af2ea 100644
--- a/services/core/java/com/android/server/timezone/PackageTracker.java
+++ b/services/core/java/com/android/server/timezone/PackageTracker.java
@@ -21,9 +21,12 @@
 import android.app.timezone.RulesUpdaterContract;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.os.Environment;
 import android.provider.TimeZoneRulesDataContract;
 import android.util.Slog;
 
+import java.io.File;
+
 /**
  * Monitors the installed applications associated with time zone updates. If the app packages are
  * updated it indicates there <em>might</em> be a time zone rules update to apply so a targeted
@@ -81,11 +84,17 @@
     /** Creates the {@link PackageTracker} for normal use. */
     static PackageTracker create(Context context) {
         PackageTrackerHelperImpl helperImpl = new PackageTrackerHelperImpl(context);
+        // TODO(nfuller): Switch to FileUtils.createDir() when available. http://b/31008728
+        File storageDir = new File(Environment.getDataSystemDirectory(), "timezone");
+        if (!storageDir.exists()) {
+            storageDir.mkdir();
+        }
+
         return new PackageTracker(
                 helperImpl /* clock */,
                 helperImpl /* configHelper */,
                 helperImpl /* packageManagerHelper */,
-                new PackageStatusStorage(context),
+                new PackageStatusStorage(storageDir),
                 new IntentHelperImpl(context));
     }
 
diff --git a/services/core/java/com/android/server/timezone/RulesManagerService.java b/services/core/java/com/android/server/timezone/RulesManagerService.java
index 58bdeb9..804a8b7 100644
--- a/services/core/java/com/android/server/timezone/RulesManagerService.java
+++ b/services/core/java/com/android/server/timezone/RulesManagerService.java
@@ -20,8 +20,8 @@
 import com.android.server.SystemService;
 import com.android.timezone.distro.DistroException;
 import com.android.timezone.distro.DistroVersion;
-import com.android.timezone.distro.TimeZoneDistro;
 import com.android.timezone.distro.StagedDistroOperation;
+import com.android.timezone.distro.TimeZoneDistro;
 
 import android.app.timezone.Callback;
 import android.app.timezone.DistroFormatVersion;
@@ -36,7 +36,9 @@
 import android.util.Slog;
 
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.util.Arrays;
 import java.util.concurrent.Executor;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -83,26 +85,22 @@
     private final PackageTracker mPackageTracker;
     private final Executor mExecutor;
     private final TimeZoneDistroInstaller mInstaller;
-    private final FileDescriptorHelper mFileDescriptorHelper;
 
     private static RulesManagerService create(Context context) {
         RulesManagerServiceHelperImpl helper = new RulesManagerServiceHelperImpl(context);
         return new RulesManagerService(
                 helper /* permissionHelper */,
                 helper /* executor */,
-                helper /* fileDescriptorHelper */,
                 PackageTracker.create(context),
                 new TimeZoneDistroInstaller(TAG, SYSTEM_TZ_DATA_FILE, TZ_DATA_DIR));
     }
 
     // A constructor that can be used by tests to supply mocked / faked dependencies.
     RulesManagerService(PermissionHelper permissionHelper,
-            Executor executor,
-            FileDescriptorHelper fileDescriptorHelper, PackageTracker packageTracker,
+            Executor executor, PackageTracker packageTracker,
             TimeZoneDistroInstaller timeZoneDistroInstaller) {
         mPermissionHelper = permissionHelper;
         mExecutor = executor;
-        mFileDescriptorHelper = fileDescriptorHelper;
         mPackageTracker = packageTracker;
         mInstaller = timeZoneDistroInstaller;
     }
@@ -177,55 +175,78 @@
     }
 
     @Override
-    public int requestInstall(
-            ParcelFileDescriptor timeZoneDistro, byte[] checkTokenBytes, ICallback callback) {
-        mPermissionHelper.enforceCallerHasPermission(REQUIRED_UPDATER_PERMISSION);
+    public int requestInstall(ParcelFileDescriptor distroParcelFileDescriptor,
+            byte[] checkTokenBytes, ICallback callback) {
 
-        CheckToken checkToken = null;
-        if (checkTokenBytes != null) {
-            checkToken = createCheckTokenOrThrow(checkTokenBytes);
-        }
-        synchronized (this) {
-            if (timeZoneDistro == null) {
-                throw new NullPointerException("timeZoneDistro == null");
-            }
-            if (callback == null) {
-                throw new NullPointerException("observer == null");
-            }
-            if (mOperationInProgress.get()) {
-                return RulesManager.ERROR_OPERATION_IN_PROGRESS;
-            }
-            mOperationInProgress.set(true);
+        boolean closeParcelFileDescriptorOnExit = true;
+        try {
+            mPermissionHelper.enforceCallerHasPermission(REQUIRED_UPDATER_PERMISSION);
 
-            // Execute the install asynchronously.
-            mExecutor.execute(new InstallRunnable(timeZoneDistro, checkToken, callback));
+            CheckToken checkToken = null;
+            if (checkTokenBytes != null) {
+                checkToken = createCheckTokenOrThrow(checkTokenBytes);
+            }
 
-            return RulesManager.SUCCESS;
+            synchronized (this) {
+                if (distroParcelFileDescriptor == null) {
+                    throw new NullPointerException("distroParcelFileDescriptor == null");
+                }
+                if (callback == null) {
+                    throw new NullPointerException("observer == null");
+                }
+                if (mOperationInProgress.get()) {
+                    return RulesManager.ERROR_OPERATION_IN_PROGRESS;
+                }
+                mOperationInProgress.set(true);
+
+                // Execute the install asynchronously.
+                mExecutor.execute(
+                        new InstallRunnable(distroParcelFileDescriptor, checkToken, callback));
+
+                // The InstallRunnable now owns the ParcelFileDescriptor, so it will close it after
+                // it executes (and we do not have to).
+                closeParcelFileDescriptorOnExit = false;
+
+                return RulesManager.SUCCESS;
+            }
+        } finally {
+            // We should close() the local ParcelFileDescriptor we were passed if it hasn't been
+            // passed to another thread to handle.
+            if (distroParcelFileDescriptor != null && closeParcelFileDescriptorOnExit) {
+                try {
+                    distroParcelFileDescriptor.close();
+                } catch (IOException e) {
+                    Slog.w(TAG, "Failed to close distroParcelFileDescriptor", e);
+                }
+            }
         }
     }
 
     private class InstallRunnable implements Runnable {
 
-        private final ParcelFileDescriptor mTimeZoneDistro;
+        private final ParcelFileDescriptor mDistroParcelFileDescriptor;
         private final CheckToken mCheckToken;
         private final ICallback mCallback;
 
-        InstallRunnable(
-                ParcelFileDescriptor timeZoneDistro, CheckToken checkToken, ICallback callback) {
-            mTimeZoneDistro = timeZoneDistro;
+        InstallRunnable(ParcelFileDescriptor distroParcelFileDescriptor, CheckToken checkToken,
+                ICallback callback) {
+            mDistroParcelFileDescriptor = distroParcelFileDescriptor;
             mCheckToken = checkToken;
             mCallback = callback;
         }
 
         @Override
         public void run() {
+            boolean success = false;
             // Adopt the ParcelFileDescriptor into this try-with-resources so it is closed
             // when we are done.
-            boolean success = false;
-            try {
-                byte[] distroBytes =
-                        RulesManagerService.this.mFileDescriptorHelper.readFully(mTimeZoneDistro);
-                TimeZoneDistro distro = new TimeZoneDistro(distroBytes);
+            try (ParcelFileDescriptor pfd = mDistroParcelFileDescriptor) {
+                // The ParcelFileDescriptor owns the underlying FileDescriptor and we'll close
+                // it at the end of the try-with-resources.
+                final boolean isFdOwner = false;
+                InputStream is = new FileInputStream(pfd.getFileDescriptor(), isFdOwner);
+
+                TimeZoneDistro distro = new TimeZoneDistro(is);
                 int installerResult = mInstaller.stageInstallWithErrorCode(distro);
                 int resultCode = mapInstallerResultToApiCode(installerResult);
                 sendFinishedStatus(mCallback, resultCode);
diff --git a/services/core/java/com/android/server/timezone/RulesManagerServiceHelperImpl.java b/services/core/java/com/android/server/timezone/RulesManagerServiceHelperImpl.java
index 15a571d..482d8e2 100644
--- a/services/core/java/com/android/server/timezone/RulesManagerServiceHelperImpl.java
+++ b/services/core/java/com/android/server/timezone/RulesManagerServiceHelperImpl.java
@@ -27,8 +27,7 @@
 /**
  * A single class that implements multiple helper interfaces for use by {@link RulesManagerService}.
  */
-final class RulesManagerServiceHelperImpl
-        implements PermissionHelper, Executor, FileDescriptorHelper {
+final class RulesManagerServiceHelperImpl implements PermissionHelper, Executor {
 
     private final Context mContext;
 
@@ -47,13 +46,4 @@
         // TODO Is there a better way?
         new Thread(runnable).start();
     }
-
-    @Override
-    public byte[] readFully(ParcelFileDescriptor parcelFileDescriptor) throws IOException {
-        try (ParcelFileDescriptor pfd = parcelFileDescriptor) {
-            // Read bytes
-            FileInputStream in = new FileInputStream(pfd.getFileDescriptor(), false /* isOwner */);
-            return Streams.readFully(in);
-        }
-    }
 }
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 35e4e58..c07bd8e 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -345,7 +345,7 @@
                             + "of user " + userInfo.id + "can unlock user profile.");
                 }
 
-                if (!StorageManager.isUserKeyUnlocked(userInfo.id)
+                if (!mUserManager.isUserUnlockingOrUnlocked(userInfo.id)
                         && !directUnlock) {
                     if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
                             + "'s trust agent " + name + ": FBE still locked and "
diff --git a/services/core/java/com/android/server/vr/Vr2dDisplay.java b/services/core/java/com/android/server/vr/Vr2dDisplay.java
index 4a1297f..8335243 100644
--- a/services/core/java/com/android/server/vr/Vr2dDisplay.java
+++ b/services/core/java/com/android/server/vr/Vr2dDisplay.java
@@ -266,6 +266,7 @@
             }
 
             int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH;
+            flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT;
             mVirtualDisplay = mDisplayManager.createVirtualDisplay(null /* projection */,
                     DISPLAY_NAME, mVirtualDisplayWidth, mVirtualDisplayHeight, mVirtualDisplayDpi,
                     null /* surface */, flags, null /* callback */, null /* handler */,
diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java
index fe74947..5f34c60 100644
--- a/services/core/java/com/android/server/wm/AppWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java
@@ -614,8 +614,8 @@
             return STARTING_WINDOW_TYPE_SPLASH_SCREEN;
         } else if (taskSwitch && allowTaskSnapshot) {
             return snapshot == null ? STARTING_WINDOW_TYPE_NONE
-                    : snapshotFillsWidth(snapshot) || fromRecents ? STARTING_WINDOW_TYPE_SNAPSHOT
-                    : STARTING_WINDOW_TYPE_SPLASH_SCREEN;
+                    : snapshotOrientationSameAsDisplay(snapshot) || fromRecents
+                            ? STARTING_WINDOW_TYPE_SNAPSHOT : STARTING_WINDOW_TYPE_SPLASH_SCREEN;
         } else {
             return STARTING_WINDOW_TYPE_NONE;
         }
@@ -640,7 +640,7 @@
         return true;
     }
 
-    private boolean snapshotFillsWidth(TaskSnapshot snapshot) {
+    private boolean snapshotOrientationSameAsDisplay(TaskSnapshot snapshot) {
         if (snapshot == null) {
             return false;
         }
@@ -655,7 +655,9 @@
         mService.mPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight,
                 stableInsets);
         displayBounds.inset(stableInsets);
-        return rect.width() >= displayBounds.width();
+        final boolean snapshotInLandscape = rect.width() >= rect.height();
+        final boolean displayInLandscape = displayBounds.width() >= displayBounds.height();
+        return snapshotInLandscape == displayInLandscape;
     }
 
     public void removeStartingWindow() {
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 2d7fc68..6b51455 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -427,8 +427,9 @@
                 inputMethodManagerInternal.hideCurrentInputMethod();
                 mImeHideRequested = true;
             }
+            return;
         }
-        setMinimizedDockedStack(false, false /* animate */);
+        setMinimizedDockedStack(false /* minimizedDock */, false /* animate */);
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 091e1cb..22b0f5b 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -18,6 +18,7 @@
 
 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
 import static android.view.WindowManager.LayoutParams.isSystemAlertWindowType;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG;
@@ -37,6 +38,7 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.Trace;
 import android.os.UserHandle;
 import android.util.MergedConfiguration;
 import android.util.Slog;
@@ -85,6 +87,7 @@
     private boolean mClientDead = false;
     private float mLastReportedAnimatorScale;
     private String mPackageName;
+    private String mRelayoutTag;
 
     public Session(WindowManagerService service, IWindowSessionCallback callback,
             IInputMethodClient client, IInputContext inputContext) {
@@ -224,10 +227,12 @@
             MergedConfiguration mergedConfiguration, Surface outSurface) {
         if (false) Slog.d(TAG_WM, ">>>>>> ENTERED relayout from "
                 + Binder.getCallingPid());
+        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, mRelayoutTag);
         int res = mService.relayoutWindow(this, window, seq, attrs,
                 requestedWidth, requestedHeight, viewFlags, flags,
                 outFrame, outOverscanInsets, outContentInsets, outVisibleInsets,
                 outStableInsets, outsets, outBackdropFrame, mergedConfiguration, outSurface);
+        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
         if (false) Slog.d(TAG_WM, "<<<<<< EXITING relayout to "
                 + Binder.getCallingPid());
         return res;
@@ -575,6 +580,7 @@
 
     void windowAddedLocked(String packageName) {
         mPackageName = packageName;
+        mRelayoutTag = "relayoutWindow: " + mPackageName;
         if (mSurfaceSession == null) {
             if (WindowManagerService.localLOGV) Slog.v(
                 TAG_WM, "First window added to " + this + ", creating SurfaceSession");
@@ -698,6 +704,7 @@
                 pw.print(" mAlertWindowSurfaces="); pw.print(mAlertWindowSurfaces);
                 pw.print(" mClientDead="); pw.print(mClientDead);
                 pw.print(" mSurfaceSession="); pw.println(mSurfaceSession);
+        pw.print(prefix); pw.print("mPackageName="); pw.println(mPackageName);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
index 297e288..b628869 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
@@ -25,6 +25,7 @@
 import android.graphics.Bitmap;
 import android.graphics.Bitmap.CompressFormat;
 import android.graphics.Bitmap.Config;
+import android.graphics.GraphicBuffer;
 import android.os.Process;
 import android.os.SystemClock;
 import android.util.ArraySet;
@@ -325,6 +326,15 @@
             final File file = getBitmapFile(mTaskId, mUserId);
             final File reducedFile = getReducedResolutionBitmapFile(mTaskId, mUserId);
             final Bitmap bitmap = Bitmap.createHardwareBitmap(mSnapshot.getSnapshot());
+            if (bitmap == null) {
+                Slog.e(TAG, "Invalid task snapshot");
+                return false;
+            } else if (bitmap.getWidth() == 0 || bitmap.getHeight() == 0) {
+                Slog.e(TAG, "Invalid task snapshot dimensions " + bitmap.getWidth() + "x"
+                        + bitmap.getHeight());
+                return false;
+            }
+
             final Bitmap swBitmap = bitmap.copy(Config.ARGB_8888, false /* isMutable */);
             final Bitmap reduced = Bitmap.createScaledBitmap(swBitmap,
                     (int) (bitmap.getWidth() * REDUCED_SCALE),
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 0c2ca85..a95a0cf 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -30,6 +30,7 @@
 import static android.os.Process.SYSTEM_UID;
 import static android.os.Process.THREAD_PRIORITY_DISPLAY;
 import static android.os.Process.myPid;
+import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 import static android.os.UserHandle.USER_NULL;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
@@ -892,11 +893,16 @@
     }
 
     void openSurfaceTransaction() {
-        synchronized (mWindowMap) {
-            if (mRoot.mSurfaceTraceEnabled) {
-                mRoot.mRemoteEventTrace.openSurfaceTransaction();
+        try {
+            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "openSurfaceTransaction");
+            synchronized (mWindowMap) {
+                if (mRoot.mSurfaceTraceEnabled) {
+                    mRoot.mRemoteEventTrace.openSurfaceTransaction();
+                }
+                SurfaceControl.openTransaction();
             }
-            SurfaceControl.openTransaction();
+        } finally {
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
         }
     }
 
@@ -912,16 +918,21 @@
      *                     blocks and we call it repeatedly, like we do for animations.
      */
     void closeSurfaceTransaction(boolean withLockHeld) {
-        synchronized (mWindowMap) {
-            if (mRoot.mSurfaceTraceEnabled) {
-                mRoot.mRemoteEventTrace.closeSurfaceTransaction();
+        try {
+            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "closeSurfaceTransaction");
+            synchronized (mWindowMap) {
+                if (mRoot.mSurfaceTraceEnabled) {
+                    mRoot.mRemoteEventTrace.closeSurfaceTransaction();
+                }
+                if (withLockHeld) {
+                    SurfaceControl.closeTransaction();
+                }
             }
-            if (withLockHeld) {
+            if (!withLockHeld) {
                 SurfaceControl.closeTransaction();
             }
-        }
-        if (!withLockHeld) {
-            SurfaceControl.closeTransaction();
+        } finally {
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
         }
     }
 
@@ -1996,6 +2007,8 @@
                     (win.mAppToken == null || win.mAttrs.type == TYPE_APPLICATION_STARTING
                             || !win.mAppToken.isClientHidden())) {
 
+                Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: viewVisibility_1");
+
                 // We are about to create a surface, but we didn't run a layout yet. So better run
                 // a layout now that we already know the right size, as a resize call will make the
                 // surface transaction blocking until next vsync and slow us down.
@@ -2007,6 +2020,7 @@
                 }
                 result = win.relayoutVisibleWindow(mergedConfiguration, result, attrChanges,
                         oldVisibility);
+
                 try {
                     result = createSurfaceControl(outSurface, result, win, winAnimator);
                 } catch (Exception e) {
@@ -2026,7 +2040,10 @@
                     imMayMove = true;
                 }
                 win.adjustStartingWindowFlags();
+                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
             } else {
+                Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: viewVisibility_2");
+
                 winAnimator.mEnterAnimationPending = false;
                 winAnimator.mEnteringAnimation = false;
                 final boolean usingSavedSurfaceBeforeVisible =
@@ -2061,18 +2078,22 @@
                     // We already told the client to go invisible, but the message may not be
                     // handled yet, or it might want to draw a last frame. If we already have a
                     // surface, let the client use that, but don't create new surface at this point.
+                    Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: getSurface");
                     winAnimator.mSurfaceController.getSurface(outSurface);
+                    Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
                 } else {
                     if (DEBUG_VISIBILITY) Slog.i(TAG_WM, "Releasing surface in: " + win);
 
                     try {
-                        Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmReleaseOutSurface_"
+                        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "wmReleaseOutSurface_"
                                 + win.mAttrs.getTitle());
                         outSurface.release();
                     } finally {
-                        Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
+                        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
                     }
                 }
+
+                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
             }
 
             if (focusMayChange) {
@@ -2109,8 +2130,11 @@
             }
 
             win.setDisplayLayoutNeeded();
-            win.mGivenInsetsPending = (flags&WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;
+            win.mGivenInsetsPending = (flags & WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;
+            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
+                    "relayoutWindow: updateOrientationFromAppTokens");
             configChanged = updateOrientationFromAppTokensLocked(false, displayId);
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
 
             // We may be deferring layout passes at the moment, but since the client is interested
             // in the new out values right now we need to force a layout.
@@ -2163,7 +2187,9 @@
         }
 
         if (configChanged) {
+            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: sendNewConfiguration");
             sendNewConfiguration(displayId);
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
         }
         Binder.restoreCallingIdentity(origId);
         return result;
@@ -2224,8 +2250,14 @@
         if (!win.mHasSurface) {
             result |= RELAYOUT_RES_SURFACE_CHANGED;
         }
-        WindowSurfaceController surfaceController = winAnimator.createSurfaceLocked(
-            win.mAttrs.type, win.mOwnerUid);
+
+        WindowSurfaceController surfaceController;
+        try {
+            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "createSurfaceControl");
+            surfaceController = winAnimator.createSurfaceLocked(win.mAttrs.type, win.mOwnerUid);
+        } finally {
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+        }
         if (surfaceController != null) {
             surfaceController.getSurface(outSurface);
             if (SHOW_TRANSACTIONS) Slog.i(TAG_WM, "  OUT SURFACE " + outSurface + ": copied");
@@ -2235,6 +2267,7 @@
             Slog.w(TAG_WM, "Failed to create surface control for " + win);
             outSurface.release();
         }
+
         return result;
     }
 
@@ -2281,7 +2314,7 @@
         // frozen, there is no reason to animate and it can cause strange
         // artifacts when we unfreeze the display if some different animation
         // is running.
-        Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "WM#applyAnimationLocked");
+        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "WM#applyAnimationLocked");
         if (okToDisplay()) {
             final DisplayContent displayContent = atoken.getTask().getDisplayContent();
             final DisplayInfo displayInfo = displayContent.getDisplayInfo();
@@ -2337,7 +2370,7 @@
         } else {
             atoken.mAppAnimator.clearAnimation();
         }
-        Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
+        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
 
         return atoken.mAppAnimator.animation != null;
     }
@@ -2915,9 +2948,10 @@
     }
 
     public void setKeyguardGoingAway(boolean keyguardGoingAway) {
-        synchronized (mWindowMap) {
-            mKeyguardGoingAway = keyguardGoingAway;
-        }
+// TODO: Use of this can be removed. Revert ag/I8369723d6a77f2c602f1ef080371fa7cd9ee094e
+//        synchronized (mWindowMap) {
+//            mKeyguardGoingAway = keyguardGoingAway;
+//        }
     }
 
     // -------------------------------------------------------------
@@ -3424,7 +3458,7 @@
 
             if (!mBootAnimationStopped) {
                 // Do this one time.
-                Trace.asyncTraceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
+                Trace.asyncTraceBegin(TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
                 try {
                     IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
                     if (surfaceFlinger != null) {
@@ -3447,7 +3481,7 @@
             }
 
             EventLog.writeEvent(EventLogTags.WM_BOOT_ANIMATION_DONE, SystemClock.uptimeMillis());
-            Trace.asyncTraceEnd(Trace.TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
+            Trace.asyncTraceEnd(TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
             mDisplayEnabled = true;
             if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG_WM, "******************** ENABLING SCREEN!");
 
@@ -3678,12 +3712,12 @@
             throw new SecurityException("Requires READ_FRAME_BUFFER permission");
         }
         try {
-            Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "screenshotWallpaper");
+            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "screenshotWallpaper");
             return screenshotApplications(null /* appToken */, DEFAULT_DISPLAY, -1 /* width */,
                     -1 /* height */, true /* includeFullDisplay */, 1f /* frameScale */,
                     Bitmap.Config.ARGB_8888, true /* wallpaperOnly */, false /* includeDecor */);
         } finally {
-            Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
         }
     }
 
@@ -3869,6 +3903,8 @@
                 + " alwaysSendConfiguration=" + alwaysSendConfiguration
                 + " forceRelayout=" + forceRelayout);
 
+        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "updateRotation");
+
         long origId = Binder.clearCallingIdentity();
 
         try {
@@ -3877,20 +3913,28 @@
             final int displayId;
             synchronized (mWindowMap) {
                 final DisplayContent displayContent = getDefaultDisplayContentLocked();
+                Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "updateRotation: display");
                 rotationChanged = displayContent.updateRotationUnchecked(
                         false /* inTransaction */);
+                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
                 if (!rotationChanged || forceRelayout) {
                     displayContent.setLayoutNeeded();
+                    Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
+                            "updateRotation: performSurfacePlacement");
                     mWindowPlacerLocked.performSurfacePlacement();
+                    Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
                 }
                 displayId = displayContent.getDisplayId();
             }
 
             if (rotationChanged || alwaysSendConfiguration) {
+                Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "updateRotation: sendNewConfiguration");
                 sendNewConfiguration(displayId);
+                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
             }
         } finally {
             Binder.restoreCallingIdentity(origId);
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
         }
     }
 
@@ -5855,7 +5899,7 @@
     boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
         WindowState newFocus = mRoot.computeFocusedWindow();
         if (mCurrentFocus != newFocus) {
-            Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmUpdateFocus");
+            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "wmUpdateFocus");
             // This check makes sure that we don't already have the focus
             // change message pending.
             mH.removeMessages(H.REPORT_FOCUS_CHANGE);
@@ -5931,7 +5975,7 @@
             // other apps' UI.
             displayContent.scheduleToastWindowsTimeoutIfNeededLocked(oldFocus, newFocus);
 
-            Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
             return true;
         }
         return false;
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index edbdf8b..27927e6 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
@@ -33,6 +34,7 @@
 import android.graphics.Region;
 import android.os.IBinder;
 import android.os.Debug;
+import android.os.Trace;
 import android.view.Surface;
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
@@ -101,8 +103,10 @@
             mSurfaceControl = new SurfaceTrace(
                     s, name, w, h, format, flags, windowType, ownerUid);
         } else {
+            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "new SurfaceControl");
             mSurfaceControl = new SurfaceControl(
                     s, name, w, h, format, flags, windowType, ownerUid);
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
         }
 
         if (mService.mRoot.mSurfaceTraceEnabled) {
diff --git a/services/core/jni/Android.mk b/services/core/jni/Android.mk
index 3c5779e..fdcf9df 100644
--- a/services/core/jni/Android.mk
+++ b/services/core/jni/Android.mk
@@ -56,6 +56,7 @@
 LOCAL_SHARED_LIBRARIES += \
     libandroid_runtime \
     libandroidfw \
+    libaudioclient \
     libbase \
     libappfuse \
     libbinder \
diff --git a/services/core/jni/NativeCallbackThread.cpp b/services/core/jni/NativeCallbackThread.cpp
index 7d668e3..0c84e6d 100644
--- a/services/core/jni/NativeCallbackThread.cpp
+++ b/services/core/jni/NativeCallbackThread.cpp
@@ -107,10 +107,15 @@
         mQueueCond.signal();
     }
 
-    auto ret = pthread_join(mThread, nullptr);
-    ALOGE_IF(ret != 0, "Couldn't join thread: %d", ret);
+    if (pthread_self() == mThread) {
+        // you can't self-join a thread, but it's ok when calling from our sub-task
+        ALOGD("About to stop native callback thread %p", this);
+    } else {
+        auto ret = pthread_join(mThread, nullptr);
+        ALOGE_IF(ret != 0, "Couldn't join thread: %d", ret);
 
-    ALOGD("Stopped native callback thread %p", this);
+        ALOGD("Stopped native callback thread %p", this);
+    }
 }
 
 } // namespace android
diff --git a/services/core/jni/com_android_server_power_PowerManagerService.cpp b/services/core/jni/com_android_server_power_PowerManagerService.cpp
index c722629..86c5e99 100644
--- a/services/core/jni/com_android_server_power_PowerManagerService.cpp
+++ b/services/core/jni/com_android_server_power_PowerManagerService.cpp
@@ -157,8 +157,10 @@
 static void nativeSetInteractive(JNIEnv* /* env */, jclass /* clazz */, jboolean enable) {
     std::lock_guard<std::mutex> lock(gPowerHalMutex);
     if (getPowerHal()) {
-        String8 err("Excessive delay in setInteractive(%s) while turning screen %s");
-        ALOGD_IF_SLOW(20, String8::format(err, enable ? "true" : "false", enable ? "on" : "off"));
+        String8 err = String8::format(
+                "Excessive delay in setInteractive(%s) while turning screen %s",
+                enable ? "true" : "false", enable ? "on" : "off");
+        ALOGD_IF_SLOW(20, err);
         Return<void> ret = gPowerHal->setInteractive(enable);
         processReturn(ret, "setInteractive");
     }
diff --git a/services/core/jni/com_android_server_radio_RadioService.cpp b/services/core/jni/com_android_server_radio_RadioService.cpp
index 2e0fbfd..fa64901 100644
--- a/services/core/jni/com_android_server_radio_RadioService.cpp
+++ b/services/core/jni/com_android_server_radio_RadioService.cpp
@@ -199,10 +199,10 @@
 
     HalRevision halRev;
     if (V1_1::IBroadcastRadio::castFrom(module).withDefault(nullptr) != nullptr) {
-        ALOGI("Opening tuner with broadcast radio HAL 1.1");
+        ALOGI("Opening tuner %d with broadcast radio HAL 1.1", moduleId);
         halRev = HalRevision::V1_1;
     } else {
-        ALOGI("Opening tuner with broadcast radio HAL 1.0");
+        ALOGI("Opening tuner %d with broadcast radio HAL 1.0", moduleId);
         halRev = HalRevision::V1_0;
     }
 
@@ -233,7 +233,7 @@
     }
 
     Tuner::setHalTuner(env, tuner, halTuner);
-    ALOGI("Opened tuner %p", halTuner.get());
+    ALOGD("Opened tuner %p", halTuner.get());
     return tuner.release();
 }
 
diff --git a/services/core/jni/com_android_server_radio_Tuner.cpp b/services/core/jni/com_android_server_radio_Tuner.cpp
index 2819e12..4b6f30b 100644
--- a/services/core/jni/com_android_server_radio_Tuner.cpp
+++ b/services/core/jni/com_android_server_radio_Tuner.cpp
@@ -23,7 +23,9 @@
 #include "com_android_server_radio_TunerCallback.h"
 
 #include <android/hardware/broadcastradio/1.1/IBroadcastRadioFactory.h>
+#include <binder/IPCThreadState.h>
 #include <core_jni_helpers.h>
+#include <media/AudioSystem.h>
 #include <utils/Log.h>
 #include <JNIHelp.h>
 
@@ -33,6 +35,7 @@
 namespace Tuner {
 
 using hardware::Return;
+using hardware::hidl_death_recipient;
 using hardware::hidl_vec;
 
 namespace V1_0 = hardware::broadcastradio::V1_0;
@@ -59,12 +62,26 @@
     } Tuner;
 } gjni;
 
+static const char* const kAudioDeviceName = "Radio tuner source";
+
+class HalDeathRecipient : public hidl_death_recipient {
+    wp<V1_1::ITunerCallback> mTunerCallback;
+
+public:
+    HalDeathRecipient(wp<V1_1::ITunerCallback> tunerCallback):mTunerCallback(tunerCallback) {}
+
+    virtual void serviceDied(uint64_t cookie, const wp<hidl::base::V1_0::IBase>& who);
+};
+
 struct TunerContext {
     TunerContext() {}
 
+    bool mIsClosed = false;
     HalRevision mHalRev;
+    bool mWithAudio;
     sp<V1_0::ITuner> mHalTuner;
     sp<V1_1::ITuner> mHalTuner11;
+    sp<HalDeathRecipient> mHalDeathRecipient;
 
 private:
     DISALLOW_COPY_AND_ASSIGN(TunerContext);
@@ -83,12 +100,13 @@
     return getNativeContext(env->GetLongField(jTuner.get(), gjni.Tuner.nativeContext));
 }
 
-static jlong nativeInit(JNIEnv *env, jobject obj, jint halRev) {
+static jlong nativeInit(JNIEnv *env, jobject obj, jint halRev, bool withAudio) {
     ALOGV("nativeInit()");
     AutoMutex _l(gContextMutex);
 
     auto ctx = new TunerContext();
     ctx->mHalRev = static_cast<HalRevision>(halRev);
+    ctx->mWithAudio = withAudio;
 
     static_assert(sizeof(jlong) >= sizeof(ctx), "jlong is smaller than a pointer");
     return reinterpret_cast<jlong>(ctx);
@@ -102,6 +120,28 @@
     delete ctx;
 }
 
+void HalDeathRecipient::serviceDied(uint64_t cookie __unused,
+        const wp<hidl::base::V1_0::IBase>& who __unused) {
+    ALOGW("HAL Tuner died unexpectedly");
+
+    auto tunerCallback = mTunerCallback.promote();
+    if (tunerCallback == nullptr) return;
+
+    tunerCallback->hardwareFailure();
+}
+
+// TODO(b/62713378): implement support for multiple tuners open at the same time
+static void notifyAudioService(TunerContext& ctx, bool connected) {
+    if (!ctx.mWithAudio) return;
+
+    ALOGD("Notifying AudioService about new state: %d", connected);
+    auto token = IPCThreadState::self()->clearCallingIdentity();
+    AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_IN_FM_TUNER,
+            connected ? AUDIO_POLICY_DEVICE_STATE_AVAILABLE : AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
+            nullptr, kAudioDeviceName);
+    IPCThreadState::self()->restoreCallingIdentity(token);
+}
+
 void setHalTuner(JNIEnv *env, JavaRef<jobject> const &jTuner, sp<V1_0::ITuner> halTuner) {
     ALOGV("setHalTuner(%p)", halTuner.get());
     ALOGE_IF(halTuner == nullptr, "HAL tuner is a nullptr");
@@ -109,10 +149,25 @@
     AutoMutex _l(gContextMutex);
     auto& ctx = getNativeContext(env, jTuner);
 
+    if (ctx.mIsClosed) {
+        ALOGD("Tuner was closed during initialization");
+        // dropping the last reference will close HAL tuner
+        return;
+    }
+    if (ctx.mHalTuner != nullptr) {
+        ALOGE("HAL tuner is already set.");
+        return;
+    }
+
     ctx.mHalTuner = halTuner;
     ctx.mHalTuner11 = V1_1::ITuner::castFrom(halTuner).withDefault(nullptr);
     ALOGW_IF(ctx.mHalRev >= HalRevision::V1_1 && ctx.mHalTuner11 == nullptr,
             "Provided tuner does not implement 1.1 HAL");
+
+    ctx.mHalDeathRecipient = new HalDeathRecipient(getNativeCallback(env, jTuner));
+    halTuner->linkToDeath(ctx.mHalDeathRecipient, 0);
+
+    notifyAudioService(ctx, true);
 }
 
 sp<V1_0::ITuner> getHalTuner(jlong nativeContext) {
@@ -139,8 +194,21 @@
 static void nativeClose(JNIEnv *env, jobject obj, jlong nativeContext) {
     AutoMutex _l(gContextMutex);
     auto& ctx = getNativeContext(nativeContext);
-    if (ctx.mHalTuner == nullptr) return;
+    if (ctx.mIsClosed) return;
+    ctx.mIsClosed = true;
+
+    if (ctx.mHalTuner == nullptr) {
+        ALOGI("Tuner closed during initialization");
+        return;
+    }
+
     ALOGI("Closing tuner %p", ctx.mHalTuner.get());
+
+    notifyAudioService(ctx, false);
+
+    ctx.mHalTuner->unlinkToDeath(ctx.mHalDeathRecipient);
+    ctx.mHalDeathRecipient = nullptr;
+
     ctx.mHalTuner11 = nullptr;
     ctx.mHalTuner = nullptr;
 }
@@ -334,7 +402,7 @@
 }
 
 static const JNINativeMethod gTunerMethods[] = {
-    { "nativeInit", "(I)J", (void*)nativeInit },
+    { "nativeInit", "(IZ)J", (void*)nativeInit },
     { "nativeFinalize", "(J)V", (void*)nativeFinalize },
     { "nativeClose", "(J)V", (void*)nativeClose },
     { "nativeSetConfiguration", "(JLandroid/hardware/radio/RadioManager$BandConfig;)V",
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 136d335..8cac6e0 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -43,6 +43,7 @@
 import static android.app.admin.DevicePolicyManager.DELEGATION_PERMISSION_GRANT;
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
 import static android.app.admin.DevicePolicyManager.PROFILE_KEYGUARD_FEATURES_AFFECT_OWNER;
+import static android.app.admin.DevicePolicyManager.WIPE_EUICC;
 import static android.app.admin.DevicePolicyManager.WIPE_EXTERNAL_STORAGE;
 import static android.app.admin.DevicePolicyManager.WIPE_RESET_PROTECTION_DATA;
 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
@@ -1691,9 +1692,9 @@
             mContext.getSystemService(PowerManager.class).reboot(reason);
         }
 
-        void recoverySystemRebootWipeUserData(boolean shutdown, String reason, boolean force)
-                throws IOException {
-            RecoverySystem.rebootWipeUserData(mContext, shutdown, reason, force);
+        void recoverySystemRebootWipeUserData(boolean shutdown, String reason, boolean force,
+                boolean wipeEuicc) throws IOException {
+            RecoverySystem.rebootWipeUserData(mContext, shutdown, reason, force, wipeEuicc);
         }
 
         boolean systemPropertiesGetBoolean(String key, boolean def) {
@@ -5302,7 +5303,7 @@
         }
     }
 
-    private void forceWipeDeviceNoLock(boolean wipeExtRequested, String reason) {
+    private void forceWipeDeviceNoLock(boolean wipeExtRequested, String reason, boolean wipeEuicc) {
         wtfIfInLock();
 
         if (wipeExtRequested) {
@@ -5312,7 +5313,7 @@
         }
         try {
             mInjector.recoverySystemRebootWipeUserData(
-                    /*shutdown=*/ false, reason, /*force=*/ true);
+                    /*shutdown=*/ false, reason, /*force=*/ true, /*wipeEuicc=*/ wipeEuicc);
         } catch (IOException | SecurityException e) {
             Slog.w(LOG_TAG, "Failed requesting data wipe", e);
         }
@@ -5389,7 +5390,7 @@
             // removes that user (but still clears FRP...)
             if (userId == UserHandle.USER_SYSTEM) {
                 forceWipeDeviceNoLock(/*wipeExtRequested=*/ (flags & WIPE_EXTERNAL_STORAGE) != 0,
-                        reason);
+                        reason, /*wipeEuicc=*/ (flags & WIPE_EUICC) != 0);
             } else {
                 forceWipeUser(userId);
             }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java
index 70c7e58..6086354 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java
@@ -25,8 +25,8 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.SystemClock;
-import android.util.Log;
 import android.util.LongSparseArray;
+import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
 
@@ -60,16 +60,21 @@
     /** Delay after which older batches get discarded after a retrieval. */
     private static final long RETRIEVED_BATCH_DISCARD_DELAY_MS = 5 * 60 * 1000; // 5m
 
+    /** Do not call into mDpm with locks held */
     private final DevicePolicyManagerService mDpm;
     private final AlarmManager mAlarmManager;
 
     private final OnAlarmListener mBatchTimeoutAlarmListener = new OnAlarmListener() {
         @Override
         public void onAlarm() {
-            Log.d(TAG, "Received a batch finalization timeout alarm, finalizing "
+            Slog.d(TAG, "Received a batch finalization timeout alarm, finalizing "
                     + mNetworkEvents.size() + " pending events.");
+            Bundle notificationExtras = null;
             synchronized (NetworkLoggingHandler.this) {
-                finalizeBatchAndNotifyDeviceOwnerLocked();
+                notificationExtras = finalizeBatchAndBuildDeviceOwnerMessageLocked();
+            }
+            if (notificationExtras != null) {
+                notifyDeviceOwner(notificationExtras);
             }
         }
     };
@@ -110,17 +115,21 @@
             case LOG_NETWORK_EVENT_MSG: {
                 final NetworkEvent networkEvent = msg.getData().getParcelable(NETWORK_EVENT_KEY);
                 if (networkEvent != null) {
+                    Bundle notificationExtras = null;
                     synchronized (NetworkLoggingHandler.this) {
                         mNetworkEvents.add(networkEvent);
                         if (mNetworkEvents.size() >= MAX_EVENTS_PER_BATCH) {
-                            finalizeBatchAndNotifyDeviceOwnerLocked();
+                            notificationExtras = finalizeBatchAndBuildDeviceOwnerMessageLocked();
                         }
                     }
+                    if (notificationExtras != null) {
+                        notifyDeviceOwner(notificationExtras);
+                    }
                 }
                 break;
             }
             default: {
-                Log.d(TAG, "NetworkLoggingHandler received an unknown of message.");
+                Slog.d(TAG, "NetworkLoggingHandler received an unknown of message.");
                 break;
             }
         }
@@ -133,40 +142,48 @@
         mAlarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP, when,
                 BATCH_FINALIZATION_TIMEOUT_ALARM_INTERVAL_MS, NETWORK_LOGGING_TIMEOUT_ALARM_TAG,
                 mBatchTimeoutAlarmListener, this);
-        Log.d(TAG, "Scheduled a new batch finalization alarm " + BATCH_FINALIZATION_TIMEOUT_MS
+        Slog.d(TAG, "Scheduled a new batch finalization alarm " + BATCH_FINALIZATION_TIMEOUT_MS
                 + "ms from now.");
     }
 
     synchronized void pause() {
-        Log.d(TAG, "Paused network logging");
+        Slog.d(TAG, "Paused network logging");
         mPaused = true;
     }
 
-    synchronized void resume() {
-        if (!mPaused) {
-            Log.d(TAG, "Attempted to resume network logging, but logging is not paused.");
-            return;
+    void resume() {
+        Bundle notificationExtras = null;
+        synchronized (this) {
+            if (!mPaused) {
+                Slog.d(TAG, "Attempted to resume network logging, but logging is not paused.");
+                return;
+            }
+
+            Slog.d(TAG, "Resumed network logging. Current batch=" + mCurrentBatchToken
+                    + ", LastRetrievedBatch=" + mLastRetrievedBatchToken);
+            mPaused = false;
+
+            // If there is a batch ready that the device owner hasn't been notified about, do it now.
+            if (mBatches.size() > 0 && mLastRetrievedBatchToken != mCurrentBatchToken) {
+                scheduleBatchFinalization();
+                notificationExtras = buildDeviceOwnerMessageLocked();
+            }
         }
-
-        Log.d(TAG, "Resumed network logging. Current batch=" + mCurrentBatchToken
-                + ", LastRetrievedBatch=" + mLastRetrievedBatchToken);
-        mPaused = false;
-
-        // If there is a batch ready that the device owner hasn't been notified about, do it now.
-        if (mBatches.size() > 0 && mLastRetrievedBatchToken != mCurrentBatchToken) {
-            scheduleBatchFinalization();
-            notifyDeviceOwnerLocked();
+        if (notificationExtras != null) {
+            notifyDeviceOwner(notificationExtras);
         }
     }
 
     synchronized void discardLogs() {
         mBatches.clear();
         mNetworkEvents = new ArrayList<>();
-        Log.d(TAG, "Discarded all network logs");
+        Slog.d(TAG, "Discarded all network logs");
     }
 
     @GuardedBy("this")
-    private void finalizeBatchAndNotifyDeviceOwnerLocked() {
+    /** @returns extras if a message should be sent to the device owner */
+    private Bundle finalizeBatchAndBuildDeviceOwnerMessageLocked() {
+        Bundle notificationExtras = null;
         if (mNetworkEvents.size() > 0) {
             // Finalize the batch and start a new one from scratch.
             if (mBatches.size() >= MAX_BATCHES) {
@@ -177,27 +194,39 @@
             mBatches.append(mCurrentBatchToken, mNetworkEvents);
             mNetworkEvents = new ArrayList<>();
             if (!mPaused) {
-                notifyDeviceOwnerLocked();
+                notificationExtras = buildDeviceOwnerMessageLocked();
             }
         } else {
             // Don't notify the DO, since there are no events; DPC can still retrieve
             // the last full batch if not paused.
-            Log.d(TAG, "Was about to finalize the batch, but there were no events to send to"
+            Slog.d(TAG, "Was about to finalize the batch, but there were no events to send to"
                     + " the DPC, the batchToken of last available batch: " + mCurrentBatchToken);
         }
         // Regardless of whether the batch was non-empty schedule a new finalization after timeout.
         scheduleBatchFinalization();
+        return notificationExtras;
     }
 
-    /** Sends a notification to the DO. Should only be called when there is a batch available. */
     @GuardedBy("this")
-    private void notifyDeviceOwnerLocked() {
+    /** Build extras notification to the DO. Should only be called when there
+        is a batch available. */
+    private Bundle buildDeviceOwnerMessageLocked() {
         final Bundle extras = new Bundle();
         final int lastBatchSize = mBatches.valueAt(mBatches.size() - 1).size();
         extras.putLong(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_TOKEN, mCurrentBatchToken);
         extras.putInt(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_COUNT, lastBatchSize);
-        Log.d(TAG, "Sending network logging batch broadcast to device owner, batchToken: "
-                + mCurrentBatchToken);
+        return extras;
+    }
+
+    /** Sends a notification to the DO. Should not hold locks as DevicePolicyManagerService may
+        call into NetworkLoggingHandler. */
+    private void notifyDeviceOwner(Bundle extras) {
+        Slog.d(TAG, "Sending network logging batch broadcast to device owner, batchToken: "
+                + extras.getLong(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_TOKEN, -1));
+        if (Thread.holdsLock(this)) {
+            Slog.wtfStack(TAG, "Shouldn't be called with NetworkLoggingHandler lock held");
+            return;
+        }
         mDpm.sendDeviceOwnerCommand(DeviceAdminReceiver.ACTION_NETWORK_LOGS_AVAILABLE, extras);
     }
 
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index d5e1993..ed52326 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -189,6 +189,8 @@
             "com.google.android.clockwork.connectivity.WearConnectivityService";
     private static final String WEAR_DISPLAY_SERVICE_CLASS =
             "com.google.android.clockwork.display.WearDisplayService";
+    private static final String WEAR_LEFTY_SERVICE_CLASS =
+            "com.google.android.clockwork.lefty.WearLeftyService";
     private static final String WEAR_TIME_SERVICE_CLASS =
             "com.google.android.clockwork.time.WearTimeService";
     private static final String ACCOUNT_SERVICE_CLASS =
@@ -701,8 +703,7 @@
         boolean disableVrManager = SystemProperties.getBoolean("config.disable_vrmanager", false);
         boolean disableCameraService = SystemProperties.getBoolean("config.disable_cameraservice",
                 false);
-        // TODO(b/36863239): Remove when transitioned from native service.
-        boolean enableRadioService = SystemProperties.getBoolean("config.enable_java_radio", false);
+        boolean enableLeftyService = SystemProperties.getBoolean("config.enable_lefty", false);
 
         boolean isEmulator = SystemProperties.get("ro.kernel.qemu").equals("1");
 
@@ -1203,8 +1204,7 @@
             mSystemServiceManager.startService(AudioService.Lifecycle.class);
             traceEnd();
 
-            if (enableRadioService &&
-                    mPackageManager.hasSystemFeature(PackageManager.FEATURE_RADIO)) {
+            if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_RADIO)) {
                 traceBeginAndSlog("StartRadioService");
                 mSystemServiceManager.startService(RadioService.class);
                 traceEnd();
@@ -1498,6 +1498,12 @@
                 mSystemServiceManager.startService(WEAR_DISPLAY_SERVICE_CLASS);
                 mSystemServiceManager.startService(WEAR_TIME_SERVICE_CLASS);
                 traceEnd();
+
+                if (enableLeftyService) {
+                    traceBeginAndSlog("StartWearLeftyService");
+                    mSystemServiceManager.startService(WEAR_LEFTY_SERVICE_CLASS);
+                    traceEnd();
+                }
             }
         }
 
diff --git a/services/net/java/android/net/ip/IpManager.java b/services/net/java/android/net/ip/IpManager.java
index ede2b3a..a94536c 100644
--- a/services/net/java/android/net/ip/IpManager.java
+++ b/services/net/java/android/net/ip/IpManager.java
@@ -20,16 +20,17 @@
 import com.android.internal.util.WakeupMessage;
 
 import android.content.Context;
-import android.net.apf.ApfCapabilities;
-import android.net.apf.ApfFilter;
 import android.net.DhcpResults;
+import android.net.INetd;
 import android.net.InterfaceConfiguration;
 import android.net.LinkAddress;
-import android.net.LinkProperties;
 import android.net.LinkProperties.ProvisioningChange;
+import android.net.LinkProperties;
 import android.net.ProxyInfo;
 import android.net.RouteInfo;
 import android.net.StaticIpConfiguration;
+import android.net.apf.ApfCapabilities;
+import android.net.apf.ApfFilter;
 import android.net.dhcp.DhcpClient;
 import android.net.metrics.IpConnectivityLog;
 import android.net.metrics.IpManagerEvent;
@@ -38,7 +39,9 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.ServiceSpecificException;
 import android.os.SystemClock;
+import android.system.OsConstants;
 import android.text.TextUtils;
 import android.util.LocalLog;
 import android.util.Log;
@@ -319,6 +322,16 @@
                 return this;
             }
 
+            public Builder withIPv6AddrGenModeEUI64() {
+                mConfig.mIPv6AddrGenMode = INetd.IPV6_ADDR_GEN_MODE_EUI64;
+                return this;
+            }
+
+            public Builder withIPv6AddrGenModeStablePrivacy() {
+                mConfig.mIPv6AddrGenMode = INetd.IPV6_ADDR_GEN_MODE_STABLE_PRIVACY;
+                return this;
+            }
+
             public ProvisioningConfiguration build() {
                 return new ProvisioningConfiguration(mConfig);
             }
@@ -331,6 +344,7 @@
         /* package */ StaticIpConfiguration mStaticIpConfig;
         /* package */ ApfCapabilities mApfCapabilities;
         /* package */ int mProvisioningTimeoutMs = DEFAULT_TIMEOUT_MS;
+        /* package */ int mIPv6AddrGenMode = INetd.IPV6_ADDR_GEN_MODE_STABLE_PRIVACY;
 
         public ProvisioningConfiguration() {}
 
@@ -354,6 +368,7 @@
                     .add("mStaticIpConfig: " + mStaticIpConfig)
                     .add("mApfCapabilities: " + mApfCapabilities)
                     .add("mProvisioningTimeoutMs: " + mProvisioningTimeoutMs)
+                    .add("mIPv6AddrGenMode: " + mIPv6AddrGenMode)
                     .toString();
         }
     }
@@ -699,7 +714,6 @@
         return shouldLog;
     }
 
-    // TODO: Migrate all Log.e(...) to logError(...).
     private void logError(String fmt, Object... args) {
         final String msg = "ERROR " + String.format(fmt, args);
         Log.e(mTag, msg);
@@ -1020,7 +1034,7 @@
     }
 
     private void doImmediateProvisioningFailure(int failureType) {
-        if (DBG) { Log.e(mTag, "onProvisioningFailure(): " + failureType); }
+        logError("onProvisioningFailure(): %s", failureType);
         recordMetric(failureType);
         mCallback.onProvisioningFailure(new LinkProperties(mLinkProperties));
     }
@@ -1044,16 +1058,25 @@
         return true;
     }
 
+    private void setIPv6AddrGenModeIfSupported() throws RemoteException {
+        try {
+            mNwService.setIPv6AddrGenMode(mInterfaceName, mConfiguration.mIPv6AddrGenMode);
+        } catch (ServiceSpecificException e) {
+            if (e.errorCode != OsConstants.EOPNOTSUPP) {
+                throw e;
+            }
+        }
+    }
+
     private boolean startIPv6() {
         // Set privacy extensions.
         try {
             mNwService.setInterfaceIpv6PrivacyExtensions(mInterfaceName, true);
+
+            setIPv6AddrGenModeIfSupported();
             mNwService.enableIpv6(mInterfaceName);
-        } catch (RemoteException re) {
-            logError("Unable to change interface settings: %s", re);
-            return false;
-        } catch (IllegalStateException ie) {
-            logError("Unable to change interface settings: %s", ie);
+        } catch (IllegalStateException | RemoteException | ServiceSpecificException e) {
+            logError("Unable to change interface settings: %s", e);
             return false;
         }
 
@@ -1146,7 +1169,7 @@
 
                 case DhcpClient.CMD_ON_QUIT:
                     // Everything is already stopped.
-                    Log.e(mTag, "Unexpected CMD_ON_QUIT (already stopped).");
+                    logError("Unexpected CMD_ON_QUIT (already stopped).");
                     break;
 
                 default:
@@ -1352,7 +1375,7 @@
                     break;
 
                 case CMD_START:
-                    Log.e(mTag, "ALERT: START received in StartedState. Please fix caller.");
+                    logError("ALERT: START received in StartedState. Please fix caller.");
                     break;
 
                 case CMD_CONFIRM:
@@ -1451,13 +1474,13 @@
                             handleIPv4Failure();
                             break;
                         default:
-                            Log.e(mTag, "Unknown CMD_POST_DHCP_ACTION status:" + msg.arg1);
+                            logError("Unknown CMD_POST_DHCP_ACTION status: %s", msg.arg1);
                     }
                     break;
 
                 case DhcpClient.CMD_ON_QUIT:
                     // DHCPv4 quit early for some reason.
-                    Log.e(mTag, "Unexpected CMD_ON_QUIT.");
+                    logError("Unexpected CMD_ON_QUIT.");
                     mDhcpClient = null;
                     break;
 
diff --git a/services/print/java/com/android/server/print/RemotePrintSpooler.java b/services/print/java/com/android/server/print/RemotePrintSpooler.java
index f4c9c86..abd2244 100644
--- a/services/print/java/com/android/server/print/RemotePrintSpooler.java
+++ b/services/print/java/com/android/server/print/RemotePrintSpooler.java
@@ -72,7 +72,7 @@
     private static final boolean DEBUG = false;
 
     private static final long BIND_SPOOLER_SERVICE_TIMEOUT =
-            ("eng".equals(Build.TYPE)) ? 120000 : 10000;
+            (Build.IS_ENG) ? 120000 : 10000;
 
     private final Object mLock = new Object();
 
diff --git a/services/tests/notification/AndroidManifest.xml b/services/tests/notification/AndroidManifest.xml
index 99d9c7b..c20020a 100644
--- a/services/tests/notification/AndroidManifest.xml
+++ b/services/tests/notification/AndroidManifest.xml
@@ -31,7 +31,7 @@
     </application>
 
     <instrumentation
-        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:name="android.testing.TestableInstrumentation"
         android:targetPackage="com.android.frameworks.tests.notification"
         android:label="Notification Tests" />
 </manifest>
diff --git a/services/tests/notification/src/com/android/server/notification/AlertRateLimiterTest.java b/services/tests/notification/src/com/android/server/notification/AlertRateLimiterTest.java
new file mode 100644
index 0000000..5ed8210
--- /dev/null
+++ b/services/tests/notification/src/com/android/server/notification/AlertRateLimiterTest.java
@@ -0,0 +1,72 @@
+/*
+ * 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.notification;
+
+import static com.android.server.notification.AlertRateLimiter.ALLOWED_ALERT_INTERVAL;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.SmallTest;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class AlertRateLimiterTest extends NotificationTestCase {
+
+    private long mTestStartTime;
+    private
+    AlertRateLimiter mLimiter;
+
+    @Before
+    public void setUp() {
+        mTestStartTime = 1225731600000L;
+        mLimiter = new AlertRateLimiter();
+    }
+
+    @Test
+    public void testFirstAlertAllowed() throws Exception {
+        assertFalse(mLimiter.isRateLimited(mTestStartTime));
+    }
+
+    @Test
+    public void testAllowedAfterSecond() throws Exception {
+        assertFalse(mLimiter.isRateLimited(mTestStartTime));
+        assertFalse(mLimiter.isRateLimited(mTestStartTime + ALLOWED_ALERT_INTERVAL));
+    }
+
+    @Test
+    public void testAllowedAfterSecondEvenWithBlockedEntries() throws Exception {
+        assertFalse(mLimiter.isRateLimited(mTestStartTime));
+        assertTrue(mLimiter.isRateLimited(mTestStartTime + ALLOWED_ALERT_INTERVAL - 1));
+        assertFalse(mLimiter.isRateLimited(mTestStartTime + ALLOWED_ALERT_INTERVAL));
+    }
+
+    @Test
+    public void testAllowedDisallowedBeforeSecond() throws Exception {
+        assertFalse(mLimiter.isRateLimited(mTestStartTime));
+        assertTrue(mLimiter.isRateLimited(mTestStartTime + ALLOWED_ALERT_INTERVAL - 1));
+    }
+
+    @Test
+    public void testDisallowedTimePast() throws Exception {
+        assertFalse(mLimiter.isRateLimited(mTestStartTime));
+        assertTrue(mLimiter.isRateLimited(mTestStartTime - ALLOWED_ALERT_INTERVAL));
+    }
+}
diff --git a/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
index ae98274..807703b 100644
--- a/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
+++ b/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
@@ -23,6 +23,7 @@
 import static junit.framework.Assert.assertNull;
 import static junit.framework.Assert.assertTrue;
 
+import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyBoolean;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.anyObject;
@@ -76,6 +77,8 @@
     @Mock android.media.IRingtonePlayer mRingtonePlayer;
     @Mock Light mLight;
     @Mock Handler mHandler;
+    @Mock
+    NotificationUsageStats mUsageStats;
 
     private NotificationManagerService mService;
     private String mPkg = "com.android.server.notification";
@@ -115,6 +118,8 @@
         when(mAudioManager.getStreamVolume(anyInt())).thenReturn(10);
         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
 
+        when(mUsageStats.isAlertRateLimited(any())).thenReturn(false);
+
         mService = new NotificationManagerService(getContext());
         mService.setAudioManager(mAudioManager);
         mService.setVibrator(mVibrator);
@@ -123,6 +128,7 @@
         mService.setLights(mLight);
         mService.setScreenOn(false);
         mService.setFallbackVibrationPattern(FALLBACK_VIBRATION_PATTERN);
+        mService.setUsageStats(mUsageStats);
     }
 
     //
@@ -806,6 +812,39 @@
         verifyNeverBeep();
     }
 
+    @Test
+    public void testRepeatedSoundOverLimitMuted() throws Exception {
+        when(mUsageStats.isAlertRateLimited(any())).thenReturn(true);
+
+        NotificationRecord r = getBeepyNotification();
+
+        mService.buzzBeepBlinkLocked(r);
+        verifyNeverBeep();
+    }
+
+    @Test
+    public void testPostingSilentNotificationDoesNotAffectRateLimiting() throws Exception {
+        NotificationRecord r = getQuietNotification();
+        mService.buzzBeepBlinkLocked(r);
+
+        verify(mUsageStats, never()).isAlertRateLimited(any());
+    }
+
+    @Test
+    public void testCrossUserSoundMuted() throws Exception {
+        final Notification n = new Builder(getContext(), "test")
+                .setSmallIcon(android.R.drawable.sym_def_app_icon).build();
+
+        int userId = mUser.getIdentifier() + 1;
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 0, mTag, mUid,
+                mPid, n, UserHandle.of(userId), null, System.currentTimeMillis());
+        NotificationRecord r = new NotificationRecord(getContext(), sbn,
+                new NotificationChannel("test", "test", IMPORTANCE_HIGH));
+
+        mService.buzzBeepBlinkLocked(r);
+        verifyNeverBeep();
+    }
+
     static class VibrateRepeatMatcher implements ArgumentMatcher<VibrationEffect> {
         private final int mRepeatIndex;
 
diff --git a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
index a356ae0..8ff4639 100644
--- a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -37,6 +37,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.ActivityManager;
 import android.app.INotificationManager;
 import android.app.Notification;
 import android.app.NotificationChannel;
@@ -50,6 +51,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ParceledListSlice;
 import android.graphics.Color;
+import android.media.AudioManager;
 import android.os.Binder;
 import android.os.Process;
 import android.os.UserHandle;
@@ -103,6 +105,10 @@
     File mFile;
     @Mock
     private NotificationUsageStats mUsageStats;
+    @Mock
+    private AudioManager mAudioManager;
+    @Mock
+    ActivityManager mActivityManager;
     private NotificationChannel mTestNotificationChannel = new NotificationChannel(
             TEST_CHANNEL_ID, TEST_CHANNEL_ID, NotificationManager.IMPORTANCE_DEFAULT);
     @Mock
@@ -112,6 +118,7 @@
     private ManagedServices.ManagedServiceInfo mListener;
     @Mock private ICompanionDeviceManager mCompanionMgr;
     @Mock SnoozeHelper mSnoozeHelper;
+    @Mock GroupHelper mGroupHelper;
 
     // Use a Testable subclass so we can simulate calls from the system without failing.
     private static class TestableNotificationManagerService extends NotificationManagerService {
@@ -153,6 +160,7 @@
                 .thenReturn(applicationInfo);
         final LightsManager mockLightsManager = mock(LightsManager.class);
         when(mockLightsManager.getLight(anyInt())).thenReturn(mock(Light.class));
+        when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
         // Use this testable looper.
         mTestableLooper = TestableLooper.get(this);
 
@@ -168,12 +176,13 @@
             mNotificationManagerService.init(mTestableLooper.getLooper(), mPackageManager,
                     mPackageManagerClient, mockLightsManager, mNotificationListeners,
                     mNotificationAssistants, mConditionProviders, mCompanionMgr,
-                    mSnoozeHelper, mUsageStats, mPolicyFile);
+                    mSnoozeHelper, mUsageStats, mPolicyFile, mActivityManager, mGroupHelper);
         } catch (SecurityException e) {
             if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
                 throw e;
             }
         }
+        mNotificationManagerService.setAudioManager(mAudioManager);
 
         // Tests call directly into the Binder.
         mBinderService = mNotificationManagerService.getBinderService();
@@ -1035,4 +1044,90 @@
         verify(mNotificationListeners, never()).setPackageOrComponentEnabled(
                 any(), anyInt(), anyBoolean(), anyBoolean());
     }
+
+    @Test
+    public void testSetListenerAccess_doesNothingOnLowRam() throws Exception {
+        when(mActivityManager.isLowRamDevice()).thenReturn(true);
+        ComponentName c = ComponentName.unflattenFromString("package/Component");
+        mBinderService.setNotificationListenerAccessGranted(c, true);
+
+        verify(mNotificationListeners, never()).setPackageOrComponentEnabled(
+                c.flattenToString(), 0, true, true);
+        verify(mConditionProviders, never()).setPackageOrComponentEnabled(
+                c.flattenToString(), 0, false, true);
+        verify(mNotificationAssistants, never()).setPackageOrComponentEnabled(
+                any(), anyInt(), anyBoolean(), anyBoolean());
+    }
+
+    @Test
+    public void testSetAssistantAccess_doesNothingOnLowRam() throws Exception {
+        when(mActivityManager.isLowRamDevice()).thenReturn(true);
+        ComponentName c = ComponentName.unflattenFromString("package/Component");
+        mBinderService.setNotificationAssistantAccessGranted(c, true);
+
+
+        verify(mNotificationListeners, never()).setPackageOrComponentEnabled(
+                c.flattenToString(), 0, true, true);
+        verify(mConditionProviders, never()).setPackageOrComponentEnabled(
+                c.flattenToString(), 0, false, true);
+        verify(mNotificationAssistants, never()).setPackageOrComponentEnabled(
+                any(), anyInt(), anyBoolean(), anyBoolean());
+    }
+
+    @Test
+    public void testSetDndAccess_doesNothingOnLowRam() throws Exception {
+        when(mActivityManager.isLowRamDevice()).thenReturn(true);
+        ComponentName c = ComponentName.unflattenFromString("package/Component");
+        mBinderService.setNotificationPolicyAccessGranted(c.getPackageName(), true);
+
+        verify(mNotificationListeners, never()).setPackageOrComponentEnabled(
+                c.flattenToString(), 0, true, true);
+        verify(mConditionProviders, never()).setPackageOrComponentEnabled(
+                c.flattenToString(), 0, false, true);
+        verify(mNotificationAssistants, never()).setPackageOrComponentEnabled(
+                any(), anyInt(), anyBoolean(), anyBoolean());
+    }
+
+    @Test
+    public void testOnlyAutogroupIfGroupChanged_noPriorNoti_autogroups() throws Exception {
+        NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, null, false);
+        mNotificationManagerService.addEnqueuedNotification(r);
+        NotificationManagerService.PostNotificationRunnable runnable =
+                mNotificationManagerService.new PostNotificationRunnable(r.getKey());
+        runnable.run();
+        waitForIdle();
+
+        verify(mGroupHelper, times(1)).onNotificationPosted(any());
+    }
+
+    @Test
+    public void testOnlyAutogroupIfGroupChanged_groupChanged_autogroups()
+            throws Exception {
+        NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, "group", false);
+        mNotificationManagerService.addNotification(r);
+
+        r = generateNotificationRecord(mTestNotificationChannel, 0, null, false);
+        mNotificationManagerService.addEnqueuedNotification(r);
+        NotificationManagerService.PostNotificationRunnable runnable =
+                mNotificationManagerService.new PostNotificationRunnable(r.getKey());
+        runnable.run();
+        waitForIdle();
+
+        verify(mGroupHelper, times(1)).onNotificationPosted(any());
+    }
+
+    @Test
+    public void testOnlyAutogroupIfGroupChanged_noGroupChanged_autogroups()
+            throws Exception {
+        NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, "group", false);
+        mNotificationManagerService.addNotification(r);
+        mNotificationManagerService.addEnqueuedNotification(r);
+
+        NotificationManagerService.PostNotificationRunnable runnable =
+                mNotificationManagerService.new PostNotificationRunnable(r.getKey());
+        runnable.run();
+        waitForIdle();
+
+        verify(mGroupHelper, never()).onNotificationPosted(any());
+    }
 }
diff --git a/services/tests/notification/src/com/android/server/notification/NotificationTest.java b/services/tests/notification/src/com/android/server/notification/NotificationTest.java
new file mode 100644
index 0000000..4165e9e
--- /dev/null
+++ b/services/tests/notification/src/com/android/server/notification/NotificationTest.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2017 The Android Open Source 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.notification;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.app.ActivityManager;
+import android.app.Notification;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.graphics.Color;
+import android.os.Build;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class NotificationTest extends NotificationTestCase {
+
+    @Mock
+    ActivityManager mAm;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void testStripsExtendersInLowRamMode() {
+        Notification.Builder nb = new Notification.Builder(mContext, "channel");
+        nb.extend(new Notification.CarExtender().setColor(Color.RED));
+        nb.extend(new Notification.TvExtender().setChannelId("different channel"));
+        nb.extend(new Notification.WearableExtender().setDismissalId("dismiss"));
+        Notification before = nb.build();
+
+        Notification after = Notification.Builder.maybeCloneStrippedForDelivery(before, true);
+
+        assertEquals("different channel", new Notification.TvExtender(before).getChannelId());
+        assertNull(new Notification.TvExtender(after).getChannelId());
+
+        assertEquals(Color.RED, new Notification.CarExtender(before).getColor());
+        assertEquals(Notification.COLOR_DEFAULT, new Notification.CarExtender(after).getColor());
+
+        assertEquals("dismiss", new Notification.WearableExtender(before).getDismissalId());
+        assertNull(new Notification.WearableExtender(after).getDismissalId());
+    }
+
+    @Test
+    public void testStripsRemoteViewsInLowRamMode() {
+        Context context = spy(getContext());
+        ApplicationInfo ai = new ApplicationInfo();
+        ai.targetSdkVersion = Build.VERSION_CODES.M;
+        when(context.getApplicationInfo()).thenReturn(ai);
+
+        final Notification.BigTextStyle style = new Notification.BigTextStyle()
+                .bigText("hello")
+                .setSummaryText("And the summary");
+        Notification before = new Notification.Builder(context, "channel")
+                .setContentText("hi")
+                .setStyle(style)
+                .build();
+
+        Notification after = Notification.Builder.maybeCloneStrippedForDelivery(before, true);
+        assertNotNull(before.contentView);
+        assertNotNull(before.bigContentView);
+        assertNotNull(before.headsUpContentView);
+        assertNull(after.contentView);
+        assertNull(after.bigContentView);
+        assertNull(after.headsUpContentView);
+    }
+
+    @Test
+    public void testDoesNotStripsExtendersInNormalRamMode() {
+        Notification.Builder nb = new Notification.Builder(mContext, "channel");
+        nb.extend(new Notification.CarExtender().setColor(Color.RED));
+        nb.extend(new Notification.TvExtender().setChannelId("different channel"));
+        nb.extend(new Notification.WearableExtender().setDismissalId("dismiss"));
+        Notification before = nb.build();
+        Notification after = Notification.Builder.maybeCloneStrippedForDelivery(before, false);
+
+        assertTrue(before == after);
+
+        assertEquals("different channel", new Notification.TvExtender(before).getChannelId());
+        assertEquals(Color.RED, new Notification.CarExtender(before).getColor());
+        assertEquals("dismiss", new Notification.WearableExtender(before).getDismissalId());
+    }
+}
+
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 a33153e..5471715 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
@@ -269,9 +269,9 @@
         }
 
         @Override
-        void recoverySystemRebootWipeUserData(boolean shutdown, String reason, boolean force)
-                throws IOException {
-            services.recoverySystem.rebootWipeUserData(shutdown, reason, force);
+        void recoverySystemRebootWipeUserData(boolean shutdown, String reason, boolean force,
+                boolean wipeEuicc) throws IOException {
+            services.recoverySystem.rebootWipeUserData(shutdown, reason, force, wipeEuicc);
         }
 
         @Override
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 6393b0b..c58b733 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -17,6 +17,7 @@
 
 import static android.app.admin.DevicePolicyManager.DELEGATION_APP_RESTRICTIONS;
 import static android.app.admin.DevicePolicyManager.DELEGATION_CERT_INSTALL;
+import static android.app.admin.DevicePolicyManager.WIPE_EUICC;
 import static android.os.UserManagerInternal.CAMERA_DISABLED_GLOBALLY;
 import static android.os.UserManagerInternal.CAMERA_DISABLED_LOCALLY;
 import static android.os.UserManagerInternal.CAMERA_NOT_DISABLED;
@@ -3451,7 +3452,21 @@
 
         dpm.wipeData(0);
         verify(getServices().recoverySystem).rebootWipeUserData(
-                /*shutdown=*/ eq(false), anyString(), /*force=*/ eq(true));
+                /*shutdown=*/ eq(false), anyString(), /*force=*/ eq(true),
+                /*wipeEuicc=*/ eq(false));
+    }
+
+    public void testWipeEuiccDataEnabled() throws Exception {
+        setDeviceOwner();
+        when(getServices().userManager.getUserRestrictionSource(
+            UserManager.DISALLOW_FACTORY_RESET,
+            UserHandle.SYSTEM))
+            .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
+
+        dpm.wipeData(WIPE_EUICC);
+        verify(getServices().recoverySystem).rebootWipeUserData(
+                /*shutdown=*/ eq(false), anyString(), /*force=*/ eq(true),
+                /*wipeEuicc=*/ eq(true));
     }
 
     public void testWipeDataDeviceOwnerDisallowed() throws Exception {
@@ -3549,7 +3564,8 @@
         // The device should be wiped even if DISALLOW_FACTORY_RESET is enabled, because both the
         // user restriction and the policy were set by the DO.
         verify(getServices().recoverySystem).rebootWipeUserData(
-                /*shutdown=*/ eq(false), anyString(), /*force=*/ eq(true));
+                /*shutdown=*/ eq(false), anyString(), /*force=*/ eq(true),
+                /*wipeEuicc=*/ eq(false));
     }
 
     public void testMaximumFailedPasswordAttemptsReachedDeviceOwnerDisallowed() throws Exception {
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
index ed8de05..8121bcf 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
@@ -314,8 +314,8 @@
     }
 
     public static class RecoverySystemForMock {
-        public void rebootWipeUserData(
-                boolean shutdown, String reason, boolean force) throws IOException {
+        public void rebootWipeUserData(boolean shutdown, String reason, boolean force,
+                boolean wipeEuicc) throws IOException {
         }
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
index c399a5d..e3ce17b 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -29,6 +29,7 @@
 import android.view.WindowManagerInternal;
 
 import com.android.server.LocalServices;
+import com.android.server.display.DisplayDeviceInfo;
 import com.android.server.display.DisplayManagerService.SyncRoot;
 import com.android.server.display.VirtualDisplayAdapter.SurfaceControlDisplayFactory;
 
@@ -115,4 +116,30 @@
         assertEquals(uniqueIdPrefix + uniqueId, dv.uniqueId);
         assertEquals(displayId, dv.displayId);
     }
+
+    public void testCreateVirtualDisplayRotatesWithContent() throws Exception {
+        // This is effectively the DisplayManager service published to ServiceManager.
+        DisplayManagerService.BinderService bs = mDisplayManager.new BinderService();
+
+        String uniqueId = "uniqueId --- Rotates With Content Test";
+        int width = 600;
+        int height = 800;
+        int dpi = 320;
+        int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT;
+
+        when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
+        int displayId = bs.createVirtualDisplay(mMockAppToken /* callback */,
+                null /* projection */, "com.android.frameworks.servicestests",
+                "Test Virtual Display", width, height, dpi, null /* surface */, flags /* flags */,
+                uniqueId);
+
+        mDisplayManager.performTraversalInTransactionFromWindowManagerInternal();
+
+        // flush the handler
+        mHandler.runWithScissors(() -> {}, 0 /* now */);
+
+        DisplayDeviceInfo ddi = mDisplayManager.getDisplayDeviceInfoInternal(displayId);
+        assertNotNull(ddi);
+        assertTrue((ddi.flags & DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT) != 0);
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserLifecycleStressTest.java b/services/tests/servicestests/src/com/android/server/pm/UserLifecycleStressTest.java
new file mode 100644
index 0000000..304e0e9
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/UserLifecycleStressTest.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.server.pm;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import android.app.ActivityManager;
+import android.app.IStopUserCallback;
+import android.content.Context;
+import android.content.pm.UserInfo;
+import android.os.RemoteException;
+import android.os.UserManager;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.LargeTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.IOException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * To run the test:
+ * bit FrameworksServicesTests:com.android.server.pm.UserLifecycleStressTest
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class UserLifecycleStressTest {
+    private static final String TAG = "UserLifecycleStressTest";
+    // TODO: Make this smaller once we have improved it.
+    private static final int MAX_TIME_STOP_USER_IN_SECOND = 30;
+    private static final int NUM_ITERATIONS_STOP_USER = 10;
+    private static final int WAIT_BEFORE_STOP_USER_IN_SECOND = 3;
+
+    private Context mContext;
+    private UserManager mUserManager;
+    private ActivityManager mActivityManager;
+
+    @Before
+    public void setup() {
+        mContext = InstrumentationRegistry.getInstrumentation().getContext();
+        mUserManager = mContext.getSystemService(UserManager.class);
+        mActivityManager = mContext.getSystemService(ActivityManager.class);
+    }
+
+    /**
+     * Create and stop user 10 times in a row. Check stop user can be finished in a reasonable
+     * amount of time.
+     */
+    @Test
+    public void stopManagedProfileStressTest()
+            throws IOException, RemoteException, InterruptedException {
+        for (int i = 0; i < NUM_ITERATIONS_STOP_USER; i++) {
+            final UserInfo userInfo = mUserManager.createProfileForUser("TestUser",
+                    UserInfo.FLAG_MANAGED_PROFILE, mActivityManager.getCurrentUser());
+            assertNotNull(userInfo);
+            try {
+                assertTrue(
+                        "Failed to start the profile",
+                        ActivityManager.getService().startUserInBackground(userInfo.id));
+                // Seems the broadcast queue is getting more busy if we wait a few seconds before
+                // stopping the user.
+                TimeUnit.SECONDS.sleep(WAIT_BEFORE_STOP_USER_IN_SECOND);
+                stopUser(userInfo.id);
+            } finally {
+                mUserManager.removeUser(userInfo.id);
+            }
+        }
+    }
+
+    private void stopUser(int userId) throws RemoteException, InterruptedException {
+        final long startTime = System.currentTimeMillis();
+        CountDownLatch countDownLatch = new CountDownLatch(1);
+        ActivityManager.getService().
+                stopUser(userId, true,
+                        new IStopUserCallback.Stub() {
+                            @Override
+                            public void userStopped(int userId) throws RemoteException {
+                                countDownLatch.countDown();
+                            }
+
+                            @Override
+                            public void userStopAborted(int userId) throws RemoteException {
+
+                            }
+                        });
+        boolean stoppedBeforeTimeout =
+                countDownLatch.await(MAX_TIME_STOP_USER_IN_SECOND, TimeUnit.SECONDS);
+        assertTrue(
+                "Take more than " + MAX_TIME_STOP_USER_IN_SECOND + "s to stop user",
+                stoppedBeforeTimeout);
+        Log.d(TAG, "stopUser takes " + (System.currentTimeMillis() - startTime) + " ms");
+    }
+}
+
diff --git a/services/tests/servicestests/src/com/android/server/timezone/PackageStatusStorageTest.java b/services/tests/servicestests/src/com/android/server/timezone/PackageStatusStorageTest.java
index e085270..dd56072 100644
--- a/services/tests/servicestests/src/com/android/server/timezone/PackageStatusStorageTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezone/PackageStatusStorageTest.java
@@ -21,10 +21,11 @@
 import org.junit.Test;
 
 import android.content.Context;
-import android.database.sqlite.SQLiteDatabase;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 
+import java.io.File;
+
 import static junit.framework.Assert.assertTrue;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -40,15 +41,16 @@
     @Before
     public void setUp() throws Exception {
         Context context = InstrumentationRegistry.getContext();
+        File dataDir = context.getFilesDir();
 
         // Using the instrumentation context means the database is created in a test app-specific
         // directory.
-        mPackageStatusStorage = new PackageStatusStorage(context);
+        mPackageStatusStorage = new PackageStatusStorage(dataDir);
     }
 
     @After
     public void tearDown() throws Exception {
-        mPackageStatusStorage.deleteDatabaseForTests();
+        mPackageStatusStorage.deleteFileForTests();
     }
 
     @Test
@@ -90,7 +92,7 @@
     }
 
     @Test
-    public void generateCheckToken_missingRowBehavior() {
+    public void generateCheckToken_missingFileBehavior() {
         // Assert initial state.
         assertNull(mPackageStatusStorage.getPackageStatus());
 
@@ -100,15 +102,15 @@
         // There should now be state.
         assertNotNull(mPackageStatusStorage.getPackageStatus());
 
-        // Corrupt the table by removing the one row.
-        mPackageStatusStorage.deleteRowForTests();
+        // Corrupt the data by removing the file.
+        mPackageStatusStorage.deleteFileForTests();
 
         // Check that generateCheckToken recovers.
         assertNotNull(mPackageStatusStorage.generateCheckToken(VALID_PACKAGE_VERSIONS));
     }
 
     @Test
-    public void getPackageStatus_missingRowBehavior() {
+    public void getPackageStatus_missingFileBehavior() {
         // Assert initial state.
         assertNull(mPackageStatusStorage.getPackageStatus());
 
@@ -118,14 +120,14 @@
         // There should now be a state.
         assertNotNull(mPackageStatusStorage.getPackageStatus());
 
-        // Corrupt the table by removing the one row.
-        mPackageStatusStorage.deleteRowForTests();
+        // Corrupt the data by removing the file.
+        mPackageStatusStorage.deleteFileForTests();
 
         assertNull(mPackageStatusStorage.getPackageStatus());
     }
 
     @Test
-    public void markChecked_missingRowBehavior() {
+    public void markChecked_missingFileBehavior() {
         // Assert initial state.
         CheckToken token1 = mPackageStatusStorage.generateCheckToken(VALID_PACKAGE_VERSIONS);
         assertNotNull(token1);
@@ -133,10 +135,10 @@
         // There should now be a state.
         assertNotNull(mPackageStatusStorage.getPackageStatus());
 
-        // Corrupt the table by removing the one row.
-        mPackageStatusStorage.deleteRowForTests();
+        // Corrupt the data by removing the file.
+        mPackageStatusStorage.deleteFileForTests();
 
-        // The missing row should mean token1 is now considered invalid, so we should get a false.
+        // The missing file should mean token1 is now considered invalid, so we should get a false.
         assertFalse(mPackageStatusStorage.markChecked(token1, true /* succeeded */));
 
         // The storage should have recovered and we should be able to carry on like before.
diff --git a/services/tests/servicestests/src/com/android/server/timezone/PackageTrackerTest.java b/services/tests/servicestests/src/com/android/server/timezone/PackageTrackerTest.java
index 45b0af3..4c7680b 100644
--- a/services/tests/servicestests/src/com/android/server/timezone/PackageTrackerTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezone/PackageTrackerTest.java
@@ -71,7 +71,7 @@
 
         // Using the instrumentation context means the database is created in a test app-specific
         // directory. We can use the real thing for this test.
-        mPackageStatusStorage = new PackageStatusStorage(context);
+        mPackageStatusStorage = new PackageStatusStorage(context.getFilesDir());
 
         // For other interactions with the Android framework we create a fake object.
         mFakeIntentHelper = new FakeIntentHelper();
@@ -88,7 +88,7 @@
     @After
     public void tearDown() throws Exception {
         if (mPackageStatusStorage != null) {
-            mPackageStatusStorage.deleteDatabaseForTests();
+            mPackageStatusStorage.deleteFileForTests();
         }
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/timezone/RulesManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/timezone/RulesManagerServiceTest.java
index 86116a9..3b76d5e 100644
--- a/services/tests/servicestests/src/com/android/server/timezone/RulesManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezone/RulesManagerServiceTest.java
@@ -17,8 +17,8 @@
 package com.android.server.timezone;
 
 import com.android.timezone.distro.DistroVersion;
-import com.android.timezone.distro.TimeZoneDistro;
 import com.android.timezone.distro.StagedDistroOperation;
+import com.android.timezone.distro.TimeZoneDistro;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -30,6 +30,8 @@
 import android.app.timezone.RulesState;
 import android.os.ParcelFileDescriptor;
 
+import java.io.File;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.util.concurrent.Executor;
 import javax.annotation.Nullable;
@@ -42,7 +44,7 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
-import static org.mockito.Matchers.eq;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.doThrow;
@@ -61,7 +63,6 @@
 
     private FakeExecutor mFakeExecutor;
     private PermissionHelper mMockPermissionHelper;
-    private FileDescriptorHelper mMockFileDescriptorHelper;
     private PackageTracker mMockPackageTracker;
     private TimeZoneDistroInstaller mMockTimeZoneDistroInstaller;
 
@@ -69,7 +70,6 @@
     public void setUp() {
         mFakeExecutor = new FakeExecutor();
 
-        mMockFileDescriptorHelper = mock(FileDescriptorHelper.class);
         mMockPackageTracker = mock(PackageTracker.class);
         mMockPermissionHelper = mock(PermissionHelper.class);
         mMockTimeZoneDistroInstaller = mock(TimeZoneDistroInstaller.class);
@@ -77,7 +77,6 @@
         mRulesManagerService = new RulesManagerService(
                 mMockPermissionHelper,
                 mFakeExecutor,
-                mMockFileDescriptorHelper,
                 mMockPackageTracker,
                 mMockTimeZoneDistroInstaller);
     }
@@ -273,9 +272,8 @@
                 revision);
         configureInstalledDistroVersion(installedDistroVersion);
 
-        byte[] expectedContent = createArbitraryBytes(1000);
-        ParcelFileDescriptor parcelFileDescriptor = createFakeParcelFileDescriptor();
-        configureParcelFileDescriptorReadSuccess(parcelFileDescriptor, expectedContent);
+        ParcelFileDescriptor parcelFileDescriptor =
+                createParcelFileDescriptor(createArbitraryBytes(1000));
 
         // Start an async operation so there is one in progress. The mFakeExecutor won't actually
         // execute it.
@@ -284,36 +282,41 @@
 
         mRulesManagerService.requestInstall(parcelFileDescriptor, tokenBytes, callback);
 
+        // Request the rules state while the async operation is "happening".
+        RulesState actualRulesState = mRulesManagerService.getRulesState();
         RulesState expectedRuleState = new RulesState(
                 systemRulesVersion, RulesManagerService.DISTRO_FORMAT_VERSION_SUPPORTED,
                 true /* operationInProgress */,
                 RulesState.STAGED_OPERATION_UNKNOWN, null /* stagedDistroRulesVersion */,
                 RulesState.DISTRO_STATUS_UNKNOWN, null /* installedDistroRulesVersion */);
-        assertEquals(expectedRuleState, mRulesManagerService.getRulesState());
+        assertEquals(expectedRuleState, actualRulesState);
     }
 
     @Test
     public void requestInstall_operationInProgress() throws Exception {
         configureCallerHasPermission();
 
-        byte[] expectedContent = createArbitraryBytes(1000);
-        ParcelFileDescriptor parcelFileDescriptor = createFakeParcelFileDescriptor();
-        configureParcelFileDescriptorReadSuccess(parcelFileDescriptor, expectedContent);
+        ParcelFileDescriptor parcelFileDescriptor1 =
+                createParcelFileDescriptor(createArbitraryBytes(1000));
 
         byte[] tokenBytes = createArbitraryTokenBytes();
         ICallback callback = new StubbedCallback();
 
         // First request should succeed.
         assertEquals(RulesManager.SUCCESS,
-                mRulesManagerService.requestInstall(parcelFileDescriptor, tokenBytes, callback));
+                mRulesManagerService.requestInstall(parcelFileDescriptor1, tokenBytes, callback));
 
         // Something async should be enqueued. Clear it but do not execute it so we can detect the
         // second request does nothing.
         mFakeExecutor.getAndResetLastCommand();
 
         // Second request should fail.
+        ParcelFileDescriptor parcelFileDescriptor2 =
+                createParcelFileDescriptor(createArbitraryBytes(1000));
         assertEquals(RulesManager.ERROR_OPERATION_IN_PROGRESS,
-                mRulesManagerService.requestInstall(parcelFileDescriptor, tokenBytes, callback));
+                mRulesManagerService.requestInstall(parcelFileDescriptor2, tokenBytes, callback));
+
+        assertClosed(parcelFileDescriptor2);
 
         // Assert nothing async was enqueued.
         mFakeExecutor.assertNothingQueued();
@@ -325,9 +328,8 @@
     public void requestInstall_badToken() throws Exception {
         configureCallerHasPermission();
 
-        byte[] expectedContent = createArbitraryBytes(1000);
-        ParcelFileDescriptor parcelFileDescriptor = createFakeParcelFileDescriptor();
-        configureParcelFileDescriptorReadSuccess(parcelFileDescriptor, expectedContent);
+        ParcelFileDescriptor parcelFileDescriptor =
+                createParcelFileDescriptor(createArbitraryBytes(1000));
 
         byte[] badTokenBytes = new byte[2];
         ICallback callback = new StubbedCallback();
@@ -338,6 +340,8 @@
         } catch (IllegalArgumentException expected) {
         }
 
+        assertClosed(parcelFileDescriptor);
+
         // Assert nothing async was enqueued.
         mFakeExecutor.assertNothingQueued();
         verifyNoInstallerCallsMade();
@@ -367,7 +371,8 @@
     public void requestInstall_nullCallback() throws Exception {
         configureCallerHasPermission();
 
-        ParcelFileDescriptor parcelFileDescriptor = createFakeParcelFileDescriptor();
+        ParcelFileDescriptor parcelFileDescriptor =
+                createParcelFileDescriptor(createArbitraryBytes(1000));
         byte[] tokenBytes = createArbitraryTokenBytes();
         ICallback callback = null;
 
@@ -376,6 +381,8 @@
             fail();
         } catch (NullPointerException expected) {}
 
+        assertClosed(parcelFileDescriptor);
+
         // Assert nothing async was enqueued.
         mFakeExecutor.assertNothingQueued();
         verifyNoInstallerCallsMade();
@@ -386,9 +393,8 @@
     public void requestInstall_asyncSuccess() throws Exception {
         configureCallerHasPermission();
 
-        ParcelFileDescriptor parcelFileDescriptor = createFakeParcelFileDescriptor();
-        byte[] expectedContent = createArbitraryBytes(1000);
-        configureParcelFileDescriptorReadSuccess(parcelFileDescriptor, expectedContent);
+        ParcelFileDescriptor parcelFileDescriptor =
+                createParcelFileDescriptor(createArbitraryBytes(1000));
 
         CheckToken token = createArbitraryToken();
         byte[] tokenBytes = token.toByteArray();
@@ -404,16 +410,16 @@
         verifyNoInstallerCallsMade();
         verifyNoPackageTrackerCallsMade();
 
-        TimeZoneDistro expectedDistro = new TimeZoneDistro(expectedContent);
-
         // Set up the installer.
-        configureStageInstallExpectation(expectedDistro, TimeZoneDistroInstaller.INSTALL_SUCCESS);
+        configureStageInstallExpectation(TimeZoneDistroInstaller.INSTALL_SUCCESS);
 
         // Simulate the async execution.
         mFakeExecutor.simulateAsyncExecutionOfLastCommand();
 
+        assertClosed(parcelFileDescriptor);
+
         // Verify the expected calls were made to other components.
-        verifyStageInstallCalled(expectedDistro);
+        verifyStageInstallCalled();
         verifyPackageTrackerCalled(token, true /* success */);
 
         // Check the callback was called.
@@ -424,9 +430,8 @@
     public void requestInstall_nullTokenBytes() throws Exception {
         configureCallerHasPermission();
 
-        ParcelFileDescriptor parcelFileDescriptor = createFakeParcelFileDescriptor();
-        byte[] expectedContent = createArbitraryBytes(1000);
-        configureParcelFileDescriptorReadSuccess(parcelFileDescriptor, expectedContent);
+        ParcelFileDescriptor parcelFileDescriptor =
+                createParcelFileDescriptor(createArbitraryBytes(1000));
 
         TestCallback callback = new TestCallback();
 
@@ -439,16 +444,16 @@
         verifyNoInstallerCallsMade();
         callback.assertNoResultReceived();
 
-        TimeZoneDistro expectedDistro = new TimeZoneDistro(expectedContent);
-
         // Set up the installer.
-        configureStageInstallExpectation(expectedDistro, TimeZoneDistroInstaller.INSTALL_SUCCESS);
+        configureStageInstallExpectation(TimeZoneDistroInstaller.INSTALL_SUCCESS);
 
         // Simulate the async execution.
         mFakeExecutor.simulateAsyncExecutionOfLastCommand();
 
+        assertClosed(parcelFileDescriptor);
+
         // Verify the expected calls were made to other components.
-        verifyStageInstallCalled(expectedDistro);
+        verifyStageInstallCalled();
         verifyPackageTrackerCalled(null /* expectedToken */, true /* success */);
 
         // Check the callback was received.
@@ -459,9 +464,8 @@
     public void requestInstall_asyncInstallFail() throws Exception {
         configureCallerHasPermission();
 
-        byte[] expectedContent = createArbitraryBytes(1000);
-        ParcelFileDescriptor parcelFileDescriptor = createFakeParcelFileDescriptor();
-        configureParcelFileDescriptorReadSuccess(parcelFileDescriptor, expectedContent);
+        ParcelFileDescriptor parcelFileDescriptor =
+                createParcelFileDescriptor(createArbitraryBytes(1000));
 
         CheckToken token = createArbitraryToken();
         byte[] tokenBytes = token.toByteArray();
@@ -476,17 +480,16 @@
         verifyNoInstallerCallsMade();
         callback.assertNoResultReceived();
 
-        TimeZoneDistro expectedDistro = new TimeZoneDistro(expectedContent);
-
         // Set up the installer.
-        configureStageInstallExpectation(
-                expectedDistro, TimeZoneDistroInstaller.INSTALL_FAIL_VALIDATION_ERROR);
+        configureStageInstallExpectation(TimeZoneDistroInstaller.INSTALL_FAIL_VALIDATION_ERROR);
 
         // Simulate the async execution.
         mFakeExecutor.simulateAsyncExecutionOfLastCommand();
 
+        assertClosed(parcelFileDescriptor);
+
         // Verify the expected calls were made to other components.
-        verifyStageInstallCalled(expectedDistro);
+        verifyStageInstallCalled();
 
         // Validation failure is treated like a successful check: repeating it won't improve things.
         boolean expectedSuccess = true;
@@ -497,38 +500,6 @@
     }
 
     @Test
-    public void requestInstall_asyncParcelFileDescriptorReadFail() throws Exception {
-        configureCallerHasPermission();
-
-        ParcelFileDescriptor parcelFileDescriptor = createFakeParcelFileDescriptor();
-        configureParcelFileDescriptorReadFailure(parcelFileDescriptor);
-
-        CheckToken token = createArbitraryToken();
-        byte[] tokenBytes = token.toByteArray();
-
-        TestCallback callback = new TestCallback();
-
-        // Request the install.
-        assertEquals(RulesManager.SUCCESS,
-                mRulesManagerService.requestInstall(parcelFileDescriptor, tokenBytes, callback));
-
-        // Simulate the async execution.
-        mFakeExecutor.simulateAsyncExecutionOfLastCommand();
-
-        // Verify nothing else happened.
-        verifyNoInstallerCallsMade();
-
-        // A failure to read the ParcelFileDescriptor is treated as a failure. It might be the
-        // result of a file system error. This is a fairly arbitrary choice.
-        verifyPackageTrackerCalled(token, false /* success */);
-
-        verifyNoPackageTrackerCallsMade();
-
-        // Check the callback was received.
-        callback.assertResultReceived(Callback.ERROR_UNKNOWN_FAILURE);
-    }
-
-    @Test
     public void requestUninstall_operationInProgress() throws Exception {
         configureCallerHasPermission();
 
@@ -776,20 +747,9 @@
                 .enforceCallerHasPermission(REQUIRED_UPDATER_PERMISSION);
     }
 
-    private void configureParcelFileDescriptorReadSuccess(ParcelFileDescriptor parcelFileDescriptor,
-            byte[] content) throws Exception {
-        when(mMockFileDescriptorHelper.readFully(parcelFileDescriptor)).thenReturn(content);
-    }
-
-    private void configureParcelFileDescriptorReadFailure(ParcelFileDescriptor parcelFileDescriptor)
+    private void configureStageInstallExpectation(int resultCode)
             throws Exception {
-        when(mMockFileDescriptorHelper.readFully(parcelFileDescriptor))
-                .thenThrow(new IOException("Simulated failure"));
-    }
-
-    private void configureStageInstallExpectation(TimeZoneDistro expected, int resultCode)
-            throws Exception {
-        when(mMockTimeZoneDistroInstaller.stageInstallWithErrorCode(eq(expected)))
+        when(mMockTimeZoneDistroInstaller.stageInstallWithErrorCode(any(TimeZoneDistro.class)))
                 .thenReturn(resultCode);
     }
 
@@ -797,8 +757,8 @@
         doReturn(success).when(mMockTimeZoneDistroInstaller).stageUninstall();
     }
 
-    private void verifyStageInstallCalled(TimeZoneDistro expected) throws Exception {
-        verify(mMockTimeZoneDistroInstaller).stageInstallWithErrorCode(eq(expected));
+    private void verifyStageInstallCalled() throws Exception {
+        verify(mMockTimeZoneDistroInstaller).stageInstallWithErrorCode(any(TimeZoneDistro.class));
         verifyNoMoreInteractions(mMockTimeZoneDistroInstaller);
         reset(mMockTimeZoneDistroInstaller);
     }
@@ -830,10 +790,6 @@
         return new CheckToken(1, new PackageVersions(1, 1));
     }
 
-    private ParcelFileDescriptor createFakeParcelFileDescriptor() {
-        return new ParcelFileDescriptor((ParcelFileDescriptor) null);
-    }
-
     private void configureDeviceSystemRulesVersion(String systemRulesVersion) throws Exception {
         when(mMockTimeZoneDistroInstaller.getSystemRulesVersion()).thenReturn(systemRulesVersion);
     }
@@ -873,6 +829,10 @@
                 .thenThrow(new IOException("Simulated failure"));
     }
 
+    private static void assertClosed(ParcelFileDescriptor parcelFileDescriptor) {
+        assertFalse(parcelFileDescriptor.getFileDescriptor().valid());
+    }
+
     private static class FakeExecutor implements Executor {
 
         private Runnable mLastCommand;
@@ -929,4 +889,17 @@
             fail("Unexpected call");
         }
     }
+
+    private static ParcelFileDescriptor createParcelFileDescriptor(byte[] bytes)
+            throws IOException {
+        File file = File.createTempFile("pfd", null);
+        try (FileOutputStream fos = new FileOutputStream(file)) {
+            fos.write(bytes);
+        }
+        ParcelFileDescriptor pfd =
+                ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
+        // This should now be safe to delete. The ParcelFileDescriptor has an open fd.
+        file.delete();
+        return pfd;
+    }
 }
diff --git a/services/usb/java/com/android/server/usb/UsbDebuggingManager.java b/services/usb/java/com/android/server/usb/UsbDebuggingManager.java
index f6d9e9a..703f1a1 100644
--- a/services/usb/java/com/android/server/usb/UsbDebuggingManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDebuggingManager.java
@@ -43,12 +43,10 @@
 import com.android.server.FgThread;
 
 import java.io.File;
-import java.io.FileDescriptor;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.io.PrintWriter;
 import java.security.MessageDigest;
 import java.util.Arrays;
 
@@ -56,10 +54,10 @@
     private static final String TAG = "UsbDebuggingManager";
     private static final boolean DEBUG = false;
 
-    private final String ADBD_SOCKET = "adbd";
-    private final String ADB_DIRECTORY = "misc/adb";
-    private final String ADB_KEYS_FILE = "adb_keys";
-    private final int BUFFER_SIZE = 4096;
+    private static final String ADBD_SOCKET = "adbd";
+    private static final String ADB_DIRECTORY = "misc/adb";
+    private static final String ADB_KEYS_FILE = "adb_keys";
+    private static final int BUFFER_SIZE = 4096;
 
     private final Context mContext;
     private final Handler mHandler;
@@ -346,7 +344,7 @@
     }
 
     /**
-     * @returns true if the componentName led to an Activity that was started.
+     * @return true if the componentName led to an Activity that was started.
      */
     private boolean startConfirmationActivity(ComponentName componentName, UserHandle userHandle,
             String key, String fingerprints) {
@@ -365,7 +363,7 @@
     }
 
     /**
-     * @returns true if the componentName led to a Service that was started.
+     * @return true if the componentName led to a Service that was started.
      */
     private boolean startConfirmationService(ComponentName componentName, UserHandle userHandle,
             String key, String fingerprints) {
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 42272fd..1a24d95 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -92,14 +92,6 @@
     private static final String USB_CONFIG_PROPERTY = "sys.usb.config";
 
     /**
-     * The property which stores the current build type (user/userdebug/eng).
-     */
-    private static final String BUILD_TYPE_PROPERTY = "ro.build.type";
-
-    private static final String BUILD_TYPE_USERDEBUG = "userdebug";
-    private static final String BUILD_TYPE_ENG = "eng";
-
-    /**
      * The non-persistent property which stores the current USB actual state.
      */
     private static final String USB_STATE_PROPERTY = "sys.usb.state";
@@ -179,7 +171,7 @@
     private static Set<Integer> sBlackListedInterfaces;
 
     static {
-        sBlackListedInterfaces = new HashSet<Integer>();
+        sBlackListedInterfaces = new HashSet<>();
         sBlackListedInterfaces.add(UsbConstants.USB_CLASS_AUDIO);
         sBlackListedInterfaces.add(UsbConstants.USB_CLASS_COMM);
         sBlackListedInterfaces.add(UsbConstants.USB_CLASS_HID);
@@ -191,7 +183,7 @@
         sBlackListedInterfaces.add(UsbConstants.USB_CLASS_CONTENT_SEC);
         sBlackListedInterfaces.add(UsbConstants.USB_CLASS_VIDEO);
         sBlackListedInterfaces.add(UsbConstants.USB_CLASS_WIRELESS_CONTROLLER);
-    };
+    }
 
     private class AdbSettingsObserver extends ContentObserver {
         public AdbSettingsObserver() {
@@ -225,44 +217,6 @@
         }
     };
 
-    private final BroadcastReceiver mPortReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            UsbPort port = intent.getParcelableExtra(UsbManager.EXTRA_PORT);
-            UsbPortStatus status = intent.getParcelableExtra(UsbManager.EXTRA_PORT_STATUS);
-            mHandler.updateHostState(port, status);
-        }
-    };
-
-    private final BroadcastReceiver mChargingReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
-            boolean usbCharging = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
-            mHandler.sendMessage(MSG_UPDATE_CHARGING_STATE, usbCharging);
-        }
-    };
-
-    private final BroadcastReceiver mHostReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            Iterator devices = ((UsbManager) context.getSystemService(Context.USB_SERVICE))
-                    .getDeviceList().entrySet().iterator();
-            if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) {
-                mHandler.sendMessage(MSG_UPDATE_HOST_STATE, devices, true);
-            } else {
-                mHandler.sendMessage(MSG_UPDATE_HOST_STATE, devices, false);
-            }
-        }
-    };
-
-    private final BroadcastReceiver mLanguageChangedReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            mHandler.sendEmptyMessage(MSG_LOCALE_CHANGED);
-        }
-    };
-
     public UsbDeviceManager(Context context, UsbAlsaManager alsaManager,
             UsbSettingsManager settingsManager) {
         mContext = context;
@@ -287,17 +241,56 @@
         if (secureAdbEnabled && !dataEncrypted) {
             mDebuggingManager = new UsbDebuggingManager(context);
         }
-        mContext.registerReceiver(mPortReceiver,
+
+        BroadcastReceiver portReceiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                UsbPort port = intent.getParcelableExtra(UsbManager.EXTRA_PORT);
+                UsbPortStatus status = intent.getParcelableExtra(UsbManager.EXTRA_PORT_STATUS);
+                mHandler.updateHostState(port, status);
+            }
+        };
+
+        BroadcastReceiver chargingReceiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
+                boolean usbCharging = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
+                mHandler.sendMessage(MSG_UPDATE_CHARGING_STATE, usbCharging);
+            }
+        };
+
+        BroadcastReceiver hostReceiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                Iterator devices = ((UsbManager) context.getSystemService(Context.USB_SERVICE))
+                        .getDeviceList().entrySet().iterator();
+                if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) {
+                    mHandler.sendMessage(MSG_UPDATE_HOST_STATE, devices, true);
+                } else {
+                    mHandler.sendMessage(MSG_UPDATE_HOST_STATE, devices, false);
+                }
+            }
+        };
+
+        BroadcastReceiver languageChangedReceiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                mHandler.sendEmptyMessage(MSG_LOCALE_CHANGED);
+            }
+        };
+
+        mContext.registerReceiver(portReceiver,
                 new IntentFilter(UsbManager.ACTION_USB_PORT_CHANGED));
-        mContext.registerReceiver(mChargingReceiver,
+        mContext.registerReceiver(chargingReceiver,
                 new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
 
         IntentFilter filter =
                 new IntentFilter(UsbManager.ACTION_USB_DEVICE_ATTACHED);
         filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
-        mContext.registerReceiver(mHostReceiver, filter);
+        mContext.registerReceiver(hostReceiver, filter);
 
-        mContext.registerReceiver(mLanguageChangedReceiver,
+        mContext.registerReceiver(languageChangedReceiver,
                 new IntentFilter(Intent.ACTION_LOCALE_CHANGED));
     }
 
@@ -326,7 +319,7 @@
 
         // We do not show the USB notification if the primary volume supports mass storage.
         // The legacy mass storage UI will be used instead.
-        boolean massStorageSupported = false;
+        boolean massStorageSupported;
         final StorageManager storageManager = StorageManager.from(mContext);
         final StorageVolume primary = storageManager.getPrimaryVolume();
         massStorageSupported = primary != null && primary.allowMassStorage();
@@ -454,7 +447,7 @@
                             SystemProperties.get(USB_STATE_PROPERTY));
                 }
 
-                /**
+                /*
                  * Use the normal bootmode persistent prop to maintain state of adb across
                  * all boot modes.
                  */
@@ -462,7 +455,7 @@
                         SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY),
                         UsbManager.USB_FUNCTION_ADB);
 
-                /**
+                /*
                  * Previous versions can set persist config to mtp/ptp but it does not
                  * get reset on OTA. Reset the property here instead.
                  */
@@ -652,10 +645,7 @@
 
         private boolean isNormalBoot() {
             String bootMode = SystemProperties.get(BOOT_MODE_PROPERTY, "unknown");
-            if (bootMode.equals(NORMAL_BOOT) || bootMode.equals("unknown")) {
-                return true;
-            }
-            return false;
+            return bootMode.equals(NORMAL_BOOT) || bootMode.equals("unknown");
         }
 
         private boolean trySetEnabledFunctions(String functions, boolean forceRestart) {
@@ -1311,25 +1301,21 @@
                 String[] items = config.split(":");
                 if (items.length == 3 || items.length == 4) {
                     if (mOemModeMap == null) {
-                        mOemModeMap = new HashMap<String, HashMap<String,
-                                Pair<String, String>>>();
+                        mOemModeMap = new HashMap<>();
                     }
                     HashMap<String, Pair<String, String>> overrideMap
                             = mOemModeMap.get(items[0]);
                     if (overrideMap == null) {
-                        overrideMap = new HashMap<String,
-                                Pair<String, String>>();
+                        overrideMap = new HashMap<>();
                         mOemModeMap.put(items[0], overrideMap);
                     }
 
                     // Favoring the first combination if duplicate exists
                     if (!overrideMap.containsKey(items[1])) {
                         if (items.length == 3) {
-                            overrideMap.put(items[1],
-                                    new Pair<String, String>(items[2], ""));
+                            overrideMap.put(items[1], new Pair<>(items[2], ""));
                         } else {
-                            overrideMap.put(items[1],
-                                    new Pair<String, String>(items[2], items[3]));
+                            overrideMap.put(items[1], new Pair<>(items[2], items[3]));
                         }
                     }
                 }
@@ -1390,7 +1376,7 @@
         String bootMode = SystemProperties.get(BOOT_MODE_PROPERTY, "unknown");
         String persistProp = USB_PERSISTENT_CONFIG_PROPERTY;
         if (!(bootMode.equals(NORMAL_BOOT) || bootMode.equals("unknown"))) {
-            if (functions == true) {
+            if (functions) {
                 persistProp = "persist.sys.usb." + bootMode + ".func";
             } else {
                 persistProp = "persist.sys.usb." + bootMode + ".config";
diff --git a/services/usb/java/com/android/server/usb/UsbHostManager.java b/services/usb/java/com/android/server/usb/UsbHostManager.java
index af78c05..737b572 100644
--- a/services/usb/java/com/android/server/usb/UsbHostManager.java
+++ b/services/usb/java/com/android/server/usb/UsbHostManager.java
@@ -16,7 +16,6 @@
 
 package com.android.server.usb;
 
-import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.ComponentName;
 import android.content.Context;
@@ -44,13 +43,11 @@
     private static final boolean DEBUG = false;
 
     // contains all connected USB devices
-    private final HashMap<String, UsbDevice> mDevices = new HashMap<String, UsbDevice>();
-
+    private final HashMap<String, UsbDevice> mDevices = new HashMap<>();
 
     // USB busses to exclude from USB host support
     private final String[] mHostBlacklist;
 
-    private final Context mContext;
     private final Object mLock = new Object();
 
     private UsbDevice mNewDevice;
@@ -71,7 +68,6 @@
 
     public UsbHostManager(Context context, UsbAlsaManager alsaManager,
             UsbSettingsManager settingsManager) {
-        mContext = context;
         mHostBlacklist = context.getResources().getStringArray(
                 com.android.internal.R.array.config_usbHostBlacklist);
         mUsbAlsaManager = alsaManager;
@@ -119,17 +115,14 @@
     }
 
     /* returns true if the USB device should not be accessible by applications */
-    private boolean isBlackListed(int clazz, int subClass, int protocol) {
+    private boolean isBlackListed(int clazz, int subClass) {
         // blacklist hubs
         if (clazz == UsbConstants.USB_CLASS_HUB) return true;
 
         // blacklist HID boot devices (mouse and keyboard)
-        if (clazz == UsbConstants.USB_CLASS_HID &&
-                subClass == UsbConstants.USB_INTERFACE_SUBCLASS_BOOT) {
-            return true;
-        }
+        return clazz == UsbConstants.USB_CLASS_HID
+                && subClass == UsbConstants.USB_INTERFACE_SUBCLASS_BOOT;
 
-        return false;
     }
 
     /* Called from JNI in monitorUsbHostBus() to report new USB devices
@@ -137,6 +130,7 @@
        interfaces and endpoints, and finally call endUsbDeviceAdded after all descriptors
        have been processed
      */
+    @SuppressWarnings("unused")
     private boolean beginUsbDeviceAdded(String deviceName, int vendorID, int productID,
             int deviceClass, int deviceSubclass, int deviceProtocol,
             String manufacturerName, String productName, int version, String serialNumber) {
@@ -161,7 +155,7 @@
         // such test until endUsbDeviceAdded() when we have that info.
 
         if (isBlackListed(deviceName) ||
-                isBlackListed(deviceClass, deviceSubclass, deviceProtocol)) {
+                isBlackListed(deviceClass, deviceSubclass)) {
             return false;
         }
 
@@ -183,9 +177,9 @@
                     deviceClass, deviceSubclass, deviceProtocol,
                     manufacturerName, productName, versionString, serialNumber);
 
-            mNewConfigurations = new ArrayList<UsbConfiguration>();
-            mNewInterfaces = new ArrayList<UsbInterface>();
-            mNewEndpoints = new ArrayList<UsbEndpoint>();
+            mNewConfigurations = new ArrayList<>();
+            mNewInterfaces = new ArrayList<>();
+            mNewEndpoints = new ArrayList<>();
         }
 
         return true;
@@ -194,6 +188,7 @@
     /* Called from JNI in monitorUsbHostBus() to report new USB configuration for the device
        currently being added.  Returns true if successful, false in case of error.
      */
+    @SuppressWarnings("unused")
     private void addUsbConfiguration(int id, String name, int attributes, int maxPower) {
         if (mNewConfiguration != null) {
             mNewConfiguration.setInterfaces(
@@ -208,6 +203,7 @@
     /* Called from JNI in monitorUsbHostBus() to report new USB interface for the device
        currently being added.  Returns true if successful, false in case of error.
      */
+    @SuppressWarnings("unused")
     private void addUsbInterface(int id, String name, int altSetting,
             int Class, int subClass, int protocol) {
         if (mNewInterface != null) {
@@ -223,11 +219,13 @@
     /* Called from JNI in monitorUsbHostBus() to report new USB endpoint for the device
        currently being added.  Returns true if successful, false in case of error.
      */
+    @SuppressWarnings("unused")
     private void addUsbEndpoint(int address, int attributes, int maxPacketSize, int interval) {
         mNewEndpoints.add(new UsbEndpoint(address, attributes, maxPacketSize, interval));
     }
 
     /* Called from JNI in monitorUsbHostBus() to finish adding a new device */
+    @SuppressWarnings("unused")
     private void endUsbDeviceAdded() {
         if (DEBUG) {
             Slog.d(TAG, "usb:UsbHostManager.endUsbDeviceAdded()");
@@ -273,6 +271,7 @@
     }
 
     /* Called from JNI in monitorUsbHostBus to report USB device removal */
+    @SuppressWarnings("unused")
     private void usbDeviceRemoved(String deviceName) {
         synchronized (mLock) {
             UsbDevice device = mDevices.remove(deviceName);
@@ -288,11 +287,7 @@
         synchronized (mLock) {
             // Create a thread to call into native code to wait for USB host events.
             // This thread will call us back on usbDeviceAdded and usbDeviceRemoved.
-            Runnable runnable = new Runnable() {
-                public void run() {
-                    monitorUsbHostBus();
-                }
-            };
+            Runnable runnable = this::monitorUsbHostBus;
             new Thread(null, runnable, "UsbService host thread").start();
         }
     }
diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java
index 7e2496c..9d800ad 100644
--- a/services/usb/java/com/android/server/usb/UsbPortManager.java
+++ b/services/usb/java/com/android/server/usb/UsbPortManager.java
@@ -87,9 +87,6 @@
     // Mostly due a command sent by the remote Usb device.
     private HALCallback mHALCallback = new HALCallback(null, this);
 
-    // Notification object used to listen to the start of the usb daemon.
-    private final ServiceNotification mServiceNotification = new ServiceNotification();
-
     // Cookie sent for usb hal death notification.
     private static final int USB_HAL_DEATH_COOKIE = 1000;
 
@@ -107,18 +104,20 @@
     // Ports may temporarily have different dispositions as they are added or removed
     // but the class invariant is that this list will only contain ports with DISPOSITION_READY
     // except while updatePortsLocked() is in progress.
-    private final ArrayMap<String, PortInfo> mPorts = new ArrayMap<String, PortInfo>();
+    private final ArrayMap<String, PortInfo> mPorts = new ArrayMap<>();
 
     // List of all simulated ports, indexed by id.
     private final ArrayMap<String, RawPortInfo> mSimulatedPorts =
-            new ArrayMap<String, RawPortInfo>();
+            new ArrayMap<>();
 
     public UsbPortManager(Context context) {
         mContext = context;
         try {
+            ServiceNotification serviceNotification = new ServiceNotification();
+
             boolean ret = IServiceManager.getService()
                     .registerForNotifications("android.hardware.usb@1.0::IUsb",
-                            "", mServiceNotification);
+                            "", serviceNotification);
             if (!ret) {
                 logAndPrint(Log.ERROR, null,
                         "Failed to register service start notification");
@@ -258,7 +257,6 @@
                         logAndPrintException(pw, "Failed to set the USB port mode: "
                                 + "portId=" + portId
                                 + ", newMode=" + UsbPort.modeToString(newRole.role), e);
-                        return;
                     }
                 } else {
                     // Change power and data role independently as needed.
@@ -289,7 +287,6 @@
                                             + ", newDataRole=" + UsbPort.dataRoleToString(newRole
                                             .role),
                                     e);
-                            return;
                         }
                     }
                 }
@@ -415,10 +412,6 @@
         public IndentingPrintWriter pw;
         public UsbPortManager portManager;
 
-        HALCallback() {
-            super();
-        }
-
         HALCallback(IndentingPrintWriter pw, UsbPortManager portManager) {
             this.pw = pw;
             this.portManager = portManager;
@@ -434,7 +427,7 @@
                 return;
             }
 
-            ArrayList<RawPortInfo> newPortInfo = new ArrayList<RawPortInfo>();
+            ArrayList<RawPortInfo> newPortInfo = new ArrayList<>();
 
             for (PortStatus current : currentPortStatus) {
                 RawPortInfo temp = new RawPortInfo(current.portName,
@@ -452,7 +445,6 @@
             message.what = MSG_UPDATE_PORTS;
             message.setData(bundle);
             portManager.mHandler.sendMessage(message);
-            return;
         }
 
 
@@ -467,7 +459,7 @@
                 return;
             }
 
-            ArrayList<RawPortInfo> newPortInfo = new ArrayList<RawPortInfo>();
+            ArrayList<RawPortInfo> newPortInfo = new ArrayList<>();
 
             for (PortStatus_1_1 current : currentPortStatus) {
                 RawPortInfo temp = new RawPortInfo(current.status.portName,
@@ -485,7 +477,6 @@
             message.what = MSG_UPDATE_PORTS;
             message.setData(bundle);
             portManager.mHandler.sendMessage(message);
-            return;
         }
 
         public void notifyRoleSwitchStatus(String portName, PortRole role, int retval) {
@@ -495,7 +486,7 @@
                 logAndPrint(Log.ERROR, pw, portName + " role switch failed");
             }
         }
-    };
+    }
 
     final class DeathRecipient implements HwBinder.DeathRecipient {
         public IndentingPrintWriter pw;
diff --git a/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java b/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java
index 840ae22..ebb5a62 100644
--- a/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java
+++ b/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java
@@ -225,7 +225,7 @@
                 } else if ("serial-number".equals(name)) {
                     serialNumber = value;
                 } else {
-                    int intValue = -1;
+                    int intValue;
                     int radix = 10;
                     if (value != null && value.length() > 2 && value.charAt(0) == '0' &&
                         (value.charAt(1) == 'x' || value.charAt(1) == 'X')) {
@@ -388,9 +388,9 @@
                      (filter.mSerialNumber != null &&
                         mSerialNumber != null &&
                         !mSerialNumber.equals(filter.mSerialNumber))) {
-                    return(false);
+                    return false;
                 }
-                return(true);
+                return true;
             }
             if (obj instanceof UsbDevice) {
                 UsbDevice device = (UsbDevice)obj;
@@ -415,7 +415,7 @@
                             !mProductName.equals(device.getProductName())) ||
                         (device.getSerialNumber() != null &&
                             !mSerialNumber.equals(device.getSerialNumber()))) {
-                    return(false);
+                    return false;
                 }
                 return true;
             }
@@ -501,8 +501,7 @@
         public boolean matches(UsbAccessory acc) {
             if (mManufacturer != null && !acc.getManufacturer().equals(mManufacturer)) return false;
             if (mModel != null && !acc.getModel().equals(mModel)) return false;
-            if (mVersion != null && !acc.getVersion().equals(mVersion)) return false;
-            return true;
+            return !(mVersion != null && !acc.getVersion().equals(mVersion));
         }
 
         /**
@@ -517,8 +516,7 @@
                 return false;
             }
             if (mModel != null && !Objects.equals(accessory.mModel, mModel)) return false;
-            if (mVersion != null && !Objects.equals(accessory.mVersion, mVersion)) return false;
-            return true;
+            return !(mVersion != null && !Objects.equals(accessory.mVersion, mVersion));
         }
 
         @Override
@@ -624,13 +622,8 @@
         mPackageMonitor.register(context, null, UserHandle.ALL, true);
         mMtpNotificationManager = new MtpNotificationManager(
                 parentUserContext,
-                new MtpNotificationManager.OnOpenInAppListener() {
-                    @Override
-                    public void onOpenInApp(UsbDevice device) {
-                        resolveActivity(createDeviceAttachedIntent(device),
-                                device, false /* showMtpNotification */);
-                    }
-                });
+                device -> resolveActivity(createDeviceAttachedIntent(device),
+                        device, false /* showMtpNotification */));
     }
 
     /**
@@ -727,9 +720,7 @@
                         XmlUtils.nextElement(parser);
                     }
                 }
-            } catch (IOException e) {
-                Log.wtf(TAG, "Failed to read single-user settings", e);
-            } catch (XmlPullParserException e) {
+            } catch (IOException | XmlPullParserException e) {
                 Log.wtf(TAG, "Failed to read single-user settings", e);
             } finally {
                 IoUtils.closeQuietly(fis);
@@ -1015,8 +1006,8 @@
         }
     }
 
-    private final ArrayList<ResolveInfo> getDeviceMatchesLocked(UsbDevice device, Intent intent) {
-        ArrayList<ResolveInfo> matches = new ArrayList<ResolveInfo>();
+    private ArrayList<ResolveInfo> getDeviceMatchesLocked(UsbDevice device, Intent intent) {
+        ArrayList<ResolveInfo> matches = new ArrayList<>();
         List<ResolveInfo> resolveInfos = queryIntentActivitiesForAllProfiles(intent);
         int count = resolveInfos.size();
         for (int i = 0; i < count; i++) {
@@ -1029,9 +1020,9 @@
         return removeForwardIntentIfNotNeeded(preferHighPriority(matches));
     }
 
-    private final ArrayList<ResolveInfo> getAccessoryMatchesLocked(
+    private ArrayList<ResolveInfo> getAccessoryMatchesLocked(
             UsbAccessory accessory, Intent intent) {
-        ArrayList<ResolveInfo> matches = new ArrayList<ResolveInfo>();
+        ArrayList<ResolveInfo> matches = new ArrayList<>();
         List<ResolveInfo> resolveInfos = queryIntentActivitiesForAllProfiles(intent);
         int count = resolveInfos.size();
         for (int i = 0; i < count; i++) {
@@ -1402,7 +1393,7 @@
     void setDevicePackage(@NonNull UsbDevice device, @Nullable String packageName,
             @NonNull UserHandle user) {
         DeviceFilter filter = new DeviceFilter(device);
-        boolean changed = false;
+        boolean changed;
         synchronized (mLock) {
             if (packageName == null) {
                 changed = (mDevicePreferenceMap.remove(filter) != null);
@@ -1430,7 +1421,7 @@
     void setAccessoryPackage(@NonNull UsbAccessory accessory, @Nullable String packageName,
             @NonNull UserHandle user) {
         AccessoryFilter filter = new AccessoryFilter(accessory);
-        boolean changed = false;
+        boolean changed;
         synchronized (mLock) {
             if (packageName == null) {
                 changed = (mAccessoryPreferenceMap.remove(filter) != null);
@@ -1460,8 +1451,7 @@
         UserPackage userPackage = new UserPackage(packageName, user);
         synchronized (mLock) {
             if (mDevicePreferenceMap.values().contains(userPackage)) return true;
-            if (mAccessoryPreferenceMap.values().contains(userPackage)) return true;
-            return false;
+            return mAccessoryPreferenceMap.values().contains(userPackage);
         }
     }
 
@@ -1493,9 +1483,9 @@
         synchronized (mLock) {
             if (mDevicePreferenceMap.containsValue(userPackage)) {
                 // make a copy of the key set to avoid ConcurrentModificationException
-                Object[] keys = mDevicePreferenceMap.keySet().toArray();
+                DeviceFilter[] keys = mDevicePreferenceMap.keySet().toArray(new DeviceFilter[0]);
                 for (int i = 0; i < keys.length; i++) {
-                    Object key = keys[i];
+                    DeviceFilter key = keys[i];
                     if (userPackage.equals(mDevicePreferenceMap.get(key))) {
                         mDevicePreferenceMap.remove(key);
                         cleared = true;
@@ -1504,9 +1494,10 @@
             }
             if (mAccessoryPreferenceMap.containsValue(userPackage)) {
                 // make a copy of the key set to avoid ConcurrentModificationException
-                Object[] keys = mAccessoryPreferenceMap.keySet().toArray();
+                AccessoryFilter[] keys =
+                        mAccessoryPreferenceMap.keySet().toArray(new AccessoryFilter[0]);
                 for (int i = 0; i < keys.length; i++) {
-                    Object key = keys[i];
+                    AccessoryFilter key = keys[i];
                     if (userPackage.equals(mAccessoryPreferenceMap.get(key))) {
                         mAccessoryPreferenceMap.remove(key);
                         cleared = true;
diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java
index 61e1e8f..e4fcea7 100644
--- a/services/usb/java/com/android/server/usb/UsbService.java
+++ b/services/usb/java/com/android/server/usb/UsbService.java
@@ -134,25 +134,25 @@
 
         onSwitchUser(UserHandle.USER_SYSTEM);
 
+        BroadcastReceiver receiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                final String action = intent.getAction();
+                if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
+                        .equals(action)) {
+                    if (mDeviceManager != null) {
+                        mDeviceManager.updateUserRestrictions();
+                    }
+                }
+            }
+        };
+
         final IntentFilter filter = new IntentFilter();
         filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
         filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
-        mContext.registerReceiver(mReceiver, filter, null, null);
+        mContext.registerReceiver(receiver, filter, null, null);
     }
 
-    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            final String action = intent.getAction();
-            if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
-                    .equals(action)) {
-                if (mDeviceManager != null) {
-                    mDeviceManager.updateUserRestrictions();
-                }
-            }
-        }
-    };
-
     /**
      * Set new {@link #mCurrentUserId} and propagate it to other modules.
      *
@@ -681,7 +681,7 @@
         }
     }
 
-    private static final String removeLastChar(String value) {
+    private static String removeLastChar(String value) {
         return value.substring(0, value.length() - 1);
     }
 }
diff --git a/services/usb/java/com/android/server/usb/UsbSettingsManager.java b/services/usb/java/com/android/server/usb/UsbSettingsManager.java
index 7a55be4..c7e5998d 100644
--- a/services/usb/java/com/android/server/usb/UsbSettingsManager.java
+++ b/services/usb/java/com/android/server/usb/UsbSettingsManager.java
@@ -28,6 +28,7 @@
 import android.os.UserManager;
 import android.util.Slog;
 import android.util.SparseArray;
+
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.IndentingPrintWriter;
 
diff --git a/services/usb/java/com/android/server/usb/UsbUserSettingsManager.java b/services/usb/java/com/android/server/usb/UsbUserSettingsManager.java
index 4a34ece..96c5211 100644
--- a/services/usb/java/com/android/server/usb/UsbUserSettingsManager.java
+++ b/services/usb/java/com/android/server/usb/UsbUserSettingsManager.java
@@ -32,6 +32,7 @@
 import android.os.UserHandle;
 import android.util.Slog;
 import android.util.SparseBooleanArray;
+
 import com.android.internal.util.IndentingPrintWriter;
 
 import java.util.HashMap;
@@ -48,10 +49,10 @@
 
     // Temporary mapping USB device name to list of UIDs with permissions for the device
     private final HashMap<String, SparseBooleanArray> mDevicePermissionMap =
-            new HashMap<String, SparseBooleanArray>();
+            new HashMap<>();
     // Temporary mapping UsbAccessory to list of UIDs with permissions for the accessory
     private final HashMap<UsbAccessory, SparseBooleanArray> mAccessoryPermissionMap =
-            new HashMap<UsbAccessory, SparseBooleanArray>();
+            new HashMap<>();
 
     private final Object mLock = new Object();
 
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index c147578..c1289d3 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -188,6 +188,19 @@
      */
     public static final String EVENT_HANDOVER_COMPLETE =
             "android.telecom.event.HANDOVER_COMPLETE";
+
+    /**
+     * Call event sent from Telecom to the handover destination {@link ConnectionService} via
+     * {@link Connection#onCallEvent(String, Bundle)} to inform the handover destination that the
+     * source connection has disconnected.  The {@link Bundle} parameter for the call event will be
+     * {@code null}.
+     * <p>
+     * A handover is initiated with the {@link #EVENT_REQUEST_HANDOVER} call event.
+     * @hide
+     */
+    public static final String EVENT_HANDOVER_SOURCE_DISCONNECTED =
+            "android.telecom.event.HANDOVER_SOURCE_DISCONNECTED";
+
     /**
      * Call event sent from Telecom to the handover {@link ConnectionService} via
      * {@link Connection#onCallEvent(String, Bundle)} to inform a {@link Connection} that a handover
diff --git a/telecomm/java/android/telecom/Log.java b/telecomm/java/android/telecom/Log.java
index de20538..3361b5b 100644
--- a/telecomm/java/android/telecom/Log.java
+++ b/telecomm/java/android/telecom/Log.java
@@ -56,7 +56,7 @@
     public static boolean ERROR = isLoggable(android.util.Log.ERROR);
 
     private static final boolean FORCE_LOGGING = false; /* STOP SHIP if true */
-    private static final boolean USER_BUILD = Build.TYPE.equals("user");
+    private static final boolean USER_BUILD = Build.IS_USER;
 
     // Used to synchronize singleton logging lazy initialization
     private static final Object sSingletonSync = new Object();
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 8be30d2..52b64b6 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1455,23 +1455,6 @@
             "disable_voice_barring_notification_bool";
 
     /**
-     * URL from which the proto containing the public key of the Carrier used for
-     * IMSI encryption will be downloaded.
-     * @hide
-     */
-    public static final String IMSI_KEY_DOWNLOAD_URL_STRING = "imsi_key_download_url_string";
-
-    /**
-     * Time in days, after which the key will expire, and a new key will need to be downloaded.
-     * default value is {@link IMSI_ENCRYPTION_DAYS_TIME_DISABLED}, and indicates that IMSI
-     * encryption is not enabled by default for a carrier. Value of 0 indicates that the key
-     * does not expire.
-     * @hide
-     */
-    public static final String IMSI_KEY_EXPIRATION_DAYS_TIME_INT =
-            "imsi_key_expiration_days_time_int";
-
-    /**
      * List of operators considered non-roaming which won't show roaming icon.
      * <p>
      * Can use mcc or mcc+mnc as item. For example, 302 or 21407.
@@ -1495,6 +1478,23 @@
     public static final String KEY_ROAMING_OPERATOR_STRING_ARRAY =
             "roaming_operator_string_array";
 
+    /**
+     * URL from which the proto containing the public key of the Carrier used for
+     * IMSI encryption will be downloaded.
+     * @hide
+     */
+    public static final String IMSI_KEY_DOWNLOAD_URL_STRING = "imsi_key_download_url_string";
+
+    /**
+     * Time in days, after which the key will expire, and a new key will need to be downloaded.
+     * default value is {@link IMSI_ENCRYPTION_DAYS_TIME_DISABLED}, and indicates that IMSI
+     * encryption is not enabled by default for a carrier. Value of 0 indicates that the key
+     * does not expire.
+     * @hide
+     */
+    public static final String IMSI_KEY_EXPIRATION_DAYS_TIME_INT =
+            "imsi_key_expiration_days_time_int";
+
     /** The default value for every variable. */
     private final static PersistableBundle sDefaults;
 
@@ -1747,6 +1747,8 @@
         sDefaults.putString(IMSI_KEY_DOWNLOAD_URL_STRING, null);
         sDefaults.putStringArray(KEY_NON_ROAMING_OPERATOR_STRING_ARRAY, null);
         sDefaults.putStringArray(KEY_ROAMING_OPERATOR_STRING_ARRAY, null);
+        sDefaults.putInt(IMSI_KEY_EXPIRATION_DAYS_TIME_INT, IMSI_ENCRYPTION_DAYS_TIME_DISABLED);
+        sDefaults.putString(IMSI_KEY_DOWNLOAD_URL_STRING, null);
     }
 
     /**
diff --git a/telephony/java/android/telephony/Rlog.java b/telephony/java/android/telephony/Rlog.java
index 2a31e3a..e0b46e1 100644
--- a/telephony/java/android/telephony/Rlog.java
+++ b/telephony/java/android/telephony/Rlog.java
@@ -33,7 +33,7 @@
  */
 public final class Rlog {
 
-    private static final boolean USER_BUILD = Build.TYPE.equals("user");
+    private static final boolean USER_BUILD = Build.IS_USER;
 
     private Rlog() {
     }
diff --git a/telephony/java/android/telephony/TelephonyScanManager.java b/telephony/java/android/telephony/TelephonyScanManager.java
index c905d3a..92a21b6 100644
--- a/telephony/java/android/telephony/TelephonyScanManager.java
+++ b/telephony/java/android/telephony/TelephonyScanManager.java
@@ -20,15 +20,18 @@
 
 import android.content.Context;
 import android.os.Binder;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.Message;
 import android.os.Messenger;
+import android.os.Parcelable;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.util.Log;
 import android.util.SparseArray;
+import java.util.Arrays;
 import java.util.List;
 
 import com.android.internal.telephony.ITelephony;
@@ -42,6 +45,9 @@
     private static final String TAG = "TelephonyScanManager";
 
     /** @hide */
+    public static final String SCAN_RESULT_KEY = "scanResult";
+
+    /** @hide */
     public static final int CALLBACK_SCAN_RESULTS = 1;
     /** @hide */
     public static final int CALLBACK_SCAN_ERROR = 2;
@@ -112,7 +118,13 @@
                 switch (message.what) {
                     case CALLBACK_SCAN_RESULTS:
                         try {
-                            callback.onResults((List<CellInfo>) message.obj);
+                            final Bundle b = message.getData();
+                            final Parcelable[] parcelables = b.getParcelableArray(SCAN_RESULT_KEY);
+                            CellInfo[] ci = new CellInfo[parcelables.length];
+                            for (int i = 0; i < parcelables.length; i++) {
+                                ci[i] = (CellInfo) parcelables[i];
+                            }
+                            callback.onResults((List<CellInfo>) Arrays.asList(ci));
                         } catch (Exception e) {
                             Rlog.e(TAG, "Exception in networkscan callback onResults", e);
                         }
diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java
index 11770fb..8304d84 100644
--- a/telephony/java/android/telephony/euicc/EuiccManager.java
+++ b/telephony/java/android/telephony/euicc/EuiccManager.java
@@ -320,7 +320,8 @@
             return;
         }
         try {
-            mController.getDownloadableSubscriptionMetadata(subscription, callbackIntent);
+            mController.getDownloadableSubscriptionMetadata(
+                    subscription, mContext.getOpPackageName(), callbackIntent);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -349,7 +350,8 @@
             return;
         }
         try {
-            mController.getDefaultDownloadableSubscriptionList(callbackIntent);
+            mController.getDefaultDownloadableSubscriptionList(
+                    mContext.getOpPackageName(), callbackIntent);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -473,6 +475,36 @@
         }
     }
 
+    /**
+     * Ensure that subscriptions will be retained on the next factory reset.
+     *
+     * <p>By default, all subscriptions on the eUICC are erased the first time a device boots (ever
+     * and after factory resets). This ensures that the data is wiped after a factory reset is
+     * performed via fastboot or recovery mode, as these modes do not support the necessary radio
+     * communication needed to wipe the eSIM.
+     *
+     * <p>However, this method may be called right before a factory reset issued via settings when
+     * the user elects to retain subscriptions. Doing so will mark them for retention so that they
+     * are not cleared after the ensuing reset.
+     *
+     * <p>Requires that the calling app has the {@link android.Manifest.permission#MASTER_CLEAR}
+     * permission. This is for internal system use only.
+     *
+     * @param callbackIntent a PendingIntent to launch when the operation completes.
+     * @hide
+     */
+    public void retainSubscriptionsForFactoryReset(PendingIntent callbackIntent) {
+        if (!isEnabled()) {
+            sendUnavailableError(callbackIntent);
+            return;
+        }
+        try {
+            mController.retainSubscriptionsForFactoryReset(callbackIntent);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
     private static void sendUnavailableError(PendingIntent callbackIntent) {
         try {
             callbackIntent.send(EMBEDDED_SUBSCRIPTION_RESULT_ERROR);
diff --git a/telephony/java/android/telephony/ims/ImsServiceProxy.java b/telephony/java/android/telephony/ims/ImsServiceProxy.java
index a75cd86..038e295 100644
--- a/telephony/java/android/telephony/ims/ImsServiceProxy.java
+++ b/telephony/java/android/telephony/ims/ImsServiceProxy.java
@@ -90,11 +90,11 @@
                         " status: " + status);
                 if (mSlotId == slotId && feature == mSupportedFeature) {
                     mFeatureStatusCached = status;
+                    if (mStatusCallback != null) {
+                        mStatusCallback.notifyStatusChanged();
+                    }
                 }
             }
-            if (mStatusCallback != null) {
-                mStatusCallback.notifyStatusChanged();
-            }
         }
     };
 
@@ -129,7 +129,9 @@
     @Override
     public void endSession(int sessionId) throws RemoteException {
         synchronized (mLock) {
-            checkServiceIsReady();
+            // Only check to make sure the binder connection still exists. This method should
+            // still be able to be called when the state is STATE_NOT_AVAILABLE.
+            checkBinderConnection();
             getServiceInterface(mBinder).endSession(mSlotId, mSupportedFeature, sessionId);
         }
     }
diff --git a/telephony/java/com/android/ims/ImsConfig.java b/telephony/java/com/android/ims/ImsConfig.java
index c301029..e7b22bd 100644
--- a/telephony/java/com/android/ims/ImsConfig.java
+++ b/telephony/java/com/android/ims/ImsConfig.java
@@ -697,4 +697,11 @@
                     ImsReasonInfo.CODE_LOCAL_SERVICE_UNAVAILABLE);
         }
     }
+
+    /**
+     * @return true if the binder connection is alive, false otherwise.
+     */
+    public boolean isBinderAlive() {
+        return miConfig.asBinder().isBinderAlive();
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/NetworkScanResult.java b/telephony/java/com/android/internal/telephony/NetworkScanResult.java
index 7a7c174..95f39d7 100644
--- a/telephony/java/com/android/internal/telephony/NetworkScanResult.java
+++ b/telephony/java/com/android/internal/telephony/NetworkScanResult.java
@@ -35,10 +35,10 @@
 public final class NetworkScanResult implements Parcelable {
 
     // Contains only part of the scan result and more are coming.
-    public static final int SCAN_STATUS_PARTIAL = 0;
+    public static final int SCAN_STATUS_PARTIAL = 1;
 
     // Contains the last part of the scan result and the scan is now complete.
-    public static final int SCAN_STATUS_COMPLETE = 1;
+    public static final int SCAN_STATUS_COMPLETE = 2;
 
     // The status of the scan, only valid when scanError = SUCCESS.
     public int scanStatus;
diff --git a/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl b/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl
index 725b89b..b3fc90d 100644
--- a/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl
+++ b/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl
@@ -26,8 +26,9 @@
 interface IEuiccController {
     oneway void continueOperation(in Intent resolutionIntent, in Bundle resolutionExtras);
     oneway void getDownloadableSubscriptionMetadata(in DownloadableSubscription subscription,
-        in PendingIntent callbackIntent);
-    oneway void getDefaultDownloadableSubscriptionList(in PendingIntent callbackIntent);
+        String callingPackage, in PendingIntent callbackIntent);
+    oneway void getDefaultDownloadableSubscriptionList(
+        String callingPackage, in PendingIntent callbackIntent);
     String getEid();
     oneway void downloadSubscription(in DownloadableSubscription subscription,
         boolean switchAfterDownload, String callingPackage, in PendingIntent callbackIntent);
@@ -39,4 +40,5 @@
     oneway void updateSubscriptionNickname(int subscriptionId, String nickname,
         in PendingIntent callbackIntent);
     oneway void eraseSubscriptions(in PendingIntent callbackIntent);
+    oneway void retainSubscriptionsForFactoryReset(in PendingIntent callbackIntent);
 }
\ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java b/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java
index f28d126..0fabc2f 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java
@@ -30,10 +30,6 @@
     /** Private constructor for utility class. */
     private SmsCbConstants() { }
 
-    /** Channel 50 required by Brazil. ID 0~999 is allocated by GSMA */
-    public static final int MESSAGE_ID_GSMA_ALLOCATED_CHANNEL_50
-            = 0x0032;
-
     /** Start of PWS Message Identifier range (includes ETWS and CMAS). */
     public static final int MESSAGE_ID_PWS_FIRST_IDENTIFIER
             = 0x1100; // 4352
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
index 582506a..d4098d9 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
@@ -278,6 +278,10 @@
                 scAddress, destinationAddress, mtiByte,
                 statusReportRequested, ret);
 
+        // Skip encoding pdu if error occurs when create pdu head and the error will be handled
+        // properly later on encodedMessage sanity check.
+        if (bo == null) return ret;
+
         // User Data (and length)
         byte[] userData;
         try {
@@ -420,6 +424,9 @@
                 scAddress, destinationAddress, (byte) 0x41, // MTI = SMS-SUBMIT,
                                                             // TP-UDHI = true
                 statusReportRequested, ret);
+        // Skip encoding pdu if error occurs when create pdu head and the error will be handled
+        // properly later on encodedMessage sanity check.
+        if (bo == null) return ret;
 
         // TP-Data-Coding-Scheme
         // No class, 8 bit data
@@ -451,7 +458,7 @@
      * @param destinationAddress the address of the destination for the message
      * @param mtiByte
      * @param ret <code>SubmitPdu</code> containing the encoded SC
-     *        address, if applicable, and the encoded message
+     *        address, if applicable, and the encoded message. Returns null on encode error.
      */
     private static ByteArrayOutputStream getSubmitPduHead(
             String scAddress, String destinationAddress, byte mtiByte,
@@ -482,6 +489,9 @@
 
         daBytes = PhoneNumberUtils.networkPortionToCalledPartyBCD(destinationAddress);
 
+        // return empty pduHead for invalid destination address
+        if (daBytes == null) return null;
+
         // destination address length in BCD digits, ignoring TON byte and pad
         // TODO Should be better.
         bo.write((daBytes.length - 1) * 2
diff --git a/test-runner/src/android/test/ClassPathPackageInfo.java b/test-runner/src/android/test/ClassPathPackageInfo.java
deleted file mode 100644
index 2cf76af..0000000
--- a/test-runner/src/android/test/ClassPathPackageInfo.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.test;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * The Package object doesn't allow you to iterate over the contained
- * classes and subpackages of that package.  This is a version that does.
- *
- * {@hide} Not needed for 1.0 SDK.
- */
-@Deprecated
-public class ClassPathPackageInfo {
-
-    private final ClassPathPackageInfoSource source;
-    private final String packageName;
-    private final Set<String> subpackageNames;
-    private final Set<Class<?>> topLevelClasses;
-
-    ClassPathPackageInfo(ClassPathPackageInfoSource source, String packageName,
-            Set<String> subpackageNames, Set<Class<?>> topLevelClasses) {
-        this.source = source;
-        this.packageName = packageName;
-        this.subpackageNames = Collections.unmodifiableSet(subpackageNames);
-        this.topLevelClasses = Collections.unmodifiableSet(topLevelClasses);
-    }
-
-    public Set<ClassPathPackageInfo> getSubpackages() {
-        Set<ClassPathPackageInfo> info = new HashSet<>();
-        for (String name : subpackageNames) {
-            info.add(source.getPackageInfo(name));
-        }
-        return info;
-    }
-
-    public Set<Class<?>> getTopLevelClassesRecursive() {
-        Set<Class<?>> set = new HashSet<>();
-        addTopLevelClassesTo(set);
-        return set;
-    }
-
-    private void addTopLevelClassesTo(Set<Class<?>> set) {
-        set.addAll(topLevelClasses);
-        for (ClassPathPackageInfo info : getSubpackages()) {
-            info.addTopLevelClassesTo(set);
-        }
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj instanceof ClassPathPackageInfo) {
-            ClassPathPackageInfo that = (ClassPathPackageInfo) obj;
-            return (this.packageName).equals(that.packageName);
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return packageName.hashCode();
-    }
-}
diff --git a/test-runner/src/android/test/ClassPathPackageInfoSource.java b/test-runner/src/android/test/ClassPathPackageInfoSource.java
index 9bcc25a..755b540 100644
--- a/test-runner/src/android/test/ClassPathPackageInfoSource.java
+++ b/test-runner/src/android/test/ClassPathPackageInfoSource.java
@@ -21,15 +21,12 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.util.Collections;
 import java.util.Enumeration;
-import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Map;
 import java.util.Set;
 import java.util.TreeSet;
 import java.util.regex.Pattern;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
 
 /**
  * Generate {@link ClassPathPackageInfo}s by scanning apk paths.
@@ -39,11 +36,13 @@
 @Deprecated
 public class ClassPathPackageInfoSource {
 
-    private static final String CLASS_EXTENSION = ".class";
-
     private static final ClassLoader CLASS_LOADER
             = ClassPathPackageInfoSource.class.getClassLoader();
 
+    private static String[] apkPaths;
+
+    private static ClassPathPackageInfoSource classPathSource;
+
     private final SimpleCache<String, ClassPathPackageInfo> cache =
             new SimpleCache<String, ClassPathPackageInfo>() {
                 @Override
@@ -54,23 +53,28 @@
 
     // The class path of the running application
     private final String[] classPath;
-    private static String[] apkPaths;
 
-    // A cache of jar file contents
-    private final Map<File, Set<String>> jarFiles = new HashMap<>();
-    private ClassLoader classLoader;
+    private final ClassLoader classLoader;
 
-    ClassPathPackageInfoSource() {
+    private ClassPathPackageInfoSource(ClassLoader classLoader) {
+        this.classLoader = classLoader;
         classPath = getClassPath();
     }
 
-
-    public static void setApkPaths(String[] apkPaths) {
+    static void setApkPaths(String[] apkPaths) {
         ClassPathPackageInfoSource.apkPaths = apkPaths;
     }
 
-    public ClassPathPackageInfo getPackageInfo(String pkgName) {
-        return cache.get(pkgName);
+    public static ClassPathPackageInfoSource forClassPath(ClassLoader classLoader) {
+        if (classPathSource == null) {
+            classPathSource = new ClassPathPackageInfoSource(classLoader);
+        }
+        return classPathSource;
+    }
+
+    public Set<Class<?>> getTopLevelClassesRecursive(String packageName) {
+        ClassPathPackageInfo packageInfo = cache.get(packageName);
+        return packageInfo.getTopLevelClassesRecursive();
     }
 
     private ClassPathPackageInfo createPackageInfo(String packageName) {
@@ -96,7 +100,7 @@
                         + "'. Message: " + e.getMessage(), e);
             }
         }
-        return new ClassPathPackageInfo(this, packageName, subpackageNames,
+        return new ClassPathPackageInfo(packageName, subpackageNames,
                 topLevelClasses);
     }
 
@@ -107,9 +111,6 @@
      */
     private void findClasses(String packageName, Set<String> classNames,
             Set<String> subpackageNames) {
-        String packagePrefix = packageName + '.';
-        String pathPrefix = packagePrefix.replace('.', '/');
-
         for (String entryName : classPath) {
             File classPathEntry = new File(entryName);
 
@@ -150,58 +151,6 @@
 
     /**
      * Finds all classes and sub packages that are below the packageName and
-     * add them to the respective sets. Searches the package in a class directory.
-     */
-    private void findClassesInDirectory(File classDir,
-            String packagePrefix, String pathPrefix, Set<String> classNames,
-            Set<String> subpackageNames)
-            throws IOException {
-        File directory = new File(classDir, pathPrefix);
-
-        if (directory.exists()) {
-            for (File f : directory.listFiles()) {
-                String name = f.getName();
-                if (name.endsWith(CLASS_EXTENSION) && isToplevelClass(name)) {
-                    classNames.add(packagePrefix + getClassName(name));
-                } else if (f.isDirectory()) {
-                    subpackageNames.add(packagePrefix + name);
-                }
-            }
-        }
-    }
-
-    /**
-     * Finds all classes and sub packages that are below the packageName and
-     * add them to the respective sets. Searches the package in a single jar file.
-     */
-    private void findClassesInJar(File jarFile, String pathPrefix,
-            Set<String> classNames, Set<String> subpackageNames)
-            throws IOException {
-        Set<String> entryNames = getJarEntries(jarFile);
-        // check if the Jar contains the package.
-        if (!entryNames.contains(pathPrefix)) {
-            return;
-        }
-        int prefixLength = pathPrefix.length();
-        for (String entryName : entryNames) {
-            if (entryName.startsWith(pathPrefix)) {
-                if (entryName.endsWith(CLASS_EXTENSION)) {
-                    // check if the class is in the package itself or in one of its
-                    // subpackages.
-                    int index = entryName.indexOf('/', prefixLength);
-                    if (index >= 0) {
-                        String p = entryName.substring(0, index).replace('/', '.');
-                        subpackageNames.add(p);
-                    } else if (isToplevelClass(entryName)) {
-                        classNames.add(getClassName(entryName).replace('/', '.'));
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Finds all classes and sub packages that are below the packageName and
      * add them to the respective sets. Searches the package in a single apk file.
      */
     private void findClassesInApk(String apkPath, String packageName,
@@ -242,47 +191,6 @@
     }
 
     /**
-     * Gets the class and package entries from a Jar.
-     */
-    private Set<String> getJarEntries(File jarFile)
-            throws IOException {
-        Set<String> entryNames = jarFiles.get(jarFile);
-        if (entryNames == null) {
-            entryNames = new HashSet<>();
-            ZipFile zipFile = new ZipFile(jarFile);
-            Enumeration<? extends ZipEntry> entries = zipFile.entries();
-            while (entries.hasMoreElements()) {
-                String entryName = entries.nextElement().getName();
-                if (entryName.endsWith(CLASS_EXTENSION)) {
-                    // add the entry name of the class
-                    entryNames.add(entryName);
-
-                    // add the entry name of the classes package, i.e. the entry name of
-                    // the directory that the class is in. Used to quickly skip jar files
-                    // if they do not contain a certain package.
-                    //
-                    // Also add parent packages so that a JAR that contains
-                    // pkg1/pkg2/Foo.class will be marked as containing pkg1/ in addition
-                    // to pkg1/pkg2/ and pkg1/pkg2/Foo.class.  We're still interested in
-                    // JAR files that contains subpackages of a given package, even if
-                    // an intermediate package contains no direct classes.
-                    //
-                    // Classes in the default package will cause a single package named
-                    // "" to be added instead.
-                    int lastIndex = entryName.lastIndexOf('/');
-                    do {
-                        String packageName = entryName.substring(0, lastIndex + 1);
-                        entryNames.add(packageName);
-                        lastIndex = entryName.lastIndexOf('/', lastIndex - 1);
-                    } while (lastIndex > 0);
-                }
-            }
-            jarFiles.put(jarFile, entryNames);
-        }
-        return entryNames;
-    }
-
-    /**
      * Checks if a given file name represents a toplevel class.
      */
     private static boolean isToplevelClass(String fileName) {
@@ -290,14 +198,6 @@
     }
 
     /**
-     * Given the absolute path of a class file, return the class name.
-     */
-    private static String getClassName(String className) {
-        int classNameEnd = className.length() - CLASS_EXTENSION.length();
-        return className.substring(0, classNameEnd);
-    }
-
-    /**
      * Gets the class path from the System Property "java.class.path" and splits
      * it up into the individual elements.
      */
@@ -307,7 +207,56 @@
         return classPath.split(Pattern.quote(separator));
     }
 
-    public void setClassLoader(ClassLoader classLoader) {
-        this.classLoader = classLoader;
+    /**
+     * The Package object doesn't allow you to iterate over the contained
+     * classes and subpackages of that package.  This is a version that does.
+     */
+    private class ClassPathPackageInfo {
+
+        private final String packageName;
+        private final Set<String> subpackageNames;
+        private final Set<Class<?>> topLevelClasses;
+
+        private ClassPathPackageInfo(String packageName,
+                Set<String> subpackageNames, Set<Class<?>> topLevelClasses) {
+            this.packageName = packageName;
+            this.subpackageNames = Collections.unmodifiableSet(subpackageNames);
+            this.topLevelClasses = Collections.unmodifiableSet(topLevelClasses);
+        }
+
+        private Set<ClassPathPackageInfo> getSubpackages() {
+            Set<ClassPathPackageInfo> info = new HashSet<>();
+            for (String name : subpackageNames) {
+                info.add(cache.get(name));
+            }
+            return info;
+        }
+
+        private Set<Class<?>> getTopLevelClassesRecursive() {
+            Set<Class<?>> set = new HashSet<>();
+            addTopLevelClassesTo(set);
+            return set;
+        }
+
+        private void addTopLevelClassesTo(Set<Class<?>> set) {
+            set.addAll(topLevelClasses);
+            for (ClassPathPackageInfo info : getSubpackages()) {
+                info.addTopLevelClassesTo(set);
+            }
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof ClassPathPackageInfo) {
+                ClassPathPackageInfo that = (ClassPathPackageInfo) obj;
+                return (this.packageName).equals(that.packageName);
+            }
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            return packageName.hashCode();
+        }
     }
 }
diff --git a/test-runner/src/android/test/InstrumentationTestRunner.java b/test-runner/src/android/test/InstrumentationTestRunner.java
index 29e21a7..b2582c1 100644
--- a/test-runner/src/android/test/InstrumentationTestRunner.java
+++ b/test-runner/src/android/test/InstrumentationTestRunner.java
@@ -16,8 +16,9 @@
 
 package android.test;
 
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.SmallTest;
 import com.android.internal.util.Predicate;
-import com.android.internal.util.Predicates;
 
 import android.app.Activity;
 import android.app.Instrumentation;
@@ -27,7 +28,6 @@
 import android.test.suitebuilder.TestMethod;
 import android.test.suitebuilder.TestPredicates;
 import android.test.suitebuilder.TestSuiteBuilder;
-import android.test.suitebuilder.annotation.HasAnnotation;
 import android.test.suitebuilder.annotation.LargeTest;
 import android.util.Log;
 
@@ -49,6 +49,8 @@
 import junit.runner.BaseTestRunner;
 import junit.textui.ResultPrinter;
 
+import static android.test.suitebuilder.TestPredicates.hasAnnotation;
+
 /**
  * An {@link Instrumentation} that runs various types of {@link junit.framework.TestCase}s against
  * an Android package (application).
@@ -193,6 +195,12 @@
     /** @hide */
     static final String ARGUMENT_NOT_ANNOTATION = "notAnnotation";
 
+    private static final Predicate<TestMethod> SELECT_SMALL = hasAnnotation(SmallTest.class);
+
+    private static final Predicate<TestMethod> SELECT_MEDIUM = hasAnnotation(MediumTest.class);
+
+    private static final Predicate<TestMethod> SELECT_LARGE = hasAnnotation(LargeTest.class);
+
     /**
      * This constant defines the maximum allowed runtime (in ms) for a test included in the "small"
      * suite. It is used to make an educated guess at what suite an unlabeled test belongs.
@@ -460,11 +468,11 @@
     private Predicate<TestMethod> getSizePredicateFromArg(String sizeArg) {
 
         if (SMALL_SUITE.equals(sizeArg)) {
-            return TestPredicates.SELECT_SMALL;
+            return SELECT_SMALL;
         } else if (MEDIUM_SUITE.equals(sizeArg)) {
-            return TestPredicates.SELECT_MEDIUM;
+            return SELECT_MEDIUM;
         } else if (LARGE_SUITE.equals(sizeArg)) {
-            return TestPredicates.SELECT_LARGE;
+            return SELECT_LARGE;
         } else {
             return null;
         }
@@ -479,7 +487,7 @@
     private Predicate<TestMethod> getAnnotationPredicate(String annotationClassName) {
         Class<? extends Annotation> annotationClass = getAnnotationClass(annotationClassName);
         if (annotationClass != null) {
-            return new HasAnnotation(annotationClass);
+            return hasAnnotation(annotationClass);
         }
         return null;
     }
@@ -493,7 +501,7 @@
      private Predicate<TestMethod> getNotAnnotationPredicate(String annotationClassName) {
          Class<? extends Annotation> annotationClass = getAnnotationClass(annotationClassName);
          if (annotationClass != null) {
-             return Predicates.not(new HasAnnotation(annotationClass));
+             return TestPredicates.not(hasAnnotation(annotationClass));
          }
          return null;
      }
diff --git a/test-runner/src/android/test/PackageInfoSources.java b/test-runner/src/android/test/PackageInfoSources.java
deleted file mode 100644
index 205f86b..0000000
--- a/test-runner/src/android/test/PackageInfoSources.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.test;
-
-/**
- * {@hide} Not needed for SDK.
- */
-@Deprecated
-public class PackageInfoSources {
-
-    private static ClassPathPackageInfoSource classPathSource;
-
-    private PackageInfoSources() {
-    }
-
-    public static ClassPathPackageInfoSource forClassPath(ClassLoader classLoader) {
-        if (classPathSource == null) {
-            classPathSource = new ClassPathPackageInfoSource();
-            classPathSource.setClassLoader(classLoader);
-        }
-        return classPathSource;
-    }
-
-}
diff --git a/test-runner/src/android/test/TestCase.java b/test-runner/src/android/test/TestCase.java
deleted file mode 100644
index b234f44..0000000
--- a/test-runner/src/android/test/TestCase.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.test;
-
-import android.content.Context;
-
-/**
- * {@hide}
- * More complex interface for test cases.
- *
- * <p>Just implementing Runnable is enough for many test cases.  If you
- * have additional setup or teardown, this interface might be for you,
- * especially if you need to share it between different test cases, or your
- * teardown code must execute regardless of whether your test passed.
- *
- * <p>See the android.test package documentation (click the more... link)
- * for a full description
- */
-@Deprecated
-public interface TestCase extends Runnable
-{
-    /**
-     * Called before run() is called.
-     */
-    public void setUp(Context context);
-
-    /**
-     * Called after run() is called, even if run() threw an exception, but
-     * not if setUp() threw an execption.
-     */
-    public void tearDown();
-}
-
diff --git a/test-runner/src/android/test/TestCaseUtil.java b/test-runner/src/android/test/TestCaseUtil.java
index dc053a2..1562909 100644
--- a/test-runner/src/android/test/TestCaseUtil.java
+++ b/test-runner/src/android/test/TestCaseUtil.java
@@ -40,16 +40,6 @@
     private TestCaseUtil() {
     }
 
-    @SuppressWarnings("unchecked")
-    public static List<String> getTestCaseNames(Test test, boolean flatten) {
-        List<Test> tests = (List<Test>) getTests(test, flatten);
-        List<String> testCaseNames = new ArrayList<>();
-        for (Test aTest : tests) {
-            testCaseNames.add(getTestName(aTest));
-        }
-        return testCaseNames;
-    }
-
     public static List<? extends Test> getTests(Test test, boolean flatten) {
         return getTests(test, flatten, new HashSet<Class<?>>());
     }
@@ -92,7 +82,7 @@
         return testCases;
     }
 
-    private static Test invokeSuiteMethodIfPossible(Class testClass,
+    static Test invokeSuiteMethodIfPossible(Class testClass,
             Set<Class<?>> seen) {
         try {
             Method suiteMethod = testClass.getMethod(
@@ -120,7 +110,7 @@
         return null;
     }
 
-    public static String getTestName(Test test) {
+    static String getTestName(Test test) {
         if (test instanceof TestCase) {
             TestCase testCase = (TestCase) test;
             return testCase.getName();
@@ -138,34 +128,4 @@
         }
         return "";
     }
-
-    public static Test getTestAtIndex(TestSuite testSuite, int position) {
-        int index = 0;
-        Enumeration enumeration = testSuite.tests();
-        while (enumeration.hasMoreElements()) {
-            Test test = (Test) enumeration.nextElement();
-            if (index == position) {
-                return test;
-            }
-            index++;
-        }
-        return null;
-    }
-
-    public static TestSuite createTestSuite(Class<? extends Test> testClass)
-            throws InstantiationException, IllegalAccessException {
-
-        Test test = invokeSuiteMethodIfPossible(testClass,
-                new HashSet<Class<?>>());
-        if (test == null) {
-            return new TestSuite(testClass);
-
-        } else if (TestCase.class.isAssignableFrom(test.getClass())) {
-            TestSuite testSuite = new TestSuite(test.getClass().getName());
-            testSuite.addTest(test);
-            return testSuite;
-        }
-
-        return (TestSuite) test;
-    }
 }
diff --git a/test-runner/src/android/test/TestPrinter.java b/test-runner/src/android/test/TestPrinter.java
index a23f06d..01d392d 100644
--- a/test-runner/src/android/test/TestPrinter.java
+++ b/test-runner/src/android/test/TestPrinter.java
@@ -21,7 +21,6 @@
 import junit.framework.TestListener;
 
 import java.util.HashSet;
-import java.util.List;
 import java.util.Set;
 
 /**
@@ -34,52 +33,37 @@
  * {@hide} Not needed for 1.0 SDK.
  */
 @Deprecated
-public class TestPrinter implements TestRunner.Listener, TestListener {
+class TestPrinter implements TestListener {
 
     private String mTag;
     private boolean mOnlyFailures;
     private Set<String> mFailedTests = new HashSet<String>();
 
 
-    public TestPrinter(String tag, boolean onlyFailures) {
+    TestPrinter(String tag, boolean onlyFailures) {
         mTag = tag;
         mOnlyFailures = onlyFailures;
     }
 
-    public void started(String className) {
+    private void started(String className) {
         if (!mOnlyFailures) {
             Log.i(mTag, "started: " + className);
         }
     }
 
-    public void finished(String className) {
+    private void finished(String className) {
         if (!mOnlyFailures) {
             Log.i(mTag, "finished: " + className);
         }
     }
 
-    public void performance(String className,
-            long itemTimeNS, int iterations,
-            List<TestRunner.IntermediateTime> intermediates) {
-        Log.i(mTag, "perf: " + className + " = " + itemTimeNS + "ns/op (done "
-                + iterations + " times)");
-        if (intermediates != null && intermediates.size() > 0) {
-            int N = intermediates.size();
-            for (int i = 0; i < N; i++) {
-                TestRunner.IntermediateTime time = intermediates.get(i);
-                Log.i(mTag, "  intermediate: " + time.name + " = "
-                        + time.timeInNS + "ns");
-            }
-        }
-    }
-
-    public void passed(String className) {
+    private void passed(String className) {
         if (!mOnlyFailures) {
             Log.i(mTag, "passed: " + className);
         }
     }
 
-    public void failed(String className, Throwable exception) {
+    private void failed(String className, Throwable exception) {
         Log.i(mTag, "failed: " + className);
         Log.i(mTag, "----- begin exception -----");
         Log.i(mTag, "", exception);
diff --git a/test-runner/src/android/test/TestRunner.java b/test-runner/src/android/test/TestRunner.java
deleted file mode 100644
index ff045c3..0000000
--- a/test-runner/src/android/test/TestRunner.java
+++ /dev/null
@@ -1,725 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.test;
-
-import android.content.Context;
-import android.util.Log;
-import android.os.Debug;
-import android.os.SystemClock;
-
-import java.io.File;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.List;
-
-import junit.framework.TestSuite;
-import junit.framework.TestListener;
-import junit.framework.Test;
-import junit.framework.TestResult;
-
-/**
- * Support class that actually runs a test. Android uses this class,
- * and you probably will not need to instantiate, extend, or call this
- * class yourself. See the full {@link android.test} package description
- * to learn more about testing Android applications.
- *
- * {@hide} Not needed for 1.0 SDK.
- */
-@Deprecated
-public class TestRunner implements PerformanceTestCase.Intermediates {
-    public static final int REGRESSION = 0;
-    public static final int PERFORMANCE = 1;
-    public static final int PROFILING = 2;
-
-    public static final int CLEARSCREEN = 0;
-    private static final String TAG = "TestHarness";
-    private Context mContext;
-
-    private int mMode = REGRESSION;
-
-    private List<Listener> mListeners = new ArrayList<>();
-    private int mPassed;
-    private int mFailed;
-
-    private int mInternalIterations;
-    private long mStartTime;
-    private long mEndTime;
-
-    private String mClassName;
-
-    List<IntermediateTime> mIntermediates = null;
-
-    private static Class mRunnableClass;
-    private static Class mJUnitClass;
-
-    static {
-        try {
-            mRunnableClass = Class.forName("java.lang.Runnable", false, null);
-            mJUnitClass = Class.forName("junit.framework.TestCase", false, null);
-        } catch (ClassNotFoundException ex) {
-            throw new RuntimeException("shouldn't happen", ex);
-        }
-    }
-
-    public class JunitTestSuite extends TestSuite implements TestListener {
-        boolean mError = false;
-
-        public JunitTestSuite() {
-            super();
-        }
-
-        @Override
-        public void run(TestResult result) {
-            result.addListener(this);
-            super.run(result);
-            result.removeListener(this);
-        }
-
-        /**
-         * Implemented method of the interface TestListener which will listen for the
-         * start of a test.
-         *
-         * @param test
-         */
-        public void startTest(Test test) {
-            started(test.toString());
-        }
-
-        /**
-         * Implemented method of the interface TestListener which will listen for the
-         * end of the test.
-         *
-         * @param test
-         */
-        public void endTest(Test test) {
-            finished(test.toString());
-            if (!mError) {
-                passed(test.toString());
-            }
-        }
-
-        /**
-         * Implemented method of the interface TestListener which will listen for an
-         * mError while running the test.
-         *
-         * @param test
-         */
-        public void addError(Test test, Throwable t) {
-            mError = true;
-            failed(test.toString(), t);
-        }
-
-        public void addFailure(Test test, junit.framework.AssertionFailedError t) {
-            mError = true;
-            failed(test.toString(), t);
-        }
-    }
-
-    /**
-     * Listener.performance() 'intermediates' argument is a list of these.
-     */
-    public static class IntermediateTime {
-        public IntermediateTime(String name, long timeInNS) {
-            this.name = name;
-            this.timeInNS = timeInNS;
-        }
-
-        public String name;
-        public long timeInNS;
-    }
-
-    /**
-     * Support class that receives status on test progress. You should not need to
-     * extend this interface yourself.
-     */
-    public interface Listener {
-        void started(String className);
-        void finished(String className);
-        void performance(String className,
-                long itemTimeNS, int iterations,
-                List<IntermediateTime> itermediates);
-        void passed(String className);
-        void failed(String className, Throwable execption);
-    }
-
-    public TestRunner(Context context) {
-        mContext = context;
-    }
-
-    public void addListener(Listener listener) {
-        mListeners.add(listener);
-    }
-
-    public void startProfiling() {
-        File file = new File("/tmp/trace");
-        file.mkdir();
-        String base = "/tmp/trace/" + mClassName + ".dmtrace";
-        Debug.startMethodTracing(base, 8 * 1024 * 1024);
-    }
-
-    public void finishProfiling() {
-        Debug.stopMethodTracing();
-    }
-
-    private void started(String className) {
-
-        int count = mListeners.size();
-        for (int i = 0; i < count; i++) {
-            mListeners.get(i).started(className);
-        }
-    }
-
-    private void finished(String className) {
-        int count = mListeners.size();
-        for (int i = 0; i < count; i++) {
-            mListeners.get(i).finished(className);
-        }
-    }
-
-    private void performance(String className,
-            long itemTimeNS,
-            int iterations,
-            List<IntermediateTime> intermediates) {
-        int count = mListeners.size();
-        for (int i = 0; i < count; i++) {
-            mListeners.get(i).performance(className,
-                    itemTimeNS,
-                    iterations,
-                    intermediates);
-        }
-    }
-
-    public void passed(String className) {
-        mPassed++;
-        int count = mListeners.size();
-        for (int i = 0; i < count; i++) {
-            mListeners.get(i).passed(className);
-        }
-    }
-
-    public void failed(String className, Throwable exception) {
-        mFailed++;
-        int count = mListeners.size();
-        for (int i = 0; i < count; i++) {
-            mListeners.get(i).failed(className, exception);
-        }
-    }
-
-    public int passedCount() {
-        return mPassed;
-    }
-
-    public int failedCount() {
-        return mFailed;
-    }
-
-    public void run(String[] classes) {
-        for (String cl : classes) {
-            run(cl);
-        }
-    }
-
-    public void setInternalIterations(int count) {
-        mInternalIterations = count;
-    }
-
-    public void startTiming(boolean realTime) {
-        if (realTime) {
-            mStartTime = System.currentTimeMillis();
-        } else {
-            mStartTime = SystemClock.currentThreadTimeMillis();
-        }
-    }
-
-    public void addIntermediate(String name) {
-        addIntermediate(name, (System.currentTimeMillis() - mStartTime) * 1000000);
-    }
-
-    public void addIntermediate(String name, long timeInNS) {
-        mIntermediates.add(new IntermediateTime(name, timeInNS));
-    }
-
-    public void finishTiming(boolean realTime) {
-        if (realTime) {
-            mEndTime = System.currentTimeMillis();
-        } else {
-            mEndTime = SystemClock.currentThreadTimeMillis();
-        }
-    }
-
-    public void setPerformanceMode(int mode) {
-        mMode = mode;
-    }
-
-    private void missingTest(String className, Throwable e) {
-        started(className);
-        finished(className);
-        failed(className, e);
-    }
-
-    /*
-    This class determines if more suites are added to this class then adds all individual
-    test classes to a test suite for run
-     */
-    public void run(String className) {
-        try {
-            mClassName = className;
-            Class clazz = mContext.getClassLoader().loadClass(className);
-            Method method = getChildrenMethod(clazz);
-            if (method != null) {
-                String[] children = getChildren(method);
-                run(children);
-            } else if (mRunnableClass.isAssignableFrom(clazz)) {
-                Runnable test = (Runnable) clazz.newInstance();
-                TestCase testcase = null;
-                if (test instanceof TestCase) {
-                    testcase = (TestCase) test;
-                }
-                Throwable e = null;
-                boolean didSetup = false;
-                started(className);
-                try {
-                    if (testcase != null) {
-                        testcase.setUp(mContext);
-                        didSetup = true;
-                    }
-                    if (mMode == PERFORMANCE) {
-                        runInPerformanceMode(test, className, false, className);
-                    } else if (mMode == PROFILING) {
-                        //Need a way to mark a test to be run in profiling mode or not.
-                        startProfiling();
-                        test.run();
-                        finishProfiling();
-                    } else {
-                        test.run();
-                    }
-                } catch (Throwable ex) {
-                    e = ex;
-                }
-                if (testcase != null && didSetup) {
-                    try {
-                        testcase.tearDown();
-                    } catch (Throwable ex) {
-                        e = ex;
-                    }
-                }
-                finished(className);
-                if (e == null) {
-                    passed(className);
-                } else {
-                    failed(className, e);
-                }
-            } else if (mJUnitClass.isAssignableFrom(clazz)) {
-                Throwable e = null;
-                //Create a Junit Suite.
-                JunitTestSuite suite = new JunitTestSuite();
-                Method[] methods = getAllTestMethods(clazz);
-                for (Method m : methods) {
-                    junit.framework.TestCase test = (junit.framework.TestCase) clazz.newInstance();
-                    test.setName(m.getName());
-
-                    if (test instanceof AndroidTestCase) {
-                        AndroidTestCase testcase = (AndroidTestCase) test;
-                        try {
-                            testcase.setContext(mContext);
-                            testcase.setTestContext(mContext);
-                        } catch (Exception ex) {
-                            Log.i("TestHarness", ex.toString());
-                        }
-                    }
-                    suite.addTest(test);
-                }
-                if (mMode == PERFORMANCE) {
-                    final int testCount = suite.testCount();
-
-                    for (int j = 0; j < testCount; j++) {
-                        Test test = suite.testAt(j);
-                        started(test.toString());
-                        try {
-                            runInPerformanceMode(test, className, true, test.toString());
-                        } catch (Throwable ex) {
-                            e = ex;
-                        }
-                        finished(test.toString());
-                        if (e == null) {
-                            passed(test.toString());
-                        } else {
-                            failed(test.toString(), e);
-                        }
-                    }
-                } else if (mMode == PROFILING) {
-                    //Need a way to mark a test to be run in profiling mode or not.
-                    startProfiling();
-                    junit.textui.TestRunner.run(suite);
-                    finishProfiling();
-                } else {
-                    junit.textui.TestRunner.run(suite);
-                }
-            } else {
-                System.out.println("Test wasn't Runnable and didn't have a"
-                        + " children method: " + className);
-            }
-        } catch (ClassNotFoundException e) {
-            Log.e("ClassNotFoundException for " + className, e.toString());
-            if (isJunitTest(className)) {
-                runSingleJunitTest(className);
-            } else {
-                missingTest(className, e);
-            }
-        } catch (InstantiationException e) {
-            System.out.println("InstantiationException for " + className);
-            missingTest(className, e);
-        } catch (IllegalAccessException e) {
-            System.out.println("IllegalAccessException for " + className);
-            missingTest(className, e);
-        }
-    }
-
-    public void runInPerformanceMode(Object testCase, String className, boolean junitTest,
-            String testNameInDb) throws Exception {
-        boolean increaseIterations = true;
-        int iterations = 1;
-        long duration = 0;
-        mIntermediates = null;
-
-        mInternalIterations = 1;
-        Class clazz = mContext.getClassLoader().loadClass(className);
-        Object perftest = clazz.newInstance();
-
-        PerformanceTestCase perftestcase = null;
-        if (perftest instanceof PerformanceTestCase) {
-            perftestcase = (PerformanceTestCase) perftest;
-            // only run the test if it is not marked as a performance only test
-            if (mMode == REGRESSION && perftestcase.isPerformanceOnly()) return;
-        }
-
-        // First force GCs, to avoid GCs happening during out
-        // test and skewing its time.
-        Runtime.getRuntime().runFinalization();
-        Runtime.getRuntime().gc();
-
-        if (perftestcase != null) {
-            mIntermediates = new ArrayList<IntermediateTime>();
-            iterations = perftestcase.startPerformance(this);
-            if (iterations > 0) {
-                increaseIterations = false;
-            } else {
-                iterations = 1;
-            }
-        }
-
-        // Pause briefly to let things settle down...
-        Thread.sleep(1000);
-        do {
-            mEndTime = 0;
-            if (increaseIterations) {
-                // Test case does not implement
-                // PerformanceTestCase or returned 0 iterations,
-                // so we take care of measure the whole test time.
-                mStartTime = SystemClock.currentThreadTimeMillis();
-            } else {
-                // Try to make it obvious if the test case
-                // doesn't call startTiming().
-                mStartTime = 0;
-            }
-
-            if (junitTest) {
-                for (int i = 0; i < iterations; i++) {
-                    junit.textui.TestRunner.run((junit.framework.Test) testCase);
-                }
-            } else {
-                Runnable test = (Runnable) testCase;
-                for (int i = 0; i < iterations; i++) {
-                    test.run();
-                }
-            }
-
-            long endTime = mEndTime;
-            if (endTime == 0) {
-                endTime = SystemClock.currentThreadTimeMillis();
-            }
-
-            duration = endTime - mStartTime;
-            if (!increaseIterations) {
-                break;
-            }
-            if (duration <= 1) {
-                iterations *= 1000;
-            } else if (duration <= 10) {
-                iterations *= 100;
-            } else if (duration < 100) {
-                iterations *= 10;
-            } else if (duration < 1000) {
-                iterations *= (int) ((1000 / duration) + 2);
-            } else {
-                break;
-            }
-        } while (true);
-
-        if (duration != 0) {
-            iterations *= mInternalIterations;
-            performance(testNameInDb, (duration * 1000000) / iterations,
-                    iterations, mIntermediates);
-        }
-    }
-
-    public void runSingleJunitTest(String className) {
-        Throwable excep = null;
-        int index = className.lastIndexOf('$');
-        String testName = "";
-        String originalClassName = className;
-        if (index >= 0) {
-            className = className.substring(0, index);
-            testName = originalClassName.substring(index + 1);
-        }
-        try {
-            Class clazz = mContext.getClassLoader().loadClass(className);
-            if (mJUnitClass.isAssignableFrom(clazz)) {
-                junit.framework.TestCase test = (junit.framework.TestCase) clazz.newInstance();
-                JunitTestSuite newSuite = new JunitTestSuite();
-                test.setName(testName);
-
-                if (test instanceof AndroidTestCase) {
-                    AndroidTestCase testcase = (AndroidTestCase) test;
-                    try {
-                        testcase.setContext(mContext);
-                    } catch (Exception ex) {
-                        Log.w(TAG, "Exception encountered while trying to set the context.", ex);
-                    }
-                }
-                newSuite.addTest(test);
-
-                if (mMode == PERFORMANCE) {
-                    try {
-                        started(test.toString());
-                        runInPerformanceMode(test, className, true, test.toString());
-                        finished(test.toString());
-                        if (excep == null) {
-                            passed(test.toString());
-                        } else {
-                            failed(test.toString(), excep);
-                        }
-                    } catch (Throwable ex) {
-                        excep = ex;
-                    }
-
-                } else if (mMode == PROFILING) {
-                    startProfiling();
-                    junit.textui.TestRunner.run(newSuite);
-                    finishProfiling();
-                } else {
-                    junit.textui.TestRunner.run(newSuite);
-                }
-            }
-        } catch (ClassNotFoundException e) {
-            Log.e("TestHarness", "No test case to run", e);
-        } catch (IllegalAccessException e) {
-            Log.e("TestHarness", "Illegal Access Exception", e);
-        } catch (InstantiationException e) {
-            Log.e("TestHarness", "Instantiation Exception", e);
-        }
-    }
-
-    public static Method getChildrenMethod(Class clazz) {
-        try {
-            return clazz.getMethod("children", (Class[]) null);
-        } catch (NoSuchMethodException e) {
-        }
-
-        return null;
-    }
-
-    public static Method getChildrenMethod(Context c, String className) {
-        try {
-            return getChildrenMethod(c.getClassLoader().loadClass(className));
-        } catch (ClassNotFoundException e) {
-        }
-        return null;
-    }
-
-    public static String[] getChildren(Context c, String className) {
-        Method m = getChildrenMethod(c, className);
-        String[] testChildren = getTestChildren(c, className);
-        if (m == null & testChildren == null) {
-            throw new RuntimeException("couldn't get children method for "
-                    + className);
-        }
-        if (m != null) {
-            String[] children = getChildren(m);
-            if (testChildren != null) {
-                String[] allChildren = new String[testChildren.length + children.length];
-                System.arraycopy(children, 0, allChildren, 0, children.length);
-                System.arraycopy(testChildren, 0, allChildren, children.length, testChildren.length);
-                return allChildren;
-            } else {
-                return children;
-            }
-        } else {
-            if (testChildren != null) {
-                return testChildren;
-            }
-        }
-        return null;
-    }
-
-    public static String[] getChildren(Method m) {
-        try {
-            if (!Modifier.isStatic(m.getModifiers())) {
-                throw new RuntimeException("children method is not static");
-            }
-            return (String[]) m.invoke(null, (Object[]) null);
-        } catch (IllegalAccessException e) {
-        } catch (InvocationTargetException e) {
-        }
-        return new String[0];
-    }
-
-    public static String[] getTestChildren(Context c, String className) {
-        try {
-            Class clazz = c.getClassLoader().loadClass(className);
-
-            if (mJUnitClass.isAssignableFrom(clazz)) {
-                return getTestChildren(clazz);
-            }
-        } catch (ClassNotFoundException e) {
-            Log.e("TestHarness", "No class found", e);
-        }
-        return null;
-    }
-
-    public static String[] getTestChildren(Class clazz) {
-        Method[] methods = getAllTestMethods(clazz);
-
-        String[] onScreenTestNames = new String[methods.length];
-        int index = 0;
-        for (Method m : methods) {
-            onScreenTestNames[index] = clazz.getName() + "$" + m.getName();
-            index++;
-        }
-        return onScreenTestNames;
-    }
-
-    public static Method[] getAllTestMethods(Class clazz) {
-        Method[] allMethods = clazz.getDeclaredMethods();
-        int numOfMethods = 0;
-        for (Method m : allMethods) {
-            boolean mTrue = isTestMethod(m);
-            if (mTrue) {
-                numOfMethods++;
-            }
-        }
-        int index = 0;
-        Method[] testMethods = new Method[numOfMethods];
-        for (Method m : allMethods) {
-            boolean mTrue = isTestMethod(m);
-            if (mTrue) {
-                testMethods[index] = m;
-                index++;
-            }
-        }
-        return testMethods;
-    }
-
-    private static boolean isTestMethod(Method m) {
-        return m.getName().startsWith("test") &&
-                m.getReturnType() == void.class &&
-                m.getParameterTypes().length == 0;
-    }
-
-    public static int countJunitTests(Class clazz) {
-        Method[] allTestMethods = getAllTestMethods(clazz);
-        int numberofMethods = allTestMethods.length;
-
-        return numberofMethods;
-    }
-
-    public static boolean isTestSuite(Context c, String className) {
-        boolean childrenMethods = getChildrenMethod(c, className) != null;
-
-        try {
-            Class clazz = c.getClassLoader().loadClass(className);
-            if (mJUnitClass.isAssignableFrom(clazz)) {
-                int numTests = countJunitTests(clazz);
-                if (numTests > 0)
-                    childrenMethods = true;
-            }
-        } catch (ClassNotFoundException e) {
-        }
-        return childrenMethods;
-    }
-
-
-    public boolean isJunitTest(String className) {
-        int index = className.lastIndexOf('$');
-        if (index >= 0) {
-            className = className.substring(0, index);
-        }
-        try {
-            Class clazz = mContext.getClassLoader().loadClass(className);
-            if (mJUnitClass.isAssignableFrom(clazz)) {
-                return true;
-            }
-        } catch (ClassNotFoundException e) {
-        }
-        return false;
-    }
-
-    /**
-     * Returns the number of tests that will be run if you try to do this.
-     */
-    public static int countTests(Context c, String className) {
-        try {
-            Class clazz = c.getClassLoader().loadClass(className);
-            Method method = getChildrenMethod(clazz);
-            if (method != null) {
-
-                String[] children = getChildren(method);
-                int rv = 0;
-                for (String child : children) {
-                    rv += countTests(c, child);
-                }
-                return rv;
-            } else if (mRunnableClass.isAssignableFrom(clazz)) {
-                return 1;
-            } else if (mJUnitClass.isAssignableFrom(clazz)) {
-                return countJunitTests(clazz);
-            }
-        } catch (ClassNotFoundException e) {
-            return 1; // this gets the count right, because either this test
-            // is missing, and it will fail when run or it is a single Junit test to be run.
-        }
-        return 0;
-    }
-
-    /**
-     * Returns a title to display given the className of a test.
-     * <p/>
-     * <p>Currently this function just returns the portion of the
-     * class name after the last '.'
-     */
-    public static String getTitle(String className) {
-        int indexDot = className.lastIndexOf('.');
-        int indexDollar = className.lastIndexOf('$');
-        int index = indexDot > indexDollar ? indexDot : indexDollar;
-        if (index >= 0) {
-            className = className.substring(index + 1);
-        }
-        return className;
-    }
-}
diff --git a/test-runner/src/android/test/mock/MockContext.java b/test-runner/src/android/test/mock/MockContext.java
index ebad81c..5e5ba46 100644
--- a/test-runner/src/android/test/mock/MockContext.java
+++ b/test-runner/src/android/test/mock/MockContext.java
@@ -816,6 +816,12 @@
 
     /** {@hide} */
     @Override
+    public boolean canLoadUnsafeResources() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@hide} */
+    @Override
     public IBinder getActivityToken() {
         throw new UnsupportedOperationException();
     }
diff --git a/test-runner/src/android/test/suitebuilder/AssignableFrom.java b/test-runner/src/android/test/suitebuilder/AssignableFrom.java
index 38b4ee3..84db066 100644
--- a/test-runner/src/android/test/suitebuilder/AssignableFrom.java
+++ b/test-runner/src/android/test/suitebuilder/AssignableFrom.java
@@ -20,9 +20,9 @@
 
 class AssignableFrom implements Predicate<TestMethod> {
 
-    private final Class root;
+    private final Class<?> root;
 
-    AssignableFrom(Class root) {
+    AssignableFrom(Class<?> root) {
         this.root = root;
     }
 
diff --git a/test-runner/src/android/test/suitebuilder/TestGrouping.java b/test-runner/src/android/test/suitebuilder/TestGrouping.java
index 307afb5..030bc42 100644
--- a/test-runner/src/android/test/suitebuilder/TestGrouping.java
+++ b/test-runner/src/android/test/suitebuilder/TestGrouping.java
@@ -16,9 +16,7 @@
 
 package android.test.suitebuilder;
 
-import android.test.ClassPathPackageInfo;
 import android.test.ClassPathPackageInfoSource;
-import android.test.PackageInfoSources;
 import android.util.Log;
 import com.android.internal.util.Predicate;
 import junit.framework.TestCase;
@@ -131,10 +129,9 @@
     }
 
     private List<Class<? extends TestCase>> testCaseClassesInPackage(String packageName) {
-        ClassPathPackageInfoSource source = PackageInfoSources.forClassPath(classLoader);
-        ClassPathPackageInfo packageInfo = source.getPackageInfo(packageName);
+        ClassPathPackageInfoSource source = ClassPathPackageInfoSource.forClassPath(classLoader);
 
-        return selectTestClasses(packageInfo.getTopLevelClassesRecursive());
+        return selectTestClasses(source.getTopLevelClassesRecursive(packageName));
     }
 
     @SuppressWarnings("unchecked")
diff --git a/test-runner/src/android/test/suitebuilder/TestPredicates.java b/test-runner/src/android/test/suitebuilder/TestPredicates.java
index 47aca55..616d1a9 100644
--- a/test-runner/src/android/test/suitebuilder/TestPredicates.java
+++ b/test-runner/src/android/test/suitebuilder/TestPredicates.java
@@ -17,30 +17,63 @@
 package android.test.suitebuilder;
 
 import android.test.InstrumentationTestCase;
-import android.test.suitebuilder.annotation.HasAnnotation;
-import android.test.suitebuilder.annotation.Suppress;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.test.suitebuilder.annotation.Smoke;
+import android.test.suitebuilder.annotation.Suppress;
 import com.android.internal.util.Predicate;
-import com.android.internal.util.Predicates;
+import java.lang.annotation.Annotation;
 
 /**
  * {@hide} Not needed for 1.0 SDK.
  */
 public class TestPredicates {
 
-    public static final Predicate<TestMethod> SELECT_INSTRUMENTATION =
-            new AssignableFrom(InstrumentationTestCase.class);
-    public static final Predicate<TestMethod> REJECT_INSTRUMENTATION =
-            Predicates.not(SELECT_INSTRUMENTATION);
+    static final Predicate<TestMethod> REJECT_INSTRUMENTATION =
+            not(new AssignableFrom(InstrumentationTestCase.class));
 
-    public static final Predicate<TestMethod> SELECT_SMOKE = new HasAnnotation(Smoke.class);
-    public static final Predicate<TestMethod> SELECT_SMALL = new HasAnnotation(SmallTest.class);
-    public static final Predicate<TestMethod> SELECT_MEDIUM = new HasAnnotation(MediumTest.class);
-    public static final Predicate<TestMethod> SELECT_LARGE = new HasAnnotation(LargeTest.class);
-    public static final Predicate<TestMethod> REJECT_SUPPRESSED =
-            Predicates.not(new HasAnnotation(Suppress.class));
+    static final Predicate<TestMethod> SELECT_SMOKE = hasAnnotation(Smoke.class);
 
+    static final Predicate<TestMethod> REJECT_SUPPRESSED = not(hasAnnotation(Suppress.class));
+
+    /**
+     * Return a predicate that checks to see if a {@link TestMethod} has an instance of the supplied
+     * annotation class, either on the method or on the containing class.
+     */
+    public static Predicate<TestMethod> hasAnnotation(Class<? extends Annotation> annotationClass) {
+        return new HasAnnotation(annotationClass);
+    }
+
+    private static class HasAnnotation implements Predicate<TestMethod> {
+
+        private final Class<? extends Annotation> annotationClass;
+
+        private HasAnnotation(Class<? extends Annotation> annotationClass) {
+            this.annotationClass = annotationClass;
+        }
+
+        @Override
+        public boolean apply(TestMethod testMethod) {
+            return testMethod.getAnnotation(annotationClass) != null ||
+                    testMethod.getEnclosingClass().getAnnotation(annotationClass) != null;
+        }
+    }
+
+    /**
+     * Returns a Predicate that evaluates to true iff the given Predicate
+     * evaluates to false.
+     */
+    public static <T> Predicate<T> not(Predicate<? super T> predicate) {
+        return new NotPredicate<T>(predicate);
+    }
+
+    private static class NotPredicate<T> implements Predicate<T> {
+        private final Predicate<? super T> predicate;
+
+        private NotPredicate(Predicate<? super T> predicate) {
+            this.predicate = predicate;
+        }
+
+        public boolean apply(T t) {
+            return !predicate.apply(t);
+        }
+    }
 }
diff --git a/test-runner/src/android/test/suitebuilder/annotation/HasAnnotation.java b/test-runner/src/android/test/suitebuilder/annotation/HasAnnotation.java
deleted file mode 100644
index a2868fc..0000000
--- a/test-runner/src/android/test/suitebuilder/annotation/HasAnnotation.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.test.suitebuilder.annotation;
-
-import static com.android.internal.util.Predicates.or;
-import com.android.internal.util.Predicate;
-import android.test.suitebuilder.TestMethod;
-
-import java.lang.annotation.Annotation;
-
-/**
- * A predicate that checks to see if a {@link TestMethod} has a specific annotation, either on the
- * method or on the containing class.
- * 
- * {@hide} Not needed for 1.0 SDK.
- */
-public class HasAnnotation implements Predicate<TestMethod> {
-
-    private Predicate<TestMethod> hasMethodOrClassAnnotation;
-
-    public HasAnnotation(Class<? extends Annotation> annotationClass) {
-        this.hasMethodOrClassAnnotation = or(
-                new HasMethodAnnotation(annotationClass),
-                new HasClassAnnotation(annotationClass));
-    }
-
-    public boolean apply(TestMethod testMethod) {
-        return hasMethodOrClassAnnotation.apply(testMethod);
-    }
-}
diff --git a/test-runner/src/android/test/suitebuilder/annotation/HasClassAnnotation.java b/test-runner/src/android/test/suitebuilder/annotation/HasClassAnnotation.java
deleted file mode 100644
index ac76f4c..0000000
--- a/test-runner/src/android/test/suitebuilder/annotation/HasClassAnnotation.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.test.suitebuilder.annotation;
-
-import java.lang.annotation.Annotation;
-
-import android.test.suitebuilder.TestMethod;
-import com.android.internal.util.Predicate;
-
-/**
- * A predicate that checks to see if a {@link android.test.suitebuilder.TestMethod} has a specific annotation on the
- * containing class. Consider using the public {@link HasAnnotation} class instead of this class.
- * 
- * {@hide} Not needed for 1.0 SDK.
- */
-class HasClassAnnotation implements Predicate<TestMethod> {
-
-    private Class<? extends Annotation> annotationClass;
-
-    public HasClassAnnotation(Class<? extends Annotation> annotationClass) {
-        this.annotationClass = annotationClass;
-    }
-
-    public boolean apply(TestMethod testMethod) {
-        return testMethod.getEnclosingClass().getAnnotation(annotationClass) != null;
-    }
-}
diff --git a/test-runner/src/android/test/suitebuilder/annotation/HasMethodAnnotation.java b/test-runner/src/android/test/suitebuilder/annotation/HasMethodAnnotation.java
deleted file mode 100644
index 96bd922..0000000
--- a/test-runner/src/android/test/suitebuilder/annotation/HasMethodAnnotation.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.test.suitebuilder.annotation;
-
-import com.android.internal.util.Predicate;
-import android.test.suitebuilder.TestMethod;
-
-import java.lang.annotation.Annotation;
-
-/**
- * A predicate that checks to see if a the method represented by {@link TestMethod} has a certain
- * annotation on it. Consider using the public {@link HasAnnotation} class instead of this class.
- * 
- * {@hide} Not needed for 1.0 SDK.
- */
-class HasMethodAnnotation implements Predicate<TestMethod> {
-
-    private final Class<? extends Annotation> annotationClass;
-
-    public HasMethodAnnotation(Class<? extends Annotation> annotationClass) {
-        this.annotationClass = annotationClass;
-    }
-
-    public boolean apply(TestMethod testMethod) {
-        return testMethod.getAnnotation(annotationClass) != null;
-    }
-}
diff --git a/test-runner/tests/Android.mk b/test-runner/tests/Android.mk
index 68fd662..7ee047e4 100644
--- a/test-runner/tests/Android.mk
+++ b/test-runner/tests/Android.mk
@@ -16,6 +16,13 @@
 include $(CLEAR_VARS)
 
 # We only want this apk build for tests.
+#
+# Run the tests using the following commands:
+#   adb install -r ${ANDROID_PRODUCT_OUT}/data/app/FrameworkTestRunnerTests/FrameworkTestRunnerTests.apk
+#   adb shell am instrument \
+        -e notAnnotation android.test.suitebuilder.examples.error.RunAsPartOfSeparateTest \
+        -w com.android.frameworks.testrunner.tests/android.test.InstrumentationTestRunner
+#
 LOCAL_MODULE_TAGS := tests
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
diff --git a/test-runner/tests/src/android/test/TestCaseUtilTest.java b/test-runner/tests/src/android/test/TestCaseUtilTest.java
index bc6fa92..6d424b0 100644
--- a/test-runner/tests/src/android/test/TestCaseUtilTest.java
+++ b/test-runner/tests/src/android/test/TestCaseUtilTest.java
@@ -16,6 +16,8 @@
 
 package android.test;
 
+import java.util.ArrayList;
+import java.util.HashSet;
 import junit.framework.Test;
 import junit.framework.TestCase;
 import junit.framework.TestSuite;
@@ -24,40 +26,50 @@
 
 public class TestCaseUtilTest extends TestCase {
 
-    public void testGetTestCaseNamesForTestSuiteWithSuiteMethod() throws Exception {
+    @SuppressWarnings("unchecked")
+    private static List<String> getTestCaseNames(Test test) {
+        List<Test> tests = (List<Test>) TestCaseUtil.getTests(test, false);
+        List<String> testCaseNames = new ArrayList<>();
+        for (Test aTest : tests) {
+            testCaseNames.add(TestCaseUtil.getTestName(aTest));
+        }
+        return testCaseNames;
+    }
+
+    public void testGetTests_ForTestSuiteWithSuiteMethod() throws Exception {
         TestSuite testSuite = new TwoTestsInTestSuite();
 
-        List<String> testCaseNames = TestCaseUtil.getTestCaseNames(testSuite, false);
+        List<String> testCaseNames = getTestCaseNames(testSuite);
 
-        assertEquals(2, testCaseNames.size());
-        assertTrue(testCaseNames.get(0).endsWith("OneTestTestCase"));
-        assertTrue(testCaseNames.get(1).endsWith("OneTestTestSuite"));
+        assertEquals(0, testCaseNames.size());
     }
     
-    public void testGetTestCaseNamesForTestCaseWithSuiteMethod() throws Exception {
+    public void testGetTests_ForTestCaseWithSuiteMethod() throws Exception {
         TestCase testCase = new OneTestTestCaseWithSuite();
 
-        List<String> testCaseNames = TestCaseUtil.getTestCaseNames(testCase, false);
+        List<String> testCaseNames = getTestCaseNames(testCase);
 
         assertEquals(1, testCaseNames.size());
         assertTrue(testCaseNames.get(0).endsWith("testOne"));
     }
 
-    public void testCreateTestForTestCase() throws Exception {
-        Test test = TestCaseUtil.createTestSuite(OneTestTestCase.class);
-        assertEquals(1, test.countTestCases());
+    public void testInvokeSuiteMethodIfPossible_ForTestCase() throws Exception {
+        Test test = TestCaseUtil.invokeSuiteMethodIfPossible(OneTestTestCase.class, new HashSet<>());
+        assertNull(test);
     }
-    
-    public void testCreateTestForTestSuiteWithSuiteMethod() throws Exception {
-        Test test = TestCaseUtil.createTestSuite(TwoTestsInTestSuite.class);
+
+    public void testInvokeSuiteMethodIfPossible_ForTestSuiteWithSuiteMethod() throws Exception {
+        Test test = TestCaseUtil.invokeSuiteMethodIfPossible(TwoTestsInTestSuite.class, new HashSet<>());
+        assertNotNull(test);
         assertEquals(2, test.countTestCases());
     }
 
-    public void testCreateTestForTestCaseWithSuiteMethod() throws Exception {
-        Test test = TestCaseUtil.createTestSuite(OneTestTestCaseWithSuite.class);
+    public void testInvokeSuiteMethodIfPossible_ForTestCaseWithSuiteMethod() throws Exception {
+        Test test = TestCaseUtil.invokeSuiteMethodIfPossible(OneTestTestCaseWithSuite.class, new HashSet<>());
+        assertNotNull(test);
         assertEquals(1, test.countTestCases());
     }
-    
+
     public void testReturnEmptyStringForTestSuiteWithNoName() throws Exception {
         assertEquals("", TestCaseUtil.getTestName(new TestSuite()));
     }
diff --git a/test-runner/tests/src/android/test/suitebuilder/annotation/HasAnnotationTest.java b/test-runner/tests/src/android/test/suitebuilder/TestPredicatesTest.java
similarity index 76%
rename from test-runner/tests/src/android/test/suitebuilder/annotation/HasAnnotationTest.java
rename to test-runner/tests/src/android/test/suitebuilder/TestPredicatesTest.java
index edf067d..3d8d5f1 100644
--- a/test-runner/tests/src/android/test/suitebuilder/annotation/HasAnnotationTest.java
+++ b/test-runner/tests/src/android/test/suitebuilder/TestPredicatesTest.java
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
-package android.test.suitebuilder.annotation;
+package android.test.suitebuilder;
 
-import android.test.suitebuilder.TestMethod;
+import com.android.internal.util.Predicate;
 import junit.framework.TestCase;
 
 import java.lang.annotation.ElementType;
@@ -25,7 +25,7 @@
 import java.lang.annotation.Target;
 import java.lang.reflect.Method;
 
-public class HasAnnotationTest extends TestCase {
+public class TestPredicatesTest extends TestCase {
 
     public void testThatMethodWithAnnotationIsReportedAsBeingAnnotated() throws Exception {
         assertTrue(hasExampleAnnotation(ClassWithAnnotation.class, "testWithAnnotation"));
@@ -45,7 +45,7 @@
             throws NoSuchMethodException {
         Method method = aClass.getMethod(methodName);
         TestMethod testMethod = new TestMethod(method, aClass);
-        return new HasAnnotation(Example.class).apply(testMethod);
+        return TestPredicates.hasAnnotation(Example.class).apply(testMethod);
     }
 
     @Retention(RetentionPolicy.RUNTIME)
@@ -73,4 +73,21 @@
         public void testWithoutAnnotation() {
         }
     }
+
+    private static final Predicate<Object> TRUE = new Predicate<Object>() {
+        public boolean apply(Object o) {
+            return true;
+        }
+    };
+
+    private static final Predicate<Object> FALSE = new Predicate<Object>() {
+        public boolean apply(Object o) {
+            return false;
+        }
+    };
+
+    public void testNotPredicate() throws Exception {
+        assertTrue(TestPredicates.not(FALSE).apply(null));
+        assertFalse(TestPredicates.not(TRUE).apply(null));
+    }
 }
diff --git a/test-runner/tests/src/android/test/suitebuilder/TestSuiteBuilderTest.java b/test-runner/tests/src/android/test/suitebuilder/TestSuiteBuilderTest.java
index 293c813..a2e51a1 100644
--- a/test-runner/tests/src/android/test/suitebuilder/TestSuiteBuilderTest.java
+++ b/test-runner/tests/src/android/test/suitebuilder/TestSuiteBuilderTest.java
@@ -135,10 +135,23 @@
 
         TestSuite testSuite = new OuterTest().buildTestsUnderHereRecursively();
         assertContentsInOrder(getTestCaseNames(testSuite),
-                "testOuter", "testErrorOne", "testErrorTwo", "testFailOne", "testFailTwo",
-                "testInstrumentation", "testLevel1", "testLevel2", "testAnotherOne",
-                "testSimpleOne", "testSimpleTwo", "testNonSmoke", "testSmoke", "testSubclass",
-                "testSuperclass", "testUnSuppressedMethod");
+                "testOuter",
+                "testPublicConstructor",
+                "testErrorOne",
+                "testErrorTwo",
+                "testFailOne",
+                "testFailTwo",
+                "testInstrumentation",
+                "testLevel1",
+                "testLevel2",
+                "testAnotherOne",
+                "testSimpleOne",
+                "testSimpleTwo",
+                "testNonSmoke",
+                "testSmoke",
+                "testSubclass",
+                "testSuperclass",
+                "testUnSuppressedMethod");
     }
 
     private void assertContentsInOrder(List<String> actual, String... source) {
diff --git a/test-runner/tests/src/android/test/suitebuilder/annotation/HasClassAnnotationTest.java b/test-runner/tests/src/android/test/suitebuilder/annotation/HasClassAnnotationTest.java
deleted file mode 100644
index 051ea54..0000000
--- a/test-runner/tests/src/android/test/suitebuilder/annotation/HasClassAnnotationTest.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.test.suitebuilder.annotation;
-
-import android.test.suitebuilder.TestMethod;
-import junit.framework.TestCase;
-
-import java.lang.reflect.Method;
-
-public class HasClassAnnotationTest extends TestCase {
-
-    public void testShouldTellIfParentClassHasSpecifiedClassification()
-            throws NoSuchMethodException {
-        assertTrue(classHasAnnotation(SmokeTestExample.class, Smoke.class));
-    }
-
-    public void testShouldTellIfParentClassDoesNotHaveSpecifiedClassification()
-            throws NoSuchMethodException {
-        assertFalse(classHasAnnotation(NonSmokeTestExample.class, Smoke.class));
-    }
-
-    private boolean classHasAnnotation(
-            Class<? extends TestCase> aClass,
-            Class<Smoke> expectedClassification) throws NoSuchMethodException {
-        Method method = aClass.getMethod("testSomeTest");
-
-        TestMethod testMethod = new TestMethod(method, aClass);
-        return new HasClassAnnotation(expectedClassification).apply(testMethod);
-    }
-
-    @Smoke
-    static class SmokeTestExample extends TestCase {
-
-        public void testSomeTest() {
-        }
-    }
-
-    static class NonSmokeTestExample extends TestCase {
-
-        public void testSomeTest() {
-        }
-    }
-}
diff --git a/test-runner/tests/src/android/test/suitebuilder/annotation/HasMethodAnnotationTest.java b/test-runner/tests/src/android/test/suitebuilder/annotation/HasMethodAnnotationTest.java
deleted file mode 100644
index c864e28..0000000
--- a/test-runner/tests/src/android/test/suitebuilder/annotation/HasMethodAnnotationTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.test.suitebuilder.annotation;
-
-import android.test.suitebuilder.TestMethod;
-import junit.framework.TestCase;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Method;
-
-
-public class HasMethodAnnotationTest extends TestCase {
-
-    public void testMethodWithSpecifiedAttribute() throws Exception {
-        assertTrue(methodHasAnnotation(AnnotatedMethodExample.class,
-                "testThatIsAnnotated", Smoke.class));
-    }
-
-    public void testMethodWithoutSpecifiedAttribute() throws Exception {
-        assertFalse(methodHasAnnotation(AnnotatedMethodExample.class,
-                "testThatIsNotAnnotated", Smoke.class));
-    }
-
-    private boolean methodHasAnnotation(Class<? extends TestCase> aClass,
-            String methodName,
-            Class<? extends Annotation> expectedClassification
-    ) throws NoSuchMethodException {
-        Method method = aClass.getMethod(methodName);
-        TestMethod testMethod = new TestMethod(method, aClass);
-        return new HasMethodAnnotation(expectedClassification).apply(testMethod);
-    }
-
-    static class AnnotatedMethodExample extends TestCase {
-
-        @Smoke
-        public void testThatIsAnnotated() {
-        }
-
-        public void testThatIsNotAnnotated() {
-        }
-    }
-}
diff --git a/test-runner/tests/src/android/test/suitebuilder/examples/error/ErrorTest.java b/test-runner/tests/src/android/test/suitebuilder/examples/error/ErrorTest.java
index f1f6113..ddf5dd1 100644
--- a/test-runner/tests/src/android/test/suitebuilder/examples/error/ErrorTest.java
+++ b/test-runner/tests/src/android/test/suitebuilder/examples/error/ErrorTest.java
@@ -18,6 +18,7 @@
 
 import junit.framework.TestCase;
 
+@RunAsPartOfSeparateTest
 public class ErrorTest extends TestCase {
 
     public void testErrorOne() throws Exception {
diff --git a/test-runner/tests/src/android/test/suitebuilder/examples/error/FailingTest.java b/test-runner/tests/src/android/test/suitebuilder/examples/error/FailingTest.java
index 428fd23..0170b2f 100644
--- a/test-runner/tests/src/android/test/suitebuilder/examples/error/FailingTest.java
+++ b/test-runner/tests/src/android/test/suitebuilder/examples/error/FailingTest.java
@@ -18,6 +18,7 @@
 
 import junit.framework.TestCase;
 
+@RunAsPartOfSeparateTest
 public class FailingTest extends TestCase {
 
     public void testFailOne() throws Exception {
diff --git a/test-runner/tests/src/android/test/suitebuilder/examples/error/RunAsPartOfSeparateTest.java b/test-runner/tests/src/android/test/suitebuilder/examples/error/RunAsPartOfSeparateTest.java
new file mode 100644
index 0000000..2b3a252
--- /dev/null
+++ b/test-runner/tests/src/android/test/suitebuilder/examples/error/RunAsPartOfSeparateTest.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.test.suitebuilder.examples.error;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation that marks tests that should only be run as part of a separate test and not on their
+ * own.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface RunAsPartOfSeparateTest {
+}
diff --git a/tests/StatusBar/AndroidManifest.xml b/tests/StatusBar/AndroidManifest.xml
index 81442bf..6a082e9 100644
--- a/tests/StatusBar/AndroidManifest.xml
+++ b/tests/StatusBar/AndroidManifest.xml
@@ -6,6 +6,7 @@
     <uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
     <uses-permission android:name="android.permission.VIBRATE" />
     <uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" />
+    <uses-permission android:name="android.permission.MANAGE_NOTIFICATIONS" />
 
     <application>
         <activity android:name="StatusBarTest" android:label="_StatusBar">
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
index 5dd42dd..fc68183 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
@@ -129,6 +129,42 @@
                     mNM.notify(7001, n);
                 }
             },
+            new Test("with zen") {
+                public void run()
+                {
+                    mNM.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALARMS);
+                    Notification n = new Notification.Builder(NotificationTestList.this,
+                            "default")
+                            .setSmallIcon(R.drawable.icon2)
+                            .setContentTitle("Default priority")
+                            .build();
+                    mNM.notify("default", 7004, n);
+                    try {
+                        Thread.sleep(8000);
+                    } catch (InterruptedException e) {
+                        e.printStackTrace();
+                    }
+                    mNM.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL);
+                }
+            },
+            new Test("repeated") {
+                public void run()
+                {
+                    for (int i = 0; i < 50; i++) {
+                        Notification n = new Notification.Builder(NotificationTestList.this,
+                                "default")
+                                .setSmallIcon(R.drawable.icon2)
+                                .setContentTitle("Default priority")
+                                .build();
+                        mNM.notify("default", 7004, n);
+                        try {
+                            Thread.sleep(100);
+                        } catch (InterruptedException e) {
+                            e.printStackTrace();
+                        }
+                    }
+                }
+            },
             new Test("Post a group") {
                 public void run()
                 {
diff --git a/tests/net/java/android/net/util/SharedLogTest.java b/tests/net/java/android/net/util/SharedLogTest.java
index 7fd7a63..3957cb0 100644
--- a/tests/net/java/android/net/util/SharedLogTest.java
+++ b/tests/net/java/android/net/util/SharedLogTest.java
@@ -33,9 +33,8 @@
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class SharedLogTest {
-    private static final String TIMESTAMP_PATTERN =
-            "^[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]";
-    private static final String TIMESTAMP = "mm-dd HH:MM:SS.xxx";
+    private static final String TIMESTAMP_PATTERN = "\\d{2}:\\d{2}:\\d{2}\\.\\d{3}";
+    private static final String TIMESTAMP = "HH:MM:SS.xxx";
 
     @Test
     public void testBasicOperation() {
@@ -53,12 +52,12 @@
         logLevel2a.mark("ok: last post");
 
         final String[] expected = {
-            TIMESTAMP + " - MARK first post!",
-            TIMESTAMP + " - [twoB] ERROR 2b or not 2b",
-            TIMESTAMP + " - [twoA] WARN second post?",
-            TIMESTAMP + " - still logging",
-            TIMESTAMP + " - [twoA.three] 3 >> 2",
-            TIMESTAMP + " - [twoA] MARK ok: last post",
+            " - MARK first post!",
+            " - [twoB] ERROR 2b or not 2b",
+            " - [twoA] WARN second post?",
+            " - still logging",
+            " - [twoA.three] 3 >> 2",
+            " - [twoA] MARK ok: last post",
         };
         // Verify the logs are all there and in the correct order.
         verifyLogLines(expected, logTop);
@@ -82,13 +81,12 @@
         final String[] lines = dumpOutput.split("\n");
         assertEquals(expected.length, lines.length);
 
-        for (int i = 0; i < lines.length; i++) {
-            // Fix up the timestamps.
-            lines[i] = lines[i].replaceAll(TIMESTAMP_PATTERN, TIMESTAMP);
-        }
-
         for (int i = 0; i < expected.length; i++) {
-            assertEquals(expected[i], lines[i]);
+            String got = lines[i];
+            String want = expected[i];
+            assertTrue(String.format("'%s' did not contain '%s'", got, want), got.endsWith(want));
+            assertTrue(String.format("'%s' did not contain a HH:MM:SS.xxx timestamp", got),
+                    got.replaceFirst(TIMESTAMP_PATTERN, TIMESTAMP).contains(TIMESTAMP));
         }
     }
 }
diff --git a/tests/radio/src/android/hardware/radio/tests/RadioTest.java b/tests/radio/src/android/hardware/radio/tests/RadioTest.java
index 82ce439..b7a5ac4 100644
--- a/tests/radio/src/android/hardware/radio/tests/RadioTest.java
+++ b/tests/radio/src/android/hardware/radio/tests/RadioTest.java
@@ -123,10 +123,11 @@
         // find FM band and build its config
         mModule = mModules.get(0);
         for (RadioManager.BandDescriptor band : mModule.getBands()) {
-            if (band.getType() == RadioManager.BAND_AM) {
+            int bandType = band.getType();
+            if (bandType == RadioManager.BAND_AM || bandType == RadioManager.BAND_AM_HD) {
                 mAmBandDescriptor = (RadioManager.AmBandDescriptor)band;
             }
-            if (band.getType() == RadioManager.BAND_FM) {
+            if (bandType == RadioManager.BAND_FM || bandType == RadioManager.BAND_FM_HD) {
                 mFmBandDescriptor = (RadioManager.FmBandDescriptor)band;
             }
         }
diff --git a/tests/testables/src/android/testing/TestableInstrumentation.java b/tests/testables/src/android/testing/TestableInstrumentation.java
new file mode 100644
index 0000000..93fed85
--- /dev/null
+++ b/tests/testables/src/android/testing/TestableInstrumentation.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2017 The Android Open Source 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.testing;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.TestLooperManager;
+import android.support.test.runner.AndroidJUnitRunner;
+import android.util.Log;
+
+import java.util.ArrayList;
+
+/**
+ * Wrapper around instrumentation that spins up a TestLooperManager around
+ * the main looper whenever a test is not using it to attempt to stop crashes
+ * from stopping other tests from running.
+ */
+public class TestableInstrumentation extends AndroidJUnitRunner {
+
+    private static final String TAG = "TestableInstrumentation";
+
+    private static final int MAX_CRASHES = 5;
+    private static MainLooperManager sManager;
+
+    @Override
+    public void onCreate(Bundle arguments) {
+        sManager = new MainLooperManager();
+        Log.setWtfHandler((tag, what, system) -> {
+            if (system) {
+                Log.e(TAG, "WTF!!", what);
+            } else {
+                // These normally kill the app, but we don't want that in a test, instead we want
+                // it to throw.
+                throw new RuntimeException(what);
+            }
+        });
+        super.onCreate(arguments);
+    }
+
+    @Override
+    public void finish(int resultCode, Bundle results) {
+        sManager.destroy();
+        super.finish(resultCode, results);
+    }
+
+    public static void acquireMain() {
+        if (sManager != null) {
+            sManager.acquireMain();
+        }
+    }
+
+    public static void releaseMain() {
+        if (sManager != null) {
+            sManager.releaseMain();
+        }
+    }
+
+    public class MainLooperManager implements Runnable {
+
+        private final ArrayList<Throwable> mExceptions = new ArrayList<>();
+        private Message mStopMessage;
+        private final Handler mMainHandler;
+        private TestLooperManager mManager;
+
+        public MainLooperManager() {
+            mMainHandler = new Handler(Looper.getMainLooper());
+            startManaging();
+        }
+
+        @Override
+        public void run() {
+            try {
+                synchronized (this) {
+                    // Let the thing starting us know we are up and ready to run.
+                    notify();
+                }
+                while (true) {
+                    Message m = mManager.next();
+                    if (m == mStopMessage) {
+                        mManager.recycle(m);
+                        return;
+                    }
+                    try {
+                        mManager.execute(m);
+                    } catch (Throwable t) {
+                        if (!checkStack(t) || (mExceptions.size() == MAX_CRASHES)) {
+                            throw t;
+                        }
+                        mExceptions.add(t);
+                        Log.d(TAG, "Ignoring exception to run more tests", t);
+                    }
+                    mManager.recycle(m);
+                }
+            } finally {
+                mManager.release();
+                synchronized (this) {
+                    // Let the caller know we are done managing the main thread.
+                    notify();
+                }
+            }
+        }
+
+        private boolean checkStack(Throwable t) {
+            StackTraceElement topStack = t.getStackTrace()[0];
+            String className = topStack.getClassName();
+            if (className.equals(TestLooperManager.class.getName())) {
+                topStack = t.getCause().getStackTrace()[0];
+                className = topStack.getClassName();
+            }
+            // Only interested in blocking exceptions from the app itself, not from android
+            // framework.
+            return !className.startsWith("android.")
+                    && !className.startsWith("com.android.internal");
+        }
+
+        public void destroy() {
+            mStopMessage.sendToTarget();
+            if (mExceptions.size() != 0) {
+                throw new RuntimeException("Exception caught during tests", mExceptions.get(0));
+            }
+        }
+
+        public void acquireMain() {
+            synchronized (this) {
+                mStopMessage.sendToTarget();
+                try {
+                    wait();
+                } catch (InterruptedException e) {
+                }
+            }
+        }
+
+        public void releaseMain() {
+            startManaging();
+        }
+
+        private void startManaging() {
+            mStopMessage = mMainHandler.obtainMessage();
+            synchronized (this) {
+                mManager = acquireLooperManager(Looper.getMainLooper());
+                // This bit needs to happen on a background thread or it will hang if called
+                // from the same thread we are looking to block.
+                new Thread(() -> {
+                    // Post a message to the main handler that will manage executing all future
+                    // messages.
+                    mMainHandler.post(this);
+                    while (!mManager.hasMessages(mMainHandler, null, this));
+                    // Lastly run the message that executes this so it can manage the main thread.
+                    Message next = mManager.next();
+                    // Run through messages until we reach ours.
+                    while (next.getCallback() != this) {
+                        mManager.execute(next);
+                        mManager.recycle(next);
+                        next = mManager.next();
+                    }
+                    mManager.execute(next);
+                }).start();
+                if (Looper.myLooper() != Looper.getMainLooper()) {
+                    try {
+                        wait();
+                    } catch (InterruptedException e) {
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/tests/testables/src/android/testing/TestableLooper.java b/tests/testables/src/android/testing/TestableLooper.java
index f6c3cb3..f1a7092 100644
--- a/tests/testables/src/android/testing/TestableLooper.java
+++ b/tests/testables/src/android/testing/TestableLooper.java
@@ -29,7 +29,6 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
-import java.lang.reflect.Field;
 import java.util.Map;
 
 /**
@@ -49,7 +48,7 @@
     private TestLooperManager mQueueWrapper;
 
     public TestableLooper(Looper l) throws Exception {
-        this(InstrumentationRegistry.getInstrumentation().acquireLooperManager(l), l);
+        this(acquireLooperManager(l), l);
     }
 
     private TestableLooper(TestLooperManager wrapper, Looper l) throws Exception {
@@ -78,6 +77,9 @@
      */
     public void destroy() throws NoSuchFieldException, IllegalAccessException {
         mQueueWrapper.release();
+        if (mLooper == Looper.getMainLooper()) {
+            TestableInstrumentation.releaseMain();
+        }
     }
 
     /**
@@ -196,6 +198,13 @@
         }
     }
 
+    private static TestLooperManager acquireLooperManager(Looper l) {
+        if (l == Looper.getMainLooper()) {
+            TestableInstrumentation.acquireMain();
+        }
+        return InstrumentationRegistry.getInstrumentation().acquireLooperManager(l);
+    }
+
     private static final Map<Object, TestableLooper> sLoopers = new ArrayMap<>();
 
     /**
@@ -247,8 +256,7 @@
             }
             boolean set = mTestableLooper.mQueueWrapper == null;
             if (set) {
-                mTestableLooper.mQueueWrapper = InstrumentationRegistry.getInstrumentation()
-                        .acquireLooperManager(mLooper);
+                mTestableLooper.mQueueWrapper = acquireLooperManager(mLooper);
             }
             try {
                 Object[] ret = new Object[1];
@@ -283,6 +291,9 @@
                 if (set) {
                     mTestableLooper.mQueueWrapper.release();
                     mTestableLooper.mQueueWrapper = null;
+                    if (mLooper == Looper.getMainLooper()) {
+                        TestableInstrumentation.releaseMain();
+                    }
                 }
             }
         }
diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp
index 1dc47f8..d39a8a8 100644
--- a/tools/aapt2/Android.bp
+++ b/tools/aapt2/Android.bp
@@ -85,6 +85,7 @@
         "compile/Pseudolocalizer.cpp",
         "compile/XmlIdCollector.cpp",
         "configuration/ConfigurationParser.cpp",
+        "filter/AbiFilter.cpp",
         "filter/ConfigFilter.cpp",
         "flatten/Archive.cpp",
         "flatten/TableFlattener.cpp",
diff --git a/tools/aapt2/LoadedApk.cpp b/tools/aapt2/LoadedApk.cpp
index 8a8f8be..7e5efa1 100644
--- a/tools/aapt2/LoadedApk.cpp
+++ b/tools/aapt2/LoadedApk.cpp
@@ -57,6 +57,12 @@
 
 bool LoadedApk::WriteToArchive(IAaptContext* context, const TableFlattenerOptions& options,
                                IArchiveWriter* writer) {
+  FilterChain empty;
+  return WriteToArchive(context, options, &empty, writer);
+}
+
+bool LoadedApk::WriteToArchive(IAaptContext* context, const TableFlattenerOptions& options,
+                               FilterChain* filters, IArchiveWriter* writer) {
   std::set<std::string> referenced_resources;
   // List the files being referenced in the resource table.
   for (auto& pkg : table_->packages) {
@@ -89,6 +95,13 @@
       continue;
     }
 
+    if (!filters->Keep(path)) {
+      if (context->IsVerbose()) {
+        context->GetDiagnostics()->Note(DiagMessage() << "Filtered '" << path << "' from APK.");
+      }
+      continue;
+    }
+
     // The resource table needs to be re-serialized since it might have changed.
     if (path == "resources.arsc") {
       BigBuffer buffer(4096);
diff --git a/tools/aapt2/LoadedApk.h b/tools/aapt2/LoadedApk.h
index 59eb816..8aa9674 100644
--- a/tools/aapt2/LoadedApk.h
+++ b/tools/aapt2/LoadedApk.h
@@ -20,6 +20,7 @@
 #include "androidfw/StringPiece.h"
 
 #include "ResourceTable.h"
+#include "filter/Filter.h"
 #include "flatten/Archive.h"
 #include "flatten/TableFlattener.h"
 #include "io/ZipArchive.h"
@@ -49,6 +50,14 @@
   bool WriteToArchive(IAaptContext* context, const TableFlattenerOptions& options,
                       IArchiveWriter* writer);
 
+  /**
+   * Writes the APK on disk at the given path, while also removing the resource
+   * files that are not referenced in the resource table. The provided filter
+   * chain is applied to each entry in the APK file.
+   */
+  bool WriteToArchive(IAaptContext* context, const TableFlattenerOptions& options,
+                      FilterChain* filters, IArchiveWriter* writer);
+
   static std::unique_ptr<LoadedApk> LoadApkFromPath(IAaptContext* context,
                                                     const android::StringPiece& path);
 
diff --git a/tools/aapt2/ResourceUtils.cpp b/tools/aapt2/ResourceUtils.cpp
index deeef6e..6e6a2ba 100644
--- a/tools/aapt2/ResourceUtils.cpp
+++ b/tools/aapt2/ResourceUtils.cpp
@@ -512,7 +512,7 @@
 }
 
 std::unique_ptr<BinaryPrimitive> TryParseInt(const StringPiece& str) {
-  std::u16string str16 = util::Utf8ToUtf16(str);
+  std::u16string str16 = util::Utf8ToUtf16(util::TrimWhitespace(str));
   android::Res_value value;
   if (!android::ResTable::stringToInt(str16.data(), str16.size(), &value)) {
     return {};
@@ -521,7 +521,7 @@
 }
 
 std::unique_ptr<BinaryPrimitive> TryParseFloat(const StringPiece& str) {
-  std::u16string str16 = util::Utf8ToUtf16(str);
+  std::u16string str16 = util::Utf8ToUtf16(util::TrimWhitespace(str));
   android::Res_value value;
   if (!android::ResTable::stringToFloat(str16.data(), str16.size(), &value)) {
     return {};
diff --git a/tools/aapt2/ResourceUtils_test.cpp b/tools/aapt2/ResourceUtils_test.cpp
index 3a5e685e..e637c3e 100644
--- a/tools/aapt2/ResourceUtils_test.cpp
+++ b/tools/aapt2/ResourceUtils_test.cpp
@@ -36,6 +36,8 @@
   EXPECT_THAT(ResourceUtils::ParseBool("false"), Eq(Maybe<bool>(false)));
   EXPECT_THAT(ResourceUtils::ParseBool("FALSE"), Eq(Maybe<bool>(false)));
   EXPECT_THAT(ResourceUtils::ParseBool("False"), Eq(Maybe<bool>(false)));
+
+  EXPECT_THAT(ResourceUtils::ParseBool(" False\n "), Eq(Maybe<bool>(false)));
 }
 
 TEST(ResourceUtilsTest, ParseResourceName) {
@@ -199,4 +201,16 @@
   ASSERT_THAT(ResourceUtils::TryParseNullOrEmpty("@empty"), Pointee(ValueEq(BinaryPrimitive(Res_value::TYPE_NULL, Res_value::DATA_NULL_EMPTY))));
 }
 
+TEST(ResourceUtilsTest, ItemsWithWhitespaceAreParsedCorrectly) {
+  EXPECT_THAT(ResourceUtils::TryParseItemForAttribute(" 12\n   ", ResTable_map::TYPE_INTEGER),
+              Pointee(ValueEq(BinaryPrimitive(Res_value::TYPE_INT_DEC, 12u))));
+  EXPECT_THAT(ResourceUtils::TryParseItemForAttribute(" true\n   ", ResTable_map::TYPE_BOOLEAN),
+              Pointee(ValueEq(BinaryPrimitive(Res_value::TYPE_INT_BOOLEAN, 0xffffffffu))));
+
+  const float expected_float = 12.0f;
+  const uint32_t expected_float_flattened = *(uint32_t*)&expected_float;
+  EXPECT_THAT(ResourceUtils::TryParseItemForAttribute(" 12.0\n   ", ResTable_map::TYPE_FLOAT),
+              Pointee(ValueEq(BinaryPrimitive(Res_value::TYPE_FLOAT, expected_float_flattened))));
+}
+
 }  // namespace aapt
diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp
index 740a401..e6bf3a6 100644
--- a/tools/aapt2/cmd/Link.cpp
+++ b/tools/aapt2/cmd/Link.cpp
@@ -989,7 +989,8 @@
       manifest_class->GetCommentBuilder()->AppendComment(proper_annotation);
     }
 
-    const std::string& package_utf8 = context_->GetCompilationPackage();
+    const std::string package_utf8 =
+        options_.custom_java_package.value_or_default(context_->GetCompilationPackage());
 
     std::string out_path = options_.generate_java_class_path.value();
     file::AppendPath(&out_path, file::PackageToPath(package_utf8));
diff --git a/tools/aapt2/cmd/Optimize.cpp b/tools/aapt2/cmd/Optimize.cpp
index 194c0c8..9d71775 100644
--- a/tools/aapt2/cmd/Optimize.cpp
+++ b/tools/aapt2/cmd/Optimize.cpp
@@ -17,6 +17,7 @@
 #include <memory>
 #include <vector>
 
+#include "android-base/stringprintf.h"
 #include "androidfw/StringPiece.h"
 
 #include "Diagnostics.h"
@@ -26,6 +27,8 @@
 #include "SdkConstants.h"
 #include "ValueVisitor.h"
 #include "cmd/Util.h"
+#include "configuration/ConfigurationParser.h"
+#include "filter/AbiFilter.h"
 #include "flatten/TableFlattener.h"
 #include "flatten/XmlFlattener.h"
 #include "io/BigBufferInputStream.h"
@@ -33,14 +36,21 @@
 #include "optimize/ResourceDeduper.h"
 #include "optimize/VersionCollapser.h"
 #include "split/TableSplitter.h"
+#include "util/Files.h"
 
-using android::StringPiece;
+using ::aapt::configuration::Abi;
+using ::aapt::configuration::Artifact;
+using ::aapt::configuration::PostProcessingConfiguration;
+using ::android::StringPiece;
+using ::android::base::StringPrintf;
 
 namespace aapt {
 
 struct OptimizeOptions {
   // Path to the output APK.
-  std::string output_path;
+  Maybe<std::string> output_path;
+  // Path to the output APK directory for splits.
+  Maybe<std::string> output_dir;
 
   // Details of the app extracted from the AndroidManifest.xml
   AppInfo app_info;
@@ -55,6 +65,8 @@
   std::vector<SplitConstraints> split_constraints;
 
   TableFlattenerOptions table_flattener_options;
+
+  Maybe<PostProcessingConfiguration> configuration;
 };
 
 class OptimizeContext : public IAaptContext {
@@ -175,10 +187,52 @@
       ++split_constraints_iter;
     }
 
-    std::unique_ptr<IArchiveWriter> writer =
-        CreateZipFileArchiveWriter(context_->GetDiagnostics(), options_.output_path);
-    if (!apk->WriteToArchive(context_, options_.table_flattener_options, writer.get())) {
-      return 1;
+    if (options_.configuration && options_.output_dir) {
+      PostProcessingConfiguration& config = options_.configuration.value();
+
+      // For now, just write out the stripped APK since ABI splitting doesn't modify anything else.
+      for (const Artifact& artifact : config.artifacts) {
+        if (artifact.abi_group) {
+          const std::string& group = artifact.abi_group.value();
+
+          auto abi_group = config.abi_groups.find(group);
+          // TODO: Remove validation when configuration parser ensures referential integrity.
+          if (abi_group == config.abi_groups.end()) {
+            context_->GetDiagnostics()->Note(
+                DiagMessage() << "could not find referenced ABI group '" << group << "'");
+            return 1;
+          }
+          FilterChain filters;
+          filters.AddFilter(AbiFilter::FromAbiList(abi_group->second));
+
+          const std::string& path = apk->GetSource().path;
+          const StringPiece ext = file::GetExtension(path);
+          const std::string name = path.substr(0, path.rfind(ext.to_string()));
+
+          // Name is hard coded for now since only one split dimension is supported.
+          // TODO: Incorporate name generation into the configuration objects.
+          const std::string file_name =
+              StringPrintf("%s.%s%s", name.c_str(), group.c_str(), ext.data());
+          std::string out = options_.output_dir.value();
+          file::AppendPath(&out, file_name);
+
+          std::unique_ptr<IArchiveWriter> writer =
+              CreateZipFileArchiveWriter(context_->GetDiagnostics(), out);
+
+          if (!apk->WriteToArchive(context_, options_.table_flattener_options, &filters,
+                                   writer.get())) {
+            return 1;
+          }
+        }
+      }
+    }
+
+    if (options_.output_path) {
+      std::unique_ptr<IArchiveWriter> writer =
+          CreateZipFileArchiveWriter(context_->GetDiagnostics(), options_.output_path.value());
+      if (!apk->WriteToArchive(context_, options_.table_flattener_options, writer.get())) {
+        return 1;
+      }
     }
 
     return 0;
@@ -214,8 +268,8 @@
             if (file_ref->file == nullptr) {
               ResourceNameRef name(pkg->name, type->type, entry->name);
               context_->GetDiagnostics()->Warn(DiagMessage(file_ref->GetSource())
-                                                << "file for resource " << name << " with config '"
-                                                << config_value->config << "' not found");
+                                               << "file for resource " << name << " with config '"
+                                               << config_value->config << "' not found");
               continue;
             }
 
@@ -293,13 +347,16 @@
 int Optimize(const std::vector<StringPiece>& args) {
   OptimizeContext context;
   OptimizeOptions options;
+  Maybe<std::string> config_path;
   Maybe<std::string> target_densities;
   std::vector<std::string> configs;
   std::vector<std::string> split_args;
   bool verbose = false;
   Flags flags =
       Flags()
-          .RequiredFlag("-o", "Path to the output APK.", &options.output_path)
+          .OptionalFlag("-o", "Path to the output APK.", &options.output_path)
+          .OptionalFlag("-d", "Path to the output directory (for splits).", &options.output_dir)
+          .OptionalFlag("-x", "Path to XML configuration file.", &config_path)
           .OptionalFlag(
               "--target-densities",
               "Comma separated list of the screen densities that the APK will be optimized for.\n"
@@ -369,6 +426,22 @@
     }
   }
 
+  if (config_path) {
+    if (!options.output_dir) {
+      context.GetDiagnostics()->Error(
+          DiagMessage() << "Output directory is required when using a configuration file");
+      return 1;
+    }
+    std::string& path = config_path.value();
+    Maybe<ConfigurationParser> for_path = ConfigurationParser::ForPath(path);
+    if (for_path) {
+      options.configuration = for_path.value().WithDiagnostics(context.GetDiagnostics()).Parse();
+    } else {
+      context.GetDiagnostics()->Error(DiagMessage() << "Could not parse config file " << path);
+      return 1;
+    }
+  }
+
   if (!ExtractAppDataFromManifest(&context, apk.get(), &options)) {
     return 1;
   }
diff --git a/tools/aapt2/configuration/ConfigurationParser.cpp b/tools/aapt2/configuration/ConfigurationParser.cpp
index 303a809..0b6743c 100644
--- a/tools/aapt2/configuration/ConfigurationParser.cpp
+++ b/tools/aapt2/configuration/ConfigurationParser.cpp
@@ -18,6 +18,7 @@
 
 #include <algorithm>
 #include <functional>
+#include <map>
 #include <memory>
 #include <utility>
 
@@ -41,7 +42,7 @@
 using ::aapt::configuration::AndroidManifest;
 using ::aapt::configuration::AndroidSdk;
 using ::aapt::configuration::Artifact;
-using ::aapt::configuration::Configuration;
+using ::aapt::configuration::PostProcessingConfiguration;
 using ::aapt::configuration::GlTexture;
 using ::aapt::configuration::Group;
 using ::aapt::configuration::Locale;
@@ -56,15 +57,15 @@
 using ::aapt::xml::XmlNodeAction;
 using ::android::base::ReadFileToString;
 
-const std::unordered_map<std::string, Abi> kAbiMap = {
-    {"armeabi", Abi::kArmeV6},
-    {"armeabi-v7a", Abi::kArmV7a},
-    {"arm64-v8a", Abi::kArm64V8a},
-    {"x86", Abi::kX86},
-    {"x86_64", Abi::kX86_64},
-    {"mips", Abi::kMips},
-    {"mips64", Abi::kMips64},
-    {"universal", Abi::kUniversal},
+const std::unordered_map<std::string, Abi> kStringToAbiMap = {
+    {"armeabi", Abi::kArmeV6}, {"armeabi-v7a", Abi::kArmV7a},  {"arm64-v8a", Abi::kArm64V8a},
+    {"x86", Abi::kX86},        {"x86_64", Abi::kX86_64},       {"mips", Abi::kMips},
+    {"mips64", Abi::kMips64},  {"universal", Abi::kUniversal},
+};
+const std::map<Abi, std::string> kAbiToStringMap = {
+    {Abi::kArmeV6, "armeabi"}, {Abi::kArmV7a, "armeabi-v7a"},  {Abi::kArm64V8a, "arm64-v8a"},
+    {Abi::kX86, "x86"},        {Abi::kX86_64, "x86_64"},       {Abi::kMips, "mips"},
+    {Abi::kMips64, "mips64"},  {Abi::kUniversal, "universal"},
 };
 
 constexpr const char* kAaptXmlNs = "http://schemas.android.com/tools/aapt";
@@ -102,7 +103,13 @@
 
 }  // namespace
 
+namespace configuration {
 
+const std::string& AbiToString(Abi abi) {
+  return kAbiToStringMap.find(abi)->second;
+}
+
+}  // namespace configuration
 
 /** Returns a ConfigurationParser for the file located at the provided path. */
 Maybe<ConfigurationParser> ConfigurationParser::ForPath(const std::string& path) {
@@ -118,7 +125,7 @@
       diag_(&noop_) {
 }
 
-Maybe<Configuration> ConfigurationParser::Parse() {
+Maybe<PostProcessingConfiguration> ConfigurationParser::Parse() {
   std::istringstream in(contents_);
 
   auto doc = xml::Inflate(&in, diag_, Source("config.xml"));
@@ -150,10 +157,11 @@
   XmlNodeAction& artifacts_action = root_action["artifacts"];
   XmlNodeAction& groups_action = root_action["groups"];
 
-  Configuration config;
+  PostProcessingConfiguration config;
 
   // Helper to bind a static method to an action handler in the DOM executor.
-  auto bind_handler = [&config](std::function<bool(Configuration*, Element*, IDiagnostics*)> h)
+  auto bind_handler =
+      [&config](std::function<bool(PostProcessingConfiguration*, Element*, IDiagnostics*)> h)
       -> XmlNodeAction::ActionFuncWithDiag {
     return std::bind(h, &config, std::placeholders::_1, std::placeholders::_2);
   };
@@ -175,275 +183,266 @@
     return {};
   }
 
+  // TODO: Validate all references in the configuration are valid. It should be safe to assume from
+  // this point on that any references from one section to another will be present.
+
   return {config};
 }
 
 ConfigurationParser::ActionHandler ConfigurationParser::artifact_handler_ =
-    [](Configuration* config, Element* root_element, IDiagnostics* diag) -> bool {
-      Artifact artifact{};
-      for (const auto& attr : root_element->attributes) {
-        if (attr.name == "name") {
-          artifact.name = attr.value;
-        } else if (attr.name == "abi-group") {
-          artifact.abi_group = {attr.value};
-        } else if (attr.name == "screen-density-group") {
-          artifact.screen_density_group = {attr.value};
-        } else if (attr.name == "locale-group") {
-          artifact.locale_group = {attr.value};
-        } else if (attr.name == "android-sdk-group") {
-          artifact.android_sdk_group = {attr.value};
-        } else if (attr.name == "gl-texture-group") {
-          artifact.gl_texture_group = {attr.value};
-        } else if (attr.name == "device-feature-group") {
-          artifact.device_feature_group = {attr.value};
-        } else {
-          diag->Note(
-              DiagMessage() << "Unknown artifact attribute: " << attr.name << " = " << attr.value);
-        }
-      }
-      config->artifacts[artifact.name] = artifact;
-      return true;
-    };
+    [](PostProcessingConfiguration* config, Element* root_element, IDiagnostics* diag) -> bool {
+  Artifact artifact{};
+  for (const auto& attr : root_element->attributes) {
+    if (attr.name == "name") {
+      artifact.name = attr.value;
+    } else if (attr.name == "abi-group") {
+      artifact.abi_group = {attr.value};
+    } else if (attr.name == "screen-density-group") {
+      artifact.screen_density_group = {attr.value};
+    } else if (attr.name == "locale-group") {
+      artifact.locale_group = {attr.value};
+    } else if (attr.name == "android-sdk-group") {
+      artifact.android_sdk_group = {attr.value};
+    } else if (attr.name == "gl-texture-group") {
+      artifact.gl_texture_group = {attr.value};
+    } else if (attr.name == "device-feature-group") {
+      artifact.device_feature_group = {attr.value};
+    } else {
+      diag->Note(DiagMessage() << "Unknown artifact attribute: " << attr.name << " = "
+                               << attr.value);
+    }
+  }
+  config->artifacts.push_back(artifact);
+  return true;
+};
 
 ConfigurationParser::ActionHandler ConfigurationParser::artifact_format_handler_ =
-    [](Configuration* config, Element* root_element, IDiagnostics* diag) -> bool {
-      for (auto& node : root_element->children) {
+    [](PostProcessingConfiguration* config, Element* root_element, IDiagnostics* diag) -> bool {
+  for (auto& node : root_element->children) {
+    xml::Text* t;
+    if ((t = NodeCast<xml::Text>(node.get())) != nullptr) {
+      config->artifact_format = TrimWhitespace(t->text).to_string();
+      break;
+    }
+  }
+  return true;
+};
+
+ConfigurationParser::ActionHandler ConfigurationParser::abi_group_handler_ =
+    [](PostProcessingConfiguration* config, Element* root_element, IDiagnostics* diag) -> bool {
+  std::string label = GetLabel(root_element, diag);
+  if (label.empty()) {
+    return false;
+  }
+
+  auto& group = config->abi_groups[label];
+  bool valid = true;
+
+  for (auto* child : root_element->GetChildElements()) {
+    if (child->name != "abi") {
+      diag->Error(DiagMessage() << "Unexpected element in ABI group: " << child->name);
+      valid = false;
+    } else {
+      for (auto& node : child->children) {
         xml::Text* t;
         if ((t = NodeCast<xml::Text>(node.get())) != nullptr) {
-          config->artifact_format = TrimWhitespace(t->text).to_string();
+          group.push_back(kStringToAbiMap.at(TrimWhitespace(t->text).to_string()));
           break;
         }
       }
-      return true;
-    };
+    }
+  }
 
-ConfigurationParser::ActionHandler ConfigurationParser::abi_group_handler_ =
-    [](Configuration* config, Element* root_element, IDiagnostics* diag) -> bool {
-      std::string label = GetLabel(root_element, diag);
-      if (label.empty()) {
-        return false;
-      }
-
-      auto& group = config->abi_groups[label];
-      bool valid = true;
-
-      for (auto* child : root_element->GetChildElements()) {
-        if (child->name != "abi") {
-          diag->Error(
-              DiagMessage() << "Unexpected element in ABI group: " << child->name);
-          valid = false;
-        } else {
-          for (auto& node : child->children) {
-            xml::Text* t;
-            if ((t = NodeCast<xml::Text>(node.get())) != nullptr) {
-              group.push_back(kAbiMap.at(TrimWhitespace(t->text).to_string()));
-              break;
-            }
-          }
-        }
-      }
-
-      return valid;
-    };
+  return valid;
+};
 
 ConfigurationParser::ActionHandler ConfigurationParser::screen_density_group_handler_ =
-    [](Configuration* config, Element* root_element, IDiagnostics* diag) -> bool {
-      std::string label = GetLabel(root_element, diag);
-      if (label.empty()) {
-        return false;
-      }
+    [](PostProcessingConfiguration* config, Element* root_element, IDiagnostics* diag) -> bool {
+  std::string label = GetLabel(root_element, diag);
+  if (label.empty()) {
+    return false;
+  }
 
-      auto& group = config->screen_density_groups[label];
-      bool valid = true;
+  auto& group = config->screen_density_groups[label];
+  bool valid = true;
 
-      for (auto* child : root_element->GetChildElements()) {
-        if (child->name != "screen-density") {
-          diag->Error(
-              DiagMessage() << "Unexpected root_element in screen density group: "
-                            << child->name);
-          valid = false;
-        } else {
-          for (auto& node : child->children) {
-            xml::Text* t;
-            if ((t = NodeCast<xml::Text>(node.get())) != nullptr) {
-              ConfigDescription config_descriptor;
-              const android::StringPiece& text = TrimWhitespace(t->text);
-              if (ConfigDescription::Parse(text, &config_descriptor)) {
-                // Copy the density with the minimum SDK version stripped out.
-                group.push_back(config_descriptor.CopyWithoutSdkVersion());
-              } else {
-                diag->Error(
-                    DiagMessage() << "Could not parse config descriptor for screen-density: "
-                                  << text);
-                valid = false;
-              }
-              break;
-            }
+  for (auto* child : root_element->GetChildElements()) {
+    if (child->name != "screen-density") {
+      diag->Error(DiagMessage() << "Unexpected root_element in screen density group: "
+                                << child->name);
+      valid = false;
+    } else {
+      for (auto& node : child->children) {
+        xml::Text* t;
+        if ((t = NodeCast<xml::Text>(node.get())) != nullptr) {
+          ConfigDescription config_descriptor;
+          const android::StringPiece& text = TrimWhitespace(t->text);
+          if (ConfigDescription::Parse(text, &config_descriptor)) {
+            // Copy the density with the minimum SDK version stripped out.
+            group.push_back(config_descriptor.CopyWithoutSdkVersion());
+          } else {
+            diag->Error(DiagMessage()
+                        << "Could not parse config descriptor for screen-density: " << text);
+            valid = false;
           }
+          break;
         }
       }
+    }
+  }
 
-      return valid;
-    };
+  return valid;
+};
 
 ConfigurationParser::ActionHandler ConfigurationParser::locale_group_handler_ =
-    [](Configuration* config, Element* root_element, IDiagnostics* diag) -> bool {
-      std::string label = GetLabel(root_element, diag);
-      if (label.empty()) {
-        return false;
-      }
+    [](PostProcessingConfiguration* config, Element* root_element, IDiagnostics* diag) -> bool {
+  std::string label = GetLabel(root_element, diag);
+  if (label.empty()) {
+    return false;
+  }
 
-      auto& group = config->locale_groups[label];
-      bool valid = true;
+  auto& group = config->locale_groups[label];
+  bool valid = true;
 
-      for (auto* child : root_element->GetChildElements()) {
-        if (child->name != "locale") {
-          diag->Error(
-              DiagMessage() << "Unexpected root_element in screen density group: "
-                            << child->name);
-          valid = false;
+  for (auto* child : root_element->GetChildElements()) {
+    if (child->name != "locale") {
+      diag->Error(DiagMessage() << "Unexpected root_element in screen density group: "
+                                << child->name);
+      valid = false;
+    } else {
+      Locale entry;
+      for (const auto& attr : child->attributes) {
+        if (attr.name == "lang") {
+          entry.lang = {attr.value};
+        } else if (attr.name == "region") {
+          entry.region = {attr.value};
         } else {
-          Locale entry;
-          for (const auto& attr : child->attributes) {
-            if (attr.name == "lang") {
-              entry.lang = {attr.value};
-            } else if (attr.name == "region") {
-              entry.region = {attr.value};
-            } else {
-              diag->Warn(DiagMessage() << "Unknown attribute: " << attr.name
-                                       << " = " << attr.value);
-            }
-          }
-          group.push_back(entry);
+          diag->Warn(DiagMessage() << "Unknown attribute: " << attr.name << " = " << attr.value);
         }
       }
+      group.push_back(entry);
+    }
+  }
 
-      return valid;
-    };
+  return valid;
+};
 
 ConfigurationParser::ActionHandler ConfigurationParser::android_sdk_group_handler_ =
-    [](Configuration* config, Element* root_element, IDiagnostics* diag) -> bool {
-      std::string label = GetLabel(root_element, diag);
-      if (label.empty()) {
-        return false;
-      }
+    [](PostProcessingConfiguration* config, Element* root_element, IDiagnostics* diag) -> bool {
+  std::string label = GetLabel(root_element, diag);
+  if (label.empty()) {
+    return false;
+  }
 
-      auto& group = config->android_sdk_groups[label];
-      bool valid = true;
+  auto& group = config->android_sdk_groups[label];
+  bool valid = true;
 
-      for (auto* child : root_element->GetChildElements()) {
-        if (child->name != "android-sdk") {
-          diag->Error(
-              DiagMessage() << "Unexpected root_element in ABI group: " << child->name);
-          valid = false;
+  for (auto* child : root_element->GetChildElements()) {
+    if (child->name != "android-sdk") {
+      diag->Error(DiagMessage() << "Unexpected root_element in ABI group: " << child->name);
+      valid = false;
+    } else {
+      AndroidSdk entry;
+      for (const auto& attr : child->attributes) {
+        if (attr.name == "minSdkVersion") {
+          entry.min_sdk_version = {attr.value};
+        } else if (attr.name == "targetSdkVersion") {
+          entry.target_sdk_version = {attr.value};
+        } else if (attr.name == "maxSdkVersion") {
+          entry.max_sdk_version = {attr.value};
         } else {
-          AndroidSdk entry;
-          for (const auto& attr : child->attributes) {
-            if (attr.name == "minSdkVersion") {
-              entry.min_sdk_version = {attr.value};
-            } else if (attr.name == "targetSdkVersion") {
-              entry.target_sdk_version = {attr.value};
-            } else if (attr.name == "maxSdkVersion") {
-              entry.max_sdk_version = {attr.value};
-            } else {
-              diag->Warn(DiagMessage() << "Unknown attribute: " << attr.name
-                                       << " = " << attr.value);
-            }
-          }
-
-          // TODO: Fill in the manifest details when they are finalised.
-          for (auto node : child->GetChildElements()) {
-            if (node->name == "manifest") {
-              if (entry.manifest) {
-                diag->Warn(DiagMessage() << "Found multiple manifest tags. Ignoring duplicates.");
-                continue;
-              }
-              entry.manifest = {AndroidManifest()};
-            }
-          }
-
-          group.push_back(entry);
+          diag->Warn(DiagMessage() << "Unknown attribute: " << attr.name << " = " << attr.value);
         }
       }
 
-      return valid;
-    };
+      // TODO: Fill in the manifest details when they are finalised.
+      for (auto node : child->GetChildElements()) {
+        if (node->name == "manifest") {
+          if (entry.manifest) {
+            diag->Warn(DiagMessage() << "Found multiple manifest tags. Ignoring duplicates.");
+            continue;
+          }
+          entry.manifest = {AndroidManifest()};
+        }
+      }
+
+      group.push_back(entry);
+    }
+  }
+
+  return valid;
+};
 
 ConfigurationParser::ActionHandler ConfigurationParser::gl_texture_group_handler_ =
-    [](Configuration* config, Element* root_element, IDiagnostics* diag) -> bool {
-      std::string label = GetLabel(root_element, diag);
-      if (label.empty()) {
-        return false;
+    [](PostProcessingConfiguration* config, Element* root_element, IDiagnostics* diag) -> bool {
+  std::string label = GetLabel(root_element, diag);
+  if (label.empty()) {
+    return false;
+  }
+
+  auto& group = config->gl_texture_groups[label];
+  bool valid = true;
+
+  GlTexture result;
+  for (auto* child : root_element->GetChildElements()) {
+    if (child->name != "gl-texture") {
+      diag->Error(DiagMessage() << "Unexpected element in GL texture group: " << child->name);
+      valid = false;
+    } else {
+      for (const auto& attr : child->attributes) {
+        if (attr.name == "name") {
+          result.name = attr.value;
+          break;
+        }
       }
 
-      auto& group = config->gl_texture_groups[label];
-      bool valid = true;
-
-      GlTexture result;
-      for (auto* child : root_element->GetChildElements()) {
-        if (child->name != "gl-texture") {
-          diag->Error(
-              DiagMessage() << "Unexpected element in GL texture group: "
-                            << child->name);
+      for (auto* element : child->GetChildElements()) {
+        if (element->name != "texture-path") {
+          diag->Error(DiagMessage() << "Unexpected element in gl-texture element: " << child->name);
           valid = false;
-        } else {
-          for (const auto& attr : child->attributes) {
-            if (attr.name == "name") {
-              result.name = attr.value;
-              break;
-            }
-          }
-
-          for (auto* element : child->GetChildElements()) {
-            if (element->name != "texture-path") {
-              diag->Error(
-                  DiagMessage() << "Unexpected element in gl-texture element: "
-                                << child->name);
-              valid = false;
-              continue;
-            }
-            for (auto& node : element->children) {
-              xml::Text* t;
-              if ((t = NodeCast<xml::Text>(node.get())) != nullptr) {
-                result.texture_paths.push_back(TrimWhitespace(t->text).to_string());
-              }
-            }
+          continue;
+        }
+        for (auto& node : element->children) {
+          xml::Text* t;
+          if ((t = NodeCast<xml::Text>(node.get())) != nullptr) {
+            result.texture_paths.push_back(TrimWhitespace(t->text).to_string());
           }
         }
-        group.push_back(result);
       }
+    }
+    group.push_back(result);
+  }
 
-      return valid;
-    };
+  return valid;
+};
 
 ConfigurationParser::ActionHandler ConfigurationParser::device_feature_group_handler_ =
-    [](Configuration* config, Element* root_element, IDiagnostics* diag) -> bool {
-      std::string label = GetLabel(root_element, diag);
-      if (label.empty()) {
-        return false;
-      }
+    [](PostProcessingConfiguration* config, Element* root_element, IDiagnostics* diag) -> bool {
+  std::string label = GetLabel(root_element, diag);
+  if (label.empty()) {
+    return false;
+  }
 
-      auto& group = config->device_feature_groups[label];
-      bool valid = true;
+  auto& group = config->device_feature_groups[label];
+  bool valid = true;
 
-      for (auto* child : root_element->GetChildElements()) {
-        if (child->name != "supports-feature") {
-          diag->Error(
-              DiagMessage() << "Unexpected root_element in device feature group: "
-                            << child->name);
-          valid = false;
-        } else {
-          for (auto& node : child->children) {
-            xml::Text* t;
-            if ((t = NodeCast<xml::Text>(node.get())) != nullptr) {
-              group.push_back(TrimWhitespace(t->text).to_string());
-              break;
-            }
-          }
+  for (auto* child : root_element->GetChildElements()) {
+    if (child->name != "supports-feature") {
+      diag->Error(DiagMessage() << "Unexpected root_element in device feature group: "
+                                << child->name);
+      valid = false;
+    } else {
+      for (auto& node : child->children) {
+        xml::Text* t;
+        if ((t = NodeCast<xml::Text>(node.get())) != nullptr) {
+          group.push_back(TrimWhitespace(t->text).to_string());
+          break;
         }
       }
+    }
+  }
 
-      return valid;
-    };
+  return valid;
+};
 
 }  // namespace aapt
diff --git a/tools/aapt2/configuration/ConfigurationParser.h b/tools/aapt2/configuration/ConfigurationParser.h
index 8b9c085..3fae5dd 100644
--- a/tools/aapt2/configuration/ConfigurationParser.h
+++ b/tools/aapt2/configuration/ConfigurationParser.h
@@ -62,6 +62,9 @@
   kUniversal
 };
 
+/** Helper method to convert an ABI to a string representing the path within the APK. */
+const std::string& AbiToString(Abi abi);
+
 /**
  * Represents an individual locale. When a locale is included, it must be
  * declared from least specific to most specific, as a region does not make
@@ -114,11 +117,10 @@
   }
 };
 
-/**
- * AAPT2 XML configuration binary representation.
- */
-struct Configuration {
-  std::unordered_map<std::string, Artifact> artifacts;
+/** AAPT2 XML configuration file binary representation. */
+struct PostProcessingConfiguration {
+  // TODO: Support named artifacts?
+  std::vector<Artifact> artifacts;
   Maybe<std::string> artifact_format;
 
   Group<Abi> abi_groups;
@@ -162,7 +164,7 @@
    * Parses the configuration file and returns the results. If the configuration could not be parsed
    * the result is empty and any errors will be displayed with the provided diagnostics context.
    */
-  Maybe<configuration::Configuration> Parse();
+  Maybe<configuration::PostProcessingConfiguration> Parse();
 
  protected:
   /**
@@ -181,9 +183,8 @@
    * An ActionHandler for processing XML elements in the XmlActionExecutor. Returns true if the
    * element was successfully processed, otherwise returns false.
    */
-  using ActionHandler = std::function<bool(configuration::Configuration* config,
-                                           xml::Element* element,
-                                           IDiagnostics* diag)>;
+  using ActionHandler = std::function<bool(configuration::PostProcessingConfiguration* config,
+                                           xml::Element* element, IDiagnostics* diag)>;
 
   /** Handler for <artifact> tags. */
   static ActionHandler artifact_handler_;
diff --git a/tools/aapt2/configuration/ConfigurationParser_test.cpp b/tools/aapt2/configuration/ConfigurationParser_test.cpp
index 8421ee3..a4fa134 100644
--- a/tools/aapt2/configuration/ConfigurationParser_test.cpp
+++ b/tools/aapt2/configuration/ConfigurationParser_test.cpp
@@ -32,7 +32,7 @@
 using android::ResTable_config;
 using configuration::Abi;
 using configuration::AndroidSdk;
-using configuration::Configuration;
+using configuration::PostProcessingConfiguration;
 using configuration::DeviceFeature;
 using configuration::GlTexture;
 using configuration::Locale;
@@ -139,7 +139,7 @@
   auto parser = ConfigurationParser::ForContents(kValidConfig).WithDiagnostics(&diag_);
   auto result = parser.Parse();
   ASSERT_TRUE(result);
-  Configuration& value = result.value();
+  PostProcessingConfiguration& value = result.value();
   EXPECT_EQ(2ul, value.artifacts.size());
   ASSERT_TRUE(value.artifact_format);
   EXPECT_EQ(
@@ -190,13 +190,13 @@
 
   auto doc = test::BuildXmlDom(xml);
 
-  Configuration config;
+  PostProcessingConfiguration config;
   bool ok = artifact_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
   ASSERT_TRUE(ok);
 
   EXPECT_EQ(1ul, config.artifacts.size());
 
-  auto& artifact = config.artifacts.begin()->second;
+  auto& artifact = config.artifacts.front();
   EXPECT_EQ("", artifact.name); // TODO: make this fail.
   EXPECT_EQ("arm", artifact.abi_group.value());
   EXPECT_EQ("large", artifact.screen_density_group.value());
@@ -204,6 +204,21 @@
   EXPECT_EQ("19", artifact.android_sdk_group.value());
   EXPECT_EQ("dxt1", artifact.gl_texture_group.value());
   EXPECT_EQ("low-latency", artifact.device_feature_group.value());
+
+  // Perform a second action to ensure we get 2 artifacts.
+  static constexpr const char* second = R"xml(
+    <artifact
+        abi-group="other"
+        screen-density-group="large"
+        locale-group="europe"
+        android-sdk-group="19"
+        gl-texture-group="dxt1"
+        device-feature-group="low-latency"/>)xml";
+  doc = test::BuildXmlDom(second);
+
+  ok = artifact_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
+  ASSERT_TRUE(ok);
+  EXPECT_EQ(2ul, config.artifacts.size());
 }
 
 TEST_F(ConfigurationParserTest, ArtifactFormatAction) {
@@ -214,7 +229,7 @@
 
   auto doc = test::BuildXmlDom(xml);
 
-  Configuration config;
+  PostProcessingConfiguration config;
   bool ok = artifact_format_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
   ASSERT_TRUE(ok);
   ASSERT_TRUE(config.artifact_format);
@@ -237,7 +252,7 @@
 
   auto doc = test::BuildXmlDom(xml);
 
-  Configuration config;
+  PostProcessingConfiguration config;
   bool ok = abi_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
   ASSERT_TRUE(ok);
 
@@ -260,7 +275,7 @@
 
   auto doc = test::BuildXmlDom(xml);
 
-  Configuration config;
+  PostProcessingConfiguration config;
   bool ok =
       screen_density_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
   ASSERT_TRUE(ok);
@@ -290,7 +305,7 @@
 
   auto doc = test::BuildXmlDom(xml);
 
-  Configuration config;
+  PostProcessingConfiguration config;
   bool ok = locale_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
   ASSERT_TRUE(ok);
 
@@ -326,7 +341,7 @@
 
   auto doc = test::BuildXmlDom(xml);
 
-  Configuration config;
+  PostProcessingConfiguration config;
   bool ok = android_sdk_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
   ASSERT_TRUE(ok);
 
@@ -358,7 +373,7 @@
 
   auto doc = test::BuildXmlDom(xml);
 
-  Configuration config;
+  PostProcessingConfiguration config;
   bool ok = gl_texture_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
   ASSERT_TRUE(ok);
 
@@ -387,7 +402,7 @@
 
   auto doc = test::BuildXmlDom(xml);
 
-  Configuration config;
+  PostProcessingConfiguration config;
   bool ok
       = device_feature_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
   ASSERT_TRUE(ok);
diff --git a/tools/aapt2/filter/AbiFilter.cpp b/tools/aapt2/filter/AbiFilter.cpp
new file mode 100644
index 0000000..cb96235
--- /dev/null
+++ b/tools/aapt2/filter/AbiFilter.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2017 The Android Open Source 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 "AbiFilter.h"
+
+#include <memory>
+
+#include "io/Util.h"
+
+namespace aapt {
+
+std::unique_ptr<AbiFilter> AbiFilter::FromAbiList(const std::vector<configuration::Abi>& abi_list) {
+  std::unordered_set<std::string> abi_set;
+  for (auto& abi : abi_list) {
+    abi_set.insert(configuration::AbiToString(abi));
+  }
+  // Make unique by hand as the constructor is private.
+  return std::unique_ptr<AbiFilter>(new AbiFilter(abi_set));
+}
+
+bool AbiFilter::Keep(const std::string& path) {
+  // We only care about libraries.
+  if (!util::StartsWith(path, kLibPrefix)) {
+    return true;
+  }
+
+  auto abi_end = path.find('/', kLibPrefixLen);
+  if (abi_end == std::string::npos) {
+    // Ignore any files in the top level lib directory.
+    return true;
+  }
+
+  // Strip the lib/ prefix.
+  const std::string& path_abi = path.substr(kLibPrefixLen, abi_end - kLibPrefixLen);
+  return (abis_.find(path_abi) != abis_.end());
+}
+
+}  // namespace aapt
diff --git a/tools/aapt2/filter/AbiFilter.h b/tools/aapt2/filter/AbiFilter.h
new file mode 100644
index 0000000..d875cb2
--- /dev/null
+++ b/tools/aapt2/filter/AbiFilter.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2017 The Android Open Source 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.
+ */
+
+#ifndef AAPT2_ABISPLITTER_H
+#define AAPT2_ABISPLITTER_H
+
+#include <memory>
+#include <string>
+#include <unordered_set>
+#include <vector>
+
+#include "configuration/ConfigurationParser.h"
+#include "filter/Filter.h"
+
+namespace aapt {
+
+/**
+ * Filters native library paths by ABI. ABIs present in the filter list are kept and all over
+ * libraries are removed. The filter is only applied to native library paths (this under lib/).
+ */
+class AbiFilter : public IPathFilter {
+ public:
+  /** Factory method to create a filter from a list of configuration::Abi. */
+  static std::unique_ptr<AbiFilter> FromAbiList(const std::vector<configuration::Abi>& abi_list);
+
+  /** Returns true if the path is for a native library in the list of desired ABIs. */
+  bool Keep(const std::string& path) override;
+
+ private:
+  explicit AbiFilter(std::unordered_set<std::string> abis) : abis_(std::move(abis)) {
+  }
+
+  /** The path prefix to where all native libs end up inside an APK file. */
+  static constexpr const char* kLibPrefix = "lib/";
+  static constexpr size_t kLibPrefixLen = 4;
+  const std::unordered_set<std::string> abis_;
+};
+
+}  // namespace aapt
+
+#endif  // AAPT2_ABISPLITTER_H
diff --git a/tools/aapt2/filter/AbiFilter_test.cpp b/tools/aapt2/filter/AbiFilter_test.cpp
new file mode 100644
index 0000000..0c8ea35
--- /dev/null
+++ b/tools/aapt2/filter/AbiFilter_test.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2017 The Android Open Source 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 "filter/AbiFilter.h"
+
+#include <string>
+
+#include "gtest/gtest.h"
+
+namespace aapt {
+namespace {
+
+using ::aapt::configuration::Abi;
+
+struct TestData {
+  std::string path;
+  bool kept;
+};
+
+const TestData kTestData[] = {
+    /* Keep. */
+    {"lib/mips/libnative.so", true},
+    {"not/native/file.txt", true},
+    // Not sure if this is a valid use case.
+    {"lib/listing.txt", true},
+    {"lib/mips/foo/bar/baz.so", true},
+    {"lib/mips/x86/foo.so", true},
+    /* Discard. */
+    {"lib/mips_horse/foo.so", false},
+    {"lib/horse_mips/foo.so", false},
+    {"lib/mips64/armeabi-v7a/foo.so", false},
+    {"lib/mips64/x86_64/x86.so", false},
+    {"lib/x86/libnative.so", false},
+    {"lib/x86/foo/bar/baz.so", false},
+    {"lib/x86/x86/foo.so", false},
+    {"lib/x86_horse/foo.so", false},
+    {"lib/horse_x86/foo.so", false},
+    {"lib/x86/armeabi-v7a/foo.so", false},
+    {"lib/x86_64/x86_64/x86.so", false},
+};
+
+class AbiFilterTest : public ::testing::TestWithParam<TestData> {};
+
+TEST_P(AbiFilterTest, Keep) {
+  auto mips = AbiFilter::FromAbiList({Abi::kMips});
+  const TestData& data = GetParam();
+  EXPECT_EQ(mips->Keep(data.path), data.kept);
+}
+
+INSTANTIATE_TEST_CASE_P(NativePaths, AbiFilterTest, ::testing::ValuesIn(kTestData));
+
+}  // namespace
+}  // namespace aapt
diff --git a/tools/aapt2/filter/Filter.h b/tools/aapt2/filter/Filter.h
new file mode 100644
index 0000000..d737dc9
--- /dev/null
+++ b/tools/aapt2/filter/Filter.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2017 The Android Open Source 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.
+ */
+
+#ifndef AAPT2_FILTER_H
+#define AAPT2_FILTER_H
+
+#include <string>
+#include <vector>
+
+#include "util/Util.h"
+
+namespace aapt {
+
+/** A filter to be applied to a path segment. */
+class IPathFilter {
+ public:
+  ~IPathFilter() = default;
+
+  /** Returns true if the path should be kept. */
+  virtual bool Keep(const std::string& path) = 0;
+};
+
+/**
+ * Path filter that keeps anything that matches the provided prefix.
+ */
+class PrefixFilter : public IPathFilter {
+ public:
+  explicit PrefixFilter(std::string prefix) : prefix_(std::move(prefix)) {
+  }
+
+  /** Returns true if the provided path matches the prefix. */
+  bool Keep(const std::string& path) override {
+    return util::StartsWith(path, prefix_);
+  }
+
+ private:
+  const std::string prefix_;
+};
+
+/** Applies a set of IPathFilters to a path and returns true iif all filters keep the path. */
+class FilterChain : public IPathFilter {
+ public:
+  /** Adds a filter to the list to be applied to each path. */
+  void AddFilter(std::unique_ptr<IPathFilter> filter) {
+    filters_.push_back(std::move(filter));
+  }
+
+  /** Returns true if all filters keep the path. */
+  bool Keep(const std::string& path) override {
+    for (auto& filter : filters_) {
+      if (!filter->Keep(path)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+ private:
+  std::vector<std::unique_ptr<IPathFilter>> filters_;
+};
+
+}  // namespace aapt
+
+#endif  // AAPT2_FILTER_H
diff --git a/tools/aapt2/filter/Filter_test.cpp b/tools/aapt2/filter/Filter_test.cpp
new file mode 100644
index 0000000..fb75a4b
--- /dev/null
+++ b/tools/aapt2/filter/Filter_test.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2017 The Android Open Source 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 "filter/Filter.h"
+
+#include <string>
+
+#include "io/Util.h"
+
+#include "gtest/gtest.h"
+
+namespace aapt {
+namespace {
+
+TEST(FilterChainTest, EmptyChain) {
+  FilterChain chain;
+  ASSERT_TRUE(chain.Keep("some/random/path"));
+}
+
+TEST(FilterChainTest, SingleFilter) {
+  FilterChain chain;
+  chain.AddFilter(util::make_unique<PrefixFilter>("keep/"));
+
+  ASSERT_FALSE(chain.Keep("removed/path"));
+  ASSERT_TRUE(chain.Keep("keep/path/1"));
+  ASSERT_TRUE(chain.Keep("keep/path/2"));
+}
+
+TEST(FilterChainTest, MultipleFilters) {
+  FilterChain chain;
+  chain.AddFilter(util::make_unique<PrefixFilter>("keep/"));
+  chain.AddFilter(util::make_unique<PrefixFilter>("keep/really/"));
+
+  ASSERT_FALSE(chain.Keep("removed/path"));
+  ASSERT_FALSE(chain.Keep("/keep/really/wrong/prefix"));
+  ASSERT_FALSE(chain.Keep("keep/maybe/1"));
+  ASSERT_TRUE(chain.Keep("keep/really/1"));
+}
+
+}  // namespace
+}  // namespace aapt
diff --git a/tools/aapt2/java/ManifestClassGenerator_test.cpp b/tools/aapt2/java/ManifestClassGenerator_test.cpp
index 5ebf508..9f6ec21 100644
--- a/tools/aapt2/java/ManifestClassGenerator_test.cpp
+++ b/tools/aapt2/java/ManifestClassGenerator_test.cpp
@@ -18,10 +18,101 @@
 
 #include "test/Test.h"
 
+using ::testing::HasSubstr;
+using ::testing::Not;
+
 namespace aapt {
 
-static ::testing::AssertionResult GetManifestClassText(IAaptContext* context,
-                                                       xml::XmlResource* res,
+static ::testing::AssertionResult GetManifestClassText(IAaptContext* context, xml::XmlResource* res,
+                                                       std::string* out_str);
+
+TEST(ManifestClassGeneratorTest, NameIsProperlyGeneratedFromSymbol) {
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+  std::unique_ptr<xml::XmlResource> manifest = test::BuildXmlDom(R"(
+      <manifest xmlns:android="http://schemas.android.com/apk/res/android">
+        <permission android:name="android.permission.ACCESS_INTERNET" />
+        <permission android:name="android.DO_DANGEROUS_THINGS" />
+        <permission android:name="com.test.sample.permission.HUH" />
+        <permission-group android:name="foo.bar.PERMISSION" />
+      </manifest>)");
+
+  std::string actual;
+  ASSERT_TRUE(GetManifestClassText(context.get(), manifest.get(), &actual));
+
+  ASSERT_THAT(actual, HasSubstr("public static final class permission {"));
+  ASSERT_THAT(actual, HasSubstr("public static final class permission_group {"));
+
+  const size_t permission_start_pos = actual.find("public static final class permission {");
+  const size_t permission_group_start_pos =
+      actual.find("public static final class permission_group {");
+
+  //
+  // Make sure these permissions are in the permission class.
+  //
+  const std::string permission_class =
+      actual.substr(permission_start_pos, permission_group_start_pos - permission_start_pos);
+
+  EXPECT_THAT(
+      permission_class,
+      HasSubstr(
+          "public static final String ACCESS_INTERNET=\"android.permission.ACCESS_INTERNET\";"));
+  EXPECT_THAT(
+      permission_class,
+      HasSubstr("public static final String DO_DANGEROUS_THINGS=\"android.DO_DANGEROUS_THINGS\";"));
+  EXPECT_THAT(permission_class,
+              HasSubstr("public static final String HUH=\"com.test.sample.permission.HUH\";"));
+
+  //
+  // Make sure these permissions are in the permission_group class
+  //
+  const std::string permission_group_class = actual.substr(permission_group_start_pos);
+
+  EXPECT_THAT(permission_group_class,
+              HasSubstr("public static final String PERMISSION=\"foo.bar.PERMISSION\";"));
+}
+
+TEST(ManifestClassGeneratorTest, CommentsAndAnnotationsArePresent) {
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+  std::unique_ptr<xml::XmlResource> manifest = test::BuildXmlDom(R"(
+      <manifest xmlns:android="http://schemas.android.com/apk/res/android">
+        <!-- Required to access the internet.
+             Added in API 1. -->
+        <permission android:name="android.permission.ACCESS_INTERNET" />
+        <!-- @deprecated This permission is for playing outside. -->
+        <permission android:name="android.permission.PLAY_OUTSIDE" />
+        <!-- This is a private permission for system only!
+             @hide
+             @SystemApi -->
+        <permission android:name="android.permission.SECRET" />
+      </manifest>)");
+
+  std::string actual;
+  ASSERT_TRUE(GetManifestClassText(context.get(), manifest.get(), &actual));
+
+  const char* expected_access_internet = R"(    /**
+     * Required to access the internet.
+     * Added in API 1.
+     */
+    public static final String ACCESS_INTERNET="android.permission.ACCESS_INTERNET";)";
+  EXPECT_THAT(actual, HasSubstr(expected_access_internet));
+
+  const char* expected_play_outside = R"(    /**
+     * @deprecated This permission is for playing outside.
+     */
+    @Deprecated
+    public static final String PLAY_OUTSIDE="android.permission.PLAY_OUTSIDE";)";
+  EXPECT_THAT(actual, HasSubstr(expected_play_outside));
+
+  const char* expected_secret = R"(    /**
+     * This is a private permission for system only!
+     * @hide
+     */
+    @android.annotation.SystemApi
+    public static final String SECRET="android.permission.SECRET";)";
+  EXPECT_THAT(actual, HasSubstr(expected_secret));
+}
+
+static ::testing::AssertionResult GetManifestClassText(IAaptContext* context, xml::XmlResource* res,
                                                        std::string* out_str) {
   std::unique_ptr<ClassDefinition> manifest_class =
       GenerateManifestClass(context->GetDiagnostics(), res);
@@ -30,8 +121,7 @@
   }
 
   std::stringstream out;
-  if (!manifest_class->WriteJavaFile(manifest_class.get(), "android", true,
-                                     &out)) {
+  if (!manifest_class->WriteJavaFile(manifest_class.get(), "android", true, &out)) {
     return ::testing::AssertionFailure() << "failed to write java file";
   }
 
@@ -39,103 +129,4 @@
   return ::testing::AssertionSuccess();
 }
 
-TEST(ManifestClassGeneratorTest, NameIsProperlyGeneratedFromSymbol) {
-  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
-  std::unique_ptr<xml::XmlResource> manifest = test::BuildXmlDom(R"EOF(
-        <manifest xmlns:android="http://schemas.android.com/apk/res/android">
-          <permission android:name="android.permission.ACCESS_INTERNET" />
-          <permission android:name="android.DO_DANGEROUS_THINGS" />
-          <permission android:name="com.test.sample.permission.HUH" />
-          <permission-group android:name="foo.bar.PERMISSION" />
-        </manifest>)EOF");
-
-  std::string actual;
-  ASSERT_TRUE(GetManifestClassText(context.get(), manifest.get(), &actual));
-
-  const size_t permission_class_pos =
-      actual.find("public static final class permission {");
-  const size_t permission_croup_class_pos =
-      actual.find("public static final class permission_group {");
-  ASSERT_NE(std::string::npos, permission_class_pos);
-  ASSERT_NE(std::string::npos, permission_croup_class_pos);
-
-  //
-  // Make sure these permissions are in the permission class.
-  //
-
-  size_t pos = actual.find(
-      "public static final String ACCESS_INTERNET="
-      "\"android.permission.ACCESS_INTERNET\";");
-  EXPECT_GT(pos, permission_class_pos);
-  EXPECT_LT(pos, permission_croup_class_pos);
-
-  pos = actual.find(
-      "public static final String DO_DANGEROUS_THINGS="
-      "\"android.DO_DANGEROUS_THINGS\";");
-  EXPECT_GT(pos, permission_class_pos);
-  EXPECT_LT(pos, permission_croup_class_pos);
-
-  pos = actual.find(
-      "public static final String HUH=\"com.test.sample.permission.HUH\";");
-  EXPECT_GT(pos, permission_class_pos);
-  EXPECT_LT(pos, permission_croup_class_pos);
-
-  //
-  // Make sure these permissions are in the permission_group class
-  //
-
-  pos = actual.find(
-      "public static final String PERMISSION="
-      "\"foo.bar.PERMISSION\";");
-  EXPECT_GT(pos, permission_croup_class_pos);
-  EXPECT_LT(pos, std::string::npos);
-}
-
-TEST(ManifestClassGeneratorTest, CommentsAndAnnotationsArePresent) {
-  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
-  std::unique_ptr<xml::XmlResource> manifest = test::BuildXmlDom(R"EOF(
-        <manifest xmlns:android="http://schemas.android.com/apk/res/android">
-          <!-- Required to access the internet.
-               Added in API 1. -->
-          <permission android:name="android.permission.ACCESS_INTERNET" />
-          <!-- @deprecated This permission is for playing outside. -->
-          <permission android:name="android.permission.PLAY_OUTSIDE" />
-          <!-- This is a private permission for system only!
-               @hide
-               @SystemApi -->
-          <permission android:name="android.permission.SECRET" />
-        </manifest>)EOF");
-
-  std::string actual;
-  ASSERT_TRUE(GetManifestClassText(context.get(), manifest.get(), &actual));
-
-  const char* expected_access_internet =
-      R"EOF(    /**
-     * Required to access the internet.
-     * Added in API 1.
-     */
-    public static final String ACCESS_INTERNET="android.permission.ACCESS_INTERNET";)EOF";
-
-  EXPECT_NE(std::string::npos, actual.find(expected_access_internet));
-
-  const char* expected_play_outside =
-      R"EOF(    /**
-     * @deprecated This permission is for playing outside.
-     */
-    @Deprecated
-    public static final String PLAY_OUTSIDE="android.permission.PLAY_OUTSIDE";)EOF";
-
-  EXPECT_NE(std::string::npos, actual.find(expected_play_outside));
-
-  const char* expected_secret =
-      R"EOF(    /**
-     * This is a private permission for system only!
-     * @hide
-     */
-    @android.annotation.SystemApi
-    public static final String SECRET="android.permission.SECRET";)EOF";
-
-  EXPECT_NE(std::string::npos, actual.find(expected_secret));
-}
-
 }  // namespace aapt
diff --git a/tools/aapt2/java/ProguardRules.cpp b/tools/aapt2/java/ProguardRules.cpp
index 624a559..5f61fae 100644
--- a/tools/aapt2/java/ProguardRules.cpp
+++ b/tools/aapt2/java/ProguardRules.cpp
@@ -85,7 +85,11 @@
     bool check_class = false;
     bool check_name = false;
     if (node->namespace_uri.empty()) {
-      check_class = node->name == "view" || node->name == "fragment";
+      if (node->name == "view") {
+        check_class = true;
+      } else if (node->name == "fragment") {
+        check_class = check_name = true;
+      }
     } else if (node->namespace_uri == xml::kSchemaAndroid) {
       check_name = node->name == "fragment";
     }
@@ -110,6 +114,32 @@
   DISALLOW_COPY_AND_ASSIGN(LayoutVisitor);
 };
 
+class MenuVisitor : public BaseVisitor {
+ public:
+  MenuVisitor(const Source& source, KeepSet* keep_set) : BaseVisitor(source, keep_set) {
+  }
+
+  virtual void Visit(xml::Element* node) override {
+    if (node->namespace_uri.empty() && node->name == "item") {
+      for (const auto& attr : node->attributes) {
+        if (attr.namespace_uri == xml::kSchemaAndroid) {
+          if ((attr.name == "actionViewClass" || attr.name == "actionProviderClass") &&
+              util::IsJavaClassName(attr.value)) {
+            AddClass(node->line_number, attr.value);
+          } else if (attr.name == "onClick") {
+            AddMethod(node->line_number, attr.value);
+          }
+        }
+      }
+    }
+
+    BaseVisitor::Visit(node);
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MenuVisitor);
+};
+
 class XmlResourceVisitor : public BaseVisitor {
  public:
   XmlResourceVisitor(const Source& source, KeepSet* keep_set)
@@ -267,6 +297,12 @@
       break;
     }
 
+    case ResourceType::kMenu: {
+      MenuVisitor visitor(source, keep_set);
+      res->root->Accept(&visitor);
+      break;
+    }
+
     default:
       break;
   }
diff --git a/tools/aapt2/java/ProguardRules_test.cpp b/tools/aapt2/java/ProguardRules_test.cpp
new file mode 100644
index 0000000..900b073
--- /dev/null
+++ b/tools/aapt2/java/ProguardRules_test.cpp
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2017 The Android Open Source 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 "java/ProguardRules.h"
+
+#include "test/Test.h"
+
+using ::testing::HasSubstr;
+using ::testing::Not;
+
+namespace aapt {
+
+TEST(ProguardRulesTest, FragmentNameRuleIsEmitted) {
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+  std::unique_ptr<xml::XmlResource> layout = test::BuildXmlDom(R"(
+      <fragment xmlns:android="http://schemas.android.com/apk/res/android"
+          android:name="com.foo.Bar"/>)");
+  layout->file.name = test::ParseNameOrDie("layout/foo");
+
+  proguard::KeepSet set;
+  ASSERT_TRUE(proguard::CollectProguardRules({}, layout.get(), &set));
+
+  std::stringstream out;
+  ASSERT_TRUE(proguard::WriteKeepSet(&out, set));
+
+  std::string actual = out.str();
+  EXPECT_THAT(actual, HasSubstr("com.foo.Bar"));
+}
+
+TEST(ProguardRulesTest, FragmentClassRuleIsEmitted) {
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+  std::unique_ptr<xml::XmlResource> layout =
+      test::BuildXmlDom(R"(<fragment class="com.foo.Bar"/>)");
+  layout->file.name = test::ParseNameOrDie("layout/foo");
+
+  proguard::KeepSet set;
+  ASSERT_TRUE(proguard::CollectProguardRules({}, layout.get(), &set));
+
+  std::stringstream out;
+  ASSERT_TRUE(proguard::WriteKeepSet(&out, set));
+
+  std::string actual = out.str();
+  EXPECT_THAT(actual, HasSubstr("com.foo.Bar"));
+}
+
+TEST(ProguardRulesTest, FragmentNameAndClassRulesAreEmitted) {
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+  std::unique_ptr<xml::XmlResource> layout = test::BuildXmlDom(R"(
+      <fragment xmlns:android="http://schemas.android.com/apk/res/android"
+          android:name="com.foo.Baz"
+          class="com.foo.Bar"/>)");
+  layout->file.name = test::ParseNameOrDie("layout/foo");
+
+  proguard::KeepSet set;
+  ASSERT_TRUE(proguard::CollectProguardRules({}, layout.get(), &set));
+
+  std::stringstream out;
+  ASSERT_TRUE(proguard::WriteKeepSet(&out, set));
+
+  std::string actual = out.str();
+  EXPECT_THAT(actual, HasSubstr("com.foo.Bar"));
+  EXPECT_THAT(actual, HasSubstr("com.foo.Baz"));
+}
+
+TEST(ProguardRulesTest, ViewOnClickRuleIsEmitted) {
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+  std::unique_ptr<xml::XmlResource> layout = test::BuildXmlDom(R"(
+      <View xmlns:android="http://schemas.android.com/apk/res/android"
+          android:onClick="bar_method" />)");
+  layout->file.name = test::ParseNameOrDie("layout/foo");
+
+  proguard::KeepSet set;
+  ASSERT_TRUE(proguard::CollectProguardRules({}, layout.get(), &set));
+
+  std::stringstream out;
+  ASSERT_TRUE(proguard::WriteKeepSet(&out, set));
+
+  std::string actual = out.str();
+  EXPECT_THAT(actual, HasSubstr("bar_method"));
+}
+
+TEST(ProguardRulesTest, MenuRulesAreEmitted) {
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+  std::unique_ptr<xml::XmlResource> menu = test::BuildXmlDom(R"(
+      <menu xmlns:android="http://schemas.android.com/apk/res/android">
+        <item android:onClick="on_click"
+            android:actionViewClass="com.foo.Bar"
+            android:actionProviderClass="com.foo.Baz"
+            android:name="com.foo.Bat" />
+      </menu>)");
+  menu->file.name = test::ParseNameOrDie("menu/foo");
+
+  proguard::KeepSet set;
+  ASSERT_TRUE(proguard::CollectProguardRules({}, menu.get(), &set));
+
+  std::stringstream out;
+  ASSERT_TRUE(proguard::WriteKeepSet(&out, set));
+
+  std::string actual = out.str();
+  EXPECT_THAT(actual, HasSubstr("on_click"));
+  EXPECT_THAT(actual, HasSubstr("com.foo.Bar"));
+  EXPECT_THAT(actual, HasSubstr("com.foo.Baz"));
+  EXPECT_THAT(actual, Not(HasSubstr("com.foo.Bat")));
+}
+
+}  // namespace aapt
diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp
index 99fd95b..a0ffefa 100644
--- a/tools/aapt2/link/ManifestFixer.cpp
+++ b/tools/aapt2/link/ManifestFixer.cpp
@@ -309,6 +309,9 @@
   manifest_action["meta-data"] = meta_data_action;
   manifest_action["uses-split"].Action(RequiredNameIsJavaPackage);
 
+  manifest_action["key-sets"]["key-set"]["public-key"];
+  manifest_action["key-sets"]["upgrade-key-set"];
+
   // Application actions.
   xml::XmlNodeAction& application_action = manifest_action["application"];
   application_action.Action(OptionalNameIsJavaClassName);
diff --git a/tools/aapt2/link/ManifestFixer_test.cpp b/tools/aapt2/link/ManifestFixer_test.cpp
index 064d365..80edb35 100644
--- a/tools/aapt2/link/ManifestFixer_test.cpp
+++ b/tools/aapt2/link/ManifestFixer_test.cpp
@@ -18,7 +18,8 @@
 
 #include "test/Test.h"
 
-using android::StringPiece;
+using ::android::StringPiece;
+using ::testing::NotNull;
 
 namespace aapt {
 
@@ -420,4 +421,22 @@
   EXPECT_EQ(nullptr, Verify(input));
 }
 
+TEST_F(ManifestFixerTest, SupportKeySets) {
+  std::string input = R"(
+      <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="android">
+        <key-sets>
+          <key-set android:name="old-set">
+            <public-key android:name="old-key" android:value="some+old+key" />
+          </key-set>
+          <key-set android:name="new-set">
+            <public-key android:name="new-key" android:value="some+new+key" />
+          </key-set>
+          <upgrade-key-set android:name="old-set" />
+          <upgrade-key-set android:name="new-set" />
+        </key-sets>
+      </manifest>)";
+  EXPECT_THAT(Verify(input), NotNull());
+}
+
 }  // namespace aapt
diff --git a/tools/aapt2/readme.md b/tools/aapt2/readme.md
index 62945b1..ebcd469 100644
--- a/tools/aapt2/readme.md
+++ b/tools/aapt2/readme.md
@@ -3,6 +3,12 @@
 ## Version 2.18
 ### `aapt2 ...`
 - Fixed issue where enum values were interpreted as integers and range checked. (bug 62358540)
+- Fixed issue where ints and floats with trailing whitespace would not be parsed. (bug 62902869)
+- Fixed issue where `--custom-package` was not honored when writing Manifest.java. (bug 62826426)
+- Add `<key-sets>` and its nested tags to the allowed set of XML tags in AndroidManifest.xml.
+  (bug 62839863)
+- Fixed issue where Java classes referenced from fragments and menus were not added to
+  the set of Proguard keep rules. (bug 62216174)
 
 ## Version 2.17
 ### `aapt2 ...`
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 91fc2f7..e7fbe4f 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -891,9 +891,13 @@
          */
         public static final int DISABLED_DUE_TO_USER_SWITCH = 11;
         /**
+         * This network is disabled due to wrong password
+         */
+        public static final int DISABLED_BY_WRONG_PASSWORD = 12;
+        /**
          * This Maximum disable reason value
          */
-        public static final int NETWORK_SELECTION_DISABLED_MAX = 12;
+        public static final int NETWORK_SELECTION_DISABLED_MAX = 13;
 
         /**
          * Quality network selection disable reason String (for debug purpose)
@@ -910,7 +914,8 @@
                 "NETWORK_SELECTION_DISABLED_AUTHENTICATION_NO_CREDENTIALS",
                 "NETWORK_SELECTION_DISABLED_NO_INTERNET",
                 "NETWORK_SELECTION_DISABLED_BY_WIFI_MANAGER",
-                "NETWORK_SELECTION_DISABLED_BY_USER_SWITCH"
+                "NETWORK_SELECTION_DISABLED_BY_USER_SWITCH",
+                "NETWORK_SELECTION_DISABLED_BY_WRONG_PASSWORD"
         };
 
         /**
diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
index 18f30f8..bb3af3c 100644
--- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
+++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
@@ -156,9 +156,20 @@
 
     }
 
-    /** Copy constructor */
-    public WifiEnterpriseConfig(WifiEnterpriseConfig source) {
+    /**
+     * Copy over the contents of the source WifiEnterpriseConfig object over to this object.
+     *
+     * @param source Source WifiEnterpriseConfig object.
+     * @param ignoreMaskedPassword Set to true to ignore masked password field, false otherwise.
+     * @param mask if |ignoreMaskedPassword| is set, check if the incoming password field is set
+     *             to this value.
+     */
+    private void copyFrom(WifiEnterpriseConfig source, boolean ignoreMaskedPassword, String mask) {
         for (String key : source.mFields.keySet()) {
+            if (ignoreMaskedPassword && key.equals(PASSWORD_KEY)
+                    && TextUtils.equals(source.mFields.get(key), mask)) {
+                continue;
+            }
             mFields.put(key, source.mFields.get(key));
         }
         if (source.mCaCerts != null) {
@@ -178,6 +189,29 @@
         mPhase2Method = source.mPhase2Method;
     }
 
+    /**
+     * Copy constructor.
+     * This copies over all the fields verbatim (does not ignore masked password fields).
+     *
+     * @param source Source WifiEnterpriseConfig object.
+     */
+    public WifiEnterpriseConfig(WifiEnterpriseConfig source) {
+        copyFrom(source, false, "");
+    }
+
+    /**
+     * Copy fields from the provided external WifiEnterpriseConfig.
+     * This is needed to handle the WifiEnterpriseConfig objects which were sent by apps with the
+     * password field masked.
+     *
+     * @param externalConfig External WifiEnterpriseConfig object.
+     * @param mask String mask to compare against.
+     * @hide
+     */
+    public void copyFromExternal(WifiEnterpriseConfig externalConfig, String mask) {
+        copyFrom(externalConfig, true, convertToQuotedString(mask));
+    }
+
     @Override
     public int describeContents() {
         return 0;
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
index f596eef..0d4359e 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
@@ -291,7 +291,6 @@
             "android.net.wifi.p2p.CALLING_PACKAGE";
 
     IWifiP2pManager mService;
-    private final Map<Channel, Binder> mBinders = new HashMap<>();
 
     private static final int BASE = Protocol.BASE_WIFI_P2P_MANAGER;
 
@@ -670,11 +669,12 @@
      * by doing a call on {@link #initialize}
      */
     public static class Channel {
-        Channel(Context context, Looper looper, ChannelListener l) {
+        Channel(Context context, Looper looper, ChannelListener l, Binder binder) {
             mAsyncChannel = new AsyncChannel();
             mHandler = new P2pHandler(looper);
             mChannelListener = l;
             mContext = context;
+            mBinder = binder;
         }
         private final static int INVALID_LISTENER_KEY = 0;
         private ChannelListener mChannelListener;
@@ -686,6 +686,8 @@
         private final Object mListenerMapLock = new Object();
         private int mListenerKey = 0;
 
+        /* package */ final Binder mBinder;
+
         private AsyncChannel mAsyncChannel;
         private P2pHandler mHandler;
         Context mContext;
@@ -892,8 +894,8 @@
      */
     public Channel initialize(Context srcContext, Looper srcLooper, ChannelListener listener) {
         Binder binder = new Binder();
-        Channel channel = initalizeChannel(srcContext, srcLooper, listener, getMessenger(binder));
-        mBinders.put(channel, binder);
+        Channel channel = initalizeChannel(srcContext, srcLooper, listener, getMessenger(binder),
+                binder);
         return channel;
     }
 
@@ -903,14 +905,15 @@
      */
     public Channel initializeInternal(Context srcContext, Looper srcLooper,
                                       ChannelListener listener) {
-        return initalizeChannel(srcContext, srcLooper, listener, getP2pStateMachineMessenger());
+        return initalizeChannel(srcContext, srcLooper, listener, getP2pStateMachineMessenger(),
+                null);
     }
 
     private Channel initalizeChannel(Context srcContext, Looper srcLooper, ChannelListener listener,
-                                     Messenger messenger) {
+                                     Messenger messenger, Binder binder) {
         if (messenger == null) return null;
 
-        Channel c = new Channel(srcContext, srcLooper, listener);
+        Channel c = new Channel(srcContext, srcLooper, listener, binder);
         if (c.mAsyncChannel.connectSync(srcContext, c.mHandler, messenger)
                 == AsyncChannel.STATUS_SUCCESSFUL) {
             return c;
@@ -1428,8 +1431,9 @@
      */
     public void close(Channel c) {
         try {
-            mService.close(mBinders.get(c));
-            mBinders.remove(c);
+            if (c != null) {
+                mService.close(c.mBinder);
+            }
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java b/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java
index d0aedba..1a7dd13 100644
--- a/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java
@@ -20,6 +20,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
@@ -316,15 +317,37 @@
         assertEquals("\"auth=AKA'\"", getSupplicantPhase2Method());
     }
 
-    /** Verfies that the copy constructor preseves the inner method information. */
+    /**
+     * Verifies that the copy constructor preseves both the masked password and inner method
+     * information.
+     */
     @Test
     public void copyConstructor() {
         WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
+        enterpriseConfig.setPassword("*");
         enterpriseConfig.setEapMethod(Eap.TTLS);
         enterpriseConfig.setPhase2Method(Phase2.GTC);
         mEnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig);
         assertEquals("TTLS", getSupplicantEapMethod());
         assertEquals("\"autheap=GTC\"", getSupplicantPhase2Method());
+        assertEquals("*", mEnterpriseConfig.getPassword());
+    }
+
+    /**
+     * Verifies that the copy from external ignores masked passwords and preserves the
+     * inner method information.
+     */
+    @Test
+    public void copyFromExternal() {
+        WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
+        enterpriseConfig.setPassword("*");
+        enterpriseConfig.setEapMethod(Eap.TTLS);
+        enterpriseConfig.setPhase2Method(Phase2.GTC);
+        mEnterpriseConfig = new WifiEnterpriseConfig();
+        mEnterpriseConfig.copyFromExternal(enterpriseConfig, "*");
+        assertEquals("TTLS", getSupplicantEapMethod());
+        assertEquals("\"autheap=GTC\"", getSupplicantPhase2Method());
+        assertNotEquals("*", mEnterpriseConfig.getPassword());
     }
 
     /** Verfies that parceling a WifiEnterpriseConfig preseves method information. */