Merge "Introduce new window insets launch flag"
diff --git a/Android.bp b/Android.bp
index ccf02ae..286be82 100644
--- a/Android.bp
+++ b/Android.bp
@@ -902,6 +902,8 @@
         "core/java/android/net/dhcp/DhcpServingParamsParcel.aidl",
         "core/java/android/net/dhcp/IDhcpServer.aidl",
         "core/java/android/net/dhcp/IDhcpServerCallbacks.aidl",
+        "core/java/android/net/ip/IIpClient.aidl",
+        "core/java/android/net/ip/IIpClientCallbacks.aidl",
         "core/java/android/net/ipmemorystore/**/*.aidl",
     ],
     api_dir: "aidl/networkstack",
diff --git a/api/current.txt b/api/current.txt
index 5eb2474..96508c7 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -24533,6 +24533,7 @@
     ctor public MediaController2(@NonNull android.content.Context, @NonNull android.media.Session2Token, @NonNull java.util.concurrent.Executor, @NonNull android.media.MediaController2.ControllerCallback);
     method public void cancelSessionCommand(@NonNull Object);
     method public void close();
+    method public android.media.Session2Token getConnectedSessionToken();
     method public boolean isPlaybackActive();
     method @NonNull public Object sendSessionCommand(@NonNull android.media.Session2Command, @Nullable android.os.Bundle);
   }
@@ -27286,21 +27287,6 @@
 
 package android.media.session {
 
-  public final class ControllerCallbackLink implements android.os.Parcelable {
-    method public int describeContents();
-    method @NonNull public android.os.IBinder getBinder();
-    method public void notifyEvent(@NonNull String, @Nullable android.os.Bundle);
-    method public void notifyExtrasChanged(@Nullable android.os.Bundle);
-    method public void notifyMetadataChanged(@Nullable android.media.MediaMetadata);
-    method public void notifyPlaybackStateChanged(@Nullable android.media.session.PlaybackState);
-    method public void notifyQueueChanged(@Nullable java.util.List<android.media.session.MediaSession.QueueItem>);
-    method public void notifyQueueTitleChanged(@Nullable CharSequence);
-    method public void notifySessionDestroyed();
-    method public void notifyVolumeInfoChanged(@NonNull android.media.session.MediaController.PlaybackInfo);
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.media.session.ControllerCallbackLink> CREATOR;
-  }
-
   public final class MediaController {
     ctor public MediaController(@NonNull android.content.Context, @NonNull android.media.session.MediaSession.Token);
     method public void adjustVolume(int, int);
@@ -27535,36 +27521,6 @@
     method public android.media.session.PlaybackState.CustomAction.Builder setExtras(android.os.Bundle);
   }
 
-  public final class SessionCallbackLink implements android.os.Parcelable {
-    method public int describeContents();
-    method @NonNull public android.os.IBinder getBinder();
-    method public void notifyAdjustVolume(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink, int);
-    method public void notifyCommand(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink, @NonNull String, @Nullable android.os.Bundle, @Nullable android.os.ResultReceiver);
-    method public void notifyCustomAction(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink, @NonNull String, @Nullable android.os.Bundle);
-    method public void notifyFastForward(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink);
-    method public void notifyMediaButton(@NonNull String, int, int, @NonNull android.content.Intent, int, @Nullable android.os.ResultReceiver);
-    method public void notifyMediaButtonFromController(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink, @NonNull android.content.Intent);
-    method public void notifyNext(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink);
-    method public void notifyPause(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink);
-    method public void notifyPlay(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink);
-    method public void notifyPlayFromMediaId(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink, @NonNull String, @Nullable android.os.Bundle);
-    method public void notifyPlayFromSearch(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink, @NonNull String, @Nullable android.os.Bundle);
-    method public void notifyPlayFromUri(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink, @NonNull android.net.Uri, @Nullable android.os.Bundle);
-    method public void notifyPrepare(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink);
-    method public void notifyPrepareFromMediaId(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink, @NonNull String, @Nullable android.os.Bundle);
-    method public void notifyPrepareFromSearch(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink, @NonNull String, @Nullable android.os.Bundle);
-    method public void notifyPrepareFromUri(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink, @NonNull android.net.Uri, @Nullable android.os.Bundle);
-    method public void notifyPrevious(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink);
-    method public void notifyRate(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink, @NonNull android.media.Rating);
-    method public void notifyRewind(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink);
-    method public void notifySeekTo(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink, long);
-    method public void notifySetVolumeTo(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink, int);
-    method public void notifySkipToTrack(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink, long);
-    method public void notifyStop(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink);
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.media.session.SessionCallbackLink> CREATOR;
-  }
-
 }
 
 package android.media.tv {
@@ -28940,6 +28896,7 @@
     method public android.net.IpPrefix getDestination();
     method public java.net.InetAddress getGateway();
     method public String getInterface();
+    method public boolean hasGateway();
     method public boolean isDefaultRoute();
     method public boolean matches(java.net.InetAddress);
     method public void writeToParcel(android.os.Parcel, int);
diff --git a/api/system-current.txt b/api/system-current.txt
index ce0ef38..74ca75c 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -3448,7 +3448,20 @@
 package android.media.session {
 
   public final class ControllerCallbackLink implements android.os.Parcelable {
-    ctor public ControllerCallbackLink(@NonNull android.media.session.ControllerCallbackLink.CallbackStub);
+    ctor public ControllerCallbackLink(@NonNull android.content.Context, @NonNull android.media.session.ControllerCallbackLink.CallbackStub);
+    ctor public ControllerCallbackLink(android.os.IBinder);
+    method public int describeContents();
+    method @NonNull public android.os.IBinder getBinder();
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void notifyEvent(@NonNull String, @Nullable android.os.Bundle);
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void notifyExtrasChanged(@Nullable android.os.Bundle);
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void notifyMetadataChanged(@Nullable android.media.MediaMetadata);
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void notifyPlaybackStateChanged(@Nullable android.media.session.PlaybackState);
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void notifyQueueChanged(@Nullable java.util.List<android.media.session.MediaSession.QueueItem>);
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void notifyQueueTitleChanged(@Nullable CharSequence);
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void notifySessionDestroyed();
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void notifyVolumeInfoChanged(@NonNull android.media.session.MediaController.PlaybackInfo);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.media.session.ControllerCallbackLink> CREATOR;
   }
 
   public abstract static class ControllerCallbackLink.CallbackStub {
@@ -3463,6 +3476,60 @@
     method public void onVolumeInfoChanged(@NonNull android.media.session.MediaController.PlaybackInfo);
   }
 
+  public final class ControllerLink implements android.os.Parcelable {
+    ctor public ControllerLink(@NonNull android.media.session.ControllerLink.ControllerStub);
+    ctor public ControllerLink(android.os.IBinder);
+    method public int describeContents();
+    method @NonNull public android.os.IBinder getBinder();
+    method @Nullable public android.os.Bundle getExtras();
+    method @Nullable public android.media.MediaMetadata getMetadata();
+    method @Nullable public android.media.session.PlaybackState getPlaybackState();
+    method @Nullable public java.util.List<android.media.session.MediaSession.QueueItem> getQueue();
+    method @Nullable public CharSequence getQueueTitle();
+    method public int getRatingType();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.media.session.ControllerLink> CREATOR;
+  }
+
+  public abstract static class ControllerLink.ControllerStub {
+    ctor public ControllerLink.ControllerStub();
+    method public void adjustVolume(@NonNull String, @NonNull String, @NonNull android.media.session.ControllerCallbackLink, boolean, int, int);
+    method public void fastForward(@NonNull String, @NonNull android.media.session.ControllerCallbackLink);
+    method @Nullable public android.os.Bundle getExtras();
+    method public long getFlags();
+    method @Nullable public android.app.PendingIntent getLaunchPendingIntent();
+    method @Nullable public android.media.MediaMetadata getMetadata();
+    method @NonNull public String getPackageName();
+    method @Nullable public android.media.session.PlaybackState getPlaybackState();
+    method @Nullable public java.util.List<android.media.session.MediaSession.QueueItem> getQueue();
+    method @Nullable public CharSequence getQueueTitle();
+    method public int getRatingType();
+    method @NonNull public String getTag();
+    method @NonNull public android.media.session.MediaController.PlaybackInfo getVolumeAttributes();
+    method public void next(@NonNull String, @NonNull android.media.session.ControllerCallbackLink);
+    method public void pause(@NonNull String, @NonNull android.media.session.ControllerCallbackLink);
+    method public void play(@NonNull String, @NonNull android.media.session.ControllerCallbackLink);
+    method public void playFromMediaId(@NonNull String, @NonNull android.media.session.ControllerCallbackLink, @NonNull String, @Nullable android.os.Bundle);
+    method public void playFromSearch(@NonNull String, @NonNull android.media.session.ControllerCallbackLink, @NonNull String, @Nullable android.os.Bundle);
+    method public void playFromUri(@NonNull String, @NonNull android.media.session.ControllerCallbackLink, @NonNull android.net.Uri, @Nullable android.os.Bundle);
+    method public void prepare(@NonNull String, @NonNull android.media.session.ControllerCallbackLink);
+    method public void prepareFromMediaId(@NonNull String, @NonNull android.media.session.ControllerCallbackLink, @NonNull String, @Nullable android.os.Bundle);
+    method public void prepareFromSearch(@NonNull String, @NonNull android.media.session.ControllerCallbackLink, @NonNull String, @Nullable android.os.Bundle);
+    method public void prepareFromUri(@NonNull String, @NonNull android.media.session.ControllerCallbackLink, @NonNull android.net.Uri, @Nullable android.os.Bundle);
+    method public void previous(@NonNull String, @NonNull android.media.session.ControllerCallbackLink);
+    method public void rate(@NonNull String, @NonNull android.media.session.ControllerCallbackLink, @NonNull android.media.Rating);
+    method public void registerCallback(@NonNull String, @NonNull android.media.session.ControllerCallbackLink);
+    method public void rewind(@NonNull String, @NonNull android.media.session.ControllerCallbackLink);
+    method public void seekTo(@NonNull String, @NonNull android.media.session.ControllerCallbackLink, long);
+    method public void sendCommand(@NonNull String, @NonNull android.media.session.ControllerCallbackLink, @NonNull String, @Nullable android.os.Bundle, @Nullable android.os.ResultReceiver);
+    method public void sendCustomAction(@NonNull String, @NonNull android.media.session.ControllerCallbackLink, @NonNull String, @Nullable android.os.Bundle);
+    method public boolean sendMediaButton(@NonNull String, @NonNull android.media.session.ControllerCallbackLink, boolean, @NonNull android.view.KeyEvent);
+    method public void setVolumeTo(@NonNull String, @NonNull String, @NonNull android.media.session.ControllerCallbackLink, int, int);
+    method public void skipToQueueItem(@NonNull String, @NonNull android.media.session.ControllerCallbackLink, long);
+    method public void stop(@NonNull String, @NonNull android.media.session.ControllerCallbackLink);
+    method public void unregisterCallback(@NonNull android.media.session.ControllerCallbackLink);
+  }
+
   public final class MediaSessionManager {
     method @RequiresPermission(android.Manifest.permission.SET_MEDIA_KEY_LISTENER) public void setOnMediaKeyListener(android.media.session.MediaSessionManager.OnMediaKeyListener, @Nullable android.os.Handler);
     method @RequiresPermission(android.Manifest.permission.SET_VOLUME_KEY_LONG_PRESS_LISTENER) public void setOnVolumeKeyLongPressListener(android.media.session.MediaSessionManager.OnVolumeKeyLongPressListener, @Nullable android.os.Handler);
@@ -3476,6 +3543,66 @@
     method public void onVolumeKeyLongPress(android.view.KeyEvent);
   }
 
+  public final class SessionCallbackLink implements android.os.Parcelable {
+    ctor public SessionCallbackLink(android.os.IBinder);
+    method public int describeContents();
+    method @NonNull public android.os.IBinder getBinder();
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void notifyAdjustVolume(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink, int);
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void notifyCommand(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink, @NonNull String, @Nullable android.os.Bundle, @Nullable android.os.ResultReceiver);
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void notifyCustomAction(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink, @NonNull String, @Nullable android.os.Bundle);
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void notifyFastForward(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink);
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void notifyMediaButton(@NonNull String, int, int, @NonNull android.content.Intent, int, @Nullable android.os.ResultReceiver);
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void notifyMediaButtonFromController(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink, @NonNull android.content.Intent);
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void notifyNext(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink);
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void notifyPause(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink);
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void notifyPlay(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink);
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void notifyPlayFromMediaId(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink, @NonNull String, @Nullable android.os.Bundle);
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void notifyPlayFromSearch(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink, @NonNull String, @Nullable android.os.Bundle);
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void notifyPlayFromUri(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink, @NonNull android.net.Uri, @Nullable android.os.Bundle);
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void notifyPrepare(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink);
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void notifyPrepareFromMediaId(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink, @NonNull String, @Nullable android.os.Bundle);
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void notifyPrepareFromSearch(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink, @NonNull String, @Nullable android.os.Bundle);
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void notifyPrepareFromUri(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink, @NonNull android.net.Uri, @Nullable android.os.Bundle);
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void notifyPrevious(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink);
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void notifyRate(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink, @NonNull android.media.Rating);
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void notifyRewind(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink);
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void notifySeekTo(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink, long);
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void notifySetVolumeTo(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink, int);
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void notifySkipToTrack(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink, long);
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void notifyStop(@NonNull String, int, int, @NonNull android.media.session.ControllerCallbackLink);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.media.session.SessionCallbackLink> CREATOR;
+  }
+
+  public final class SessionLink implements android.os.Parcelable {
+    ctor public SessionLink(@NonNull android.media.session.SessionLink.SessionStub);
+    ctor public SessionLink(android.os.IBinder);
+    method public int describeContents();
+    method @NonNull public android.os.IBinder getBinder();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.media.session.SessionLink> CREATOR;
+  }
+
+  public abstract static class SessionLink.SessionStub {
+    ctor public SessionLink.SessionStub();
+    method public void destroySession();
+    method @NonNull public android.media.session.ControllerLink getController();
+    method public void sendEvent(@NonNull String, @Nullable android.os.Bundle);
+    method public void setActive(boolean);
+    method public void setCurrentVolume(int);
+    method public void setExtras(@Nullable android.os.Bundle);
+    method public void setFlags(int);
+    method public void setLaunchPendingIntent(@Nullable android.app.PendingIntent);
+    method public void setMediaButtonReceiver(@Nullable android.app.PendingIntent);
+    method public void setMetadata(@Nullable android.media.MediaMetadata, long, @Nullable String);
+    method public void setPlaybackState(@Nullable android.media.session.PlaybackState);
+    method public void setPlaybackToLocal(@NonNull android.media.AudioAttributes);
+    method public void setPlaybackToRemote(int, int);
+    method public void setQueue(@Nullable java.util.List<android.media.session.MediaSession.QueueItem>);
+    method public void setQueueTitle(@Nullable CharSequence);
+    method public void setRatingType(int);
+  }
+
 }
 
 package android.media.soundtrigger {
@@ -3767,6 +3894,12 @@
 
 package android.net {
 
+  public class CaptivePortal implements android.os.Parcelable {
+    field public static final int APP_RETURN_DISMISSED = 0; // 0x0
+    field public static final int APP_RETURN_UNWANTED = 1; // 0x1
+    field public static final int APP_RETURN_WANTED_AS_IS = 2; // 0x2
+  }
+
   public class ConnectivityManager {
     method @RequiresPermission(android.Manifest.permission.LOCAL_MAC_ADDRESS) public String getCaptivePortalServerUrl();
     method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public boolean isTetheringSupported();
@@ -3774,6 +3907,8 @@
     method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback);
     method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback, android.os.Handler);
     method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void stopTethering(int);
+    field public static final String EXTRA_CAPTIVE_PORTAL_PROBE_SPEC = "android.net.extra.CAPTIVE_PORTAL_PROBE_SPEC";
+    field public static final String EXTRA_CAPTIVE_PORTAL_USER_AGENT = "android.net.extra.CAPTIVE_PORTAL_USER_AGENT";
     field public static final int TETHERING_BLUETOOTH = 2; // 0x2
     field public static final int TETHERING_USB = 1; // 0x1
     field public static final int TETHERING_WIFI = 0; // 0x0
@@ -3819,22 +3954,48 @@
   public class LinkAddress implements android.os.Parcelable {
     ctor public LinkAddress(java.net.InetAddress, int);
     ctor public LinkAddress(String);
+    method public boolean isGlobalPreferred();
+    method public boolean isIPv4();
+    method public boolean isIPv6();
+    method public boolean isSameAddressAs(android.net.LinkAddress);
   }
 
   public final class LinkProperties implements android.os.Parcelable {
     ctor public LinkProperties();
+    method public boolean addDnsServer(java.net.InetAddress);
     method public boolean addRoute(android.net.RouteInfo);
     method public void clear();
+    method public String getTcpBufferSizes();
+    method public java.util.List<java.net.InetAddress> getValidatedPrivateDnsServers();
+    method public boolean hasGlobalIPv6Address();
+    method public boolean hasIPv4Address();
+    method public boolean hasIPv6DefaultRoute();
+    method public boolean isIPv4Provisioned();
+    method public boolean isIPv6Provisioned();
+    method public boolean isProvisioned();
+    method public boolean isReachable(java.net.InetAddress);
+    method public boolean removeDnsServer(java.net.InetAddress);
+    method public boolean removeRoute(android.net.RouteInfo);
     method public void setDnsServers(java.util.Collection<java.net.InetAddress>);
     method public void setDomains(String);
     method public void setHttpProxy(android.net.ProxyInfo);
     method public void setInterfaceName(String);
     method public void setLinkAddresses(java.util.Collection<android.net.LinkAddress>);
     method public void setMtu(int);
+    method public void setPrivateDnsServerName(@Nullable String);
+    method public void setTcpBufferSizes(String);
+    method public void setUsePrivateDns(boolean);
+    method public void setValidatedPrivateDnsServers(java.util.Collection<java.net.InetAddress>);
+  }
+
+  public class Network implements android.os.Parcelable {
+    method public android.net.Network getPrivateDnsBypassingCopy();
   }
 
   public final class NetworkCapabilities implements android.os.Parcelable {
     method public int getSignalStrength();
+    method public int[] getTransportTypes();
+    method public boolean satisfiedByNetworkCapabilities(android.net.NetworkCapabilities);
     field public static final int NET_CAPABILITY_OEM_PAID = 22; // 0x16
   }
 
@@ -3874,6 +4035,13 @@
     field public static final String EXTRA_PACKAGE_NAME = "packageName";
   }
 
+  public final class RouteInfo implements android.os.Parcelable {
+    method public int getType();
+    field public static final int RTN_THROW = 9; // 0x9
+    field public static final int RTN_UNICAST = 1; // 0x1
+    field public static final int RTN_UNREACHABLE = 7; // 0x7
+  }
+
   public class RssiCurve implements android.os.Parcelable {
     ctor public RssiCurve(int, int, byte[]);
     ctor public RssiCurve(int, int, byte[], int);
@@ -3930,6 +4098,146 @@
 
 }
 
+package android.net.metrics {
+
+  public final class ApfProgramEvent implements android.net.metrics.IpConnectivityLog.Event {
+  }
+
+  public static class ApfProgramEvent.Builder {
+    ctor public ApfProgramEvent.Builder();
+    method public android.net.metrics.ApfProgramEvent build();
+    method public android.net.metrics.ApfProgramEvent.Builder setActualLifetime(long);
+    method public android.net.metrics.ApfProgramEvent.Builder setCurrentRas(int);
+    method public android.net.metrics.ApfProgramEvent.Builder setFilteredRas(int);
+    method public android.net.metrics.ApfProgramEvent.Builder setFlags(boolean, boolean);
+    method public android.net.metrics.ApfProgramEvent.Builder setLifetime(long);
+    method public android.net.metrics.ApfProgramEvent.Builder setProgramLength(int);
+  }
+
+  public final class ApfStats implements android.net.metrics.IpConnectivityLog.Event {
+  }
+
+  public static class ApfStats.Builder {
+    ctor public ApfStats.Builder();
+    method public android.net.metrics.ApfStats build();
+    method public android.net.metrics.ApfStats.Builder setDroppedRas(int);
+    method public android.net.metrics.ApfStats.Builder setDurationMs(long);
+    method public android.net.metrics.ApfStats.Builder setMatchingRas(int);
+    method public android.net.metrics.ApfStats.Builder setMaxProgramSize(int);
+    method public android.net.metrics.ApfStats.Builder setParseErrors(int);
+    method public android.net.metrics.ApfStats.Builder setProgramUpdates(int);
+    method public android.net.metrics.ApfStats.Builder setProgramUpdatesAll(int);
+    method public android.net.metrics.ApfStats.Builder setProgramUpdatesAllowingMulticast(int);
+    method public android.net.metrics.ApfStats.Builder setReceivedRas(int);
+    method public android.net.metrics.ApfStats.Builder setZeroLifetimeRas(int);
+  }
+
+  public final class DhcpClientEvent implements android.net.metrics.IpConnectivityLog.Event {
+  }
+
+  public static class DhcpClientEvent.Builder {
+    ctor public DhcpClientEvent.Builder();
+    method public android.net.metrics.DhcpClientEvent build();
+    method public android.net.metrics.DhcpClientEvent.Builder setDurationMs(int);
+    method public android.net.metrics.DhcpClientEvent.Builder setMsg(String);
+  }
+
+  public final class DhcpErrorEvent implements android.net.metrics.IpConnectivityLog.Event {
+    ctor public DhcpErrorEvent(int);
+    method public static int errorCodeWithOption(int, int);
+    field public static final int BOOTP_TOO_SHORT;
+    field public static final int BUFFER_UNDERFLOW;
+    field public static final int DHCP_BAD_MAGIC_COOKIE;
+    field public static final int DHCP_ERROR = 4; // 0x4
+    field public static final int DHCP_INVALID_OPTION_LENGTH;
+    field public static final int DHCP_NO_COOKIE;
+    field public static final int DHCP_NO_MSG_TYPE;
+    field public static final int DHCP_UNKNOWN_MSG_TYPE;
+    field public static final int L2_ERROR = 1; // 0x1
+    field public static final int L2_TOO_SHORT;
+    field public static final int L2_WRONG_ETH_TYPE;
+    field public static final int L3_ERROR = 2; // 0x2
+    field public static final int L3_INVALID_IP;
+    field public static final int L3_NOT_IPV4;
+    field public static final int L3_TOO_SHORT;
+    field public static final int L4_ERROR = 3; // 0x3
+    field public static final int L4_NOT_UDP;
+    field public static final int L4_WRONG_PORT;
+    field public static final int MISC_ERROR = 5; // 0x5
+    field public static final int PARSING_ERROR;
+    field public static final int RECEIVE_ERROR;
+  }
+
+  public class IpConnectivityLog {
+    method public boolean log(long, android.net.metrics.IpConnectivityLog.Event);
+    method public boolean log(String, android.net.metrics.IpConnectivityLog.Event);
+    method public boolean log(int, int[], android.net.metrics.IpConnectivityLog.Event);
+    method public boolean log(android.net.metrics.IpConnectivityLog.Event);
+  }
+
+  public static interface IpConnectivityLog.Event extends android.os.Parcelable {
+  }
+
+  public final class IpManagerEvent implements android.net.metrics.IpConnectivityLog.Event {
+    ctor public IpManagerEvent(int, long);
+    field public static final int COMPLETE_LIFECYCLE = 3; // 0x3
+    field public static final int ERROR_INTERFACE_NOT_FOUND = 8; // 0x8
+    field public static final int ERROR_INVALID_PROVISIONING = 7; // 0x7
+    field public static final int ERROR_STARTING_IPREACHABILITYMONITOR = 6; // 0x6
+    field public static final int ERROR_STARTING_IPV4 = 4; // 0x4
+    field public static final int ERROR_STARTING_IPV6 = 5; // 0x5
+    field public static final int PROVISIONING_FAIL = 2; // 0x2
+    field public static final int PROVISIONING_OK = 1; // 0x1
+  }
+
+  public final class IpReachabilityEvent implements android.net.metrics.IpConnectivityLog.Event {
+    ctor public IpReachabilityEvent(int);
+    field public static final int NUD_FAILED = 512; // 0x200
+    field public static final int NUD_FAILED_ORGANIC = 1024; // 0x400
+    field public static final int PROBE = 256; // 0x100
+    field public static final int PROVISIONING_LOST = 768; // 0x300
+    field public static final int PROVISIONING_LOST_ORGANIC = 1280; // 0x500
+  }
+
+  public final class NetworkEvent implements android.net.metrics.IpConnectivityLog.Event {
+    ctor public NetworkEvent(int, long);
+    ctor public NetworkEvent(int);
+    field public static final int NETWORK_CAPTIVE_PORTAL_FOUND = 4; // 0x4
+    field public static final int NETWORK_CONNECTED = 1; // 0x1
+    field public static final int NETWORK_CONSECUTIVE_DNS_TIMEOUT_FOUND = 12; // 0xc
+    field public static final int NETWORK_DISCONNECTED = 7; // 0x7
+    field public static final int NETWORK_FIRST_VALIDATION_PORTAL_FOUND = 10; // 0xa
+    field public static final int NETWORK_FIRST_VALIDATION_SUCCESS = 8; // 0x8
+    field public static final int NETWORK_LINGER = 5; // 0x5
+    field public static final int NETWORK_REVALIDATION_PORTAL_FOUND = 11; // 0xb
+    field public static final int NETWORK_REVALIDATION_SUCCESS = 9; // 0x9
+    field public static final int NETWORK_UNLINGER = 6; // 0x6
+    field public static final int NETWORK_VALIDATED = 2; // 0x2
+    field public static final int NETWORK_VALIDATION_FAILED = 3; // 0x3
+  }
+
+  public final class ValidationProbeEvent implements android.net.metrics.IpConnectivityLog.Event {
+    method public static String getProbeName(int);
+    field public static final int DNS_FAILURE = 0; // 0x0
+    field public static final int DNS_SUCCESS = 1; // 0x1
+    field public static final int PROBE_DNS = 0; // 0x0
+    field public static final int PROBE_FALLBACK = 4; // 0x4
+    field public static final int PROBE_HTTP = 1; // 0x1
+    field public static final int PROBE_HTTPS = 2; // 0x2
+    field public static final int PROBE_PAC = 3; // 0x3
+    field public static final int PROBE_PRIVDNS = 5; // 0x5
+  }
+
+  public static class ValidationProbeEvent.Builder {
+    ctor public ValidationProbeEvent.Builder();
+    method public android.net.metrics.ValidationProbeEvent build();
+    method public android.net.metrics.ValidationProbeEvent.Builder setDurationMs(long);
+    method public android.net.metrics.ValidationProbeEvent.Builder setProbeType(int, boolean);
+    method public android.net.metrics.ValidationProbeEvent.Builder setReturnCode(int);
+  }
+
+}
+
 package android.net.wifi {
 
   public abstract class EasyConnectStatusCallback {
@@ -5115,6 +5423,7 @@
     field public static final String NAMESPACE_CONTENT_CAPTURE = "content_capture";
     field public static final String NAMESPACE_GAME_DRIVER = "game_driver";
     field public static final String NAMESPACE_INPUT_NATIVE_BOOT = "input_native_boot";
+    field public static final String NAMESPACE_NETD_NATIVE = "netd_native";
   }
 
   public static interface DeviceConfig.OnPropertyChangedListener {
@@ -5249,8 +5558,23 @@
     method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public static void resetToDefaults(@NonNull android.content.ContentResolver, @Nullable String);
     field public static final String APP_STANDBY_ENABLED = "app_standby_enabled";
     field public static final String AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES = "autofill_compat_mode_allowed_packages";
+    field public static final String CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS = "captive_portal_fallback_probe_specs";
+    field public static final String CAPTIVE_PORTAL_FALLBACK_URL = "captive_portal_fallback_url";
+    field public static final String CAPTIVE_PORTAL_HTTPS_URL = "captive_portal_https_url";
+    field public static final String CAPTIVE_PORTAL_HTTP_URL = "captive_portal_http_url";
+    field public static final String CAPTIVE_PORTAL_MODE = "captive_portal_mode";
+    field public static final int CAPTIVE_PORTAL_MODE_AVOID = 2; // 0x2
+    field public static final int CAPTIVE_PORTAL_MODE_IGNORE = 0; // 0x0
+    field public static final int CAPTIVE_PORTAL_MODE_PROMPT = 1; // 0x1
+    field public static final String CAPTIVE_PORTAL_OTHER_FALLBACK_URLS = "captive_portal_other_fallback_urls";
+    field public static final String CAPTIVE_PORTAL_USER_AGENT = "captive_portal_user_agent";
+    field public static final String CAPTIVE_PORTAL_USE_HTTPS = "captive_portal_use_https";
     field public static final String CARRIER_APP_NAMES = "carrier_app_names";
     field public static final String CARRIER_APP_WHITELIST = "carrier_app_whitelist";
+    field public static final String DATA_STALL_CONSECUTIVE_DNS_TIMEOUT_THRESHOLD = "data_stall_consecutive_dns_timeout_threshold";
+    field public static final String DATA_STALL_EVALUATION_TYPE = "data_stall_evaluation_type";
+    field public static final String DATA_STALL_MIN_EVALUATE_INTERVAL = "data_stall_min_evaluate_interval";
+    field public static final String DATA_STALL_VALID_DNS_TIME_THRESHOLD = "data_stall_valid_dns_time_threshold";
     field public static final String DEFAULT_SM_DP_PLUS = "default_sm_dp_plus";
     field public static final String DEVICE_DEMO_MODE = "device_demo_mode";
     field public static final String DEVICE_PROVISIONING_MOBILE_DATA_ENABLED = "device_provisioning_mobile_data";
@@ -8790,6 +9114,10 @@
     field public final android.content.pm.Signature[] signatures;
   }
 
+  public abstract class WebViewRenderer {
+    ctor public WebViewRenderer();
+  }
+
   public final class WebViewUpdateService {
     method public static android.webkit.WebViewProviderInfo[] getAllWebViewPackages();
     method public static String getCurrentWebViewPackageName();
diff --git a/api/test-current.txt b/api/test-current.txt
index fb25d13..45009bb 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -780,13 +780,62 @@
 
 package android.net {
 
+  public class CaptivePortal implements android.os.Parcelable {
+    field public static final int APP_RETURN_DISMISSED = 0; // 0x0
+    field public static final int APP_RETURN_UNWANTED = 1; // 0x1
+    field public static final int APP_RETURN_WANTED_AS_IS = 2; // 0x2
+  }
+
+  public class ConnectivityManager {
+    field public static final String EXTRA_CAPTIVE_PORTAL_PROBE_SPEC = "android.net.extra.CAPTIVE_PORTAL_PROBE_SPEC";
+    field public static final String EXTRA_CAPTIVE_PORTAL_USER_AGENT = "android.net.extra.CAPTIVE_PORTAL_USER_AGENT";
+  }
+
   public final class IpSecManager {
     field public static final int INVALID_SECURITY_PARAMETER_INDEX = 0; // 0x0
   }
 
+  public class LinkAddress implements android.os.Parcelable {
+    method public boolean isGlobalPreferred();
+    method public boolean isIPv4();
+    method public boolean isIPv6();
+    method public boolean isSameAddressAs(android.net.LinkAddress);
+  }
+
+  public final class LinkProperties implements android.os.Parcelable {
+    method public boolean addDnsServer(java.net.InetAddress);
+    method public String getTcpBufferSizes();
+    method public java.util.List<java.net.InetAddress> getValidatedPrivateDnsServers();
+    method public boolean hasGlobalIPv6Address();
+    method public boolean hasIPv4Address();
+    method public boolean hasIPv6DefaultRoute();
+    method public boolean isIPv4Provisioned();
+    method public boolean isIPv6Provisioned();
+    method public boolean isProvisioned();
+    method public boolean isReachable(java.net.InetAddress);
+    method public boolean removeDnsServer(java.net.InetAddress);
+    method public boolean removeRoute(android.net.RouteInfo);
+    method public void setPrivateDnsServerName(@Nullable String);
+    method public void setTcpBufferSizes(String);
+    method public void setUsePrivateDns(boolean);
+    method public void setValidatedPrivateDnsServers(java.util.Collection<java.net.InetAddress>);
+  }
+
+  public class Network implements android.os.Parcelable {
+    method public android.net.Network getPrivateDnsBypassingCopy();
+  }
+
   public final class NetworkCapabilities implements android.os.Parcelable {
     method public int[] getCapabilities();
     method public int[] getTransportTypes();
+    method public boolean satisfiedByNetworkCapabilities(android.net.NetworkCapabilities);
+  }
+
+  public final class RouteInfo implements android.os.Parcelable {
+    method public int getType();
+    field public static final int RTN_THROW = 9; // 0x9
+    field public static final int RTN_UNICAST = 1; // 0x1
+    field public static final int RTN_UNREACHABLE = 7; // 0x7
   }
 
   public class TrafficStats {
@@ -798,6 +847,146 @@
 
 }
 
+package android.net.metrics {
+
+  public final class ApfProgramEvent implements android.net.metrics.IpConnectivityLog.Event {
+  }
+
+  public static class ApfProgramEvent.Builder {
+    ctor public ApfProgramEvent.Builder();
+    method public android.net.metrics.ApfProgramEvent build();
+    method public android.net.metrics.ApfProgramEvent.Builder setActualLifetime(long);
+    method public android.net.metrics.ApfProgramEvent.Builder setCurrentRas(int);
+    method public android.net.metrics.ApfProgramEvent.Builder setFilteredRas(int);
+    method public android.net.metrics.ApfProgramEvent.Builder setFlags(boolean, boolean);
+    method public android.net.metrics.ApfProgramEvent.Builder setLifetime(long);
+    method public android.net.metrics.ApfProgramEvent.Builder setProgramLength(int);
+  }
+
+  public final class ApfStats implements android.net.metrics.IpConnectivityLog.Event {
+  }
+
+  public static class ApfStats.Builder {
+    ctor public ApfStats.Builder();
+    method public android.net.metrics.ApfStats build();
+    method public android.net.metrics.ApfStats.Builder setDroppedRas(int);
+    method public android.net.metrics.ApfStats.Builder setDurationMs(long);
+    method public android.net.metrics.ApfStats.Builder setMatchingRas(int);
+    method public android.net.metrics.ApfStats.Builder setMaxProgramSize(int);
+    method public android.net.metrics.ApfStats.Builder setParseErrors(int);
+    method public android.net.metrics.ApfStats.Builder setProgramUpdates(int);
+    method public android.net.metrics.ApfStats.Builder setProgramUpdatesAll(int);
+    method public android.net.metrics.ApfStats.Builder setProgramUpdatesAllowingMulticast(int);
+    method public android.net.metrics.ApfStats.Builder setReceivedRas(int);
+    method public android.net.metrics.ApfStats.Builder setZeroLifetimeRas(int);
+  }
+
+  public final class DhcpClientEvent implements android.net.metrics.IpConnectivityLog.Event {
+  }
+
+  public static class DhcpClientEvent.Builder {
+    ctor public DhcpClientEvent.Builder();
+    method public android.net.metrics.DhcpClientEvent build();
+    method public android.net.metrics.DhcpClientEvent.Builder setDurationMs(int);
+    method public android.net.metrics.DhcpClientEvent.Builder setMsg(String);
+  }
+
+  public final class DhcpErrorEvent implements android.net.metrics.IpConnectivityLog.Event {
+    ctor public DhcpErrorEvent(int);
+    method public static int errorCodeWithOption(int, int);
+    field public static final int BOOTP_TOO_SHORT;
+    field public static final int BUFFER_UNDERFLOW;
+    field public static final int DHCP_BAD_MAGIC_COOKIE;
+    field public static final int DHCP_ERROR = 4; // 0x4
+    field public static final int DHCP_INVALID_OPTION_LENGTH;
+    field public static final int DHCP_NO_COOKIE;
+    field public static final int DHCP_NO_MSG_TYPE;
+    field public static final int DHCP_UNKNOWN_MSG_TYPE;
+    field public static final int L2_ERROR = 1; // 0x1
+    field public static final int L2_TOO_SHORT;
+    field public static final int L2_WRONG_ETH_TYPE;
+    field public static final int L3_ERROR = 2; // 0x2
+    field public static final int L3_INVALID_IP;
+    field public static final int L3_NOT_IPV4;
+    field public static final int L3_TOO_SHORT;
+    field public static final int L4_ERROR = 3; // 0x3
+    field public static final int L4_NOT_UDP;
+    field public static final int L4_WRONG_PORT;
+    field public static final int MISC_ERROR = 5; // 0x5
+    field public static final int PARSING_ERROR;
+    field public static final int RECEIVE_ERROR;
+  }
+
+  public class IpConnectivityLog {
+    method public boolean log(long, android.net.metrics.IpConnectivityLog.Event);
+    method public boolean log(String, android.net.metrics.IpConnectivityLog.Event);
+    method public boolean log(int, int[], android.net.metrics.IpConnectivityLog.Event);
+    method public boolean log(android.net.metrics.IpConnectivityLog.Event);
+  }
+
+  public static interface IpConnectivityLog.Event extends android.os.Parcelable {
+  }
+
+  public final class IpManagerEvent implements android.net.metrics.IpConnectivityLog.Event {
+    ctor public IpManagerEvent(int, long);
+    field public static final int COMPLETE_LIFECYCLE = 3; // 0x3
+    field public static final int ERROR_INTERFACE_NOT_FOUND = 8; // 0x8
+    field public static final int ERROR_INVALID_PROVISIONING = 7; // 0x7
+    field public static final int ERROR_STARTING_IPREACHABILITYMONITOR = 6; // 0x6
+    field public static final int ERROR_STARTING_IPV4 = 4; // 0x4
+    field public static final int ERROR_STARTING_IPV6 = 5; // 0x5
+    field public static final int PROVISIONING_FAIL = 2; // 0x2
+    field public static final int PROVISIONING_OK = 1; // 0x1
+  }
+
+  public final class IpReachabilityEvent implements android.net.metrics.IpConnectivityLog.Event {
+    ctor public IpReachabilityEvent(int);
+    field public static final int NUD_FAILED = 512; // 0x200
+    field public static final int NUD_FAILED_ORGANIC = 1024; // 0x400
+    field public static final int PROBE = 256; // 0x100
+    field public static final int PROVISIONING_LOST = 768; // 0x300
+    field public static final int PROVISIONING_LOST_ORGANIC = 1280; // 0x500
+  }
+
+  public final class NetworkEvent implements android.net.metrics.IpConnectivityLog.Event {
+    ctor public NetworkEvent(int, long);
+    ctor public NetworkEvent(int);
+    field public static final int NETWORK_CAPTIVE_PORTAL_FOUND = 4; // 0x4
+    field public static final int NETWORK_CONNECTED = 1; // 0x1
+    field public static final int NETWORK_CONSECUTIVE_DNS_TIMEOUT_FOUND = 12; // 0xc
+    field public static final int NETWORK_DISCONNECTED = 7; // 0x7
+    field public static final int NETWORK_FIRST_VALIDATION_PORTAL_FOUND = 10; // 0xa
+    field public static final int NETWORK_FIRST_VALIDATION_SUCCESS = 8; // 0x8
+    field public static final int NETWORK_LINGER = 5; // 0x5
+    field public static final int NETWORK_REVALIDATION_PORTAL_FOUND = 11; // 0xb
+    field public static final int NETWORK_REVALIDATION_SUCCESS = 9; // 0x9
+    field public static final int NETWORK_UNLINGER = 6; // 0x6
+    field public static final int NETWORK_VALIDATED = 2; // 0x2
+    field public static final int NETWORK_VALIDATION_FAILED = 3; // 0x3
+  }
+
+  public final class ValidationProbeEvent implements android.net.metrics.IpConnectivityLog.Event {
+    method public static String getProbeName(int);
+    field public static final int DNS_FAILURE = 0; // 0x0
+    field public static final int DNS_SUCCESS = 1; // 0x1
+    field public static final int PROBE_DNS = 0; // 0x0
+    field public static final int PROBE_FALLBACK = 4; // 0x4
+    field public static final int PROBE_HTTP = 1; // 0x1
+    field public static final int PROBE_HTTPS = 2; // 0x2
+    field public static final int PROBE_PAC = 3; // 0x3
+    field public static final int PROBE_PRIVDNS = 5; // 0x5
+  }
+
+  public static class ValidationProbeEvent.Builder {
+    ctor public ValidationProbeEvent.Builder();
+    method public android.net.metrics.ValidationProbeEvent build();
+    method public android.net.metrics.ValidationProbeEvent.Builder setDurationMs(long);
+    method public android.net.metrics.ValidationProbeEvent.Builder setProbeType(int, boolean);
+    method public android.net.metrics.ValidationProbeEvent.Builder setReturnCode(int);
+  }
+
+}
+
 package android.os {
 
   public class Build {
@@ -1277,6 +1466,21 @@
     field public static final String AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES = "autofill_compat_mode_allowed_packages";
     field public static final String AUTOFILL_SMART_SUGGESTION_EMULATION_FLAGS = "autofill_smart_suggestion_emulation_flags";
     field public static final String AUTOMATIC_POWER_SAVER_MODE = "automatic_power_saver_mode";
+    field public static final String CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS = "captive_portal_fallback_probe_specs";
+    field public static final String CAPTIVE_PORTAL_FALLBACK_URL = "captive_portal_fallback_url";
+    field public static final String CAPTIVE_PORTAL_HTTPS_URL = "captive_portal_https_url";
+    field public static final String CAPTIVE_PORTAL_HTTP_URL = "captive_portal_http_url";
+    field public static final String CAPTIVE_PORTAL_MODE = "captive_portal_mode";
+    field public static final int CAPTIVE_PORTAL_MODE_AVOID = 2; // 0x2
+    field public static final int CAPTIVE_PORTAL_MODE_IGNORE = 0; // 0x0
+    field public static final int CAPTIVE_PORTAL_MODE_PROMPT = 1; // 0x1
+    field public static final String CAPTIVE_PORTAL_OTHER_FALLBACK_URLS = "captive_portal_other_fallback_urls";
+    field public static final String CAPTIVE_PORTAL_USER_AGENT = "captive_portal_user_agent";
+    field public static final String CAPTIVE_PORTAL_USE_HTTPS = "captive_portal_use_https";
+    field public static final String DATA_STALL_CONSECUTIVE_DNS_TIMEOUT_THRESHOLD = "data_stall_consecutive_dns_timeout_threshold";
+    field public static final String DATA_STALL_EVALUATION_TYPE = "data_stall_evaluation_type";
+    field public static final String DATA_STALL_MIN_EVALUATE_INTERVAL = "data_stall_min_evaluate_interval";
+    field public static final String DATA_STALL_VALID_DNS_TIME_THRESHOLD = "data_stall_valid_dns_time_threshold";
     field public static final String DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD = "dynamic_power_savings_disable_threshold";
     field public static final String DYNAMIC_POWER_SAVINGS_ENABLED = "dynamic_power_savings_enabled";
     field public static final String HIDDEN_API_BLACKLIST_EXEMPTIONS = "hidden_api_blacklist_exemptions";
diff --git a/cmds/bootanimation/bootanim.rc b/cmds/bootanimation/bootanim.rc
index 469c964..1b3c32b 100644
--- a/cmds/bootanimation/bootanim.rc
+++ b/cmds/bootanimation/bootanim.rc
@@ -2,6 +2,7 @@
     class core animation
     user graphics
     group graphics audio
+    updatable
     disabled
     oneshot
     writepid /dev/stune/top-app/tasks
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index 3107b4d..820da55 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -1089,6 +1089,14 @@
     return hardware::Void();
 }
 
+hardware::Return<void> StatsService::reportUsbPortOverheatEvent(
+        const UsbPortOverheatEvent& usbPortOverheatEvent) {
+    LogEvent event(getWallClockSec() * NS_PER_SEC, getElapsedRealtimeNs(), usbPortOverheatEvent);
+    mProcessor->OnLogEvent(&event);
+
+    return hardware::Void();
+}
+
 void StatsService::binderDied(const wp <IBinder>& who) {
     ALOGW("statscompanion service died");
     StatsdStats::getInstance().noteSystemServerRestart(getWallClockSec());
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index 135a3c9..e9b3d4f 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -199,6 +199,12 @@
     virtual Return<void> reportBatteryCausedShutdown(
             const BatteryCausedShutdown& batteryCausedShutdown) override;
 
+    /**
+     * Binder call to get UsbPortOverheatEvent atom.
+     */
+    virtual Return<void> reportUsbPortOverheatEvent(
+            const UsbPortOverheatEvent& usbPortOverheatEvent) override;
+
     /** IBinder::DeathRecipient */
     virtual void binderDied(const wp<IBinder>& who) override;
 
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index ef3eac0..f8825ac 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -91,7 +91,7 @@
         ChargingStateChanged charging_state_changed = 31;
         PluggedStateChanged plugged_state_changed = 32;
         InteractiveStateChanged interactive_state_changed = 33;
-        // 34 is available
+        TouchEventReported touch_event_reported = 34;
         WakeupAlarmOccurred wakeup_alarm_occurred = 35;
         KernelWakeupReported kernel_wakeup_reported = 36;
         WifiLockStateChanged wifi_lock_state_changed = 37;
@@ -193,6 +193,7 @@
         LowStorageStateChanged low_storage_state_changed = 130;
         GnssNfwNotificationReported gnss_nfw_notification_reported = 131;
         GnssConfigurationReported gnss_configuration_reported = 132;
+        UsbPortOverheatEvent usb_port_overheat_event_reported = 133;
     }
 
     // Pulled events will start at field 10000.
@@ -1735,6 +1736,33 @@
 }
 
 /**
+ * Logs basic timing information about touch events.
+ * Reported at most every 5 minutes while device is being interacted with.
+ *
+ * Logged from:
+ *   frameworks/native/services/inputflinger
+ */
+message TouchEventReported {
+    /**
+     * The fields latency_{min|max|mean|stdev} represent minimum, maximum, mean,
+     * and the standard deviation of latency between the kernel and framework
+     * for touchscreen events. The units are microseconds.
+     *
+     * The number is measured as the difference between the time at which
+     * the input event was received in the evdev driver,
+     * and the time at which the input event was received in EventHub.
+     */
+    // Minimum value
+    optional float latency_min_micros = 1;
+    // Maximum value
+    optional float latency_max_micros = 2;
+    // Average value
+    optional float latency_mean_micros = 3;
+    // Standard deviation
+    optional float latency_stdev_micros = 4;
+}
+
+/**
  * Logs that a setting was updated.
  * Logged from:
  *   frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -2468,6 +2496,24 @@
     optional State state = 3;
 }
 
+/** Represents USB port overheat event. */
+message UsbPortOverheatEvent {
+    /* Temperature of USB port at USB plug event, in 1/10ths of degree C. */
+    optional int32 plug_temperature_deci_c = 1;
+
+    /* Maximum temperature of USB port during overheat event, in 1/10ths of degree C. */
+    optional int32 max_temperature_deci_c = 2;
+
+    /* Time between USB plug event and overheat threshold trip, in seconds. */
+    optional int32 time_to_overheat_secs = 3;
+
+    /* Time between overheat threshold trip and hysteresis, in seconds. */
+    optional int32 time_to_hysteresis_secs = 4;
+
+    /* Time between hysteresis and active mitigation ending, in seconds. */
+    optional int32 time_to_inactive_secs = 5;
+};
+
 /*
  * Logs when a connection becomes available and lost.
  * Logged in StatsCompanionService.java
diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp
index 2ff8aa1..78a75c5 100644
--- a/cmds/statsd/src/logd/LogEvent.cpp
+++ b/cmds/statsd/src/logd/LogEvent.cpp
@@ -276,6 +276,24 @@
                                  Value(batteryCausedShutdown.voltageMicroV)));
 }
 
+LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
+                   const UsbPortOverheatEvent& usbPortOverheatEvent) {
+    mLogdTimestampNs = wallClockTimestampNs;
+    mElapsedTimestampNs = elapsedTimestampNs;
+    mTagId = android::util::USB_PORT_OVERHEAT_EVENT_REPORTED;
+
+    mValues.push_back(FieldValue(Field(mTagId, getSimpleField(1)),
+                                 Value(usbPortOverheatEvent.plugTemperatureDeciC)));
+    mValues.push_back(FieldValue(Field(mTagId, getSimpleField(2)),
+                                 Value(usbPortOverheatEvent.maxTemperatureDeciC)));
+    mValues.push_back(FieldValue(Field(mTagId, getSimpleField(3)),
+                                 Value(usbPortOverheatEvent.timeToOverheat)));
+    mValues.push_back(FieldValue(Field(mTagId, getSimpleField(4)),
+                                 Value(usbPortOverheatEvent.timeToHysteresis)));
+    mValues.push_back(FieldValue(Field(mTagId, getSimpleField(5)),
+                                 Value(usbPortOverheatEvent.timeToInactive)));
+}
+
 LogEvent::LogEvent(int32_t tagId, int64_t timestampNs) : LogEvent(tagId, timestampNs, 0) {}
 
 LogEvent::LogEvent(int32_t tagId, int64_t timestampNs, int32_t uid) {
diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h
index 43e6e4f..3f47b7e 100644
--- a/cmds/statsd/src/logd/LogEvent.h
+++ b/cmds/statsd/src/logd/LogEvent.h
@@ -118,6 +118,9 @@
     explicit LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
                       const BatteryCausedShutdown& batteryCausedShutdown);
 
+    explicit LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
+                      const UsbPortOverheatEvent& usbPortOverheatEvent);
+
     ~LogEvent();
 
     /**
diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt
index 13f8dd9..700df64 100644
--- a/config/hiddenapi-greylist.txt
+++ b/config/hiddenapi-greylist.txt
@@ -1419,11 +1419,6 @@
 Landroid/service/euicc/IRetainSubscriptionsForFactoryResetCallback;->onComplete(I)V
 Landroid/service/euicc/ISwitchToSubscriptionCallback;->onComplete(I)V
 Landroid/service/euicc/IUpdateSubscriptionNicknameCallback;->onComplete(I)V
-Landroid/service/media/IMediaBrowserServiceCallbacks$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/media/IMediaBrowserServiceCallbacks;
-Landroid/service/media/IMediaBrowserServiceCallbacks;->onConnect(Ljava/lang/String;Landroid/media/session/MediaSession$Token;Landroid/os/Bundle;)V
-Landroid/service/media/IMediaBrowserServiceCallbacks;->onConnectFailed()V
-Landroid/service/media/IMediaBrowserServiceCallbacks;->onLoadChildren(Ljava/lang/String;Landroid/content/pm/ParceledListSlice;)V
-Landroid/service/media/IMediaBrowserServiceCallbacks;->onLoadChildrenWithOptions(Ljava/lang/String;Landroid/content/pm/ParceledListSlice;Landroid/os/Bundle;)V
 Landroid/service/notification/INotificationListener$Stub;-><init>()V
 Landroid/service/persistentdata/IPersistentDataBlockService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/persistentdata/IPersistentDataBlockService;
 Landroid/service/vr/IVrManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/vr/IVrManager;
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index e155fe2..5868771f 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -1731,6 +1731,15 @@
     }
 
     /**
+     * Retrieve a non-localized public name for the operation.
+     *
+     * @hide
+     */
+    public static @NonNull String opToPublicName(int op) {
+        return sOpToString[op];
+    }
+
+    /**
      * @hide
      */
     public static int strDebugOpToOp(String op) {
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 6d7c547..86db99bf 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -9403,12 +9403,18 @@
     }
 
     /**
-     * Allows the device owner to enable or disable the backup service.
+     * Allows the device owner or profile owner to enable or disable the backup service.
      *
-     * <p> Backup service manages all backup and restore mechanisms on the device. Setting this to
-     * false will prevent data from being backed up or restored.
+     * <p> Each user has its own backup service which manages the backup and restore mechanisms in
+     * that user. Disabling the backup service will prevent data from being backed up or restored.
      *
-     * <p> Backup service is off by default when device owner is present.
+     * <p> Device owner calls this API to control backup services across all users on the device.
+     * Profile owner can use this API to enable or disable the profile's backup service. However,
+     * for a managed profile its backup functionality is only enabled if both the device owner
+     * and the profile owner have enabled the backup service.
+     *
+     * <p> By default, backup service is disabled on a device with device owner, and within a
+     * managed profile.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param enabled {@code true} to enable the backup service, {@code false} to disable it.
@@ -9424,7 +9430,12 @@
     }
 
     /**
-     * Return whether the backup service is enabled by the device owner.
+     * Return whether the backup service is enabled by the device owner or profile owner for the
+     * current user, as previously set by {@link #setBackupServiceEnabled(ComponentName, boolean)}.
+     *
+     * <p> Whether the backup functionality is actually enabled or not depends on settings from both
+     * the current user and the device owner, please see
+     * {@link #setBackupServiceEnabled(ComponentName, boolean)} for details.
      *
      * <p> Backup service manages all backup and restore mechanisms on the device.
      *
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index 983ea9f..766c566 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -136,6 +136,17 @@
     public static final String EXTRA_PIN_ITEM_REQUEST =
             "android.content.pm.extra.PIN_ITEM_REQUEST";
 
+    /**
+     * Metadata key that specifies vouched certs, so any apps signed by a cert in vouched certs
+     * will not show hidden icon in launcher even it does not have a launcher visible activity.
+     *
+     * If an app has this metadata in manifest, it won't be eligible to hide its icon even if its
+     * cert is in vouched certs list.
+     *
+     * @hide
+     */
+    public static final String VOUCHED_CERTS_KEY = "vouched_certs";
+
     private final Context mContext;
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     private final ILauncherApps mService;
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index a185c8a..88a240f 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -8494,6 +8494,18 @@
     public static PackageInfo generatePackageInfoFromApex(File apexFile, boolean collectCerts)
             throws PackageParserException {
         PackageInfo pi = new PackageInfo();
+
+        // TODO(b/123086053) properly fill in the ApplicationInfo with data from AndroidManifest
+        // Add ApplicationInfo to the PackageInfo.
+        ApplicationInfo ai = new ApplicationInfo();
+        ai.sourceDir = apexFile.getPath();
+        ai.flags = ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_INSTALLED;
+        ai.enabled = true;
+        ai.targetSdkVersion = 28;
+        ai.targetSandboxVersion = 0;
+        pi.applicationInfo = ai;
+
+
         // TODO(b/123052859): We should avoid these repeated calls to parseApkLite each time
         // we want to generate information for APEX modules.
         PackageParser.ApkLite apk = PackageParser.parseApkLite(apexFile,
diff --git a/core/java/android/database/TranslatingCursor.java b/core/java/android/database/TranslatingCursor.java
index 58e65b2..d9165b4 100644
--- a/core/java/android/database/TranslatingCursor.java
+++ b/core/java/android/database/TranslatingCursor.java
@@ -39,28 +39,29 @@
 public class TranslatingCursor extends CrossProcessCursorWrapper {
     public static class Config {
         public final Uri baseUri;
-        public final String idColumn;
-        public final String[] filePathColumns;
+        public final String auxiliaryColumn;
+        public final String[] translateColumns;
 
-        public Config(Uri baseUri, String idColumn, String... filePathColumns) {
+        public Config(Uri baseUri, String auxiliaryColumn, String... translateColumns) {
             this.baseUri = baseUri;
-            this.idColumn = idColumn;
-            this.filePathColumns = filePathColumns;
+            this.auxiliaryColumn = auxiliaryColumn;
+            this.translateColumns = translateColumns;
         }
     }
 
     public interface Translator {
-        String translate(String data, long id);
+        String translate(String data, int auxiliaryColumnIndex,
+                String matchingColumn, Cursor cursor);
     }
 
     private final @NonNull Config mConfig;
     private final @NonNull Translator mTranslator;
     private final boolean mDropLast;
 
-    private final int mIdIndex;
-    private final int[] mFilePathColIndices;
+    private final int mAuxiliaryColumnIndex;
+    private final int[] mTranslateColumnIndices;
 
-    private TranslatingCursor(@NonNull Cursor cursor, @NonNull Config config,
+    public TranslatingCursor(@NonNull Cursor cursor, @NonNull Config config,
             @NonNull Translator translator, boolean dropLast) {
         super(cursor);
 
@@ -68,10 +69,10 @@
         mTranslator = Objects.requireNonNull(translator);
         mDropLast = dropLast;
 
-        mIdIndex = cursor.getColumnIndexOrThrow(config.idColumn);
-        mFilePathColIndices = new int[config.filePathColumns.length];
-        for (int i = mFilePathColIndices.length - 1; i >= 0; --i) {
-            mFilePathColIndices[i] = cursor.getColumnIndex(config.filePathColumns[i]);
+        mAuxiliaryColumnIndex = cursor.getColumnIndexOrThrow(config.auxiliaryColumn);
+        mTranslateColumnIndices = new int[config.translateColumns.length];
+        for (int i = 0; i < mTranslateColumnIndices.length; ++i) {
+            mTranslateColumnIndices[i] = cursor.getColumnIndex(config.translateColumns[i]);
         }
     }
 
@@ -97,26 +98,27 @@
             SQLiteQueryBuilder qb, SQLiteDatabase db, String[] projectionIn, String selection,
             String[] selectionArgs, String groupBy, String having, String sortOrder, String limit,
             CancellationSignal signal) {
-        final boolean requestedId = ArrayUtils.isEmpty(projectionIn)
-                || ArrayUtils.contains(projectionIn, config.idColumn);
-        final boolean requestedData = ArrayUtils.isEmpty(projectionIn)
-                || ArrayUtils.containsAny(projectionIn, config.filePathColumns);
+        final boolean requestedAuxiliaryColumn = ArrayUtils.isEmpty(projectionIn)
+                || ArrayUtils.contains(projectionIn, config.auxiliaryColumn);
+        final boolean requestedTranslateColumns = ArrayUtils.isEmpty(projectionIn)
+                || ArrayUtils.containsAny(projectionIn, config.translateColumns);
 
-        // If caller didn't request data, we have nothing to redirect
-        if (!requestedData || !ContentResolver.DEPRECATE_DATA_COLUMNS) {
+        // If caller didn't request any columns that need to be translated,
+        // we have nothing to redirect
+        if (!requestedTranslateColumns) {
             return qb.query(db, projectionIn, selection, selectionArgs,
                     groupBy, having, sortOrder, limit, signal);
         }
 
-        // If caller didn't request id, we need to splice it in
-        if (!requestedId) {
+        // If caller didn't request auxiliary column, we need to splice it in
+        if (!requestedAuxiliaryColumn) {
             projectionIn = ArrayUtils.appendElement(String.class, projectionIn,
-                    config.idColumn);
+                    config.auxiliaryColumn);
         }
 
         final Cursor c = qb.query(db, projectionIn, selection, selectionArgs,
                 groupBy, having, sortOrder);
-        return new TranslatingCursor(c, config, translator, !requestedId);
+        return new TranslatingCursor(c, config, translator, !requestedAuxiliaryColumn);
     }
 
     @Override
@@ -139,7 +141,7 @@
 
     @Override
     public double getDouble(int columnIndex) {
-        if (ArrayUtils.contains(mFilePathColIndices, columnIndex)) {
+        if (ArrayUtils.contains(mTranslateColumnIndices, columnIndex)) {
             throw new IllegalArgumentException();
         } else {
             return super.getDouble(columnIndex);
@@ -148,7 +150,7 @@
 
     @Override
     public float getFloat(int columnIndex) {
-        if (ArrayUtils.contains(mFilePathColIndices, columnIndex)) {
+        if (ArrayUtils.contains(mTranslateColumnIndices, columnIndex)) {
             throw new IllegalArgumentException();
         } else {
             return super.getFloat(columnIndex);
@@ -157,7 +159,7 @@
 
     @Override
     public int getInt(int columnIndex) {
-        if (ArrayUtils.contains(mFilePathColIndices, columnIndex)) {
+        if (ArrayUtils.contains(mTranslateColumnIndices, columnIndex)) {
             throw new IllegalArgumentException();
         } else {
             return super.getInt(columnIndex);
@@ -166,7 +168,7 @@
 
     @Override
     public long getLong(int columnIndex) {
-        if (ArrayUtils.contains(mFilePathColIndices, columnIndex)) {
+        if (ArrayUtils.contains(mTranslateColumnIndices, columnIndex)) {
             throw new IllegalArgumentException();
         } else {
             return super.getLong(columnIndex);
@@ -175,7 +177,7 @@
 
     @Override
     public short getShort(int columnIndex) {
-        if (ArrayUtils.contains(mFilePathColIndices, columnIndex)) {
+        if (ArrayUtils.contains(mTranslateColumnIndices, columnIndex)) {
             throw new IllegalArgumentException();
         } else {
             return super.getShort(columnIndex);
@@ -184,8 +186,9 @@
 
     @Override
     public String getString(int columnIndex) {
-        if (ArrayUtils.contains(mFilePathColIndices, columnIndex)) {
-            return mTranslator.translate(super.getString(columnIndex), super.getLong(mIdIndex));
+        if (ArrayUtils.contains(mTranslateColumnIndices, columnIndex)) {
+            return mTranslator.translate(super.getString(columnIndex),
+                    mAuxiliaryColumnIndex, getColumnName(columnIndex), this);
         } else {
             return super.getString(columnIndex);
         }
@@ -193,7 +196,7 @@
 
     @Override
     public void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer) {
-        if (ArrayUtils.contains(mFilePathColIndices, columnIndex)) {
+        if (ArrayUtils.contains(mTranslateColumnIndices, columnIndex)) {
             throw new IllegalArgumentException();
         } else {
             super.copyStringToBuffer(columnIndex, buffer);
@@ -202,7 +205,7 @@
 
     @Override
     public byte[] getBlob(int columnIndex) {
-        if (ArrayUtils.contains(mFilePathColIndices, columnIndex)) {
+        if (ArrayUtils.contains(mTranslateColumnIndices, columnIndex)) {
             throw new IllegalArgumentException();
         } else {
             return super.getBlob(columnIndex);
@@ -211,7 +214,7 @@
 
     @Override
     public int getType(int columnIndex) {
-        if (ArrayUtils.contains(mFilePathColIndices, columnIndex)) {
+        if (ArrayUtils.contains(mTranslateColumnIndices, columnIndex)) {
             return Cursor.FIELD_TYPE_STRING;
         } else {
             return super.getType(columnIndex);
@@ -220,7 +223,7 @@
 
     @Override
     public boolean isNull(int columnIndex) {
-        if (ArrayUtils.contains(mFilePathColIndices, columnIndex)) {
+        if (ArrayUtils.contains(mTranslateColumnIndices, columnIndex)) {
             return getString(columnIndex) == null;
         } else {
             return super.isNull(columnIndex);
diff --git a/core/java/android/net/CaptivePortal.java b/core/java/android/net/CaptivePortal.java
index ee05f28..4047068 100644
--- a/core/java/android/net/CaptivePortal.java
+++ b/core/java/android/net/CaptivePortal.java
@@ -15,6 +15,8 @@
  */
 package android.net;
 
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -28,10 +30,16 @@
  */
 public class CaptivePortal implements Parcelable {
     /** @hide */
+    @SystemApi
+    @TestApi
     public static final int APP_RETURN_DISMISSED    = 0;
     /** @hide */
+    @SystemApi
+    @TestApi
     public static final int APP_RETURN_UNWANTED     = 1;
     /** @hide */
+    @SystemApi
+    @TestApi
     public static final int APP_RETURN_WANTED_AS_IS = 2;
 
     private final IBinder mBinder;
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index abc00fe..cee3a40 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -23,6 +23,7 @@
 import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
+import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.app.PendingIntent;
 import android.content.Context;
@@ -255,6 +256,8 @@
      * portal login activity.
      * {@hide}
      */
+    @SystemApi
+    @TestApi
     public static final String EXTRA_CAPTIVE_PORTAL_PROBE_SPEC =
             "android.net.extra.CAPTIVE_PORTAL_PROBE_SPEC";
 
@@ -262,6 +265,8 @@
      * Key for passing a user agent string to the captive portal login activity.
      * {@hide}
      */
+    @SystemApi
+    @TestApi
     public static final String EXTRA_CAPTIVE_PORTAL_USER_AGENT =
             "android.net.extra.CAPTIVE_PORTAL_USER_AGENT";
 
diff --git a/core/java/android/net/LinkAddress.java b/core/java/android/net/LinkAddress.java
index b40f15a..a536d08 100644
--- a/core/java/android/net/LinkAddress.java
+++ b/core/java/android/net/LinkAddress.java
@@ -26,6 +26,7 @@
 import static android.system.OsConstants.RT_SCOPE_UNIVERSE;
 
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.os.Build;
 import android.os.Parcel;
@@ -117,7 +118,8 @@
      * @return true if the address is IPv6.
      * @hide
      */
-    @UnsupportedAppUsage
+    @TestApi
+    @SystemApi
     public boolean isIPv6() {
         return address instanceof Inet6Address;
     }
@@ -126,6 +128,8 @@
      * @return true if the address is IPv4 or is a mapped IPv4 address.
      * @hide
      */
+    @TestApi
+    @SystemApi
     public boolean isIPv4() {
         return address instanceof Inet4Address;
     }
@@ -263,7 +267,8 @@
      * otherwise.
      * @hide
      */
-    @UnsupportedAppUsage
+    @TestApi
+    @SystemApi
     public boolean isSameAddressAs(LinkAddress other) {
         return address.equals(other.address) && prefixLength == other.prefixLength;
     }
@@ -310,6 +315,8 @@
      * Returns true if this {@code LinkAddress} is global scope and preferred.
      * @hide
      */
+    @TestApi
+    @SystemApi
     public boolean isGlobalPreferred() {
         /**
          * Note that addresses flagged as IFA_F_OPTIMISTIC are
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index c2963fd..21b6a8e 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.os.Build;
 import android.os.Parcel;
@@ -368,7 +369,8 @@
      * @return true if the DNS server was added, false if it was already present.
      * @hide
      */
-    @UnsupportedAppUsage
+    @TestApi
+    @SystemApi
     public boolean addDnsServer(InetAddress dnsServer) {
         if (dnsServer != null && !mDnses.contains(dnsServer)) {
             mDnses.add(dnsServer);
@@ -384,7 +386,8 @@
      * @return true if the DNS server was removed, false if it did not exist.
      * @hide
      */
-    @UnsupportedAppUsage
+    @TestApi
+    @SystemApi
     public boolean removeDnsServer(InetAddress dnsServer) {
         if (dnsServer != null) {
             return mDnses.remove(dnsServer);
@@ -423,6 +426,8 @@
      * @param usePrivateDns The private DNS state.
      * @hide
      */
+    @TestApi
+    @SystemApi
     public void setUsePrivateDns(boolean usePrivateDns) {
         mUsePrivateDns = usePrivateDns;
     }
@@ -448,6 +453,8 @@
      * @param privateDnsServerName The private DNS server name.
      * @hide
      */
+    @TestApi
+    @SystemApi
     public void setPrivateDnsServerName(@Nullable String privateDnsServerName) {
         mPrivateDnsServerName = privateDnsServerName;
     }
@@ -510,6 +517,8 @@
      *        object.
      * @hide
      */
+    @TestApi
+    @SystemApi
     public void setValidatedPrivateDnsServers(Collection<InetAddress> dnsServers) {
         mValidatedPrivateDnses.clear();
         for (InetAddress dnsServer: dnsServers) {
@@ -525,6 +534,8 @@
      *         DNS servers on this link.
      * @hide
      */
+    @TestApi
+    @SystemApi
     public List<InetAddress> getValidatedPrivateDnsServers() {
         return Collections.unmodifiableList(mValidatedPrivateDnses);
     }
@@ -636,7 +647,8 @@
      *
      * @hide
      */
-    @UnsupportedAppUsage
+    @TestApi
+    @SystemApi
     public void setTcpBufferSizes(String tcpBufferSizes) {
         mTcpBufferSizes = tcpBufferSizes;
     }
@@ -648,7 +660,8 @@
      *
      * @hide
      */
-    @UnsupportedAppUsage
+    @TestApi
+    @SystemApi
     public String getTcpBufferSizes() {
         return mTcpBufferSizes;
     }
@@ -699,7 +712,8 @@
      *
      * @hide
      */
-    @UnsupportedAppUsage
+    @TestApi
+    @SystemApi
     public boolean removeRoute(RouteInfo route) {
         return route != null &&
                 Objects.equals(mIfaceName, route.getInterface()) &&
@@ -960,7 +974,8 @@
      * @return {@code true} if there is an IPv4 address, {@code false} otherwise.
      * @hide
      */
-    @UnsupportedAppUsage
+    @TestApi
+    @SystemApi
     public boolean hasIPv4Address() {
         for (LinkAddress address : mLinkAddresses) {
             if (address.getAddress() instanceof Inet4Address) {
@@ -988,7 +1003,8 @@
      * @return {@code true} if there is a global preferred IPv6 address, {@code false} otherwise.
      * @hide
      */
-    @UnsupportedAppUsage
+    @TestApi
+    @SystemApi
     public boolean hasGlobalIPv6Address() {
         for (LinkAddress address : mLinkAddresses) {
           if (address.getAddress() instanceof Inet6Address && address.isGlobalPreferred()) {
@@ -1020,7 +1036,8 @@
      * @return {@code true} if there is an IPv6 default route, {@code false} otherwise.
      * @hide
      */
-    @UnsupportedAppUsage
+    @TestApi
+    @SystemApi
     public boolean hasIPv6DefaultRoute() {
         for (RouteInfo r : mRoutes) {
             if (r.isIPv6Default()) {
@@ -1099,6 +1116,8 @@
      * @return {@code true} if the link is provisioned, {@code false} otherwise.
      * @hide
      */
+    @TestApi
+    @SystemApi
     public boolean isIPv4Provisioned() {
         return (hasIPv4Address() &&
                 hasIPv4DefaultRoute() &&
@@ -1112,7 +1131,8 @@
      * @return {@code true} if the link is provisioned, {@code false} otherwise.
      * @hide
      */
-    @UnsupportedAppUsage
+    @TestApi
+    @SystemApi
     public boolean isIPv6Provisioned() {
         return (hasGlobalIPv6Address() &&
                 hasIPv6DefaultRoute() &&
@@ -1126,7 +1146,8 @@
      * @return {@code true} if the link is provisioned, {@code false} otherwise.
      * @hide
      */
-    @UnsupportedAppUsage
+    @TestApi
+    @SystemApi
     public boolean isProvisioned() {
         return (isIPv4Provisioned() || isIPv6Provisioned());
     }
@@ -1138,7 +1159,8 @@
      *         {@code false} otherwise.
      * @hide
      */
-    @UnsupportedAppUsage
+    @TestApi
+    @SystemApi
     public boolean isReachable(InetAddress ip) {
         final List<RouteInfo> allRoutes = getAllRoutes();
         // If we don't have a route to this IP address, it's not reachable.
diff --git a/core/java/android/net/LinkPropertiesParcelable.aidl b/core/java/android/net/LinkPropertiesParcelable.aidl
index b153dc7..6b52239 100644
--- a/core/java/android/net/LinkPropertiesParcelable.aidl
+++ b/core/java/android/net/LinkPropertiesParcelable.aidl
@@ -35,5 +35,4 @@
     int mtu;
     String tcpBufferSizes;
     IpPrefixParcelable nat64Prefix;
-    LinkPropertiesParcelable[] stackedLinks;
 }
\ No newline at end of file
diff --git a/core/java/android/net/MacAddress.java b/core/java/android/net/MacAddress.java
index 4e551756..77d83f5 100644
--- a/core/java/android/net/MacAddress.java
+++ b/core/java/android/net/MacAddress.java
@@ -52,6 +52,8 @@
 
     /**
      * The MacAddress zero MAC address.
+     *
+     * <p>Not publicly exposed or treated specially since the OUI 00:00:00 is registered.
      * @hide
      */
     @UnsupportedAppUsage
diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java
index bf2344d..2c831de 100644
--- a/core/java/android/net/Network.java
+++ b/core/java/android/net/Network.java
@@ -16,6 +16,8 @@
 
 package android.net;
 
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -157,6 +159,8 @@
      *
      * @hide
      */
+    @TestApi
+    @SystemApi
     public Network getPrivateDnsBypassingCopy() {
         return new Network(netId, true);
     }
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index 1b44c92..7e9bda1 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -712,6 +712,7 @@
      * @hide
      */
     @TestApi
+    @SystemApi
     public @Transport int[] getTransportTypes() {
         return BitUtils.unpackBits(mTransportTypes);
     }
@@ -1312,6 +1313,8 @@
      *
      * @hide
      */
+    @TestApi
+    @SystemApi
     public boolean satisfiedByNetworkCapabilities(NetworkCapabilities nc) {
         return satisfiedByNetworkCapabilities(nc, false);
     }
diff --git a/core/java/android/net/NetworkStack.java b/core/java/android/net/NetworkStack.java
index 2eac6de..af043ee 100644
--- a/core/java/android/net/NetworkStack.java
+++ b/core/java/android/net/NetworkStack.java
@@ -50,6 +50,8 @@
 
     public static final String NETWORKSTACK_PACKAGE_NAME = "com.android.mainline.networkstack";
 
+    private static final int NETWORKSTACK_TIMEOUT_MS = 10_000;
+
     @NonNull
     @GuardedBy("mPendingNetStackRequests")
     private final ArrayList<NetworkStackCallback> mPendingNetStackRequests = new ArrayList<>();
@@ -57,6 +59,8 @@
     @GuardedBy("mPendingNetStackRequests")
     private INetworkStackConnector mConnector;
 
+    private volatile boolean mNetworkStackStartRequested = false;
+
     private interface NetworkStackCallback {
         void onNetworkStackConnected(INetworkStackConnector connector);
     }
@@ -134,6 +138,7 @@
      * started.
      */
     public void start(Context context) {
+        mNetworkStackStartRequested = true;
         // Try to bind in-process if the library is available
         IBinder connector = null;
         try {
@@ -170,15 +175,54 @@
         }
     }
 
-    // TODO: use this method to obtain the connector when implementing network stack operations
+    /**
+     * For non-system server clients, get the connector registered by the system server.
+     */
+    private INetworkStackConnector getRemoteConnector() {
+        // Block until the NetworkStack connector is registered in ServiceManager.
+        // <p>This is only useful for non-system processes that do not have a way to be notified of
+        // registration completion. Adding a callback system would be too heavy weight considering
+        // that the connector is registered on boot, so it is unlikely that a client would request
+        // it before it is registered.
+        // TODO: consider blocking boot on registration and simplify much of the logic in this class
+        IBinder connector;
+        try {
+            final long before = System.currentTimeMillis();
+            while ((connector = ServiceManager.getService(Context.NETWORK_STACK_SERVICE)) == null) {
+                Thread.sleep(20);
+                if (System.currentTimeMillis() - before > NETWORKSTACK_TIMEOUT_MS) {
+                    Slog.e(TAG, "Timeout waiting for NetworkStack connector");
+                    return null;
+                }
+            }
+        } catch (InterruptedException e) {
+            Slog.e(TAG, "Error waiting for NetworkStack connector", e);
+            return null;
+        }
+
+        return INetworkStackConnector.Stub.asInterface(connector);
+    }
+
     private void requestConnector(@NonNull NetworkStackCallback request) {
         // TODO: PID check.
-        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+        final int caller = Binder.getCallingUid();
+        if (caller != Process.SYSTEM_UID && caller != Process.BLUETOOTH_UID) {
             // Don't even attempt to obtain the connector and give a nice error message
             throw new SecurityException(
                     "Only the system server should try to bind to the network stack.");
         }
 
+        if (!mNetworkStackStartRequested) {
+            // The network stack is not being started in this process, e.g. this process is not
+            // the system server. Get a remote connector registered by the system server.
+            final INetworkStackConnector connector = getRemoteConnector();
+            synchronized (mPendingNetStackRequests) {
+                mConnector = connector;
+            }
+            request.onNetworkStackConnected(connector);
+            return;
+        }
+
         final INetworkStackConnector connector;
         synchronized (mPendingNetStackRequests) {
             connector = mConnector;
diff --git a/core/java/android/net/RouteInfo.java b/core/java/android/net/RouteInfo.java
index 37ab9ff..6bf2c67 100644
--- a/core/java/android/net/RouteInfo.java
+++ b/core/java/android/net/RouteInfo.java
@@ -16,16 +16,17 @@
 
 package android.net;
 
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
 
-import java.net.UnknownHostException;
-import java.net.InetAddress;
 import java.net.Inet4Address;
 import java.net.Inet6Address;
-
+import java.net.InetAddress;
+import java.net.UnknownHostException;
 import java.util.Collection;
 import java.util.Objects;
 
@@ -67,12 +68,18 @@
 
 
     /** Unicast route. @hide */
+    @SystemApi
+    @TestApi
     public static final int RTN_UNICAST = 1;
 
     /** Unreachable route. @hide */
+    @SystemApi
+    @TestApi
     public static final int RTN_UNREACHABLE = 7;
 
     /** Throw route. @hide */
+    @SystemApi
+    @TestApi
     public static final int RTN_THROW = 9;
 
     /**
@@ -317,6 +324,8 @@
      *
      * @hide
      */
+    @TestApi
+    @SystemApi
     public int getType() {
         return mType;
     }
@@ -362,9 +371,7 @@
      * ({@code false}).
      *
      * @return {@code true} if a gateway is specified
-     * @hide
      */
-    @UnsupportedAppUsage
     public boolean hasGateway() {
         return mHasGateway;
     }
diff --git a/core/java/android/net/ip/IIpClient.aidl b/core/java/android/net/ip/IIpClient.aidl
new file mode 100644
index 0000000..7769ec2
--- /dev/null
+++ b/core/java/android/net/ip/IIpClient.aidl
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing perNmissions and
+ * limitations under the License.
+ */
+package android.net.ip;
+
+import android.net.ProxyInfoParcelable;
+import android.net.ProvisioningConfigurationParcelable;
+
+/** @hide */
+oneway interface IIpClient {
+    void completedPreDhcpAction();
+    void confirmConfiguration();
+    void readPacketFilterComplete(in byte[] data);
+    void shutdown();
+    void startProvisioning(in ProvisioningConfigurationParcelable req);
+    void stop();
+    void setTcpBufferSizes(in String tcpBufferSizes);
+    void setHttpProxy(in ProxyInfoParcelable proxyInfo);
+    void setMulticastFilter(boolean enabled);
+}
diff --git a/core/java/android/net/ip/IIpClientCallbacks.aidl b/core/java/android/net/ip/IIpClientCallbacks.aidl
new file mode 100644
index 0000000..f077e3b
--- /dev/null
+++ b/core/java/android/net/ip/IIpClientCallbacks.aidl
@@ -0,0 +1,66 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing perNmissions and
+ * limitations under the License.
+ */
+package android.net.ip;
+
+import android.net.LinkPropertiesParcelable;
+import android.net.ip.IIpClient;
+import android.net.DhcpResultsParcelable;
+
+/** @hide */
+oneway interface IIpClientCallbacks {
+    void onIpClientCreated(in IIpClient ipClient);
+
+    void onPreDhcpAction();
+    void onPostDhcpAction();
+
+    // This is purely advisory and not an indication of provisioning
+    // success or failure.  This is only here for callers that want to
+    // expose DHCPv4 results to other APIs (e.g., WifiInfo#setInetAddress).
+    // DHCPv4 or static IPv4 configuration failure or success can be
+    // determined by whether or not the passed-in DhcpResults object is
+    // null or not.
+    void onNewDhcpResults(in DhcpResultsParcelable dhcpResults);
+
+    void onProvisioningSuccess(in LinkPropertiesParcelable newLp);
+    void onProvisioningFailure(in LinkPropertiesParcelable newLp);
+
+    // Invoked on LinkProperties changes.
+    void onLinkPropertiesChange(in LinkPropertiesParcelable newLp);
+
+    // Called when the internal IpReachabilityMonitor (if enabled) has
+    // detected the loss of a critical number of required neighbors.
+    void onReachabilityLost(in String logMsg);
+
+    // Called when the IpClient state machine terminates.
+    void onQuit();
+
+    // Install an APF program to filter incoming packets.
+    void installPacketFilter(in byte[] filter);
+
+    // Asynchronously read back the APF program & data buffer from the wifi driver.
+    // Due to Wifi HAL limitations, the current implementation only supports dumping the entire
+    // buffer. In response to this request, the driver returns the data buffer asynchronously
+    // by sending an IpClient#EVENT_READ_PACKET_FILTER_COMPLETE message.
+    void startReadPacketFilter();
+
+    // If multicast filtering cannot be accomplished with APF, this function will be called to
+    // actuate multicast filtering using another means.
+    void setFallbackMulticastFilter(boolean enabled);
+
+    // Enabled/disable Neighbor Discover offload functionality. This is
+    // called, for example, whenever 464xlat is being started or stopped.
+    void setNeighborDiscoveryOffload(boolean enable);
+}
\ No newline at end of file
diff --git a/core/java/android/net/ip/IpClientCallbacks.java b/core/java/android/net/ip/IpClientCallbacks.java
new file mode 100644
index 0000000..db01ae4
--- /dev/null
+++ b/core/java/android/net/ip/IpClientCallbacks.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.ip;
+
+import android.net.DhcpResults;
+import android.net.LinkProperties;
+
+/**
+ * Callbacks for handling IpClient events.
+ *
+ * This is a convenience class to allow clients not to override all methods of IIpClientCallbacks,
+ * and avoid unparceling arguments.
+ * These methods are called asynchronously on a Binder thread, as IpClient lives in a different
+ * process.
+ * @hide
+ */
+public class IpClientCallbacks {
+
+    /**
+     * Callback called upon IpClient creation.
+     *
+     * @param ipClient The Binder token to communicate with IpClient.
+     */
+    public void onIpClientCreated(IIpClient ipClient) {}
+
+    /**
+     * Callback called prior to DHCP discovery/renewal.
+     *
+     * <p>In order to receive onPreDhcpAction(), call #withPreDhcpAction() when constructing a
+     * ProvisioningConfiguration.
+     *
+     * <p>Implementations of onPreDhcpAction() must call IpClient#completedPreDhcpAction() to
+     * indicate that DHCP is clear to proceed.
+      */
+    public void onPreDhcpAction() {}
+
+    /**
+     * Callback called after DHCP discovery/renewal.
+     */
+    public void onPostDhcpAction() {}
+
+    /**
+     * Callback called when new DHCP results are available.
+     *
+     * <p>This is purely advisory and not an indication of provisioning success or failure.  This is
+     * only here for callers that want to expose DHCPv4 results to other APIs
+     * (e.g., WifiInfo#setInetAddress).
+     *
+     * <p>DHCPv4 or static IPv4 configuration failure or success can be determined by whether or not
+     * the passed-in DhcpResults object is null.
+     */
+    public void onNewDhcpResults(DhcpResults dhcpResults) {}
+
+    /**
+     * Indicates that provisioning was successful.
+     */
+    public void onProvisioningSuccess(LinkProperties newLp) {}
+
+    /**
+     * Indicates that provisioning failed.
+     */
+    public void onProvisioningFailure(LinkProperties newLp) {}
+
+    /**
+     * Invoked on LinkProperties changes.
+     */
+    public void onLinkPropertiesChange(LinkProperties newLp) {}
+
+    /**Called when the internal IpReachabilityMonitor (if enabled) has
+     * detected the loss of a critical number of required neighbors.
+     */
+    public void onReachabilityLost(String logMsg) {}
+
+    /**
+     * Called when the IpClient state machine terminates.
+     */
+    public void onQuit() {}
+
+    /**
+     * Called to indicate that a new APF program must be installed to filter incoming packets.
+     */
+    public void installPacketFilter(byte[] filter) {}
+
+    /**
+     * Called to indicate that the APF Program & data buffer must be read asynchronously from the
+     * wifi driver.
+     *
+     * <p>Due to Wifi HAL limitations, the current implementation only supports dumping the entire
+     * buffer. In response to this request, the driver returns the data buffer asynchronously
+     * by sending an IpClient#EVENT_READ_PACKET_FILTER_COMPLETE message.
+     */
+    public void startReadPacketFilter() {}
+
+    /**
+     * If multicast filtering cannot be accomplished with APF, this function will be called to
+     * actuate multicast filtering using another means.
+     */
+    public void setFallbackMulticastFilter(boolean enabled) {}
+
+    /**
+     * Enabled/disable Neighbor Discover offload functionality. This is called, for example,
+     * whenever 464xlat is being started or stopped.
+     */
+    public void setNeighborDiscoveryOffload(boolean enable) {}
+}
diff --git a/core/java/android/net/metrics/ApfProgramEvent.java b/core/java/android/net/metrics/ApfProgramEvent.java
index 5dabf35..8601005 100644
--- a/core/java/android/net/metrics/ApfProgramEvent.java
+++ b/core/java/android/net/metrics/ApfProgramEvent.java
@@ -17,6 +17,8 @@
 package android.net.metrics;
 
 import android.annotation.IntDef;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -36,11 +38,15 @@
  * the APF program in place with a new APF program.
  * {@hide}
  */
-public final class ApfProgramEvent implements Parcelable {
+@TestApi
+@SystemApi
+public final class ApfProgramEvent implements IpConnectivityLog.Event {
 
     // Bitflag constants describing what an Apf program filters.
     // Bits are indexeds from LSB to MSB, starting at index 0.
+    /** @hide */
     public static final int FLAG_MULTICAST_FILTER_ON = 0;
+    /** @hide */
     public static final int FLAG_HAS_IPV4_ADDRESS    = 1;
 
     /** {@hide} */
@@ -48,21 +54,33 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface Flags {}
 
+    /** @hide */
     @UnsupportedAppUsage
-    public long lifetime;       // Maximum computed lifetime of the program in seconds
+    public final long lifetime;       // Maximum computed lifetime of the program in seconds
+    /** @hide */
     @UnsupportedAppUsage
-    public long actualLifetime; // Effective program lifetime in seconds
+    public final long actualLifetime; // Effective program lifetime in seconds
+    /** @hide */
     @UnsupportedAppUsage
-    public int filteredRas;     // Number of RAs filtered by the APF program
+    public final int filteredRas;     // Number of RAs filtered by the APF program
+    /** @hide */
     @UnsupportedAppUsage
-    public int currentRas;      // Total number of current RAs at generation time
+    public final int currentRas;      // Total number of current RAs at generation time
+    /** @hide */
     @UnsupportedAppUsage
-    public int programLength;   // Length of the APF program in bytes
+    public final int programLength;   // Length of the APF program in bytes
+    /** @hide */
     @UnsupportedAppUsage
-    public int flags;           // Bitfield compound of FLAG_* constants
+    public final int flags;           // Bitfield compound of FLAG_* constants
 
-    @UnsupportedAppUsage
-    public ApfProgramEvent() {
+    private ApfProgramEvent(long lifetime, long actualLifetime, int filteredRas, int currentRas,
+            int programLength, int flags) {
+        this.lifetime = lifetime;
+        this.actualLifetime = actualLifetime;
+        this.filteredRas = filteredRas;
+        this.currentRas = currentRas;
+        this.programLength = programLength;
+        this.flags = flags;
     }
 
     private ApfProgramEvent(Parcel in) {
@@ -74,6 +92,75 @@
         this.flags = in.readInt();
     }
 
+    /**
+     * Utility to create an instance of {@link ApfProgramEvent}.
+     */
+    public static class Builder {
+        private long mLifetime;
+        private long mActualLifetime;
+        private int mFilteredRas;
+        private int mCurrentRas;
+        private int mProgramLength;
+        private int mFlags;
+
+        /**
+         * Set the maximum computed lifetime of the program in seconds.
+         */
+        public Builder setLifetime(long lifetime) {
+            mLifetime = lifetime;
+            return this;
+        }
+
+        /**
+         * Set the effective program lifetime in seconds.
+         */
+        public Builder setActualLifetime(long lifetime) {
+            mActualLifetime = lifetime;
+            return this;
+        }
+
+        /**
+         * Set the number of RAs filtered by the APF program.
+         */
+        public Builder setFilteredRas(int filteredRas) {
+            mFilteredRas = filteredRas;
+            return this;
+        }
+
+        /**
+         * Set the total number of current RAs at generation time.
+         */
+        public Builder setCurrentRas(int currentRas) {
+            mCurrentRas = currentRas;
+            return this;
+        }
+
+        /**
+         * Set the length of the APF program in bytes.
+         */
+        public Builder setProgramLength(int programLength) {
+            mProgramLength = programLength;
+            return this;
+        }
+
+        /**
+         * Set the flags describing what an Apf program filters.
+         */
+        public Builder setFlags(boolean hasIPv4, boolean multicastFilterOn) {
+            mFlags = flagsFor(hasIPv4, multicastFilterOn);
+            return this;
+        }
+
+        /**
+         * Build a new {@link ApfProgramEvent}.
+         */
+        public ApfProgramEvent build() {
+            return new ApfProgramEvent(mLifetime, mActualLifetime, mFilteredRas, mCurrentRas,
+                    mProgramLength, mFlags);
+        }
+    }
+
+    /** @hide */
     @Override
     public void writeToParcel(Parcel out, int flags) {
         out.writeLong(lifetime);
@@ -84,6 +171,7 @@
         out.writeInt(flags);
     }
 
+    /** @hide */
     @Override
     public int describeContents() {
         return 0;
@@ -96,6 +184,7 @@
                 programLength, actualLifetime, lifetimeString, namesOf(flags));
     }
 
+    /** @hide */
     public static final Parcelable.Creator<ApfProgramEvent> CREATOR
             = new Parcelable.Creator<ApfProgramEvent>() {
         public ApfProgramEvent createFromParcel(Parcel in) {
@@ -107,6 +196,7 @@
         }
     };
 
+    /** @hide */
     @UnsupportedAppUsage
     public static @Flags int flagsFor(boolean hasIPv4, boolean multicastFilterOn) {
         int bitfield = 0;
diff --git a/core/java/android/net/metrics/ApfStats.java b/core/java/android/net/metrics/ApfStats.java
index bb2a35c..844a134 100644
--- a/core/java/android/net/metrics/ApfStats.java
+++ b/core/java/android/net/metrics/ApfStats.java
@@ -16,6 +16,8 @@
 
 package android.net.metrics;
 
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -24,42 +26,70 @@
  * An event logged for an interface with APF capabilities when its IpClient state machine exits.
  * {@hide}
  */
-public final class ApfStats implements Parcelable {
+@SystemApi
+@TestApi
+public final class ApfStats implements IpConnectivityLog.Event {
 
-    /** time interval in milliseconds these stastistics covers. */
+    /**
+     * time interval in milliseconds these stastistics covers.
+     * @hide
+     */
     @UnsupportedAppUsage
-    public long durationMs;
-    /** number of received RAs. */
+    public final long durationMs;
+    /**
+     * number of received RAs.
+     * @hide
+     */
     @UnsupportedAppUsage
-    public int receivedRas;
-    /** number of received RAs matching a known RA. */
+    public final int receivedRas;
+    /**
+     * number of received RAs matching a known RA.
+     * @hide
+     */
     @UnsupportedAppUsage
-    public int matchingRas;
-    /** number of received RAs ignored due to the MAX_RAS limit. */
+    public final int matchingRas;
+    /**
+     * number of received RAs ignored due to the MAX_RAS limit.
+     * @hide
+     */
     @UnsupportedAppUsage
-    public int droppedRas;
-    /** number of received RAs with a minimum lifetime of 0. */
+    public final int droppedRas;
+    /**
+     * number of received RAs with a minimum lifetime of 0.
+     * @hide
+     */
     @UnsupportedAppUsage
-    public int zeroLifetimeRas;
-    /** number of received RAs that could not be parsed. */
+    public final int zeroLifetimeRas;
+    /**
+     * number of received RAs that could not be parsed.
+     * @hide
+     */
     @UnsupportedAppUsage
-    public int parseErrors;
-    /** number of APF program updates from receiving RAs.. */
+    public final int parseErrors;
+    /**
+     * number of APF program updates from receiving RAs.
+     * @hide
+     */
     @UnsupportedAppUsage
-    public int programUpdates;
-    /** total number of APF program updates. */
+    public final int programUpdates;
+    /**
+     * total number of APF program updates.
+     * @hide
+     */
     @UnsupportedAppUsage
-    public int programUpdatesAll;
-    /** number of APF program updates from allowing multicast traffic. */
+    public final int programUpdatesAll;
+    /**
+     * number of APF program updates from allowing multicast traffic.
+     * @hide
+     */
     @UnsupportedAppUsage
-    public int programUpdatesAllowingMulticast;
-    /** maximum APF program size advertised by hardware. */
+    public final int programUpdatesAllowingMulticast;
+    /**
+     * maximum APF program size advertised by hardware.
+     * @hide
+     */
     @UnsupportedAppUsage
-    public int maxProgramSize;
-
-    @UnsupportedAppUsage
-    public ApfStats() {
-    }
+    public final int maxProgramSize;
 
     private ApfStats(Parcel in) {
         this.durationMs = in.readLong();
@@ -74,6 +104,130 @@
         this.maxProgramSize = in.readInt();
     }
 
+    private ApfStats(long durationMs, int receivedRas, int matchingRas, int droppedRas,
+            int zeroLifetimeRas, int parseErrors, int programUpdates, int programUpdatesAll,
+            int programUpdatesAllowingMulticast, int maxProgramSize) {
+        this.durationMs = durationMs;
+        this.receivedRas = receivedRas;
+        this.matchingRas = matchingRas;
+        this.droppedRas = droppedRas;
+        this.zeroLifetimeRas = zeroLifetimeRas;
+        this.parseErrors = parseErrors;
+        this.programUpdates = programUpdates;
+        this.programUpdatesAll = programUpdatesAll;
+        this.programUpdatesAllowingMulticast = programUpdatesAllowingMulticast;
+        this.maxProgramSize = maxProgramSize;
+    }
+
+    /**
+     * Utility to create an instance of {@link ApfStats}.
+     * @hide
+     */
+    @SystemApi
+    @TestApi
+    public static class Builder {
+        private long mDurationMs;
+        private int mReceivedRas;
+        private int mMatchingRas;
+        private int mDroppedRas;
+        private int mZeroLifetimeRas;
+        private int mParseErrors;
+        private int mProgramUpdates;
+        private int mProgramUpdatesAll;
+        private int mProgramUpdatesAllowingMulticast;
+        private int mMaxProgramSize;
+
+        /**
+         * Set the time interval in milliseconds these statistics covers.
+         */
+        public Builder setDurationMs(long durationMs) {
+            mDurationMs = durationMs;
+            return this;
+        }
+
+        /**
+         * Set the number of received RAs.
+         */
+        public Builder setReceivedRas(int receivedRas) {
+            mReceivedRas = receivedRas;
+            return this;
+        }
+
+        /**
+         * Set the number of received RAs matching a known RA.
+         */
+        public Builder setMatchingRas(int matchingRas) {
+            mMatchingRas = matchingRas;
+            return this;
+        }
+
+        /**
+         * Set the number of received RAs ignored due to the MAX_RAS limit.
+         */
+        public Builder setDroppedRas(int droppedRas) {
+            mDroppedRas = droppedRas;
+            return this;
+        }
+
+        /**
+         * Set the number of received RAs with a minimum lifetime of 0.
+         */
+        public Builder setZeroLifetimeRas(int zeroLifetimeRas) {
+            mZeroLifetimeRas = zeroLifetimeRas;
+            return this;
+        }
+
+        /**
+         * Set the number of received RAs that could not be parsed.
+         */
+        public Builder setParseErrors(int parseErrors) {
+            mParseErrors = parseErrors;
+            return this;
+        }
+
+        /**
+         * Set the number of APF program updates from receiving RAs.
+         */
+        public Builder setProgramUpdates(int programUpdates) {
+            mProgramUpdates = programUpdates;
+            return this;
+        }
+
+        /**
+         * Set the total number of APF program updates.
+         */
+        public Builder setProgramUpdatesAll(int programUpdatesAll) {
+            mProgramUpdatesAll = programUpdatesAll;
+            return this;
+        }
+
+        /**
+         * Set the number of APF program updates from allowing multicast traffic.
+         */
+        public Builder setProgramUpdatesAllowingMulticast(int programUpdatesAllowingMulticast) {
+            mProgramUpdatesAllowingMulticast = programUpdatesAllowingMulticast;
+            return this;
+        }
+
+        /**
+         * Set the maximum APF program size advertised by hardware.
+         */
+        public Builder setMaxProgramSize(int maxProgramSize) {
+            mMaxProgramSize = maxProgramSize;
+            return this;
+        }
+
+        /**
+         * Create a new {@link ApfStats}.
+         */
+        public ApfStats build() {
+            return new ApfStats(mDurationMs, mReceivedRas, mMatchingRas, mDroppedRas,
+                    mZeroLifetimeRas, mParseErrors, mProgramUpdates, mProgramUpdatesAll,
+                    mProgramUpdatesAllowingMulticast, mMaxProgramSize);
+        }
+    }
+
+    /** @hide */
     @Override
     public void writeToParcel(Parcel out, int flags) {
         out.writeLong(durationMs);
@@ -88,6 +242,7 @@
         out.writeInt(maxProgramSize);
     }
 
+    /** @hide */
     @Override
     public int describeContents() {
         return 0;
@@ -108,6 +263,7 @@
                 .toString();
     }
 
+    /** @hide */
     public static final Parcelable.Creator<ApfStats> CREATOR = new Parcelable.Creator<ApfStats>() {
         public ApfStats createFromParcel(Parcel in) {
             return new ApfStats(in);
diff --git a/core/java/android/net/metrics/DhcpClientEvent.java b/core/java/android/net/metrics/DhcpClientEvent.java
index 98a7d7e..2a942ee 100644
--- a/core/java/android/net/metrics/DhcpClientEvent.java
+++ b/core/java/android/net/metrics/DhcpClientEvent.java
@@ -16,6 +16,8 @@
 
 package android.net.metrics;
 
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -24,7 +26,9 @@
  * An event recorded when a DhcpClient state machine transitions to a new state.
  * {@hide}
  */
-public final class DhcpClientEvent implements Parcelable {
+@SystemApi
+@TestApi
+public final class DhcpClientEvent implements IpConnectivityLog.Event {
 
     // Names for recording DhcpClient pseudo-state transitions.
     /** {@hide} Represents transitions from DhcpInitState to DhcpBoundState */
@@ -32,11 +36,13 @@
     /** {@hide} Represents transitions from and to DhcpBoundState via DhcpRenewingState */
     public static final String RENEWING_BOUND = "RenewingBoundState";
 
+    /** @hide */
     public final String msg;
+    /** @hide */
     public final int durationMs;
 
     @UnsupportedAppUsage
-    public DhcpClientEvent(String msg, int durationMs) {
+    private DhcpClientEvent(String msg, int durationMs) {
         this.msg = msg;
         this.durationMs = durationMs;
     }
@@ -46,12 +52,45 @@
         this.durationMs = in.readInt();
     }
 
+    /**
+     * Utility to create an instance of {@link ApfProgramEvent}.
+     */
+    public static class Builder {
+        private String mMsg;
+        private int mDurationMs;
+
+        /**
+         * Set the message of the event.
+         */
+        public Builder setMsg(String msg) {
+            mMsg = msg;
+            return this;
+        }
+
+        /**
+         * Set the duration of the event in milliseconds.
+         */
+        public Builder setDurationMs(int durationMs) {
+            mDurationMs = durationMs;
+            return this;
+        }
+
+        /**
+         * Create a new {@link DhcpClientEvent}.
+         */
+        public DhcpClientEvent build() {
+            return new DhcpClientEvent(mMsg, mDurationMs);
+        }
+    }
+
+    /** @hide */
     @Override
     public void writeToParcel(Parcel out, int flags) {
         out.writeString(msg);
         out.writeInt(durationMs);
     }
 
+    /** @hide */
     @Override
     public int describeContents() {
         return 0;
@@ -62,6 +101,7 @@
         return String.format("DhcpClientEvent(%s, %dms)", msg, durationMs);
     }
 
+    /** @hide */
     public static final Parcelable.Creator<DhcpClientEvent> CREATOR
         = new Parcelable.Creator<DhcpClientEvent>() {
         public DhcpClientEvent createFromParcel(Parcel in) {
diff --git a/core/java/android/net/metrics/DhcpErrorEvent.java b/core/java/android/net/metrics/DhcpErrorEvent.java
index c6c06f0..18fde80 100644
--- a/core/java/android/net/metrics/DhcpErrorEvent.java
+++ b/core/java/android/net/metrics/DhcpErrorEvent.java
@@ -16,7 +16,8 @@
 
 package android.net.metrics;
 
-import android.annotation.UnsupportedAppUsage;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.SparseArray;
@@ -27,48 +28,34 @@
  * Event class used to record error events when parsing DHCP response packets.
  * {@hide}
  */
-public final class DhcpErrorEvent implements Parcelable {
+@SystemApi
+@TestApi
+public final class DhcpErrorEvent implements IpConnectivityLog.Event {
     public static final int L2_ERROR   = 1;
     public static final int L3_ERROR   = 2;
     public static final int L4_ERROR   = 3;
     public static final int DHCP_ERROR = 4;
     public static final int MISC_ERROR = 5;
 
-    @UnsupportedAppUsage
     public static final int L2_TOO_SHORT               = makeErrorCode(L2_ERROR, 1);
-    @UnsupportedAppUsage
     public static final int L2_WRONG_ETH_TYPE          = makeErrorCode(L2_ERROR, 2);
 
-    @UnsupportedAppUsage
     public static final int L3_TOO_SHORT               = makeErrorCode(L3_ERROR, 1);
-    @UnsupportedAppUsage
     public static final int L3_NOT_IPV4                = makeErrorCode(L3_ERROR, 2);
-    @UnsupportedAppUsage
     public static final int L3_INVALID_IP              = makeErrorCode(L3_ERROR, 3);
 
-    @UnsupportedAppUsage
     public static final int L4_NOT_UDP                 = makeErrorCode(L4_ERROR, 1);
-    @UnsupportedAppUsage
     public static final int L4_WRONG_PORT              = makeErrorCode(L4_ERROR, 2);
 
-    @UnsupportedAppUsage
     public static final int BOOTP_TOO_SHORT            = makeErrorCode(DHCP_ERROR, 1);
-    @UnsupportedAppUsage
     public static final int DHCP_BAD_MAGIC_COOKIE      = makeErrorCode(DHCP_ERROR, 2);
-    @UnsupportedAppUsage
     public static final int DHCP_INVALID_OPTION_LENGTH = makeErrorCode(DHCP_ERROR, 3);
-    @UnsupportedAppUsage
     public static final int DHCP_NO_MSG_TYPE           = makeErrorCode(DHCP_ERROR, 4);
-    @UnsupportedAppUsage
     public static final int DHCP_UNKNOWN_MSG_TYPE      = makeErrorCode(DHCP_ERROR, 5);
-    @UnsupportedAppUsage
     public static final int DHCP_NO_COOKIE             = makeErrorCode(DHCP_ERROR, 6);
 
-    @UnsupportedAppUsage
     public static final int BUFFER_UNDERFLOW           = makeErrorCode(MISC_ERROR, 1);
-    @UnsupportedAppUsage
     public static final int RECEIVE_ERROR              = makeErrorCode(MISC_ERROR, 2);
-    @UnsupportedAppUsage
     public static final int PARSING_ERROR              = makeErrorCode(MISC_ERROR, 3);
 
     // error code byte format (MSB to LSB):
@@ -76,9 +63,9 @@
     // byte 1: error subtype
     // byte 2: unused
     // byte 3: optional code
+    /** @hide */
     public final int errorCode;
 
-    @UnsupportedAppUsage
     public DhcpErrorEvent(int errorCode) {
         this.errorCode = errorCode;
     }
@@ -87,16 +74,19 @@
         this.errorCode = in.readInt();
     }
 
+    /** @hide */
     @Override
     public void writeToParcel(Parcel out, int flags) {
         out.writeInt(errorCode);
     }
 
+    /** @hide */
     @Override
     public int describeContents() {
         return 0;
     }
 
+    /** @hide */
     public static final Parcelable.Creator<DhcpErrorEvent> CREATOR
         = new Parcelable.Creator<DhcpErrorEvent>() {
         public DhcpErrorEvent createFromParcel(Parcel in) {
@@ -108,7 +98,6 @@
         }
     };
 
-    @UnsupportedAppUsage
     public static int errorCodeWithOption(int errorCode, int option) {
         return (0xFFFF0000 & errorCode) | (0xFF & option);
     }
diff --git a/core/java/android/net/metrics/IpConnectivityLog.java b/core/java/android/net/metrics/IpConnectivityLog.java
index 998f4ba..c04fcdc 100644
--- a/core/java/android/net/metrics/IpConnectivityLog.java
+++ b/core/java/android/net/metrics/IpConnectivityLog.java
@@ -16,6 +16,8 @@
 
 package android.net.metrics;
 
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.net.ConnectivityMetricsEvent;
 import android.net.IIpConnectivityMetrics;
@@ -23,6 +25,7 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.util.Log;
+
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.BitUtils;
 
@@ -30,18 +33,28 @@
  * Class for logging IpConnectvity events with IpConnectivityMetrics
  * {@hide}
  */
+@SystemApi
+@TestApi
 public class IpConnectivityLog {
     private static final String TAG = IpConnectivityLog.class.getSimpleName();
     private static final boolean DBG = false;
 
+    /** @hide */
     public static final String SERVICE_NAME = "connmetrics";
 
     private IIpConnectivityMetrics mService;
 
+    /**
+     * An event to be logged.
+     */
+    public interface Event extends Parcelable {}
+
+    /** @hide */
     @UnsupportedAppUsage
     public IpConnectivityLog() {
     }
 
+    /** @hide */
     @VisibleForTesting
     public IpConnectivityLog(IIpConnectivityMetrics service) {
         mService = service;
@@ -67,6 +80,7 @@
      * @param ev the event to log. If the event timestamp is 0,
      * the timestamp is set to the current time in milliseconds.
      * @return true if the event was successfully logged.
+     * @hide
      */
     public boolean log(ConnectivityMetricsEvent ev) {
         if (!checkLoggerService()) {
@@ -94,7 +108,7 @@
      * @param data is a Parcelable instance representing the event.
      * @return true if the event was successfully logged.
      */
-    public boolean log(long timestamp, Parcelable data) {
+    public boolean log(long timestamp, Event data) {
         ConnectivityMetricsEvent ev = makeEv(data);
         ev.timestamp = timestamp;
         return log(ev);
@@ -106,8 +120,7 @@
      * @param data is a Parcelable instance representing the event.
      * @return true if the event was successfully logged.
      */
-    @UnsupportedAppUsage
-    public boolean log(String ifname, Parcelable data) {
+    public boolean log(String ifname, Event data) {
         ConnectivityMetricsEvent ev = makeEv(data);
         ev.ifname = ifname;
         return log(ev);
@@ -121,7 +134,7 @@
      * @param data is a Parcelable instance representing the event.
      * @return true if the event was successfully logged.
      */
-    public boolean log(int netid, int[] transports, Parcelable data) {
+    public boolean log(int netid, int[] transports, Event data) {
         ConnectivityMetricsEvent ev = makeEv(data);
         ev.netId = netid;
         ev.transports = BitUtils.packBits(transports);
@@ -133,12 +146,11 @@
      * @param data is a Parcelable instance representing the event.
      * @return true if the event was successfully logged.
      */
-    @UnsupportedAppUsage
-    public boolean log(Parcelable data) {
+    public boolean log(Event data) {
         return log(makeEv(data));
     }
 
-    private static ConnectivityMetricsEvent makeEv(Parcelable data) {
+    private static ConnectivityMetricsEvent makeEv(Event data) {
         ConnectivityMetricsEvent ev = new ConnectivityMetricsEvent();
         ev.data = data;
         return ev;
diff --git a/core/java/android/net/metrics/IpManagerEvent.java b/core/java/android/net/metrics/IpManagerEvent.java
index c47650f..013e353 100644
--- a/core/java/android/net/metrics/IpManagerEvent.java
+++ b/core/java/android/net/metrics/IpManagerEvent.java
@@ -17,7 +17,8 @@
 package android.net.metrics;
 
 import android.annotation.IntDef;
-import android.annotation.UnsupportedAppUsage;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.SparseArray;
@@ -28,11 +29,13 @@
 import java.lang.annotation.RetentionPolicy;
 
 /**
- * An event recorded by IpManager when IP provisioning completes for a network or
+ * An event recorded by IpClient when IP provisioning completes for a network or
  * when a network disconnects.
  * {@hide}
  */
-public final class IpManagerEvent implements Parcelable {
+@SystemApi
+@TestApi
+public final class IpManagerEvent implements IpConnectivityLog.Event {
 
     public static final int PROVISIONING_OK                       = 1;
     public static final int PROVISIONING_FAIL                     = 2;
@@ -43,6 +46,7 @@
     public static final int ERROR_INVALID_PROVISIONING            = 7;
     public static final int ERROR_INTERFACE_NOT_FOUND             = 8;
 
+    /** @hide */
     @IntDef(value = {
             PROVISIONING_OK, PROVISIONING_FAIL, COMPLETE_LIFECYCLE,
             ERROR_STARTING_IPV4, ERROR_STARTING_IPV6, ERROR_STARTING_IPREACHABILITYMONITOR,
@@ -51,10 +55,11 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface EventType {}
 
+    /** @hide */
     public final @EventType int eventType;
+    /** @hide */
     public final long durationMs;
 
-    @UnsupportedAppUsage
     public IpManagerEvent(@EventType int eventType, long duration) {
         this.eventType = eventType;
         this.durationMs = duration;
@@ -65,17 +70,20 @@
         this.durationMs = in.readLong();
     }
 
+    /** @hide */
     @Override
     public void writeToParcel(Parcel out, int flags) {
         out.writeInt(eventType);
         out.writeLong(durationMs);
     }
 
+    /** @hide */
     @Override
     public int describeContents() {
         return 0;
     }
 
+    /** @hide */
     public static final Parcelable.Creator<IpManagerEvent> CREATOR
         = new Parcelable.Creator<IpManagerEvent>() {
         public IpManagerEvent createFromParcel(Parcel in) {
diff --git a/core/java/android/net/metrics/IpReachabilityEvent.java b/core/java/android/net/metrics/IpReachabilityEvent.java
index 715c95e..c736297 100644
--- a/core/java/android/net/metrics/IpReachabilityEvent.java
+++ b/core/java/android/net/metrics/IpReachabilityEvent.java
@@ -16,7 +16,8 @@
 
 package android.net.metrics;
 
-import android.annotation.UnsupportedAppUsage;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.SparseArray;
@@ -28,7 +29,9 @@
  * a neighbor probe result.
  * {@hide}
  */
-public final class IpReachabilityEvent implements Parcelable {
+@SystemApi
+@TestApi
+public final class IpReachabilityEvent implements IpConnectivityLog.Event {
 
     // Event types.
     /** A probe forced by IpReachabilityMonitor. */
@@ -47,9 +50,9 @@
     // byte 1: unused
     // byte 2: type of event: PROBE, NUD_FAILED, PROVISIONING_LOST
     // byte 3: when byte 2 == PROBE, errno code from RTNetlink or IpReachabilityMonitor.
+    /** @hide */
     public final int eventType;
 
-    @UnsupportedAppUsage
     public IpReachabilityEvent(int eventType) {
         this.eventType = eventType;
     }
@@ -58,16 +61,19 @@
         this.eventType = in.readInt();
     }
 
+    /** @hide */
     @Override
     public void writeToParcel(Parcel out, int flags) {
         out.writeInt(eventType);
     }
 
+    /** @hide */
     @Override
     public int describeContents() {
         return 0;
     }
 
+    /** @hide */
     public static final Parcelable.Creator<IpReachabilityEvent> CREATOR
         = new Parcelable.Creator<IpReachabilityEvent>() {
         public IpReachabilityEvent createFromParcel(Parcel in) {
@@ -79,18 +85,6 @@
         }
     };
 
-    /**
-     * Returns the NUD failure event type code corresponding to the given conditions.
-     */
-    @UnsupportedAppUsage
-    public static int nudFailureEventType(boolean isFromProbe, boolean isProvisioningLost) {
-        if (isFromProbe) {
-            return isProvisioningLost ? PROVISIONING_LOST : NUD_FAILED;
-        } else {
-            return isProvisioningLost ? PROVISIONING_LOST_ORGANIC : NUD_FAILED_ORGANIC;
-        }
-    }
-
     @Override
     public String toString() {
         int hi = eventType & 0xff00;
diff --git a/core/java/android/net/metrics/NetworkEvent.java b/core/java/android/net/metrics/NetworkEvent.java
index cb82fbe..f5b2ff1 100644
--- a/core/java/android/net/metrics/NetworkEvent.java
+++ b/core/java/android/net/metrics/NetworkEvent.java
@@ -17,6 +17,8 @@
 package android.net.metrics;
 
 import android.annotation.IntDef;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.SparseArray;
@@ -29,7 +31,9 @@
 /**
  * {@hide}
  */
-public final class NetworkEvent implements Parcelable {
+@SystemApi
+@TestApi
+public final class NetworkEvent implements IpConnectivityLog.Event {
 
     public static final int NETWORK_CONNECTED            = 1;
     public static final int NETWORK_VALIDATED            = 2;
@@ -46,6 +50,7 @@
 
     public static final int NETWORK_CONSECUTIVE_DNS_TIMEOUT_FOUND = 12;
 
+    /** @hide */
     @IntDef(value = {
             NETWORK_CONNECTED,
             NETWORK_VALIDATED,
@@ -63,7 +68,9 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface EventType {}
 
+    /** @hide */
     public final @EventType int eventType;
+    /** @hide */
     public final long durationMs;
 
     public NetworkEvent(@EventType int eventType, long durationMs) {
@@ -80,17 +87,20 @@
         durationMs = in.readLong();
     }
 
+    /** @hide */
     @Override
     public void writeToParcel(Parcel out, int flags) {
         out.writeInt(eventType);
         out.writeLong(durationMs);
     }
 
+    /** @hide */
     @Override
     public int describeContents() {
         return 0;
     }
 
+    /** @hide */
     public static final Parcelable.Creator<NetworkEvent> CREATOR
         = new Parcelable.Creator<NetworkEvent>() {
         public NetworkEvent createFromParcel(Parcel in) {
diff --git a/core/java/android/net/metrics/RaEvent.java b/core/java/android/net/metrics/RaEvent.java
index c41881c..d308246 100644
--- a/core/java/android/net/metrics/RaEvent.java
+++ b/core/java/android/net/metrics/RaEvent.java
@@ -24,7 +24,7 @@
  * An event logged when the APF packet socket receives an RA packet.
  * {@hide}
  */
-public final class RaEvent implements Parcelable {
+public final class RaEvent implements IpConnectivityLog.Event {
 
     public static final long NO_LIFETIME = -1L;
 
diff --git a/core/java/android/net/metrics/ValidationProbeEvent.java b/core/java/android/net/metrics/ValidationProbeEvent.java
index 12c2305..42e8aa6 100644
--- a/core/java/android/net/metrics/ValidationProbeEvent.java
+++ b/core/java/android/net/metrics/ValidationProbeEvent.java
@@ -17,6 +17,8 @@
 package android.net.metrics;
 
 import android.annotation.IntDef;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.SparseArray;
@@ -30,7 +32,9 @@
  * An event recorded by NetworkMonitor when sending a probe for finding captive portals.
  * {@hide}
  */
-public final class ValidationProbeEvent implements Parcelable {
+@SystemApi
+@TestApi
+public final class ValidationProbeEvent implements IpConnectivityLog.Event {
 
     public static final int PROBE_DNS       = 0;
     public static final int PROBE_HTTP      = 1;
@@ -45,20 +49,27 @@
     private static final int FIRST_VALIDATION  = 1 << 8;
     private static final int REVALIDATION      = 2 << 8;
 
+    /** @hide */
     @IntDef(value = {DNS_FAILURE, DNS_SUCCESS})
     @Retention(RetentionPolicy.SOURCE)
     public @interface ReturnCode {}
 
-    public long durationMs;
+    /** @hide */
+    public final long durationMs;
     // probeType byte format (MSB to LSB):
     // byte 0: unused
     // byte 1: unused
     // byte 2: 0 = UNKNOWN, 1 = FIRST_VALIDATION, 2 = REVALIDATION
     // byte 3: PROBE_* constant
-    public int probeType;
-    public @ReturnCode int returnCode;
+    /** @hide */
+    public final int probeType;
+    /** @hide */
+    public final @ReturnCode int returnCode;
 
-    public ValidationProbeEvent() {
+    private ValidationProbeEvent(long durationMs, int probeType, int returnCode) {
+        this.durationMs = durationMs;
+        this.probeType = probeType;
+        this.returnCode = returnCode;
     }
 
     private ValidationProbeEvent(Parcel in) {
@@ -67,6 +78,47 @@
         returnCode = in.readInt();
     }
 
+    /**
+     * Utility to create an instance of {@link ApfProgramEvent}.
+     */
+    public static class Builder {
+        private long mDurationMs;
+        private int mProbeType;
+        private int mReturnCode;
+
+        /**
+         * Set the duration of the probe in milliseconds.
+         */
+        public Builder setDurationMs(long durationMs) {
+            mDurationMs = durationMs;
+            return this;
+        }
+
+        /**
+         * Set the probe type based on whether it was the first validation.
+         */
+        public Builder setProbeType(int probeType, boolean firstValidation) {
+            mProbeType = makeProbeType(probeType, firstValidation);
+            return this;
+        }
+
+        /**
+         * Set the return code of the probe.
+         */
+        public Builder setReturnCode(int returnCode) {
+            mReturnCode = returnCode;
+            return this;
+        }
+
+        /**
+         * Create a new {@link ValidationProbeEvent}.
+         */
+        public ValidationProbeEvent build() {
+            return new ValidationProbeEvent(mDurationMs, mProbeType, mReturnCode);
+        }
+    }
+
+    /** @hide */
     @Override
     public void writeToParcel(Parcel out, int flags) {
         out.writeLong(durationMs);
@@ -74,11 +126,13 @@
         out.writeInt(returnCode);
     }
 
+    /** @hide */
     @Override
     public int describeContents() {
         return 0;
     }
 
+    /** @hide */
     public static final Parcelable.Creator<ValidationProbeEvent> CREATOR
         = new Parcelable.Creator<ValidationProbeEvent>() {
         public ValidationProbeEvent createFromParcel(Parcel in) {
@@ -90,7 +144,7 @@
         }
     };
 
-    public static int makeProbeType(int probeType, boolean firstValidation) {
+    private static int makeProbeType(int probeType, boolean firstValidation) {
         return (probeType & 0xff) | (firstValidation ? FIRST_VALIDATION : REVALIDATION);
     }
 
@@ -98,7 +152,7 @@
         return Decoder.constants.get(probeType & 0xff, "PROBE_???");
     }
 
-    public static String getValidationStage(int probeType) {
+    private static String getValidationStage(int probeType) {
         return Decoder.constants.get(probeType & 0xff00, "UNKNOWN");
     }
 
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 9015703..a7e6601 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -86,6 +86,14 @@
     @SystemApi
     public static final String NAMESPACE_INPUT_NATIVE_BOOT = "input_native_boot";
 
+    /**
+     * Namespace for all netd related features.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String NAMESPACE_NETD_NATIVE = "netd_native";
+
     private static final Object sLock = new Object();
     @GuardedBy("sLock")
     private static Map<OnPropertyChangedListener, Pair<String, Executor>> sListeners =
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index d5de13c..516f49c 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -10816,6 +10816,8 @@
          *
          * @hide
          */
+        @SystemApi
+        @TestApi
         public static final int CAPTIVE_PORTAL_MODE_IGNORE = 0;
 
         /**
@@ -10824,6 +10826,8 @@
          *
          * @hide
          */
+        @SystemApi
+        @TestApi
         public static final int CAPTIVE_PORTAL_MODE_PROMPT = 1;
 
         /**
@@ -10832,6 +10836,8 @@
          *
          * @hide
          */
+        @SystemApi
+        @TestApi
         public static final int CAPTIVE_PORTAL_MODE_AVOID = 2;
 
         /**
@@ -10841,6 +10847,8 @@
          * The default for this setting is CAPTIVE_PORTAL_MODE_PROMPT.
          * @hide
          */
+        @SystemApi
+        @TestApi
         public static final String CAPTIVE_PORTAL_MODE = "captive_portal_mode";
 
         /**
@@ -10869,6 +10877,8 @@
          *
          * @hide
          */
+        @SystemApi
+        @TestApi
         public static final String CAPTIVE_PORTAL_HTTPS_URL = "captive_portal_https_url";
 
         /**
@@ -10877,6 +10887,8 @@
          *
          * @hide
          */
+        @SystemApi
+        @TestApi
         public static final String CAPTIVE_PORTAL_HTTP_URL = "captive_portal_http_url";
 
         /**
@@ -10885,6 +10897,8 @@
          *
          * @hide
          */
+        @SystemApi
+        @TestApi
         public static final String CAPTIVE_PORTAL_FALLBACK_URL = "captive_portal_fallback_url";
 
         /**
@@ -10893,6 +10907,8 @@
          *
          * @hide
          */
+        @SystemApi
+        @TestApi
         public static final String CAPTIVE_PORTAL_OTHER_FALLBACK_URLS =
                 "captive_portal_other_fallback_urls";
 
@@ -10902,6 +10918,8 @@
          * by "@@,@@".
          * @hide
          */
+        @SystemApi
+        @TestApi
         public static final String CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS =
                 "captive_portal_fallback_probe_specs";
 
@@ -10912,6 +10930,8 @@
          *
          * @hide
          */
+        @SystemApi
+        @TestApi
         public static final String CAPTIVE_PORTAL_USE_HTTPS = "captive_portal_use_https";
 
         /**
@@ -10920,6 +10940,8 @@
          *
          * @hide
          */
+        @SystemApi
+        @TestApi
         public static final String CAPTIVE_PORTAL_USER_AGENT = "captive_portal_user_agent";
 
         /**
@@ -10929,6 +10951,8 @@
          *
          * @hide
          */
+        @SystemApi
+        @TestApi
         public static final String DATA_STALL_CONSECUTIVE_DNS_TIMEOUT_THRESHOLD =
                 "data_stall_consecutive_dns_timeout_threshold";
 
@@ -10937,6 +10961,8 @@
          *
          * @hide
          */
+        @SystemApi
+        @TestApi
         public static final String DATA_STALL_MIN_EVALUATE_INTERVAL =
                 "data_stall_min_evaluate_interval";
 
@@ -10946,6 +10972,8 @@
          *
          * @hide
          */
+        @SystemApi
+        @TestApi
         public static final String DATA_STALL_VALID_DNS_TIME_THRESHOLD =
                 "data_stall_valid_dns_time_threshold";
 
@@ -10955,6 +10983,8 @@
          *
          * @hide
          */
+        @SystemApi
+        @TestApi
         public static final String DATA_STALL_EVALUATION_TYPE = "data_stall_evaluation_type";
 
         /**
@@ -11103,6 +11133,10 @@
           */
         public static final String PRIVATE_DNS_DEFAULT_MODE = "private_dns_default_mode";
 
+
+        /** {@hide} */
+        public static final String
+                BLUETOOTH_BTSNOOP_DEFAULT_MODE = "bluetooth_btsnoop_default_mode";
         /** {@hide} */
         public static final String
                 BLUETOOTH_HEADSET_PRIORITY_PREFIX = "bluetooth_headset_priority_";
@@ -14109,7 +14143,7 @@
          *     intervalMultiplier    (int)
          * </pre>
          *
-         * Ex: "enabled=true,baseIntervalMillis=1000,intervalMultiplier=10"
+         * Ex: "mode=HISTORICAL_MODE_ENABLED_ACTIVE,baseIntervalMillis=1000,intervalMultiplier=10"
          *
          * @see #APPOP_HISTORY_MODE
          * @see #APPOP_HISTORY_BASE_INTERVAL_MILLIS
diff --git a/core/java/android/view/inputmethod/EditorInfo.java b/core/java/android/view/inputmethod/EditorInfo.java
index f99afe6..8e7b0db 100644
--- a/core/java/android/view/inputmethod/EditorInfo.java
+++ b/core/java/android/view/inputmethod/EditorInfo.java
@@ -479,13 +479,9 @@
      * If not {@code null}, this editor needs to talk to IMEs that run for the specified user, no
      * matter what user ID the calling process has.
      *
-     * <p>Note: This field is silently ignored when:</p>
-     * <ul>
-     *     <li>{@link android.view.inputmethod.InputMethodSystemProperty#PER_PROFILE_IME_ENABLED} is
-     *     {@code false}.</li>
-     *     <li>{@link android.view.inputmethod.InputMethodSystemProperty#MULTI_CLIENT_IME_ENABLED}
-     *     is {@code true}.</li>
-     * </ul>
+     * <p>Note: This field will be silently ignored when
+     * {@link android.view.inputmethod.InputMethodSystemProperty#MULTI_CLIENT_IME_ENABLED} is
+     * {@code true}.</p>
      *
      * <p>Note also that pseudo handles such as {@link UserHandle#ALL} are not supported.</p>
      *
diff --git a/core/java/android/webkit/WebViewRenderer.java b/core/java/android/webkit/WebViewRenderer.java
index 5328254..fc38cd9 100644
--- a/core/java/android/webkit/WebViewRenderer.java
+++ b/core/java/android/webkit/WebViewRenderer.java
@@ -16,6 +16,8 @@
 
 package android.webkit;
 
+import android.annotation.SystemApi;
+
 /**
  * WebViewRenderer provides an opaque handle to a {@link WebView} renderer.
  */
@@ -40,6 +42,7 @@
      * This class cannot be created by applications.
      * @hide
      */
+    @SystemApi
     public WebViewRenderer() {
     }
 }
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 0fb1c7c..87ad3d1 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -145,6 +145,7 @@
                     Settings.Global.BLOCKED_SLICES,
                     Settings.Global.BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT,
                     Settings.Global.BLOCKING_HELPER_STREAK_LIMIT,
+                    Settings.Global.BLUETOOTH_BTSNOOP_DEFAULT_MODE,
                     Settings.Global.BLUETOOTH_A2DP_SINK_PRIORITY_PREFIX,
                     Settings.Global.BLUETOOTH_A2DP_SRC_PRIORITY_PREFIX,
                     Settings.Global.BLUETOOTH_A2DP_SUPPORTS_OPTIONAL_CODECS_PREFIX,
diff --git a/media/java/android/media/IRemoteVolumeController.aidl b/media/java/android/media/IRemoteVolumeController.aidl
index e4a4a42..a591c11 100644
--- a/media/java/android/media/IRemoteVolumeController.aidl
+++ b/media/java/android/media/IRemoteVolumeController.aidl
@@ -25,8 +25,8 @@
  * @hide
  */
 oneway interface IRemoteVolumeController {
-    void remoteVolumeChanged(ISessionController session, int flags);
+    void remoteVolumeChanged(in ISessionController session, int flags);
     // sets the default session to use with the slider, replaces remoteSliderVisibility
     // on IVolumeController
-    void updateRemoteController(ISessionController session);
+    void updateRemoteController(in ISessionController session);
 }
diff --git a/media/java/android/media/MediaController2.java b/media/java/android/media/MediaController2.java
index 7c5335b..dd97195 100644
--- a/media/java/android/media/MediaController2.java
+++ b/media/java/android/media/MediaController2.java
@@ -152,6 +152,7 @@
                     // No-op
                 }
             }
+            mConnectedToken = null;
             mPendingCommands.clear();
             mRequestedCommandSeqNumbers.clear();
             mCallbackExecutor.execute(() -> {
@@ -162,6 +163,22 @@
     }
 
     /**
+     * Returns {@link Session2Token} of the connected session.
+     * If it is not connected yet, it returns {@code null}.
+     * <p>
+     * This may differ with the {@link Session2Token} from the constructor. For example, if the
+     * controller is created with the token for MediaSession2Service, this would return
+     * token for the {@link MediaSession2} in the service.
+     *
+     * @return Session2Token of the connected session, or {@code null} if not connected
+     */
+    public Session2Token getConnectedSessionToken() {
+        synchronized (mLock) {
+            return mConnectedToken;
+        }
+    }
+
+    /**
      * Returns whether the session's playback is active.
      *
      * @return {@code true} if playback active. {@code false} otherwise.
diff --git a/media/java/android/media/MediaDescription.java b/media/java/android/media/MediaDescription.java
index e6aea99..31079e5 100644
--- a/media/java/android/media/MediaDescription.java
+++ b/media/java/android/media/MediaDescription.java
@@ -7,6 +7,7 @@
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.text.TextUtils;
 
 /**
  * A simple set of metadata for a media item suitable for display. This can be
@@ -122,9 +123,9 @@
 
     private MediaDescription(Parcel in) {
         mMediaId = in.readString();
-        mTitle = in.readCharSequence();
-        mSubtitle = in.readCharSequence();
-        mDescription = in.readCharSequence();
+        mTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+        mSubtitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+        mDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
         mIcon = in.readParcelable(null);
         mIconUri = in.readParcelable(null);
         mExtras = in.readBundle();
@@ -210,9 +211,9 @@
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeString(mMediaId);
-        dest.writeCharSequence(mTitle);
-        dest.writeCharSequence(mSubtitle);
-        dest.writeCharSequence(mDescription);
+        TextUtils.writeToParcel(mTitle, dest, 0);
+        TextUtils.writeToParcel(mSubtitle, dest, 0);
+        TextUtils.writeToParcel(mDescription, dest, 0);
         dest.writeParcelable(mIcon, flags);
         dest.writeParcelable(mIconUri, flags);
         dest.writeBundle(mExtras);
diff --git a/media/java/android/media/MediaMetadata.java b/media/java/android/media/MediaMetadata.java
index 2721ad1..a3d75a3 100644
--- a/media/java/android/media/MediaMetadata.java
+++ b/media/java/android/media/MediaMetadata.java
@@ -34,8 +34,8 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
-import java.util.Set;
 import java.util.Objects;
+import java.util.Set;
 
 /**
  * Contains metadata about an item, such as the title, artist, etc.
@@ -422,7 +422,7 @@
     }
 
     private MediaMetadata(Parcel in) {
-        mBundle = Bundle.setDefusable(in.readBundle(), true);
+        mBundle = in.readBundle();
     }
 
     /**
diff --git a/media/java/android/media/MediaParceledListSlice.aidl b/media/java/android/media/MediaParceledListSlice.aidl
new file mode 100644
index 0000000..5c0e5bc
--- /dev/null
+++ b/media/java/android/media/MediaParceledListSlice.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+/** @hide */
+parcelable MediaParceledListSlice;
diff --git a/media/java/android/media/MediaParceledListSlice.java b/media/java/android/media/MediaParceledListSlice.java
new file mode 100644
index 0000000..16a37d9
--- /dev/null
+++ b/media/java/android/media/MediaParceledListSlice.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Transfer a large list of objects across an IPC. Splits into multiple transactions if needed.
+ * Note: Only use classes declared final in order to avoid subclasses overriding reading/writing
+ * parcel logic.
+ *
+ * TODO: Add test for sending large data
+ * @param <T> A Parcelable class which will be sent over the binder calls.
+ * @hide
+ */
+public class MediaParceledListSlice<T extends Parcelable> implements Parcelable {
+    private static final String TAG = "MediaParceledListSlice";
+    private static final boolean DEBUG = false;
+
+    private static final int MAX_IPC_SIZE = 64 * 1024; // IBinder.MAX_IPC_SIZE
+
+    final List<T> mList;
+
+    public MediaParceledListSlice(List<T> list) {
+        if (list == null) {
+            throw new IllegalArgumentException("list shouldn't be null");
+        }
+        mList = list;
+    }
+
+    MediaParceledListSlice(Parcel p) {
+        final int itemCount = p.readInt();
+        mList = new ArrayList<>(itemCount);
+        if (DEBUG) {
+            Log.d(TAG, "Retrieving " + itemCount + " items");
+        }
+        if (itemCount <= 0) {
+            return;
+        }
+
+        int i = 0;
+        while (i < itemCount) {
+            if (p.readInt() == 0) {
+                break;
+            }
+
+            final T parcelable = p.readParcelable(null);
+            mList.add(parcelable);
+
+            if (DEBUG) {
+                Log.d(TAG, "Read inline #" + i + ": " + mList.get(mList.size() - 1));
+            }
+            i++;
+        }
+        if (i >= itemCount) {
+            return;
+        }
+        final IBinder retriever = p.readStrongBinder();
+        while (i < itemCount) {
+            if (DEBUG) {
+                Log.d(TAG, "Reading more @" + i + " of " + itemCount + ": retriever=" + retriever);
+            }
+            Parcel data = Parcel.obtain();
+            Parcel reply = Parcel.obtain();
+            data.writeInt(i);
+            try {
+                retriever.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failure retrieving array; only received " + i + " of " + itemCount, e);
+                return;
+            }
+            while (i < itemCount && reply.readInt() != 0) {
+                final T parcelable = reply.readParcelable(null);
+                mList.add(parcelable);
+
+                if (DEBUG) {
+                    Log.d(TAG, "Read extra #" + i + ": " + mList.get(mList.size() - 1));
+                }
+                i++;
+            }
+            reply.recycle();
+            data.recycle();
+        }
+    }
+
+    public List<T> getList() {
+        return mList;
+    }
+
+    /**
+     * Write this to another Parcel. Note that this discards the internal Parcel
+     * and should not be used anymore. This is so we can pass this to a Binder
+     * where we won't have a chance to call recycle on this.
+     */
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        final int itemCount = mList.size();
+        dest.writeInt(itemCount);
+        if (DEBUG) {
+            Log.d(TAG, "Writing " + itemCount + " items");
+        }
+        if (itemCount > 0) {
+            int i = 0;
+            while (i < itemCount && dest.dataSize() < MAX_IPC_SIZE) {
+                dest.writeInt(1);
+
+                final T parcelable = mList.get(i);
+                dest.writeParcelable(parcelable, flags);
+
+                if (DEBUG) {
+                    Log.d(TAG, "Wrote inline #" + i + ": " + mList.get(i));
+                }
+                i++;
+            }
+            if (i < itemCount) {
+                dest.writeInt(0);
+                Binder retriever = new Binder() {
+                    @Override
+                    protected boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+                            throws RemoteException {
+                        if (code != FIRST_CALL_TRANSACTION) {
+                            return super.onTransact(code, data, reply, flags);
+                        }
+                        int i = data.readInt();
+                        if (DEBUG) {
+                            Log.d(TAG, "Writing more @" + i + " of " + itemCount);
+                        }
+                        while (i < itemCount && reply.dataSize() < MAX_IPC_SIZE) {
+                            reply.writeInt(1);
+
+                            final T parcelable = mList.get(i);
+                            reply.writeParcelable(parcelable, flags);
+
+                            if (DEBUG) {
+                                Log.d(TAG, "Wrote extra #" + i + ": " + mList.get(i));
+                            }
+                            i++;
+                        }
+                        if (i < itemCount) {
+                            if (DEBUG) {
+                                Log.d(TAG, "Breaking @" + i + " of " + itemCount);
+                            }
+                            reply.writeInt(0);
+                        }
+                        return true;
+                    }
+                };
+                if (DEBUG) {
+                    Log.d(TAG, "Breaking @" + i + " of " + itemCount + ": retriever=" + retriever);
+                }
+                dest.writeStrongBinder(retriever);
+            }
+        }
+    }
+
+    @Override
+    public int describeContents() {
+        int contents = 0;
+        final List<T> list = getList();
+        for (int i = 0; i < list.size(); i++) {
+            contents |= list.get(i).describeContents();
+        }
+        return contents;
+    }
+
+    public static final Parcelable.Creator<MediaParceledListSlice> CREATOR =
+            new Parcelable.Creator<MediaParceledListSlice>() {
+        @Override
+        public MediaParceledListSlice createFromParcel(Parcel in) {
+            return new MediaParceledListSlice(in);
+        }
+
+        @Override
+        public MediaParceledListSlice[] newArray(int size) {
+            return new MediaParceledListSlice[size];
+        }
+    };
+}
diff --git a/media/java/android/media/browse/MediaBrowser.java b/media/java/android/media/browse/MediaBrowser.java
index 2bccd88..b1b14c6 100644
--- a/media/java/android/media/browse/MediaBrowser.java
+++ b/media/java/android/media/browse/MediaBrowser.java
@@ -23,8 +23,8 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
-import android.content.pm.ParceledListSlice;
 import android.media.MediaDescription;
+import android.media.MediaParceledListSlice;
 import android.media.session.MediaController;
 import android.media.session.MediaSession;
 import android.os.Binder;
@@ -653,7 +653,7 @@
     }
 
     private final void onLoadChildren(final IMediaBrowserServiceCallbacks callback,
-            final String parentId, final ParceledListSlice list, final Bundle options) {
+            final String parentId, final MediaParceledListSlice list, final Bundle options) {
         mHandler.post(new Runnable() {
             @Override
             public void run() {
@@ -1107,12 +1107,12 @@
         }
 
         @Override
-        public void onLoadChildren(String parentId, ParceledListSlice list) {
+        public void onLoadChildren(String parentId, MediaParceledListSlice list) {
             onLoadChildrenWithOptions(parentId, list, null);
         }
 
         @Override
-        public void onLoadChildrenWithOptions(String parentId, ParceledListSlice list,
+        public void onLoadChildrenWithOptions(String parentId, MediaParceledListSlice list,
                 final Bundle options) {
             MediaBrowser mediaBrowser = mMediaBrowser.get();
             if (mediaBrowser != null) {
diff --git a/media/java/android/media/session/ControllerCallbackLink.java b/media/java/android/media/session/ControllerCallbackLink.java
index a143c9b..95e19d2 100644
--- a/media/java/android/media/session/ControllerCallbackLink.java
+++ b/media/java/android/media/session/ControllerCallbackLink.java
@@ -16,35 +16,41 @@
 
 package android.media.session;
 
+import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
+import android.content.Context;
+import android.content.pm.PackageManager;
 import android.media.MediaMetadata;
 import android.media.session.MediaController.PlaybackInfo;
 import android.media.session.MediaSession.QueueItem;
+import android.os.Binder;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.Process;
 import android.os.RemoteException;
 
 import java.util.List;
 
 /**
  * Handles incoming commands to {@link MediaController.Callback}.
- * <p>
- * This API is not generally intended for third party application developers.
+ * @hide
  */
+@SystemApi
 public final class ControllerCallbackLink implements Parcelable {
+    final Context mContext;
     final CallbackStub mCallbackStub;
     final ISessionControllerCallback mIControllerCallback;
 
     /**
      * Constructor for stub (Callee)
-     * @hide
      */
-    @SystemApi
-    public ControllerCallbackLink(@NonNull CallbackStub callbackStub) {
+    public ControllerCallbackLink(@NonNull Context context, @NonNull CallbackStub callbackStub) {
+        mContext = context;
         mCallbackStub = callbackStub;
         mIControllerCallback = new CallbackStubProxy();
     }
@@ -52,14 +58,16 @@
     /**
      * Constructor for interface (Caller)
      */
-    ControllerCallbackLink(Parcel in) {
+    public ControllerCallbackLink(IBinder binder) {
+        mContext = null;
         mCallbackStub = null;
-        mIControllerCallback = ISessionControllerCallback.Stub.asInterface(in.readStrongBinder());
+        mIControllerCallback = ISessionControllerCallback.Stub.asInterface(binder);
     }
 
     /**
      * Notify controller that the connected session is destroyed.
      */
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
     public void notifySessionDestroyed() {
         try {
             mIControllerCallback.notifySessionDestroyed();
@@ -74,6 +82,7 @@
      * @param event the name of the event
      * @param extras the extras included with the event
      */
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
     public void notifyEvent(@NonNull String event, @Nullable Bundle extras) {
         try {
             mIControllerCallback.notifyEvent(event, extras);
@@ -87,6 +96,7 @@
      *
      * @param state the new playback state
      */
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
     public void notifyPlaybackStateChanged(@Nullable PlaybackState state) {
         try {
             mIControllerCallback.notifyPlaybackStateChanged(state);
@@ -100,6 +110,7 @@
      *
      * @param metadata the new metadata
      */
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
     public void notifyMetadataChanged(@Nullable MediaMetadata metadata) {
         try {
             mIControllerCallback.notifyMetadataChanged(metadata);
@@ -113,6 +124,7 @@
      *
      * @param queue the new queue
      */
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
     public void notifyQueueChanged(@Nullable List<QueueItem> queue) {
         try {
             mIControllerCallback.notifyQueueChanged(queue);
@@ -126,6 +138,7 @@
      *
      * @param title the new queue title
      */
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
     public void notifyQueueTitleChanged(@Nullable CharSequence title) {
         try {
             mIControllerCallback.notifyQueueTitleChanged(title);
@@ -139,6 +152,7 @@
      *
      * @param extras the new extras
      */
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
     public void notifyExtrasChanged(@Nullable Bundle extras) {
         try {
             mIControllerCallback.notifyExtrasChanged(extras);
@@ -152,6 +166,7 @@
      *
      * @param info the new playback info
      */
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
     public void notifyVolumeInfoChanged(@NonNull PlaybackInfo info) {
         try {
             mIControllerCallback.notifyVolumeInfoChanged(info);
@@ -180,7 +195,7 @@
             new Parcelable.Creator<ControllerCallbackLink>() {
         @Override
         public ControllerCallbackLink createFromParcel(Parcel in) {
-            return new ControllerCallbackLink(in);
+            return new ControllerCallbackLink(in.readStrongBinder());
         }
 
         @Override
@@ -191,9 +206,7 @@
 
     /**
      * Class for Stub implementation
-     * @hide
      */
-    @SystemApi
     public abstract static class CallbackStub {
         /** Stub method for ISessionControllerCallback.notifySessionDestroyed */
         public void onSessionDestroyed() {
@@ -241,22 +254,46 @@
 
         @Override
         public void notifyPlaybackStateChanged(PlaybackState state) {
-            mCallbackStub.onPlaybackStateChanged(state);
+            ensureMediasControlPermission();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mCallbackStub.onPlaybackStateChanged(state);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
 
         @Override
         public void notifyMetadataChanged(MediaMetadata metadata) {
-            mCallbackStub.onMetadataChanged(metadata);
+            ensureMediasControlPermission();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mCallbackStub.onMetadataChanged(metadata);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
 
         @Override
         public void notifyQueueChanged(List<QueueItem> queue) {
-            mCallbackStub.onQueueChanged(queue);
+            ensureMediasControlPermission();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mCallbackStub.onQueueChanged(queue);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
 
         @Override
         public void notifyQueueTitleChanged(CharSequence title) {
-            mCallbackStub.onQueueTitleChanged(title);
+            ensureMediasControlPermission();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mCallbackStub.onQueueTitleChanged(title);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
 
         @Override
@@ -266,7 +303,31 @@
 
         @Override
         public void notifyVolumeInfoChanged(PlaybackInfo info) {
-            mCallbackStub.onVolumeInfoChanged(info);
+            ensureMediasControlPermission();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mCallbackStub.onVolumeInfoChanged(info);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        private void ensureMediasControlPermission() {
+            // Allow API calls from the System UI
+            if (mContext.checkCallingPermission(android.Manifest.permission.STATUS_BAR_SERVICE)
+                    == PackageManager.PERMISSION_GRANTED) {
+                return;
+            }
+
+            // Check if it's system server or has MEDIA_CONTENT_CONTROL.
+            // Note that system server doesn't have MEDIA_CONTENT_CONTROL, so we need extra
+            // check here.
+            if (getCallingUid() == Process.SYSTEM_UID || mContext.checkCallingPermission(
+                    android.Manifest.permission.MEDIA_CONTENT_CONTROL)
+                    == PackageManager.PERMISSION_GRANTED) {
+                return;
+            }
+            throw new SecurityException("Must hold the MEDIA_CONTENT_CONTROL permission.");
         }
     }
 }
diff --git a/media/java/android/media/session/ControllerLink.aidl b/media/java/android/media/session/ControllerLink.aidl
new file mode 100644
index 0000000..532df59
--- /dev/null
+++ b/media/java/android/media/session/ControllerLink.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.session;
+
+parcelable ControllerLink;
diff --git a/media/java/android/media/session/ControllerLink.java b/media/java/android/media/session/ControllerLink.java
new file mode 100644
index 0000000..937df20
--- /dev/null
+++ b/media/java/android/media/session/ControllerLink.java
@@ -0,0 +1,986 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.session;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.app.PendingIntent;
+import android.media.MediaMetadata;
+import android.media.MediaParceledListSlice;
+import android.media.Rating;
+import android.media.session.MediaController.PlaybackInfo;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.view.KeyEvent;
+
+import java.util.List;
+
+/**
+ * Handles incoming commands from {@link MediaController}.
+ * @hide
+ */
+@SystemApi
+public final class ControllerLink implements Parcelable {
+    public static final Parcelable.Creator<ControllerLink> CREATOR =
+            new Parcelable.Creator<ControllerLink>() {
+                @Override
+                public ControllerLink createFromParcel(Parcel in) {
+                    return new ControllerLink(in.readStrongBinder());
+                }
+
+                @Override
+                public ControllerLink[] newArray(int size) {
+                    return new ControllerLink[size];
+                }
+            };
+
+    final ControllerStub mControllerStub;
+    final ISessionController mISessionController;
+
+    /**
+     * Constructor for stub (Callee)
+     */
+    public ControllerLink(@NonNull ControllerStub controllerStub) {
+        mControllerStub = controllerStub;
+        mISessionController = new StubProxy();
+    }
+
+    /**
+     * Constructor for interface (Caller)
+     */
+    public ControllerLink(IBinder binder) {
+        mControllerStub = null;
+        mISessionController = ISessionController.Stub.asInterface(binder);
+    }
+
+    /**
+     * Tell system that a controller sends a command.
+     *
+     * @param packageName the package name of the controller
+     * @param caller the {@link ControllerCallbackLink} of the controller
+     * @param command the name of the command
+     * @param args the arguments included with the command
+     * @param cb the result receiver for getting the result of the command
+     */
+    void sendCommand(@NonNull String packageName, @NonNull ControllerCallbackLink caller,
+            @NonNull String command, @Nullable Bundle args, @Nullable ResultReceiver cb) {
+        try {
+            mISessionController.sendCommand(packageName, caller, command, args, cb);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that a controller sends a media button event.
+     *
+     * @param packageName the package name of the controller
+     * @param caller the {@link ControllerCallbackLink} of the controller
+     * @param asSystemService whether this event should be considered as from system service
+     * @param mediaButton the media button key event
+     */
+    boolean sendMediaButton(@NonNull String packageName,
+            @NonNull ControllerCallbackLink caller, boolean asSystemService,
+            @NonNull KeyEvent mediaButton) {
+        try {
+            return mISessionController.sendMediaButton(packageName, caller, asSystemService,
+                    mediaButton);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Registers a controller callback link to the system.
+     *
+     * @param packageName the package name of the controller
+     * @param cb the controller callback link to register
+     */
+    void registerCallback(@NonNull String packageName, @NonNull ControllerCallbackLink cb) {
+        try {
+            mISessionController.registerCallback(packageName, cb);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Unregisters a controller callback link from the system.
+     *
+     * @param cb the controller callback link to register
+     */
+    void unregisterCallback(@NonNull ControllerCallbackLink cb) {
+        try {
+            mISessionController.unregisterCallback(cb);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Gets the package name of the connected session.
+     */
+    @NonNull
+    String getPackageName() {
+        try {
+            return mISessionController.getPackageName();
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Gets the tag of the connected session.
+     */
+    @NonNull
+    String getTag() {
+        try {
+            return mISessionController.getTag();
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Gets the {@link PendingIntent} for launching UI of the connected session.
+     */
+    @Nullable
+    PendingIntent getLaunchPendingIntent() {
+        try {
+            return mISessionController.getLaunchPendingIntent();
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Gets the flags of the connected session.
+     */
+    long getFlags() {
+        try {
+            return mISessionController.getFlags();
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Gets the volume attributes of the connected session.
+     */
+    @NonNull
+    PlaybackInfo getVolumeAttributes() {
+        try {
+            return mISessionController.getVolumeAttributes();
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that a controller requests adjusting the volume.
+     *
+     * @param packageName the package name of the controller
+     * @param opPackageName the op package name of this request
+     * @param caller the {@link ControllerCallbackLink} of the controller
+     * @param asSystemService whether this event should be considered as from system service
+     * @param direction the direction to adjust the volume in
+     * @param flags the flags with this volume change request
+     */
+    void adjustVolume(@NonNull String packageName, @NonNull String opPackageName,
+            @NonNull ControllerCallbackLink caller, boolean asSystemService, int direction,
+            int flags) {
+        try {
+            mISessionController.adjustVolume(packageName, opPackageName, caller, asSystemService,
+                    direction, flags);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that a controller requests setting the volume.
+     *
+     * @param packageName the package name of the controller
+     * @param opPackageName the op package name of this request
+     * @param caller the {@link ControllerCallbackLink} of the controller
+     * @param flags the flags with this volume change request
+     */
+    void setVolumeTo(@NonNull String packageName, @NonNull String opPackageName,
+            @NonNull ControllerCallbackLink caller, int value, int flags) {
+        try {
+            mISessionController.setVolumeTo(packageName, opPackageName, caller, value, flags);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that a controller requests preparing media.
+     *
+     * @param packageName the package name of the controller
+     * @param caller the {@link ControllerCallbackLink} of the controller
+     */
+    void prepare(@NonNull String packageName, @NonNull ControllerCallbackLink caller) {
+        try {
+            mISessionController.prepare(packageName, caller);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that a controller requests preparing media from given media ID.
+     *
+     * @param packageName the package name of the controller
+     * @param caller the {@link ControllerCallbackLink} of the controller
+     * @param mediaId the ID of the media
+     * @param extras the extras included with this request.
+     */
+    void prepareFromMediaId(@NonNull String packageName,
+            @NonNull ControllerCallbackLink caller, @NonNull String mediaId,
+            @Nullable Bundle extras) {
+        try {
+            mISessionController.prepareFromMediaId(packageName, caller, mediaId, extras);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that a controller requests preparing media from given search query.
+     *
+     * @param packageName the package name of the controller
+     * @param caller the {@link ControllerCallbackLink} of the controller
+     * @param query the search query
+     * @param extras the extras included with this request.
+     */
+    void prepareFromSearch(@NonNull String packageName,
+            @NonNull ControllerCallbackLink caller, @NonNull String query,
+            @Nullable Bundle extras) {
+        try {
+            mISessionController.prepareFromSearch(packageName, caller, query, extras);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that a controller requests preparing media from given uri.
+     *
+     * @param packageName the package name of the controller
+     * @param caller the {@link ControllerCallbackLink} of the controller
+     * @param uri the uri of the media
+     * @param extras the extras included with this request.
+     */
+    void prepareFromUri(@NonNull String packageName, @NonNull ControllerCallbackLink caller,
+            @NonNull Uri uri, @Nullable Bundle extras) {
+        try {
+            mISessionController.prepareFromUri(packageName, caller, uri, extras);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that a controller requests playing media.
+     *
+     * @param packageName the package name of the controller
+     * @param caller the {@link ControllerCallbackLink} of the controller
+     */
+    void play(@NonNull String packageName, @NonNull ControllerCallbackLink caller) {
+        try {
+            mISessionController.play(packageName, caller);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that a controller requests playing media from given media ID.
+     *
+     * @param packageName the package name of the controller
+     * @param caller the {@link ControllerCallbackLink} of the controller
+     * @param mediaId the ID of the media
+     * @param extras the extras included with this request.
+     */
+    void playFromMediaId(@NonNull String packageName, @NonNull ControllerCallbackLink caller,
+            @NonNull String mediaId, @Nullable Bundle extras) {
+        try {
+            mISessionController.playFromMediaId(packageName, caller, mediaId, extras);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that a controller requests playing media from given search query.
+     *
+     * @param packageName the package name of the controller
+     * @param caller the {@link ControllerCallbackLink} of the controller
+     * @param query the search query
+     * @param extras the extras included with this request.
+     */
+    void playFromSearch(@NonNull String packageName, @NonNull ControllerCallbackLink caller,
+            @NonNull String query, @Nullable Bundle extras) {
+        try {
+            mISessionController.playFromSearch(packageName, caller, query, extras);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that a controller requests playing media from given uri.
+     *
+     * @param packageName the package name of the controller
+     * @param caller the {@link ControllerCallbackLink} of the controller
+     * @param uri the uri of the media
+     * @param extras the extras included with this request.
+     */
+    void playFromUri(@NonNull String packageName, @NonNull ControllerCallbackLink caller,
+            @NonNull Uri uri, @Nullable Bundle extras) {
+        try {
+            mISessionController.playFromUri(packageName, caller, uri, extras);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that a controller requests skipping to the queue item with given ID.
+     *
+     * @param packageName the package name of the controller
+     * @param caller the {@link ControllerCallbackLink} of the controller
+     * @param id the queue id of the item
+     */
+    void skipToQueueItem(@NonNull String packageName, @NonNull ControllerCallbackLink caller,
+            long id) {
+        try {
+            mISessionController.skipToQueueItem(packageName, caller, id);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that a controller requests pausing media.
+     *
+     * @param packageName the package name of the controller
+     * @param caller the {@link ControllerCallbackLink} of the controller
+     */
+    void pause(@NonNull String packageName, @NonNull ControllerCallbackLink caller) {
+        try {
+            mISessionController.pause(packageName, caller);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that a controller requests stopping media.
+     *
+     * @param packageName the package name of the controller
+     * @param caller the {@link ControllerCallbackLink} of the controller
+     */
+    void stop(@NonNull String packageName, @NonNull ControllerCallbackLink caller) {
+        try {
+            mISessionController.stop(packageName, caller);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that a controller requests skipping to the next queue item.
+     *
+     * @param packageName the package name of the controller
+     * @param caller the {@link ControllerCallbackLink} of the controller
+     */
+    void next(@NonNull String packageName, @NonNull ControllerCallbackLink caller) {
+        try {
+            mISessionController.next(packageName, caller);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that a controller requests skipping to the previous queue item.
+     *
+     * @param packageName the package name of the controller
+     * @param caller the {@link ControllerCallbackLink} of the controller
+     */
+    void previous(@NonNull String packageName, @NonNull ControllerCallbackLink caller) {
+        try {
+            mISessionController.previous(packageName, caller);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that a controller requests fast-forwarding.
+     *
+     * @param packageName the package name of the controller
+     * @param caller the {@link ControllerCallbackLink} of the controller
+     */
+    void fastForward(@NonNull String packageName, @NonNull ControllerCallbackLink caller) {
+        try {
+            mISessionController.fastForward(packageName, caller);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that a controller requests rewinding.
+     *
+     * @param packageName the package name of the controller
+     * @param caller the {@link ControllerCallbackLink} of the controller
+     */
+    void rewind(@NonNull String packageName, @NonNull ControllerCallbackLink caller) {
+        try {
+            mISessionController.rewind(packageName, caller);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that a controller requests seeking to the specific position.
+     *
+     * @param packageName the package name of the controller
+     * @param caller the {@link ControllerCallbackLink} of the controller
+     * @param pos the position to move to, in milliseconds
+     */
+    void seekTo(@NonNull String packageName, @NonNull ControllerCallbackLink caller,
+            long pos) {
+        try {
+            mISessionController.seekTo(packageName, caller, pos);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that a controller requests rating of the current media.
+     *
+     * @param packageName the package name of the controller
+     * @param caller the {@link ControllerCallbackLink} of the controller
+     * @param rating the rating of the current media
+     */
+    void rate(@NonNull String packageName, @NonNull ControllerCallbackLink caller,
+            @NonNull Rating rating) {
+        try {
+            mISessionController.rate(packageName, caller, rating);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that a controller sends a custom action.
+     *
+     * @param packageName the package name of the controller
+     * @param caller the {@link ControllerCallbackLink} of the controller
+     * @param action the name of the action
+     * @param args the arguments included with this action
+     */
+    void sendCustomAction(@NonNull String packageName,
+            @NonNull ControllerCallbackLink caller, @NonNull String action, @Nullable Bundle args) {
+        try {
+            mISessionController.sendCustomAction(packageName, caller, action, args);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Gets the current metadata of the connected session.
+     */
+    @Nullable
+    public MediaMetadata getMetadata() {
+        try {
+            return mISessionController.getMetadata();
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Gets the current playback state of the connected session.
+     */
+    @Nullable
+    public PlaybackState getPlaybackState() {
+        try {
+            return mISessionController.getPlaybackState();
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Gets the current queue of the connected session.
+     */
+    @Nullable
+    public List<MediaSession.QueueItem> getQueue() {
+        try {
+            MediaParceledListSlice queue = mISessionController.getQueue();
+            return queue == null ? null : queue.getList();
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Gets the current queue title of the connected session.
+     */
+    @Nullable
+    public CharSequence getQueueTitle() {
+        try {
+            return mISessionController.getQueueTitle();
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Gets the current extras of the connected session.
+     */
+    @Nullable
+    public Bundle getExtras() {
+        try {
+            return mISessionController.getExtras();
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Gets the current rating type of the connected session.
+     */
+    public int getRatingType() {
+        try {
+            return mISessionController.getRatingType();
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /** Gets the binder */
+    @NonNull
+    public IBinder getBinder() {
+        return mISessionController.asBinder();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeStrongBinder(mISessionController.asBinder());
+    }
+
+    /**
+     * Class for Stub implementation
+     */
+    public abstract static class ControllerStub {
+        /** Stub method for ISessionController.sendCommand */
+        public void sendCommand(@NonNull String packageName, @NonNull ControllerCallbackLink caller,
+                @NonNull String command, @Nullable Bundle args, @Nullable ResultReceiver cb) {
+        }
+
+        /** Stub method for ISessionController.sendMediaButton */
+        public boolean sendMediaButton(@NonNull String packageName,
+                @NonNull ControllerCallbackLink caller, boolean asSystemService,
+                @NonNull KeyEvent mediaButton) {
+            return false;
+        }
+
+        /** Stub method for ISessionController.registerCallback */
+        public void registerCallback(@NonNull String packageName,
+                @NonNull ControllerCallbackLink cb) {
+        }
+
+        /** Stub method for ISessionController.unregisterCallback */
+        public void unregisterCallback(@NonNull ControllerCallbackLink cb) {
+        }
+
+        /** Stub method for ISessionController.getPackageName */
+        @NonNull
+        public String getPackageName() {
+            return null;
+        }
+
+        /** Stub method for ISessionController.getTag */
+        @NonNull
+        public String getTag() {
+            return null;
+        }
+
+        /** Stub method for ISessionController.getLaunchPendingIntent */
+        @Nullable
+        public PendingIntent getLaunchPendingIntent() {
+            return null;
+        }
+
+        /** Stub method for ISessionController.getFlags */
+        public long getFlags() {
+            return 0;
+        }
+
+        /** Stub method for ISessionController.getVolumeAttributes */
+        @NonNull
+        public PlaybackInfo getVolumeAttributes() {
+            return null;
+        }
+
+        /** Stub method for ISessionController.adjustVolume */
+        public void adjustVolume(@NonNull String packageName, @NonNull String opPackageName,
+                @NonNull ControllerCallbackLink caller, boolean asSystemService, int direction,
+                int flags) {
+        }
+
+        /** Stub method for ISessionController.setVolumeTo */
+        public void setVolumeTo(@NonNull String packageName, @NonNull String opPackageName,
+                @NonNull ControllerCallbackLink caller, int value, int flags) {
+        }
+
+        /** Stub method for ISessionController.prepare */
+        public void prepare(@NonNull String packageName, @NonNull ControllerCallbackLink caller) {
+        }
+
+        /** Stub method for ISessionController.prepareFromMediaId */
+        public void prepareFromMediaId(@NonNull String packageName,
+                @NonNull ControllerCallbackLink caller, @NonNull String mediaId,
+                @Nullable Bundle extras) {
+        }
+
+        /** Stub method for ISessionController.prepareFromSearch */
+        public void prepareFromSearch(@NonNull String packageName,
+                @NonNull ControllerCallbackLink caller, @NonNull String query,
+                @Nullable Bundle extras) {
+        }
+
+        /** Stub method for ISessionController.prepareFromUri */
+        public void prepareFromUri(@NonNull String packageName,
+                @NonNull ControllerCallbackLink caller, @NonNull Uri uri, @Nullable Bundle extras) {
+        }
+
+        /** Stub method for ISessionController.play */
+        public void play(@NonNull String packageName, @NonNull ControllerCallbackLink caller) {
+        }
+
+        /** Stub method for ISessionController.playFromMediaId */
+        public void playFromMediaId(@NonNull String packageName,
+                @NonNull ControllerCallbackLink caller, @NonNull String mediaId,
+                @Nullable Bundle extras) {
+        }
+
+        /** Stub method for ISessionController.playFromSearch */
+        public void playFromSearch(@NonNull String packageName,
+                @NonNull ControllerCallbackLink caller, @NonNull String query,
+                @Nullable Bundle extras) {
+        }
+
+        /** Stub method for ISessionController.playFromUri */
+        public void playFromUri(@NonNull String packageName, @NonNull ControllerCallbackLink caller,
+                @NonNull Uri uri, @Nullable Bundle extras) {
+        }
+
+        /** Stub method for ISessionController.skipToQueueItem */
+        public void skipToQueueItem(@NonNull String packageName,
+                @NonNull ControllerCallbackLink caller, long id) {
+        }
+
+        /** Stub method for ISessionController.pause */
+        public void pause(@NonNull String packageName, @NonNull ControllerCallbackLink caller) {
+        }
+
+        /** Stub method for ISessionController.stop */
+        public void stop(@NonNull String packageName, @NonNull ControllerCallbackLink caller) {
+        }
+
+        /** Stub method for ISessionController.next */
+        public void next(@NonNull String packageName, @NonNull ControllerCallbackLink caller) {
+        }
+
+        /** Stub method for ISessionController.previous */
+        public void previous(@NonNull String packageName, @NonNull ControllerCallbackLink caller) {
+        }
+
+        /** Stub method for ISessionController.fastForward */
+        public void fastForward(@NonNull String packageName,
+                @NonNull ControllerCallbackLink caller) {
+        }
+
+        /** Stub method for ISessionController.rewind */
+        public void rewind(@NonNull String packageName, @NonNull ControllerCallbackLink caller) {
+        }
+
+        /** Stub method for ISessionController.seekTo */
+        public void seekTo(@NonNull String packageName, @NonNull ControllerCallbackLink caller,
+                long pos) {
+        }
+
+        /** Stub method for ISessionController.rate */
+        public void rate(@NonNull String packageName, @NonNull ControllerCallbackLink caller,
+                @NonNull Rating rating) {
+        }
+
+        /** Stub method for ISessionController.sendCustomAction */
+        public void sendCustomAction(@NonNull String packageName,
+                @NonNull ControllerCallbackLink caller, @NonNull String action,
+                @Nullable Bundle args) {
+        }
+
+        /** Stub method for ISessionController.getMetadata */
+        @Nullable
+        public MediaMetadata getMetadata() {
+            return null;
+        }
+
+        /** Stub method for ISessionController.getPlaybackState */
+        @Nullable
+        public PlaybackState getPlaybackState() {
+            return null;
+        }
+
+        /** Stub method for ISessionController.getQueue */
+        @Nullable
+        public List<MediaSession.QueueItem> getQueue() {
+            return null;
+        }
+
+        /** Stub method for ISessionController.getQueueTitle */
+        @Nullable
+        public CharSequence getQueueTitle() {
+            return null;
+        }
+
+        /** Stub method for ISessionController.getExtras */
+        @Nullable
+        public Bundle getExtras() {
+            return null;
+        }
+
+        /** Stub method for ISessionController.getRatingType */
+        public int getRatingType() {
+            return Rating.RATING_NONE;
+        }
+    }
+
+    private class StubProxy extends ISessionController.Stub {
+        @Override
+        public void sendCommand(String packageName, ControllerCallbackLink caller,
+                String command, Bundle args, ResultReceiver cb) {
+            mControllerStub.sendCommand(packageName, caller, command, args, cb);
+        }
+
+        @Override
+        public boolean sendMediaButton(String packageName, ControllerCallbackLink caller,
+                boolean asSystemService, KeyEvent mediaButton) {
+            return mControllerStub.sendMediaButton(packageName, caller, asSystemService,
+                    mediaButton);
+        }
+
+        @Override
+        public void registerCallback(String packageName, ControllerCallbackLink cb) {
+            mControllerStub.registerCallback(packageName, cb);
+        }
+
+        @Override
+        public void unregisterCallback(ControllerCallbackLink cb) {
+            mControllerStub.unregisterCallback(cb);
+        }
+
+        @Override
+        public String getPackageName() {
+            return mControllerStub.getPackageName();
+        }
+
+        @Override
+        public String getTag() {
+            return mControllerStub.getTag();
+        }
+
+        @Override
+        public PendingIntent getLaunchPendingIntent() {
+            return mControllerStub.getLaunchPendingIntent();
+        }
+
+        @Override
+        public long getFlags() {
+            return mControllerStub.getFlags();
+        }
+
+        @Override
+        public PlaybackInfo getVolumeAttributes() {
+            return mControllerStub.getVolumeAttributes();
+        }
+
+        @Override
+        public void adjustVolume(String packageName, String opPackageName,
+                ControllerCallbackLink caller, boolean asSystemService, int direction,
+                int flags) {
+            mControllerStub.adjustVolume(packageName, opPackageName, caller, asSystemService,
+                    direction, flags);
+        }
+
+        @Override
+        public void setVolumeTo(String packageName, String opPackageName,
+                ControllerCallbackLink caller, int value, int flags) {
+            mControllerStub.setVolumeTo(packageName, opPackageName, caller, value, flags);
+        }
+
+        @Override
+        public void prepare(String packageName, ControllerCallbackLink caller) {
+            mControllerStub.prepare(packageName, caller);
+        }
+
+        @Override
+        public void prepareFromMediaId(String packageName, ControllerCallbackLink caller,
+                String mediaId, Bundle extras) {
+            mControllerStub.prepareFromMediaId(packageName, caller, mediaId, extras);
+        }
+
+        @Override
+        public void prepareFromSearch(String packageName, ControllerCallbackLink caller,
+                String query, Bundle extras) {
+            mControllerStub.prepareFromSearch(packageName, caller, query, extras);
+        }
+
+        @Override
+        public void prepareFromUri(String packageName, ControllerCallbackLink caller,
+                Uri uri, Bundle extras) {
+            mControllerStub.prepareFromUri(packageName, caller, uri, extras);
+        }
+
+        @Override
+        public void play(String packageName, ControllerCallbackLink caller) {
+            mControllerStub.play(packageName, caller);
+        }
+
+        @Override
+        public void playFromMediaId(String packageName, ControllerCallbackLink caller,
+                String mediaId, Bundle extras) {
+            mControllerStub.playFromMediaId(packageName, caller, mediaId, extras);
+        }
+
+        @Override
+        public void playFromSearch(String packageName, ControllerCallbackLink caller,
+                String query, Bundle extras) {
+            mControllerStub.playFromSearch(packageName, caller, query, extras);
+        }
+
+        @Override
+        public void playFromUri(String packageName, ControllerCallbackLink caller,
+                Uri uri, Bundle extras) {
+            mControllerStub.playFromUri(packageName, caller, uri, extras);
+        }
+
+        @Override
+        public void skipToQueueItem(String packageName, ControllerCallbackLink caller, long id) {
+            mControllerStub.skipToQueueItem(packageName, caller, id);
+        }
+
+        @Override
+        public void pause(String packageName, ControllerCallbackLink caller) {
+            mControllerStub.pause(packageName, caller);
+        }
+
+        @Override
+        public void stop(String packageName, ControllerCallbackLink caller) {
+            mControllerStub.stop(packageName, caller);
+        }
+
+        @Override
+        public void next(String packageName, ControllerCallbackLink caller) {
+            mControllerStub.next(packageName, caller);
+        }
+
+        @Override
+        public void previous(String packageName, ControllerCallbackLink caller) {
+            mControllerStub.previous(packageName, caller);
+        }
+
+        @Override
+        public void fastForward(String packageName, ControllerCallbackLink caller) {
+            mControllerStub.fastForward(packageName, caller);
+        }
+
+        @Override
+        public void rewind(String packageName, ControllerCallbackLink caller) {
+            mControllerStub.rewind(packageName, caller);
+        }
+
+        @Override
+        public void seekTo(String packageName, ControllerCallbackLink caller, long pos) {
+            mControllerStub.seekTo(packageName, caller, pos);
+        }
+
+        @Override
+        public void rate(String packageName, ControllerCallbackLink caller, Rating rating) {
+            mControllerStub.rate(packageName, caller, rating);
+        }
+
+        @Override
+        public void sendCustomAction(String packageName, ControllerCallbackLink caller,
+                String action, Bundle args) {
+            mControllerStub.sendCustomAction(packageName, caller, action, args);
+        }
+
+        @Override
+        public MediaMetadata getMetadata() {
+            return mControllerStub.getMetadata();
+        }
+
+        @Override
+        public PlaybackState getPlaybackState() {
+            return mControllerStub.getPlaybackState();
+        }
+
+        @Override
+        public MediaParceledListSlice getQueue() {
+            List<MediaSession.QueueItem> queue = mControllerStub.getQueue();
+            return queue == null ? null : new MediaParceledListSlice(queue);
+        }
+
+        @Override
+        public CharSequence getQueueTitle() {
+            return mControllerStub.getQueueTitle();
+        }
+
+        @Override
+        public Bundle getExtras() {
+            return mControllerStub.getExtras();
+        }
+
+        @Override
+        public int getRatingType() {
+            return mControllerStub.getRatingType();
+        }
+    }
+}
diff --git a/media/java/android/media/session/ISession.aidl b/media/java/android/media/session/ISession.aidl
index 1524ad9..9b1ad7b 100644
--- a/media/java/android/media/session/ISession.aidl
+++ b/media/java/android/media/session/ISession.aidl
@@ -18,7 +18,8 @@
 import android.app.PendingIntent;
 import android.media.AudioAttributes;
 import android.media.MediaMetadata;
-import android.media.session.ISessionController;
+import android.media.MediaParceledListSlice;
+import android.media.session.ControllerLink;
 import android.media.session.PlaybackState;
 import android.media.session.MediaSession;
 import android.os.Bundle;
@@ -30,18 +31,17 @@
  */
 interface ISession {
     void sendEvent(String event, in Bundle data);
-    ISessionController getController();
+    ControllerLink getController();
     void setFlags(int flags);
     void setActive(boolean active);
     void setMediaButtonReceiver(in PendingIntent mbr);
     void setLaunchPendingIntent(in PendingIntent pi);
-    void destroy();
+    void destroySession();
 
     // These commands are for the TransportPerformer
     void setMetadata(in MediaMetadata metadata, long duration, String metadataDescription);
     void setPlaybackState(in PlaybackState state);
-    // TODO(b/122432476): Replace List with MediaParceledListSlice
-    void setQueue(in List<MediaSession.QueueItem> queue);
+    void setQueue(in MediaParceledListSlice queue);
     void setQueueTitle(CharSequence title);
     void setExtras(in Bundle extras);
     void setRatingType(int type);
diff --git a/media/java/android/media/session/ISessionController.aidl b/media/java/android/media/session/ISessionController.aidl
index 2ba09fd..a3439a1a 100644
--- a/media/java/android/media/session/ISessionController.aidl
+++ b/media/java/android/media/session/ISessionController.aidl
@@ -18,6 +18,7 @@
 import android.app.PendingIntent;
 import android.content.Intent;
 import android.media.MediaMetadata;
+import android.media.MediaParceledListSlice;
 import android.media.Rating;
 import android.media.session.ControllerCallbackLink;
 import android.media.session.MediaController;
@@ -39,9 +40,8 @@
             String command, in Bundle args, in ResultReceiver cb);
     boolean sendMediaButton(String packageName, in ControllerCallbackLink caller,
             boolean asSystemService, in KeyEvent mediaButton);
-    void registerCallbackListener(String packageName, in ControllerCallbackLink cb);
-    void unregisterCallbackListener(in ControllerCallbackLink cb);
-    boolean isTransportControlEnabled();
+    void registerCallback(String packageName, in ControllerCallbackLink cb);
+    void unregisterCallback(in ControllerCallbackLink cb);
     String getPackageName();
     String getTag();
     PendingIntent getLaunchPendingIntent();
@@ -81,7 +81,7 @@
             String action, in Bundle args);
     MediaMetadata getMetadata();
     PlaybackState getPlaybackState();
-    List<MediaSession.QueueItem> getQueue();
+    MediaParceledListSlice getQueue();
     CharSequence getQueueTitle();
     Bundle getExtras();
     int getRatingType();
diff --git a/media/java/android/media/session/ISessionManager.aidl b/media/java/android/media/session/ISessionManager.aidl
index 46516e0..ed16250 100644
--- a/media/java/android/media/session/ISessionManager.aidl
+++ b/media/java/android/media/session/ISessionManager.aidl
@@ -18,13 +18,14 @@
 import android.content.ComponentName;
 import android.media.IRemoteVolumeController;
 import android.media.Session2Token;
+import android.media.session.ControllerLink;
 import android.media.session.IActiveSessionsListener;
 import android.media.session.ICallback;
 import android.media.session.IOnMediaKeyListener;
 import android.media.session.IOnVolumeKeyLongPressListener;
-import android.media.session.ISession;
 import android.media.session.ISession2TokensListener;
 import android.media.session.SessionCallbackLink;
+import android.media.session.SessionLink;
 import android.os.Bundle;
 import android.view.KeyEvent;
 
@@ -33,9 +34,10 @@
  * @hide
  */
 interface ISessionManager {
-    ISession createSession(String packageName, in SessionCallbackLink cb, String tag, int userId);
+    SessionLink createSession(String packageName, in SessionCallbackLink sessionCb, String tag,
+            int userId);
     void notifySession2Created(in Session2Token sessionToken);
-    List<IBinder> getSessions(in ComponentName compName, int userId);
+    List<ControllerLink> getSessions(in ComponentName compName, int userId);
     List<Session2Token> getSession2Tokens(int userId);
     void dispatchMediaKeyEvent(String packageName, boolean asSystemService, in KeyEvent keyEvent,
             boolean needWakeLock);
diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java
index a1b8170c..9d537c8 100644
--- a/media/java/android/media/session/MediaController.java
+++ b/media/java/android/media/session/MediaController.java
@@ -34,7 +34,6 @@
 import android.os.Message;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.text.TextUtils;
 import android.util.Log;
@@ -68,12 +67,11 @@
     private static final int MSG_UPDATE_EXTRAS = 7;
     private static final int MSG_DESTROYED = 8;
 
-    private final ISessionController mSessionBinder;
+    private final ControllerLink mSessionBinder;
 
     private final MediaSession.Token mToken;
     private final Context mContext;
-    private final ControllerCallbackLink mCbStub =
-            new ControllerCallbackLink(new CallbackStub(this));
+    private final ControllerCallbackLink mCbStub;
     private final ArrayList<MessageHandler> mCallbacks = new ArrayList<MessageHandler>();
     private final Object mLock = new Object();
 
@@ -84,12 +82,11 @@
     private final TransportControls mTransportControls;
 
     /**
-     * Call for creating a MediaController directly from a binder. Should only
+     * Call for creating a MediaController directly from a controller link. Should only
      * be used by framework code.
-     *
      * @hide
      */
-    public MediaController(Context context, ISessionController sessionBinder) {
+    public MediaController(Context context, ControllerLink sessionBinder) {
         if (sessionBinder == null) {
             throw new IllegalArgumentException("Session token cannot be null");
         }
@@ -100,6 +97,17 @@
         mTransportControls = new TransportControls();
         mToken = new MediaSession.Token(sessionBinder);
         mContext = context;
+        mCbStub = new ControllerCallbackLink(context, new CallbackStub(this));
+    }
+
+    /**
+     * Call for creating a MediaController directly from a binder. Should only
+     * be used by framework code.
+     * @hide
+     * TODO: remove this constructor
+     */
+    public MediaController(Context context, ISessionController sessionBinder) {
+        this(context, new ControllerLink(sessionBinder.asBinder()));
     }
 
     /**
@@ -158,7 +166,7 @@
         try {
             return mSessionBinder.sendMediaButton(mContext.getPackageName(), mCbStub,
                     asSystemService, keyEvent);
-        } catch (RemoteException e) {
+        } catch (RuntimeException e) {
             // System is dead. =(
         }
         return false;
@@ -195,7 +203,7 @@
                     mSessionBinder.adjustVolume(mContext.getPackageName(),
                             mContext.getOpPackageName(), mCbStub, true, direction,
                             AudioManager.FLAG_SHOW_UI);
-                } catch (RemoteException e) {
+                } catch (RuntimeException e) {
                     Log.wtf(TAG, "Error calling adjustVolumeBy", e);
                 }
             }
@@ -209,7 +217,7 @@
                     //       AppOpsManager usages.
                     mSessionBinder.adjustVolume(mContext.getPackageName(),
                             mContext.getOpPackageName(), mCbStub, true, 0, flags);
-                } catch (RemoteException e) {
+                } catch (RuntimeException e) {
                     Log.wtf(TAG, "Error calling adjustVolumeBy", e);
                 }
             }
@@ -224,7 +232,7 @@
     public @Nullable PlaybackState getPlaybackState() {
         try {
             return mSessionBinder.getPlaybackState();
-        } catch (RemoteException e) {
+        } catch (RuntimeException e) {
             Log.wtf(TAG, "Error calling getPlaybackState.", e);
             return null;
         }
@@ -238,7 +246,7 @@
     public @Nullable MediaMetadata getMetadata() {
         try {
             return mSessionBinder.getMetadata();
-        } catch (RemoteException e) {
+        } catch (RuntimeException e) {
             Log.wtf(TAG, "Error calling getMetadata.", e);
             return null;
         }
@@ -253,7 +261,7 @@
     public @Nullable List<MediaSession.QueueItem> getQueue() {
         try {
             return mSessionBinder.getQueue();
-        } catch (RemoteException e) {
+        } catch (RuntimeException e) {
             Log.wtf(TAG, "Error calling getQueue.", e);
         }
         return null;
@@ -265,7 +273,7 @@
     public @Nullable CharSequence getQueueTitle() {
         try {
             return mSessionBinder.getQueueTitle();
-        } catch (RemoteException e) {
+        } catch (RuntimeException e) {
             Log.wtf(TAG, "Error calling getQueueTitle", e);
         }
         return null;
@@ -277,7 +285,7 @@
     public @Nullable Bundle getExtras() {
         try {
             return mSessionBinder.getExtras();
-        } catch (RemoteException e) {
+        } catch (RuntimeException e) {
             Log.wtf(TAG, "Error calling getExtras", e);
         }
         return null;
@@ -300,7 +308,7 @@
     public int getRatingType() {
         try {
             return mSessionBinder.getRatingType();
-        } catch (RemoteException e) {
+        } catch (RuntimeException e) {
             Log.wtf(TAG, "Error calling getRatingType.", e);
             return Rating.RATING_NONE;
         }
@@ -314,7 +322,7 @@
     public @MediaSession.SessionFlags long getFlags() {
         try {
             return mSessionBinder.getFlags();
-        } catch (RemoteException e) {
+        } catch (RuntimeException e) {
             Log.wtf(TAG, "Error calling getFlags.", e);
         }
         return 0;
@@ -328,7 +336,7 @@
     public @Nullable PlaybackInfo getPlaybackInfo() {
         try {
             return mSessionBinder.getVolumeAttributes();
-        } catch (RemoteException e) {
+        } catch (RuntimeException e) {
             Log.wtf(TAG, "Error calling getAudioInfo.", e);
         }
         return null;
@@ -343,7 +351,7 @@
     public @Nullable PendingIntent getSessionActivity() {
         try {
             return mSessionBinder.getLaunchPendingIntent();
-        } catch (RemoteException e) {
+        } catch (RuntimeException e) {
             Log.wtf(TAG, "Error calling getPendingIntent.", e);
         }
         return null;
@@ -376,7 +384,7 @@
             //       AppOpsManager usages.
             mSessionBinder.setVolumeTo(mContext.getPackageName(), mContext.getOpPackageName(),
                     mCbStub, value, flags);
-        } catch (RemoteException e) {
+        } catch (RuntimeException e) {
             Log.wtf(TAG, "Error calling setVolumeTo.", e);
         }
     }
@@ -401,7 +409,7 @@
             //       AppOpsManager usages.
             mSessionBinder.adjustVolume(mContext.getPackageName(), mContext.getOpPackageName(),
                     mCbStub, false, direction, flags);
-        } catch (RemoteException e) {
+        } catch (RuntimeException e) {
             Log.wtf(TAG, "Error calling adjustVolumeBy.", e);
         }
     }
@@ -467,7 +475,7 @@
         }
         try {
             mSessionBinder.sendCommand(mContext.getPackageName(), mCbStub, command, args, cb);
-        } catch (RemoteException e) {
+        } catch (RuntimeException e) {
             Log.d(TAG, "Dead object in sendCommand.", e);
         }
     }
@@ -481,7 +489,7 @@
         if (mPackageName == null) {
             try {
                 mPackageName = mSessionBinder.getPackageName();
-            } catch (RemoteException e) {
+            } catch (RuntimeException e) {
                 Log.d(TAG, "Dead object in getPackageName.", e);
             }
         }
@@ -498,7 +506,7 @@
         if (mTag == null) {
             try {
                 mTag = mSessionBinder.getTag();
-            } catch (RemoteException e) {
+            } catch (RuntimeException e) {
                 Log.d(TAG, "Dead object in getTag.", e);
             }
         }
@@ -508,7 +516,7 @@
     /*
      * @hide
      */
-    ISessionController getSessionBinder() {
+    ControllerLink getSessionBinder() {
         return mSessionBinder;
     }
 
@@ -518,7 +526,7 @@
     @UnsupportedAppUsage
     public boolean controlsSameSession(MediaController other) {
         if (other == null) return false;
-        return mSessionBinder.asBinder() == other.getSessionBinder().asBinder();
+        return mSessionBinder.getBinder() == other.getSessionBinder().getBinder();
     }
 
     private void addCallbackLocked(Callback cb, Handler handler) {
@@ -532,9 +540,9 @@
 
         if (!mCbRegistered) {
             try {
-                mSessionBinder.registerCallbackListener(mContext.getPackageName(), mCbStub);
+                mSessionBinder.registerCallback(mContext.getPackageName(), mCbStub);
                 mCbRegistered = true;
-            } catch (RemoteException e) {
+            } catch (RuntimeException e) {
                 Log.e(TAG, "Dead object in registerCallback", e);
             }
         }
@@ -552,8 +560,8 @@
         }
         if (mCbRegistered && mCallbacks.size() == 0) {
             try {
-                mSessionBinder.unregisterCallbackListener(mCbStub);
-            } catch (RemoteException e) {
+                mSessionBinder.unregisterCallback(mCbStub);
+            } catch (RuntimeException e) {
                 Log.e(TAG, "Dead object in removeCallbackLocked");
             }
             mCbRegistered = false;
@@ -680,7 +688,7 @@
         public void prepare() {
             try {
                 mSessionBinder.prepare(mContext.getPackageName(), mCbStub);
-            } catch (RemoteException e) {
+            } catch (RuntimeException e) {
                 Log.wtf(TAG, "Error calling prepare.", e);
             }
         }
@@ -705,7 +713,7 @@
             try {
                 mSessionBinder.prepareFromMediaId(mContext.getPackageName(), mCbStub, mediaId,
                         extras);
-            } catch (RemoteException e) {
+            } catch (RuntimeException e) {
                 Log.wtf(TAG, "Error calling prepare(" + mediaId + ").", e);
             }
         }
@@ -732,7 +740,7 @@
             try {
                 mSessionBinder.prepareFromSearch(mContext.getPackageName(), mCbStub, query,
                         extras);
-            } catch (RemoteException e) {
+            } catch (RuntimeException e) {
                 Log.wtf(TAG, "Error calling prepare(" + query + ").", e);
             }
         }
@@ -756,7 +764,7 @@
             }
             try {
                 mSessionBinder.prepareFromUri(mContext.getPackageName(), mCbStub, uri, extras);
-            } catch (RemoteException e) {
+            } catch (RuntimeException e) {
                 Log.wtf(TAG, "Error calling prepare(" + uri + ").", e);
             }
         }
@@ -767,7 +775,7 @@
         public void play() {
             try {
                 mSessionBinder.play(mContext.getPackageName(), mCbStub);
-            } catch (RemoteException e) {
+            } catch (RuntimeException e) {
                 Log.wtf(TAG, "Error calling play.", e);
             }
         }
@@ -787,7 +795,7 @@
             try {
                 mSessionBinder.playFromMediaId(mContext.getPackageName(), mCbStub, mediaId,
                         extras);
-            } catch (RemoteException e) {
+            } catch (RuntimeException e) {
                 Log.wtf(TAG, "Error calling play(" + mediaId + ").", e);
             }
         }
@@ -809,7 +817,7 @@
             }
             try {
                 mSessionBinder.playFromSearch(mContext.getPackageName(), mCbStub, query, extras);
-            } catch (RemoteException e) {
+            } catch (RuntimeException e) {
                 Log.wtf(TAG, "Error calling play(" + query + ").", e);
             }
         }
@@ -828,7 +836,7 @@
             }
             try {
                 mSessionBinder.playFromUri(mContext.getPackageName(), mCbStub, uri, extras);
-            } catch (RemoteException e) {
+            } catch (RuntimeException e) {
                 Log.wtf(TAG, "Error calling play(" + uri + ").", e);
             }
         }
@@ -840,7 +848,7 @@
         public void skipToQueueItem(long id) {
             try {
                 mSessionBinder.skipToQueueItem(mContext.getPackageName(), mCbStub, id);
-            } catch (RemoteException e) {
+            } catch (RuntimeException e) {
                 Log.wtf(TAG, "Error calling skipToItem(" + id + ").", e);
             }
         }
@@ -852,7 +860,7 @@
         public void pause() {
             try {
                 mSessionBinder.pause(mContext.getPackageName(), mCbStub);
-            } catch (RemoteException e) {
+            } catch (RuntimeException e) {
                 Log.wtf(TAG, "Error calling pause.", e);
             }
         }
@@ -864,7 +872,7 @@
         public void stop() {
             try {
                 mSessionBinder.stop(mContext.getPackageName(), mCbStub);
-            } catch (RemoteException e) {
+            } catch (RuntimeException e) {
                 Log.wtf(TAG, "Error calling stop.", e);
             }
         }
@@ -877,7 +885,7 @@
         public void seekTo(long pos) {
             try {
                 mSessionBinder.seekTo(mContext.getPackageName(), mCbStub, pos);
-            } catch (RemoteException e) {
+            } catch (RuntimeException e) {
                 Log.wtf(TAG, "Error calling seekTo.", e);
             }
         }
@@ -889,7 +897,7 @@
         public void fastForward() {
             try {
                 mSessionBinder.fastForward(mContext.getPackageName(), mCbStub);
-            } catch (RemoteException e) {
+            } catch (RuntimeException e) {
                 Log.wtf(TAG, "Error calling fastForward.", e);
             }
         }
@@ -900,7 +908,7 @@
         public void skipToNext() {
             try {
                 mSessionBinder.next(mContext.getPackageName(), mCbStub);
-            } catch (RemoteException e) {
+            } catch (RuntimeException e) {
                 Log.wtf(TAG, "Error calling next.", e);
             }
         }
@@ -912,7 +920,7 @@
         public void rewind() {
             try {
                 mSessionBinder.rewind(mContext.getPackageName(), mCbStub);
-            } catch (RemoteException e) {
+            } catch (RuntimeException e) {
                 Log.wtf(TAG, "Error calling rewind.", e);
             }
         }
@@ -923,7 +931,7 @@
         public void skipToPrevious() {
             try {
                 mSessionBinder.previous(mContext.getPackageName(), mCbStub);
-            } catch (RemoteException e) {
+            } catch (RuntimeException e) {
                 Log.wtf(TAG, "Error calling previous.", e);
             }
         }
@@ -938,7 +946,7 @@
         public void setRating(Rating rating) {
             try {
                 mSessionBinder.rate(mContext.getPackageName(), mCbStub, rating);
-            } catch (RemoteException e) {
+            } catch (RuntimeException e) {
                 Log.wtf(TAG, "Error calling rate.", e);
             }
         }
@@ -973,7 +981,7 @@
             }
             try {
                 mSessionBinder.sendCustomAction(mContext.getPackageName(), mCbStub, action, args);
-            } catch (RemoteException e) {
+            } catch (RuntimeException e) {
                 Log.d(TAG, "Dead object in sendCustomAction.", e);
             }
         }
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index e07cf15..f02d9ba 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -37,9 +37,7 @@
 import android.os.Message;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.RemoteException;
 import android.os.ResultReceiver;
-import android.os.UserHandle;
 import android.service.media.MediaBrowserService;
 import android.text.TextUtils;
 import android.util.Log;
@@ -128,7 +126,7 @@
 
     private final MediaSession.Token mSessionToken;
     private final MediaController mController;
-    private final ISession mBinder;
+    private final SessionLink mSessionLink;
     private final SessionCallbackLink mCbStub;
 
     // Do not change the name of mCallback. Support lib accesses this by using reflection.
@@ -149,21 +147,6 @@
      * @param tag A short name for debugging purposes.
      */
     public MediaSession(@NonNull Context context, @NonNull String tag) {
-        this(context, tag, UserHandle.myUserId());
-    }
-
-    /**
-     * Creates a new session as the specified user. To create a session as a
-     * user other than your own you must hold the
-     * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL}
-     * permission.
-     *
-     * @param context The context to use to create the session.
-     * @param tag A short name for debugging purposes.
-     * @param userId The user id to create the session as.
-     * @hide
-     */
-    public MediaSession(@NonNull Context context, @NonNull String tag, int userId) {
         if (context == null) {
             throw new IllegalArgumentException("context cannot be null.");
         }
@@ -171,15 +154,15 @@
             throw new IllegalArgumentException("tag cannot be null or empty");
         }
         mMaxBitmapSize = context.getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.config_mediaMetadataBitmapMaxSize);
-        mCbStub = new SessionCallbackLink(new CallbackStub(this));
+                android.R.dimen.config_mediaMetadataBitmapMaxSize);
+        mCbStub = new SessionCallbackLink(context, new CallbackStub(this));
         MediaSessionManager manager = (MediaSessionManager) context
                 .getSystemService(Context.MEDIA_SESSION_SERVICE);
         try {
-            mBinder = manager.createSession(mCbStub, tag, userId);
-            mSessionToken = new Token(mBinder.getController());
+            mSessionLink = manager.createSession(mCbStub, tag);
+            mSessionToken = new Token(mSessionLink.getController());
             mController = new MediaController(context, mSessionToken);
-        } catch (RemoteException e) {
+        } catch (RuntimeException e) {
             throw new RuntimeException("Remote error creating session.", e);
         }
     }
@@ -236,8 +219,8 @@
      */
     public void setSessionActivity(@Nullable PendingIntent pi) {
         try {
-            mBinder.setLaunchPendingIntent(pi);
-        } catch (RemoteException e) {
+            mSessionLink.setLaunchPendingIntent(pi);
+        } catch (RuntimeException e) {
             Log.wtf(TAG, "Failure in setLaunchPendingIntent.", e);
         }
     }
@@ -252,8 +235,8 @@
      */
     public void setMediaButtonReceiver(@Nullable PendingIntent mbr) {
         try {
-            mBinder.setMediaButtonReceiver(mbr);
-        } catch (RemoteException e) {
+            mSessionLink.setMediaButtonReceiver(mbr);
+        } catch (RuntimeException e) {
             Log.wtf(TAG, "Failure in setMediaButtonReceiver.", e);
         }
     }
@@ -265,8 +248,8 @@
      */
     public void setFlags(@SessionFlags int flags) {
         try {
-            mBinder.setFlags(flags);
-        } catch (RemoteException e) {
+            mSessionLink.setFlags(flags);
+        } catch (RuntimeException e) {
             Log.wtf(TAG, "Failure in setFlags.", e);
         }
     }
@@ -287,8 +270,8 @@
             throw new IllegalArgumentException("Attributes cannot be null for local playback.");
         }
         try {
-            mBinder.setPlaybackToLocal(attributes);
-        } catch (RemoteException e) {
+            mSessionLink.setPlaybackToLocal(attributes);
+        } catch (RuntimeException e) {
             Log.wtf(TAG, "Failure in setPlaybackToLocal.", e);
         }
     }
@@ -319,10 +302,10 @@
         });
 
         try {
-            mBinder.setPlaybackToRemote(volumeProvider.getVolumeControl(),
+            mSessionLink.setPlaybackToRemote(volumeProvider.getVolumeControl(),
                     volumeProvider.getMaxVolume());
-            mBinder.setCurrentVolume(volumeProvider.getCurrentVolume());
-        } catch (RemoteException e) {
+            mSessionLink.setCurrentVolume(volumeProvider.getCurrentVolume());
+        } catch (RuntimeException e) {
             Log.wtf(TAG, "Failure in setPlaybackToRemote.", e);
         }
     }
@@ -340,9 +323,9 @@
             return;
         }
         try {
-            mBinder.setActive(active);
+            mSessionLink.setActive(active);
             mActive = active;
-        } catch (RemoteException e) {
+        } catch (RuntimeException e) {
             Log.wtf(TAG, "Failure in setActive.", e);
         }
     }
@@ -369,8 +352,8 @@
             throw new IllegalArgumentException("event cannot be null or empty");
         }
         try {
-            mBinder.sendEvent(event, extras);
-        } catch (RemoteException e) {
+            mSessionLink.sendEvent(event, extras);
+        } catch (RuntimeException e) {
             Log.wtf(TAG, "Error sending event", e);
         }
     }
@@ -382,8 +365,8 @@
      */
     public void release() {
         try {
-            mBinder.destroy();
-        } catch (RemoteException e) {
+            mSessionLink.destroySession();
+        } catch (RuntimeException e) {
             Log.wtf(TAG, "Error releasing session: ", e);
         }
     }
@@ -418,8 +401,8 @@
     public void setPlaybackState(@Nullable PlaybackState state) {
         mPlaybackState = state;
         try {
-            mBinder.setPlaybackState(state);
-        } catch (RemoteException e) {
+            mSessionLink.setPlaybackState(state);
+        } catch (RuntimeException e) {
             Log.wtf(TAG, "Dead object in setPlaybackState.", e);
         }
     }
@@ -447,8 +430,8 @@
         String metadataDescription = "size=" + fields + ", description=" + description;
 
         try {
-            mBinder.setMetadata(metadata, duration, metadataDescription);
-        } catch (RemoteException e) {
+            mSessionLink.setMetadata(metadata, duration, metadataDescription);
+        } catch (RuntimeException e) {
             Log.wtf(TAG, "Dead object in setPlaybackState.", e);
         }
     }
@@ -466,8 +449,8 @@
      */
     public void setQueue(@Nullable List<QueueItem> queue) {
         try {
-            mBinder.setQueue(queue);
-        } catch (RemoteException e) {
+            mSessionLink.setQueue(queue);
+        } catch (RuntimeException e) {
             Log.wtf("Dead object in setQueue.", e);
         }
     }
@@ -481,8 +464,8 @@
      */
     public void setQueueTitle(@Nullable CharSequence title) {
         try {
-            mBinder.setQueueTitle(title);
-        } catch (RemoteException e) {
+            mSessionLink.setQueueTitle(title);
+        } catch (RuntimeException e) {
             Log.wtf("Dead object in setQueueTitle.", e);
         }
     }
@@ -502,8 +485,8 @@
      */
     public void setRatingType(@Rating.Style int type) {
         try {
-            mBinder.setRatingType(type);
-        } catch (RemoteException e) {
+            mSessionLink.setRatingType(type);
+        } catch (RuntimeException e) {
             Log.e(TAG, "Error in setRatingType.", e);
         }
     }
@@ -517,8 +500,8 @@
      */
     public void setExtras(@Nullable Bundle extras) {
         try {
-            mBinder.setExtras(extras);
-        } catch (RemoteException e) {
+            mSessionLink.setExtras(extras);
+        } catch (RuntimeException e) {
             Log.wtf("Dead object in setExtras.", e);
         }
     }
@@ -553,8 +536,8 @@
             }
         }
         try {
-            mBinder.setCurrentVolume(provider.getCurrentVolume());
-        } catch (RemoteException e) {
+            mSessionLink.setCurrentVolume(provider.getCurrentVolume());
+        } catch (RuntimeException e) {
             Log.e(TAG, "Error in notifyVolumeChanged", e);
         }
     }
@@ -709,12 +692,12 @@
      */
     public static final class Token implements Parcelable {
 
-        private ISessionController mBinder;
+        private ControllerLink mBinder;
 
         /**
          * @hide
          */
-        public Token(ISessionController binder) {
+        public Token(ControllerLink binder) {
             mBinder = binder;
         }
 
@@ -725,14 +708,14 @@
 
         @Override
         public void writeToParcel(Parcel dest, int flags) {
-            dest.writeStrongBinder(mBinder.asBinder());
+            dest.writeParcelable(mBinder, flags);
         }
 
         @Override
         public int hashCode() {
             final int prime = 31;
             int result = 1;
-            result = prime * result + ((mBinder == null) ? 0 : mBinder.asBinder().hashCode());
+            result = prime * result + ((mBinder == null) ? 0 : mBinder.getBinder().hashCode());
             return result;
         }
 
@@ -748,20 +731,22 @@
             if (mBinder == null) {
                 if (other.mBinder != null)
                     return false;
-            } else if (!mBinder.asBinder().equals(other.mBinder.asBinder()))
+            } else if (!mBinder.getBinder().equals(other.mBinder.getBinder())) {
                 return false;
+            }
             return true;
         }
 
-        ISessionController getBinder() {
+        ControllerLink getBinder() {
             return mBinder;
         }
 
-        public static final Parcelable.Creator<Token> CREATOR
-                = new Parcelable.Creator<Token>() {
+        public static final Parcelable.Creator<Token> CREATOR =
+                new Parcelable.Creator<Token>() {
             @Override
             public Token createFromParcel(Parcel in) {
-                return new Token(ISessionController.Stub.asInterface(in.readStrongBinder()));
+                ControllerLink link = in.readParcelable(null);
+                return new Token(link);
             }
 
             @Override
diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java
index 4596c22..77e758fc 100644
--- a/media/java/android/media/session/MediaSessionManager.java
+++ b/media/java/android/media/session/MediaSessionManager.java
@@ -104,9 +104,14 @@
      * @return The binder object from the system
      * @hide
      */
-    public @NonNull ISession createSession(@NonNull SessionCallbackLink cbStub,
-            @NonNull String tag, int userId) throws RemoteException {
-        return mService.createSession(mContext.getPackageName(), cbStub, tag, userId);
+    @NonNull
+    public SessionLink createSession(@NonNull SessionCallbackLink cbStub, @NonNull String tag) {
+        try {
+            return mService.createSession(mContext.getPackageName(), cbStub, tag,
+                    UserHandle.myUserId());
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
     }
 
     /**
@@ -171,11 +176,10 @@
             @Nullable ComponentName notificationListener, int userId) {
         ArrayList<MediaController> controllers = new ArrayList<MediaController>();
         try {
-            List<IBinder> binders = mService.getSessions(notificationListener, userId);
+            List<ControllerLink> binders = mService.getSessions(notificationListener, userId);
             int size = binders.size();
             for (int i = 0; i < size; i++) {
-                MediaController controller = new MediaController(mContext, ISessionController.Stub
-                        .asInterface(binders.get(i)));
+                MediaController controller = new MediaController(mContext, binders.get(i));
                 controllers.add(controller);
             }
         } catch (RemoteException e) {
diff --git a/media/java/android/media/session/PlaybackState.java b/media/java/android/media/session/PlaybackState.java
index 17d16b8..2c57d1f 100644
--- a/media/java/android/media/session/PlaybackState.java
+++ b/media/java/android/media/session/PlaybackState.java
@@ -25,11 +25,11 @@
 import android.os.Parcelable;
 import android.os.SystemClock;
 import android.text.TextUtils;
-import java.util.ArrayList;
-import java.util.List;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Playback state for a {@link MediaSession}. This includes a state like
@@ -318,7 +318,7 @@
         mActions = in.readLong();
         mCustomActions = in.createTypedArrayList(CustomAction.CREATOR);
         mActiveItemId = in.readLong();
-        mErrorMessage = in.readCharSequence();
+        mErrorMessage = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
         mExtras = in.readBundle();
     }
 
@@ -353,7 +353,7 @@
         dest.writeLong(mActions);
         dest.writeTypedList(mCustomActions);
         dest.writeLong(mActiveItemId);
-        dest.writeCharSequence(mErrorMessage);
+        TextUtils.writeToParcel(mErrorMessage, dest, 0);
         dest.writeBundle(mExtras);
     }
 
diff --git a/media/java/android/media/session/SessionCallbackLink.java b/media/java/android/media/session/SessionCallbackLink.java
index 7547bff..0265687b 100644
--- a/media/java/android/media/session/SessionCallbackLink.java
+++ b/media/java/android/media/session/SessionCallbackLink.java
@@ -16,31 +16,40 @@
 
 package android.media.session;
 
+import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.media.Rating;
 import android.net.Uri;
+import android.os.Binder;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
 
 /**
  * Handles incoming commands to {@link MediaSession.Callback}.
- * <p>
- * This API is not generally intended for third party application developers.
+ * @hide
  */
+@SystemApi
 public final class SessionCallbackLink implements Parcelable {
+    final Context mContext;
     final CallbackStub mCallbackStub;
     final ISessionCallback mISessionCallback;
 
     /**
      * Constructor for stub (Callee)
      */
-    SessionCallbackLink(@NonNull CallbackStub callbackStub) {
+    SessionCallbackLink(@NonNull Context context, @NonNull CallbackStub callbackStub) {
+        mContext = context;
         mCallbackStub = callbackStub;
         mISessionCallback = new CallbackStubProxy();
     }
@@ -48,9 +57,10 @@
     /**
      * Constructor for interface (Caller)
      */
-    SessionCallbackLink(Parcel in) {
+    public SessionCallbackLink(IBinder binder) {
+        mContext = null;
         mCallbackStub = null;
-        mISessionCallback = ISessionCallback.Stub.asInterface(in.readStrongBinder());
+        mISessionCallback = ISessionCallback.Stub.asInterface(binder);
     }
 
     /**
@@ -64,6 +74,7 @@
      * @param args the arguments included with the command
      * @param cb the result receiver for getting the result of the command
      */
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
     public void notifyCommand(@NonNull String packageName, int pid, int uid,
             @NonNull ControllerCallbackLink caller, @NonNull String command,
             @Nullable Bundle args, @Nullable ResultReceiver cb) {
@@ -84,6 +95,7 @@
      * @param sequenceNumber the sequence number of this call
      * @param cb the result receiver for getting the result of the command
      */
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
     public void notifyMediaButton(@NonNull String packageName, int pid, int uid,
             @NonNull Intent mediaButtonIntent, int sequenceNumber,
             @Nullable ResultReceiver cb) {
@@ -104,6 +116,7 @@
      * @param caller the {@link ControllerCallbackLink} of the controller
      * @param mediaButtonIntent the media button intent
      */
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
     public void notifyMediaButtonFromController(@NonNull String packageName, int pid, int uid,
             @NonNull ControllerCallbackLink caller, @NonNull Intent mediaButtonIntent) {
         try {
@@ -122,6 +135,7 @@
      * @param uid the uid of the controller
      * @param caller the {@link ControllerCallbackLink} of the controller
      */
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
     public void notifyPrepare(@NonNull String packageName, int pid, int uid,
             @NonNull ControllerCallbackLink caller) {
         try {
@@ -141,6 +155,7 @@
      * @param mediaId the ID of the media
      * @param extras the extras included with this request.
      */
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
     public void notifyPrepareFromMediaId(@NonNull String packageName, int pid, int uid,
             @NonNull ControllerCallbackLink caller, @NonNull String mediaId,
             @Nullable Bundle extras) {
@@ -162,6 +177,7 @@
      * @param query the search query
      * @param extras the extras included with this request.
      */
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
     public void notifyPrepareFromSearch(@NonNull String packageName, int pid, int uid,
             @NonNull ControllerCallbackLink caller, @NonNull String query,
             @Nullable Bundle extras) {
@@ -182,6 +198,7 @@
      * @param uri the uri of the media
      * @param extras the extras included with this request.
      */
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
     public void notifyPrepareFromUri(@NonNull String packageName, int pid, int uid,
             @NonNull ControllerCallbackLink caller, @NonNull Uri uri, @Nullable Bundle extras) {
         try {
@@ -199,6 +216,7 @@
      * @param uid the uid of the controller
      * @param caller the {@link ControllerCallbackLink} of the controller
      */
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
     public void notifyPlay(@NonNull String packageName, int pid, int uid,
             @NonNull ControllerCallbackLink caller) {
         try {
@@ -218,6 +236,7 @@
      * @param mediaId the ID of the media
      * @param extras the extras included with this request.
      */
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
     public void notifyPlayFromMediaId(@NonNull String packageName, int pid, int uid,
             @NonNull ControllerCallbackLink caller, @NonNull String mediaId,
             @Nullable Bundle extras) {
@@ -238,6 +257,7 @@
      * @param query the search query
      * @param extras the extras included with this request.
      */
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
     public void notifyPlayFromSearch(@NonNull String packageName, int pid, int uid,
             @NonNull ControllerCallbackLink caller, @NonNull String query,
             @Nullable Bundle extras) {
@@ -258,6 +278,7 @@
      * @param uri the uri of the media
      * @param extras the extras included with this request.
      */
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
     public void notifyPlayFromUri(@NonNull String packageName, int pid, int uid,
             @NonNull ControllerCallbackLink caller, @NonNull Uri uri, @Nullable Bundle extras) {
         try {
@@ -276,6 +297,7 @@
      * @param caller the {@link ControllerCallbackLink} of the controller
      * @param id the queue id of the item
      */
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
     public void notifySkipToTrack(@NonNull String packageName, int pid, int uid,
             @NonNull ControllerCallbackLink caller, long id) {
         try {
@@ -293,6 +315,7 @@
      * @param uid the uid of the controller
      * @param caller the {@link ControllerCallbackLink} of the controller
      */
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
     public void notifyPause(@NonNull String packageName, int pid, int uid,
             @NonNull ControllerCallbackLink caller) {
         try {
@@ -310,6 +333,7 @@
      * @param uid the uid of the controller
      * @param caller the {@link ControllerCallbackLink} of the controller
      */
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
     public void notifyStop(@NonNull String packageName, int pid, int uid,
             @NonNull ControllerCallbackLink caller) {
         try {
@@ -327,6 +351,7 @@
      * @param uid the uid of the controller
      * @param caller the {@link ControllerCallbackLink} of the controller
      */
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
     public void notifyNext(@NonNull String packageName, int pid, int uid,
             @NonNull ControllerCallbackLink caller) {
         try {
@@ -344,6 +369,7 @@
      * @param uid the uid of the controller
      * @param caller the {@link ControllerCallbackLink} of the controller
      */
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
     public void notifyPrevious(@NonNull String packageName, int pid, int uid,
             @NonNull ControllerCallbackLink caller) {
         try {
@@ -361,6 +387,7 @@
      * @param uid the uid of the controller
      * @param caller the {@link ControllerCallbackLink} of the controller
      */
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
     public void notifyFastForward(@NonNull String packageName, int pid, int uid,
             @NonNull ControllerCallbackLink caller) {
         try {
@@ -378,6 +405,7 @@
      * @param uid the uid of the controller
      * @param caller the {@link ControllerCallbackLink} of the controller
      */
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
     public void notifyRewind(@NonNull String packageName, int pid, int uid,
             @NonNull ControllerCallbackLink caller) {
         try {
@@ -396,6 +424,7 @@
      * @param caller the {@link ControllerCallbackLink} of the controller
      * @param pos the position to move to, in milliseconds
      */
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
     public void notifySeekTo(@NonNull String packageName, int pid, int uid,
             @NonNull ControllerCallbackLink caller, long pos) {
         try {
@@ -414,6 +443,7 @@
      * @param caller the {@link ControllerCallbackLink} of the controller
      * @param rating the rating of the current media
      */
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
     public void notifyRate(@NonNull String packageName, int pid, int uid,
             @NonNull ControllerCallbackLink caller, @NonNull Rating rating) {
         try {
@@ -433,6 +463,7 @@
      * @param action the name of the action
      * @param args the arguments included with this action
      */
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
     public void notifyCustomAction(@NonNull String packageName, int pid, int uid,
             @NonNull ControllerCallbackLink caller, @NonNull String action, @Nullable Bundle args) {
         try {
@@ -451,6 +482,7 @@
      * @param caller the {@link ControllerCallbackLink} of the controller
      * @param direction the direction of the volume change.
      */
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
     public void notifyAdjustVolume(@NonNull String packageName, int pid, int uid,
             @NonNull ControllerCallbackLink caller, int direction) {
         try {
@@ -469,6 +501,7 @@
      * @param caller the {@link ControllerCallbackLink} of the controller
      * @param value the volume value to set
      */
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
     public void notifySetVolumeTo(@NonNull String packageName, int pid, int uid,
             @NonNull ControllerCallbackLink caller, int value) {
         try {
@@ -498,7 +531,7 @@
             new Parcelable.Creator<SessionCallbackLink>() {
                 @Override
                 public SessionCallbackLink createFromParcel(Parcel in) {
-                    return new SessionCallbackLink(in);
+                    return new SessionCallbackLink(in.readStrongBinder());
                 }
 
                 @Override
@@ -636,141 +669,296 @@
         @Override
         public void notifyCommand(String packageName, int pid, int uid,
                 ControllerCallbackLink caller, String command, Bundle args, ResultReceiver cb) {
-            mCallbackStub.onCommand(packageName, pid, uid, caller, command, args, cb);
+            ensureMediasControlPermission();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mCallbackStub.onCommand(packageName, pid, uid, caller, command, args, cb);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
 
         @Override
         public void notifyMediaButton(String packageName, int pid, int uid,
                 Intent mediaButtonIntent, int sequenceNumber, ResultReceiver cb) {
-            mCallbackStub.onMediaButton(packageName, pid, uid, mediaButtonIntent, sequenceNumber,
-                    cb);
+            ensureMediasControlPermission();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mCallbackStub.onMediaButton(packageName, pid, uid, mediaButtonIntent,
+                        sequenceNumber, cb);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
 
         @Override
         public void notifyMediaButtonFromController(String packageName, int pid, int uid,
                 ControllerCallbackLink caller, Intent mediaButtonIntent) {
-            mCallbackStub.onMediaButtonFromController(packageName, pid, uid, caller,
-                    mediaButtonIntent);
+            ensureMediasControlPermission();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mCallbackStub.onMediaButtonFromController(packageName, pid, uid, caller,
+                        mediaButtonIntent);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
 
         @Override
         public void notifyPrepare(String packageName, int pid, int uid,
                 ControllerCallbackLink caller) {
-            mCallbackStub.onPrepare(packageName, pid, uid, caller);
+            ensureMediasControlPermission();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mCallbackStub.onPrepare(packageName, pid, uid, caller);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
 
         @Override
         public void notifyPrepareFromMediaId(String packageName, int pid, int uid,
                 ControllerCallbackLink caller, String mediaId, Bundle extras) {
-            mCallbackStub.onPrepareFromMediaId(packageName, pid, uid, caller, mediaId, extras);
+            ensureMediasControlPermission();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mCallbackStub.onPrepareFromMediaId(packageName, pid, uid, caller, mediaId, extras);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
 
         @Override
         public void notifyPrepareFromSearch(String packageName, int pid, int uid,
                 ControllerCallbackLink caller, String query, Bundle extras) {
-            mCallbackStub.onPrepareFromSearch(packageName, pid, uid, caller, query, extras);
+            ensureMediasControlPermission();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mCallbackStub.onPrepareFromSearch(packageName, pid, uid, caller, query, extras);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
 
         @Override
         public void notifyPrepareFromUri(String packageName, int pid, int uid,
                 ControllerCallbackLink caller, Uri uri, Bundle extras) {
-            mCallbackStub.onPrepareFromUri(packageName, pid, uid, caller, uri, extras);
+            ensureMediasControlPermission();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mCallbackStub.onPrepareFromUri(packageName, pid, uid, caller, uri, extras);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
 
         @Override
         public void notifyPlay(String packageName, int pid, int uid,
                 ControllerCallbackLink caller) {
-            mCallbackStub.onPlay(packageName, pid, uid, caller);
+            ensureMediasControlPermission();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mCallbackStub.onPlay(packageName, pid, uid, caller);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
 
         @Override
         public void notifyPlayFromMediaId(String packageName, int pid, int uid,
                 ControllerCallbackLink caller, String mediaId, Bundle extras) {
-            mCallbackStub.onPlayFromMediaId(packageName, pid, uid, caller, mediaId, extras);
+            ensureMediasControlPermission();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mCallbackStub.onPlayFromMediaId(packageName, pid, uid, caller, mediaId, extras);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
 
         @Override
         public void notifyPlayFromSearch(String packageName, int pid, int uid,
                 ControllerCallbackLink caller, String query, Bundle extras) {
-            mCallbackStub.onPlayFromSearch(packageName, pid, uid, caller, query, extras);
+            ensureMediasControlPermission();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mCallbackStub.onPlayFromSearch(packageName, pid, uid, caller, query, extras);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
 
         @Override
         public void notifyPlayFromUri(String packageName, int pid, int uid,
                 ControllerCallbackLink caller, Uri uri, Bundle extras) {
-            mCallbackStub.onPlayFromUri(packageName, pid, uid, caller, uri, extras);
+            ensureMediasControlPermission();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mCallbackStub.onPlayFromUri(packageName, pid, uid, caller, uri, extras);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
 
         @Override
         public void notifySkipToTrack(String packageName, int pid, int uid,
                 ControllerCallbackLink caller, long id) {
-            mCallbackStub.onSkipToTrack(packageName, pid, uid, caller, id);
+            ensureMediasControlPermission();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mCallbackStub.onSkipToTrack(packageName, pid, uid, caller, id);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
 
         @Override
         public void notifyPause(String packageName, int pid, int uid,
                 ControllerCallbackLink caller) {
-            mCallbackStub.onPause(packageName, pid, uid, caller);
+            ensureMediasControlPermission();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mCallbackStub.onPause(packageName, pid, uid, caller);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
 
         @Override
         public void notifyStop(String packageName, int pid, int uid,
                 ControllerCallbackLink caller) {
-            mCallbackStub.onStop(packageName, pid, uid, caller);
+            ensureMediasControlPermission();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mCallbackStub.onStop(packageName, pid, uid, caller);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
 
         @Override
         public void notifyNext(String packageName, int pid, int uid,
                 ControllerCallbackLink caller) {
-            mCallbackStub.onNext(packageName, pid, uid, caller);
+            ensureMediasControlPermission();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mCallbackStub.onNext(packageName, pid, uid, caller);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
 
         @Override
         public void notifyPrevious(String packageName, int pid, int uid,
                 ControllerCallbackLink caller) {
-            mCallbackStub.onPrevious(packageName, pid, uid, caller);
+            ensureMediasControlPermission();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mCallbackStub.onPrevious(packageName, pid, uid, caller);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
 
         @Override
         public void notifyFastForward(String packageName, int pid, int uid,
                 ControllerCallbackLink caller) {
-            mCallbackStub.onFastForward(packageName, pid, uid, caller);
+            ensureMediasControlPermission();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mCallbackStub.onFastForward(packageName, pid, uid, caller);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
 
         @Override
         public void notifyRewind(String packageName, int pid, int uid,
                 ControllerCallbackLink caller) {
-            mCallbackStub.onRewind(packageName, pid, uid, caller);
+            ensureMediasControlPermission();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mCallbackStub.onRewind(packageName, pid, uid, caller);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
 
         @Override
         public void notifySeekTo(String packageName, int pid, int uid,
                 ControllerCallbackLink caller, long pos) {
-            mCallbackStub.onSeekTo(packageName, pid, uid, caller, pos);
+            ensureMediasControlPermission();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mCallbackStub.onSeekTo(packageName, pid, uid, caller, pos);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
 
         @Override
         public void notifyRate(String packageName, int pid, int uid, ControllerCallbackLink caller,
                 Rating rating) {
-            mCallbackStub.onRate(packageName, pid, uid, caller, rating);
+            ensureMediasControlPermission();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mCallbackStub.onRate(packageName, pid, uid, caller, rating);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
 
-        @Override
         public void notifyCustomAction(String packageName, int pid, int uid,
                 ControllerCallbackLink caller, String action, Bundle args) {
-            mCallbackStub.onCustomAction(packageName, pid, uid, caller, action, args);
+            ensureMediasControlPermission();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mCallbackStub.onCustomAction(packageName, pid, uid, caller, action, args);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
 
         @Override
         public void notifyAdjustVolume(String packageName, int pid, int uid,
                 ControllerCallbackLink caller, int direction) {
-            mCallbackStub.onAdjustVolume(packageName, pid, uid, caller, direction);
+            ensureMediasControlPermission();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mCallbackStub.onAdjustVolume(packageName, pid, uid, caller, direction);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
 
         @Override
         public void notifySetVolumeTo(String packageName, int pid, int uid,
                 ControllerCallbackLink caller, int value) {
-            mCallbackStub.onSetVolumeTo(packageName, pid, uid, caller, value);
+            ensureMediasControlPermission();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mCallbackStub.onSetVolumeTo(packageName, pid, uid, caller, value);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        private void ensureMediasControlPermission() {
+            // Allow API calls from the System UI
+            if (mContext.checkCallingPermission(android.Manifest.permission.STATUS_BAR_SERVICE)
+                    == PackageManager.PERMISSION_GRANTED) {
+                return;
+            }
+
+            // Check if it's system server or has MEDIA_CONTENT_CONTROL.
+            // Note that system server doesn't have MEDIA_CONTENT_CONTROL, so we need extra
+            // check here.
+            if (getCallingUid() == Process.SYSTEM_UID || mContext.checkCallingPermission(
+                    android.Manifest.permission.MEDIA_CONTENT_CONTROL)
+                    == PackageManager.PERMISSION_GRANTED) {
+                return;
+            }
+            throw new SecurityException("Must hold the MEDIA_CONTENT_CONTROL permission.");
         }
     }
 }
diff --git a/media/java/android/media/session/SessionLink.aidl b/media/java/android/media/session/SessionLink.aidl
new file mode 100644
index 0000000..c3be23e
--- /dev/null
+++ b/media/java/android/media/session/SessionLink.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.session;
+
+parcelable SessionLink;
diff --git a/media/java/android/media/session/SessionLink.java b/media/java/android/media/session/SessionLink.java
new file mode 100644
index 0000000..0da0a5a
--- /dev/null
+++ b/media/java/android/media/session/SessionLink.java
@@ -0,0 +1,454 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.session;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.app.PendingIntent;
+import android.media.AudioAttributes;
+import android.media.MediaMetadata;
+import android.media.MediaParceledListSlice;
+import android.media.Rating;
+import android.media.VolumeProvider;
+import android.media.session.MediaSession.QueueItem;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+
+import java.util.List;
+
+/**
+ * Handles incoming commands from {@link MediaSession}.
+ * @hide
+ */
+@SystemApi
+public final class SessionLink implements Parcelable {
+    public static final Parcelable.Creator<SessionLink> CREATOR =
+            new Parcelable.Creator<SessionLink>() {
+                @Override
+                public SessionLink createFromParcel(Parcel in) {
+                    return new SessionLink(in.readStrongBinder());
+                }
+
+                @Override
+                public SessionLink[] newArray(int size) {
+                    return new SessionLink[size];
+                }
+            };
+
+    final SessionStub mSessionStub;
+    final ISession mISession;
+
+    /**
+     * Constructor for stub (Callee)
+     */
+    public SessionLink(@NonNull SessionStub sessionStub) {
+        mSessionStub = sessionStub;
+        mISession = new StubProxy();
+    }
+
+    /**
+     * Constructor for interface (Caller)
+     */
+    public SessionLink(IBinder binder) {
+        mSessionStub = null;
+        mISession = ISession.Stub.asInterface(binder);
+    }
+
+    /**
+     * Tell system that the session sends an event to all the connected controllers.
+     *
+     * @param event the name of the event
+     * @param extras the extras included with the event
+     */
+    void sendEvent(@NonNull String event, @Nullable Bundle extras) {
+        try {
+            mISession.sendEvent(event, extras);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Gets the controller link from the system.
+     */
+    @NonNull
+    ControllerLink getController() {
+        try {
+            return mISession.getController();
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that the session sets the flags.
+     *
+     * @param flags the new session flags
+     */
+    void setFlags(int flags) {
+        try {
+            mISession.setFlags(flags);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that the session is (in)active.
+     *
+     * @param active the new activeness state
+     */
+    void setActive(boolean active) {
+        try {
+            mISession.setActive(active);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that the session sets the media button receiver.
+     *
+     * @param mbr the pending intent for media button receiver
+     */
+    void setMediaButtonReceiver(@Nullable PendingIntent mbr) {
+        try {
+            mISession.setMediaButtonReceiver(mbr);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that the session sets the pending intent for launching UI.
+     *
+     * @param pi the pending intent for launching UI
+     */
+    void setLaunchPendingIntent(@Nullable PendingIntent pi) {
+        try {
+            mISession.setLaunchPendingIntent(pi);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that the session is destroyed.
+     */
+    void destroySession() {
+        try {
+            mISession.destroySession();
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that the session sets the new metadata.
+     *
+     * @param metadata the new metadata
+     * @param duration the duration of the media in milliseconds
+     * @param metadataDescription the description of the metadata
+     */
+    void setMetadata(@Nullable MediaMetadata metadata, long duration,
+            @Nullable String metadataDescription) {
+        try {
+            mISession.setMetadata(metadata, duration, metadataDescription);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that the session sets the new playback state.
+     *
+     * @param state the new playback state
+     */
+    void setPlaybackState(@Nullable PlaybackState state) {
+        try {
+            mISession.setPlaybackState(state);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that the session sets the new queue.
+     *
+     * @param queue the new queue
+     */
+    void setQueue(@Nullable List<QueueItem> queue) {
+        try {
+            mISession.setQueue(queue == null ? null : new MediaParceledListSlice(queue));
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that the session sets the new queue title.
+     *
+     * @param title the new queue title
+     */
+    void setQueueTitle(@Nullable CharSequence title) {
+        try {
+            mISession.setQueueTitle(title);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that the session sets the new extras.
+     *
+     * @param extras the new extras
+     */
+    void setExtras(@Nullable Bundle extras) {
+        try {
+            mISession.setExtras(extras);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that the session sets the new rating type of the current media.
+     *
+     * @param type the rating type.
+     */
+    void setRatingType(@Rating.Style int type) {
+        try {
+            mISession.setRatingType(type);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that the session represents a local playback.
+     *
+     * @param attributes the audio attributes of the local playback.
+     */
+    void setPlaybackToLocal(@NonNull AudioAttributes attributes) {
+        try {
+            mISession.setPlaybackToLocal(attributes);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that the session represents a remote playback.
+     *
+     * @param control the volume control type
+     * @param max the max volume
+     */
+    void setPlaybackToRemote(@VolumeProvider.ControlType int control, int max) {
+        try {
+            mISession.setPlaybackToRemote(control, max);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Tell system that the session sets the new current volume.
+     *
+     * @param currentVolume the new current volume
+     */
+    void setCurrentVolume(int currentVolume) {
+        try {
+            mISession.setCurrentVolume(currentVolume);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /** Gets the binder */
+    @NonNull
+    public IBinder getBinder() {
+        return mISession.asBinder();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeStrongBinder(mISession.asBinder());
+    }
+
+    /**
+     * Class for Stub implementation
+     */
+    public abstract static class SessionStub {
+        /** Stub method for ISession.sendEvent */
+        public void sendEvent(@NonNull String event, @Nullable Bundle data) {
+        }
+
+        /** Stub method for ISession.getController */
+        @NonNull
+        public ControllerLink getController() {
+            return null;
+        }
+
+        /** Stub method for ISession.setFlags */
+        public void setFlags(int flags) {
+        }
+
+        /** Stub method for ISession.setActive */
+        public void setActive(boolean active) {
+        }
+
+        /** Stub method for ISession.setMediaButtonReceiver */
+        public void setMediaButtonReceiver(@Nullable PendingIntent mbr) {
+        }
+
+        /** Stub method for ISession.setLaunchPendingIntent */
+        public void setLaunchPendingIntent(@Nullable PendingIntent pi) {
+        }
+
+        /** Stub method for ISession.destroySession */
+        public void destroySession() {
+        }
+
+        /** Stub method for ISession.setMetadata */
+        public void setMetadata(@Nullable MediaMetadata metadata, long duration,
+                @Nullable String metadataDescription) {
+        }
+
+        /** Stub method for ISession.setPlaybackState */
+        public void setPlaybackState(@Nullable PlaybackState state) {
+        }
+
+        /** Stub method for ISession.setQueue */
+        public void setQueue(@Nullable List<QueueItem> queue) {
+        }
+
+        /** Stub method for ISession.setQueueTitle */
+        public void setQueueTitle(@Nullable CharSequence title) {
+        }
+
+        /** Stub method for ISession.setExtras */
+        public void setExtras(@Nullable Bundle extras) {
+        }
+
+        /** Stub method for ISession.setRatingType */
+        public void setRatingType(int type) {
+        }
+
+        /** Stub method for ISession.setPlaybackToLocal */
+        public void setPlaybackToLocal(@NonNull AudioAttributes attributes) {
+        }
+
+        /** Stub method for ISession.setPlaybackToRemote */
+        public void setPlaybackToRemote(int control, int max) {
+        }
+
+        /** Stub method for ISession.setCurrentVolume */
+        public void setCurrentVolume(int currentVolume) {
+        }
+    }
+
+    private class StubProxy extends ISession.Stub {
+        @Override
+        public void sendEvent(String event, Bundle data) {
+            mSessionStub.sendEvent(event, data);
+        }
+
+        @Override
+        public ControllerLink getController() {
+            return mSessionStub.getController();
+        }
+
+        @Override
+        public void setFlags(int flags) {
+            mSessionStub.setFlags(flags);
+        }
+
+        @Override
+        public void setActive(boolean active) {
+            mSessionStub.setActive(active);
+        }
+
+        @Override
+        public void setMediaButtonReceiver(PendingIntent mbr) {
+            mSessionStub.setMediaButtonReceiver(mbr);
+        }
+
+        @Override
+        public void setLaunchPendingIntent(PendingIntent pi) {
+            mSessionStub.setLaunchPendingIntent(pi);
+        }
+
+        @Override
+        public void destroySession() {
+            mSessionStub.destroySession();
+        }
+
+        @Override
+        public void setMetadata(MediaMetadata metadata, long duration, String metadataDescription) {
+            mSessionStub.setMetadata(metadata, duration, metadataDescription);
+        }
+
+        @Override
+        public void setPlaybackState(PlaybackState state) {
+            mSessionStub.setPlaybackState(state);
+        }
+
+        @Override
+        public void setQueue(MediaParceledListSlice queue) {
+            mSessionStub.setQueue(queue == null ? null : queue.getList());
+        }
+
+        @Override
+        public void setQueueTitle(CharSequence title) {
+            mSessionStub.setQueueTitle(title);
+        }
+
+        @Override
+        public void setExtras(Bundle extras) {
+            mSessionStub.setExtras(extras);
+        }
+
+        @Override
+        public void setRatingType(int type) {
+            mSessionStub.setRatingType(type);
+        }
+
+        @Override
+        public void setPlaybackToLocal(AudioAttributes attributes) {
+            mSessionStub.setPlaybackToLocal(attributes);
+        }
+
+        @Override
+        public void setPlaybackToRemote(int control, int max) {
+            mSessionStub.setPlaybackToRemote(control, max);
+        }
+
+        @Override
+        public void setCurrentVolume(int currentVolume) {
+            mSessionStub.setCurrentVolume(currentVolume);
+        }
+    }
+}
diff --git a/media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl b/media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl
index deeab1a..8dc480d 100644
--- a/media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl
+++ b/media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl
@@ -2,8 +2,8 @@
 
 package android.service.media;
 
-import android.content.pm.ParceledListSlice;
 import android.graphics.Bitmap;
+import android.media.MediaParceledListSlice;
 import android.media.session.MediaSession;
 import android.os.Bundle;
 
@@ -22,6 +22,7 @@
      */
     void onConnect(String root, in MediaSession.Token session, in Bundle extras);
     void onConnectFailed();
-    void onLoadChildren(String mediaId, in ParceledListSlice list);
-    void onLoadChildrenWithOptions(String mediaId, in ParceledListSlice list, in Bundle options);
+    void onLoadChildren(String mediaId, in MediaParceledListSlice list);
+    void onLoadChildrenWithOptions(String mediaId, in MediaParceledListSlice list,
+            in Bundle options);
 }
diff --git a/media/java/android/service/media/MediaBrowserService.java b/media/java/android/service/media/MediaBrowserService.java
index 5a60ac1..d19d117 100644
--- a/media/java/android/service/media/MediaBrowserService.java
+++ b/media/java/android/service/media/MediaBrowserService.java
@@ -25,21 +25,18 @@
 import android.app.Service;
 import android.content.Intent;
 import android.content.pm.PackageManager;
-import android.content.pm.ParceledListSlice;
+import android.media.MediaParceledListSlice;
 import android.media.browse.MediaBrowser;
 import android.media.browse.MediaBrowserUtils;
 import android.media.session.MediaSession;
+import android.media.session.MediaSessionManager;
+import android.media.session.MediaSessionManager.RemoteUserInfo;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
-import android.media.session.MediaSessionManager;
-import android.media.session.MediaSessionManager.RemoteUserInfo;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
-import android.service.media.IMediaBrowserService;
-import android.service.media.IMediaBrowserServiceCallbacks;
-import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.Pair;
@@ -672,8 +669,8 @@
      */
     private void performLoadChildren(final String parentId, final ConnectionRecord connection,
             final Bundle options) {
-        final Result<List<MediaBrowser.MediaItem>> result
-                = new Result<List<MediaBrowser.MediaItem>>(parentId) {
+        final Result<List<MediaBrowser.MediaItem>> result =
+                new Result<List<MediaBrowser.MediaItem>>(parentId) {
             @Override
             void onResultSent(List<MediaBrowser.MediaItem> list, @ResultFlags int flag) {
                 if (mConnections.get(connection.callbacks.asBinder()) != connection) {
@@ -686,9 +683,9 @@
 
                 List<MediaBrowser.MediaItem> filteredList =
                         (flag & RESULT_FLAG_OPTION_NOT_HANDLED) != 0
-                        ? applyOptions(list, options) : list;
-                final ParceledListSlice<MediaBrowser.MediaItem> pls =
-                        filteredList == null ? null : new ParceledListSlice<>(filteredList);
+                                ? applyOptions(list, options) : list;
+                final MediaParceledListSlice<MediaBrowser.MediaItem> pls =
+                        filteredList == null ? null : new MediaParceledListSlice<>(filteredList);
                 try {
                     connection.callbacks.onLoadChildrenWithOptions(parentId, pls, options);
                 } catch (RemoteException ex) {
diff --git a/packages/NetworkStack/src/com/android/server/NetworkStackService.java b/packages/NetworkStack/src/com/android/server/NetworkStackService.java
index 057012d..cca71e7 100644
--- a/packages/NetworkStack/src/com/android/server/NetworkStackService.java
+++ b/packages/NetworkStack/src/com/android/server/NetworkStackService.java
@@ -20,6 +20,7 @@
 import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
 import static android.net.dhcp.IDhcpServer.STATUS_UNKNOWN_ERROR;
 
+import static com.android.server.util.PermissionUtil.checkDumpPermission;
 import static com.android.server.util.PermissionUtil.checkNetworkStackCallingPermission;
 
 import android.annotation.NonNull;
@@ -139,7 +140,7 @@
         @Override
         protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter fout,
                 @Nullable String[] args) {
-            checkNetworkStackCallingPermission();
+            checkDumpPermission();
             final IndentingPrintWriter pw = new IndentingPrintWriter(fout, "  ");
             pw.println("NetworkStack logs:");
             mLog.dump(fd, pw, args);
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
index 4077d93..c8a8e1f 100644
--- a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
+++ b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
@@ -1598,10 +1598,11 @@
     private void logValidationProbe(long durationMs, int probeType, int probeResult) {
         int[] transports = mNetworkCapabilities.getTransportTypes();
         boolean isFirstValidation = validationStage().mIsFirstValidation;
-        ValidationProbeEvent ev = new ValidationProbeEvent();
-        ev.probeType = ValidationProbeEvent.makeProbeType(probeType, isFirstValidation);
-        ev.returnCode = probeResult;
-        ev.durationMs = durationMs;
+        ValidationProbeEvent ev = new ValidationProbeEvent.Builder()
+                .setProbeType(probeType, isFirstValidation)
+                .setReturnCode(probeResult)
+                .setDurationMs(durationMs)
+                .build();
         mMetricsLog.log(mNetId, transports, ev);
     }
 
diff --git a/packages/NetworkStack/src/com/android/server/util/PermissionUtil.java b/packages/NetworkStack/src/com/android/server/util/PermissionUtil.java
index 733f873..82bf038 100644
--- a/packages/NetworkStack/src/com/android/server/util/PermissionUtil.java
+++ b/packages/NetworkStack/src/com/android/server/util/PermissionUtil.java
@@ -31,8 +31,21 @@
      */
     public static void checkNetworkStackCallingPermission() {
         // TODO: check that the calling PID is the system server.
-        if (getCallingUid() != Process.SYSTEM_UID && getCallingUid() != Process.ROOT_UID) {
-            throw new SecurityException("Invalid caller: " + getCallingUid());
+        final int caller = getCallingUid();
+        if (caller != Process.SYSTEM_UID && caller != Process.BLUETOOTH_UID) {
+            throw new SecurityException("Invalid caller: " + caller);
+        }
+    }
+
+    /**
+     * Check that the caller is allowed to dump the network stack, e.g. dumpsys.
+     * @throws SecurityException The caller is not allowed to dump the network stack.
+     */
+    public static void checkDumpPermission() {
+        final int caller = getCallingUid();
+        if (caller != Process.SYSTEM_UID && caller != Process.ROOT_UID
+                && caller != Process.SHELL_UID) {
+            throw new SecurityException("No dump permissions for caller: " + caller);
         }
     }
 
diff --git a/packages/SettingsLib/res/values/arrays.xml b/packages/SettingsLib/res/values/arrays.xml
index 09fa284..ed3c11c 100644
--- a/packages/SettingsLib/res/values/arrays.xml
+++ b/packages/SettingsLib/res/values/arrays.xml
@@ -102,6 +102,20 @@
 
 
     <!-- Bluetooth settings -->
+    <!-- Titles for Bluetooth HCI Snoop Logging -->
+    <string-array name="bt_hci_snoop_log_entries">
+        <item>Disabled</item>
+        <item>Enabled Filtered</item>
+        <item>Enabled</item>
+    </string-array>
+
+    <!-- Values for Bluetooth HCI Snoop Logging -->
+    <string-array name="bt_hci_snoop_log_values" translatable="false">
+        <item>disabled</item>
+        <item>filtered</item>
+        <item>full</item>
+    </string-array>
+
     <!-- Titles for Bluetooth AVRCP Versions -->
     <string-array name="bluetooth_avrcp_versions">
         <item>AVRCP 1.4 (Default)</item>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 16bfcc9..c8f8d73 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -591,8 +591,8 @@
     <string name="keep_screen_on_summary">Screen will never sleep while charging</string>
     <!-- Setting Checkbox title whether to enable Bluetooth HCI snoop log -->
     <string name="bt_hci_snoop_log">Enable Bluetooth HCI snoop log</string>
-    <!-- setting Checkbox summary whether to capture all Bluetooth HCI packets in a file -->
-    <string name="bt_hci_snoop_log_summary">Capture all Bluetooth HCI packets in a file (Toggle Bluetooth after changing this setting)</string>
+    <!-- setting Checkbox summary whether to capture all Bluetooth HCI packets in a file [CHAR_LIMIT=100] -->
+    <string name="bt_hci_snoop_log_summary">Capture Bluetooth packets. (Toggle Bluetooth after changing this setting)</string>
     <!-- setting Checkbox title whether to enable OEM unlock [CHAR_LIMIT=35] -->
     <string name="oem_unlock_enable">OEM unlocking</string>
     <!-- setting Checkbox summary whether to enable OEM unlock [CHAR_LIMIT=50] -->
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
index 24d7011..c059156 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
@@ -74,6 +74,7 @@
                 device.refresh();
             }
             mIsProfileReady=true;
+            mProfileManager.callServiceConnectedListeners();
         }
 
         public void onServiceDisconnected(int profile) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
index 577d98d..77dfbe9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
@@ -71,8 +71,8 @@
 
             // Check current list of CachedDevices to see if any are Hearing Aid devices.
             mDeviceManager.updateHearingAidsDevices();
-
             mIsProfileReady=true;
+            mProfileManager.callServiceConnectedListeners();
         }
 
         public void onServiceDisconnected(int profile) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java
index 959f9b2..a5c6f0c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java
@@ -54,17 +54,17 @@
     }
 
     @Override
-    public void connect() {
+    public boolean connect() {
         //TODO(b/117129183): add callback to notify LocalMediaManager connection state.
-        mIsConnected = mCachedDevice.setActive();
-        super.connect();
-        Log.d(TAG, "connect() device : " + getName() + ", is selected : " + mIsConnected);
+        final boolean isConnected = mCachedDevice.setActive();
+        setConnectedRecord();
+        Log.d(TAG, "connect() device : " + getName() + ", is selected : " + isConnected);
+        return isConnected;
     }
 
     @Override
     public void disconnect() {
         //TODO(b/117129183): disconnected last select device
-        mIsConnected = false;
     }
 
     /**
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaManager.java
index ab1cca0..fa2dd88 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaManager.java
@@ -18,6 +18,7 @@
 import android.app.Notification;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
 import android.content.Context;
 import android.util.Log;
 
@@ -35,36 +36,48 @@
 /**
  * BluetoothMediaManager provide interface to get Bluetooth device list.
  */
-public class BluetoothMediaManager extends MediaManager implements BluetoothCallback {
+public class BluetoothMediaManager extends MediaManager implements BluetoothCallback,
+        LocalBluetoothProfileManager.ServiceListener {
 
     private static final String TAG = "BluetoothMediaManager";
 
-    private final DeviceAttributeChangeCallback mCachedDeviceCallback =
-            new DeviceAttributeChangeCallback();
-
     private LocalBluetoothManager mLocalBluetoothManager;
     private LocalBluetoothProfileManager mProfileManager;
+    private CachedBluetoothDeviceManager mCachedBluetoothDeviceManager;
 
     private MediaDevice mLastAddedDevice;
     private MediaDevice mLastRemovedDevice;
 
+    private boolean mIsA2dpProfileReady = false;
+    private boolean mIsHearingAidProfileReady = false;
+
     BluetoothMediaManager(Context context, LocalBluetoothManager localBluetoothManager,
             Notification notification) {
         super(context, notification);
 
         mLocalBluetoothManager = localBluetoothManager;
         mProfileManager = mLocalBluetoothManager.getProfileManager();
+        mCachedBluetoothDeviceManager = mLocalBluetoothManager.getCachedDeviceManager();
     }
 
     @Override
     public void startScan() {
-        mMediaDevices.clear();
         mLocalBluetoothManager.getEventManager().registerCallback(this);
         buildBluetoothDeviceList();
         dispatchDeviceListAdded();
+
+        // The profile may not ready when calling startScan().
+        // Device status are all disconnected since profiles are not ready to connected.
+        // In this case, we observe onServiceConnected() in LocalBluetoothProfileManager.
+        // When A2dpProfile or HearingAidProfile is connected will call buildBluetoothDeviceList()
+        // again to find the connected devices.
+        if (!mIsA2dpProfileReady || !mIsHearingAidProfileReady) {
+            mProfileManager.addServiceListener(this);
+        }
     }
 
     private void buildBluetoothDeviceList() {
+        mMediaDevices.clear();
         addConnectedA2dpDevices();
         addConnectedHearingAidDevices();
     }
@@ -77,12 +90,10 @@
         }
 
         final List<BluetoothDevice> devices = a2dpProfile.getConnectedDevices();
-        final CachedBluetoothDeviceManager cachedBluetoothDeviceManager =
-                mLocalBluetoothManager.getCachedDeviceManager();
 
         for (BluetoothDevice device : devices) {
             final CachedBluetoothDevice cachedDevice =
-                    cachedBluetoothDeviceManager.findDevice(device);
+                    mCachedBluetoothDeviceManager.findDevice(device);
 
             if (cachedDevice == null) {
                 Log.w(TAG, "Can't found CachedBluetoothDevice : " + device.getName());
@@ -96,6 +107,8 @@
                 addMediaDevice(cachedDevice);
             }
         }
+
+        mIsA2dpProfileReady = a2dpProfile.isProfileReady();
     }
 
     private void addConnectedHearingAidDevices() {
@@ -107,12 +120,10 @@
 
         final List<Long> devicesHiSyncIds = new ArrayList<>();
         final List<BluetoothDevice> devices = hapProfile.getConnectedDevices();
-        final CachedBluetoothDeviceManager cachedBluetoothDeviceManager =
-                mLocalBluetoothManager.getCachedDeviceManager();
 
         for (BluetoothDevice device : devices) {
             final CachedBluetoothDevice cachedDevice =
-                    cachedBluetoothDeviceManager.findDevice(device);
+                    mCachedBluetoothDeviceManager.findDevice(device);
 
             if (cachedDevice == null) {
                 Log.w(TAG, "Can't found CachedBluetoothDevice : " + device.getName());
@@ -130,13 +141,14 @@
                 addMediaDevice(cachedDevice);
             }
         }
+
+        mIsHearingAidProfileReady = hapProfile.isProfileReady();
     }
 
     private void addMediaDevice(CachedBluetoothDevice cachedDevice) {
         MediaDevice mediaDevice = findMediaDevice(MediaDeviceUtils.getId(cachedDevice));
         if (mediaDevice == null) {
             mediaDevice = new BluetoothMediaDevice(mContext, cachedDevice);
-            cachedDevice.registerCallback(mCachedDeviceCallback);
             mLastAddedDevice = mediaDevice;
             mMediaDevices.add(mediaDevice);
         }
@@ -145,16 +157,6 @@
     @Override
     public void stopScan() {
         mLocalBluetoothManager.getEventManager().unregisterCallback(this);
-        unregisterCachedDeviceCallback();
-    }
-
-    private void unregisterCachedDeviceCallback() {
-        for (MediaDevice device : mMediaDevices) {
-            if (device instanceof BluetoothMediaDevice) {
-                ((BluetoothMediaDevice) device).getCachedDevice()
-                        .unregisterCallback(mCachedDeviceCallback);
-            }
-        }
     }
 
     @Override
@@ -166,8 +168,6 @@
             final List<MediaDevice> removeDevicesList = new ArrayList<>();
             for (MediaDevice device : mMediaDevices) {
                 if (device instanceof BluetoothMediaDevice) {
-                    ((BluetoothMediaDevice) device).getCachedDevice()
-                            .unregisterCallback(mCachedDeviceCallback);
                     removeDevicesList.add(device);
                 }
             }
@@ -212,7 +212,6 @@
     private void removeMediaDevice(CachedBluetoothDevice cachedDevice) {
         final MediaDevice mediaDevice = findMediaDevice(MediaDeviceUtils.getId(cachedDevice));
         if (mediaDevice != null) {
-            cachedDevice.unregisterCallback(mCachedDeviceCallback);
             mLastRemovedDevice = mediaDevice;
             mMediaDevices.remove(mediaDevice);
         }
@@ -252,10 +251,34 @@
             dispatchDeviceRemoved(cachedDevice);
         }
     }
-    class DeviceAttributeChangeCallback implements CachedBluetoothDevice.Callback {
-        @Override
-        public void onDeviceAttributesChanged() {
-            dispatchDeviceAttributesChanged();
+
+    @Override
+    public void onActiveDeviceChanged(CachedBluetoothDevice activeDevice, int bluetoothProfile) {
+        Log.d(TAG, "onActiveDeviceChanged : device : "
+                + activeDevice + ", profile : " + bluetoothProfile);
+        if (BluetoothProfile.HEARING_AID == bluetoothProfile
+                || BluetoothProfile.A2DP == bluetoothProfile) {
+            final String id = activeDevice == null
+                    ? PhoneMediaDevice.ID : MediaDeviceUtils.getId(activeDevice);
+            dispatchConnectedDeviceChanged(id);
         }
     }
+
+    @Override
+    public void onServiceConnected() {
+        if (!mIsA2dpProfileReady || !mIsHearingAidProfileReady) {
+            buildBluetoothDeviceList();
+            dispatchDeviceListAdded();
+        }
+
+        //Remove the listener once a2dpProfile and hearingAidProfile are ready.
+        if (mIsA2dpProfileReady && mIsHearingAidProfileReady) {
+            mProfileManager.removeServiceListener(this);
+        }
+    }
+
+    @Override
+    public void onServiceDisconnected() {
+
+    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java
index 21a81e0..04f70cc 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java
@@ -16,6 +16,7 @@
 package com.android.settingslib.media;
 
 import android.content.Context;
+import android.widget.Toast;
 
 import androidx.mediarouter.media.MediaRouter;
 
@@ -43,7 +44,7 @@
 
     @Override
     public int getIcon() {
-        //TODO(b/117129183): This is not final icon for cast device, just for demo.
+        //TODO(b/121083246): This is not final icon for cast device, just for demo.
         return R.drawable.ic_settings_print;
     }
 
@@ -53,15 +54,15 @@
     }
 
     @Override
-    public void connect() {
-        //TODO(b/117129183): use MediaController2 to transfer media
-        mIsConnected = true;
-        super.connect();
+    public boolean connect() {
+        //TODO(b/121083246): use SystemApi to transfer media
+        setConnectedRecord();
+        Toast.makeText(mContext, "This is cast device !", Toast.LENGTH_SHORT).show();
+        return false;
     }
 
     @Override
     public void disconnect() {
-        //TODO(b/117129183): disconnected last select device
-        mIsConnected = false;
+        //TODO(b/121083246): disconnected last select device
     }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
index 6907238..bc8e2c3 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
@@ -22,6 +22,8 @@
 import androidx.mediarouter.media.MediaRouteSelector;
 import androidx.mediarouter.media.MediaRouter;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 /**
  * InfoMediaManager provide interface to get InfoMediaDevice list.
  */
@@ -29,9 +31,13 @@
 
     private static final String TAG = "InfoMediaManager";
 
-    private final MediaRouterCallback mMediaRouterCallback = new MediaRouterCallback();
+    @VisibleForTesting
+    final MediaRouterCallback mMediaRouterCallback = new MediaRouterCallback();
+    @VisibleForTesting
+    MediaRouteSelector mSelector;
+    @VisibleForTesting
+    MediaRouter mMediaRouter;
 
-    private MediaRouter mMediaRouter;
     private String mPackageName;
 
     InfoMediaManager(Context context, String packageName, Notification notification) {
@@ -39,24 +45,20 @@
 
         mMediaRouter = MediaRouter.getInstance(context);
         mPackageName = packageName;
+        mSelector = new MediaRouteSelector.Builder()
+                .addControlCategory(getControlCategoryByPackageName(mPackageName))
+                .build();
     }
 
     @Override
     public void startScan() {
         mMediaDevices.clear();
-        startScanCastDevice();
-    }
-
-    private void startScanCastDevice() {
-        final MediaRouteSelector selector = new MediaRouteSelector.Builder()
-                .addControlCategory(getControlCategoryByPackageName(mPackageName))
-                .build();
-
-        mMediaRouter.addCallback(selector, mMediaRouterCallback,
+        mMediaRouter.addCallback(mSelector, mMediaRouterCallback,
                 MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
     }
 
-    private String getControlCategoryByPackageName(String packageName) {
+    @VisibleForTesting
+    String getControlCategoryByPackageName(String packageName) {
         //TODO(b/117129183): Use package name to get ControlCategory.
         //Since api not ready, return fixed ControlCategory for prototype.
         return "com.google.android.gms.cast.CATEGORY_CAST/4F8B3483";
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
index c9479d4..44d945a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
@@ -16,12 +16,15 @@
 package com.android.settingslib.media;
 
 import android.app.Notification;
+import android.bluetooth.BluetoothProfile;
 import android.content.Context;
 import android.util.Log;
 
 import androidx.annotation.IntDef;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.settingslib.bluetooth.BluetoothCallback;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 
 import java.lang.annotation.Retention;
@@ -50,16 +53,20 @@
     }
 
     private final Collection<DeviceCallback> mCallbacks = new ArrayList<>();
-    private final MediaDeviceCallback mMediaDeviceCallback = new MediaDeviceCallback();
+    @VisibleForTesting
+    final MediaDeviceCallback mMediaDeviceCallback = new MediaDeviceCallback();
 
     private Context mContext;
-    private List<MediaDevice> mMediaDevices = new ArrayList<>();
     private BluetoothMediaManager mBluetoothMediaManager;
     private InfoMediaManager mInfoMediaManager;
-
     private LocalBluetoothManager mLocalBluetoothManager;
-    private MediaDevice mLastConnectedDevice;
-    private MediaDevice mPhoneDevice;
+
+    @VisibleForTesting
+    List<MediaDevice> mMediaDevices = new ArrayList<>();
+    @VisibleForTesting
+    MediaDevice mPhoneDevice;
+    @VisibleForTesting
+    MediaDevice mCurrentConnectedDevice;
 
     /**
      * Register to start receiving callbacks for MediaDevice events.
@@ -93,28 +100,40 @@
         mInfoMediaManager = new InfoMediaManager(context, packageName, notification);
     }
 
+    @VisibleForTesting
+    LocalMediaManager(Context context, LocalBluetoothManager localBluetoothManager,
+            BluetoothMediaManager bluetoothMediaManager, InfoMediaManager infoMediaManager) {
+        mContext = context;
+        mLocalBluetoothManager = localBluetoothManager;
+        mBluetoothMediaManager = bluetoothMediaManager;
+        mInfoMediaManager = infoMediaManager;
+    }
+
     /**
      * Connect the MediaDevice to transfer media
      * @param connectDevice the MediaDevice
      */
     public void connectDevice(MediaDevice connectDevice) {
-        if (connectDevice == mLastConnectedDevice) {
+        final MediaDevice device = getMediaDeviceById(mMediaDevices, connectDevice.getId());
+        if (device == mCurrentConnectedDevice) {
+            Log.d(TAG, "connectDevice() this device all ready connected! : " + device.getName());
             return;
         }
 
-        if (mLastConnectedDevice != null) {
-            mLastConnectedDevice.disconnect();
+        //TODO(b/121083246): Update it once remote media API is ready.
+        if (mCurrentConnectedDevice != null && !(connectDevice instanceof InfoMediaDevice)) {
+            mCurrentConnectedDevice.disconnect();
         }
 
-        connectDevice.connect();
-        if (connectDevice.isConnected()) {
-            mLastConnectedDevice = connectDevice;
+        final boolean isConnected = device.connect();
+        if (isConnected) {
+            mCurrentConnectedDevice = device;
         }
 
-        final int state = connectDevice.isConnected()
+        final int state = isConnected
                 ? MediaDeviceState.STATE_CONNECTED
                 : MediaDeviceState.STATE_DISCONNECTED;
-        dispatchSelectedDeviceStateChanged(connectDevice, state);
+        dispatchSelectedDeviceStateChanged(device, state);
     }
 
     void dispatchSelectedDeviceStateChanged(MediaDevice device, @MediaDeviceState int state) {
@@ -189,6 +208,31 @@
         return null;
     }
 
+    /**
+     * Find the current connected MediaDevice.
+     *
+     * @return MediaDevice
+     */
+    public MediaDevice getCurrentConnectedDevice() {
+        return mCurrentConnectedDevice;
+    }
+
+    private MediaDevice updateCurrentConnectedDevice() {
+        for (MediaDevice device : mMediaDevices) {
+            if (device instanceof  BluetoothMediaDevice) {
+                if (isConnected(((BluetoothMediaDevice) device).getCachedDevice())) {
+                    return device;
+                }
+            }
+        }
+        return mMediaDevices.contains(mPhoneDevice) ? mPhoneDevice : null;
+    }
+
+    private boolean isConnected(CachedBluetoothDevice device) {
+        return device.isActiveDevice(BluetoothProfile.A2DP)
+                || device.isActiveDevice(BluetoothProfile.HEARING_AID);
+    }
+
     class MediaDeviceCallback implements MediaManager.MediaDeviceCallback {
         @Override
         public void onDeviceAdded(MediaDevice device) {
@@ -201,8 +245,13 @@
 
         @Override
         public void onDeviceListAdded(List<MediaDevice> devices) {
-            mMediaDevices.addAll(devices);
+            for (MediaDevice device : devices) {
+                if (getMediaDeviceById(mMediaDevices, device.getId()) == null) {
+                    mMediaDevices.add(device);
+                }
+            }
             addPhoneDeviceIfNecessary();
+            mCurrentConnectedDevice = updateCurrentConnectedDevice();
             dispatchDeviceListUpdate();
         }
 
@@ -226,6 +275,20 @@
         public void onDeviceAttributesChanged() {
             dispatchDeviceListUpdate();
         }
+
+        @Override
+        public void onConnectedDeviceChanged(String id) {
+            final MediaDevice connectDevice = getMediaDeviceById(mMediaDevices, id);
+
+            if (connectDevice == mCurrentConnectedDevice) {
+                Log.d(TAG, "onConnectedDeviceChanged() this device all ready connected! : "
+                        + connectDevice.getName());
+                return;
+            }
+            mCurrentConnectedDevice = connectDevice;
+
+            dispatchDeviceListUpdate();
+        }
     }
 
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
index 33b621c..f35c30e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
@@ -41,7 +41,6 @@
 
     private int mConnectedRecord;
 
-    protected boolean mIsConnected = false;
     protected Context mContext;
     protected int mType;
 
@@ -57,15 +56,6 @@
     }
 
     /**
-     * Check the MediaDevice is be connected to transfer.
-     *
-     * @return true if the MediaDevice is be connected to transfer, false otherwise.
-     */
-    public boolean isConnected() {
-        return mIsConnected;
-    }
-
-    /**
      * Get name from MediaDevice.
      *
      * @return name of MediaDevice.
@@ -87,8 +77,12 @@
 
     /**
      * Transfer MediaDevice for media
+     *
+     * @return result of transfer media
      */
-    public void connect() {
+    public abstract boolean connect();
+
+    void setConnectedRecord() {
         mConnectedRecord++;
         ConnectionRecordManager.getInstance().setConnectionRecord(mContext, getId(),
                 mConnectedRecord);
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaManager.java
index 72b6b09..2c3a96c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/MediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaManager.java
@@ -96,7 +96,7 @@
     protected void dispatchDeviceListAdded() {
         synchronized (mCallbacks) {
             for (MediaDeviceCallback callback : mCallbacks) {
-                callback.onDeviceListAdded(mMediaDevices);
+                callback.onDeviceListAdded(new ArrayList<>(mMediaDevices));
             }
         }
     }
@@ -109,10 +109,10 @@
         }
     }
 
-    protected void dispatchDeviceAttributesChanged() {
+    protected void dispatchConnectedDeviceChanged(String id) {
         synchronized (mCallbacks) {
             for (MediaDeviceCallback callback : mCallbacks) {
-                callback.onDeviceAttributesChanged();
+                callback.onConnectedDeviceChanged(id);
             }
         }
     }
@@ -153,5 +153,12 @@
          * Callback for notifying MediaDevice attributes is changed.
          */
         void onDeviceAttributesChanged();
+
+        /**
+         * Callback for notifying connected MediaDevice is changed.
+         *
+         * @param id the id of MediaDevice
+         */
+        void onConnectedDeviceChanged(String id);
     }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaOutputSliceConstants.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaOutputSliceConstants.java
new file mode 100644
index 0000000..e600cb8
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaOutputSliceConstants.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.media;
+
+/**
+ * Class to access MediaOutput constants.
+ */
+public class MediaOutputSliceConstants {
+
+    /**
+     * Key for the Media output setting.
+     */
+    public static final String KEY_MEDIA_OUTPUT = "media_output";
+
+    /**
+     * Activity Action: Show a settings dialog containing {@link MediaDevice} to transfer media.
+     */
+    public static final String ACTION_MEDIA_OUTPUT =
+            "com.android.settings.panel.action.MEDIA_OUTPUT";
+
+    /**
+     * An string extra specifying a media package name.
+     */
+    public static final String EXTRA_PACKAGE_NAME =
+            "com.android.settings.panel.extra.PACKAGE_NAME";
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
index e0f3c2f..c808214 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
@@ -62,20 +62,22 @@
     }
 
     @Override
-    public void connect() {
+    public boolean connect() {
         final HearingAidProfile hapProfile = mProfileManager.getHearingAidProfile();
         final A2dpProfile a2dpProfile = mProfileManager.getA2dpProfile();
 
+        boolean isConnected = false;
+
         if (hapProfile != null && a2dpProfile != null) {
-            mIsConnected = hapProfile.setActiveDevice(null) && a2dpProfile.setActiveDevice(null);
-            super.connect();
+            isConnected = hapProfile.setActiveDevice(null) && a2dpProfile.setActiveDevice(null);
+            setConnectedRecord();
         }
-        Log.d(TAG, "connect() device : " + getName() + ", is selected : " + mIsConnected);
+        Log.d(TAG, "connect() device : " + getName() + ", is selected : " + isConnected);
+        return isConnected;
     }
 
     @Override
     public void disconnect() {
         //TODO(b/117129183): disconnected last select device
-        mIsConnected = false;
     }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/BluetoothMediaDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/BluetoothMediaDeviceTest.java
new file mode 100644
index 0000000..e5d1b18
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/BluetoothMediaDeviceTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.media;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.bluetooth.BluetoothProfile;
+import android.content.Context;
+
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class BluetoothMediaDeviceTest {
+
+    @Mock
+    private CachedBluetoothDevice mDevice;
+
+    private Context mContext;
+    private BluetoothMediaDevice mBluetoothMediaDevice;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+
+        when(mDevice.isActiveDevice(BluetoothProfile.A2DP)).thenReturn(true);
+        when(mDevice.isActiveDevice(BluetoothProfile.HEARING_AID)).thenReturn(true);
+
+        mBluetoothMediaDevice = new BluetoothMediaDevice(mContext, mDevice);
+    }
+
+    @Test
+    public void connect_setActiveSuccess_isConnectedReturnTrue() {
+        when(mDevice.setActive()).thenReturn(true);
+
+        assertThat(mBluetoothMediaDevice.connect()).isTrue();
+    }
+
+    @Test
+    public void connect_setActiveFail_isConnectedReturnFalse() {
+        when(mDevice.setActive()).thenReturn(false);
+
+        assertThat(mBluetoothMediaDevice.connect()).isFalse();
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/BluetoothMediaManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/BluetoothMediaManagerTest.java
new file mode 100644
index 0000000..a20e22b
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/BluetoothMediaManagerTest.java
@@ -0,0 +1,416 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.media;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
+import android.content.Context;
+
+import com.android.settingslib.bluetooth.A2dpProfile;
+import com.android.settingslib.bluetooth.BluetoothEventManager;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
+import com.android.settingslib.bluetooth.HearingAidProfile;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+@RunWith(RobolectricTestRunner.class)
+public class BluetoothMediaManagerTest {
+
+    private static final String TEST_ADDRESS = "11:22:33:44:55:66";
+
+    @Mock
+    private LocalBluetoothManager mLocalBluetoothManager;
+    @Mock
+    private LocalBluetoothProfileManager mProfileManager;
+    @Mock
+    private A2dpProfile mA2dpProfile;
+    @Mock
+    private HearingAidProfile mHapProfile;
+    @Mock
+    private CachedBluetoothDeviceManager mCachedDeviceManager;
+    @Mock
+    private BluetoothEventManager mEventManager;
+    @Mock
+    private MediaManager.MediaDeviceCallback mCallback;
+
+    private BluetoothMediaManager mMediaManager;
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+
+        when(mLocalBluetoothManager.getProfileManager()).thenReturn(mProfileManager);
+        when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(mCachedDeviceManager);
+        when(mProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile);
+        when(mProfileManager.getHearingAidProfile()).thenReturn(mHapProfile);
+        when(mLocalBluetoothManager.getEventManager()).thenReturn(mEventManager);
+
+        mMediaManager = new BluetoothMediaManager(mContext, mLocalBluetoothManager, null);
+    }
+
+    @Test
+    public void startScan_haveA2dpProfileConnectedBluetoothDevice_shouldAddDevice() {
+        final List<BluetoothDevice> devices = new ArrayList<>();
+        final CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class);
+        final BluetoothDevice bluetoothDevice = mock(BluetoothDevice.class);
+        devices.add(bluetoothDevice);
+
+        when(mA2dpProfile.getConnectedDevices()).thenReturn(devices);
+        when(mCachedDeviceManager.findDevice(bluetoothDevice)).thenReturn(cachedDevice);
+        when(cachedDevice.isConnected()).thenReturn(true);
+
+        assertThat(mMediaManager.mMediaDevices).isEmpty();
+        mMediaManager.startScan();
+        assertThat(mMediaManager.mMediaDevices).hasSize(devices.size());
+    }
+
+    @Test
+    public void startScan_haveA2dpProfileDisconnectedBluetoothDevice_shouldNotAddDevice() {
+        final List<BluetoothDevice> devices = new ArrayList<>();
+        final CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class);
+        final BluetoothDevice bluetoothDevice = mock(BluetoothDevice.class);
+        devices.add(bluetoothDevice);
+
+        when(mA2dpProfile.getConnectedDevices()).thenReturn(devices);
+        when(mCachedDeviceManager.findDevice(bluetoothDevice)).thenReturn(cachedDevice);
+        when(cachedDevice.isConnected()).thenReturn(false);
+
+        assertThat(mMediaManager.mMediaDevices).isEmpty();
+        mMediaManager.startScan();
+        assertThat(mMediaManager.mMediaDevices).isEmpty();
+    }
+
+    @Test
+    public void startScan_noA2dpProfileBluetoothDevice_shouldNotAddDevice() {
+        final List<BluetoothDevice> devices = new ArrayList<>();
+
+        when(mA2dpProfile.getConnectedDevices()).thenReturn(devices);
+
+        assertThat(mMediaManager.mMediaDevices).isEmpty();
+        mMediaManager.startScan();
+        assertThat(mMediaManager.mMediaDevices).isEmpty();
+    }
+
+    @Test
+    public void startScan_haveHapProfileConnectedBluetoothDevice_shouldAddDevice() {
+        final List<BluetoothDevice> devices = new ArrayList<>();
+        final CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class);
+        final BluetoothDevice bluetoothDevice = mock(BluetoothDevice.class);
+        devices.add(bluetoothDevice);
+
+        when(mHapProfile.getConnectedDevices()).thenReturn(devices);
+        when(mCachedDeviceManager.findDevice(bluetoothDevice)).thenReturn(cachedDevice);
+        when(cachedDevice.isConnected()).thenReturn(true);
+
+        assertThat(mMediaManager.mMediaDevices).isEmpty();
+        mMediaManager.startScan();
+        assertThat(mMediaManager.mMediaDevices).hasSize(devices.size());
+    }
+
+    @Test
+    public void startScan_noHapProfileBluetoothDevice_shouldNotAddDevice() {
+        final List<BluetoothDevice> devices = new ArrayList<>();
+
+        when(mHapProfile.getConnectedDevices()).thenReturn(devices);
+
+        assertThat(mMediaManager.mMediaDevices).isEmpty();
+        mMediaManager.startScan();
+        assertThat(mMediaManager.mMediaDevices).isEmpty();
+    }
+
+    @Test
+    public void starScan_a2dpAndHapProfileNotReady_shouldRegisterCallback() {
+        final Collection<CachedBluetoothDevice> mDevices = new ArrayList<>();
+        final CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class);
+        mDevices.add(cachedDevice);
+
+        when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn(mDevices);
+        when(mA2dpProfile.isProfileReady()).thenReturn(false);
+        when(mHapProfile.isProfileReady()).thenReturn(false);
+
+        mMediaManager.startScan();
+
+        verify(mProfileManager).addServiceListener(mMediaManager);
+    }
+
+    @Test
+    public void starScan_a2dpAndHapProfileReady_shouldNotRegisterCallback() {
+        final Collection<CachedBluetoothDevice> mDevices = new ArrayList<>();
+        final CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class);
+        mDevices.add(cachedDevice);
+
+        when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn(mDevices);
+        when(mA2dpProfile.isProfileReady()).thenReturn(true);
+        when(mHapProfile.isProfileReady()).thenReturn(true);
+
+        mMediaManager.startScan();
+
+        verify(mProfileManager, never()).addServiceListener(mMediaManager);
+    }
+
+    @Test
+    public void onServiceConnected_a2dpAndHapProfileNotReady_doNothing() {
+        final Collection<CachedBluetoothDevice> mDevices = new ArrayList<>();
+        final CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class);
+        mDevices.add(cachedDevice);
+
+        when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn(mDevices);
+        when(mA2dpProfile.isProfileReady()).thenReturn(false);
+        when(mHapProfile.isProfileReady()).thenReturn(false);
+
+        mMediaManager.startScan();
+        mMediaManager.onServiceConnected();
+
+        verify(mProfileManager, never()).removeServiceListener(mMediaManager);
+    }
+
+    @Test
+    public void onDeviceAttributesChanged_a2dpAndHapProfileReady_shouldUnregisterCallback() {
+        final Collection<CachedBluetoothDevice> mDevices = new ArrayList<>();
+        final CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class);
+        mDevices.add(cachedDevice);
+
+        when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn(mDevices);
+        when(mA2dpProfile.isProfileReady()).thenReturn(true);
+        when(mHapProfile.isProfileReady()).thenReturn(true);
+
+        mMediaManager.startScan();
+        mMediaManager.onServiceConnected();
+
+        verify(mProfileManager).removeServiceListener(mMediaManager);
+    }
+
+    @Test
+    public void onBluetoothStateChanged_bluetoothStateIsOn_callOnDeviceListAdded() {
+        mMediaManager.registerCallback(mCallback);
+        mMediaManager.onBluetoothStateChanged(BluetoothAdapter.STATE_ON);
+
+        verify(mCallback).onDeviceListAdded(any());
+    }
+
+    @Test
+    public void onBluetoothStateChanged_bluetoothStateIsOff_callOnDeviceListRemoved() {
+        final BluetoothMediaDevice device1 = mock(BluetoothMediaDevice.class);
+        final BluetoothMediaDevice device2 = mock(BluetoothMediaDevice.class);
+        mMediaManager.mMediaDevices.add(device1);
+        mMediaManager.mMediaDevices.add(device2);
+
+        mMediaManager.registerCallback(mCallback);
+        mMediaManager.onBluetoothStateChanged(BluetoothAdapter.STATE_OFF);
+
+        assertThat(mMediaManager.mMediaDevices).isEmpty();
+        verify(mCallback).onDeviceListRemoved(any());
+    }
+
+    @Test
+    public void onDeviceAdded_cachedDeviceIsConnected_callOnDeviceAdded() {
+        final CachedBluetoothDevice device = mock(CachedBluetoothDevice.class);
+
+        when(device.isConnectedHearingAidDevice()).thenReturn(true);
+        when(device.isConnectedA2dpDevice()).thenReturn(true);
+
+        assertThat(mMediaManager.mMediaDevices).isEmpty();
+        mMediaManager.registerCallback(mCallback);
+        mMediaManager.onDeviceAdded(device);
+
+        assertThat(mMediaManager.mMediaDevices).hasSize(1);
+        verify(mCallback).onDeviceAdded(any());
+
+    }
+
+    @Test
+    public void onDeviceAdded_cachedDeviceIsDisconnected_doNothing() {
+        final CachedBluetoothDevice device = mock(CachedBluetoothDevice.class);
+
+        when(device.isConnectedHearingAidDevice()).thenReturn(false);
+        when(device.isConnectedA2dpDevice()).thenReturn(false);
+
+        assertThat(mMediaManager.mMediaDevices).isEmpty();
+        mMediaManager.registerCallback(mCallback);
+        mMediaManager.onDeviceAdded(device);
+
+        assertThat(mMediaManager.mMediaDevices).isEmpty();
+        verify(mCallback, never()).onDeviceAdded(any());
+
+    }
+
+    @Test
+    public void onDeviceDeleted_cachedDeviceIsConnected_doNothing() {
+        final CachedBluetoothDevice device = mock(CachedBluetoothDevice.class);
+        final BluetoothMediaDevice bluetoothMediaDevice = mock(BluetoothMediaDevice.class);
+        mMediaManager.mMediaDevices.add(bluetoothMediaDevice);
+
+        when(device.isConnectedHearingAidDevice()).thenReturn(true);
+        when(device.isConnectedA2dpDevice()).thenReturn(true);
+        when(device.getAddress()).thenReturn(TEST_ADDRESS);
+        when(bluetoothMediaDevice.getId()).thenReturn(TEST_ADDRESS);
+
+        assertThat(mMediaManager.mMediaDevices).hasSize(1);
+        mMediaManager.registerCallback(mCallback);
+        mMediaManager.onDeviceDeleted(device);
+
+        assertThat(mMediaManager.mMediaDevices).hasSize(1);
+        verify(mCallback, never()).onDeviceRemoved(any());
+    }
+
+    @Test
+    public void onDeviceDeleted_cachedDeviceIsDisconnected_callOnDeviceRemoved() {
+        final CachedBluetoothDevice device = mock(CachedBluetoothDevice.class);
+        final BluetoothMediaDevice bluetoothMediaDevice = mock(BluetoothMediaDevice.class);
+        mMediaManager.mMediaDevices.add(bluetoothMediaDevice);
+
+        when(device.isConnectedHearingAidDevice()).thenReturn(false);
+        when(device.isConnectedA2dpDevice()).thenReturn(false);
+        when(device.getAddress()).thenReturn(TEST_ADDRESS);
+        when(bluetoothMediaDevice.getId()).thenReturn(TEST_ADDRESS);
+
+        assertThat(mMediaManager.mMediaDevices).hasSize(1);
+        mMediaManager.registerCallback(mCallback);
+        mMediaManager.onDeviceDeleted(device);
+
+        assertThat(mMediaManager.mMediaDevices).isEmpty();
+        verify(mCallback).onDeviceRemoved(any());
+    }
+
+    @Test
+    public void onProfileConnectionStateChanged_cachedDeviceIsConnect_callOnDeviceAdded() {
+        final CachedBluetoothDevice device = mock(CachedBluetoothDevice.class);
+
+        when(device.isConnectedHearingAidDevice()).thenReturn(true);
+        when(device.isConnectedA2dpDevice()).thenReturn(true);
+
+        assertThat(mMediaManager.mMediaDevices).isEmpty();
+        mMediaManager.registerCallback(mCallback);
+        mMediaManager.onProfileConnectionStateChanged(device, 0, 0);
+
+        assertThat(mMediaManager.mMediaDevices).hasSize(1);
+        verify(mCallback).onDeviceAdded(any());
+    }
+
+    @Test
+    public void onProfileConnectionStateChanged_cachedDeviceIsDisconnect_callOnDeviceRemoved() {
+        final CachedBluetoothDevice device = mock(CachedBluetoothDevice.class);
+        final BluetoothMediaDevice bluetoothMediaDevice = mock(BluetoothMediaDevice.class);
+        mMediaManager.mMediaDevices.add(bluetoothMediaDevice);
+
+        when(device.isConnectedHearingAidDevice()).thenReturn(false);
+        when(device.isConnectedA2dpDevice()).thenReturn(false);
+        when(device.getAddress()).thenReturn(TEST_ADDRESS);
+        when(bluetoothMediaDevice.getId()).thenReturn(TEST_ADDRESS);
+
+        assertThat(mMediaManager.mMediaDevices).hasSize(1);
+        mMediaManager.registerCallback(mCallback);
+        mMediaManager.onProfileConnectionStateChanged(device, 0, 0);
+
+        assertThat(mMediaManager.mMediaDevices).isEmpty();
+        verify(mCallback).onDeviceRemoved(any());
+    }
+
+    @Test
+    public void onAclConnectionStateChanged_cachedDeviceIsConnect_callOnDeviceAdded() {
+        final CachedBluetoothDevice device = mock(CachedBluetoothDevice.class);
+
+        when(device.isConnectedHearingAidDevice()).thenReturn(true);
+        when(device.isConnectedA2dpDevice()).thenReturn(true);
+
+        assertThat(mMediaManager.mMediaDevices).isEmpty();
+        mMediaManager.registerCallback(mCallback);
+        mMediaManager.onAclConnectionStateChanged(device, 0);
+
+        assertThat(mMediaManager.mMediaDevices).hasSize(1);
+        verify(mCallback).onDeviceAdded(any());
+    }
+
+    @Test
+    public void onAclConnectionStateChanged_cachedDeviceIsDisconnect_callOnDeviceRemoved() {
+        final CachedBluetoothDevice device = mock(CachedBluetoothDevice.class);
+        final BluetoothMediaDevice bluetoothMediaDevice = mock(BluetoothMediaDevice.class);
+        mMediaManager.mMediaDevices.add(bluetoothMediaDevice);
+
+        when(device.isConnectedHearingAidDevice()).thenReturn(false);
+        when(device.isConnectedA2dpDevice()).thenReturn(false);
+        when(device.getAddress()).thenReturn(TEST_ADDRESS);
+        when(bluetoothMediaDevice.getId()).thenReturn(TEST_ADDRESS);
+
+        assertThat(mMediaManager.mMediaDevices).hasSize(1);
+        mMediaManager.registerCallback(mCallback);
+        mMediaManager.onAclConnectionStateChanged(device, 0);
+
+        assertThat(mMediaManager.mMediaDevices).isEmpty();
+        verify(mCallback).onDeviceRemoved(any());
+    }
+
+    @Test
+    public void onActiveDeviceChanged_isHapProfile_callOnActiveDeviceChanged() {
+        final CachedBluetoothDevice device = mock(CachedBluetoothDevice.class);
+
+        when(device.getAddress()).thenReturn(TEST_ADDRESS);
+
+        mMediaManager.registerCallback(mCallback);
+        mMediaManager.onActiveDeviceChanged(device, BluetoothProfile.HEARING_AID);
+
+        verify(mCallback).onConnectedDeviceChanged(any());
+    }
+
+    @Test
+    public void onActiveDeviceChanged_isA2dpProfile_callOnActiveDeviceChanged() {
+        final CachedBluetoothDevice device = mock(CachedBluetoothDevice.class);
+
+        when(device.getAddress()).thenReturn(TEST_ADDRESS);
+
+        mMediaManager.registerCallback(mCallback);
+        mMediaManager.onActiveDeviceChanged(device, BluetoothProfile.A2DP);
+
+        verify(mCallback).onConnectedDeviceChanged(any());
+    }
+
+    @Test
+    public void onActiveDeviceChanged_isNotA2dpAndHapProfile_doNothing() {
+        final CachedBluetoothDevice device = mock(CachedBluetoothDevice.class);
+
+        when(device.getAddress()).thenReturn(TEST_ADDRESS);
+
+        mMediaManager.registerCallback(mCallback);
+        mMediaManager.onActiveDeviceChanged(device, BluetoothProfile.HEALTH);
+
+        verify(mCallback, never()).onConnectedDeviceChanged(any());
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java
new file mode 100644
index 0000000..b11cf69
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.media;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+
+import androidx.mediarouter.media.MediaRouteSelector;
+import androidx.mediarouter.media.MediaRouter;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class InfoMediaManagerTest {
+
+    private static final String TEST_PACKAGE_NAME = "com.test.packagename";
+    private static final String TEST_ID = "test_id";
+
+    @Mock
+    private MediaRouter mMediaRouter;
+    @Mock
+    private MediaRouteSelector mSelector;
+
+    private InfoMediaManager mInfoMediaManager;
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+
+        mInfoMediaManager = new InfoMediaManager(mContext, TEST_PACKAGE_NAME, null);
+        mInfoMediaManager.mMediaRouter = mMediaRouter;
+        mInfoMediaManager.mSelector = mSelector;
+    }
+
+    @Test
+    public void stopScan_shouldRemoveCallback() {
+        mInfoMediaManager.stopScan();
+
+        verify(mMediaRouter).removeCallback(mInfoMediaManager.mMediaRouterCallback);
+    }
+
+    @Test
+    public void startScan_shouldAddCallback() {
+        mInfoMediaManager.startScan();
+
+        verify(mMediaRouter).addCallback(mSelector, mInfoMediaManager.mMediaRouterCallback,
+                MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
+    }
+
+    @Test
+    public void onRouteAdded_mediaDeviceNotExistInList_addMediaDevice() {
+        final MediaRouter.RouteInfo info = mock(MediaRouter.RouteInfo.class);
+        when(info.getId()).thenReturn(TEST_ID);
+
+        final MediaDevice mediaDevice = mInfoMediaManager.findMediaDevice(TEST_ID);
+        assertThat(mediaDevice).isNull();
+
+        mInfoMediaManager.mMediaRouterCallback.onRouteAdded(mMediaRouter, info);
+
+        final MediaDevice infoDevice = mInfoMediaManager.mMediaDevices.get(0);
+        assertThat(infoDevice.getId()).isEqualTo(TEST_ID);
+    }
+
+    @Test
+    public void onRouteAdded_mediaDeviceExistInList_doNothing() {
+        final MediaRouter.RouteInfo info = mock(MediaRouter.RouteInfo.class);
+        when(info.getId()).thenReturn(TEST_ID);
+        final InfoMediaDevice infoDevice = new InfoMediaDevice(mContext, info);
+        mInfoMediaManager.mMediaDevices.add(infoDevice);
+
+        final MediaDevice mediaDevice = mInfoMediaManager.findMediaDevice(TEST_ID);
+        final int size = mInfoMediaManager.mMediaDevices.size();
+        assertThat(mediaDevice).isNotNull();
+
+        mInfoMediaManager.mMediaRouterCallback.onRouteAdded(mMediaRouter, info);
+
+        assertThat(mInfoMediaManager.mMediaDevices).hasSize(size);
+    }
+
+    @Test
+    public void onRouteRemoved_mediaDeviceExistInList_removeMediaDevice() {
+        final MediaRouter.RouteInfo info = mock(MediaRouter.RouteInfo.class);
+        when(info.getId()).thenReturn(TEST_ID);
+        final InfoMediaDevice infoDevice = new InfoMediaDevice(mContext, info);
+        mInfoMediaManager.mMediaDevices.add(infoDevice);
+
+        final MediaDevice mediaDevice = mInfoMediaManager.findMediaDevice(TEST_ID);
+        assertThat(mediaDevice).isNotNull();
+        assertThat(mInfoMediaManager.mMediaDevices).hasSize(1);
+
+        mInfoMediaManager.mMediaRouterCallback.onRouteRemoved(mMediaRouter, info);
+
+        assertThat(mInfoMediaManager.mMediaDevices).isEmpty();
+    }
+
+    @Test
+    public void onRouteRemoved_mediaDeviceNotExistInList_doNothing() {
+        final MediaRouter.RouteInfo info = mock(MediaRouter.RouteInfo.class);
+        when(info.getId()).thenReturn(TEST_ID);
+
+        final MediaDevice mediaDevice = mInfoMediaManager.findMediaDevice(TEST_ID);
+        final int size = mInfoMediaManager.mMediaDevices.size();
+        assertThat(mediaDevice).isNull();
+
+        mInfoMediaManager.mMediaRouterCallback.onRouteRemoved(mMediaRouter, info);
+
+        assertThat(mInfoMediaManager.mMediaDevices).hasSize(size);
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java
new file mode 100644
index 0000000..3556814
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java
@@ -0,0 +1,369 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.media;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+
+import com.android.settingslib.bluetooth.A2dpProfile;
+import com.android.settingslib.bluetooth.HearingAidProfile;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(RobolectricTestRunner.class)
+public class LocalMediaManagerTest {
+
+    private static final String TEST_DEVICE_ID_1 = "device_id_1";
+    private static final String TEST_DEVICE_ID_2 = "device_id_2";
+    private static final String TEST_DEVICE_ID_3 = "device_id_3";
+    private static final String TEST_CURRENT_DEVICE_ID = "currentDevice_id";
+
+    @Mock
+    private BluetoothMediaManager mBluetoothMediaManager;
+    @Mock
+    private InfoMediaManager mInfoMediaManager;
+    @Mock
+    private LocalBluetoothManager mLocalBluetoothManager;
+    @Mock
+    private LocalMediaManager.DeviceCallback mCallback;
+    @Mock
+    private HearingAidProfile mHapProfile;
+    @Mock
+    private A2dpProfile mA2dpProfile;
+    @Mock
+    private LocalBluetoothProfileManager mLocalProfileManager;
+
+    private Context mContext;
+    private LocalMediaManager mLocalMediaManager;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+
+        when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalProfileManager);
+        when(mLocalProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile);
+        when(mLocalProfileManager.getHearingAidProfile()).thenReturn(mHapProfile);
+
+        mLocalMediaManager = new LocalMediaManager(mContext, mLocalBluetoothManager,
+                mBluetoothMediaManager, mInfoMediaManager);
+    }
+
+    @Test
+    public void startScan_mediaDevicesListShouldBeClear() {
+        final MediaDevice device = mock(MediaDevice.class);
+        mLocalMediaManager.mMediaDevices.add(device);
+
+        assertThat(mLocalMediaManager.mMediaDevices).hasSize(1);
+        mLocalMediaManager.startScan();
+        assertThat(mLocalMediaManager.mMediaDevices).isEmpty();
+    }
+
+    @Test
+    public void connectDevice_deviceNotEqualCurrentConnectedDevice_connectDevice() {
+        final MediaDevice currentDevice = mock(MediaDevice.class);
+        final MediaDevice device = mock(MediaDevice.class);
+        mLocalMediaManager.mMediaDevices.add(currentDevice);
+        mLocalMediaManager.mMediaDevices.add(device);
+        mLocalMediaManager.mCurrentConnectedDevice = currentDevice;
+
+        when(device.getId()).thenReturn(TEST_DEVICE_ID_1);
+        when(currentDevice.getId()).thenReturn(TEST_CURRENT_DEVICE_ID);
+
+        mLocalMediaManager.registerCallback(mCallback);
+        mLocalMediaManager.connectDevice(device);
+
+        verify(currentDevice).disconnect();
+        verify(device).connect();
+        verify(mCallback).onSelectedDeviceStateChanged(any(),
+                eq(LocalMediaManager.MediaDeviceState.STATE_DISCONNECTED));
+    }
+
+    @Test
+    public void getMediaDeviceById_idExist_shouldReturnMediaDevice() {
+        final MediaDevice device1 = mock(MediaDevice.class);
+        final MediaDevice device2 = mock(MediaDevice.class);
+        mLocalMediaManager.mMediaDevices.add(device1);
+        mLocalMediaManager.mMediaDevices.add(device2);
+
+        when(device1.getId()).thenReturn(TEST_DEVICE_ID_1);
+        when(device2.getId()).thenReturn(TEST_DEVICE_ID_2);
+
+        final MediaDevice device = mLocalMediaManager
+                .getMediaDeviceById(mLocalMediaManager.mMediaDevices, TEST_DEVICE_ID_2);
+
+        assertThat(device.getId()).isEqualTo(TEST_DEVICE_ID_2);
+    }
+
+    @Test
+    public void getMediaDeviceById_idNotExist_shouldReturnNull() {
+        final MediaDevice device1 = mock(MediaDevice.class);
+        final MediaDevice device2 = mock(MediaDevice.class);
+        mLocalMediaManager.mMediaDevices.add(device1);
+        mLocalMediaManager.mMediaDevices.add(device2);
+
+        when(device1.getId()).thenReturn(TEST_DEVICE_ID_1);
+        when(device2.getId()).thenReturn(TEST_DEVICE_ID_2);
+
+        final MediaDevice device = mLocalMediaManager
+                .getMediaDeviceById(mLocalMediaManager.mMediaDevices, TEST_CURRENT_DEVICE_ID);
+
+        assertThat(device).isNull();
+    }
+
+    @Test
+    public void onDeviceAdded_mediaDeviceAndPhoneDeviceNotExistInList_addBothDevice() {
+        final MediaDevice device = mock(MediaDevice.class);
+
+        assertThat(mLocalMediaManager.mMediaDevices).isEmpty();
+        mLocalMediaManager.registerCallback(mCallback);
+        mLocalMediaManager.mMediaDeviceCallback.onDeviceAdded(device);
+
+        assertThat(mLocalMediaManager.mMediaDevices).hasSize(2);
+        verify(mCallback).onDeviceListUpdate(any());
+    }
+
+    @Test
+    public void onDeviceAdded_mediaDeviceNotExistAndPhoneDeviceExistInList_addMediaDevice() {
+        final MediaDevice device1 = mock(MediaDevice.class);
+        final MediaDevice device2 = mock(MediaDevice.class);
+        mLocalMediaManager.mPhoneDevice = mock(PhoneMediaDevice.class);
+        mLocalMediaManager.mMediaDevices.add(device1);
+        mLocalMediaManager.mMediaDevices.add(mLocalMediaManager.mPhoneDevice);
+
+        assertThat(mLocalMediaManager.mMediaDevices).hasSize(2);
+        mLocalMediaManager.registerCallback(mCallback);
+        mLocalMediaManager.mMediaDeviceCallback.onDeviceAdded(device2);
+
+        assertThat(mLocalMediaManager.mMediaDevices).hasSize(3);
+        verify(mCallback).onDeviceListUpdate(any());
+    }
+
+    @Test
+    public void onDeviceAdded_mediaDeviceAndPhoneDeviceExistInList_doNothing() {
+        final MediaDevice device1 = mock(MediaDevice.class);
+        mLocalMediaManager.mPhoneDevice = mock(PhoneMediaDevice.class);
+        mLocalMediaManager.mMediaDevices.add(device1);
+        mLocalMediaManager.mMediaDevices.add(mLocalMediaManager.mPhoneDevice);
+
+        assertThat(mLocalMediaManager.mMediaDevices).hasSize(2);
+        mLocalMediaManager.registerCallback(mCallback);
+        mLocalMediaManager.mMediaDeviceCallback.onDeviceAdded(device1);
+
+        assertThat(mLocalMediaManager.mMediaDevices).hasSize(2);
+        verify(mCallback, never()).onDeviceListUpdate(any());
+    }
+
+    @Test
+    public void onDeviceListAdded_phoneDeviceNotExistInList_addPhoneDeviceAndDevicesList() {
+        final List<MediaDevice> devices = new ArrayList<>();
+        final MediaDevice device1 = mock(MediaDevice.class);
+        final MediaDevice device2 = mock(MediaDevice.class);
+        devices.add(device1);
+        devices.add(device2);
+
+        when(device1.getId()).thenReturn(TEST_DEVICE_ID_1);
+        when(device2.getId()).thenReturn(TEST_DEVICE_ID_2);
+
+        assertThat(mLocalMediaManager.mMediaDevices).isEmpty();
+        mLocalMediaManager.registerCallback(mCallback);
+        mLocalMediaManager.mMediaDeviceCallback.onDeviceListAdded(devices);
+
+        assertThat(mLocalMediaManager.mMediaDevices).hasSize(3);
+        verify(mCallback).onDeviceListUpdate(any());
+    }
+
+    @Test
+    public void onDeviceListAdded_phoneDeviceExistInList_addDeviceList() {
+        final List<MediaDevice> devices = new ArrayList<>();
+        final MediaDevice device1 = mock(MediaDevice.class);
+        final MediaDevice device2 = mock(MediaDevice.class);
+        final MediaDevice device3 = mock(MediaDevice.class);
+        mLocalMediaManager.mPhoneDevice = mock(PhoneMediaDevice.class);
+        devices.add(device1);
+        devices.add(device2);
+        mLocalMediaManager.mMediaDevices.add(device3);
+        mLocalMediaManager.mMediaDevices.add(mLocalMediaManager.mPhoneDevice);
+
+        when(device1.getId()).thenReturn(TEST_DEVICE_ID_1);
+        when(device2.getId()).thenReturn(TEST_DEVICE_ID_2);
+        when(device3.getId()).thenReturn(TEST_DEVICE_ID_3);
+        when(mLocalMediaManager.mPhoneDevice.getId()).thenReturn("test_phone_id");
+
+        assertThat(mLocalMediaManager.mMediaDevices).hasSize(2);
+        mLocalMediaManager.registerCallback(mCallback);
+        mLocalMediaManager.mMediaDeviceCallback.onDeviceListAdded(devices);
+
+        assertThat(mLocalMediaManager.mMediaDevices).hasSize(4);
+        verify(mCallback).onDeviceListUpdate(any());
+    }
+
+    @Test
+    public void onDeviceRemoved_phoneDeviceIsLastDeviceAfterRemoveMediaDevice_removeBothDevice() {
+        final MediaDevice device1 = mock(MediaDevice.class);
+        mLocalMediaManager.mPhoneDevice = mock(PhoneMediaDevice.class);
+        mLocalMediaManager.mMediaDevices.add(device1);
+        mLocalMediaManager.mMediaDevices.add(mLocalMediaManager.mPhoneDevice);
+
+        assertThat(mLocalMediaManager.mMediaDevices).hasSize(2);
+        mLocalMediaManager.registerCallback(mCallback);
+        mLocalMediaManager.mMediaDeviceCallback.onDeviceRemoved(device1);
+
+        assertThat(mLocalMediaManager.mMediaDevices).isEmpty();
+        verify(mCallback).onDeviceListUpdate(any());
+    }
+
+    @Test
+    public void onDeviceRemoved_phoneDeviceNotLastDeviceAfterRemoveMediaDevice_removeMediaDevice() {
+        final MediaDevice device1 = mock(MediaDevice.class);
+        final MediaDevice device2 = mock(MediaDevice.class);
+        mLocalMediaManager.mPhoneDevice = mock(PhoneMediaDevice.class);
+        mLocalMediaManager.mMediaDevices.add(device1);
+        mLocalMediaManager.mMediaDevices.add(device2);
+        mLocalMediaManager.mMediaDevices.add(mLocalMediaManager.mPhoneDevice);
+
+        assertThat(mLocalMediaManager.mMediaDevices).hasSize(3);
+        mLocalMediaManager.registerCallback(mCallback);
+        mLocalMediaManager.mMediaDeviceCallback.onDeviceRemoved(device2);
+
+        assertThat(mLocalMediaManager.mMediaDevices).hasSize(2);
+        verify(mCallback).onDeviceListUpdate(any());
+    }
+
+    @Test
+    public void onDeviceRemoved_removeMediaDeviceNotInList_doNothing() {
+        final MediaDevice device1 = mock(MediaDevice.class);
+        final MediaDevice device2 = mock(MediaDevice.class);
+        mLocalMediaManager.mPhoneDevice = mock(PhoneMediaDevice.class);
+        mLocalMediaManager.mMediaDevices.add(device2);
+        mLocalMediaManager.mMediaDevices.add(mLocalMediaManager.mPhoneDevice);
+
+        assertThat(mLocalMediaManager.mMediaDevices).hasSize(2);
+        mLocalMediaManager.registerCallback(mCallback);
+        mLocalMediaManager.mMediaDeviceCallback.onDeviceRemoved(device1);
+
+        assertThat(mLocalMediaManager.mMediaDevices).hasSize(2);
+        verify(mCallback, never()).onDeviceListUpdate(any());
+    }
+
+    @Test
+    public void onDeviceListRemoved_phoneDeviceIsLastDeviceAfterRemoveDeviceList_removeAll() {
+        final List<MediaDevice> devices = new ArrayList<>();
+        final MediaDevice device1 = mock(MediaDevice.class);
+        final MediaDevice device2 = mock(MediaDevice.class);
+        mLocalMediaManager.mPhoneDevice = mock(PhoneMediaDevice.class);
+        devices.add(device1);
+        devices.add(device2);
+        mLocalMediaManager.mMediaDevices.add(device1);
+        mLocalMediaManager.mMediaDevices.add(device2);
+        mLocalMediaManager.mMediaDevices.add(mLocalMediaManager.mPhoneDevice);
+
+        assertThat(mLocalMediaManager.mMediaDevices).hasSize(3);
+        mLocalMediaManager.registerCallback(mCallback);
+        mLocalMediaManager.mMediaDeviceCallback.onDeviceListRemoved(devices);
+
+        assertThat(mLocalMediaManager.mMediaDevices).isEmpty();
+        verify(mCallback).onDeviceListUpdate(any());
+    }
+
+    @Test
+    public void onDeviceListRemoved_phoneDeviceNotLastDeviceAfterRemoveDeviceList_removeList() {
+        final List<MediaDevice> devices = new ArrayList<>();
+        final MediaDevice device1 = mock(MediaDevice.class);
+        final MediaDevice device2 = mock(MediaDevice.class);
+        final MediaDevice device3 = mock(MediaDevice.class);
+        mLocalMediaManager.mPhoneDevice = mock(PhoneMediaDevice.class);
+        devices.add(device1);
+        devices.add(device3);
+        mLocalMediaManager.mMediaDevices.add(device1);
+        mLocalMediaManager.mMediaDevices.add(device2);
+        mLocalMediaManager.mMediaDevices.add(device3);
+        mLocalMediaManager.mMediaDevices.add(mLocalMediaManager.mPhoneDevice);
+
+        assertThat(mLocalMediaManager.mMediaDevices).hasSize(4);
+        mLocalMediaManager.registerCallback(mCallback);
+        mLocalMediaManager.mMediaDeviceCallback.onDeviceListRemoved(devices);
+
+        assertThat(mLocalMediaManager.mMediaDevices).hasSize(2);
+        verify(mCallback).onDeviceListUpdate(any());
+    }
+
+    @Test
+    public void onDeviceAttributesChanged_shouldDispatchDeviceListUpdate() {
+        mLocalMediaManager.registerCallback(mCallback);
+
+        mLocalMediaManager.mMediaDeviceCallback.onDeviceAttributesChanged();
+
+        verify(mCallback).onDeviceListUpdate(any());
+    }
+
+    @Test
+    public void onConnectedDeviceChanged_connectedAndCurrentDeviceAreDifferent_notifyThemChanged() {
+        final MediaDevice device1 = mock(MediaDevice.class);
+        final MediaDevice device2 = mock(MediaDevice.class);
+
+        mLocalMediaManager.mMediaDevices.add(device1);
+        mLocalMediaManager.mMediaDevices.add(device2);
+        mLocalMediaManager.mCurrentConnectedDevice = device1;
+
+        when(device1.getId()).thenReturn(TEST_DEVICE_ID_1);
+        when(device2.getId()).thenReturn(TEST_DEVICE_ID_2);
+
+        mLocalMediaManager.registerCallback(mCallback);
+        mLocalMediaManager.mMediaDeviceCallback.onConnectedDeviceChanged(TEST_DEVICE_ID_2);
+
+        assertThat(mLocalMediaManager.getCurrentConnectedDevice()).isEqualTo(device2);
+        verify(mCallback).onDeviceListUpdate(any());
+    }
+
+    @Test
+    public void onConnectedDeviceChanged_connectedAndCurrentDeviceAreSame_doNothing() {
+        final MediaDevice device1 = mock(MediaDevice.class);
+        final MediaDevice device2 = mock(MediaDevice.class);
+
+        mLocalMediaManager.mMediaDevices.add(device1);
+        mLocalMediaManager.mMediaDevices.add(device2);
+        mLocalMediaManager.mCurrentConnectedDevice = device1;
+
+        when(device1.getId()).thenReturn(TEST_DEVICE_ID_1);
+        when(device2.getId()).thenReturn(TEST_DEVICE_ID_2);
+
+        mLocalMediaManager.registerCallback(mCallback);
+        mLocalMediaManager.mMediaDeviceCallback.onConnectedDeviceChanged(TEST_DEVICE_ID_1);
+
+        verify(mCallback, never()).onDeviceListUpdate(any());
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java
index 9bbdd01..fc514f0 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java
@@ -25,8 +25,11 @@
 
 import androidx.mediarouter.media.MediaRouter;
 
+import com.android.settingslib.bluetooth.A2dpProfile;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.HearingAidProfile;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -78,6 +81,14 @@
     private MediaRouter.RouteInfo mRouteInfo2;
     @Mock
     private MediaRouter.RouteInfo mRouteInfo3;
+    @Mock
+    private LocalBluetoothProfileManager mProfileManager;
+    @Mock
+    private HearingAidProfile mHapProfile;
+    @Mock
+    private A2dpProfile mA2dpProfile;
+    @Mock
+    private BluetoothDevice mDevice;
 
     private BluetoothMediaDevice mBluetoothMediaDevice1;
     private BluetoothMediaDevice mBluetoothMediaDevice2;
@@ -109,6 +120,10 @@
         when(mRouteInfo1.getName()).thenReturn(DEVICE_NAME_1);
         when(mRouteInfo2.getName()).thenReturn(DEVICE_NAME_2);
         when(mRouteInfo3.getName()).thenReturn(DEVICE_NAME_3);
+        when(mLocalBluetoothManager.getProfileManager()).thenReturn(mProfileManager);
+        when(mProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile);
+        when(mProfileManager.getHearingAidProfile()).thenReturn(mHapProfile);
+        when(mA2dpProfile.getActiveDevice()).thenReturn(mDevice);
 
         mBluetoothMediaDevice1 = new BluetoothMediaDevice(mContext, mCachedDevice1);
         mBluetoothMediaDevice2 = new BluetoothMediaDevice(mContext, mCachedDevice2);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceUtilsTest.java
new file mode 100644
index 0000000..6e29e13
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceUtilsTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.media;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import androidx.mediarouter.media.MediaRouter;
+
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public class MediaDeviceUtilsTest {
+
+    private static final String TEST_ADDRESS = "11:22:33:44:55:66";
+    private static final String TEST_ROUTE_ID = "test_route_id";
+
+    @Mock
+    private CachedBluetoothDevice mDevice;
+    @Mock
+    private MediaRouter.RouteInfo mRouteInfo;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void getId_returnBluetoothDeviceAddress() {
+        when(mDevice.getAddress()).thenReturn(TEST_ADDRESS);
+
+        final String id = MediaDeviceUtils.getId(mDevice);
+
+        assertThat(id).isEqualTo(TEST_ADDRESS);
+    }
+
+    @Test
+    public void getId_returnRouteInfoId() {
+        when(mRouteInfo.getId()).thenReturn(TEST_ROUTE_ID);
+
+        final String id = MediaDeviceUtils.getId(mRouteInfo);
+
+        assertThat(id).isEqualTo(TEST_ROUTE_ID);
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaManagerTest.java
new file mode 100644
index 0000000..98eccb5
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaManagerTest.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.media;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class MediaManagerTest {
+
+    private static final String TEST_ID = "test_id";
+
+    @Mock
+    private MediaManager.MediaDeviceCallback mCallback;
+    @Mock
+    private MediaDevice mDevice;
+
+    private MediaManager mMediaManager;
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+
+        when(mDevice.getId()).thenReturn(TEST_ID);
+
+        mMediaManager = new MediaManager(mContext, null) {
+            @Override
+            public void startScan() {
+
+            }
+
+            @Override
+            public void stopScan() {
+
+            }
+        };
+    }
+
+    @Test
+    public void dispatchDeviceAdded_registerCallback_shouldDispatchCallback() {
+        mMediaManager.registerCallback(mCallback);
+
+        mMediaManager.dispatchDeviceAdded(mDevice);
+
+        verify(mCallback).onDeviceAdded(mDevice);
+    }
+
+    @Test
+    public void dispatchDeviceRemoved_registerCallback_shouldDispatchCallback() {
+        mMediaManager.registerCallback(mCallback);
+
+        mMediaManager.dispatchDeviceRemoved(mDevice);
+
+        verify(mCallback).onDeviceRemoved(mDevice);
+    }
+
+    @Test
+    public void dispatchDeviceListAdded_registerCallback_shouldDispatchCallback() {
+        mMediaManager.registerCallback(mCallback);
+
+        mMediaManager.dispatchDeviceListAdded();
+
+        verify(mCallback).onDeviceListAdded(any());
+    }
+
+    @Test
+    public void dispatchDeviceListRemoved_registerCallback_shouldDispatchCallback() {
+        mMediaManager.registerCallback(mCallback);
+
+        mMediaManager.dispatchDeviceListRemoved(mMediaManager.mMediaDevices);
+
+        verify(mCallback).onDeviceListRemoved(mMediaManager.mMediaDevices);
+    }
+
+    @Test
+    public void dispatchActiveDeviceChanged_registerCallback_shouldDispatchCallback() {
+        mMediaManager.registerCallback(mCallback);
+
+        mMediaManager.dispatchConnectedDeviceChanged(TEST_ID);
+
+        verify(mCallback).onConnectedDeviceChanged(TEST_ID);
+    }
+
+    @Test
+    public void findMediaDevice_idExist_shouldReturnMediaDevice() {
+        mMediaManager.mMediaDevices.add(mDevice);
+
+        final MediaDevice device = mMediaManager.findMediaDevice(TEST_ID);
+
+        assertThat(device.getId()).isEqualTo(mDevice.getId());
+    }
+
+    @Test
+    public void findMediaDevice_idNotExist_shouldReturnNull() {
+        mMediaManager.mMediaDevices.add(mDevice);
+
+        final MediaDevice device = mMediaManager.findMediaDevice("123");
+
+        assertThat(device).isNull();
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/PhoneMediaDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/PhoneMediaDeviceTest.java
new file mode 100644
index 0000000..5ba33f5
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/PhoneMediaDeviceTest.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.media;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.bluetooth.BluetoothDevice;
+import android.content.Context;
+
+import com.android.settingslib.bluetooth.A2dpProfile;
+import com.android.settingslib.bluetooth.HearingAidProfile;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class PhoneMediaDeviceTest {
+
+    @Mock
+    private LocalBluetoothProfileManager mLocalProfileManager;
+    @Mock
+    private LocalBluetoothManager mLocalBluetoothManager;
+    @Mock
+    private HearingAidProfile mHapProfile;
+    @Mock
+    private A2dpProfile mA2dpProfile;
+    @Mock
+    private BluetoothDevice mDevice;
+
+    private Context mContext;
+    private PhoneMediaDevice mPhoneMediaDevice;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+
+        when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalProfileManager);
+        when(mLocalProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile);
+        when(mLocalProfileManager.getHearingAidProfile()).thenReturn(mHapProfile);
+        when(mA2dpProfile.getActiveDevice()).thenReturn(mDevice);
+
+        mPhoneMediaDevice = new PhoneMediaDevice(mContext, mLocalBluetoothManager);
+    }
+
+    @Test
+    public void connect_phoneDeviceSetActiveSuccess_isConnectedReturnTrue() {
+        when(mA2dpProfile.setActiveDevice(null)).thenReturn(true);
+        when(mHapProfile.setActiveDevice(null)).thenReturn(true);
+
+        assertThat(mPhoneMediaDevice.connect()).isTrue();
+    }
+
+    @Test
+    public void connect_a2dpProfileSetActiveFail_isConnectedReturnFalse() {
+        when(mA2dpProfile.setActiveDevice(null)).thenReturn(false);
+        when(mHapProfile.setActiveDevice(null)).thenReturn(true);
+
+        assertThat(mPhoneMediaDevice.connect()).isFalse();
+    }
+
+    @Test
+    public void connect_hearingAidProfileSetActiveFail_isConnectedReturnFalse() {
+        when(mA2dpProfile.setActiveDevice(null)).thenReturn(true);
+        when(mHapProfile.setActiveDevice(null)).thenReturn(false);
+
+        assertThat(mPhoneMediaDevice.connect()).isFalse();
+    }
+
+    @Test
+    public void connect_hearingAidAndA2dpProfileSetActiveFail_isConnectedReturnFalse() {
+        when(mA2dpProfile.setActiveDevice(null)).thenReturn(false);
+        when(mHapProfile.setActiveDevice(null)).thenReturn(false);
+
+        assertThat(mPhoneMediaDevice.connect()).isFalse();
+    }
+}
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-af/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-af/strings.xml
new file mode 100644
index 0000000..9ac5fd6
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-af/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Eksperiment met verstek navigasiebalk (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-am/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-am/strings.xml
new file mode 100644
index 0000000..c15f374
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-am/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"ነባሪ የዳሰሳ አሞሌ ሙከራ (48 ዲፒ)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ar/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ar/strings.xml
new file mode 100644
index 0000000..26abf03
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ar/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"‏تجربة شريط التنقل التلقائي (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-as/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-as/strings.xml
new file mode 100644
index 0000000..cfd21b1
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-as/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"ডিফ’ল্ট নেভিগে’শ্বন বাৰ সম্পৰীক্ষা (৪৮ডিপি)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-az/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-az/strings.xml
new file mode 100644
index 0000000..a7e9110
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-az/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Defolt Naviqasiya Paneli Təcrübəsi (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-b+sr+Latn/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-b+sr+Latn/strings.xml
new file mode 100644
index 0000000..1222625
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-b+sr+Latn/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Eksperiment sa tankom trakom za navigaciju (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-be/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-be/strings.xml
new file mode 100644
index 0000000..da91427
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-be/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Эксперымент са стандартнай панэллю навігацыі (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-bg/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-bg/strings.xml
new file mode 100644
index 0000000..7295457
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-bg/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Експеримент със стандартна лента за навигация (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-bn/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-bn/strings.xml
new file mode 100644
index 0000000..1515805
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-bn/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"ডিফল্ট নেভিগেশন বার সম্পর্কিত পরীক্ষা (৪৮ ডিপি)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-bs/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-bs/strings.xml
new file mode 100644
index 0000000..dea0884
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-bs/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Eksperiment sa zadanom trakom za navigaciju (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ca/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ca/strings.xml
new file mode 100644
index 0000000..d422c86
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ca/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Experiment amb barra de navegació predeterminada (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-cs/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-cs/strings.xml
new file mode 100644
index 0000000..61d4131
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-cs/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Výchozí navigační panel – experiment (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-da/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-da/strings.xml
new file mode 100644
index 0000000..78c5ff3
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-da/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Test med standardnavigationslinje (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-de/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-de/strings.xml
new file mode 100644
index 0000000..a0779b5
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-de/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Test mit Standard-Navigationsleiste (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-el/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-el/strings.xml
new file mode 100644
index 0000000..b34cf5afb
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-el/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Πείραμα προεπιλεγμένης γραμμής πλοήγησης (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-en-rAU/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..aa3bf66
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-en-rAU/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Default Navigation Bar Experiment (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-en-rCA/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-en-rCA/strings.xml
new file mode 100644
index 0000000..aa3bf66
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-en-rCA/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Default Navigation Bar Experiment (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-en-rGB/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..aa3bf66
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-en-rGB/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Default Navigation Bar Experiment (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-en-rIN/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..aa3bf66
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-en-rIN/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Default Navigation Bar Experiment (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-es-rUS/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..81297d0
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-es-rUS/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Experimento de la barra navegación predeterminada (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-es/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-es/strings.xml
new file mode 100644
index 0000000..81297d0
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-es/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Experimento de la barra navegación predeterminada (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-et/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-et/strings.xml
new file mode 100644
index 0000000..8a442be
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-et/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Vaikenavigeerimisriba katse (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-eu/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-eu/strings.xml
new file mode 100644
index 0000000..fdf4c4e
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-eu/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Nabigazio-barra lehenetsiaren esperimentua (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-fa/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-fa/strings.xml
new file mode 100644
index 0000000..d521f79
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-fa/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"‏آزمایش نوار پیمایش پیش‌فرض (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-fi/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-fi/strings.xml
new file mode 100644
index 0000000..2e538a3
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-fi/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Oletusnavigointipalkin kokeilu (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-fr-rCA/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..171a37e
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-fr-rCA/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Expérience de barre de navigation par défaut (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-fr/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-fr/strings.xml
new file mode 100644
index 0000000..bcbf94d
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-fr/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Test relatif à la barre de navigation par défaut (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-gl/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-gl/strings.xml
new file mode 100644
index 0000000..b9a0165
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-gl/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Experimento da barra de navegación predeterminada (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-gu/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-gu/strings.xml
new file mode 100644
index 0000000..f4cdb38
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-gu/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"ડિફૉલ્ટ નૅવિગેશન બારનો પ્રયોગ (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-hi/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-hi/strings.xml
new file mode 100644
index 0000000..ee8a739
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-hi/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"डिफ़ॉल्ट नेविगेशन बार प्रयोग (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-hr/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-hr/strings.xml
new file mode 100644
index 0000000..63a5b044
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-hr/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Eksperiment s tankom navigacijskom trakom (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-hu/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-hu/strings.xml
new file mode 100644
index 0000000..110347c
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-hu/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Kísérleti alapértelmezett navigációs sáv (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-hy/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-hy/strings.xml
new file mode 100644
index 0000000..9ef0d82
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-hy/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Նավարկման կանխադրված գոտու փորձարկում (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-in/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-in/strings.xml
new file mode 100644
index 0000000..c48e0a7
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-in/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Eksperimen Menu Navigasi Default (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-is/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-is/strings.xml
new file mode 100644
index 0000000..1950f5d
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-is/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Tilraun með sjálfgefna yfirlitsstiku (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-it/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-it/strings.xml
new file mode 100644
index 0000000..45985d9
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-it/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Esperimento Barra di navigazione predefinita (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-iw/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-iw/strings.xml
new file mode 100644
index 0000000..1d99dfe
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-iw/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"‏ניסוי של סרגל ניווט דק (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ja/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ja/strings.xml
new file mode 100644
index 0000000..80e6954
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ja/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"デフォルト ナビゲーション バー テスト(48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ka/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ka/strings.xml
new file mode 100644
index 0000000..f623c11
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ka/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"ნავიგაციის ნაგულისხმევი ზოლის ექსპერიმენტი (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-kk/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-kk/strings.xml
new file mode 100644
index 0000000..f42d9ac
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-kk/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Әдепкі навигация жолағы (эксперимент) (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-km/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-km/strings.xml
new file mode 100644
index 0000000..a1316b7
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-km/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"ការពិសោធ​នៃ​របារ​រុករក​លំនាំដើម (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-kn/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-kn/strings.xml
new file mode 100644
index 0000000..15f3f4a
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-kn/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"ಡೀಫಾಲ್ಟ್ ನ್ಯಾವಿಗೇಶನ್‌ ಬಾರ್‌ ಪ್ರಯೋಗ (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ko/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ko/strings.xml
new file mode 100644
index 0000000..08a93df
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ko/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"기본 탐색 메뉴 실험(48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ky/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ky/strings.xml
new file mode 100644
index 0000000..e352c7f3
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ky/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Демейки чабыттоо тилкесин сыноо (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-lo/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-lo/strings.xml
new file mode 100644
index 0000000..6dfeacf
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-lo/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"ການທົດສອບແຖບນໍາທາງແບບບາງ (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-lt/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-lt/strings.xml
new file mode 100644
index 0000000..0752655
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-lt/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Numatytosios naršymo juostos eksperimentas (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-lv/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-lv/strings.xml
new file mode 100644
index 0000000..c72c9eb
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-lv/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Noklusējuma navigācijas joslas eksperiments (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-mk/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-mk/strings.xml
new file mode 100644
index 0000000..de21e96
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-mk/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Експеримент со стандардна лента за навигација (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ml/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ml/strings.xml
new file mode 100644
index 0000000..8870ae7
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ml/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"സ്ലിം നാവിഗേഷൻ ബാർ പരീക്ഷണം (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-mn/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-mn/strings.xml
new file mode 100644
index 0000000..29377d1
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-mn/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Өгөгдмөл навигацийн самбарын туршилт (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-mr/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-mr/strings.xml
new file mode 100644
index 0000000..3057fe7
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-mr/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"डीफॉल्ट नॅव्हिगेशन बार प्रयोग (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ms/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ms/strings.xml
new file mode 100644
index 0000000..047a6ce
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ms/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Pengalaman Bar Navigasi Lalai (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-my/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-my/strings.xml
new file mode 100644
index 0000000..37b559a
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-my/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"မူရင်း လမ်းညွှန်ဘား စမ်းသပ်မှု (၄၈dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-nb/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-nb/strings.xml
new file mode 100644
index 0000000..e6cc2af
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-nb/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Eksperiment med standard navigasjonsrad (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ne/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ne/strings.xml
new file mode 100644
index 0000000..5df6f56
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ne/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"पूर्वनिर्धारित नेभिगेसन पट्टीको परीक्षण (४८dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-nl/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-nl/strings.xml
new file mode 100644
index 0000000..f97a352
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-nl/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Experiment voor standaard navigatiebalk (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-or/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-or/strings.xml
new file mode 100644
index 0000000..e602159
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-or/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"ଡିଫଲ୍ଟ ନାଭିଗେସନ୍ ବାର୍‍ର ପ୍ରୟୋଗ (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-pa/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-pa/strings.xml
new file mode 100644
index 0000000..0c26291
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-pa/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"ਪੂਰਵ-ਨਿਰਧਾਰਤ ਦਿਸ਼ਾ-ਨਿਰਦੇਸ਼ ਪੱਟੀ ਪ੍ਰਯੋਗ (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-pl/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-pl/strings.xml
new file mode 100644
index 0000000..395e678
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-pl/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Eksperyment z domyślnym paskiem nawigacyjnym (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-pt-rBR/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..06f1966
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-pt-rBR/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Experimento de barra de navegação padrão (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-pt-rPT/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..e2bb116
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-pt-rPT/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Experiência de barra de navegação predefinida (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-pt/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-pt/strings.xml
new file mode 100644
index 0000000..06f1966
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-pt/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Experimento de barra de navegação padrão (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ro/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ro/strings.xml
new file mode 100644
index 0000000..2547137
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ro/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Experiment cu bară de navigare prestabilită (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ru/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ru/strings.xml
new file mode 100644
index 0000000..b5e26b3
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ru/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Экспериментальная панель навигации по умолчанию (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-si/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-si/strings.xml
new file mode 100644
index 0000000..7ef2c3e
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-si/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"පෙරනිමි සංචලන තීරු පරීක්‍ෂණය (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-sk/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-sk/strings.xml
new file mode 100644
index 0000000..9946848
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-sk/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Experiment s predvoleným navigačným panelom (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-sl/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-sl/strings.xml
new file mode 100644
index 0000000..34b33ae
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-sl/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Preizkus s privzeto vrstico za krmarjenje (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-sq/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-sq/strings.xml
new file mode 100644
index 0000000..428e43d
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-sq/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Eksperimenti i shiritit të parazgjedhur të navigimit (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-sr/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-sr/strings.xml
new file mode 100644
index 0000000..a1f914c
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-sr/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Експеримент са танком траком за навигацију (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-sv/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-sv/strings.xml
new file mode 100644
index 0000000..96f4f56
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-sv/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Standardnavigeringsfält för experiment (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-sw/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-sw/strings.xml
new file mode 100644
index 0000000..3ca80c2
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-sw/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Jaribio Chaguomsingi la Sehemu ya Viungo Muhimu (dp 48)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ta/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ta/strings.xml
new file mode 100644
index 0000000..2ff46e8
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ta/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"இயல்புநிலை வழிசெலுத்துதல் பட்டி சோதனை (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-te/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-te/strings.xml
new file mode 100644
index 0000000..99a32ed
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-te/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"డిఫాల్ట్ నావిగేషన్ పట్టీ ప్రయోగం (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-th/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-th/strings.xml
new file mode 100644
index 0000000..acfb209
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-th/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"การทดสอบแถบนำทางเริ่มต้น (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-tl/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-tl/strings.xml
new file mode 100644
index 0000000..6284190
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-tl/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Eksperimentong Default na Navigation Bar (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-tr/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-tr/strings.xml
new file mode 100644
index 0000000..518e801
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-tr/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Varsayılan Gezinme Çubuğu Denemesi (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-uk/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-uk/strings.xml
new file mode 100644
index 0000000..bff10a6
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-uk/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Експеримент зі стандартною панеллю навігації (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ur/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ur/strings.xml
new file mode 100644
index 0000000..ff19804
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-ur/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"‏ڈیفالٹ نیویگیشن بار کا تجربہ (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-uz/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-uz/strings.xml
new file mode 100644
index 0000000..d208c7b
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-uz/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Standart navigatsiya paneli tajribasi (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-vi/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-vi/strings.xml
new file mode 100644
index 0000000..067de92
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-vi/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Thử nghiệm thanh điều hướng mặc định (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-zh-rCN/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..75a1207
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-zh-rCN/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"默认导航栏实验 (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-zh-rHK/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..32ff1b2
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-zh-rHK/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"預設導覽列實驗 (48 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-zh-rTW/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..f8fe18c
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-zh-rTW/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"預設導覽列實驗 (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-zu/strings.xml b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-zu/strings.xml
new file mode 100644
index 0000000..0e56660
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarDefaultOverlay/res/values-zu/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="3475628315769912732">"Ukuhlolwa kwebha yokuzulazula ezenzakalelayo (48dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-af/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-af/strings.xml
new file mode 100644
index 0000000..7e52c2a
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-af/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Eksperiment met dun navigasiebalk (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-am/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-am/strings.xml
new file mode 100644
index 0000000..533bf95
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-am/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"የቀጭን ዳሰሳ አሞሌ ሙከራ (24 ዲፒ)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ar/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ar/strings.xml
new file mode 100644
index 0000000..b338de5
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ar/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"‏تجربة شريط التنقل الصغير الحجم (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-as/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-as/strings.xml
new file mode 100644
index 0000000..1c15d70
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-as/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"লাহী নেভিগে’শ্বন বাৰ সম্পৰীক্ষা (২৪ডিপি)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-az/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-az/strings.xml
new file mode 100644
index 0000000..1696946
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-az/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Ensiz Naviqasiya Paneli Təcrübəsi (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-b+sr+Latn/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-b+sr+Latn/strings.xml
new file mode 100644
index 0000000..fafec1d
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-b+sr+Latn/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Eksperiment sa tankom trakom za navigaciju (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-be/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-be/strings.xml
new file mode 100644
index 0000000..ba572a5
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-be/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Эксперымент з тонкай панэллю навігацыі (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-bg/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-bg/strings.xml
new file mode 100644
index 0000000..752eb1d
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-bg/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Експеримент с тънка лента за навигация (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-bn/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-bn/strings.xml
new file mode 100644
index 0000000..b486c9f
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-bn/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"স্লিম নেভিগেশন বার সম্পর্কিত পরীক্ষা (২৪ ডিপি)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-bs/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-bs/strings.xml
new file mode 100644
index 0000000..25fb785
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-bs/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Eksperiment s tankom trakom za navigaciju (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ca/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ca/strings.xml
new file mode 100644
index 0000000..d859f0a
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ca/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Experiment amb barra de navegació fina (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-cs/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-cs/strings.xml
new file mode 100644
index 0000000..d81c6e3
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-cs/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Úzký navigační panel – experiment (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-da/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-da/strings.xml
new file mode 100644
index 0000000..2f10bfe
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-da/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Test med smal navigationslinje (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-de/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-de/strings.xml
new file mode 100644
index 0000000..2c0937b
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-de/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Test mit schmaler Navigationsleiste (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-el/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-el/strings.xml
new file mode 100644
index 0000000..ef522b3
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-el/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Πείραμα λεπτής γραμμής πλοήγησης (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-en-rAU/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..d9958ec
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-en-rAU/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Slim Navigation Bar Experiment (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-en-rCA/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-en-rCA/strings.xml
new file mode 100644
index 0000000..d9958ec
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-en-rCA/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Slim Navigation Bar Experiment (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-en-rGB/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..d9958ec
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-en-rGB/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Slim Navigation Bar Experiment (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-en-rIN/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..d9958ec
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-en-rIN/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Slim Navigation Bar Experiment (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-es-rUS/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..7c47655
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-es-rUS/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Experimento de la barra navegación delgada (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-es/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-es/strings.xml
new file mode 100644
index 0000000..7c47655
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-es/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Experimento de la barra navegación delgada (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-et/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-et/strings.xml
new file mode 100644
index 0000000..bf23377
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-et/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Kitsa navigeerimisriba katse (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-eu/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-eu/strings.xml
new file mode 100644
index 0000000..cc4276ed
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-eu/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Nabigazio-barra finaren esperimentua (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-fa/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-fa/strings.xml
new file mode 100644
index 0000000..3c584d4
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-fa/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"‏آزمایش نوار پیمایش باریک (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-fi/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-fi/strings.xml
new file mode 100644
index 0000000..33236aa
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-fi/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Ohuen navigointipalkin kokeilu (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-fr-rCA/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..523a593
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-fr-rCA/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Expérience de barre de navigation mince (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-fr/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-fr/strings.xml
new file mode 100644
index 0000000..f5a75c7f
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-fr/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Test relatif à la barre de navigation fine (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-gl/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-gl/strings.xml
new file mode 100644
index 0000000..8a4b2ab
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-gl/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Experimento de barra de navegación estreita (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-gu/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-gu/strings.xml
new file mode 100644
index 0000000..aa3466d
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-gu/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"સ્લિમ નૅવિગેશન બારનો પ્રયોગ (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-hi/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-hi/strings.xml
new file mode 100644
index 0000000..f3a5b02
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-hi/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"स्लिम नेविगेशन बार प्रयोग (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-hr/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-hr/strings.xml
new file mode 100644
index 0000000..6532bf8
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-hr/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Eksperiment s tankom navigacijskom trakom (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-hu/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-hu/strings.xml
new file mode 100644
index 0000000..2a8adf9
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-hu/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Kísérleti keskeny navigációs sáv (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-hy/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-hy/strings.xml
new file mode 100644
index 0000000..a48dfc5
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-hy/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Նավարկման նեղ գոտու փորձարկում (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-in/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-in/strings.xml
new file mode 100644
index 0000000..961b639
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-in/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Eksperimen Menu Navigasi Ramping (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-is/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-is/strings.xml
new file mode 100644
index 0000000..659f126
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-is/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Tilraun með þunna yfirlitsstiku (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-it/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-it/strings.xml
new file mode 100644
index 0000000..57df77d
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-it/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Esperimento Barra di navigazione sottile (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-iw/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-iw/strings.xml
new file mode 100644
index 0000000..5fbc0a2
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-iw/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"‏ניסוי של סרגל ניווט דק (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ja/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ja/strings.xml
new file mode 100644
index 0000000..ab2d149
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ja/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"スリム ナビゲーション バー テスト(24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ka/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ka/strings.xml
new file mode 100644
index 0000000..2605327
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ka/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"ნავიგაციის მჭიდრო ზოლის ექსპერიმენტი (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-kk/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-kk/strings.xml
new file mode 100644
index 0000000..99c6085
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-kk/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Жіңішке навигация жолағы (эксперимент) (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-km/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-km/strings.xml
new file mode 100644
index 0000000..f63a7bc
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-km/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"ការពិសោធ​នៃ​របាររុករក​ស្ដើង (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-kn/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-kn/strings.xml
new file mode 100644
index 0000000..74a72df
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-kn/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"ಸ್ಲಿಮ್ ನ್ಯಾವಿಗೇಶನ್‌ ಬಾರ್‌ ಪ್ರಯೋಗ (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ko/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ko/strings.xml
new file mode 100644
index 0000000..0b8acb5
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ko/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"슬림한 탐색 메뉴 실험(24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ky/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ky/strings.xml
new file mode 100644
index 0000000..5629ecd
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ky/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Чакан чабыттоо тилкесин сыноо (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-lo/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-lo/strings.xml
new file mode 100644
index 0000000..71846dc
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-lo/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"ການທົດສອບແຖບນໍາທາງແບບບາງ (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-lt/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-lt/strings.xml
new file mode 100644
index 0000000..e340412
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-lt/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Plonos naršymo juostos eksperimentas (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-lv/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-lv/strings.xml
new file mode 100644
index 0000000..eb963eb
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-lv/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Plānas navigācijas joslas eksperiments (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-mk/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-mk/strings.xml
new file mode 100644
index 0000000..9e57314
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-mk/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Експеримент со тенка лента за навигација (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ml/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ml/strings.xml
new file mode 100644
index 0000000..41862af
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ml/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"സ്ലിം നാവിഗേഷൻ ബാർ പരീക്ഷണം (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-mn/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-mn/strings.xml
new file mode 100644
index 0000000..e83a219
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-mn/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Нимгэн навигацийн самбарын туршилт (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-mr/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-mr/strings.xml
new file mode 100644
index 0000000..e9ac6ee
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-mr/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"स्लिम नॅव्हिगेशन बार प्रयोग (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ms/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ms/strings.xml
new file mode 100644
index 0000000..134293c
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ms/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Pengalaman Bar Navigasi Nipis (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-my/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-my/strings.xml
new file mode 100644
index 0000000..a525c08d3
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-my/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"လမ်းညွှန်ဘားအသေး စမ်းသပ်မှု (၂၄dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-nb/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-nb/strings.xml
new file mode 100644
index 0000000..e431c90
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-nb/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Eksperiment med tynn navigasjonsrad (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ne/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ne/strings.xml
new file mode 100644
index 0000000..ff71d9a
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ne/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"पातलो नेभिगेसन पट्टीको परीक्षण (२४dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-nl/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-nl/strings.xml
new file mode 100644
index 0000000..b3a09cc
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-nl/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Experiment voor smalle navigatiebalk (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-or/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-or/strings.xml
new file mode 100644
index 0000000..98ee79b
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-or/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"ସ୍ଲିମ୍ ନାଭିଗେସନ୍ ବାର୍‍ର ପ୍ରୟୋଗ (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-pa/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-pa/strings.xml
new file mode 100644
index 0000000..06e4fd5
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-pa/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"ਸਲਿਮ ਦਿਸ਼ਾ-ਨਿਰਦੇਸ਼ ਪੱਟੀ ਪ੍ਰਯੋਗ (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-pl/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-pl/strings.xml
new file mode 100644
index 0000000..e466973
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-pl/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Eksperyment z wąskim paskiem nawigacyjnym (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-pt-rBR/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..df3c38a
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-pt-rBR/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Experimento de barra de navegação fina (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-pt-rPT/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..dc72eab
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-pt-rPT/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Experiência de barra de navegação fina (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-pt/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-pt/strings.xml
new file mode 100644
index 0000000..df3c38a
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-pt/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Experimento de barra de navegação fina (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ro/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ro/strings.xml
new file mode 100644
index 0000000..dc9200c
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ro/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Experiment cu bară de navigare subțire (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ru/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ru/strings.xml
new file mode 100644
index 0000000..99d5ce4
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ru/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Экспериментальная узкая панель навигации (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-si/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-si/strings.xml
new file mode 100644
index 0000000..501010f
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-si/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"සිහින් සංචලන තීරු පරීක්‍ෂණය (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-sk/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-sk/strings.xml
new file mode 100644
index 0000000..eaddff1
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-sk/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Experiment s úzkym navigačným panelom (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-sl/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-sl/strings.xml
new file mode 100644
index 0000000..69d777e
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-sl/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Preizkus z vitko vrstico za krmarjenje (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-sq/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-sq/strings.xml
new file mode 100644
index 0000000..9109a0e
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-sq/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Eksperimenti i shiritit të hollë të navigimit (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-sr/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-sr/strings.xml
new file mode 100644
index 0000000..eb68b0b
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-sr/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Експеримент са танком траком за навигацију (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-sv/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-sv/strings.xml
new file mode 100644
index 0000000..ed9ffa2
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-sv/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Experimentellt tunt navigeringsfält (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-sw/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-sw/strings.xml
new file mode 100644
index 0000000..bf120d6
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-sw/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Jaribio la Sehemu ya Viungo Muhimu Inayoweza Kupunguzwa (dp 24)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ta/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ta/strings.xml
new file mode 100644
index 0000000..29590cf
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ta/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"மெலிதான வழிசெலுத்துதல் பட்டி சோதனை (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-te/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-te/strings.xml
new file mode 100644
index 0000000..fa95dec
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-te/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"సన్నని నావిగేషన్ పట్టీ ప్రయోగం (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-th/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-th/strings.xml
new file mode 100644
index 0000000..e46eda2
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-th/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"การทดสอบแถบนำทางแบบบาง (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-tl/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-tl/strings.xml
new file mode 100644
index 0000000..3457f4b
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-tl/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Eksperimentong Slim na Navigation Bar (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-tr/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-tr/strings.xml
new file mode 100644
index 0000000..bab4695
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-tr/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"İnce Gezinme Çubuğu Denemesi (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-uk/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-uk/strings.xml
new file mode 100644
index 0000000..8f790be
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-uk/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Експеримент із тонкою панеллю навігації (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ur/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ur/strings.xml
new file mode 100644
index 0000000..a34cf80
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-ur/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"‏پتلے نیویگیشن بار کا تجربہ (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-uz/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-uz/strings.xml
new file mode 100644
index 0000000..a20309a
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-uz/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Ingichka navigatsiya paneli tajribasi (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-vi/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-vi/strings.xml
new file mode 100644
index 0000000..530feeb
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-vi/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Thử nghiệm thanh điều hướng mỏng (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-zh-rCN/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..6472d4f
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-zh-rCN/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"精简导航栏实验 (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-zh-rHK/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..181e41c
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-zh-rHK/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"精簡導覽列實驗 (24 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-zh-rTW/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..a6d53f4
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-zh-rTW/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"細長導覽列實驗 (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-zu/strings.xml b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-zu/strings.xml
new file mode 100644
index 0000000..338d906
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim24Overlay/res/values-zu/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="9207872199884142345">"Ukuhlolwa kwebha yokuzulazula encane (24dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-af/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-af/strings.xml
new file mode 100644
index 0000000..e3d7313
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-af/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Eksperiment met dun navigasiebalk (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-am/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-am/strings.xml
new file mode 100644
index 0000000..f3128dd
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-am/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"የቀጭን ዳሰሳ አሞሌ ሙከራ (32 ዲፒ)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ar/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ar/strings.xml
new file mode 100644
index 0000000..670d09e
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ar/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"‏تجربة شريط التنقل الصغير الحجم (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-as/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-as/strings.xml
new file mode 100644
index 0000000..42d135a
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-as/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"লাহী নেভিগে’শ্বন বাৰ সম্পৰীক্ষা (৩২ডিপি)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-az/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-az/strings.xml
new file mode 100644
index 0000000..ef07c44
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-az/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Ensiz Naviqasiya Paneli Təcrübəsi (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-b+sr+Latn/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-b+sr+Latn/strings.xml
new file mode 100644
index 0000000..024e5d5
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-b+sr+Latn/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Eksperiment sa tankom trakom za navigaciju (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-be/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-be/strings.xml
new file mode 100644
index 0000000..71ffb20
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-be/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Эксперымент з тонкай панэллю навігацыі (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-bg/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-bg/strings.xml
new file mode 100644
index 0000000..fc159b2
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-bg/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Експеримент с тънка лента за навигация (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-bn/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-bn/strings.xml
new file mode 100644
index 0000000..cba2ffb
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-bn/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"স্লিম নেভিগেশন বার সম্পর্কিত পরীক্ষা (৩২ ডিপি)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-bs/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-bs/strings.xml
new file mode 100644
index 0000000..378c39b
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-bs/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Eksperiment s tankom trakom za navigaciju (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ca/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ca/strings.xml
new file mode 100644
index 0000000..6b5c71b
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ca/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Experiment amb barra de navegació fina (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-cs/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-cs/strings.xml
new file mode 100644
index 0000000..c779583
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-cs/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Úzký navigační panel – experiment (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-da/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-da/strings.xml
new file mode 100644
index 0000000..2f83f76
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-da/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Test med smal navigationslinje (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-de/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-de/strings.xml
new file mode 100644
index 0000000..2446b8a
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-de/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Test mit schmaler Navigationsleiste (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-el/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-el/strings.xml
new file mode 100644
index 0000000..97c52cf4
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-el/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Πείραμα λεπτής γραμμής πλοήγησης (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-en-rAU/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..90e7fae
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-en-rAU/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Slim Navigation Bar Experiment (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-en-rCA/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-en-rCA/strings.xml
new file mode 100644
index 0000000..90e7fae
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-en-rCA/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Slim Navigation Bar Experiment (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-en-rGB/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..90e7fae
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-en-rGB/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Slim Navigation Bar Experiment (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-en-rIN/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..90e7fae
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-en-rIN/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Slim Navigation Bar Experiment (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-es-rUS/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..02bb563
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-es-rUS/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Experimento de la barra navegación delgada (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-es/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-es/strings.xml
new file mode 100644
index 0000000..02bb563
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-es/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Experimento de la barra navegación delgada (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-et/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-et/strings.xml
new file mode 100644
index 0000000..d979cc3
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-et/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Kitsa navigeerimisriba katse (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-eu/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-eu/strings.xml
new file mode 100644
index 0000000..a9b869c
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-eu/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Nabigazio-barra finaren esperimentua (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-fa/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-fa/strings.xml
new file mode 100644
index 0000000..fb724e0
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-fa/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"‏آزمایش نوار پیمایش باریک (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-fi/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-fi/strings.xml
new file mode 100644
index 0000000..88fa2b9
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-fi/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Ohuen navigointipalkin kokeilu (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-fr-rCA/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..2a73bd3
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-fr-rCA/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Expérience de barre de navigation mince (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-fr/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-fr/strings.xml
new file mode 100644
index 0000000..1530d81
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-fr/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Test relatif à la barre de navigation fine (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-gl/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-gl/strings.xml
new file mode 100644
index 0000000..174f501
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-gl/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Experimento da barra de navegación estreita (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-gu/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-gu/strings.xml
new file mode 100644
index 0000000..1e9de62
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-gu/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"સ્લિમ નૅવિગેશન બારનો પ્રયોગ (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-hi/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-hi/strings.xml
new file mode 100644
index 0000000..f52b1fd
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-hi/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"स्लिम नेविगेशन बार प्रयोग (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-hr/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-hr/strings.xml
new file mode 100644
index 0000000..04aed15
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-hr/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Eksperiment s tankom navigacijskom trakom (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-hu/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-hu/strings.xml
new file mode 100644
index 0000000..500b45e
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-hu/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Kísérleti keskeny navigációs sáv (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-hy/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-hy/strings.xml
new file mode 100644
index 0000000..a5f684b
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-hy/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Նավարկման նեղ գոտու փորձարկում (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-in/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-in/strings.xml
new file mode 100644
index 0000000..fe78b4c
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-in/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Eksperimen Menu Navigasi Ramping (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-is/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-is/strings.xml
new file mode 100644
index 0000000..1d6da50
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-is/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Tilraun með þunna yfirlitsstiku (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-it/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-it/strings.xml
new file mode 100644
index 0000000..dc3530e
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-it/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Esperimento Barra di navigazione sottile (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-iw/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-iw/strings.xml
new file mode 100644
index 0000000..8832941
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-iw/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"‏ניסוי של סרגל ניווט דק (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ja/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ja/strings.xml
new file mode 100644
index 0000000..7bab58a
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ja/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"スリム ナビゲーション バー テスト(32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ka/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ka/strings.xml
new file mode 100644
index 0000000..8a7f3bf
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ka/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"ნავიგაციის მჭიდრო ზოლის ექსპერიმენტი (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-kk/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-kk/strings.xml
new file mode 100644
index 0000000..182ac1a
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-kk/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Жіңішке навигация жолағы (эксперимент) (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-km/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-km/strings.xml
new file mode 100644
index 0000000..0a52f66
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-km/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"ការពិសោធ​នៃ​របាររុករក​ស្ដើង (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-kn/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-kn/strings.xml
new file mode 100644
index 0000000..118303f
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-kn/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"ಸ್ಲಿಮ್ ನ್ಯಾವಿಗೇಶನ್‌ ಬಾರ್‌ ಪ್ರಯೋಗ (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ko/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ko/strings.xml
new file mode 100644
index 0000000..11f28ce
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ko/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"슬림한 탐색 메뉴 실험(32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ky/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ky/strings.xml
new file mode 100644
index 0000000..4418c4d
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ky/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Чакан чабыттоо тилкесин сыноо (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-lo/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-lo/strings.xml
new file mode 100644
index 0000000..090ab09
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-lo/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"ການທົດສອບແຖບນໍາທາງແບບບາງ (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-lt/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-lt/strings.xml
new file mode 100644
index 0000000..cb72a0f
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-lt/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Plonos naršymo juostos eksperimentas (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-lv/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-lv/strings.xml
new file mode 100644
index 0000000..164e7d2
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-lv/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Plānas navigācijas joslas eksperiments (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-mk/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-mk/strings.xml
new file mode 100644
index 0000000..e10d685
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-mk/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Експеримент со тенка лента за навигација (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ml/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ml/strings.xml
new file mode 100644
index 0000000..878ea10
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ml/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"സ്ലിം നാവിഗേഷൻ ബാർ പരീക്ഷണം (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-mn/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-mn/strings.xml
new file mode 100644
index 0000000..a808c5c
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-mn/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Нимгэн навигацийн самбарын туршилт (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-mr/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-mr/strings.xml
new file mode 100644
index 0000000..8454ba7
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-mr/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"स्लिम नॅव्हिगेशन बार प्रयोग (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ms/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ms/strings.xml
new file mode 100644
index 0000000..6494245
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ms/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Pengalaman Bar Navigasi Nipis (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-my/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-my/strings.xml
new file mode 100644
index 0000000..11586c0
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-my/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"လမ်းညွှန်ဘားအသေး စမ်းသပ်မှု (၃၂dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-nb/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-nb/strings.xml
new file mode 100644
index 0000000..625c605
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-nb/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Eksperiment med tynn navigasjonsrad (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ne/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ne/strings.xml
new file mode 100644
index 0000000..b0d019c
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ne/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"पातलो नेभिगेसन पट्टीको परीक्षण (३२dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-nl/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-nl/strings.xml
new file mode 100644
index 0000000..9d14cef
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-nl/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Experiment voor smalle navigatiebalk (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-or/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-or/strings.xml
new file mode 100644
index 0000000..e941c52
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-or/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"ସ୍ଲିମ୍ ନାଭିଗେସନ୍ ବାର୍‍ର ପ୍ରୟୋଗ (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-pa/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-pa/strings.xml
new file mode 100644
index 0000000..c85e9d6
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-pa/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"ਸਲਿਮ ਦਿਸ਼ਾ-ਨਿਰਦੇਸ਼ ਪੱਟੀ ਪ੍ਰਯੋਗ (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-pl/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-pl/strings.xml
new file mode 100644
index 0000000..a254e62
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-pl/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Eksperyment z wąskim paskiem nawigacyjnym (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-pt-rBR/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..8bab19c
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-pt-rBR/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Experimento de barra de navegação fina (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-pt-rPT/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..133d97d
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-pt-rPT/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Experiência de barra de navegação fina (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-pt/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-pt/strings.xml
new file mode 100644
index 0000000..8bab19c
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-pt/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Experimento de barra de navegação fina (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ro/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ro/strings.xml
new file mode 100644
index 0000000..f1518718
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ro/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Experiment cu bară de navigare subțire (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ru/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ru/strings.xml
new file mode 100644
index 0000000..3031ae0
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ru/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Экспериментальная узкая панель навигации (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-si/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-si/strings.xml
new file mode 100644
index 0000000..a257a76
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-si/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"සිහින් සංචලන තීරු පරීක්‍ෂණය (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-sk/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-sk/strings.xml
new file mode 100644
index 0000000..f9fe39b
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-sk/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Experiment s úzkym navigačným panelom (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-sl/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-sl/strings.xml
new file mode 100644
index 0000000..5849b03
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-sl/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Preizkus z vitko vrstico za krmarjenje (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-sq/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-sq/strings.xml
new file mode 100644
index 0000000..719f233
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-sq/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Eksperimenti i shiritit të hollë të navigimit (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-sr/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-sr/strings.xml
new file mode 100644
index 0000000..3d67560
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-sr/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Експеримент са танком траком за навигацију (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-sv/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-sv/strings.xml
new file mode 100644
index 0000000..daee00a
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-sv/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Experimentellt tunt navigeringsfält (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-sw/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-sw/strings.xml
new file mode 100644
index 0000000..cf44256
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-sw/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Jaribio la Sehemu ya Viungo Muhimu Inayoweza Kupunguzwa (dp 32)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ta/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ta/strings.xml
new file mode 100644
index 0000000..e69442a
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ta/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"மெலிதான வழிசெலுத்துதல் பட்டி சோதனை (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-te/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-te/strings.xml
new file mode 100644
index 0000000..5a39ccf
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-te/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"సన్నని నావిగేషన్ పట్టీ ప్రయోగం (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-th/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-th/strings.xml
new file mode 100644
index 0000000..e197554
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-th/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"การทดสอบแถบนำทางแบบบาง (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-tl/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-tl/strings.xml
new file mode 100644
index 0000000..bbaa96f
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-tl/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Eksperimentong Slim na Navigation Bar (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-tr/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-tr/strings.xml
new file mode 100644
index 0000000..d315cf4
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-tr/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"İnce Gezinme Çubuğu Denemesi (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-uk/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-uk/strings.xml
new file mode 100644
index 0000000..e75f766
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-uk/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Експеримент із тонкою панеллю навігації (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ur/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ur/strings.xml
new file mode 100644
index 0000000..743903d
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-ur/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"‏پتلے نیویگیشن بار کا تجربہ (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-uz/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-uz/strings.xml
new file mode 100644
index 0000000..d8519a7
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-uz/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Ingichka navigatsiya paneli tajribasi (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-vi/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-vi/strings.xml
new file mode 100644
index 0000000..bc22ff8
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-vi/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Thử nghiệm thanh điều hướng mỏng (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-zh-rCN/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..b0e6f58
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-zh-rCN/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"精简导航栏实验 (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-zh-rHK/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..5dd0d79
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-zh-rHK/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"精簡導覽列實驗 (32 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-zh-rTW/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..b1f6b06
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-zh-rTW/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"細長導覽列實驗 (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-zu/strings.xml b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-zu/strings.xml
new file mode 100644
index 0000000..9a8bb4f
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim32Overlay/res/values-zu/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="2616250866244714325">"Ukuhlolwa kwebha yokuzulazula encane (32dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-af/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-af/strings.xml
new file mode 100644
index 0000000..e815299
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-af/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Eksperiment met dun navigasiebalk (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-am/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-am/strings.xml
new file mode 100644
index 0000000..5644a85
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-am/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"የቀጭን ዳሰሳ አሞሌ ሙከራ (40 ዲፒ)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ar/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ar/strings.xml
new file mode 100644
index 0000000..40a11de
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ar/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"‏تجربة شريط التنقل الصغير الحجم (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-as/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-as/strings.xml
new file mode 100644
index 0000000..1c4003f
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-as/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"লাহী নেভিগে’শ্বন বাৰ সম্পৰীক্ষা (৪০ডিপি)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-az/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-az/strings.xml
new file mode 100644
index 0000000..5897e75
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-az/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Ensiz Naviqasiya Paneli Təcrübəsi (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-b+sr+Latn/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-b+sr+Latn/strings.xml
new file mode 100644
index 0000000..1f49607
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-b+sr+Latn/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Eksperiment sa tankom trakom za navigaciju (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-be/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-be/strings.xml
new file mode 100644
index 0000000..2c46430
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-be/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Эксперымент з тонкай панэллю навігацыі (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-bg/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-bg/strings.xml
new file mode 100644
index 0000000..25a1496
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-bg/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Експеримент с тънка лента за навигация (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-bn/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-bn/strings.xml
new file mode 100644
index 0000000..66ba5b0
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-bn/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"স্লিম নেভিগেশন বার সম্পর্কিত পরীক্ষা (৪০ ডিপি)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-bs/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-bs/strings.xml
new file mode 100644
index 0000000..21597ce
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-bs/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Eksperiment s tankom trakom za navigaciju (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ca/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ca/strings.xml
new file mode 100644
index 0000000..34ce751
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ca/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Experiment amb barra de navegació fina (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-cs/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-cs/strings.xml
new file mode 100644
index 0000000..cd87611
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-cs/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Úzký navigační panel – experiment (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-da/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-da/strings.xml
new file mode 100644
index 0000000..fcbd7b5
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-da/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Test med smal navigationslinje (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-de/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-de/strings.xml
new file mode 100644
index 0000000..8ee35b7
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-de/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Test mit schmaler Navigationsleiste (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-el/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-el/strings.xml
new file mode 100644
index 0000000..c016e83
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-el/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Πείραμα λεπτής γραμμής πλοήγησης (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-en-rAU/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..b3621cb
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-en-rAU/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Slim Navigation Bar Experiment (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-en-rCA/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-en-rCA/strings.xml
new file mode 100644
index 0000000..b3621cb
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-en-rCA/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Slim Navigation Bar Experiment (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-en-rGB/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..b3621cb
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-en-rGB/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Slim Navigation Bar Experiment (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-en-rIN/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..b3621cb
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-en-rIN/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Slim Navigation Bar Experiment (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-es-rUS/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..d1cc0fe
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-es-rUS/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Experimento de la barra navegación delgada (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-es/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-es/strings.xml
new file mode 100644
index 0000000..d1cc0fe
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-es/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Experimento de la barra navegación delgada (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-et/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-et/strings.xml
new file mode 100644
index 0000000..64dc9ae
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-et/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Kitsa navigeerimisriba katse (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-eu/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-eu/strings.xml
new file mode 100644
index 0000000..98a4dd9
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-eu/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Nabigazio-barra finaren esperimentua (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-fa/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-fa/strings.xml
new file mode 100644
index 0000000..987ab4a
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-fa/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"‏آزمایش نوار پیمایش باریک (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-fi/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-fi/strings.xml
new file mode 100644
index 0000000..e850c3f
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-fi/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Ohuen navigointipalkin kokeilu (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-fr-rCA/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..c196ef9
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-fr-rCA/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Expérience de barre de navigation mince (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-fr/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-fr/strings.xml
new file mode 100644
index 0000000..dd1ec9c
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-fr/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Test relatif à la barre de navigation fine (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-gl/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-gl/strings.xml
new file mode 100644
index 0000000..5c44987
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-gl/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Experimento da barra de navegación estreita (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-gu/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-gu/strings.xml
new file mode 100644
index 0000000..ed1f5ce
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-gu/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"સ્લિમ નૅવિગેશન બારનો પ્રયોગ (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-hi/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-hi/strings.xml
new file mode 100644
index 0000000..64141ce
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-hi/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"स्लिम नेविगेशन बार प्रयोग (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-hr/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-hr/strings.xml
new file mode 100644
index 0000000..41ec2e7
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-hr/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Eksperiment s tankom navigacijskom trakom (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-hu/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-hu/strings.xml
new file mode 100644
index 0000000..3fb2907
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-hu/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Kísérleti keskeny navigációs sáv (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-hy/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-hy/strings.xml
new file mode 100644
index 0000000..04d6995
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-hy/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Նավարկման նեղ գոտու փորձարկում (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-in/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-in/strings.xml
new file mode 100644
index 0000000..2f01577
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-in/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Eksperimen Menu Navigasi Ramping (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-is/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-is/strings.xml
new file mode 100644
index 0000000..5ccf607
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-is/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Tilraun með þunna yfirlitsstiku (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-it/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-it/strings.xml
new file mode 100644
index 0000000..1522bd3
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-it/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Esperimento Barra di navigazione sottile (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-iw/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-iw/strings.xml
new file mode 100644
index 0000000..cf40958
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-iw/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"‏ניסוי של סרגל ניווט דק (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ja/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ja/strings.xml
new file mode 100644
index 0000000..51797e6
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ja/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"スリム ナビゲーション バー テスト(40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ka/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ka/strings.xml
new file mode 100644
index 0000000..575b453
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ka/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"ნავიგაციის მჭიდრო ზოლის ექსპერიმენტი (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-kk/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-kk/strings.xml
new file mode 100644
index 0000000..4febe3f
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-kk/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Жіңішке навигация жолағы (эксперимент) (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-km/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-km/strings.xml
new file mode 100644
index 0000000..58b9e16
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-km/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"ការពិសោធ​នៃ​របាររុករក​ស្ដើង (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-kn/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-kn/strings.xml
new file mode 100644
index 0000000..35a6776
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-kn/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"ಸ್ಲಿಮ್ ನ್ಯಾವಿಗೇಶನ್‌ ಬಾರ್‌ ಪ್ರಯೋಗ (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ko/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ko/strings.xml
new file mode 100644
index 0000000..bced462
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ko/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"슬림한 탐색 메뉴 실험(40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ky/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ky/strings.xml
new file mode 100644
index 0000000..8b34990
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ky/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Чакан чабыттоо тилкесин сыноо (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-lo/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-lo/strings.xml
new file mode 100644
index 0000000..b7fe3cf
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-lo/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"ການທົດສອບແຖບນໍາທາງແບບບາງ (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-lt/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-lt/strings.xml
new file mode 100644
index 0000000..808a90c
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-lt/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Plonos naršymo juostos eksperimentas (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-lv/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-lv/strings.xml
new file mode 100644
index 0000000..002e8687
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-lv/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Plānas navigācijas joslas eksperiments (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-mk/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-mk/strings.xml
new file mode 100644
index 0000000..148b5ed
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-mk/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Експеримент со тенка лента за навигација (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ml/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ml/strings.xml
new file mode 100644
index 0000000..be37488
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ml/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"സ്ലിം നാവിഗേഷൻ ബാർ പരീക്ഷണം (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-mn/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-mn/strings.xml
new file mode 100644
index 0000000..41e2ce1
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-mn/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Нимгэн навигацийн самбарын туршилт (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-mr/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-mr/strings.xml
new file mode 100644
index 0000000..d946257
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-mr/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"स्लिम नॅव्हिगेशन बार प्रयोग (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ms/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ms/strings.xml
new file mode 100644
index 0000000..a442be3
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ms/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Pengalaman Bar Navigasi Nipis (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-my/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-my/strings.xml
new file mode 100644
index 0000000..f12cf41
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-my/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"လမ်းညွှန်ဘားအသေး စမ်းသပ်မှု (၄၀dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-nb/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-nb/strings.xml
new file mode 100644
index 0000000..d138836
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-nb/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Eksperiment med tynn navigasjonsrad (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ne/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ne/strings.xml
new file mode 100644
index 0000000..9fce6c2
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ne/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"पातलो नेभिगेसन पट्टीको परीक्षण (४०dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-nl/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-nl/strings.xml
new file mode 100644
index 0000000..8eae8ce
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-nl/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Experiment voor smalle navigatiebalk (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-or/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-or/strings.xml
new file mode 100644
index 0000000..aff8e9c
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-or/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"ସ୍ଲିମ୍ ନାଭିଗେସନ୍‍ ବାର୍‍ର ପ୍ରୟୋଗ (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-pa/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-pa/strings.xml
new file mode 100644
index 0000000..c23a03f
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-pa/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"ਸਲਿਮ ਦਿਸ਼ਾ-ਨਿਰਦੇਸ਼ ਪੱਟੀ ਪ੍ਰਯੋਗ (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-pl/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-pl/strings.xml
new file mode 100644
index 0000000..7cd3e4e
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-pl/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Eksperyment z wąskim paskiem nawigacyjnym (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-pt-rBR/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..dbc47fd
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-pt-rBR/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Experimento de barra de navegação fina (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-pt-rPT/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..82ef087
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-pt-rPT/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Experiência de barra de navegação fina (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-pt/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-pt/strings.xml
new file mode 100644
index 0000000..dbc47fd
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-pt/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Experimento de barra de navegação fina (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ro/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ro/strings.xml
new file mode 100644
index 0000000..18a96e0
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ro/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Experiment cu bară de navigare subțire (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ru/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ru/strings.xml
new file mode 100644
index 0000000..195ab10
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ru/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Экспериментальная узкая панель навигации (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-si/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-si/strings.xml
new file mode 100644
index 0000000..0bda351
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-si/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"සිහින් සංචලන තීරු පරීක්‍ෂණය (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-sk/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-sk/strings.xml
new file mode 100644
index 0000000..9aebdfbe
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-sk/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Experiment s úzkym navigačným panelom (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-sl/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-sl/strings.xml
new file mode 100644
index 0000000..68f6e6d
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-sl/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Preizkus z vitko vrstico za krmarjenje (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-sq/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-sq/strings.xml
new file mode 100644
index 0000000..18c1ff0
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-sq/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Eksperimenti i shiritit të hollë të navigimit (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-sr/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-sr/strings.xml
new file mode 100644
index 0000000..8067165
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-sr/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Експеримент са танком траком за навигацију (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-sv/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-sv/strings.xml
new file mode 100644
index 0000000..d91626e
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-sv/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Experimentellt tunt navigeringsfält (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-sw/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-sw/strings.xml
new file mode 100644
index 0000000..f3ca208
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-sw/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Jaribio la Sehemu ya Viungo Muhimu Inayoweza Kupunguzwa (dp 40)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ta/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ta/strings.xml
new file mode 100644
index 0000000..04bee67
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ta/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"மெலிதான வழிசெலுத்துதல் பட்டி சோதனை (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-te/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-te/strings.xml
new file mode 100644
index 0000000..fc0cd55
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-te/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"సన్నని నావిగేషన్ పట్టీ ప్రయోగం (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-th/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-th/strings.xml
new file mode 100644
index 0000000..33d46e4
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-th/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"การทดสอบแถบนำทางแบบบาง (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-tl/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-tl/strings.xml
new file mode 100644
index 0000000..bf6451f
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-tl/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Eksperimentong Slim na Navigation Bar (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-tr/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-tr/strings.xml
new file mode 100644
index 0000000..7918059
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-tr/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"İnce Gezinme  Çubuğu Denemesi (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-uk/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-uk/strings.xml
new file mode 100644
index 0000000..b45b9b4
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-uk/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Експеримент із тонкою панеллю навігації (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ur/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ur/strings.xml
new file mode 100644
index 0000000..9281ff8
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-ur/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"‏پتلے نیویگیشن بار کا تجربہ (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-uz/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-uz/strings.xml
new file mode 100644
index 0000000..46e7334
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-uz/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Ingichka navigatsiya paneli tajribasi (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-vi/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-vi/strings.xml
new file mode 100644
index 0000000..ea0f155
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-vi/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Thử nghiệm thanh điều hướng mỏng (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-zh-rCN/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..5746854
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-zh-rCN/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"精简导航栏实验 (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-zh-rHK/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..aad885b
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-zh-rHK/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"精簡導覽列實驗 (40 dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-zh-rTW/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..590e4f5
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-zh-rTW/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"細長導覽列實驗 (40dp)"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-zu/strings.xml b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-zu/strings.xml
new file mode 100644
index 0000000..e077f08
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlim40Overlay/res/values-zu/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="experiment_navigationbar_overlay" msgid="6415947279345789008">"Ukuhlolwa kwebha yokuzulazula encane (40dp)"</string>
+</resources>
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index ff378b3..14322ec 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -124,6 +124,11 @@
      */
     @VisibleForTesting
     protected void startServiceForUser(int userId) {
+        if (mServiceUsers.get(userId) != null) {
+            Slog.i(TAG, "userId " + userId + " already started, so not starting again");
+            return;
+        }
+
         UserBackupManagerService userBackupManagerService =
                 UserBackupManagerService.createAndInitializeService(
                         userId, mContext, mTrampoline, mTransportWhitelist);
@@ -155,7 +160,12 @@
         }
     }
 
-    SparseArray<UserBackupManagerService> getServiceUsers() {
+    /**
+     *  Returns a lst of users currently unlocked that have a
+     *  {@link UserBackupManagerService} registered.
+     */
+    @VisibleForTesting
+    public SparseArray<UserBackupManagerService> getServiceUsers() {
         return mServiceUsers;
     }
 
diff --git a/services/backup/java/com/android/server/backup/Trampoline.java b/services/backup/java/com/android/server/backup/Trampoline.java
index 4ca2545..b9a6f3c 100644
--- a/services/backup/java/com/android/server/backup/Trampoline.java
+++ b/services/backup/java/com/android/server/backup/Trampoline.java
@@ -32,7 +32,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.os.Binder;
-import android.os.Environment;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IBinder;
@@ -45,7 +44,6 @@
 import android.provider.Settings;
 import android.util.Slog;
 
-import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.DumpUtils;
 
 import java.io.File;
@@ -65,8 +63,8 @@
  * following two ways:
  *
  * <ul>
- *   <li>Temporary - create the file {@link #BACKUP_SUPPRESS_FILENAME}, or
- *   <li>Permanent - set the system property {@link #BACKUP_DISABLE_PROPERTY} to true.
+ * <li>Temporary - create the file {@link #BACKUP_SUPPRESS_FILENAME}, or
+ * <li>Permanent - set the system property {@link #BACKUP_DISABLE_PROPERTY} to true.
  * </ul>
  *
  * Temporary disabling is controlled by {@link #setBackupServiceActive(int, boolean)} through
@@ -91,10 +89,9 @@
 
     private final Context mContext;
 
-    @GuardedBy("mStateLock")
-    private final File mSuppressFile;
-
     private final boolean mGlobalDisable;
+    // Lock to write backup suppress files.
+    // TODD(b/121198006): remove this object and synchronized all methods on "this".
     private final Object mStateLock = new Object();
 
     private volatile BackupManagerService mService;
@@ -104,9 +101,6 @@
     public Trampoline(Context context) {
         mContext = context;
         mGlobalDisable = isBackupDisabled();
-        mSuppressFile = getSuppressFile();
-        mSuppressFile.getParentFile().mkdirs();
-
         mHandlerThread = new HandlerThread(BACKUP_THREAD, Process.THREAD_PRIORITY_BACKGROUND);
         mHandlerThread.start();
         mHandler = new Handler(mHandlerThread.getLooper());
@@ -132,11 +126,42 @@
         return Binder.getCallingUid();
     }
 
-    protected File getSuppressFile() {
-        return new File(new File(Environment.getDataDirectory(), "backup"),
+    protected File getSuppressFileForUser(int userId) {
+        return new File(UserBackupManagerFiles.getBaseStateDir(userId),
                 BACKUP_SUPPRESS_FILENAME);
     }
 
+    protected void createBackupSuppressFileForUser(int userId) throws IOException {
+        synchronized (mStateLock) {
+            getSuppressFileForUser(userId).getParentFile().mkdirs();
+            getSuppressFileForUser(userId).createNewFile();
+        }
+    }
+
+    private void deleteBackupSuppressFileForUser(int userId) {
+        if (!getSuppressFileForUser(userId).delete()) {
+            Slog.w(TAG, "Failed deleting backup suppressed file for user: " + userId);
+        }
+    }
+
+    // A user is ready for a backup if it's unlocked and is not suppressed by a device
+    // admin (device owner or profile owner).
+    private boolean isUserReadyForBackup(int userId) {
+        return mService != null && mService.getServiceUsers().get(userId) != null
+                && !isBackupSuppressedForUser(userId);
+    }
+
+    private boolean isBackupSuppressedForUser(int userId) {
+        // If backup is disabled for system user, it's disabled for all other users on device.
+        if (getSuppressFileForUser(UserHandle.USER_SYSTEM).exists()) {
+            return true;
+        }
+        if (userId != UserHandle.USER_SYSTEM) {
+            return getSuppressFileForUser(userId).exists();
+        }
+        return false;
+    }
+
     protected Context getContext() {
         return mContext;
     }
@@ -162,12 +187,9 @@
                         Slog.i(TAG, "Backup service not supported");
                         return;
                     }
-
                     synchronized (mStateLock) {
-                        if (!mSuppressFile.exists()) {
+                        if (mService == null) {
                             mService = createBackupManagerService();
-                        } else {
-                            Slog.i(TAG, "Backup service inactive");
                         }
                     }
                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
@@ -190,10 +212,11 @@
     }
 
     private void startServiceForUser(int userId) {
-        BackupManagerService service = mService;
-        if (service != null) {
+        // We know that the user is unlocked here because it is called from setBackupServiceActive
+        // and unlockUser which have these guarantees. So we can check if the file exists.
+        if (mService != null && !isBackupSuppressedForUser(userId)) {
             Slog.i(TAG, "Starting service for user: " + userId);
-            service.startServiceForUser(userId);
+            mService.startServiceForUser(userId);
         }
     }
 
@@ -209,10 +232,9 @@
 
         postToHandler(
                 () -> {
-                    BackupManagerService service = mService;
-                    if (service != null) {
+                    if (mService != null) {
                         Slog.i(TAG, "Stopping service for user: " + userId);
-                        service.stopServiceForUser(userId);
+                        mService.stopServiceForUser(userId);
                     }
                 });
     }
@@ -221,6 +243,8 @@
      * Only privileged callers should be changing the backup state. This method only acts on {@link
      * UserHandle#USER_SYSTEM} and is a no-op if passed non-system users. Deactivating backup in the
      * system user also deactivates backup in all users.
+     *
+     * This call will only work if the calling {@code userID} is unlocked.
      */
     public void setBackupServiceActive(int userId, boolean makeActive) {
         int caller = binderGetCallingUid();
@@ -246,16 +270,21 @@
         synchronized (mStateLock) {
             Slog.i(TAG, "Making backup " + (makeActive ? "" : "in") + "active");
             if (makeActive) {
-                mService = createBackupManagerService();
-                mSuppressFile.delete();
+                if (mService == null) {
+                    mService = createBackupManagerService();
+                }
+                deleteBackupSuppressFileForUser(userId);
                 startServiceForUser(userId);
             } else {
-                mService = null;
                 try {
-                    mSuppressFile.createNewFile();
+                    //TODO(b/121198006): what if this throws an exception?
+                    createBackupSuppressFileForUser(userId);
                 } catch (IOException e) {
                     Slog.e(TAG, "Unable to persist backup service inactivity");
                 }
+                //TODO(b/121198006): loop through active users that have work profile and
+                // stop them as well.
+                stopUser(userId);
             }
         }
     }
@@ -271,20 +300,15 @@
      */
     @Override
     public boolean isBackupServiceActive(int userId) {
-        // TODO: http://b/22388012
-        if (userId == UserHandle.USER_SYSTEM) {
-            synchronized (mStateLock) {
-                return mService != null;
-            }
+        synchronized (mStateLock) {
+            return isUserReadyForBackup(userId);
         }
-        return false;
     }
 
     @Override
     public void dataChangedForUser(int userId, String packageName) throws RemoteException {
-        BackupManagerService svc = mService;
-        if (svc != null) {
-            svc.dataChanged(userId, packageName);
+        if (isUserReadyForBackup(userId)) {
+            mService.dataChanged(userId, packageName);
         }
     }
 
@@ -296,18 +320,16 @@
     @Override
     public void initializeTransportsForUser(
             int userId, String[] transportNames, IBackupObserver observer) throws RemoteException {
-        BackupManagerService svc = mService;
-        if (svc != null) {
-            svc.initializeTransports(userId, transportNames, observer);
+        if (isUserReadyForBackup(userId)) {
+            mService.initializeTransports(userId, transportNames, observer);
         }
     }
 
     @Override
     public void clearBackupDataForUser(int userId, String transportName, String packageName)
             throws RemoteException {
-        BackupManagerService svc = mService;
-        if (svc != null) {
-            svc.clearBackupData(userId, transportName, packageName);
+        if (isUserReadyForBackup(userId)) {
+            mService.clearBackupData(userId, transportName, packageName);
         }
     }
 
@@ -320,9 +342,8 @@
     @Override
     public void agentConnectedForUser(int userId, String packageName, IBinder agent)
             throws RemoteException {
-        BackupManagerService svc = mService;
-        if (svc != null) {
-            svc.agentConnected(userId, packageName, agent);
+        if (isUserReadyForBackup(userId)) {
+            mService.agentConnected(userId, packageName, agent);
         }
     }
 
@@ -333,9 +354,8 @@
 
     @Override
     public void agentDisconnectedForUser(int userId, String packageName) throws RemoteException {
-        BackupManagerService svc = mService;
-        if (svc != null) {
-            svc.agentDisconnected(userId, packageName);
+        if (isUserReadyForBackup(userId)) {
+            mService.agentDisconnected(userId, packageName);
         }
     }
 
@@ -347,9 +367,8 @@
     @Override
     public void restoreAtInstallForUser(int userId, String packageName, int token)
             throws RemoteException {
-        BackupManagerService svc = mService;
-        if (svc != null) {
-            svc.restoreAtInstall(userId, packageName, token);
+        if (isUserReadyForBackup(userId)) {
+            mService.restoreAtInstall(userId, packageName, token);
         }
     }
 
@@ -361,9 +380,8 @@
     @Override
     public void setBackupEnabledForUser(@UserIdInt int userId, boolean isEnabled)
             throws RemoteException {
-        BackupManagerService svc = mService;
-        if (svc != null) {
-            svc.setBackupEnabled(userId, isEnabled);
+        if (isUserReadyForBackup(userId)) {
+            mService.setBackupEnabled(userId, isEnabled);
         }
     }
 
@@ -374,9 +392,8 @@
 
     @Override
     public void setAutoRestoreForUser(int userId, boolean doAutoRestore) throws RemoteException {
-        BackupManagerService svc = mService;
-        if (svc != null) {
-            svc.setAutoRestore(userId, doAutoRestore);
+        if (isUserReadyForBackup(userId)) {
+            mService.setAutoRestore(userId, doAutoRestore);
         }
     }
 
@@ -387,8 +404,7 @@
 
     @Override
     public boolean isBackupEnabledForUser(@UserIdInt int userId) throws RemoteException {
-        BackupManagerService svc = mService;
-        return (svc != null) ? svc.isBackupEnabled(userId) : false;
+        return isUserReadyForBackup(userId) && mService.isBackupEnabled(userId);
     }
 
     @Override
@@ -398,21 +414,20 @@
 
     @Override
     public boolean setBackupPassword(String currentPw, String newPw) throws RemoteException {
-        BackupManagerService svc = mService;
-        return (svc != null) ? svc.setBackupPassword(currentPw, newPw) : false;
+        int userId = binderGetCallingUserId();
+        return (isUserReadyForBackup(userId)) && mService.setBackupPassword(currentPw, newPw);
     }
 
     @Override
     public boolean hasBackupPassword() throws RemoteException {
-        BackupManagerService svc = mService;
-        return (svc != null) ? svc.hasBackupPassword() : false;
+        int userId = binderGetCallingUserId();
+        return (isUserReadyForBackup(userId)) && mService.hasBackupPassword();
     }
 
     @Override
     public void backupNowForUser(@UserIdInt int userId) throws RemoteException {
-        BackupManagerService svc = mService;
-        if (svc != null) {
-            svc.backupNow(userId);
+        if (isUserReadyForBackup(userId)) {
+            mService.backupNow(userId);
         }
     }
 
@@ -425,9 +440,8 @@
             boolean includeApks, boolean includeObbs, boolean includeShared, boolean doWidgets,
             boolean allApps, boolean allIncludesSystem, boolean doCompress, boolean doKeyValue,
             String[] packageNames) throws RemoteException {
-        BackupManagerService svc = mService;
-        if (svc != null) {
-            svc.adbBackup(userId, fd, includeApks, includeObbs, includeShared, doWidgets,
+        if (isUserReadyForBackup(userId)) {
+            mService.adbBackup(userId, fd, includeApks, includeObbs, includeShared, doWidgets,
                     allApps, allIncludesSystem, doCompress, doKeyValue, packageNames);
         }
     }
@@ -435,17 +449,15 @@
     @Override
     public void fullTransportBackupForUser(int userId, String[] packageNames)
             throws RemoteException {
-        BackupManagerService svc = mService;
-        if (svc != null) {
-            svc.fullTransportBackup(userId, packageNames);
+        if (isUserReadyForBackup(userId)) {
+            mService.fullTransportBackup(userId, packageNames);
         }
     }
 
     @Override
     public void adbRestore(@UserIdInt int userId, ParcelFileDescriptor fd) throws RemoteException {
-        BackupManagerService svc = mService;
-        if (svc != null) {
-            svc.adbRestore(userId, fd);
+        if (isUserReadyForBackup(userId)) {
+            mService.adbRestore(userId, fd);
         }
     }
 
@@ -458,9 +470,8 @@
             String encryptionPassword,
             IFullBackupRestoreObserver observer)
             throws RemoteException {
-        BackupManagerService svc = mService;
-        if (svc != null) {
-            svc.acknowledgeAdbBackupOrRestore(userId, token, allow,
+        if (isUserReadyForBackup(userId)) {
+            mService.acknowledgeAdbBackupOrRestore(userId, token, allow,
                     curPassword, encryptionPassword, observer);
         }
     }
@@ -468,8 +479,7 @@
     @Override
     public void acknowledgeFullBackupOrRestore(int token, boolean allow, String curPassword,
             String encryptionPassword, IFullBackupRestoreObserver observer)
-                    throws RemoteException {
-        BackupManagerService svc = mService;
+            throws RemoteException {
         acknowledgeFullBackupOrRestoreForUser(
                 binderGetCallingUserId(), token, allow, curPassword, encryptionPassword, observer);
     }
@@ -477,8 +487,7 @@
 
     @Override
     public String getCurrentTransportForUser(int userId) throws RemoteException {
-        BackupManagerService svc = mService;
-        return (svc != null) ? svc.getCurrentTransport(userId) : null;
+        return (isUserReadyForBackup(userId)) ? mService.getCurrentTransport(userId) : null;
     }
 
     @Override
@@ -493,14 +502,13 @@
     @Override
     @Nullable
     public ComponentName getCurrentTransportComponentForUser(int userId) {
-        BackupManagerService svc = mService;
-        return (svc != null) ? svc.getCurrentTransportComponent(userId) : null;
+        return (isUserReadyForBackup(userId)) ? mService.getCurrentTransportComponent(userId)
+                : null;
     }
 
     @Override
     public String[] listAllTransportsForUser(int userId) throws RemoteException {
-        BackupManagerService svc = mService;
-        return (svc != null) ? svc.listAllTransports(userId) : null;
+        return (isUserReadyForBackup(userId)) ? mService.listAllTransports(userId) : null;
     }
 
     @Override
@@ -510,14 +518,14 @@
 
     @Override
     public ComponentName[] listAllTransportComponentsForUser(int userId) throws RemoteException {
-        BackupManagerService svc = mService;
-        return (svc != null) ? svc.listAllTransportComponents(userId) : null;
+        return (isUserReadyForBackup(userId)) ? mService.listAllTransportComponents(userId)
+                : null;
     }
 
     @Override
     public String[] getTransportWhitelist() {
-        BackupManagerService svc = mService;
-        return (svc != null) ? svc.getTransportWhitelist() : null;
+        int userId = binderGetCallingUserId();
+        return (isUserReadyForBackup(userId)) ? mService.getTransportWhitelist() : null;
     }
 
     @Override
@@ -529,9 +537,9 @@
             String currentDestinationString,
             @Nullable Intent dataManagementIntent,
             String dataManagementLabel) {
-        BackupManagerService svc = mService;
-        if (svc != null) {
-            svc.updateTransportAttributes(
+
+        if (isUserReadyForBackup(userId)) {
+            mService.updateTransportAttributes(
                     userId,
                     transportComponent,
                     name,
@@ -545,8 +553,8 @@
     @Override
     public String selectBackupTransportForUser(int userId, String transport)
             throws RemoteException {
-        BackupManagerService svc = mService;
-        return (svc != null) ? svc.selectBackupTransport(userId, transport) : null;
+        return (isUserReadyForBackup(userId)) ? mService.selectBackupTransport(userId, transport)
+                : null;
     }
 
     @Override
@@ -557,9 +565,8 @@
     @Override
     public void selectBackupTransportAsyncForUser(int userId, ComponentName transport,
             ISelectBackupTransportCallback listener) throws RemoteException {
-        BackupManagerService svc = mService;
-        if (svc != null) {
-            svc.selectBackupTransportAsync(userId, transport, listener);
+        if (isUserReadyForBackup(userId)) {
+            mService.selectBackupTransportAsync(userId, transport, listener);
         } else {
             if (listener != null) {
                 try {
@@ -574,8 +581,8 @@
     @Override
     public Intent getConfigurationIntentForUser(int userId, String transport)
             throws RemoteException {
-        BackupManagerService svc = mService;
-        return (svc != null) ? svc.getConfigurationIntent(userId, transport) : null;
+        return isUserReadyForBackup(userId) ? mService.getConfigurationIntent(userId, transport)
+                : null;
     }
 
     @Override
@@ -586,8 +593,8 @@
 
     @Override
     public String getDestinationStringForUser(int userId, String transport) throws RemoteException {
-        BackupManagerService svc = mService;
-        return (svc != null) ? svc.getDestinationString(userId, transport) : null;
+        return isUserReadyForBackup(userId) ? mService.getDestinationString(userId, transport)
+                : null;
     }
 
     @Override
@@ -598,8 +605,8 @@
     @Override
     public Intent getDataManagementIntentForUser(int userId, String transport)
             throws RemoteException {
-        BackupManagerService svc = mService;
-        return (svc != null) ? svc.getDataManagementIntent(userId, transport) : null;
+        return isUserReadyForBackup(userId) ? mService.getDataManagementIntent(userId, transport)
+                : null;
     }
 
     @Override
@@ -611,8 +618,8 @@
     @Override
     public String getDataManagementLabelForUser(int userId, String transport)
             throws RemoteException {
-        BackupManagerService svc = mService;
-        return (svc != null) ? svc.getDataManagementLabel(userId, transport) : null;
+        return isUserReadyForBackup(userId) ? mService.getDataManagementLabel(userId, transport)
+                : null;
     }
 
     @Override
@@ -624,44 +631,43 @@
     @Override
     public IRestoreSession beginRestoreSessionForUser(
             int userId, String packageName, String transportID) throws RemoteException {
-        BackupManagerService svc = mService;
-        return (svc != null) ? svc.beginRestoreSession(userId, packageName, transportID) : null;
+        return isUserReadyForBackup(userId) ? mService.beginRestoreSession(userId, packageName,
+                transportID) : null;
     }
 
     @Override
     public void opComplete(int token, long result) throws RemoteException {
-        BackupManagerService svc = mService;
-        if (svc != null) {
-            svc.opComplete(binderGetCallingUserId(), token, result);
+        int userId = binderGetCallingUserId();
+        if (isUserReadyForBackup(userId)) {
+            mService.opComplete(binderGetCallingUserId(), token, result);
         }
     }
 
     @Override
     public long getAvailableRestoreTokenForUser(int userId, String packageName) {
-        BackupManagerService svc = mService;
-        return (svc != null) ? svc.getAvailableRestoreToken(userId, packageName) : 0;
+        return isUserReadyForBackup(userId) ? mService.getAvailableRestoreToken(userId,
+                packageName) : 0;
     }
 
     @Override
     public boolean isAppEligibleForBackupForUser(int userId, String packageName) {
-        BackupManagerService svc = mService;
-        return (svc != null) ? svc.isAppEligibleForBackup(userId, packageName) : false;
+        return isUserReadyForBackup(userId) && mService.isAppEligibleForBackup(userId,
+                packageName);
     }
 
     @Override
     public String[] filterAppsEligibleForBackupForUser(int userId, String[] packages) {
-        BackupManagerService svc = mService;
-        return (svc != null) ? svc.filterAppsEligibleForBackup(userId, packages) : null;
+        return isUserReadyForBackup(userId) ? mService.filterAppsEligibleForBackup(userId,
+                packages) : null;
     }
 
     @Override
     public int requestBackupForUser(@UserIdInt int userId, String[] packages, IBackupObserver
             observer, IBackupManagerMonitor monitor, int flags) throws RemoteException {
-        BackupManagerService svc = mService;
-        if (svc == null) {
+        if (!isUserReadyForBackup(userId)) {
             return BackupManager.ERROR_BACKUP_NOT_ALLOWED;
         }
-        return svc.requestBackup(userId, packages, observer, monitor, flags);
+        return mService.requestBackup(userId, packages, observer, monitor, flags);
     }
 
     @Override
@@ -673,9 +679,8 @@
 
     @Override
     public void cancelBackupsForUser(@UserIdInt int userId) throws RemoteException {
-        BackupManagerService svc = mService;
-        if (svc != null) {
-            svc.cancelBackups(userId);
+        if (isUserReadyForBackup(userId)) {
+            mService.cancelBackups(userId);
         }
     }
 
@@ -687,10 +692,9 @@
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
-
-        BackupManagerService svc = mService;
-        if (svc != null) {
-            svc.dump(fd, pw, args);
+        int userId = binderGetCallingUserId();
+        if (isUserReadyForBackup(userId)) {
+            mService.dump(fd, pw, args);
         } else {
             pw.println("Inactive");
         }
@@ -699,14 +703,12 @@
     // Full backup/restore entry points - non-Binder; called directly
     // by the full-backup scheduled job
     /* package */ boolean beginFullBackup(@UserIdInt int userId, FullBackupJob scheduledJob) {
-        BackupManagerService svc = mService;
-        return (svc != null) ? svc.beginFullBackup(userId, scheduledJob) : false;
+        return (isUserReadyForBackup(userId)) && mService.beginFullBackup(userId, scheduledJob);
     }
 
     /* package */ void endFullBackup(@UserIdInt int userId) {
-        BackupManagerService svc = mService;
-        if (svc != null) {
-            svc.endFullBackup(userId);
+        if (isUserReadyForBackup(userId)) {
+            mService.endFullBackup(userId);
         }
     }
 }
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index aed0684..c84389b 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -39,14 +39,6 @@
 import static android.net.NetworkStats.UID_ALL;
 import static android.net.TrafficStats.UID_TETHERING;
 
-import static com.android.server.NetworkManagementService.NetdResponseCode.ClatdStatusResult;
-import static com.android.server.NetworkManagementService.NetdResponseCode.InterfaceGetCfgResult;
-import static com.android.server.NetworkManagementService.NetdResponseCode.InterfaceListResult;
-import static com.android.server.NetworkManagementService.NetdResponseCode.IpFwdStatusResult;
-import static com.android.server.NetworkManagementService.NetdResponseCode.TetherDnsFwdTgtListResult;
-import static com.android.server.NetworkManagementService.NetdResponseCode.TetherInterfaceListResult;
-import static com.android.server.NetworkManagementService.NetdResponseCode.TetherStatusResult;
-import static com.android.server.NetworkManagementService.NetdResponseCode.TetheringStatsListResult;
 import static com.android.server.NetworkManagementService.NetdResponseCode.TtyListResult;
 import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED;
 
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index c2117a7..128d98b 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -78,6 +78,7 @@
     @VisibleForTesting
     static final String[] sDeviceConfigScopes = new String[] {
         DeviceConfig.NAMESPACE_INPUT_NATIVE_BOOT,
+        DeviceConfig.NAMESPACE_NETD_NATIVE,
     };
 
     private final String[] mGlobalSettings;
diff --git a/services/core/java/com/android/server/appop/HistoricalRegistry.java b/services/core/java/com/android/server/appop/HistoricalRegistry.java
index 714a807..708de73 100644
--- a/services/core/java/com/android/server/appop/HistoricalRegistry.java
+++ b/services/core/java/com/android/server/appop/HistoricalRegistry.java
@@ -27,7 +27,9 @@
 import android.content.ContentResolver;
 import android.database.ContentObserver;
 import android.net.Uri;
+import android.os.Build;
 import android.os.Bundle;
+import android.os.Debug;
 import android.os.Environment;
 import android.os.Message;
 import android.os.Process;
@@ -38,6 +40,7 @@
 import android.util.Slog;
 import android.util.TimeUtils;
 import android.util.Xml;
+
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.AtomicDirectory;
 import com.android.internal.os.BackgroundThread;
@@ -45,6 +48,7 @@
 import com.android.internal.util.XmlUtils;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.FgThread;
+
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlSerializer;
@@ -59,10 +63,12 @@
 import java.nio.file.Files;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.Date;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -105,6 +111,7 @@
 // TODO (bug:122218838): Validate changed time is handled correctly
 final class HistoricalRegistry {
     private static final boolean DEBUG = false;
+    private static final boolean KEEP_WTF_LOG = Build.IS_DEBUGGABLE;
 
     private static final String LOG_TAG = HistoricalRegistry.class.getSimpleName();
 
@@ -123,7 +130,7 @@
     private static final int MSG_WRITE_PENDING_HISTORY = 1;
 
     // See mMode
-    private static final int DEFAULT_MODE = AppOpsManager.HISTORICAL_MODE_DISABLED;
+    private static final int DEFAULT_MODE = AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE;
 
     // See mBaseSnapshotInterval
     private static final long DEFAULT_SNAPSHOT_INTERVAL_MILLIS = TimeUnit.MINUTES.toMillis(15);
@@ -131,11 +138,13 @@
     // See mIntervalCompressionMultiplier
     private static final long DEFAULT_COMPRESSION_STEP = 10;
 
+    private static final String HISTORY_FILE_SUFFIX = ".xml";
+
     /**
      * Whether history is enabled.
      */
     @GuardedBy("mInMemoryLock")
-    private int mMode = AppOpsManager.HISTORICAL_MODE_DISABLED;
+    private int mMode = AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE;
 
     /**
      * This granularity has been chosen to allow clean delineation for intervals
@@ -172,10 +181,16 @@
     HistoricalRegistry(@NonNull Object lock) {
         mInMemoryLock = lock;
         if (mMode != AppOpsManager.HISTORICAL_MODE_DISABLED) {
-            synchronized (mInMemoryLock) {
-                // When starting always adjust history to now.
-                mPendingHistoryOffsetMillis = System.currentTimeMillis()
-                        - mPersistence.getLastPersistTimeMillisDLocked();
+            synchronized (mOnDiskLock) {
+                synchronized (mInMemoryLock) {
+                    // When starting always adjust history to now.
+                    final long lastPersistTimeMills =
+                            mPersistence.getLastPersistTimeMillisDLocked();
+                    if (lastPersistTimeMills > 0) {
+                        mPendingHistoryOffsetMillis =
+                                System.currentTimeMillis() - lastPersistTimeMills;
+                    }
+                }
             }
         }
     }
@@ -236,8 +251,8 @@
                 + "=" + setting + " resetting!");
     }
 
-    void dump(String prefix, PrintWriter pw,  int filterUid,
-            String filterPackage, int filterOp) {
+    void dump(String prefix, PrintWriter pw, int filterUid,
+              String filterPackage, int filterOp) {
         synchronized (mOnDiskLock) {
             synchronized (mInMemoryLock) {
                 pw.println();
@@ -522,6 +537,7 @@
             persistPendingHistory(pendingWrites);
         }
     }
+
     private void persistPendingHistory(@NonNull List<HistoricalOps> pendingWrites) {
         synchronized (mOnDiskLock) {
             BackgroundThread.getHandler().removeMessages(MSG_WRITE_PENDING_HISTORY);
@@ -574,8 +590,6 @@
 
         private static final String LOG_TAG = Persistence.class.getSimpleName();
 
-        private static final String HISTORY_FILE_SUFFIX = ".xml";
-
         private static final String TAG_HISTORY = "history";
         private static final String TAG_OPS = "ops";
         private static final String TAG_UID = "uid";
@@ -603,7 +617,7 @@
         }
 
         private final AtomicDirectory mHistoricalAppOpsDir = new AtomicDirectory(
-                new File(new File(Environment.getDataSystemDeDirectory(), "appops"), "history"));
+                new File(new File(Environment.getDataSystemDirectory(), "appops"), "history"));
 
         private File generateFile(@NonNull File baseDir, int depth) {
             final long globalBeginMillis = computeGlobalIntervalBeginMillis(depth);
@@ -622,10 +636,20 @@
             try {
                 final File newBaseDir = mHistoricalAppOpsDir.startWrite();
                 final File oldBaseDir = mHistoricalAppOpsDir.getBackupDirectory();
-                handlePersistHistoricalOpsRecursiveDLocked(newBaseDir, oldBaseDir, ops, 0);
+                final HistoricalFilesInvariant filesInvariant;
+                if (DEBUG) {
+                    filesInvariant = new HistoricalFilesInvariant();
+                    filesInvariant.startTracking(oldBaseDir);
+                }
+                final Set<String> oldFileNames = getHistoricalFileNames(oldBaseDir);
+                handlePersistHistoricalOpsRecursiveDLocked(newBaseDir, oldBaseDir, ops,
+                        oldFileNames,  0);
+                if (DEBUG) {
+                    filesInvariant.stopTracking(newBaseDir);
+                }
                 mHistoricalAppOpsDir.finishWrite();
             } catch (Throwable t) {
-                Slog.wtf(LOG_TAG, "Failed to write historical app ops, restoring backup", t);
+                wtf("Failed to write historical app ops, restoring backup", t, null);
                 mHistoricalAppOpsDir.failWrite();
             }
         }
@@ -649,15 +673,23 @@
         }
 
         long getLastPersistTimeMillisDLocked() {
+            File baseDir = null;
             try {
-                final File baseDir = mHistoricalAppOpsDir.startRead();
-                final File file = generateFile(baseDir, 0);
-                if (file.exists()) {
-                    return file.lastModified();
+                baseDir = mHistoricalAppOpsDir.startRead();
+                final File[] files = baseDir.listFiles();
+                if (files != null && files.length > 0) {
+                    final Set<File> historyFiles = new ArraySet<>();
+                    Collections.addAll(historyFiles, files);
+                    for (int i = 0;; i++) {
+                        final File file = generateFile(baseDir, i);
+                        if (historyFiles.contains(file)) {
+                            return file.lastModified();
+                        }
+                    }
                 }
                 mHistoricalAppOpsDir.finishRead();
-            } catch (IOException e) {
-                Slog.wtf("Error reading historical app ops. Deleting history.", e);
+            } catch (Throwable e) {
+                wtf("Error reading historical app ops. Deleting history.", e, baseDir);
                 mHistoricalAppOpsDir.delete();
             }
             return 0;
@@ -680,27 +712,27 @@
         private @Nullable LinkedList<HistoricalOps> collectHistoricalOpsBaseDLocked(
                 int filterUid, @NonNull String filterPackageName, @Nullable String[] filterOpNames,
                 long filterBeginTimeMillis, long filterEndTimeMillis) {
+            File baseDir = null;
             try {
-                final File baseDir = mHistoricalAppOpsDir.startRead();
-                final File[] files = baseDir.listFiles();
-                if (files == null) {
-                    return null;
+                baseDir = mHistoricalAppOpsDir.startRead();
+                final HistoricalFilesInvariant filesInvariant;
+                if (DEBUG) {
+                    filesInvariant = new HistoricalFilesInvariant();
+                    filesInvariant.startTracking(baseDir);
                 }
-                final ArraySet<File> historyFiles = new ArraySet<>(files.length);
-                for (File file : files) {
-                    if (file.isFile() && file.getName().endsWith(HISTORY_FILE_SUFFIX)) {
-                        historyFiles.add(file);
-                    }
-                }
+                final Set<String> historyFiles = getHistoricalFileNames(baseDir);
                 final long[] globalContentOffsetMillis = {0};
                 final LinkedList<HistoricalOps> ops = collectHistoricalOpsRecursiveDLocked(
                         baseDir, filterUid, filterPackageName, filterOpNames, filterBeginTimeMillis,
                         filterEndTimeMillis, globalContentOffsetMillis, null /*outOps*/,
                         0 /*depth*/, historyFiles);
+                if (DEBUG) {
+                    filesInvariant.stopTracking(baseDir);
+                }
                 mHistoricalAppOpsDir.finishRead();
                 return ops;
-            } catch (IOException | XmlPullParserException e) {
-                Slog.wtf("Error reading historical app ops. Deleting history.", e);
+            } catch (Throwable t) {
+                wtf("Error reading historical app ops. Deleting history.", t, baseDir);
                 mHistoricalAppOpsDir.delete();
             }
             return null;
@@ -711,7 +743,7 @@
                 @Nullable String[] filterOpNames, long filterBeginTimeMillis,
                 long filterEndTimeMillis, @NonNull long[] globalContentOffsetMillis,
                 @Nullable LinkedList<HistoricalOps> outOps, int depth,
-                @NonNull ArraySet<File> historyFiles)
+                @NonNull Set<String> historyFiles)
                 throws IOException, XmlPullParserException {
             final long previousIntervalEndMillis = (long) Math.pow(mIntervalCompressionMultiplier,
                     depth) * mBaseSnapshotInterval;
@@ -761,17 +793,9 @@
             return outOps;
         }
 
-        private boolean createHardLinkToExistingFile(@NonNull File fromFile, @NonNull File toFile)
-                throws IOException {
-            if (!fromFile.exists()) {
-                return false;
-            }
-            Files.createLink(toFile.toPath(), fromFile.toPath());
-            return true;
-        }
-
         private void handlePersistHistoricalOpsRecursiveDLocked(@NonNull File newBaseDir,
-                @NonNull File oldBaseDir, @Nullable List<HistoricalOps> passedOps, int depth)
+                @NonNull File oldBaseDir, @Nullable List<HistoricalOps> passedOps,
+                @NonNull Set<String> oldFileNames, int depth)
                 throws IOException, XmlPullParserException {
             final long previousIntervalEndMillis = (long) Math.pow(mIntervalCompressionMultiplier,
                     depth) * mBaseSnapshotInterval;
@@ -779,12 +803,15 @@
                     depth + 1) * mBaseSnapshotInterval;
 
             if (passedOps == null || passedOps.isEmpty()) {
-                // If there is an old file we need to copy it over to the new state.
-                final File oldFile = generateFile(oldBaseDir, depth);
-                final File newFile = generateFile(newBaseDir, depth);
-                if (createHardLinkToExistingFile(oldFile, newFile)) {
+                if (!oldFileNames.isEmpty()) {
+                    // If there is an old file we need to copy it over to the new state.
+                    final File oldFile = generateFile(oldBaseDir, depth);
+                    if (oldFileNames.remove(oldFile.getName())) {
+                        final File newFile = generateFile(newBaseDir, depth);
+                        Files.createLink(newFile.toPath(), oldFile.toPath());
+                    }
                     handlePersistHistoricalOpsRecursiveDLocked(newBaseDir, oldBaseDir,
-                            passedOps, depth + 1);
+                            passedOps, oldFileNames, depth + 1);
                 }
                 return;
             }
@@ -900,9 +927,11 @@
                 enforceOpsWellFormed(overflowedOps);
             }
 
+            final File newFile = generateFile(newBaseDir, depth);
+            oldFileNames.remove(newFile.getName());
+
             if (persistedOps != null) {
                 normalizeSnapshotForSlotDuration(persistedOps, slotDurationMillis);
-                final File newFile = generateFile(newBaseDir, depth);
                 writeHistoricalOpsDLocked(persistedOps, intervalOverflowMillis, newFile);
                 if (DEBUG) {
                     Slog.i(LOG_TAG, "Persisted at depth: " + depth
@@ -912,7 +941,7 @@
             }
 
             handlePersistHistoricalOpsRecursiveDLocked(newBaseDir, oldBaseDir,
-                    overflowedOps, depth + 1);
+                    overflowedOps, oldFileNames, depth + 1);
         }
 
         private @NonNull List<HistoricalOps> readHistoricalOpsLocked(File baseDir,
@@ -920,11 +949,11 @@
                 @Nullable String filterPackageName, @Nullable String[] filterOpNames,
                 long filterBeginTimeMillis, long filterEndTimeMillis,
                 @Nullable long[] cumulativeOverflowMillis, int depth,
-                @NonNull ArraySet<File> historyFiles)
+                @NonNull Set<String> historyFiles)
                 throws IOException, XmlPullParserException {
             final File file = generateFile(baseDir, depth);
             if (historyFiles != null) {
-                historyFiles.remove(file);
+                historyFiles.remove(file.getName());
             }
             if (filterBeginTimeMillis >= filterEndTimeMillis
                     || filterEndTimeMillis < intervalBeginMillis) {
@@ -1085,7 +1114,7 @@
                 throws IOException, XmlPullParserException {
             final int op = XmlUtils.readIntAttribute(parser, ATTR_NAME);
             if (filterOpNames != null && !ArrayUtils.contains(filterOpNames,
-                    AppOpsManager.opToName(op))) {
+                    AppOpsManager.opToPublicName(op))) {
                 XmlUtils.skipCurrentTag(parser);
                 return null;
             }
@@ -1364,6 +1393,61 @@
             }
             return builder.toString();
         }
+
+        private static Set<String> getHistoricalFileNames(@NonNull File historyDir)  {
+            final File[] files = historyDir.listFiles();
+            if (files == null) {
+                return Collections.emptySet();
+            }
+            final ArraySet<String> fileNames = new ArraySet<>(files.length);
+            for (File file : files) {
+                fileNames.add(file.getName());
+
+            }
+            return fileNames;
+        }
+    }
+
+    private static class HistoricalFilesInvariant {
+        private final @NonNull List<File> mBeginFiles = new ArrayList<>();
+
+        public void startTracking(@NonNull File folder) {
+            final File[] files = folder.listFiles();
+            if (files != null) {
+                Collections.addAll(mBeginFiles, files);
+            }
+        }
+
+        public void stopTracking(@NonNull File folder) {
+            final List<File> endFiles = new ArrayList<>();
+            final File[] files = folder.listFiles();
+            if (files != null) {
+                Collections.addAll(endFiles, files);
+            }
+            final long beginOldestFileOffsetMillis = getOldestFileOffsetMillis(mBeginFiles);
+            final long endOldestFileOffsetMillis = getOldestFileOffsetMillis(endFiles);
+            if (endOldestFileOffsetMillis < beginOldestFileOffsetMillis) {
+                final String message = "History loss detected!"
+                        + "\nold files: " + mBeginFiles;
+                wtf(message, null, folder);
+                throw new IllegalStateException(message);
+            }
+        }
+
+        private static long getOldestFileOffsetMillis(@NonNull List<File> files) {
+            if (files.isEmpty()) {
+                return 0;
+            }
+            String longestName = files.get(0).getName();
+            final int fileCount = files.size();
+            for (int i = 1; i < fileCount; i++) {
+                final File file = files.get(i);
+                if (file.getName().length() > longestName.length()) {
+                    longestName = file.getName();
+                }
+            }
+            return Long.parseLong(longestName.replace(HISTORY_FILE_SUFFIX, ""));
+        }
     }
 
     private final class StringDumpVisitor implements AppOpsManager.HistoricalOpsVisitor {
@@ -1493,4 +1577,30 @@
             }
         }
     }
+
+    private static void wtf(@Nullable String message, @Nullable Throwable t,
+            @Nullable File storage) {
+        Slog.wtf(LOG_TAG, message, t);
+        if (KEEP_WTF_LOG) {
+            try {
+                final File file = new File(new File(Environment.getDataSystemDirectory(), "appops"),
+                        "wtf" + TimeUtils.formatForLogging(System.currentTimeMillis()));
+                if (file.createNewFile()) {
+                    try (PrintWriter writer = new PrintWriter(file)) {
+                        if (t != null) {
+                            writer.append('\n').append(t.toString());
+                        }
+                        writer.append('\n').append(Debug.getCallers(10));
+                        if (storage != null) {
+                            writer.append("\nfiles: " + Arrays.toString(storage.listFiles()));
+                        } else {
+                            writer.append("\nfiles: none");
+                        }
+                    }
+                }
+            } catch (IOException e) {
+                /* ignore */
+            }
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 6c3cc58..2d197bb 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -2845,7 +2845,7 @@
             int unverifiedTargetSdkVersion) {
         final int callingUserId = UserHandle.getCallingUserId();
         final int userId;
-        if (PER_PROFILE_IME_ENABLED && attribute != null && attribute.targetInputMethodUser != null
+        if (attribute != null && attribute.targetInputMethodUser != null
                 && attribute.targetInputMethodUser.getIdentifier() != callingUserId) {
             mContext.enforceCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL,
                     "Using EditorInfo.user requires INTERACT_ACROSS_USERS_FULL.");
@@ -2862,9 +2862,6 @@
         }
         InputBindResult res = null;
         synchronized (mMethodMap) {
-            // Needs to check the validity before clearing calling identity
-            // Note that cross-profile access is always allowed here to allow profile-switching.
-            final boolean calledFromValidUser = calledFromValidUserLocked(true);
             final int windowDisplayId =
                     mWindowManagerInternal.getDisplayIdForWindow(windowToken);
             final long ident = Binder.clearCallingIdentity();
@@ -2908,10 +2905,12 @@
                     return InputBindResult.NOT_IME_TARGET_WINDOW;
                 }
 
-                if (!calledFromValidUser) {
+                // cross-profile access is always allowed here to allow profile-switching.
+                if (!mSettings.isCurrentProfile(userId)) {
                     Slog.w(TAG, "A background user is requesting window. Hiding IME.");
-                    Slog.w(TAG, "If you want to interect with IME, you need "
-                            + "android.permission.INTERACT_ACROSS_USERS_FULL");
+                    Slog.w(TAG, "If you need to impersonate a foreground user/profile from"
+                            + " a background user, use EditorInfo.targetInputMethodUser with"
+                            + " INTERACT_ACROSS_USERS_FULL permission.");
                     hideCurrentInputLocked(0, null);
                     return InputBindResult.INVALID_USER;
                 }
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 7fffe8e..d8c2432 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -27,14 +27,14 @@
 import android.media.Rating;
 import android.media.VolumeProvider;
 import android.media.session.ControllerCallbackLink;
-import android.media.session.ISession;
-import android.media.session.ISessionController;
+import android.media.session.ControllerLink;
 import android.media.session.MediaController;
 import android.media.session.MediaController.PlaybackInfo;
 import android.media.session.MediaSession;
 import android.media.session.MediaSession.QueueItem;
 import android.media.session.PlaybackState;
 import android.media.session.SessionCallbackLink;
+import android.media.session.SessionLink;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
@@ -77,8 +77,8 @@
     private final int mUserId;
     private final String mPackageName;
     private final String mTag;
-    private final ControllerStub mController;
-    private final SessionStub mSession;
+    private final ControllerLink mController;
+    private final SessionLink mSession;
     private final SessionCb mSessionCb;
     private final MediaSessionService.ServiceImpl mService;
     private final Context mContext;
@@ -127,8 +127,8 @@
         mUserId = userId;
         mPackageName = ownerPackageName;
         mTag = tag;
-        mController = new ControllerStub();
-        mSession = new SessionStub();
+        mController = new ControllerLink(new ControllerStub());
+        mSession = new SessionLink(new SessionStub());
         mSessionCb = new SessionCb(cb);
         mService = service;
         mContext = mService.getContext();
@@ -139,20 +139,20 @@
     }
 
     /**
-     * Get the binder for the {@link MediaSession}.
+     * Get the session link for the {@link MediaSession}.
      *
-     * @return The session binder apps talk to.
+     * @return The session link apps talk to.
      */
-    public ISession getSessionBinder() {
+    public SessionLink getSessionBinder() {
         return mSession;
     }
 
     /**
-     * Get the binder for the {@link MediaController}.
+     * Get the controller link for the {@link MediaController}.
      *
-     * @return The controller binder apps talk to.
+     * @return The controller link apps talk to.
      */
-    public ISessionController getControllerBinder() {
+    public ControllerLink getControllerLink() {
         return mController;
     }
 
@@ -642,7 +642,7 @@
             if (mDestroyed) {
                 return;
             }
-            PlaybackInfo info = mController.getVolumeAttributes();
+            PlaybackInfo info = getVolumeAttributes();
             for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
                 ControllerCallbackLinkHolder holder = mControllerCallbackHolders.get(i);
                 try {
@@ -750,6 +750,25 @@
         return -1;
     }
 
+    private PlaybackInfo getVolumeAttributes() {
+        int volumeType;
+        AudioAttributes attributes;
+        synchronized (mLock) {
+            if (mVolumeType == PlaybackInfo.PLAYBACK_TYPE_REMOTE) {
+                int current = mOptimisticVolume != -1 ? mOptimisticVolume : mCurrentVolume;
+                return new PlaybackInfo(mVolumeType, mVolumeControlType, mMaxVolume, current,
+                        mAudioAttrs);
+            }
+            volumeType = mVolumeType;
+            attributes = mAudioAttrs;
+        }
+        int stream = AudioAttributes.toLegacyStreamType(attributes);
+        int max = mAudioManager.getStreamMaxVolume(stream);
+        int current = mAudioManager.getStreamVolume(stream);
+        return new PlaybackInfo(volumeType, VolumeProvider.VOLUME_CONTROL_ABSOLUTE, max,
+                current, attributes);
+    }
+
     private final Runnable mClearOptimisticVolumeRunnable = new Runnable() {
         @Override
         public void run() {
@@ -761,9 +780,9 @@
         }
     };
 
-    private final class SessionStub extends ISession.Stub {
+    private final class SessionStub extends SessionLink.SessionStub {
         @Override
-        public void destroy() {
+        public void destroySession() {
             final long token = Binder.clearCallingIdentity();
             try {
                 mService.destroySession(MediaSessionRecord.this);
@@ -779,7 +798,7 @@
         }
 
         @Override
-        public ISessionController getController() {
+        public ControllerLink getController() {
             return mController;
         }
 
@@ -798,8 +817,8 @@
         @Override
         public void setFlags(int flags) {
             if ((flags & MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY) != 0) {
-                int pid = getCallingPid();
-                int uid = getCallingUid();
+                int pid = Binder.getCallingPid();
+                int uid = Binder.getCallingUid();
                 mService.enforcePhoneStatePermission(pid, uid);
             }
             mFlags = flags;
@@ -1183,7 +1202,7 @@
         }
     }
 
-    class ControllerStub extends ISessionController.Stub {
+    class ControllerStub extends ControllerLink.ControllerStub {
         @Override
         public void sendCommand(String packageName, ControllerCallbackLink caller,
                 String command, Bundle args, ResultReceiver cb) {
@@ -1199,7 +1218,7 @@
         }
 
         @Override
-        public void registerCallbackListener(String packageName, ControllerCallbackLink cb) {
+        public void registerCallback(String packageName, ControllerCallbackLink cb) {
             synchronized (mLock) {
                 // If this session is already destroyed tell the caller and
                 // don't add them.
@@ -1223,7 +1242,7 @@
         }
 
         @Override
-        public void unregisterCallbackListener(ControllerCallbackLink cb) {
+        public void unregisterCallback(ControllerCallbackLink cb) {
             synchronized (mLock) {
                 int index = getControllerHolderIndexForCb(cb);
                 if (index != -1) {
@@ -1257,22 +1276,7 @@
 
         @Override
         public PlaybackInfo getVolumeAttributes() {
-            int volumeType;
-            AudioAttributes attributes;
-            synchronized (mLock) {
-                if (mVolumeType == PlaybackInfo.PLAYBACK_TYPE_REMOTE) {
-                    int current = mOptimisticVolume != -1 ? mOptimisticVolume : mCurrentVolume;
-                    return new PlaybackInfo(mVolumeType, mVolumeControlType, mMaxVolume, current,
-                            mAudioAttrs);
-                }
-                volumeType = mVolumeType;
-                attributes = mAudioAttrs;
-            }
-            int stream = AudioAttributes.toLegacyStreamType(attributes);
-            int max = mAudioManager.getStreamMaxVolume(stream);
-            int current = mAudioManager.getStreamVolume(stream);
-            return new PlaybackInfo(volumeType, VolumeProvider.VOLUME_CONTROL_ABSOLUTE, max,
-                    current, attributes);
+            return MediaSessionRecord.this.getVolumeAttributes();
         }
 
         @Override
@@ -1449,11 +1453,6 @@
         public int getRatingType() {
             return mRatingType;
         }
-
-        @Override
-        public boolean isTransportControlEnabled() {
-            return MediaSessionRecord.this.isTransportControlEnabled();
-        }
     }
 
     private class ControllerCallbackLinkHolder {
diff --git a/services/core/java/com/android/server/media/MediaSessionServiceImpl.java b/services/core/java/com/android/server/media/MediaSessionServiceImpl.java
index f374c6d..e3ae8a7 100644
--- a/services/core/java/com/android/server/media/MediaSessionServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaSessionServiceImpl.java
@@ -45,16 +45,18 @@
 import android.media.MediaController2;
 import android.media.Session2CommandGroup;
 import android.media.Session2Token;
+import android.media.session.ControllerLink;
 import android.media.session.IActiveSessionsListener;
 import android.media.session.ICallback;
 import android.media.session.IOnMediaKeyListener;
 import android.media.session.IOnVolumeKeyLongPressListener;
-import android.media.session.ISession;
 import android.media.session.ISession2TokensListener;
+import android.media.session.ISessionController;
 import android.media.session.ISessionManager;
 import android.media.session.MediaSession;
 import android.media.session.MediaSessionManager;
 import android.media.session.SessionCallbackLink;
+import android.media.session.SessionLink;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
@@ -288,7 +290,9 @@
             return;
         }
         try {
-            mRvc.remoteVolumeChanged(session.getControllerBinder(), flags);
+            mRvc.remoteVolumeChanged(
+                    ISessionController.Stub.asInterface(session.getControllerLink().getBinder()),
+                    flags);
         } catch (Exception e) {
             Log.wtf(TAG, "Error sending volume change to system UI.", e);
         }
@@ -614,7 +618,7 @@
             int size = records.size();
             ArrayList<MediaSession.Token> tokens = new ArrayList<MediaSession.Token>();
             for (int i = 0; i < size; i++) {
-                tokens.add(new MediaSession.Token(records.get(i).getControllerBinder()));
+                tokens.add(new MediaSession.Token(records.get(i).getControllerLink()));
             }
             pushRemoteVolumeUpdateLocked(userId);
             for (int i = mSessionsListeners.size() - 1; i >= 0; i--) {
@@ -641,7 +645,9 @@
                     return;
                 }
                 MediaSessionRecord record = user.mPriorityStack.getDefaultRemoteSession(userId);
-                mRvc.updateRemoteController(record == null ? null : record.getControllerBinder());
+                mRvc.updateRemoteController(record == null ? null
+                        : ISessionController.Stub.asInterface(
+                                record.getControllerLink().getBinder()));
             } catch (RemoteException e) {
                 Log.wtf(TAG, "Error sending default remote volume to sys ui.", e);
             }
@@ -858,7 +864,7 @@
                 MediaSessionRecord mediaButtonSession = getMediaButtonSessionLocked();
                 if (mediaButtonSession != null) {
                     mCallback.onAddressedPlayerChangedToMediaSession(
-                            new MediaSession.Token(mediaButtonSession.getControllerBinder()));
+                            new MediaSession.Token(mediaButtonSession.getControllerLink()));
                 } else if (mCurrentFullUserRecord.mLastMediaButtonReceiver != null) {
                     mCallback.onAddressedPlayerChangedToMediaButtonReceiver(
                             mCurrentFullUserRecord.mLastMediaButtonReceiver
@@ -978,7 +984,7 @@
         private boolean mVoiceButtonHandled = false;
 
         @Override
-        public ISession createSession(String packageName, SessionCallbackLink cb, String tag,
+        public SessionLink createSession(String packageName, SessionCallbackLink cb, String tag,
                 int userId) throws RemoteException {
             final int pid = Binder.getCallingPid();
             final int uid = Binder.getCallingUid();
@@ -1023,18 +1029,18 @@
         }
 
         @Override
-        public List<IBinder> getSessions(ComponentName componentName, int userId) {
+        public List<ControllerLink> getSessions(ComponentName componentName, int userId) {
             final int pid = Binder.getCallingPid();
             final int uid = Binder.getCallingUid();
             final long token = Binder.clearCallingIdentity();
 
             try {
                 int resolvedUserId = verifySessionsRequest(componentName, userId, pid, uid);
-                ArrayList<IBinder> binders = new ArrayList<IBinder>();
+                ArrayList<ControllerLink> binders = new ArrayList<>();
                 synchronized (mLock) {
                     List<MediaSessionRecord> records = getActiveSessionsLocked(resolvedUserId);
                     for (MediaSessionRecord record : records) {
-                        binders.add(record.getControllerBinder().asBinder());
+                        binders.add(record.getControllerLink());
                     }
                 }
                 return binders;
@@ -1798,7 +1804,7 @@
                 if (mCurrentFullUserRecord.mCallback != null) {
                     try {
                         mCurrentFullUserRecord.mCallback.onMediaKeyEventDispatchedToMediaSession(
-                                keyEvent, new MediaSession.Token(session.getControllerBinder()));
+                                keyEvent, new MediaSession.Token(session.getControllerLink()));
                     } catch (RemoteException e) {
                         Log.w(TAG, "Failed to send callback", e);
                     }
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index b6dae19..a33f14b 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -33,6 +33,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ILauncherApps;
 import android.content.pm.IOnAppsChangedListener;
+import android.content.pm.LauncherApps;
 import android.content.pm.LauncherApps.ShortcutQuery;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
@@ -42,6 +43,8 @@
 import android.content.pm.ShortcutInfo;
 import android.content.pm.ShortcutServiceInternal;
 import android.content.pm.ShortcutServiceInternal.ShortcutChangeListener;
+import android.content.pm.Signature;
+import android.content.pm.SigningInfo;
 import android.content.pm.UserInfo;
 import android.graphics.Rect;
 import android.net.Uri;
@@ -56,21 +59,31 @@
 import android.os.UserManager;
 import android.os.UserManagerInternal;
 import android.provider.Settings;
+import android.util.ByteStringUtils;
 import android.util.Log;
 import android.util.Slog;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.content.PackageMonitor;
 import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.DumpUtils;
 import com.android.internal.util.Preconditions;
+import com.android.internal.util.StatLogger;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
 import com.android.server.wm.ActivityTaskManagerInternal;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * Service that manages requests and callbacks for launchers that support
@@ -108,6 +121,17 @@
     static class LauncherAppsImpl extends ILauncherApps.Stub {
         private static final boolean DEBUG = false;
         private static final String TAG = "LauncherAppsService";
+
+        // Stats
+        @VisibleForTesting
+        interface Stats {
+            int INIT_VOUCHED_SIGNATURES = 0;
+            int COUNT = INIT_VOUCHED_SIGNATURES + 1;
+        }
+        private final StatLogger mStatLogger = new StatLogger(new String[] {
+                "initVouchedSignatures"
+        });
+
         private final Context mContext;
         private final UserManager mUm;
         private final UserManagerInternal mUserManagerInternal;
@@ -117,11 +141,16 @@
         private final PackageCallbackList<IOnAppsChangedListener> mListeners
                 = new PackageCallbackList<IOnAppsChangedListener>();
         private final DevicePolicyManager mDpm;
+        private final ConcurrentHashMap<UserHandle, Set<String>> mVouchedSignaturesByUser;
+        private final Set<String> mVouchProviders;
 
         private final MyPackageMonitor mPackageMonitor = new MyPackageMonitor();
+        private final VouchesChangedMonitor mVouchesChangedMonitor = new VouchesChangedMonitor();
 
         private final Handler mCallbackHandler;
 
+        private final Object mVouchedSignaturesLocked = new Object();
+
         public LauncherAppsImpl(Context context) {
             mContext = context;
             mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
@@ -136,6 +165,9 @@
             mShortcutServiceInternal.addListener(mPackageMonitor);
             mCallbackHandler = BackgroundThread.getHandler();
             mDpm = (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+            mVouchedSignaturesByUser = new ConcurrentHashMap<>();
+            mVouchProviders = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>());
+            mVouchesChangedMonitor.register(mContext, UserHandle.ALL, true, mCallbackHandler);
         }
 
         @VisibleForTesting
@@ -355,7 +387,7 @@
                     }
                     ApplicationInfo appInfo = pmInt.getApplicationInfo(packageName, /*flags*/ 0,
                             callingUid, user.getIdentifier());
-                    if (shouldShowHiddenApp(appInfo)) {
+                    if (shouldShowHiddenApp(user, appInfo)) {
                         ResolveInfo info = getHiddenAppActivityInfo(packageName, callingUid, user);
                         if (info != null) {
                             result.add(info);
@@ -371,7 +403,7 @@
                         user.getIdentifier(), callingUid);
                 for (ApplicationInfo applicationInfo : installedPackages) {
                     if (!visiblePackages.contains(applicationInfo.packageName)) {
-                        if (!shouldShowHiddenApp(applicationInfo)) {
+                        if (!shouldShowHiddenApp(user, applicationInfo)) {
                             continue;
                         }
                         ResolveInfo info = getHiddenAppActivityInfo(applicationInfo.packageName,
@@ -387,13 +419,130 @@
             }
         }
 
-        private static boolean shouldShowHiddenApp(ApplicationInfo appInfo) {
+        private boolean shouldShowHiddenApp(UserHandle user, ApplicationInfo appInfo) {
             if (appInfo == null || appInfo.isSystemApp() || appInfo.isUpdatedSystemApp()) {
                 return false;
             }
+            if (!mVouchedSignaturesByUser.containsKey(user)) {
+                initVouchedSignatures(user);
+            }
+            if (mVouchProviders.contains(appInfo.packageName)) {
+                // If it's a vouching packages then we must show hidden app
+                return true;
+            }
+            // If app's signature is in vouch list, do not show hidden app
+            final Set<String> vouches = mVouchedSignaturesByUser.get(user);
+            try {
+                final PackageInfo pkgInfo = mContext.getPackageManager().getPackageInfo(
+                        appInfo.packageName, PackageManager.GET_SIGNING_CERTIFICATES);
+                final Signature[] signatures = getLatestSignatures(pkgInfo.signingInfo);
+                // If any of the signatures appears in vouches, then we don't show hidden app
+                for (Signature signature : signatures) {
+                    final String certDigest = computePackageCertDigest(signature);
+                    if (vouches.contains(certDigest)) {
+                        return false;
+                    }
+                }
+            } catch (PackageManager.NameNotFoundException e) {
+                // Should not happen
+            }
             return true;
         }
 
+        @VisibleForTesting
+        static String computePackageCertDigest(Signature signature) {
+            MessageDigest messageDigest;
+            try {
+                messageDigest = MessageDigest.getInstance("SHA1");
+            } catch (NoSuchAlgorithmException e) {
+                // Should not happen
+                return null;
+            }
+            messageDigest.update(signature.toByteArray());
+            final byte[] digest = messageDigest.digest();
+            return ByteStringUtils.toHexString(digest);
+        }
+
+        @VisibleForTesting
+        static Signature[] getLatestSignatures(SigningInfo signingInfo) {
+            if (signingInfo.hasMultipleSigners()) {
+                return signingInfo.getApkContentsSigners();
+            } else {
+                final Signature[] signatures = signingInfo.getSigningCertificateHistory();
+                return new Signature[]{signatures[0]};
+            }
+        }
+
+        private void updateVouches(String packageName, UserHandle user) {
+            final PackageManagerInternal pmInt =
+                    LocalServices.getService(PackageManagerInternal.class);
+            ApplicationInfo appInfo = pmInt.getApplicationInfo(packageName,
+                    PackageManager.GET_META_DATA, Binder.getCallingUid(), user.getIdentifier());
+            if (appInfo == null) {
+                Log.w(TAG, "appInfo " + packageName + " is null");
+                return;
+            }
+            updateVouches(appInfo, user);
+        }
+
+        private void updateVouches(ApplicationInfo appInfo, UserHandle user) {
+            if (appInfo == null || appInfo.metaData == null) {
+                // No meta-data
+                return;
+            }
+            int tokenResourceId = appInfo.metaData.getInt(LauncherApps.VOUCHED_CERTS_KEY);
+            if (tokenResourceId == 0) {
+                // No xml file
+                return;
+            }
+            mVouchProviders.add(appInfo.packageName);
+            Set<String> vouches = mVouchedSignaturesByUser.get(user);
+            try {
+                List<String> signatures = Arrays.asList(
+                        mContext.getPackageManager().getResourcesForApplication(
+                                appInfo.packageName).getStringArray(tokenResourceId));
+                for (String signature : signatures) {
+                    vouches.add(signature.toUpperCase());
+                }
+            } catch (PackageManager.NameNotFoundException e) {
+                // Should not happen
+            }
+        }
+
+        private void initVouchedSignatures(UserHandle user) {
+            synchronized (mVouchedSignaturesLocked) {
+                if (mVouchedSignaturesByUser.contains(user)) {
+                    return;
+                }
+                final long startTime = mStatLogger.getTime();
+
+                Set<String> vouches = Collections.newSetFromMap(
+                        new ConcurrentHashMap<String, Boolean>());
+
+                final int callingUid = injectBinderCallingUid();
+                long ident = Binder.clearCallingIdentity();
+                try {
+                    final PackageManagerInternal pmInt =
+                            LocalServices.getService(PackageManagerInternal.class);
+                    List<ApplicationInfo> installedPackages = pmInt.getInstalledApplications(
+                            PackageManager.GET_META_DATA, user.getIdentifier(), callingUid);
+                    for (ApplicationInfo appInfo : installedPackages) {
+                        updateVouches(appInfo, user);
+                    }
+                } finally {
+                    Binder.restoreCallingIdentity(ident);
+                }
+                mVouchedSignaturesByUser.putIfAbsent(user, vouches);
+                mStatLogger.logDurationStat(Stats.INIT_VOUCHED_SIGNATURES, startTime);
+            }
+        }
+
+        @Override
+        public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+            if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
+            mStatLogger.dump(pw, "  ");
+        }
+
         @Override
         public ActivityInfo resolveActivity(
                 String callingPackage, ComponentName component, UserHandle user)
@@ -760,6 +909,18 @@
             mCallbackHandler.post(r);
         }
 
+        private class VouchesChangedMonitor extends PackageMonitor {
+            @Override
+            public void onPackageAdded(String packageName, int uid) {
+                updateVouches(packageName, new UserHandle(getChangingUserId()));
+            }
+
+            @Override
+            public void onPackageModified(String packageName) {
+                updateVouches(packageName, new UserHandle(getChangingUserId()));
+            }
+        }
+
         private class MyPackageMonitor extends PackageMonitor implements ShortcutChangeListener {
 
             // TODO Simplify with lambdas.
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index f8e24ff..575eeca 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -7656,18 +7656,7 @@
             }
 
             // Shutting down backup manager service permanently.
-            long ident = mInjector.binderClearCallingIdentity();
-            try {
-                if (mInjector.getIBackupManager() != null) {
-                    mInjector.getIBackupManager()
-                            .setBackupServiceActive(UserHandle.USER_SYSTEM, false);
-                }
-            } catch (RemoteException e) {
-                throw new IllegalStateException("Failed deactivating backup service.", e);
-            } finally {
-                mInjector.binderRestoreCallingIdentity(ident);
-            }
-
+            toggleBackupServiceActive(UserHandle.USER_SYSTEM, /* makeActive= */ false);
             if (isAdb()) {
                 // Log device owner provisioning was started using adb.
                 MetricsLogger.action(mContext, PROVISIONING_ENTRY_POINT_ADB, LOG_TAG_DEVICE_OWNER);
@@ -7695,7 +7684,7 @@
                 saveUserRestrictionsLocked(userId);
             }
 
-            ident = mInjector.binderClearCallingIdentity();
+            long ident = mInjector.binderClearCallingIdentity();
             try {
                 // TODO Send to system too?
                 sendOwnerChangedBroadcast(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED, userId);
@@ -7952,6 +7941,9 @@
                         .write();
             }
 
+            // Shutting down backup manager service permanently.
+            toggleBackupServiceActive(userHandle, /* makeActive= */ false);
+
             mOwners.setProfileOwner(who, ownerName, userHandle);
             mOwners.writeProfileOwner(userHandle);
             Slog.i(LOG_TAG, "Profile owner set: " + who + " on user " + userHandle);
@@ -7975,6 +7967,24 @@
         }
     }
 
+
+    private void toggleBackupServiceActive(int userId, boolean makeActive) {
+        // Shutting down backup manager service permanently.
+        enforceUserUnlocked(userId);
+        long ident = mInjector.binderClearCallingIdentity();
+        try {
+            if (mInjector.getIBackupManager() != null) {
+                mInjector.getIBackupManager()
+                        .setBackupServiceActive(userId, makeActive);
+            }
+        } catch (RemoteException e) {
+            throw new IllegalStateException("Failed deactivating backup service.", e);
+        } finally {
+            mInjector.binderRestoreCallingIdentity(ident);
+        }
+
+    }
+
     @Override
     public void clearProfileOwner(ComponentName who) {
         if (!mHasFeature) {
@@ -12727,22 +12737,9 @@
             return;
         }
         Preconditions.checkNotNull(admin);
-        synchronized (getLockObject()) {
-            getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
-        }
-
-        final long ident = mInjector.binderClearCallingIdentity();
-        try {
-            IBackupManager ibm = mInjector.getIBackupManager();
-            if (ibm != null) {
-                ibm.setBackupServiceActive(UserHandle.USER_SYSTEM, enabled);
-            }
-        } catch (RemoteException e) {
-            throw new IllegalStateException(
-                "Failed " + (enabled ? "" : "de") + "activating backup service.", e);
-        } finally {
-            mInjector.binderRestoreCallingIdentity(ident);
-        }
+        enforceProfileOrDeviceOwner(admin);
+        int userId = mInjector.userHandleGetCallingUserId();
+        toggleBackupServiceActive(userId, enabled);
     }
 
     @Override
@@ -12751,11 +12748,13 @@
         if (!mHasFeature) {
             return true;
         }
+
+        enforceProfileOrDeviceOwner(admin);
         synchronized (getLockObject()) {
             try {
-                getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
                 IBackupManager ibm = mInjector.getIBackupManager();
-                return ibm != null && ibm.isBackupServiceActive(UserHandle.USER_SYSTEM);
+                return ibm != null && ibm.isBackupServiceActive(
+                    mInjector.userHandleGetCallingUserId());
             } catch (RemoteException e) {
                 throw new IllegalStateException("Failed requesting backup service state.", e);
             }
diff --git a/services/net/java/android/net/apf/ApfFilter.java b/services/net/java/android/net/apf/ApfFilter.java
index f037905..3351b25 100644
--- a/services/net/java/android/net/apf/ApfFilter.java
+++ b/services/net/java/android/net/apf/ApfFilter.java
@@ -16,8 +16,19 @@
 
 package android.net.apf;
 
-import static android.net.util.NetworkConstants.*;
-import static android.system.OsConstants.*;
+import static android.net.util.NetworkConstants.ICMPV6_ECHO_REQUEST_TYPE;
+import static android.net.util.NetworkConstants.ICMPV6_NEIGHBOR_ADVERTISEMENT;
+import static android.net.util.NetworkConstants.ICMPV6_ROUTER_ADVERTISEMENT;
+import static android.net.util.NetworkConstants.ICMPV6_ROUTER_SOLICITATION;
+import static android.system.OsConstants.AF_PACKET;
+import static android.system.OsConstants.ARPHRD_ETHER;
+import static android.system.OsConstants.ETH_P_ARP;
+import static android.system.OsConstants.ETH_P_IP;
+import static android.system.OsConstants.ETH_P_IPV6;
+import static android.system.OsConstants.IPPROTO_ICMPV6;
+import static android.system.OsConstants.IPPROTO_UDP;
+import static android.system.OsConstants.SOCK_RAW;
+
 import static com.android.internal.util.BitUtils.bytesToBEInt;
 import static com.android.internal.util.BitUtils.getUint16;
 import static com.android.internal.util.BitUtils.getUint32;
@@ -34,7 +45,7 @@
 import android.net.NetworkUtils;
 import android.net.apf.ApfGenerator.IllegalInstructionException;
 import android.net.apf.ApfGenerator.Register;
-import android.net.ip.IpClient;
+import android.net.ip.IpClientCallbacks;
 import android.net.metrics.ApfProgramEvent;
 import android.net.metrics.ApfStats;
 import android.net.metrics.IpConnectivityLog;
@@ -48,10 +59,14 @@
 import android.text.format.DateUtils;
 import android.util.Log;
 import android.util.Pair;
+
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.HexDump;
 import com.android.internal.util.IndentingPrintWriter;
+
+import libcore.io.IoBridge;
+
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.net.Inet4Address;
@@ -63,7 +78,6 @@
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.Arrays;
-import libcore.io.IoBridge;
 
 /**
  * For networks that support packet filtering via APF programs, {@code ApfFilter}
@@ -174,7 +188,13 @@
         private final byte[] mPacket = new byte[1514];
         private final FileDescriptor mSocket;
         private final long mStart = SystemClock.elapsedRealtime();
-        private final ApfStats mStats = new ApfStats();
+
+        private int mReceivedRas = 0;
+        private int mMatchingRas = 0;
+        private int mDroppedRas = 0;
+        private int mParseErrors = 0;
+        private int mZeroLifetimeRas = 0;
+        private int mProgramUpdates = 0;
 
         private volatile boolean mStopped;
 
@@ -207,26 +227,26 @@
         }
 
         private void updateStats(ProcessRaResult result) {
-            mStats.receivedRas++;
+            mReceivedRas++;
             switch(result) {
                 case MATCH:
-                    mStats.matchingRas++;
+                    mMatchingRas++;
                     return;
                 case DROPPED:
-                    mStats.droppedRas++;
+                    mDroppedRas++;
                     return;
                 case PARSE_ERROR:
-                    mStats.parseErrors++;
+                    mParseErrors++;
                     return;
                 case ZERO_LIFETIME:
-                    mStats.zeroLifetimeRas++;
+                    mZeroLifetimeRas++;
                     return;
                 case UPDATE_EXPIRY:
-                    mStats.matchingRas++;
-                    mStats.programUpdates++;
+                    mMatchingRas++;
+                    mProgramUpdates++;
                     return;
                 case UPDATE_NEW_RA:
-                    mStats.programUpdates++;
+                    mProgramUpdates++;
                     return;
             }
         }
@@ -234,11 +254,19 @@
         private void logStats() {
             final long nowMs = SystemClock.elapsedRealtime();
             synchronized (this) {
-                mStats.durationMs = nowMs - mStart;
-                mStats.maxProgramSize = mApfCapabilities.maximumApfProgramSize;
-                mStats.programUpdatesAll = mNumProgramUpdates;
-                mStats.programUpdatesAllowingMulticast = mNumProgramUpdatesAllowingMulticast;
-                mMetricsLog.log(mStats);
+                final ApfStats stats = new ApfStats.Builder()
+                        .setReceivedRas(mReceivedRas)
+                        .setMatchingRas(mMatchingRas)
+                        .setDroppedRas(mDroppedRas)
+                        .setParseErrors(mParseErrors)
+                        .setZeroLifetimeRas(mZeroLifetimeRas)
+                        .setProgramUpdates(mProgramUpdates)
+                        .setDurationMs(nowMs - mStart)
+                        .setMaxProgramSize(mApfCapabilities.maximumApfProgramSize)
+                        .setProgramUpdatesAll(mNumProgramUpdates)
+                        .setProgramUpdatesAllowingMulticast(mNumProgramUpdatesAllowingMulticast)
+                        .build();
+                mMetricsLog.log(stats);
                 logApfProgramEventLocked(nowMs / DateUtils.SECOND_IN_MILLIS);
             }
         }
@@ -308,7 +336,7 @@
     private static final int APF_MAX_ETH_TYPE_BLACK_LIST_LEN = 20;
 
     private final ApfCapabilities mApfCapabilities;
-    private final IpClient.Callback mIpClientCallback;
+    private final IpClientCallbacks mIpClientCallback;
     private final InterfaceParams mInterfaceParams;
     private final IpConnectivityLog mMetricsLog;
 
@@ -349,7 +377,7 @@
 
     @VisibleForTesting
     ApfFilter(Context context, ApfConfiguration config, InterfaceParams ifParams,
-            IpClient.Callback ipClientCallback, IpConnectivityLog log) {
+            IpClientCallbacks ipClientCallback, IpConnectivityLog log) {
         mApfCapabilities = config.apfCapabilities;
         mIpClientCallback = ipClientCallback;
         mInterfaceParams = ifParams;
@@ -849,7 +877,7 @@
     @GuardedBy("this")
     private long mLastInstalledProgramMinLifetime;
     @GuardedBy("this")
-    private ApfProgramEvent mLastInstallEvent;
+    private ApfProgramEvent.Builder mLastInstallEvent;
 
     // For debugging only. The last program installed.
     @GuardedBy("this")
@@ -1281,12 +1309,12 @@
         }
         mIpClientCallback.installPacketFilter(program);
         logApfProgramEventLocked(now);
-        mLastInstallEvent = new ApfProgramEvent();
-        mLastInstallEvent.lifetime = programMinLifetime;
-        mLastInstallEvent.filteredRas = rasToFilter.size();
-        mLastInstallEvent.currentRas = mRas.size();
-        mLastInstallEvent.programLength = program.length;
-        mLastInstallEvent.flags = ApfProgramEvent.flagsFor(mIPv4Address != null, mMulticastFilter);
+        mLastInstallEvent = new ApfProgramEvent.Builder()
+                .setLifetime(programMinLifetime)
+                .setFilteredRas(rasToFilter.size())
+                .setCurrentRas(mRas.size())
+                .setProgramLength(program.length)
+                .setFlags(mIPv4Address != null, mMulticastFilter);
     }
 
     @GuardedBy("this")
@@ -1294,13 +1322,14 @@
         if (mLastInstallEvent == null) {
             return;
         }
-        ApfProgramEvent ev = mLastInstallEvent;
+        ApfProgramEvent.Builder ev = mLastInstallEvent;
         mLastInstallEvent = null;
-        ev.actualLifetime = now - mLastTimeInstalledProgram;
-        if (ev.actualLifetime < APF_PROGRAM_EVENT_LIFETIME_THRESHOLD) {
+        final long actualLifetime = now - mLastTimeInstalledProgram;
+        ev.setActualLifetime(actualLifetime);
+        if (actualLifetime < APF_PROGRAM_EVENT_LIFETIME_THRESHOLD) {
             return;
         }
-        mMetricsLog.log(ev);
+        mMetricsLog.log(ev.build());
     }
 
     /**
@@ -1390,7 +1419,7 @@
      * filtering using APF programs.
      */
     public static ApfFilter maybeCreate(Context context, ApfConfiguration config,
-            InterfaceParams ifParams, IpClient.Callback ipClientCallback) {
+            InterfaceParams ifParams, IpClientCallbacks ipClientCallback) {
         if (context == null || config == null || ifParams == null) return null;
         ApfCapabilities apfCapabilities =  config.apfCapabilities;
         if (apfCapabilities == null) return null;
diff --git a/services/net/java/android/net/dhcp/DhcpClient.java b/services/net/java/android/net/dhcp/DhcpClient.java
index a956cef..15acc0e 100644
--- a/services/net/java/android/net/dhcp/DhcpClient.java
+++ b/services/net/java/android/net/dhcp/DhcpClient.java
@@ -16,28 +16,39 @@
 
 package android.net.dhcp;
 
-import com.android.internal.util.HexDump;
-import com.android.internal.util.Protocol;
-import com.android.internal.util.State;
-import com.android.internal.util.MessageUtils;
-import com.android.internal.util.StateMachine;
-import com.android.internal.util.WakeupMessage;
+import static android.net.dhcp.DhcpPacket.DHCP_BROADCAST_ADDRESS;
+import static android.net.dhcp.DhcpPacket.DHCP_DNS_SERVER;
+import static android.net.dhcp.DhcpPacket.DHCP_DOMAIN_NAME;
+import static android.net.dhcp.DhcpPacket.DHCP_LEASE_TIME;
+import static android.net.dhcp.DhcpPacket.DHCP_MTU;
+import static android.net.dhcp.DhcpPacket.DHCP_REBINDING_TIME;
+import static android.net.dhcp.DhcpPacket.DHCP_RENEWAL_TIME;
+import static android.net.dhcp.DhcpPacket.DHCP_ROUTER;
+import static android.net.dhcp.DhcpPacket.DHCP_SUBNET_MASK;
+import static android.net.dhcp.DhcpPacket.DHCP_VENDOR_INFO;
+import static android.net.dhcp.DhcpPacket.INADDR_ANY;
+import static android.net.dhcp.DhcpPacket.INADDR_BROADCAST;
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.AF_PACKET;
+import static android.system.OsConstants.ETH_P_IP;
+import static android.system.OsConstants.IPPROTO_UDP;
+import static android.system.OsConstants.SOCK_DGRAM;
+import static android.system.OsConstants.SOCK_RAW;
+import static android.system.OsConstants.SOL_SOCKET;
+import static android.system.OsConstants.SO_BINDTODEVICE;
+import static android.system.OsConstants.SO_BROADCAST;
+import static android.system.OsConstants.SO_RCVBUF;
+import static android.system.OsConstants.SO_REUSEADDR;
 
 import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
 import android.net.DhcpResults;
-import android.net.InterfaceConfiguration;
-import android.net.LinkAddress;
 import android.net.NetworkUtils;
 import android.net.TrafficStats;
-import android.net.metrics.IpConnectivityLog;
 import android.net.metrics.DhcpClientEvent;
 import android.net.metrics.DhcpErrorEvent;
+import android.net.metrics.IpConnectivityLog;
 import android.net.util.InterfaceParams;
 import android.os.Message;
-import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.system.ErrnoException;
 import android.system.Os;
@@ -47,20 +58,23 @@
 import android.util.SparseArray;
 import android.util.TimeUtils;
 
+import com.android.internal.util.HexDump;
+import com.android.internal.util.MessageUtils;
+import com.android.internal.util.Protocol;
+import com.android.internal.util.State;
+import com.android.internal.util.StateMachine;
+import com.android.internal.util.WakeupMessage;
+
+import libcore.io.IoBridge;
+
 import java.io.FileDescriptor;
 import java.io.IOException;
-import java.lang.Thread;
 import java.net.Inet4Address;
 import java.net.SocketException;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
 import java.util.Random;
 
-import libcore.io.IoBridge;
-
-import static android.system.OsConstants.*;
-import static android.net.dhcp.DhcpPacket.*;
-
 /**
  * A DHCPv4 client.
  *
@@ -1029,6 +1043,10 @@
     }
 
     private void logState(String name, int durationMs) {
-        mMetricsLog.log(mIfaceName, new DhcpClientEvent(name, durationMs));
+        final DhcpClientEvent event = new DhcpClientEvent.Builder()
+                .setMsg(name)
+                .setDurationMs(durationMs)
+                .build();
+        mMetricsLog.log(mIfaceName, event);
     }
 }
diff --git a/services/net/java/android/net/ip/ConnectivityPacketTracker.java b/services/net/java/android/net/ip/ConnectivityPacketTracker.java
index e6ddbbc..bef425a 100644
--- a/services/net/java/android/net/ip/ConnectivityPacketTracker.java
+++ b/services/net/java/android/net/ip/ConnectivityPacketTracker.java
@@ -16,27 +16,27 @@
 
 package android.net.ip;
 
-import static android.system.OsConstants.*;
+import static android.system.OsConstants.AF_PACKET;
+import static android.system.OsConstants.ARPHRD_ETHER;
+import static android.system.OsConstants.ETH_P_ALL;
+import static android.system.OsConstants.SOCK_RAW;
 
 import android.net.NetworkUtils;
-import android.net.util.PacketReader;
 import android.net.util.ConnectivityPacketSummary;
 import android.net.util.InterfaceParams;
+import android.net.util.PacketReader;
 import android.os.Handler;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.PacketSocketAddress;
 import android.text.TextUtils;
-import android.util.Log;
 import android.util.LocalLog;
+import android.util.Log;
 
-import libcore.io.IoBridge;
 import libcore.util.HexEncoding;
 
 import java.io.FileDescriptor;
-import java.io.InterruptedIOException;
 import java.io.IOException;
-import java.net.SocketException;
 
 
 /**
diff --git a/services/net/java/android/net/ip/InterfaceController.java b/services/net/java/android/net/ip/InterfaceController.java
index 02e4f87..55dfcef 100644
--- a/services/net/java/android/net/ip/InterfaceController.java
+++ b/services/net/java/android/net/ip/InterfaceController.java
@@ -19,7 +19,6 @@
 import android.net.INetd;
 import android.net.InterfaceConfiguration;
 import android.net.LinkAddress;
-import android.net.util.NetdService;
 import android.net.util.SharedLog;
 import android.os.INetworkManagementService;
 import android.os.RemoteException;
diff --git a/services/net/java/android/net/ip/IpClient.java b/services/net/java/android/net/ip/IpClient.java
index 0176dd4..b0c0957 100644
--- a/services/net/java/android/net/ip/IpClient.java
+++ b/services/net/java/android/net/ip/IpClient.java
@@ -16,19 +16,18 @@
 
 package android.net.ip;
 
-import com.android.internal.util.HexDump;
-import com.android.internal.util.MessageUtils;
-import com.android.internal.util.WakeupMessage;
+import static android.net.shared.LinkPropertiesParcelableUtil.fromStableParcelable;
 
 import android.content.Context;
 import android.net.DhcpResults;
 import android.net.INetd;
 import android.net.IpPrefix;
 import android.net.LinkAddress;
-import android.net.LinkProperties.ProvisioningChange;
 import android.net.LinkProperties;
 import android.net.Network;
+import android.net.ProvisioningConfigurationParcelable;
 import android.net.ProxyInfo;
+import android.net.ProxyInfoParcelable;
 import android.net.RouteInfo;
 import android.net.StaticIpConfiguration;
 import android.net.apf.ApfCapabilities;
@@ -36,10 +35,10 @@
 import android.net.dhcp.DhcpClient;
 import android.net.metrics.IpConnectivityLog;
 import android.net.metrics.IpManagerEvent;
+import android.net.shared.InitialConfiguration;
 import android.net.util.InterfaceParams;
 import android.net.util.MultinetworkPolicyTracker;
 import android.net.util.NetdService;
-import android.net.util.NetworkConstants;
 import android.net.util.SharedLog;
 import android.os.ConditionVariable;
 import android.os.INetworkManagementService;
@@ -52,29 +51,24 @@
 import android.util.Log;
 import android.util.SparseArray;
 
-import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.IState;
+import com.android.internal.util.IndentingPrintWriter;
+import com.android.internal.util.MessageUtils;
 import com.android.internal.util.Preconditions;
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
+import com.android.internal.util.WakeupMessage;
 import com.android.server.net.NetlinkTracker;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
 import java.net.InetAddress;
-import java.net.SocketException;
-import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashSet;
-import java.util.Objects;
 import java.util.List;
-import java.util.Set;
-import java.util.StringJoiner;
+import java.util.Objects;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CountDownLatch;
 import java.util.function.Predicate;
@@ -134,83 +128,17 @@
     }
 
     /**
-     * Callbacks for handling IpClient events.
-     *
-     * These methods are called by IpClient on its own thread. Implementations
-     * of this class MUST NOT carry out long-running computations or hold locks
-     * for which there might be contention with other code calling public
-     * methods of the same IpClient instance.
+     * TODO: remove after migrating clients to use IpClientCallbacks directly
+     * @see IpClientCallbacks
      */
-    public static class Callback {
-        // In order to receive onPreDhcpAction(), call #withPreDhcpAction()
-        // when constructing a ProvisioningConfiguration.
-        //
-        // Implementations of onPreDhcpAction() must call
-        // IpClient#completedPreDhcpAction() to indicate that DHCP is clear
-        // to proceed.
-        public void onPreDhcpAction() {}
-        public void onPostDhcpAction() {}
+    public static class Callback extends IpClientCallbacks {}
 
-        // This is purely advisory and not an indication of provisioning
-        // success or failure.  This is only here for callers that want to
-        // expose DHCPv4 results to other APIs (e.g., WifiInfo#setInetAddress).
-        // DHCPv4 or static IPv4 configuration failure or success can be
-        // determined by whether or not the passed-in DhcpResults object is
-        // null or not.
-        public void onNewDhcpResults(DhcpResults dhcpResults) {}
-
-        public void onProvisioningSuccess(LinkProperties newLp) {}
-        public void onProvisioningFailure(LinkProperties newLp) {}
-
-        // Invoked on LinkProperties changes.
-        public void onLinkPropertiesChange(LinkProperties newLp) {}
-
-        // Called when the internal IpReachabilityMonitor (if enabled) has
-        // detected the loss of a critical number of required neighbors.
-        public void onReachabilityLost(String logMsg) {}
-
-        // Called when the IpClient state machine terminates.
-        public void onQuit() {}
-
-        // Install an APF program to filter incoming packets.
-        public void installPacketFilter(byte[] filter) {}
-
-        // Asynchronously read back the APF program & data buffer from the wifi driver.
-        // Due to Wifi HAL limitations, the current implementation only supports dumping the entire
-        // buffer. In response to this request, the driver returns the data buffer asynchronously
-        // by sending an IpClient#EVENT_READ_PACKET_FILTER_COMPLETE message.
-        public void startReadPacketFilter() {}
-
-        // If multicast filtering cannot be accomplished with APF, this function will be called to
-        // actuate multicast filtering using another means.
-        public void setFallbackMulticastFilter(boolean enabled) {}
-
-        // Enabled/disable Neighbor Discover offload functionality. This is
-        // called, for example, whenever 464xlat is being started or stopped.
-        public void setNeighborDiscoveryOffload(boolean enable) {}
-    }
-
-    public static class WaitForProvisioningCallback extends Callback {
-        private final ConditionVariable mCV = new ConditionVariable();
-        private LinkProperties mCallbackLinkProperties;
-
-        public LinkProperties waitForProvisioning() {
-            mCV.block();
-            return mCallbackLinkProperties;
-        }
-
-        @Override
-        public void onProvisioningSuccess(LinkProperties newLp) {
-            mCallbackLinkProperties = newLp;
-            mCV.open();
-        }
-
-        @Override
-        public void onProvisioningFailure(LinkProperties newLp) {
-            mCallbackLinkProperties = null;
-            mCV.open();
-        }
-    }
+    /**
+     * TODO: remove once clients are migrated to IpClientUtil.WaitForProvisioningCallback
+     * @see IpClientUtil.WaitForProvisioningCallbacks
+     */
+    public static class WaitForProvisioningCallback
+            extends IpClientUtil.WaitForProvisioningCallbacks {}
 
     // Use a wrapper class to log in order to ensure complete and detailed
     // logging. This method is lighter weight than annotations/reflection
@@ -232,12 +160,12 @@
     // once passed on to the callback they may be modified by another thread.
     //
     // TODO: Find an lighter weight approach.
-    private class LoggingCallbackWrapper extends Callback {
+    private class LoggingCallbackWrapper extends IpClientCallbacks {
         private static final String PREFIX = "INVOKE ";
-        private final Callback mCallback;
+        private final IpClientCallbacks mCallback;
 
-        public LoggingCallbackWrapper(Callback callback) {
-            mCallback = (callback != null) ? callback : new Callback();
+        LoggingCallbackWrapper(IpClientCallbacks callback) {
+            mCallback = (callback != null) ? callback : new IpClientCallbacks();
         }
 
         private void log(String msg) {
@@ -307,288 +235,102 @@
     }
 
     /**
-     * This class encapsulates parameters to be passed to
-     * IpClient#startProvisioning(). A defensive copy is made by IpClient
-     * and the values specified herein are in force until IpClient#stop()
-     * is called.
-     *
-     * Example use:
-     *
-     *     final ProvisioningConfiguration config =
-     *             mIpClient.buildProvisioningConfiguration()
-     *                     .withPreDhcpAction()
-     *                     .withProvisioningTimeoutMs(36 * 1000)
-     *                     .build();
-     *     mIpClient.startProvisioning(config);
-     *     ...
-     *     mIpClient.stop();
-     *
-     * The specified provisioning configuration will only be active until
-     * IpClient#stop() is called. Future calls to IpClient#startProvisioning()
-     * must specify the configuration again.
+     * TODO: remove after migrating clients to use the shared configuration class directly.
+     * @see android.net.shared.ProvisioningConfiguration
      */
-    public static class ProvisioningConfiguration {
-        // TODO: Delete this default timeout once those callers that care are
-        // fixed to pass in their preferred timeout.
-        //
-        // We pick 36 seconds so we can send DHCP requests at
-        //
-        //     t=0, t=2, t=6, t=14, t=30
-        //
-        // allowing for 10% jitter.
-        private static final int DEFAULT_TIMEOUT_MS = 36 * 1000;
-
-        public static class Builder {
-            private ProvisioningConfiguration mConfig = new ProvisioningConfiguration();
-
-            public Builder withoutIPv4() {
-                mConfig.mEnableIPv4 = false;
-                return this;
-            }
-
-            public Builder withoutIPv6() {
-                mConfig.mEnableIPv6 = false;
-                return this;
-            }
-
-            public Builder withoutMultinetworkPolicyTracker() {
-                mConfig.mUsingMultinetworkPolicyTracker = false;
-                return this;
-            }
-
-            public Builder withoutIpReachabilityMonitor() {
-                mConfig.mUsingIpReachabilityMonitor = false;
-                return this;
-            }
-
-            public Builder withPreDhcpAction() {
-                mConfig.mRequestedPreDhcpActionMs = DEFAULT_TIMEOUT_MS;
-                return this;
-            }
-
-            public Builder withPreDhcpAction(int dhcpActionTimeoutMs) {
-                mConfig.mRequestedPreDhcpActionMs = dhcpActionTimeoutMs;
-                return this;
-            }
-
-            public Builder withInitialConfiguration(InitialConfiguration initialConfig) {
-                mConfig.mInitialConfig = initialConfig;
-                return this;
-            }
-
-            public Builder withStaticConfiguration(StaticIpConfiguration staticConfig) {
-                mConfig.mStaticIpConfig = staticConfig;
-                return this;
-            }
-
-            public Builder withApfCapabilities(ApfCapabilities apfCapabilities) {
-                mConfig.mApfCapabilities = apfCapabilities;
-                return this;
-            }
-
-            public Builder withProvisioningTimeoutMs(int timeoutMs) {
-                mConfig.mProvisioningTimeoutMs = timeoutMs;
-                return this;
-            }
-
-            public Builder withRandomMacAddress() {
-                mConfig.mIPv6AddrGenMode = INetd.IPV6_ADDR_GEN_MODE_EUI64;
-                return this;
-            }
-
-            public Builder withStableMacAddress() {
-                mConfig.mIPv6AddrGenMode = INetd.IPV6_ADDR_GEN_MODE_STABLE_PRIVACY;
-                return this;
-            }
-
-            public Builder withNetwork(Network network) {
-                mConfig.mNetwork = network;
-                return this;
-            }
-
-            public Builder withDisplayName(String displayName) {
-                mConfig.mDisplayName = displayName;
-                return this;
-            }
-
-            public ProvisioningConfiguration build() {
-                return new ProvisioningConfiguration(mConfig);
-            }
-        }
-
-        /* package */ boolean mEnableIPv4 = true;
-        /* package */ boolean mEnableIPv6 = true;
-        /* package */ boolean mUsingMultinetworkPolicyTracker = true;
-        /* package */ boolean mUsingIpReachabilityMonitor = true;
-        /* package */ int mRequestedPreDhcpActionMs;
-        /* package */ InitialConfiguration mInitialConfig;
-        /* package */ StaticIpConfiguration mStaticIpConfig;
-        /* package */ ApfCapabilities mApfCapabilities;
-        /* package */ int mProvisioningTimeoutMs = DEFAULT_TIMEOUT_MS;
-        /* package */ int mIPv6AddrGenMode = INetd.IPV6_ADDR_GEN_MODE_STABLE_PRIVACY;
-        /* package */ Network mNetwork = null;
-        /* package */ String mDisplayName = null;
-
-        public ProvisioningConfiguration() {} // used by Builder
-
-        public ProvisioningConfiguration(ProvisioningConfiguration other) {
-            mEnableIPv4 = other.mEnableIPv4;
-            mEnableIPv6 = other.mEnableIPv6;
-            mUsingMultinetworkPolicyTracker = other.mUsingMultinetworkPolicyTracker;
-            mUsingIpReachabilityMonitor = other.mUsingIpReachabilityMonitor;
-            mRequestedPreDhcpActionMs = other.mRequestedPreDhcpActionMs;
-            mInitialConfig = InitialConfiguration.copy(other.mInitialConfig);
-            mStaticIpConfig = other.mStaticIpConfig;
-            mApfCapabilities = other.mApfCapabilities;
-            mProvisioningTimeoutMs = other.mProvisioningTimeoutMs;
-            mIPv6AddrGenMode = other.mIPv6AddrGenMode;
-            mNetwork = other.mNetwork;
-            mDisplayName = other.mDisplayName;
-        }
-
-        @Override
-        public String toString() {
-            return new StringJoiner(", ", getClass().getSimpleName() + "{", "}")
-                    .add("mEnableIPv4: " + mEnableIPv4)
-                    .add("mEnableIPv6: " + mEnableIPv6)
-                    .add("mUsingMultinetworkPolicyTracker: " + mUsingMultinetworkPolicyTracker)
-                    .add("mUsingIpReachabilityMonitor: " + mUsingIpReachabilityMonitor)
-                    .add("mRequestedPreDhcpActionMs: " + mRequestedPreDhcpActionMs)
-                    .add("mInitialConfig: " + mInitialConfig)
-                    .add("mStaticIpConfig: " + mStaticIpConfig)
-                    .add("mApfCapabilities: " + mApfCapabilities)
-                    .add("mProvisioningTimeoutMs: " + mProvisioningTimeoutMs)
-                    .add("mIPv6AddrGenMode: " + mIPv6AddrGenMode)
-                    .add("mNetwork: " + mNetwork)
-                    .add("mDisplayName: " + mDisplayName)
-                    .toString();
-        }
-
-        public boolean isValid() {
-            return (mInitialConfig == null) || mInitialConfig.isValid();
-        }
-    }
-
-    public static class InitialConfiguration {
-        public final Set<LinkAddress> ipAddresses = new HashSet<>();
-        public final Set<IpPrefix> directlyConnectedRoutes = new HashSet<>();
-        public final Set<InetAddress> dnsServers = new HashSet<>();
-        public Inet4Address gateway; // WiFi legacy behavior with static ipv4 config
-
-        public static InitialConfiguration copy(InitialConfiguration config) {
-            if (config == null) {
-                return null;
-            }
-            InitialConfiguration configCopy = new InitialConfiguration();
-            configCopy.ipAddresses.addAll(config.ipAddresses);
-            configCopy.directlyConnectedRoutes.addAll(config.directlyConnectedRoutes);
-            configCopy.dnsServers.addAll(config.dnsServers);
-            return configCopy;
-        }
-
-        @Override
-        public String toString() {
-            return String.format(
-                    "InitialConfiguration(IPs: {%s}, prefixes: {%s}, DNS: {%s}, v4 gateway: %s)",
-                    join(", ", ipAddresses), join(", ", directlyConnectedRoutes),
-                    join(", ", dnsServers), gateway);
-        }
-
-        public boolean isValid() {
-            if (ipAddresses.isEmpty()) {
-                return false;
-            }
-
-            // For every IP address, there must be at least one prefix containing that address.
-            for (LinkAddress addr : ipAddresses) {
-                if (!any(directlyConnectedRoutes, (p) -> p.contains(addr.getAddress()))) {
-                    return false;
-                }
-            }
-            // For every dns server, there must be at least one prefix containing that address.
-            for (InetAddress addr : dnsServers) {
-                if (!any(directlyConnectedRoutes, (p) -> p.contains(addr))) {
-                    return false;
-                }
-            }
-            // All IPv6 LinkAddresses have an RFC7421-suitable prefix length
-            // (read: compliant with RFC4291#section2.5.4).
-            if (any(ipAddresses, not(InitialConfiguration::isPrefixLengthCompliant))) {
-                return false;
-            }
-            // If directlyConnectedRoutes contains an IPv6 default route
-            // then ipAddresses MUST contain at least one non-ULA GUA.
-            if (any(directlyConnectedRoutes, InitialConfiguration::isIPv6DefaultRoute)
-                    && all(ipAddresses, not(InitialConfiguration::isIPv6GUA))) {
-                return false;
-            }
-            // The prefix length of routes in directlyConnectedRoutes be within reasonable
-            // bounds for IPv6: /48-/64 just as we’d accept in RIOs.
-            if (any(directlyConnectedRoutes, not(InitialConfiguration::isPrefixLengthCompliant))) {
-                return false;
-            }
-            // There no more than one IPv4 address
-            if (ipAddresses.stream().filter(LinkAddress::isIPv4).count() > 1) {
-                return false;
-            }
-
-            return true;
+    public static class ProvisioningConfiguration
+            extends android.net.shared.ProvisioningConfiguration {
+        public ProvisioningConfiguration(android.net.shared.ProvisioningConfiguration other) {
+            super(other);
         }
 
         /**
-         * @return true if the given list of addressess and routes satisfies provisioning for this
-         * InitialConfiguration. LinkAddresses and RouteInfo objects are not compared with equality
-         * because addresses and routes seen by Netlink will contain additional fields like flags,
-         * interfaces, and so on. If this InitialConfiguration has no IP address specified, the
-         * provisioning check always fails.
-         *
-         * If the given list of routes is null, only addresses are taken into considerations.
+         * @see android.net.shared.ProvisioningConfiguration.Builder
          */
-        public boolean isProvisionedBy(List<LinkAddress> addresses, List<RouteInfo> routes) {
-            if (ipAddresses.isEmpty()) {
-                return false;
+        public static class Builder extends android.net.shared.ProvisioningConfiguration.Builder {
+            // Override all methods to have a return type matching this Builder
+            @Override
+            public Builder withoutIPv4() {
+                super.withoutIPv4();
+                return this;
             }
 
-            for (LinkAddress addr : ipAddresses) {
-                if (!any(addresses, (addrSeen) -> addr.isSameAddressAs(addrSeen))) {
-                    return false;
-                }
+            @Override
+            public Builder withoutIPv6() {
+                super.withoutIPv6();
+                return this;
             }
 
-            if (routes != null) {
-                for (IpPrefix prefix : directlyConnectedRoutes) {
-                    if (!any(routes, (routeSeen) -> isDirectlyConnectedRoute(routeSeen, prefix))) {
-                        return false;
-                    }
-                }
+            @Override
+            public Builder withoutMultinetworkPolicyTracker() {
+                super.withoutMultinetworkPolicyTracker();
+                return this;
             }
 
-            return true;
-        }
+            @Override
+            public Builder withoutIpReachabilityMonitor() {
+                super.withoutIpReachabilityMonitor();
+                return this;
+            }
 
-        private static boolean isDirectlyConnectedRoute(RouteInfo route, IpPrefix prefix) {
-            return !route.hasGateway() && prefix.equals(route.getDestination());
-        }
+            @Override
+            public Builder withPreDhcpAction() {
+                super.withPreDhcpAction();
+                return this;
+            }
 
-        private static boolean isPrefixLengthCompliant(LinkAddress addr) {
-            return addr.isIPv4() || isCompliantIPv6PrefixLength(addr.getPrefixLength());
-        }
+            @Override
+            public Builder withPreDhcpAction(int dhcpActionTimeoutMs) {
+                super.withPreDhcpAction(dhcpActionTimeoutMs);
+                return this;
+            }
 
-        private static boolean isPrefixLengthCompliant(IpPrefix prefix) {
-            return prefix.isIPv4() || isCompliantIPv6PrefixLength(prefix.getPrefixLength());
-        }
+            @Override
+            public Builder withStaticConfiguration(StaticIpConfiguration staticConfig) {
+                super.withStaticConfiguration(staticConfig);
+                return this;
+            }
 
-        private static boolean isCompliantIPv6PrefixLength(int prefixLength) {
-            return (NetworkConstants.RFC6177_MIN_PREFIX_LENGTH <= prefixLength)
-                    && (prefixLength <= NetworkConstants.RFC7421_PREFIX_LENGTH);
-        }
+            @Override
+            public Builder withApfCapabilities(ApfCapabilities apfCapabilities) {
+                super.withApfCapabilities(apfCapabilities);
+                return this;
+            }
 
-        private static boolean isIPv6DefaultRoute(IpPrefix prefix) {
-            return prefix.getAddress().equals(Inet6Address.ANY);
-        }
+            @Override
+            public Builder withProvisioningTimeoutMs(int timeoutMs) {
+                super.withProvisioningTimeoutMs(timeoutMs);
+                return this;
+            }
 
-        private static boolean isIPv6GUA(LinkAddress addr) {
-            return addr.isIPv6() && addr.isGlobalPreferred();
+            @Override
+            public Builder withRandomMacAddress() {
+                super.withRandomMacAddress();
+                return this;
+            }
+
+            @Override
+            public Builder withStableMacAddress() {
+                super.withStableMacAddress();
+                return this;
+            }
+
+            @Override
+            public Builder withNetwork(Network network) {
+                super.withNetwork(network);
+                return this;
+            }
+
+            @Override
+            public Builder withDisplayName(String displayName) {
+                super.withDisplayName(displayName);
+                return this;
+            }
+
+            @Override
+            public ProvisioningConfiguration build() {
+                return new ProvisioningConfiguration(mConfig);
+            }
         }
     }
 
@@ -600,7 +342,7 @@
     private static final int CMD_START                            = 3;
     private static final int CMD_CONFIRM                          = 4;
     private static final int EVENT_PRE_DHCP_ACTION_COMPLETE       = 5;
-    // Sent by NetlinkTracker to communicate netlink events.
+    // Triggered by NetlinkTracker to communicate netlink events.
     private static final int EVENT_NETLINK_LINKPROPERTIES_CHANGED = 6;
     private static final int CMD_UPDATE_TCP_BUFFER_SIZES          = 7;
     private static final int CMD_UPDATE_HTTP_PROXY                = 8;
@@ -628,6 +370,11 @@
 
     private static final int IMMEDIATE_FAILURE_DURATION = 0;
 
+    private static final int PROV_CHANGE_STILL_NOT_PROVISIONED = 1;
+    private static final int PROV_CHANGE_LOST_PROVISIONING = 2;
+    private static final int PROV_CHANGE_GAINED_PROVISIONING = 3;
+    private static final int PROV_CHANGE_STILL_PROVISIONED = 4;
+
     private final State mStoppedState = new StoppedState();
     private final State mStoppingState = new StoppingState();
     private final State mStartedState = new StartedState();
@@ -638,7 +385,7 @@
     private final String mInterfaceName;
     private final String mClatInterfaceName;
     @VisibleForTesting
-    protected final Callback mCallback;
+    protected final IpClientCallbacks mCallback;
     private final Dependencies mDependencies;
     private final CountDownLatch mShutdownLatch;
     private final INetworkManagementService mNwService;
@@ -657,7 +404,7 @@
      * Non-final member variables accessed only from within our StateMachine.
      */
     private LinkProperties mLinkProperties;
-    private ProvisioningConfiguration mConfiguration;
+    private android.net.shared.ProvisioningConfiguration mConfiguration;
     private MultinetworkPolicyTracker mMultinetworkPolicyTracker;
     private IpReachabilityMonitor mIpReachabilityMonitor;
     private DhcpClient mDhcpClient;
@@ -686,12 +433,15 @@
             return NetdService.getInstance();
         }
 
+        /**
+         * Get interface parameters for the specified interface.
+         */
         public InterfaceParams getInterfaceParams(String ifname) {
             return InterfaceParams.getByName(ifname);
         }
     }
 
-    public IpClient(Context context, String ifName, Callback callback) {
+    public IpClient(Context context, String ifName, IpClientCallbacks callback) {
         this(context, ifName, callback, new Dependencies());
     }
 
@@ -699,16 +449,18 @@
      * An expanded constructor, useful for dependency injection.
      * TODO: migrate all test users to mock IpClient directly and remove this ctor.
      */
-    public IpClient(Context context, String ifName, Callback callback,
+    public IpClient(Context context, String ifName, IpClientCallbacks callback,
             INetworkManagementService nwService) {
         this(context, ifName, callback, new Dependencies() {
             @Override
-            public INetworkManagementService getNMS() { return nwService; }
+            public INetworkManagementService getNMS() {
+                return nwService;
+            }
         });
     }
 
     @VisibleForTesting
-    IpClient(Context context, String ifName, Callback callback, Dependencies deps) {
+    IpClient(Context context, String ifName, IpClientCallbacks callback, Dependencies deps) {
         super(IpClient.class.getSimpleName() + "." + ifName);
         Preconditions.checkNotNull(ifName);
         Preconditions.checkNotNull(callback);
@@ -750,7 +502,7 @@
                     return;
                 }
 
-                final String msg = "interfaceAdded(" + iface +")";
+                final String msg = "interfaceAdded(" + iface + ")";
                 logMsg(msg);
             }
 
@@ -768,13 +520,13 @@
                     return;
                 }
 
-                final String msg = "interfaceRemoved(" + iface +")";
+                final String msg = "interfaceRemoved(" + iface + ")";
                 logMsg(msg);
             }
 
             private void logMsg(String msg) {
                 Log.d(mTag, msg);
-                getHandler().post(() -> { mLog.log("OBSERVED " + msg); });
+                getHandler().post(() -> mLog.log("OBSERVED " + msg));
             }
         };
 
@@ -795,11 +547,64 @@
         startStateMachineUpdaters();
     }
 
+    /**
+     * Make a IIpClient connector to communicate with this IpClient.
+     */
+    public IIpClient makeConnector() {
+        return new IpClientConnector();
+    }
+
+    class IpClientConnector extends IIpClient.Stub {
+        @Override
+        public void completedPreDhcpAction() {
+            IpClient.this.completedPreDhcpAction();
+        }
+        @Override
+        public void confirmConfiguration() {
+            IpClient.this.confirmConfiguration();
+        }
+        @Override
+        public void readPacketFilterComplete(byte[] data) {
+            IpClient.this.readPacketFilterComplete(data);
+        }
+        @Override
+        public void shutdown() {
+            IpClient.this.shutdown();
+        }
+        @Override
+        public void startProvisioning(ProvisioningConfigurationParcelable req) {
+            IpClient.this.startProvisioning(
+                    android.net.shared.ProvisioningConfiguration.fromStableParcelable(req));
+        }
+        @Override
+        public void stop() {
+            IpClient.this.stop();
+        }
+        @Override
+        public void setTcpBufferSizes(String tcpBufferSizes) {
+            IpClient.this.setTcpBufferSizes(tcpBufferSizes);
+        }
+        @Override
+        public void setHttpProxy(ProxyInfoParcelable proxyInfo) {
+            IpClient.this.setHttpProxy(fromStableParcelable(proxyInfo));
+        }
+        @Override
+        public void setMulticastFilter(boolean enabled) {
+            IpClient.this.setMulticastFilter(enabled);
+        }
+        // TODO: remove and have IpClient logs dumped in NetworkStack dumpsys
+        public void dumpIpClientLogs(FileDescriptor fd, PrintWriter pw, String[] args) {
+            IpClient.this.dump(fd, pw, args);
+        }
+    }
+
     private void configureAndStartStateMachine() {
+        // CHECKSTYLE:OFF IndentationCheck
         addState(mStoppedState);
         addState(mStartedState);
             addState(mRunningState, mStartedState);
         addState(mStoppingState);
+        // CHECKSTYLE:ON IndentationCheck
 
         setInitialState(mStoppedState);
 
@@ -828,7 +633,9 @@
         mShutdownLatch.countDown();
     }
 
-    // Shut down this IpClient instance altogether.
+    /**
+     * Shut down this IpClient instance altogether.
+     */
     public void shutdown() {
         stop();
         sendMessage(CMD_TERMINATE_AFTER_STOP);
@@ -849,7 +656,10 @@
         return new ProvisioningConfiguration.Builder();
     }
 
-    public void startProvisioning(ProvisioningConfiguration req) {
+    /**
+     * Start provisioning with the provided parameters.
+     */
+    public void startProvisioning(android.net.shared.ProvisioningConfiguration req) {
         if (!req.isValid()) {
             doImmediateProvisioningFailure(IpManagerEvent.ERROR_INVALID_PROVISIONING);
             return;
@@ -863,7 +673,7 @@
         }
 
         mCallback.setNeighborDiscoveryOffload(true);
-        sendMessage(CMD_START, new ProvisioningConfiguration(req));
+        sendMessage(CMD_START, new android.net.shared.ProvisioningConfiguration(req));
     }
 
     // TODO: Delete this.
@@ -874,21 +684,37 @@
     }
 
     public void startProvisioning() {
-        startProvisioning(new ProvisioningConfiguration());
+        startProvisioning(new android.net.shared.ProvisioningConfiguration());
     }
 
+    /**
+     * Stop this IpClient.
+     *
+     * <p>This does not shut down the StateMachine itself, which is handled by {@link #shutdown()}.
+     */
     public void stop() {
         sendMessage(CMD_STOP);
     }
 
+    /**
+     * Confirm the provisioning configuration.
+     */
     public void confirmConfiguration() {
         sendMessage(CMD_CONFIRM);
     }
 
+    /**
+     * For clients using {@link ProvisioningConfiguration.Builder#withPreDhcpAction()}, must be
+     * called after {@link IIpClientCallbacks#onPreDhcpAction} to indicate that DHCP is clear to
+     * proceed.
+     */
     public void completedPreDhcpAction() {
         sendMessage(EVENT_PRE_DHCP_ACTION_COMPLETE);
     }
 
+    /**
+     * Indicate that packet filter read is complete.
+     */
     public void readPacketFilterComplete(byte[] data) {
         sendMessage(EVENT_READ_PACKET_FILTER_COMPLETE, data);
     }
@@ -921,6 +747,9 @@
         sendMessage(CMD_SET_MULTICAST_FILTER, enabled);
     }
 
+    /**
+     * Dump logs of this IpClient.
+     */
     public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
         if (args != null && args.length > 0 && DUMP_ARG_CONFIRM.equals(args[0])) {
             // Execute confirmConfiguration() and take no further action.
@@ -930,7 +759,7 @@
 
         // Thread-unsafe access to mApfFilter but just used for debugging.
         final ApfFilter apfFilter = mApfFilter;
-        final ProvisioningConfiguration provisioningConfig = mConfiguration;
+        final android.net.shared.ProvisioningConfiguration provisioningConfig = mConfiguration;
         final ApfCapabilities apfCapabilities = (provisioningConfig != null)
                 ? provisioningConfig.mApfCapabilities : null;
 
@@ -1086,18 +915,18 @@
     // object that is a correct and complete assessment of what changed, taking
     // account of the asymmetries described in the comments in this function.
     // Then switch to using it everywhere (IpReachabilityMonitor, etc.).
-    private ProvisioningChange compareProvisioning(LinkProperties oldLp, LinkProperties newLp) {
-        ProvisioningChange delta;
+    private int compareProvisioning(LinkProperties oldLp, LinkProperties newLp) {
+        int delta;
         InitialConfiguration config = mConfiguration != null ? mConfiguration.mInitialConfig : null;
         final boolean wasProvisioned = isProvisioned(oldLp, config);
         final boolean isProvisioned = isProvisioned(newLp, config);
 
         if (!wasProvisioned && isProvisioned) {
-            delta = ProvisioningChange.GAINED_PROVISIONING;
+            delta = PROV_CHANGE_GAINED_PROVISIONING;
         } else if (wasProvisioned && isProvisioned) {
-            delta = ProvisioningChange.STILL_PROVISIONED;
+            delta = PROV_CHANGE_STILL_PROVISIONED;
         } else if (!wasProvisioned && !isProvisioned) {
-            delta = ProvisioningChange.STILL_NOT_PROVISIONED;
+            delta = PROV_CHANGE_STILL_NOT_PROVISIONED;
         } else {
             // (wasProvisioned && !isProvisioned)
             //
@@ -1109,7 +938,7 @@
             // that to be a network without DNS servers and connect anyway.
             //
             // See the comment below.
-            delta = ProvisioningChange.LOST_PROVISIONING;
+            delta = PROV_CHANGE_LOST_PROVISIONING;
         }
 
         final boolean lostIPv6 = oldLp.isIPv6Provisioned() && !newLp.isIPv6Provisioned();
@@ -1145,7 +974,7 @@
         // delta will never be LOST_PROVISIONING. So check for loss of
         // provisioning here too.
         if (lostIPv4Address || (lostIPv6 && !ignoreIPv6ProvisioningLoss)) {
-            delta = ProvisioningChange.LOST_PROVISIONING;
+            delta = PROV_CHANGE_LOST_PROVISIONING;
         }
 
         // Additionally:
@@ -1154,28 +983,34 @@
         // IPv6 default route then also consider the loss of that default route
         // to be a loss of provisioning. See b/27962810.
         if (oldLp.hasGlobalIPv6Address() && (lostIPv6Router && !ignoreIPv6ProvisioningLoss)) {
-            delta = ProvisioningChange.LOST_PROVISIONING;
+            delta = PROV_CHANGE_LOST_PROVISIONING;
         }
 
         return delta;
     }
 
-    private void dispatchCallback(ProvisioningChange delta, LinkProperties newLp) {
+    private void dispatchCallback(int delta, LinkProperties newLp) {
         switch (delta) {
-            case GAINED_PROVISIONING:
-                if (DBG) { Log.d(mTag, "onProvisioningSuccess()"); }
+            case PROV_CHANGE_GAINED_PROVISIONING:
+                if (DBG) {
+                    Log.d(mTag, "onProvisioningSuccess()");
+                }
                 recordMetric(IpManagerEvent.PROVISIONING_OK);
                 mCallback.onProvisioningSuccess(newLp);
                 break;
 
-            case LOST_PROVISIONING:
-                if (DBG) { Log.d(mTag, "onProvisioningFailure()"); }
+            case PROV_CHANGE_LOST_PROVISIONING:
+                if (DBG) {
+                    Log.d(mTag, "onProvisioningFailure()");
+                }
                 recordMetric(IpManagerEvent.PROVISIONING_FAIL);
                 mCallback.onProvisioningFailure(newLp);
                 break;
 
             default:
-                if (DBG) { Log.d(mTag, "onLinkPropertiesChange()"); }
+                if (DBG) {
+                    Log.d(mTag, "onLinkPropertiesChange()");
+                }
                 mCallback.onLinkPropertiesChange(newLp);
                 break;
         }
@@ -1184,7 +1019,7 @@
     // Updates all IpClient-related state concerned with LinkProperties.
     // Returns a ProvisioningChange for possibly notifying other interested
     // parties that are not fronted by IpClient.
-    private ProvisioningChange setLinkProperties(LinkProperties newLp) {
+    private int setLinkProperties(LinkProperties newLp) {
         if (mApfFilter != null) {
             mApfFilter.setLinkProperties(newLp);
         }
@@ -1192,10 +1027,10 @@
             mIpReachabilityMonitor.updateLinkProperties(newLp);
         }
 
-        ProvisioningChange delta = compareProvisioning(mLinkProperties, newLp);
+        int delta = compareProvisioning(mLinkProperties, newLp);
         mLinkProperties = new LinkProperties(newLp);
 
-        if (delta == ProvisioningChange.GAINED_PROVISIONING) {
+        if (delta == PROV_CHANGE_GAINED_PROVISIONING) {
             // TODO: Add a proper ProvisionedState and cancel the alarm in
             // its enter() method.
             mProvisioningTimeoutAlarm.cancel();
@@ -1291,17 +1126,17 @@
         if (Objects.equals(newLp, mLinkProperties)) {
             return true;
         }
-        final ProvisioningChange delta = setLinkProperties(newLp);
+        final int delta = setLinkProperties(newLp);
         if (sendCallbacks) {
             dispatchCallback(delta, newLp);
         }
-        return (delta != ProvisioningChange.LOST_PROVISIONING);
+        return (delta != PROV_CHANGE_LOST_PROVISIONING);
     }
 
     private void handleIPv4Success(DhcpResults dhcpResults) {
         mDhcpResults = new DhcpResults(dhcpResults);
         final LinkProperties newLp = assembleLinkProperties();
-        final ProvisioningChange delta = setLinkProperties(newLp);
+        final int delta = setLinkProperties(newLp);
 
         if (DBG) {
             Log.d(mTag, "onNewDhcpResults(" + Objects.toString(dhcpResults) + ")");
@@ -1319,7 +1154,9 @@
         // any addresses upon entry to StoppedState.
         mInterfaceCtrl.clearIPv4Address();
         mDhcpResults = null;
-        if (DBG) { Log.d(mTag, "onNewDhcpResults(null)"); }
+        if (DBG) {
+            Log.d(mTag, "onNewDhcpResults(null)");
+        }
         mCallback.onNewDhcpResults(null);
 
         handleProvisioningFailure();
@@ -1327,7 +1164,7 @@
 
     private void handleProvisioningFailure() {
         final LinkProperties newLp = assembleLinkProperties();
-        ProvisioningChange delta = setLinkProperties(newLp);
+        int delta = setLinkProperties(newLp);
         // If we've gotten here and we're still not provisioned treat that as
         // a total loss of provisioning.
         //
@@ -1336,12 +1173,12 @@
         // timeout expired.
         //
         // Regardless: GAME OVER.
-        if (delta == ProvisioningChange.STILL_NOT_PROVISIONED) {
-            delta = ProvisioningChange.LOST_PROVISIONING;
+        if (delta == PROV_CHANGE_STILL_NOT_PROVISIONED) {
+            delta = PROV_CHANGE_LOST_PROVISIONING;
         }
 
         dispatchCallback(delta, newLp);
-        if (delta == ProvisioningChange.LOST_PROVISIONING) {
+        if (delta == PROV_CHANGE_LOST_PROVISIONING) {
             transitionTo(mStoppingState);
         }
     }
@@ -1372,9 +1209,9 @@
     }
 
     private boolean startIPv6() {
-        return mInterfaceCtrl.setIPv6PrivacyExtensions(true) &&
-               mInterfaceCtrl.setIPv6AddrGenModeIfSupported(mConfiguration.mIPv6AddrGenMode) &&
-               mInterfaceCtrl.enableIPv6();
+        return mInterfaceCtrl.setIPv6PrivacyExtensions(true)
+                && mInterfaceCtrl.setIPv6AddrGenModeIfSupported(mConfiguration.mIPv6AddrGenMode)
+                && mInterfaceCtrl.enableIPv6();
     }
 
     private boolean applyInitialConfig(InitialConfiguration config) {
@@ -1392,10 +1229,10 @@
             // settings observer to watch for update and re-program these
             // parameters (Q: is this level of dynamic updatability really
             // necessary or does reading from settings at startup suffice?).
-            final int NUM_SOLICITS = 5;
-            final int INTER_SOLICIT_INTERVAL_MS = 750;
+            final int numSolicits = 5;
+            final int interSolicitIntervalMs = 750;
             setNeighborParameters(mDependencies.getNetd(), mInterfaceName,
-                    NUM_SOLICITS, INTER_SOLICIT_INTERVAL_MS);
+                    numSolicits, interSolicitIntervalMs);
         } catch (Exception e) {
             mLog.e("Failed to adjust neighbor parameters", e);
             // Carry on using the system defaults (currently: 3, 1000);
@@ -1463,7 +1300,7 @@
                     break;
 
                 case CMD_START:
-                    mConfiguration = (ProvisioningConfiguration) msg.obj;
+                    mConfiguration = (android.net.shared.ProvisioningConfiguration) msg.obj;
                     transitionTo(mStartedState);
                     break;
 
@@ -1542,8 +1379,8 @@
             mStartTimeMillis = SystemClock.elapsedRealtime();
 
             if (mConfiguration.mProvisioningTimeoutMs > 0) {
-                final long alarmTime = SystemClock.elapsedRealtime() +
-                        mConfiguration.mProvisioningTimeoutMs;
+                final long alarmTime = SystemClock.elapsedRealtime()
+                        + mConfiguration.mProvisioningTimeoutMs;
                 mProvisioningTimeoutAlarm.schedule(alarmTime);
             }
 
@@ -1598,8 +1435,7 @@
         }
 
         private boolean readyToProceed() {
-            return (!mLinkProperties.hasIPv4Address() &&
-                    !mLinkProperties.hasGlobalIPv6Address());
+            return (!mLinkProperties.hasIPv4Address() && !mLinkProperties.hasGlobalIPv6Address());
         }
     }
 
@@ -1650,7 +1486,7 @@
             if (mConfiguration.mUsingMultinetworkPolicyTracker) {
                 mMultinetworkPolicyTracker = new MultinetworkPolicyTracker(
                         mContext, getHandler(),
-                        () -> { mLog.log("OBSERVED AvoidBadWifi changed"); });
+                        () -> mLog.log("OBSERVED AvoidBadWifi changed"));
                 mMultinetworkPolicyTracker.start();
             }
 
@@ -1711,8 +1547,8 @@
             if (!mDhcpActionInFlight) {
                 mCallback.onPreDhcpAction();
                 mDhcpActionInFlight = true;
-                final long alarmTime = SystemClock.elapsedRealtime() +
-                        mConfiguration.mRequestedPreDhcpActionMs;
+                final long alarmTime = SystemClock.elapsedRealtime()
+                        + mConfiguration.mRequestedPreDhcpActionMs;
                 mDhcpActionTimeoutAlarm.schedule(alarmTime);
             }
         }
@@ -1814,7 +1650,7 @@
                         mDhcpClient.sendMessage(DhcpClient.EVENT_LINKADDRESS_CONFIGURED);
                     } else {
                         logError("Failed to set IPv4 address.");
-                        dispatchCallback(ProvisioningChange.LOST_PROVISIONING,
+                        dispatchCallback(PROV_CHANGE_LOST_PROVISIONING,
                                 new LinkProperties(mLinkProperties));
                         transitionTo(mStoppingState);
                     }
@@ -1881,16 +1717,18 @@
     }
 
     private static void setNeighborParameters(
-            INetd netd, String ifName, int num_solicits, int inter_solicit_interval_ms)
+            INetd netd, String ifName, int numSolicits, int interSolicitIntervalMs)
             throws RemoteException, IllegalArgumentException {
         Preconditions.checkNotNull(netd);
         Preconditions.checkArgument(!TextUtils.isEmpty(ifName));
-        Preconditions.checkArgument(num_solicits > 0);
-        Preconditions.checkArgument(inter_solicit_interval_ms > 0);
+        Preconditions.checkArgument(numSolicits > 0);
+        Preconditions.checkArgument(interSolicitIntervalMs > 0);
 
         for (int family : new Integer[]{INetd.IPV4, INetd.IPV6}) {
-            netd.setProcSysNet(family, INetd.NEIGH, ifName, "retrans_time_ms", Integer.toString(inter_solicit_interval_ms));
-            netd.setProcSysNet(family, INetd.NEIGH, ifName, "ucast_solicit", Integer.toString(num_solicits));
+            netd.setProcSysNet(family, INetd.NEIGH, ifName, "retrans_time_ms",
+                    Integer.toString(interSolicitIntervalMs));
+            netd.setProcSysNet(family, INetd.NEIGH, ifName, "ucast_solicit",
+                    Integer.toString(numSolicits));
         }
     }
 
@@ -1919,7 +1757,7 @@
     static <T> T find(Iterable<T> coll, Predicate<T> fn) {
         for (T t: coll) {
             if (fn.test(t)) {
-              return t;
+                return t;
             }
         }
         return null;
diff --git a/services/net/java/android/net/ip/IpClientUtil.java b/services/net/java/android/net/ip/IpClientUtil.java
new file mode 100644
index 0000000..0aec101
--- /dev/null
+++ b/services/net/java/android/net/ip/IpClientUtil.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.ip;
+
+import android.content.Context;
+import android.net.LinkProperties;
+import android.os.ConditionVariable;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+
+/**
+ * Utilities and wrappers to simplify communication with IpClient, which lives in the NetworkStack
+ * process.
+ *
+ * @hide
+ */
+public class IpClientUtil {
+    // TODO: remove once IpClient dumps are moved to NetworkStack and callers don't need this arg
+    public static final String DUMP_ARG = IpClient.DUMP_ARG;
+
+    /**
+     * Subclass of {@link IpClientCallbacks} allowing clients to block until provisioning is
+     * complete with {@link WaitForProvisioningCallbacks#waitForProvisioning()}.
+     */
+    public static class WaitForProvisioningCallbacks extends IpClientCallbacks {
+        private final ConditionVariable mCV = new ConditionVariable();
+        private LinkProperties mCallbackLinkProperties;
+
+        /**
+         * Block until either {@link #onProvisioningSuccess(LinkProperties)} or
+         * {@link #onProvisioningFailure(LinkProperties)} is called.
+         */
+        public LinkProperties waitForProvisioning() {
+            mCV.block();
+            return mCallbackLinkProperties;
+        }
+
+        @Override
+        public void onProvisioningSuccess(LinkProperties newLp) {
+            mCallbackLinkProperties = newLp;
+            mCV.open();
+        }
+
+        @Override
+        public void onProvisioningFailure(LinkProperties newLp) {
+            mCallbackLinkProperties = null;
+            mCV.open();
+        }
+    }
+
+    /**
+     * Create a new IpClient.
+     *
+     * <p>This is a convenience method to allow clients to use {@link IpClientCallbacks} instead of
+     * {@link IIpClientCallbacks}.
+     */
+    public static void makeIpClient(Context context, String ifName, IpClientCallbacks callback) {
+        // TODO: request IpClient asynchronously from NetworkStack.
+        final IpClient ipClient = new IpClient(context, ifName, callback);
+        callback.onIpClientCreated(ipClient.makeConnector());
+    }
+
+    /**
+     * Dump logs for the specified IpClient.
+     * TODO: remove logging from this method once IpClient logs are dumped in NetworkStack dumpsys,
+     * then remove callers and delete.
+     */
+    public static void dumpIpClient(
+            IIpClient connector, FileDescriptor fd, PrintWriter pw, String[] args) {
+        if (!(connector instanceof IpClient.IpClientConnector)) {
+            pw.println("Invalid connector");
+            return;
+        }
+        ((IpClient.IpClientConnector) connector).dumpIpClientLogs(fd, pw, args);
+    }
+}
diff --git a/services/net/java/android/net/ip/IpManager.java b/services/net/java/android/net/ip/IpManager.java
deleted file mode 100644
index 2eb36a2..0000000
--- a/services/net/java/android/net/ip/IpManager.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * 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.net.ip;
-
-import android.content.Context;
-import android.net.INetd;
-import android.net.LinkProperties;
-import android.net.Network;
-import android.net.StaticIpConfiguration;
-import android.net.apf.ApfCapabilities;
-import android.net.util.NetdService;
-import android.os.INetworkManagementService;
-import android.os.ServiceManager;
-import android.net.apf.ApfCapabilities;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-
-/*
- * TODO: Delete this altogether in favor of its renamed successor: IpClient.
- *
- * @hide
- */
-public class IpManager extends IpClient {
-    public static class ProvisioningConfiguration extends IpClient.ProvisioningConfiguration {
-        public ProvisioningConfiguration(IpClient.ProvisioningConfiguration ipcConfig) {
-            super(ipcConfig);
-        }
-
-        public static class Builder extends IpClient.ProvisioningConfiguration.Builder {
-            @Override
-            public Builder withoutIPv4() {
-                super.withoutIPv4();
-                return this;
-            }
-            @Override
-            public Builder withoutIPv6() {
-                super.withoutIPv6();
-                return this;
-            }
-            @Override
-            public Builder withoutIpReachabilityMonitor() {
-                super.withoutIpReachabilityMonitor();
-                return this;
-            }
-            @Override
-            public Builder withPreDhcpAction() {
-                super.withPreDhcpAction();
-                return this;
-            }
-            @Override
-            public Builder withPreDhcpAction(int dhcpActionTimeoutMs) {
-                super.withPreDhcpAction(dhcpActionTimeoutMs);
-                return this;
-            }
-            // No Override; locally defined type.
-            public Builder withInitialConfiguration(InitialConfiguration initialConfig) {
-                super.withInitialConfiguration((IpClient.InitialConfiguration) initialConfig);
-                return this;
-            }
-            @Override
-            public Builder withStaticConfiguration(StaticIpConfiguration staticConfig) {
-                super.withStaticConfiguration(staticConfig);
-                return this;
-            }
-            @Override
-            public Builder withApfCapabilities(ApfCapabilities apfCapabilities) {
-                super.withApfCapabilities(apfCapabilities);
-                return this;
-            }
-            @Override
-            public Builder withProvisioningTimeoutMs(int timeoutMs) {
-                super.withProvisioningTimeoutMs(timeoutMs);
-                return this;
-            }
-            @Override
-            public Builder withNetwork(Network network) {
-                super.withNetwork(network);
-                return this;
-            }
-            @Override
-            public Builder withDisplayName(String displayName) {
-                super.withDisplayName(displayName);
-                return this;
-            }
-            @Override
-            public ProvisioningConfiguration build() {
-                return new ProvisioningConfiguration(super.build());
-            }
-        }
-    }
-
-    public static ProvisioningConfiguration.Builder buildProvisioningConfiguration() {
-        return new ProvisioningConfiguration.Builder();
-    }
-
-    public static class InitialConfiguration extends IpClient.InitialConfiguration {
-    }
-
-    public static class Callback extends IpClient.Callback {
-    }
-
-    public IpManager(Context context, String ifName, Callback callback) {
-        super(context, ifName, callback);
-    }
-
-    public void startProvisioning(ProvisioningConfiguration req) {
-        super.startProvisioning((IpClient.ProvisioningConfiguration) req);
-    }
-}
diff --git a/services/net/java/android/net/ip/IpNeighborMonitor.java b/services/net/java/android/net/ip/IpNeighborMonitor.java
index 9512f1b..34bf4b6 100644
--- a/services/net/java/android/net/ip/IpNeighborMonitor.java
+++ b/services/net/java/android/net/ip/IpNeighborMonitor.java
@@ -16,8 +16,8 @@
 
 package android.net.ip;
 
-import static android.net.netlink.NetlinkConstants.hexify;
 import static android.net.netlink.NetlinkConstants.RTM_DELNEIGH;
+import static android.net.netlink.NetlinkConstants.hexify;
 import static android.net.netlink.NetlinkConstants.stringForNlMsgType;
 
 import android.net.MacAddress;
@@ -26,7 +26,6 @@
 import android.net.netlink.NetlinkSocket;
 import android.net.netlink.RtNetlinkNeighborMessage;
 import android.net.netlink.StructNdMsg;
-import android.net.netlink.StructNlMsgHdr;
 import android.net.util.PacketReader;
 import android.net.util.SharedLog;
 import android.os.Handler;
diff --git a/services/net/java/android/net/ip/IpReachabilityMonitor.java b/services/net/java/android/net/ip/IpReachabilityMonitor.java
index 7e02a28..29e2f0c 100644
--- a/services/net/java/android/net/ip/IpReachabilityMonitor.java
+++ b/services/net/java/android/net/ip/IpReachabilityMonitor.java
@@ -16,11 +16,13 @@
 
 package android.net.ip;
 
+import static android.net.metrics.IpReachabilityEvent.NUD_FAILED;
+import static android.net.metrics.IpReachabilityEvent.NUD_FAILED_ORGANIC;
+import static android.net.metrics.IpReachabilityEvent.PROVISIONING_LOST;
+import static android.net.metrics.IpReachabilityEvent.PROVISIONING_LOST_ORGANIC;
+
 import android.content.Context;
-import android.net.LinkAddress;
 import android.net.LinkProperties;
-import android.net.LinkProperties.ProvisioningChange;
-import android.net.ProxyInfo;
 import android.net.RouteInfo;
 import android.net.ip.IpNeighborMonitor.NeighborEvent;
 import android.net.metrics.IpConnectivityLog;
@@ -33,28 +35,19 @@
 import android.os.PowerManager;
 import android.os.PowerManager.WakeLock;
 import android.os.SystemClock;
-import android.system.ErrnoException;
-import android.system.OsConstants;
 import android.util.Log;
 
-import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.DumpUtils.Dump;
 
-import java.io.InterruptedIOException;
 import java.io.PrintWriter;
 import java.net.Inet6Address;
 import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.nio.ByteBuffer;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 
 /**
@@ -314,10 +307,11 @@
             }
         }
 
-        final ProvisioningChange delta = LinkProperties.compareProvisioning(
-                mLinkProperties, whatIfLp);
+        final boolean lostProvisioning =
+                (mLinkProperties.isIPv4Provisioned() && !whatIfLp.isIPv4Provisioned())
+                || (mLinkProperties.isIPv6Provisioned() && !whatIfLp.isIPv6Provisioned());
 
-        if (delta == ProvisioningChange.LOST_PROVISIONING) {
+        if (lostProvisioning) {
             final String logMsg = "FAILURE: LOST_PROVISIONING, " + event;
             Log.w(TAG, logMsg);
             if (mCallback != null) {
@@ -326,7 +320,7 @@
                 mCallback.notifyLost(ip, logMsg);
             }
         }
-        logNudFailed(delta);
+        logNudFailed(lostProvisioning);
     }
 
     private boolean avoidingBadLinks() {
@@ -376,11 +370,21 @@
         mMetricsLog.log(mInterfaceParams.name, new IpReachabilityEvent(eventType));
     }
 
-    private void logNudFailed(ProvisioningChange delta) {
+    private void logNudFailed(boolean lostProvisioning) {
         long duration = SystemClock.elapsedRealtime() - mLastProbeTimeMs;
         boolean isFromProbe = (duration < getProbeWakeLockDuration());
-        boolean isProvisioningLost = (delta == ProvisioningChange.LOST_PROVISIONING);
-        int eventType = IpReachabilityEvent.nudFailureEventType(isFromProbe, isProvisioningLost);
+        int eventType = nudFailureEventType(isFromProbe, lostProvisioning);
         mMetricsLog.log(mInterfaceParams.name, new IpReachabilityEvent(eventType));
     }
+
+    /**
+     * Returns the NUD failure event type code corresponding to the given conditions.
+     */
+    private static int nudFailureEventType(boolean isFromProbe, boolean isProvisioningLost) {
+        if (isFromProbe) {
+            return isProvisioningLost ? PROVISIONING_LOST : NUD_FAILED;
+        } else {
+            return isProvisioningLost ? PROVISIONING_LOST_ORGANIC : NUD_FAILED_ORGANIC;
+        }
+    }
 }
diff --git a/services/net/java/android/net/ip/RouterAdvertisementDaemon.java b/services/net/java/android/net/ip/RouterAdvertisementDaemon.java
index d197d01..8e3023b 100644
--- a/services/net/java/android/net/ip/RouterAdvertisementDaemon.java
+++ b/services/net/java/android/net/ip/RouterAdvertisementDaemon.java
@@ -18,11 +18,15 @@
 
 import static android.net.util.NetworkConstants.IPV6_MIN_MTU;
 import static android.net.util.NetworkConstants.RFC7421_PREFIX_LENGTH;
-import static android.system.OsConstants.*;
+import static android.system.OsConstants.AF_INET6;
+import static android.system.OsConstants.IPPROTO_ICMPV6;
+import static android.system.OsConstants.SOCK_RAW;
+import static android.system.OsConstants.SOL_SOCKET;
+import static android.system.OsConstants.SO_BINDTODEVICE;
+import static android.system.OsConstants.SO_SNDTIMEO;
 
 import android.net.IpPrefix;
 import android.net.LinkAddress;
-import android.net.LinkProperties;
 import android.net.NetworkUtils;
 import android.net.TrafficStats;
 import android.net.util.InterfaceParams;
@@ -34,10 +38,8 @@
 import com.android.internal.annotations.GuardedBy;
 
 import libcore.io.IoBridge;
-import libcore.util.HexEncoding;
 
 import java.io.FileDescriptor;
-import java.io.InterruptedIOException;
 import java.io.IOException;
 import java.net.Inet6Address;
 import java.net.InetAddress;
@@ -47,7 +49,6 @@
 import java.nio.BufferOverflowException;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
-import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
diff --git a/services/net/java/android/net/netlink/ConntrackMessage.java b/services/net/java/android/net/netlink/ConntrackMessage.java
index 4ee6432..6978739 100644
--- a/services/net/java/android/net/netlink/ConntrackMessage.java
+++ b/services/net/java/android/net/netlink/ConntrackMessage.java
@@ -16,22 +16,15 @@
 
 package android.net.netlink;
 
-import static android.net.netlink.NetlinkConstants.alignedLengthOf;
-import static android.net.netlink.StructNlAttr.makeNestedType;
-import static android.net.netlink.StructNlAttr.NLA_HEADERLEN;
 import static android.net.netlink.StructNlMsgHdr.NLM_F_ACK;
-import static android.net.netlink.StructNlMsgHdr.NLM_F_DUMP;
 import static android.net.netlink.StructNlMsgHdr.NLM_F_REPLACE;
 import static android.net.netlink.StructNlMsgHdr.NLM_F_REQUEST;
-import static android.net.util.NetworkConstants.IPV4_ADDR_LEN;
+
 import static java.nio.ByteOrder.BIG_ENDIAN;
 
 import android.system.OsConstants;
-import android.util.Log;
 
 import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 
diff --git a/services/net/java/android/net/shared/LinkPropertiesParcelableUtil.java b/services/net/java/android/net/shared/LinkPropertiesParcelableUtil.java
index d5213df..51d955d 100644
--- a/services/net/java/android/net/shared/LinkPropertiesParcelableUtil.java
+++ b/services/net/java/android/net/shared/LinkPropertiesParcelableUtil.java
@@ -182,9 +182,6 @@
         parcel.mtu = lp.getMtu();
         parcel.tcpBufferSizes = lp.getTcpBufferSizes();
         parcel.nat64Prefix = toStableParcelable(lp.getNat64Prefix());
-        parcel.stackedLinks = toParcelableArray(
-                lp.getStackedLinks(), LinkPropertiesParcelableUtil::toStableParcelable,
-                LinkPropertiesParcelable.class);
         return parcel;
     }
 
@@ -216,9 +213,6 @@
         lp.setMtu(parcel.mtu);
         lp.setTcpBufferSizes(parcel.tcpBufferSizes);
         lp.setNat64Prefix(fromStableParcelable(parcel.nat64Prefix));
-        for (LinkPropertiesParcelable stackedLink : parcel.stackedLinks) {
-            lp.addStackedLink(fromStableParcelable(stackedLink));
-        }
         return lp;
     }
 }
diff --git a/services/net/java/android/net/shared/ProvisioningConfiguration.java b/services/net/java/android/net/shared/ProvisioningConfiguration.java
index d995d1b..f937065 100644
--- a/services/net/java/android/net/shared/ProvisioningConfiguration.java
+++ b/services/net/java/android/net/shared/ProvisioningConfiguration.java
@@ -22,6 +22,7 @@
 import android.net.ProvisioningConfigurationParcelable;
 import android.net.StaticIpConfiguration;
 import android.net.apf.ApfCapabilities;
+import android.net.ip.IIpClient;
 
 import java.util.Objects;
 import java.util.StringJoiner;
diff --git a/services/net/java/android/net/util/ConnectivityPacketSummary.java b/services/net/java/android/net/util/ConnectivityPacketSummary.java
index 4951400..ec833b0 100644
--- a/services/net/java/android/net/util/ConnectivityPacketSummary.java
+++ b/services/net/java/android/net/util/ConnectivityPacketSummary.java
@@ -16,19 +16,56 @@
 
 package android.net.util;
 
-import android.net.dhcp.DhcpPacket;
+import static android.net.util.NetworkConstants.ARP_HWTYPE_ETHER;
+import static android.net.util.NetworkConstants.ARP_PAYLOAD_LEN;
+import static android.net.util.NetworkConstants.ARP_REPLY;
+import static android.net.util.NetworkConstants.ARP_REQUEST;
+import static android.net.util.NetworkConstants.DHCP4_CLIENT_PORT;
+import static android.net.util.NetworkConstants.ETHER_ADDR_LEN;
+import static android.net.util.NetworkConstants.ETHER_DST_ADDR_OFFSET;
+import static android.net.util.NetworkConstants.ETHER_HEADER_LEN;
+import static android.net.util.NetworkConstants.ETHER_SRC_ADDR_OFFSET;
+import static android.net.util.NetworkConstants.ETHER_TYPE_ARP;
+import static android.net.util.NetworkConstants.ETHER_TYPE_IPV4;
+import static android.net.util.NetworkConstants.ETHER_TYPE_IPV6;
+import static android.net.util.NetworkConstants.ETHER_TYPE_OFFSET;
+import static android.net.util.NetworkConstants.ICMPV6_HEADER_MIN_LEN;
+import static android.net.util.NetworkConstants.ICMPV6_ND_OPTION_LENGTH_SCALING_FACTOR;
+import static android.net.util.NetworkConstants.ICMPV6_ND_OPTION_MIN_LENGTH;
+import static android.net.util.NetworkConstants.ICMPV6_ND_OPTION_MTU;
+import static android.net.util.NetworkConstants.ICMPV6_ND_OPTION_SLLA;
+import static android.net.util.NetworkConstants.ICMPV6_ND_OPTION_TLLA;
+import static android.net.util.NetworkConstants.ICMPV6_NEIGHBOR_ADVERTISEMENT;
+import static android.net.util.NetworkConstants.ICMPV6_NEIGHBOR_SOLICITATION;
+import static android.net.util.NetworkConstants.ICMPV6_ROUTER_ADVERTISEMENT;
+import static android.net.util.NetworkConstants.ICMPV6_ROUTER_SOLICITATION;
+import static android.net.util.NetworkConstants.IPV4_ADDR_LEN;
+import static android.net.util.NetworkConstants.IPV4_DST_ADDR_OFFSET;
+import static android.net.util.NetworkConstants.IPV4_FLAGS_OFFSET;
+import static android.net.util.NetworkConstants.IPV4_FRAGMENT_MASK;
+import static android.net.util.NetworkConstants.IPV4_HEADER_MIN_LEN;
+import static android.net.util.NetworkConstants.IPV4_IHL_MASK;
+import static android.net.util.NetworkConstants.IPV4_PROTOCOL_OFFSET;
+import static android.net.util.NetworkConstants.IPV4_SRC_ADDR_OFFSET;
+import static android.net.util.NetworkConstants.IPV6_ADDR_LEN;
+import static android.net.util.NetworkConstants.IPV6_HEADER_LEN;
+import static android.net.util.NetworkConstants.IPV6_PROTOCOL_OFFSET;
+import static android.net.util.NetworkConstants.IPV6_SRC_ADDR_OFFSET;
+import static android.net.util.NetworkConstants.UDP_HEADER_LEN;
+import static android.net.util.NetworkConstants.asString;
+import static android.net.util.NetworkConstants.asUint;
+import static android.system.OsConstants.IPPROTO_ICMPV6;
+import static android.system.OsConstants.IPPROTO_UDP;
+
 import android.net.MacAddress;
+import android.net.dhcp.DhcpPacket;
 
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
-import java.util.Arrays;
 import java.util.StringJoiner;
 
-import static android.system.OsConstants.*;
-import static android.net.util.NetworkConstants.*;
-
 
 /**
  * Critical connectivity packet summarizing class.
diff --git a/services/net/java/android/net/util/InterfaceParams.java b/services/net/java/android/net/util/InterfaceParams.java
index a4b2fbb..7b060da 100644
--- a/services/net/java/android/net/util/InterfaceParams.java
+++ b/services/net/java/android/net/util/InterfaceParams.java
@@ -16,9 +16,9 @@
 
 package android.net.util;
 
-import static android.net.MacAddress.ALL_ZEROS_ADDRESS;
 import static android.net.util.NetworkConstants.ETHER_MTU;
 import static android.net.util.NetworkConstants.IPV6_MIN_MTU;
+
 import static com.android.internal.util.Preconditions.checkArgument;
 
 import android.net.MacAddress;
@@ -67,7 +67,8 @@
         checkArgument((index > 0), "invalid interface index");
         this.name = name;
         this.index = index;
-        this.macAddr = (macAddr != null) ? macAddr : ALL_ZEROS_ADDRESS;
+        this.macAddr = (macAddr != null) ? macAddr : MacAddress.fromBytes(new byte[] {
+                0x02, 0x00, 0x00, 0x00, 0x00, 0x00 });
         this.defaultMtu = (defaultMtu > IPV6_MIN_MTU) ? defaultMtu : IPV6_MIN_MTU;
     }
 
diff --git a/services/net/java/android/net/util/NetdService.java b/services/net/java/android/net/util/NetdService.java
index 6e69ff5..80b2c27 100644
--- a/services/net/java/android/net/util/NetdService.java
+++ b/services/net/java/android/net/util/NetdService.java
@@ -19,7 +19,6 @@
 import android.net.INetd;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.os.ServiceSpecificException;
 import android.os.SystemClock;
 import android.util.Log;
 
diff --git a/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java b/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java
index 6a9a121..ac4a5fe 100644
--- a/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java
+++ b/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java
@@ -25,7 +25,6 @@
 
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
@@ -48,6 +47,7 @@
 import android.platform.test.annotations.Presubmit;
 import android.provider.Settings;
 import android.test.mock.MockContentResolver;
+import android.util.SparseArray;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -90,17 +90,30 @@
     };
     private static final int NON_USER_SYSTEM = UserHandle.USER_SYSTEM + 1;
 
-    @UserIdInt private int mUserId;
-    @Mock private BackupManagerService mBackupManagerServiceMock;
-    @Mock private Context mContextMock;
-    @Mock private File mSuppressFileMock;
-    @Mock private File mSuppressFileParentMock;
-    @Mock private IBinder mAgentMock;
-    @Mock private ParcelFileDescriptor mParcelFileDescriptorMock;
-    @Mock private IFullBackupRestoreObserver mFullBackupRestoreObserverMock;
-    @Mock private IBackupObserver mBackupObserverMock;
-    @Mock private IBackupManagerMonitor mBackupManagerMonitorMock;
-    @Mock private PrintWriter mPrintWriterMock;
+    @UserIdInt
+    private int mUserId;
+    @Mock
+    private BackupManagerService mBackupManagerServiceMock;
+    @Mock
+    private UserBackupManagerService mUserBackupManagerService;
+    @Mock
+    private Context mContextMock;
+    @Mock
+    private File mSuppressFileMock;
+    @Mock
+    private File mSuppressFileParentMock;
+    @Mock
+    private IBinder mAgentMock;
+    @Mock
+    private ParcelFileDescriptor mParcelFileDescriptorMock;
+    @Mock
+    private IFullBackupRestoreObserver mFullBackupRestoreObserverMock;
+    @Mock
+    private IBackupObserver mBackupObserverMock;
+    @Mock
+    private IBackupManagerMonitor mBackupManagerMonitorMock;
+    @Mock
+    private PrintWriter mPrintWriterMock;
 
     private FileDescriptor mFileDescriptorStub = new FileDescriptor();
 
@@ -110,16 +123,20 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
+        mUserId = NON_USER_SYSTEM;
+
+        SparseArray<UserBackupManagerService> serviceUsers = new SparseArray<>();
+        serviceUsers.append(UserHandle.SYSTEM.getIdentifier(), mUserBackupManagerService);
+        serviceUsers.append(NON_USER_SYSTEM, mUserBackupManagerService);
+        when(mBackupManagerServiceMock.getServiceUsers()).thenReturn(serviceUsers);
 
         TrampolineTestable.sBackupManagerServiceMock = mBackupManagerServiceMock;
-        TrampolineTestable.sSuppressFile = mSuppressFileMock;
         TrampolineTestable.sCallingUserId = UserHandle.USER_SYSTEM;
         TrampolineTestable.sCallingUid = Process.SYSTEM_UID;
         TrampolineTestable.sBackupDisabled = false;
 
         when(mSuppressFileMock.getParentFile()).thenReturn(mSuppressFileParentMock);
 
-        mUserId = NON_USER_SYSTEM;
         mTrampoline = new TrampolineTestable(mContextMock);
 
         mContentResolver = new MockContentResolver();
@@ -128,11 +145,6 @@
     }
 
     @Test
-    public void constructor_createsSuppressFileDirectory() {
-        verify(mSuppressFileParentMock).mkdirs();
-    }
-
-    @Test
     public void unlockUser_whenMultiUserSettingDisabled_callsBackupManagerServiceForSystemUser() {
         Settings.Global.putInt(mContentResolver, Settings.Global.BACKUP_MULTI_USER_ENABLED, 0);
         mTrampoline.initializeService();
@@ -147,9 +159,9 @@
         Settings.Global.putInt(mContentResolver, Settings.Global.BACKUP_MULTI_USER_ENABLED, 0);
         mTrampoline.initializeService();
 
-        mTrampoline.unlockUser(10);
+        mTrampoline.unlockUser(NON_USER_SYSTEM);
 
-        verify(mBackupManagerServiceMock, never()).startServiceForUser(10);
+        verify(mBackupManagerServiceMock, never()).startServiceForUser(NON_USER_SYSTEM);
     }
 
     @Test
@@ -157,9 +169,9 @@
         Settings.Global.putInt(mContentResolver, Settings.Global.BACKUP_MULTI_USER_ENABLED, 1);
         mTrampoline.initializeService();
 
-        mTrampoline.unlockUser(10);
+        mTrampoline.unlockUser(NON_USER_SYSTEM);
 
-        verify(mBackupManagerServiceMock).startServiceForUser(10);
+        verify(mBackupManagerServiceMock).startServiceForUser(NON_USER_SYSTEM);
     }
 
     @Test
@@ -177,19 +189,20 @@
         Settings.Global.putInt(mContentResolver, Settings.Global.BACKUP_MULTI_USER_ENABLED, 0);
         mTrampoline.initializeService();
 
-        mTrampoline.stopUser(10);
+        mTrampoline.stopUser(NON_USER_SYSTEM);
 
-        verify(mBackupManagerServiceMock, never()).stopServiceForUser(10);
+        verify(mBackupManagerServiceMock, never()).stopServiceForUser(NON_USER_SYSTEM);
     }
 
     @Test
     public void stopUser_whenMultiUserSettingEnabled_callsBackupManagerServiceForNonSystemUser() {
         Settings.Global.putInt(mContentResolver, Settings.Global.BACKUP_MULTI_USER_ENABLED, 1);
+
         mTrampoline.initializeService();
 
-        mTrampoline.stopUser(10);
+        mTrampoline.stopUser(NON_USER_SYSTEM);
 
-        verify(mBackupManagerServiceMock).stopServiceForUser(10);
+        verify(mBackupManagerServiceMock).stopServiceForUser(NON_USER_SYSTEM);
     }
 
     @Test
@@ -211,9 +224,10 @@
 
     // Verify that BackupManagerService is not initialized if suppress file exists.
     @Test
-    public void initializeService_suppressFileExists_nonInitialized() {
-        when(mSuppressFileMock.exists()).thenReturn(true);
+    public void initializeService_suppressFileExists_nonInitialized() throws Exception {
         TrampolineTestable trampoline = new TrampolineTestable(mContextMock);
+        trampoline.createBackupSuppressFileForUser(UserHandle.USER_SYSTEM);
+
 
         trampoline.initializeService();
 
@@ -233,6 +247,14 @@
     }
 
     @Test
+    public void isBackupServiceActive_forNonSysUser_whenSysUserIsDeactivated_returnsFalse() {
+        mTrampoline.setBackupServiceActive(NON_USER_SYSTEM, true);
+        mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, false);
+
+        assertFalse(mTrampoline.isBackupServiceActive(NON_USER_SYSTEM));
+    }
+
+    @Test
     public void setBackupServiceActive_callerSystemUid_serviceCreated() {
         TrampolineTestable.sCallingUid = Process.SYSTEM_UID;
 
@@ -292,11 +314,18 @@
     }
 
     @Test
+    public void setBackupServiceActive_makeNonActive_alreadyNonActive_ignored() {
+        mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, false);
+        mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, false);
+
+        assertFalse(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
+    }
+
+    @Test
     public void setBackupServiceActive_makeActive_serviceCreatedAndSuppressFileDeleted() {
         mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, true);
 
         assertTrue(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
-        verify(mSuppressFileMock).delete();
     }
 
     @Test
@@ -308,40 +337,25 @@
         mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, false);
 
         assertFalse(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
-        verify(mSuppressFileMock).createNewFile();
     }
 
     @Test
-    public void
-    setBackupServiceActive_makeNonActive_serviceDeletedAndSuppressFileCreated_ioExceptionHandled()
-            throws IOException {
-        when(mSuppressFileMock.createNewFile()).thenThrow(new IOException());
+    public void setBackupActive_nonSystemUser_disabledForSystemUser_ignored() {
         mTrampoline.initializeService();
-        assertTrue(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
-
         mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, false);
+        mTrampoline.setBackupServiceActive(NON_USER_SYSTEM, true);
 
-        assertFalse(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
-        verify(mSuppressFileMock).createNewFile();
+        assertFalse(mTrampoline.isBackupServiceActive(NON_USER_SYSTEM));
     }
 
     @Test
-    public void setBackupServiceActive_makeNonActive_alreadyNonActive_ignored() throws IOException {
-        reset(mSuppressFileMock);
-
-        mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, false);
-
-        verifyNoMoreInteractions(mSuppressFileMock);
-    }
-
-    @Test
-    public void dataChanged_calledBeforeInitialize_ignored() throws RemoteException {
+    public void dataChanged_calledBeforeInitialize_ignored() throws Exception {
         mTrampoline.dataChanged(PACKAGE_NAME);
         verifyNoMoreInteractions(mBackupManagerServiceMock);
     }
 
     @Test
-    public void dataChangedForUser_forwarded() throws RemoteException {
+    public void dataChangedForUser_forwarded() throws Exception {
         mTrampoline.initializeService();
 
         mTrampoline.dataChangedForUser(mUserId, PACKAGE_NAME);
@@ -350,7 +364,7 @@
     }
 
     @Test
-    public void dataChanged_forwarded() throws RemoteException {
+    public void dataChanged_forwarded() throws Exception {
         TrampolineTestable.sCallingUserId = mUserId;
         mTrampoline.initializeService();
 
@@ -360,13 +374,13 @@
     }
 
     @Test
-    public void clearBackupData_calledBeforeInitialize_ignored() throws RemoteException {
+    public void clearBackupData_calledBeforeInitialize_ignored() throws Exception {
         mTrampoline.clearBackupData(TRANSPORT_NAME, PACKAGE_NAME);
         verifyNoMoreInteractions(mBackupManagerServiceMock);
     }
 
     @Test
-    public void clearBackupDataForUser_forwarded() throws RemoteException {
+    public void clearBackupDataForUser_forwarded() throws Exception {
         mTrampoline.initializeService();
 
         mTrampoline.clearBackupDataForUser(mUserId, TRANSPORT_NAME, PACKAGE_NAME);
@@ -375,7 +389,7 @@
     }
 
     @Test
-    public void clearBackupData_forwarded() throws RemoteException {
+    public void clearBackupData_forwarded() throws Exception {
         TrampolineTestable.sCallingUserId = mUserId;
         mTrampoline.initializeService();
 
@@ -385,13 +399,13 @@
     }
 
     @Test
-    public void agentConnected_calledBeforeInitialize_ignored() throws RemoteException {
+    public void agentConnected_calledBeforeInitialize_ignored() throws Exception {
         mTrampoline.agentConnected(PACKAGE_NAME, mAgentMock);
         verifyNoMoreInteractions(mBackupManagerServiceMock);
     }
 
     @Test
-    public void agentConnectedForUser_forwarded() throws RemoteException {
+    public void agentConnectedForUser_forwarded() throws Exception {
         mTrampoline.initializeService();
 
         mTrampoline.agentConnectedForUser(mUserId, PACKAGE_NAME, mAgentMock);
@@ -400,7 +414,7 @@
     }
 
     @Test
-    public void agentConnected_forwarded() throws RemoteException {
+    public void agentConnected_forwarded() throws Exception {
         TrampolineTestable.sCallingUserId = mUserId;
         mTrampoline.initializeService();
 
@@ -410,13 +424,13 @@
     }
 
     @Test
-    public void agentDisconnected_calledBeforeInitialize_ignored() throws RemoteException {
+    public void agentDisconnected_calledBeforeInitialize_ignored() throws Exception {
         mTrampoline.agentDisconnected(PACKAGE_NAME);
         verifyNoMoreInteractions(mBackupManagerServiceMock);
     }
 
     @Test
-    public void agentDisconnectedForUser_forwarded() throws RemoteException {
+    public void agentDisconnectedForUser_forwarded() throws Exception {
         mTrampoline.initializeService();
 
         mTrampoline.agentDisconnectedForUser(mUserId, PACKAGE_NAME);
@@ -425,7 +439,7 @@
     }
 
     @Test
-    public void agentDisconnected_forwarded() throws RemoteException {
+    public void agentDisconnected_forwarded() throws Exception {
         TrampolineTestable.sCallingUserId = mUserId;
         mTrampoline.initializeService();
 
@@ -435,13 +449,13 @@
     }
 
     @Test
-    public void restoreAtInstall_calledBeforeInitialize_ignored() throws RemoteException {
+    public void restoreAtInstall_calledBeforeInitialize_ignored() throws Exception {
         mTrampoline.restoreAtInstall(PACKAGE_NAME, 123);
         verifyNoMoreInteractions(mBackupManagerServiceMock);
     }
 
     @Test
-    public void restoreAtInstallForUser_forwarded() throws RemoteException {
+    public void restoreAtInstallForUser_forwarded() throws Exception {
         mTrampoline.initializeService();
 
         mTrampoline.restoreAtInstallForUser(mUserId, PACKAGE_NAME, 123);
@@ -450,7 +464,7 @@
     }
 
     @Test
-    public void restoreAtInstall_forwarded() throws RemoteException {
+    public void restoreAtInstall_forwarded() throws Exception {
         TrampolineTestable.sCallingUserId = mUserId;
         mTrampoline.initializeService();
 
@@ -460,13 +474,13 @@
     }
 
     @Test
-    public void setBackupEnabled_calledBeforeInitialize_ignored() throws RemoteException {
+    public void setBackupEnabled_calledBeforeInitialize_ignored() throws Exception {
         mTrampoline.setBackupEnabled(true);
         verifyNoMoreInteractions(mBackupManagerServiceMock);
     }
 
     @Test
-    public void setBackupEnabledForUser_forwarded() throws RemoteException {
+    public void setBackupEnabledForUser_forwarded() throws Exception {
         mTrampoline.initializeService();
 
         mTrampoline.setBackupEnabledForUser(mUserId, true);
@@ -475,7 +489,7 @@
     }
 
     @Test
-    public void setBackupEnabled_forwardedToCallingUserId() throws RemoteException {
+    public void setBackupEnabled_forwardedToCallingUserId() throws Exception {
         TrampolineTestable.sCallingUserId = mUserId;
         mTrampoline.initializeService();
 
@@ -485,13 +499,13 @@
     }
 
     @Test
-    public void setAutoRestore_calledBeforeInitialize_ignored() throws RemoteException {
+    public void setAutoRestore_calledBeforeInitialize_ignored() throws Exception {
         mTrampoline.setAutoRestore(true);
         verifyNoMoreInteractions(mBackupManagerServiceMock);
     }
 
     @Test
-    public void setAutoRestoreForUser_forwarded() throws RemoteException {
+    public void setAutoRestoreForUser_forwarded() throws Exception {
         mTrampoline.initializeService();
 
         mTrampoline.setAutoRestoreForUser(mUserId, true);
@@ -500,7 +514,7 @@
     }
 
     @Test
-    public void setAutoRestore_forwarded() throws RemoteException {
+    public void setAutoRestore_forwarded() throws Exception {
         TrampolineTestable.sCallingUserId = mUserId;
         mTrampoline.initializeService();
 
@@ -510,13 +524,13 @@
     }
 
     @Test
-    public void isBackupEnabled_calledBeforeInitialize_ignored() throws RemoteException {
+    public void isBackupEnabled_calledBeforeInitialize_ignored() throws Exception {
         assertFalse(mTrampoline.isBackupEnabled());
         verifyNoMoreInteractions(mBackupManagerServiceMock);
     }
 
     @Test
-    public void isBackupEnabledForUser_forwarded() throws RemoteException {
+    public void isBackupEnabledForUser_forwarded() throws Exception {
         mTrampoline.initializeService();
 
         mTrampoline.isBackupEnabledForUser(mUserId);
@@ -525,7 +539,7 @@
     }
 
     @Test
-    public void isBackupEnabled_forwardedToCallingUserId() throws RemoteException {
+    public void isBackupEnabled_forwardedToCallingUserId() throws Exception {
         TrampolineTestable.sCallingUserId = mUserId;
         mTrampoline.initializeService();
 
@@ -535,39 +549,39 @@
     }
 
     @Test
-    public void setBackupPassword_calledBeforeInitialize_ignored() throws RemoteException {
+    public void setBackupPassword_calledBeforeInitialize_ignored() throws Exception {
         mTrampoline.setBackupPassword(CURRENT_PASSWORD, NEW_PASSWORD);
         verifyNoMoreInteractions(mBackupManagerServiceMock);
     }
 
     @Test
-    public void setBackupPassword_forwarded() throws RemoteException {
+    public void setBackupPassword_forwarded() throws Exception {
         mTrampoline.initializeService();
         mTrampoline.setBackupPassword(CURRENT_PASSWORD, NEW_PASSWORD);
         verify(mBackupManagerServiceMock).setBackupPassword(CURRENT_PASSWORD, NEW_PASSWORD);
     }
 
     @Test
-    public void hasBackupPassword_calledBeforeInitialize_ignored() throws RemoteException {
+    public void hasBackupPassword_calledBeforeInitialize_ignored() throws Exception {
         assertFalse(mTrampoline.hasBackupPassword());
         verifyNoMoreInteractions(mBackupManagerServiceMock);
     }
 
     @Test
-    public void hasBackupPassword_forwarded() throws RemoteException {
+    public void hasBackupPassword_forwarded() throws Exception {
         mTrampoline.initializeService();
         mTrampoline.hasBackupPassword();
         verify(mBackupManagerServiceMock).hasBackupPassword();
     }
 
     @Test
-    public void backupNow_calledBeforeInitialize_ignored() throws RemoteException {
+    public void backupNow_calledBeforeInitialize_ignored() throws Exception {
         mTrampoline.backupNow();
         verifyNoMoreInteractions(mBackupManagerServiceMock);
     }
 
     @Test
-    public void backupNowForUser_forwarded() throws RemoteException {
+    public void backupNowForUser_forwarded() throws Exception {
         mTrampoline.initializeService();
 
         mTrampoline.backupNowForUser(mUserId);
@@ -576,7 +590,7 @@
     }
 
     @Test
-    public void backupNow_forwardedToCallingUserId() throws RemoteException {
+    public void backupNow_forwardedToCallingUserId() throws Exception {
         TrampolineTestable.sCallingUserId = mUserId;
         mTrampoline.initializeService();
 
@@ -586,7 +600,7 @@
     }
 
     @Test
-    public void adbBackup_calledBeforeInitialize_ignored() throws RemoteException {
+    public void adbBackup_calledBeforeInitialize_ignored() throws Exception {
         mTrampoline.adbBackup(mUserId, mParcelFileDescriptorMock, true, true,
                 true, true, true, true, true, true,
                 PACKAGE_NAMES);
@@ -594,7 +608,7 @@
     }
 
     @Test
-    public void adbBackup_forwarded() throws RemoteException {
+    public void adbBackup_forwarded() throws Exception {
         mTrampoline.initializeService();
         mTrampoline.adbBackup(mUserId, mParcelFileDescriptorMock, true, true,
                 true, true, true, true, true, true,
@@ -604,13 +618,13 @@
     }
 
     @Test
-    public void fullTransportBackup_calledBeforeInitialize_ignored() throws RemoteException {
+    public void fullTransportBackup_calledBeforeInitialize_ignored() throws Exception {
         mTrampoline.fullTransportBackupForUser(mUserId, PACKAGE_NAMES);
         verifyNoMoreInteractions(mBackupManagerServiceMock);
     }
 
     @Test
-    public void fullTransportBackupForUser_forwarded() throws RemoteException {
+    public void fullTransportBackupForUser_forwarded() throws Exception {
         mTrampoline.initializeService();
 
         mTrampoline.fullTransportBackupForUser(mUserId, PACKAGE_NAMES);
@@ -619,13 +633,13 @@
     }
 
     @Test
-    public void adbRestore_calledBeforeInitialize_ignored() throws RemoteException {
+    public void adbRestore_calledBeforeInitialize_ignored() throws Exception {
         mTrampoline.adbRestore(mUserId, mParcelFileDescriptorMock);
         verifyNoMoreInteractions(mBackupManagerServiceMock);
     }
 
     @Test
-    public void adbRestore_forwarded() throws RemoteException {
+    public void adbRestore_forwarded() throws Exception {
         mTrampoline.initializeService();
         mTrampoline.adbRestore(mUserId, mParcelFileDescriptorMock);
         verify(mBackupManagerServiceMock).adbRestore(mUserId, mParcelFileDescriptorMock);
@@ -633,14 +647,14 @@
 
     @Test
     public void acknowledgeFullBackupOrRestore_calledBeforeInitialize_ignored()
-            throws RemoteException {
+            throws Exception {
         mTrampoline.acknowledgeFullBackupOrRestore(123, true, CURRENT_PASSWORD, ENCRYPTION_PASSWORD,
                 mFullBackupRestoreObserverMock);
         verifyNoMoreInteractions(mBackupManagerServiceMock);
     }
 
     @Test
-    public void acknowledgeFullBackupOrRestoreForUser_forwarded() throws RemoteException {
+    public void acknowledgeFullBackupOrRestoreForUser_forwarded() throws Exception {
         mTrampoline.initializeService();
 
         mTrampoline.acknowledgeFullBackupOrRestoreForUser(
@@ -662,7 +676,7 @@
     }
 
     @Test
-    public void acknowledgeFullBackupOrRestore_forwarded() throws RemoteException {
+    public void acknowledgeFullBackupOrRestore_forwarded() throws Exception {
         TrampolineTestable.sCallingUserId = mUserId;
         mTrampoline.initializeService();
 
@@ -680,13 +694,13 @@
     }
 
     @Test
-    public void getCurrentTransport_calledBeforeInitialize_ignored() throws RemoteException {
+    public void getCurrentTransport_calledBeforeInitialize_ignored() throws Exception {
         assertNull(mTrampoline.getCurrentTransport());
         verifyNoMoreInteractions(mBackupManagerServiceMock);
     }
 
     @Test
-    public void getCurrentTransportForUser_forwarded() throws RemoteException {
+    public void getCurrentTransportForUser_forwarded() throws Exception {
         when(mBackupManagerServiceMock.getCurrentTransport(mUserId)).thenReturn(TRANSPORT_NAME);
         mTrampoline.initializeService();
 
@@ -695,7 +709,7 @@
     }
 
     @Test
-    public void getCurrentTransport_forwarded() throws RemoteException {
+    public void getCurrentTransport_forwarded() throws Exception {
         TrampolineTestable.sCallingUserId = mUserId;
         when(mBackupManagerServiceMock.getCurrentTransport(mUserId)).thenReturn(TRANSPORT_NAME);
         mTrampoline.initializeService();
@@ -705,13 +719,13 @@
     }
 
     @Test
-    public void listAllTransports_calledBeforeInitialize_ignored() throws RemoteException {
+    public void listAllTransports_calledBeforeInitialize_ignored() throws Exception {
         assertNull(mTrampoline.listAllTransports());
         verifyNoMoreInteractions(mBackupManagerServiceMock);
     }
 
     @Test
-    public void listAllTransportsForUser_forwarded() throws RemoteException {
+    public void listAllTransportsForUser_forwarded() throws Exception {
         when(mBackupManagerServiceMock.listAllTransports(mUserId)).thenReturn(TRANSPORTS);
         mTrampoline.initializeService();
 
@@ -721,7 +735,7 @@
 
 
     @Test
-    public void listAllTransports_forwarded() throws RemoteException {
+    public void listAllTransports_forwarded() throws Exception {
         TrampolineTestable.sCallingUserId = mUserId;
         when(mBackupManagerServiceMock.listAllTransports(mUserId)).thenReturn(TRANSPORTS);
         mTrampoline.initializeService();
@@ -732,13 +746,13 @@
 
     @Test
     public void listAllTransportComponentsForUser_calledBeforeInitialize_ignored()
-            throws RemoteException {
+            throws Exception {
         assertNull(mTrampoline.listAllTransportComponentsForUser(mUserId));
         verifyNoMoreInteractions(mBackupManagerServiceMock);
     }
 
     @Test
-    public void listAllTransportComponentsForUser_forwarded() throws RemoteException {
+    public void listAllTransportComponentsForUser_forwarded() throws Exception {
         when(mBackupManagerServiceMock.listAllTransportComponents(mUserId)).thenReturn(
                 TRANSPORT_COMPONENTS);
         mTrampoline.initializeService();
@@ -748,13 +762,13 @@
     }
 
     @Test
-    public void getTransportWhitelist_calledBeforeInitialize_ignored() throws RemoteException {
+    public void getTransportWhitelist_calledBeforeInitialize_ignored() throws Exception {
         assertNull(mTrampoline.getTransportWhitelist());
         verifyNoMoreInteractions(mBackupManagerServiceMock);
     }
 
     @Test
-    public void getTransportWhitelist_forwarded() throws RemoteException {
+    public void getTransportWhitelist_forwarded() {
         when(mBackupManagerServiceMock.getTransportWhitelist()).thenReturn(TRANSPORTS);
         mTrampoline.initializeService();
 
@@ -763,8 +777,7 @@
     }
 
     @Test
-    public void updateTransportAttributesForUser_calledBeforeInitialize_ignored()
-            throws RemoteException {
+    public void updateTransportAttributesForUser_calledBeforeInitialize_ignored() {
         mTrampoline.updateTransportAttributesForUser(
                 mUserId,
                 TRANSPORT_COMPONENT_NAME,
@@ -778,7 +791,7 @@
     }
 
     @Test
-    public void updateTransportAttributesForUser_forwarded() throws RemoteException {
+    public void updateTransportAttributesForUser_forwarded() {
         when(mBackupManagerServiceMock.getTransportWhitelist()).thenReturn(TRANSPORTS);
         mTrampoline.initializeService();
 
@@ -809,7 +822,7 @@
     }
 
     @Test
-    public void selectBackupTransportForUser_forwarded() throws RemoteException {
+    public void selectBackupTransportForUser_forwarded() throws Exception {
         mTrampoline.initializeService();
 
         mTrampoline.selectBackupTransportForUser(mUserId, TRANSPORT_NAME);
@@ -818,7 +831,7 @@
     }
 
     @Test
-    public void selectBackupTransport_forwarded() throws RemoteException {
+    public void selectBackupTransport_forwarded() throws Exception {
         TrampolineTestable.sCallingUserId = mUserId;
         mTrampoline.initializeService();
 
@@ -895,7 +908,7 @@
     }
 
     @Test
-    public void selectBackupTransportAsyncForUser_forwarded() throws RemoteException {
+    public void selectBackupTransportAsyncForUser_forwarded() throws Exception {
         mTrampoline.initializeService();
 
         mTrampoline.selectBackupTransportAsyncForUser(mUserId, TRANSPORT_COMPONENT_NAME, null);
@@ -905,13 +918,13 @@
     }
 
     @Test
-    public void getConfigurationIntent_calledBeforeInitialize_ignored() throws RemoteException {
+    public void getConfigurationIntent_calledBeforeInitialize_ignored() throws Exception {
         mTrampoline.getConfigurationIntent(TRANSPORT_NAME);
         verifyNoMoreInteractions(mBackupManagerServiceMock);
     }
 
     @Test
-    public void getConfigurationIntentForUser_forwarded() throws RemoteException {
+    public void getConfigurationIntentForUser_forwarded() throws Exception {
         Intent configurationIntentStub = new Intent();
         when(mBackupManagerServiceMock.getConfigurationIntent(mUserId, TRANSPORT_NAME)).thenReturn(
                 configurationIntentStub);
@@ -924,7 +937,7 @@
     }
 
     @Test
-    public void getConfigurationIntent_forwarded() throws RemoteException {
+    public void getConfigurationIntent_forwarded() throws Exception {
         TrampolineTestable.sCallingUserId = mUserId;
         Intent configurationIntentStub = new Intent();
         when(mBackupManagerServiceMock.getConfigurationIntent(mUserId, TRANSPORT_NAME)).thenReturn(
@@ -936,13 +949,13 @@
     }
 
     @Test
-    public void getDestinationString_calledBeforeInitialize_ignored() throws RemoteException {
+    public void getDestinationString_calledBeforeInitialize_ignored() throws Exception {
         assertNull(mTrampoline.getDestinationString(TRANSPORT_NAME));
         verifyNoMoreInteractions(mBackupManagerServiceMock);
     }
 
     @Test
-    public void getDestinationStringForUser_forwarded() throws RemoteException {
+    public void getDestinationStringForUser_forwarded() throws Exception {
         when(mBackupManagerServiceMock.getDestinationString(mUserId, TRANSPORT_NAME)).thenReturn(
                 DESTINATION_STRING);
         mTrampoline.initializeService();
@@ -954,7 +967,7 @@
     }
 
     @Test
-    public void getDestinationString_forwarded() throws RemoteException {
+    public void getDestinationString_forwarded() throws Exception {
         TrampolineTestable.sCallingUserId = mUserId;
         when(mBackupManagerServiceMock.getDestinationString(mUserId, TRANSPORT_NAME)).thenReturn(
                 DESTINATION_STRING);
@@ -965,13 +978,13 @@
     }
 
     @Test
-    public void getDataManagementIntent_calledBeforeInitialize_ignored() throws RemoteException {
+    public void getDataManagementIntent_calledBeforeInitialize_ignored() throws Exception {
         assertNull(mTrampoline.getDataManagementIntent(TRANSPORT_NAME));
         verifyNoMoreInteractions(mBackupManagerServiceMock);
     }
 
     @Test
-    public void getDataManagementIntentForUser_forwarded() throws RemoteException {
+    public void getDataManagementIntentForUser_forwarded() throws Exception {
         Intent dataManagementIntent = new Intent();
         when(mBackupManagerServiceMock.getDataManagementIntent(mUserId, TRANSPORT_NAME)).thenReturn(
                 dataManagementIntent);
@@ -984,7 +997,7 @@
     }
 
     @Test
-    public void getDataManagementIntent_forwarded() throws RemoteException {
+    public void getDataManagementIntent_forwarded() throws Exception {
         TrampolineTestable.sCallingUserId = mUserId;
         Intent dataManagementIntent = new Intent();
         when(mBackupManagerServiceMock.getDataManagementIntent(mUserId, TRANSPORT_NAME)).thenReturn(
@@ -996,13 +1009,13 @@
     }
 
     @Test
-    public void getDataManagementLabel_calledBeforeInitialize_ignored() throws RemoteException {
+    public void getDataManagementLabel_calledBeforeInitialize_ignored() throws Exception {
         assertNull(mTrampoline.getDataManagementLabel(TRANSPORT_NAME));
         verifyNoMoreInteractions(mBackupManagerServiceMock);
     }
 
     @Test
-    public void getDataManagementLabelForUser_forwarded() throws RemoteException {
+    public void getDataManagementLabelForUser_forwarded() throws Exception {
         when(mBackupManagerServiceMock.getDataManagementLabel(mUserId, TRANSPORT_NAME)).thenReturn(
                 DATA_MANAGEMENT_LABEL);
         mTrampoline.initializeService();
@@ -1014,7 +1027,7 @@
     }
 
     @Test
-    public void getDataManagementLabel_forwarded() throws RemoteException {
+    public void getDataManagementLabel_forwarded() throws Exception {
         TrampolineTestable.sCallingUserId = mUserId;
         when(mBackupManagerServiceMock.getDataManagementLabel(mUserId, TRANSPORT_NAME)).thenReturn(
                 DATA_MANAGEMENT_LABEL);
@@ -1025,13 +1038,13 @@
     }
 
     @Test
-    public void beginRestoreSession_calledBeforeInitialize_ignored() throws RemoteException {
+    public void beginRestoreSession_calledBeforeInitialize_ignored() throws Exception {
         mTrampoline.beginRestoreSessionForUser(mUserId, PACKAGE_NAME, TRANSPORT_NAME);
         verifyNoMoreInteractions(mBackupManagerServiceMock);
     }
 
     @Test
-    public void beginRestoreSessionForUser_forwarded() throws RemoteException {
+    public void beginRestoreSessionForUser_forwarded() throws Exception {
         mTrampoline.initializeService();
 
         mTrampoline.beginRestoreSessionForUser(mUserId, PACKAGE_NAME, TRANSPORT_NAME);
@@ -1041,13 +1054,13 @@
     }
 
     @Test
-    public void opComplete_calledBeforeInitialize_ignored() throws RemoteException {
+    public void opComplete_calledBeforeInitialize_ignored() throws Exception {
         mTrampoline.opComplete(1, 2);
         verifyNoMoreInteractions(mBackupManagerServiceMock);
     }
 
     @Test
-    public void opComplete_forwarded() throws RemoteException {
+    public void opComplete_forwarded() throws Exception {
         TrampolineTestable.sCallingUserId = mUserId;
         mTrampoline.initializeService();
 
@@ -1057,14 +1070,13 @@
     }
 
     @Test
-    public void getAvailableRestoreTokenForUser_calledBeforeInitialize_ignored()
-            throws RemoteException {
+    public void getAvailableRestoreTokenForUser_calledBeforeInitialize_ignored() {
         assertEquals(0, mTrampoline.getAvailableRestoreTokenForUser(mUserId, PACKAGE_NAME));
         verifyNoMoreInteractions(mBackupManagerServiceMock);
     }
 
     @Test
-    public void getAvailableRestoreTokenForUser_forwarded() throws RemoteException {
+    public void getAvailableRestoreTokenForUser_forwarded() {
         when(mBackupManagerServiceMock.getAvailableRestoreToken(mUserId, PACKAGE_NAME))
                 .thenReturn(123L);
         mTrampoline.initializeService();
@@ -1074,14 +1086,13 @@
     }
 
     @Test
-    public void isAppEligibleForBackupForUser_calledBeforeInitialize_ignored()
-            throws RemoteException {
+    public void isAppEligibleForBackupForUser_calledBeforeInitialize_ignored() {
         assertFalse(mTrampoline.isAppEligibleForBackupForUser(mUserId, PACKAGE_NAME));
         verifyNoMoreInteractions(mBackupManagerServiceMock);
     }
 
     @Test
-    public void isAppEligibleForBackupForUser_forwarded() throws RemoteException {
+    public void isAppEligibleForBackupForUser_forwarded() {
         when(mBackupManagerServiceMock.isAppEligibleForBackup(mUserId, PACKAGE_NAME))
                 .thenReturn(true);
         mTrampoline.initializeService();
@@ -1098,7 +1109,7 @@
     }
 
     @Test
-    public void requestBackupForUser_forwarded() throws RemoteException {
+    public void requestBackupForUser_forwarded() throws Exception {
         when(mBackupManagerServiceMock.requestBackup(mUserId, PACKAGE_NAMES,
                 mBackupObserverMock, mBackupManagerMonitorMock, 123)).thenReturn(456);
         mTrampoline.initializeService();
@@ -1110,7 +1121,7 @@
     }
 
     @Test
-    public void requestBackup_forwardedToCallingUserId() throws RemoteException {
+    public void requestBackup_forwardedToCallingUserId() throws Exception {
         TrampolineTestable.sCallingUserId = mUserId;
         when(mBackupManagerServiceMock.requestBackup(NON_USER_SYSTEM, PACKAGE_NAMES,
                 mBackupObserverMock, mBackupManagerMonitorMock, 123)).thenReturn(456);
@@ -1123,13 +1134,13 @@
     }
 
     @Test
-    public void cancelBackups_calledBeforeInitialize_ignored() throws RemoteException {
+    public void cancelBackups_calledBeforeInitialize_ignored() throws Exception {
         mTrampoline.cancelBackups();
         verifyNoMoreInteractions(mBackupManagerServiceMock);
     }
 
     @Test
-    public void cancelBackupsForUser_forwarded() throws RemoteException {
+    public void cancelBackupsForUser_forwarded() throws Exception {
         mTrampoline.initializeService();
 
         mTrampoline.cancelBackupsForUser(mUserId);
@@ -1138,7 +1149,7 @@
     }
 
     @Test
-    public void cancelBackups_forwardedToCallingUserId() throws RemoteException {
+    public void cancelBackups_forwardedToCallingUserId() throws Exception {
         TrampolineTestable.sCallingUserId = mUserId;
         mTrampoline.initializeService();
 
@@ -1148,13 +1159,13 @@
     }
 
     @Test
-    public void beginFullBackup_calledBeforeInitialize_ignored() throws RemoteException {
+    public void beginFullBackup_calledBeforeInitialize_ignored() throws Exception {
         mTrampoline.beginFullBackup(mUserId, new FullBackupJob());
         verifyNoMoreInteractions(mBackupManagerServiceMock);
     }
 
     @Test
-    public void beginFullBackup_forwarded() throws RemoteException {
+    public void beginFullBackup_forwarded() throws Exception {
         FullBackupJob fullBackupJob = new FullBackupJob();
         when(mBackupManagerServiceMock.beginFullBackup(mUserId, fullBackupJob)).thenReturn(true);
 
@@ -1164,20 +1175,20 @@
     }
 
     @Test
-    public void endFullBackup_calledBeforeInitialize_ignored() throws RemoteException {
+    public void endFullBackup_calledBeforeInitialize_ignored() {
         mTrampoline.endFullBackup(mUserId);
         verifyNoMoreInteractions(mBackupManagerServiceMock);
     }
 
     @Test
-    public void endFullBackup_forwarded() throws RemoteException {
+    public void endFullBackup_forwarded() {
         mTrampoline.initializeService();
         mTrampoline.endFullBackup(mUserId);
         verify(mBackupManagerServiceMock).endFullBackup(mUserId);
     }
 
     @Test
-    public void dump_callerDoesNotHavePermission_ignored() throws RemoteException {
+    public void dump_callerDoesNotHavePermission_ignored() {
         when(mContextMock.checkCallingOrSelfPermission(
                 android.Manifest.permission.DUMP)).thenReturn(
                 PackageManager.PERMISSION_DENIED);
@@ -1189,7 +1200,7 @@
     }
 
     @Test
-    public void dump_calledBeforeInitialize_ignored() throws RemoteException {
+    public void dump_calledBeforeInitialize_ignored() {
         when(mContextMock.checkCallingOrSelfPermission(
                 android.Manifest.permission.DUMP)).thenReturn(
                 PackageManager.PERMISSION_GRANTED);
@@ -1200,7 +1211,7 @@
     }
 
     @Test
-    public void dump_callerHasPermission_forwarded() throws RemoteException {
+    public void dump_callerHasPermission_forwarded() {
         when(mContextMock.checkCallingOrSelfPermission(
                 android.Manifest.permission.DUMP)).thenReturn(
                 PackageManager.PERMISSION_GRANTED);
@@ -1213,11 +1224,36 @@
 
     private static class TrampolineTestable extends Trampoline {
         static boolean sBackupDisabled = false;
-        static File sSuppressFile = null;
         static int sCallingUserId = -1;
         static int sCallingUid = -1;
         static BackupManagerService sBackupManagerServiceMock = null;
         private int mCreateServiceCallsCount = 0;
+        private SparseArray<FakeFile> mSuppressFiles = new SparseArray<>();
+
+        private static class FakeFile extends File {
+            private boolean mExists;
+
+            FakeFile(String pathname) {
+                super(pathname);
+            }
+
+            @Override
+            public boolean exists() {
+                return mExists;
+            }
+
+            @Override
+            public boolean delete() {
+                mExists = false;
+                return true;
+            }
+
+            @Override
+            public boolean createNewFile() throws IOException {
+                mExists = true;
+                return true;
+            }
+        }
 
         TrampolineTestable(Context context) {
             super(context);
@@ -1229,8 +1265,12 @@
         }
 
         @Override
-        public File getSuppressFile() {
-            return sSuppressFile;
+        public File getSuppressFileForUser(int userId) {
+            if (mSuppressFiles.get(userId) == null) {
+                FakeFile file = new FakeFile(Integer.toString(userId));
+                mSuppressFiles.append(userId, file);
+            }
+            return mSuppressFiles.get(userId);
         }
 
         protected int binderGetCallingUserId() {
@@ -1249,6 +1289,11 @@
         }
 
         @Override
+        protected void createBackupSuppressFileForUser(int userId) throws IOException {
+            getSuppressFileForUser(userId).createNewFile();
+        }
+
+        @Override
         protected void postToHandler(Runnable runnable) {
             runnable.run();
         }
diff --git a/services/tests/servicestests/src/com/android/server/pm/LauncherAppsServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/LauncherAppsServiceTest.java
new file mode 100644
index 0000000..d7dc58d
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/LauncherAppsServiceTest.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.assertEquals;
+
+import android.content.pm.PackageParser;
+import android.content.pm.Signature;
+import android.content.pm.SigningInfo;
+import android.platform.test.annotations.Presubmit;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.junit.MockitoJUnitRunner;
+
+@Presubmit
+@RunWith(MockitoJUnitRunner.class)
+public class LauncherAppsServiceTest {
+
+    private static final Signature SIGNATURE_1 = new Signature(new byte[]{0x00, 0x01, 0x02, 0x03});
+    private static final Signature SIGNATURE_2 = new Signature(new byte[]{0x04, 0x05, 0x06, 0x07});
+    private static final Signature SIGNATURE_3 = new Signature(new byte[]{0x08, 0x09, 0x10, 0x11});
+
+    @Test
+    public void testComputePackageCertDigest() {
+        String digest = LauncherAppsService.LauncherAppsImpl.computePackageCertDigest(SIGNATURE_1);
+        assertEquals("A02A05B025B928C039CF1AE7E8EE04E7C190C0DB", digest);
+    }
+
+    @Test
+    public void testGetLatestSignaturesWithSingleCert() {
+        SigningInfo signingInfo = new SigningInfo(
+                new PackageParser.SigningDetails(
+                        new Signature[]{SIGNATURE_1},
+                        PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
+                        null,
+                        null));
+        Signature[] signatures = LauncherAppsService.LauncherAppsImpl.getLatestSignatures(
+                signingInfo);
+        assertEquals(1, signatures.length);
+        assertEquals(SIGNATURE_1, signatures[0]);
+    }
+
+    @Test
+    public void testGetLatestSignaturesWithMultiCert() {
+        SigningInfo signingInfo = new SigningInfo(
+                new PackageParser.SigningDetails(
+                        new Signature[]{SIGNATURE_1, SIGNATURE_2},
+                        PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
+                        null,
+                        null));
+        Signature[] signatures = LauncherAppsService.LauncherAppsImpl.getLatestSignatures(
+                signingInfo);
+        assertEquals(2, signatures.length);
+        assertEquals(SIGNATURE_1, signatures[0]);
+        assertEquals(SIGNATURE_2, signatures[1]);
+    }
+
+    @Test
+    public void testGetLatestSignaturesWithCertHistory() {
+        SigningInfo signingInfo = new SigningInfo(
+                new PackageParser.SigningDetails(
+                        new Signature[]{SIGNATURE_1},
+                        PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
+                        null,
+                        new Signature[]{SIGNATURE_2, SIGNATURE_3}));
+        Signature[] signatures = LauncherAppsService.LauncherAppsImpl.getLatestSignatures(
+                signingInfo);
+        assertEquals(1, signatures.length);
+        assertEquals(SIGNATURE_2, signatures[0]);
+    }
+
+}
diff --git a/tests/net/java/android/net/apf/ApfTest.java b/tests/net/java/android/net/apf/ApfTest.java
index 151b559..3c3e7ce 100644
--- a/tests/net/java/android/net/apf/ApfTest.java
+++ b/tests/net/java/android/net/apf/ApfTest.java
@@ -16,10 +16,19 @@
 
 package android.net.apf;
 
-import static android.net.util.NetworkConstants.*;
-import static android.system.OsConstants.*;
+import static android.net.util.NetworkConstants.ICMPV6_ECHO_REQUEST_TYPE;
+import static android.net.util.NetworkConstants.ICMPV6_ROUTER_ADVERTISEMENT;
+import static android.system.OsConstants.AF_UNIX;
+import static android.system.OsConstants.ARPHRD_ETHER;
+import static android.system.OsConstants.ETH_P_ARP;
+import static android.system.OsConstants.ETH_P_IP;
+import static android.system.OsConstants.ETH_P_IPV6;
+import static android.system.OsConstants.IPPROTO_ICMPV6;
+import static android.system.OsConstants.IPPROTO_UDP;
+import static android.system.OsConstants.SOCK_STREAM;
+
 import static com.android.internal.util.BitUtils.bytesToBEInt;
-import static com.android.internal.util.BitUtils.put;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -33,7 +42,7 @@
 import android.net.apf.ApfFilter.ApfConfiguration;
 import android.net.apf.ApfGenerator.IllegalInstructionException;
 import android.net.apf.ApfGenerator.Register;
-import android.net.ip.IpClient;
+import android.net.ip.IpClientCallbacks;
 import android.net.metrics.IpConnectivityLog;
 import android.net.metrics.RaEvent;
 import android.net.util.InterfaceParams;
@@ -47,8 +56,20 @@
 import android.system.Os;
 import android.text.format.DateUtils;
 import android.util.Log;
+
 import com.android.frameworks.tests.net.R;
 import com.android.internal.util.HexDump;
+
+import libcore.io.IoUtils;
+import libcore.io.Streams;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileOutputStream;
@@ -59,14 +80,6 @@
 import java.nio.ByteBuffer;
 import java.util.List;
 import java.util.Random;
-import libcore.io.IoUtils;
-import libcore.io.Streams;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
 
 /**
  * Tests for APF program generator and interpreter.
@@ -902,7 +915,7 @@
             HexDump.toHexString(data, false), result);
     }
 
-    private class MockIpClientCallback extends IpClient.Callback {
+    private class MockIpClientCallback extends IpClientCallbacks {
         private final ConditionVariable mGotApfProgram = new ConditionVariable();
         private byte[] mLastApfProgram;
 
@@ -933,7 +946,7 @@
         private final long mFixedTimeMs = SystemClock.elapsedRealtime();
 
         public TestApfFilter(Context context, ApfConfiguration config,
-                IpClient.Callback ipClientCallback, IpConnectivityLog log) throws Exception {
+                IpClientCallbacks ipClientCallback, IpConnectivityLog log) throws Exception {
             super(context, config, InterfaceParams.getByName("lo"), ipClientCallback, log);
         }
 
@@ -1062,7 +1075,7 @@
     private static final byte[] IPV4_ANY_HOST_ADDR       = {0, 0, 0, 0};
 
     // Helper to initialize a default apfFilter.
-    private ApfFilter setupApfFilter(IpClient.Callback ipClientCallback, ApfConfiguration config)
+    private ApfFilter setupApfFilter(IpClientCallbacks ipClientCallback, ApfConfiguration config)
             throws Exception {
         LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19);
         LinkProperties lp = new LinkProperties();
@@ -1509,7 +1522,8 @@
     }
 
     private void verifyRaEvent(RaEvent expected) {
-        ArgumentCaptor<Parcelable> captor = ArgumentCaptor.forClass(Parcelable.class);
+        ArgumentCaptor<IpConnectivityLog.Event> captor =
+                ArgumentCaptor.forClass(IpConnectivityLog.Event.class);
         verify(mLog, atLeastOnce()).log(captor.capture());
         RaEvent got = lastRaEvent(captor.getAllValues());
         if (!raEventEquals(expected, got)) {
@@ -1517,7 +1531,7 @@
         }
     }
 
-    private RaEvent lastRaEvent(List<Parcelable> events) {
+    private RaEvent lastRaEvent(List<IpConnectivityLog.Event> events) {
         RaEvent got = null;
         for (Parcelable ev : events) {
             if (ev instanceof RaEvent) {
diff --git a/tests/net/java/android/net/ip/IpClientTest.java b/tests/net/java/android/net/ip/IpClientTest.java
index cba3c65..a2dcfef 100644
--- a/tests/net/java/android/net/ip/IpClientTest.java
+++ b/tests/net/java/android/net/ip/IpClientTest.java
@@ -23,7 +23,6 @@
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyString;
 import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.timeout;
@@ -40,9 +39,8 @@
 import android.net.LinkProperties;
 import android.net.MacAddress;
 import android.net.RouteInfo;
-import android.net.ip.IpClient.Callback;
-import android.net.ip.IpClient.InitialConfiguration;
-import android.net.ip.IpClient.ProvisioningConfiguration;
+import android.net.shared.InitialConfiguration;
+import android.net.shared.ProvisioningConfiguration;
 import android.net.util.InterfaceParams;
 import android.os.INetworkManagementService;
 import android.provider.Settings;
@@ -50,8 +48,8 @@
 import android.support.test.runner.AndroidJUnit4;
 import android.test.mock.MockContentResolver;
 
-import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.internal.R;
+import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.server.net.BaseNetworkObserver;
 
 import org.junit.Before;
@@ -63,8 +61,8 @@
 
 import java.net.InetAddress;
 import java.util.Arrays;
-import java.util.List;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 
 /**
@@ -87,7 +85,7 @@
     @Mock private INetworkManagementService mNMService;
     @Mock private INetd mNetd;
     @Mock private Resources mResources;
-    @Mock private Callback mCb;
+    @Mock private IpClientCallbacks mCb;
     @Mock private AlarmManager mAlarm;
     @Mock private IpClient.Dependencies mDependecies;
     private MockContentResolver mContentResolver;
@@ -179,7 +177,7 @@
     public void testInterfaceNotFoundFailsImmediately() throws Exception {
         setTestInterfaceParams(null);
         final IpClient ipc = new IpClient(mContext, TEST_IFNAME, mCb, mDependecies);
-        ipc.startProvisioning(new IpClient.ProvisioningConfiguration());
+        ipc.startProvisioning(new ProvisioningConfiguration());
         verify(mCb, times(1)).onProvisioningFailure(any());
         ipc.shutdown();
     }
diff --git a/tests/net/java/android/net/shared/LinkPropertiesParcelableUtilTest.java b/tests/net/java/android/net/shared/LinkPropertiesParcelableUtilTest.java
index 6f711c0..b6d01db 100644
--- a/tests/net/java/android/net/shared/LinkPropertiesParcelableUtilTest.java
+++ b/tests/net/java/android/net/shared/LinkPropertiesParcelableUtilTest.java
@@ -48,61 +48,52 @@
     private LinkProperties mLinkProperties;
 
     private static final String TEST_LINKPROPS_IFACE = "TEST_IFACE";
-    private static final String TEST_STACKED_LINK_1_IFACE = "TEST_STACKED_IFACE_1";
-    private static final String TEST_STACKED_LINK_2_IFACE = "TEST_STACKED_IFACE_2";
 
     @Before
     public void setUp() {
-        mLinkProperties = makeLinkProperties(TEST_LINKPROPS_IFACE);
-        mLinkProperties.addStackedLink(makeLinkProperties(TEST_STACKED_LINK_1_IFACE));
-        mLinkProperties.addStackedLink(makeLinkProperties(TEST_STACKED_LINK_2_IFACE));
-    }
-
-    private static LinkProperties makeLinkProperties(String iface) {
-        final LinkProperties lp = new LinkProperties();
-        lp.setInterfaceName(iface);
-        lp.setLinkAddresses(Arrays.asList(
+        mLinkProperties = new LinkProperties();
+        mLinkProperties.setInterfaceName(TEST_LINKPROPS_IFACE);
+        mLinkProperties.setLinkAddresses(Arrays.asList(
                 new LinkAddress(InetAddresses.parseNumericAddress("192.168.0.42"), 16),
                 new LinkAddress(InetAddresses.parseNumericAddress("2001:db8::7"), 42)));
-        lp.setDnsServers(Arrays.asList(
+        mLinkProperties.setDnsServers(Arrays.asList(
                 InetAddresses.parseNumericAddress("2001:db8::42"),
                 InetAddresses.parseNumericAddress("192.168.1.1")
         ));
-        lp.setValidatedPrivateDnsServers(Arrays.asList(
+        mLinkProperties.setValidatedPrivateDnsServers(Arrays.asList(
                 InetAddresses.parseNumericAddress("2001:db8::43"),
                 InetAddresses.parseNumericAddress("192.168.42.43")
         ));
-        lp.setPcscfServers(Arrays.asList(
+        mLinkProperties.setPcscfServers(Arrays.asList(
                 InetAddresses.parseNumericAddress("2001:db8::47"),
                 InetAddresses.parseNumericAddress("192.168.42.47")
         ));
-        lp.setUsePrivateDns(true);
-        lp.setPrivateDnsServerName("test.example.com");
-        lp.setDomains("test1.example.com,test2.example.com");
-        lp.addRoute(new RouteInfo(
+        mLinkProperties.setUsePrivateDns(true);
+        mLinkProperties.setPrivateDnsServerName("test.example.com");
+        mLinkProperties.setDomains("test1.example.com,test2.example.com");
+        mLinkProperties.addRoute(new RouteInfo(
                 new IpPrefix(InetAddresses.parseNumericAddress("2001:db8::44"), 45),
                 InetAddresses.parseNumericAddress("2001:db8::45"),
-                iface,
+                TEST_LINKPROPS_IFACE,
                 RouteInfo.RTN_UNICAST
         ));
-        lp.addRoute(new RouteInfo(
+        mLinkProperties.addRoute(new RouteInfo(
                 new IpPrefix(InetAddresses.parseNumericAddress("192.168.44.45"), 16),
                 InetAddresses.parseNumericAddress("192.168.45.1"),
-                iface,
+                TEST_LINKPROPS_IFACE,
                 RouteInfo.RTN_THROW
         ));
-        lp.setHttpProxy(new ProxyInfo("test3.example.com", 8000,
+        mLinkProperties.setHttpProxy(new ProxyInfo("test3.example.com", 8000,
                 "excl1.example.com,excl2.example.com"));
-        lp.setMtu(5000);
-        lp.setTcpBufferSizes("1,2,3,4,5,6");
-        lp.setNat64Prefix(new IpPrefix(InetAddresses.parseNumericAddress("2001:db8::48"), 96));
+        mLinkProperties.setMtu(5000);
+        mLinkProperties.setTcpBufferSizes("1,2,3,4,5,6");
+        mLinkProperties.setNat64Prefix(
+                new IpPrefix(InetAddresses.parseNumericAddress("2001:db8::48"), 96));
 
         // Verify that this test does not miss any new field added later.
         // If any added field is not included in LinkProperties#equals, assertLinkPropertiesEquals
         // must also be updated.
         assertFieldCountEquals(14, LinkProperties.class);
-
-        return lp;
     }
 
     @Test
@@ -186,7 +177,7 @@
     private static void assertLinkPropertiesEquals(LinkProperties expected, LinkProperties actual) {
         assertEquals(expected, actual);
 
-        // LinkProperties equals() does not include stacked links
-        assertEquals(expected.getStackedLinks(), actual.getStackedLinks());
+        // Equality on stacked links is not tested as they should not be passed to processes using
+        // LinkPropertiesParcelable.
     }
 }
diff --git a/tests/net/java/android/net/util/ConnectivityPacketSummaryTest.java b/tests/net/java/android/net/util/ConnectivityPacketSummaryTest.java
index f9b7ec8..dfaf52a 100644
--- a/tests/net/java/android/net/util/ConnectivityPacketSummaryTest.java
+++ b/tests/net/java/android/net/util/ConnectivityPacketSummaryTest.java
@@ -16,19 +16,18 @@
 
 package android.net.util;
 
-import static android.net.util.NetworkConstants.*;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
 import android.net.MacAddress;
-import android.support.test.runner.AndroidJUnit4;
 import android.support.test.filters.SmallTest;
-
-import org.junit.runner.RunWith;
-import org.junit.Test;
+import android.support.test.runner.AndroidJUnit4;
 
 import libcore.util.HexEncoding;
 
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 /**
  * Tests for ConnectivityPacketSummary.
  *
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 882babf..1c26418 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -4775,7 +4775,7 @@
 
         // Clat iface up, expect stack link updated.
         clat.interfaceLinkStateChanged(CLAT_PREFIX + MOBILE_IFNAME, true);
-        waitForIdle();
+        networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
         List<LinkProperties> stackedLps = mCm.getLinkProperties(mCellNetworkAgent.getNetwork())
                 .getStackedLinks();
         assertEquals(makeClatLinkProperties(myIpv4), stackedLps.get(0));
@@ -4783,7 +4783,6 @@
         // Change trivial linkproperties and see if stacked link is preserved.
         cellLp.addDnsServer(InetAddress.getByName("8.8.8.8"));
         mCellNetworkAgent.sendLinkProperties(cellLp);
-        waitForIdle();
         networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
 
         List<LinkProperties> stackedLpsAfterChange =
@@ -4795,19 +4794,19 @@
         cellLp.addLinkAddress(myIpv4);
         cellLp.addRoute(new RouteInfo(myIpv4, null, MOBILE_IFNAME));
         mCellNetworkAgent.sendLinkProperties(cellLp);
-        waitForIdle();
         networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
         verify(mMockNetd, times(1)).clatdStop(MOBILE_IFNAME);
 
         // Clat iface removed, expect linkproperties revert to original one
         clat.interfaceRemoved(CLAT_PREFIX + MOBILE_IFNAME);
-        waitForIdle();
         networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
         LinkProperties actualLpAfterIpv4 = mCm.getLinkProperties(mCellNetworkAgent.getNetwork());
         assertEquals(cellLp, actualLpAfterIpv4);
 
         // Clean up
         mCellNetworkAgent.disconnect();
+        networkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
+        networkCallback.assertNoCallback();
         mCm.unregisterNetworkCallback(networkCallback);
     }
 
diff --git a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java b/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
index 8359fe2..1a0cb74 100644
--- a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
+++ b/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
@@ -18,14 +18,15 @@
 
 import static android.net.metrics.INetdEventListener.EVENT_GETADDRINFO;
 import static android.net.metrics.INetdEventListener.EVENT_GETHOSTBYNAME;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.net.ConnectivityManager;
@@ -34,12 +35,11 @@
 import android.net.IpPrefix;
 import android.net.LinkAddress;
 import android.net.LinkProperties;
-import android.net.RouteInfo;
 import android.net.Network;
 import android.net.NetworkCapabilities;
+import android.net.RouteInfo;
 import android.net.metrics.ApfProgramEvent;
 import android.net.metrics.ApfStats;
-import android.net.metrics.DefaultNetworkEvent;
 import android.net.metrics.DhcpClientEvent;
 import android.net.metrics.IpConnectivityLog;
 import android.net.metrics.IpManagerEvent;
@@ -55,6 +55,13 @@
 import com.android.internal.util.BitUtils;
 import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass;
 
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.util.Collections;
@@ -62,13 +69,6 @@
 import java.util.Iterator;
 import java.util.List;
 
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class IpConnectivityMetricsTest {
@@ -154,7 +154,7 @@
     @Test
     public void testRateLimiting() {
         final IpConnectivityLog logger = new IpConnectivityLog(mService.impl);
-        final ApfProgramEvent ev = new ApfProgramEvent();
+        final ApfProgramEvent ev = new ApfProgramEvent.Builder().build();
         final long fakeTimestamp = 1;
 
         int attempt = 100; // More than burst quota, but less than buffer size.
@@ -304,26 +304,31 @@
         when(mCm.getNetworkCapabilities(new Network(100))).thenReturn(ncWifi);
         when(mCm.getNetworkCapabilities(new Network(101))).thenReturn(ncCell);
 
-        ApfStats apfStats = new ApfStats();
-        apfStats.durationMs = 45000;
-        apfStats.receivedRas = 10;
-        apfStats.matchingRas = 2;
-        apfStats.droppedRas = 2;
-        apfStats.parseErrors = 2;
-        apfStats.zeroLifetimeRas = 1;
-        apfStats.programUpdates = 4;
-        apfStats.programUpdatesAll = 7;
-        apfStats.programUpdatesAllowingMulticast = 3;
-        apfStats.maxProgramSize = 2048;
+        ApfStats apfStats = new ApfStats.Builder()
+                .setDurationMs(45000)
+                .setReceivedRas(10)
+                .setMatchingRas(2)
+                .setDroppedRas(2)
+                .setParseErrors(2)
+                .setZeroLifetimeRas(1)
+                .setProgramUpdates(4)
+                .setProgramUpdatesAll(7)
+                .setProgramUpdatesAllowingMulticast(3)
+                .setMaxProgramSize(2048)
+                .build();
 
-        ValidationProbeEvent validationEv = new ValidationProbeEvent();
-        validationEv.durationMs = 40730;
-        validationEv.probeType = ValidationProbeEvent.PROBE_HTTP;
-        validationEv.returnCode = 204;
+        final ValidationProbeEvent validationEv = new ValidationProbeEvent.Builder()
+                .setDurationMs(40730)
+                .setProbeType(ValidationProbeEvent.PROBE_HTTP, true)
+                .setReturnCode(204)
+                .build();
 
+        final DhcpClientEvent event = new DhcpClientEvent.Builder()
+                .setMsg("SomeState")
+                .setDurationMs(192)
+                .build();
         Parcelable[] events = {
-            new IpReachabilityEvent(IpReachabilityEvent.NUD_FAILED),
-            new DhcpClientEvent("SomeState", 192),
+            new IpReachabilityEvent(IpReachabilityEvent.NUD_FAILED), event,
             new IpManagerEvent(IpManagerEvent.PROVISIONING_OK, 5678),
             validationEv,
             apfStats,
@@ -424,7 +429,7 @@
                 "  validation_probe_event <",
                 "    latency_ms: 40730",
                 "    probe_result: 204",
-                "    probe_type: 1",
+                "    probe_type: 257",
                 "  >",
                 ">",
                 "events <",
diff --git a/tools/apilint/apilint.py b/tools/apilint/apilint.py
index d1fe43e..75c3eba 100644
--- a/tools/apilint/apilint.py
+++ b/tools/apilint/apilint.py
@@ -297,6 +297,7 @@
 class V2LineParser(object):
     __slots__ = ["tokenized", "current", "len"]
 
+    FIELD_KINDS = ("field", "property", "enum_constant")
     MODIFIERS = set("public protected internal private abstract default static final transient volatile synchronized native operator sealed strictfp infix inline suspend vararg".split())
     JAVA_LANG_TYPES = set("AbstractMethodError AbstractStringBuilder Appendable ArithmeticException ArrayIndexOutOfBoundsException ArrayStoreException AssertionError AutoCloseable Boolean BootstrapMethodError Byte Character CharSequence Class ClassCastException ClassCircularityError ClassFormatError ClassLoader ClassNotFoundException Cloneable CloneNotSupportedException Comparable Compiler Deprecated Double Enum EnumConstantNotPresentException Error Exception ExceptionInInitializerError Float FunctionalInterface IllegalAccessError IllegalAccessException IllegalArgumentException IllegalMonitorStateException IllegalStateException IllegalThreadStateException IncompatibleClassChangeError IndexOutOfBoundsException InheritableThreadLocal InstantiationError InstantiationException Integer InternalError InterruptedException Iterable LinkageError Long Math NegativeArraySizeException NoClassDefFoundError NoSuchFieldError NoSuchFieldException NoSuchMethodError NoSuchMethodException NullPointerException Number NumberFormatException Object OutOfMemoryError Override Package package-info.java Process ProcessBuilder ProcessEnvironment ProcessImpl Readable ReflectiveOperationException Runnable Runtime RuntimeException RuntimePermission SafeVarargs SecurityException SecurityManager Short StackOverflowError StackTraceElement StrictMath String StringBuffer StringBuilder StringIndexOutOfBoundsException SuppressWarnings System Thread ThreadDeath ThreadGroup ThreadLocal Throwable TypeNotPresentException UNIXProcess UnknownError UnsatisfiedLinkError UnsupportedClassVersionError UnsupportedOperationException VerifyError VirtualMachineError Void".split())
 
@@ -355,7 +356,7 @@
         self.parse_eof()
 
     def parse_into_field(self, field):
-        kind = self.parse_one_of("field", "property")
+        kind = self.parse_one_of(*V2LineParser.FIELD_KINDS)
         field.split = [kind]
         annotations = self.parse_annotations()
         if "@Deprecated" in annotations:
@@ -591,6 +592,14 @@
     sig_format = 1
 
     re_blame = re.compile("^([a-z0-9]{7,}) \(<([^>]+)>.+?\) (.+?)$")
+
+    field_prefixes = map(lambda kind: "    %s" % (kind,), V2LineParser.FIELD_KINDS)
+    def startsWithFieldPrefix(raw):
+        for prefix in field_prefixes:
+            if raw.startswith(prefix):
+                return True
+        return False
+
     for raw in f:
         line += 1
         raw = raw.rstrip()
@@ -611,7 +620,7 @@
             clazz.ctors.append(Method(clazz, line, raw, blame, sig_format=sig_format))
         elif raw.startswith("    method"):
             clazz.methods.append(Method(clazz, line, raw, blame, sig_format=sig_format))
-        elif raw.startswith("    field") or raw.startswith("    property"):
+        elif startsWithFieldPrefix(raw):
             clazz.fields.append(Field(clazz, line, raw, blame, sig_format=sig_format))
         elif raw.startswith("  }") and clazz:
             yield clazz
diff --git a/tools/apilint/apilint_test.py b/tools/apilint/apilint_test.py
index fde61a9..9c261d5 100644
--- a/tools/apilint/apilint_test.py
+++ b/tools/apilint/apilint_test.py
@@ -143,6 +143,27 @@
                                       out_classes_with_base=classes_with_base)
         self.assertEquals(map(lambda x: x.fullname, classes_with_base), ["android.app.WallpaperColors"])
 
+class ParseV2Stream(unittest.TestCase):
+    def test_field_kinds(self):
+        api = apilint._parse_stream("""
+// Signature format: 2.0
+package android {
+  public enum SomeEnum {
+    enum_constant public static final android.SomeEnum ENUM_CONST;
+    field public static final int FIELD_CONST;
+    property public final int someProperty;
+    ctor public SomeEnum();
+    method public Object? getObject();
+  }
+}
+        """.strip().split('\n'))
+
+        self.assertEquals(api['android.SomeEnum'].fields[0].split[0], 'enum_constant')
+        self.assertEquals(api['android.SomeEnum'].fields[1].split[0], 'field')
+        self.assertEquals(api['android.SomeEnum'].fields[2].split[0], 'property')
+        self.assertEquals(api['android.SomeEnum'].ctors[0].split[0], 'ctor')
+        self.assertEquals(api['android.SomeEnum'].methods[0].split[0], 'method')
+
 class V2TokenizerTests(unittest.TestCase):
     def _test(self, raw, expected):
         self.assertEquals(apilint.V2Tokenizer(raw).tokenize(), expected)
@@ -211,6 +232,10 @@
         self.assertEquals('Interface', cls.implements)
         self.assertEquals('pkg.Some.Name', cls.fullname)
 
+    def test_enum(self):
+        cls = self._cls("public enum Some.Name {")
+        self._field("enum_constant public static final android.ValueType COLOR;")
+
     def test_interface(self):
         cls = self._cls("@Deprecated @IntRange(from=1, to=2) public interface Some.Name extends Interface<Class> {")
         self.assertTrue('deprecated' in cls.split)