Merge "Modify constructor of NetworkRegistrationState"
diff --git a/Android.bp b/Android.bp
index 41d5f28..cc9cfe9 100644
--- a/Android.bp
+++ b/Android.bp
@@ -290,7 +290,6 @@
         "core/java/android/service/euicc/IUpdateSubscriptionNicknameCallback.aidl",
         "core/java/android/service/gatekeeper/IGateKeeperService.aidl",
         "core/java/android/service/intelligence/IIntelligenceService.aidl",
-
         "core/java/android/service/notification/INotificationListener.aidl",
         "core/java/android/service/notification/IStatusBarNotificationHolder.aidl",
         "core/java/android/service/notification/IConditionListener.aidl",
@@ -573,6 +572,7 @@
         "telephony/java/com/android/internal/telephony/IApnSourceService.aidl",
         "telephony/java/com/android/internal/telephony/ICarrierConfigLoader.aidl",
         "telephony/java/com/android/internal/telephony/IMms.aidl",
+        "telephony/java/com/android/internal/telephony/INumberVerificationCallback.aidl",
         "telephony/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl",
         "telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl",
         "telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl",
@@ -782,9 +782,11 @@
 java_library_host {
     name: "inspector-annotation",
     srcs: [
-        "core/java/android/view/inspector/InspectableChildren.java",
         "core/java/android/view/inspector/InspectableNodeName.java",
         "core/java/android/view/inspector/InspectableProperty.java",
+        // Needed for the ResourceId.ID_NULL constant
+        "core/java/android/content/res/ResourceId.java",
+        "core/java/android/annotation/AnyRes.java",
     ],
 }
 
diff --git a/api/current.txt b/api/current.txt
index 079539e..83827ea 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -13728,6 +13728,7 @@
   public abstract class ColorSpace {
     method public static android.graphics.ColorSpace adapt(android.graphics.ColorSpace, float[]);
     method public static android.graphics.ColorSpace adapt(android.graphics.ColorSpace, float[], android.graphics.ColorSpace.Adaptation);
+    method public static float[] cctToIlluminantdXyz(int);
     method public static float[] chromaticAdaptation(android.graphics.ColorSpace.Adaptation, float[], float[]);
     method public static android.graphics.ColorSpace.Connector connect(android.graphics.ColorSpace, android.graphics.ColorSpace);
     method public static android.graphics.ColorSpace.Connector connect(android.graphics.ColorSpace, android.graphics.ColorSpace, android.graphics.ColorSpace.RenderIntent);
@@ -29062,7 +29063,7 @@
     method public static int compareSignalLevel(int, int);
     method public android.net.wifi.WifiManager.MulticastLock createMulticastLock(java.lang.String);
     method public android.net.wifi.WifiManager.WifiLock createWifiLock(int, java.lang.String);
-    method public android.net.wifi.WifiManager.WifiLock createWifiLock(java.lang.String);
+    method public deprecated android.net.wifi.WifiManager.WifiLock createWifiLock(java.lang.String);
     method public deprecated boolean disableNetwork(int);
     method public deprecated boolean disconnect();
     method public deprecated boolean enableNetwork(int, boolean);
@@ -29124,9 +29125,10 @@
     field public static final int STATUS_NETWORK_SUGGESTIONS_SUCCESS = 0; // 0x0
     field public static final deprecated java.lang.String SUPPLICANT_CONNECTION_CHANGE_ACTION = "android.net.wifi.supplicant.CONNECTION_CHANGE";
     field public static final deprecated java.lang.String SUPPLICANT_STATE_CHANGED_ACTION = "android.net.wifi.supplicant.STATE_CHANGE";
-    field public static final int WIFI_MODE_FULL = 1; // 0x1
+    field public static final deprecated int WIFI_MODE_FULL = 1; // 0x1
     field public static final int WIFI_MODE_FULL_HIGH_PERF = 3; // 0x3
-    field public static final int WIFI_MODE_SCAN_ONLY = 2; // 0x2
+    field public static final int WIFI_MODE_FULL_LOW_LATENCY = 4; // 0x4
+    field public static final deprecated int WIFI_MODE_SCAN_ONLY = 2; // 0x2
     field public static final java.lang.String WIFI_STATE_CHANGED_ACTION = "android.net.wifi.WIFI_STATE_CHANGED";
     field public static final int WIFI_STATE_DISABLED = 1; // 0x1
     field public static final int WIFI_STATE_DISABLING = 0; // 0x0
@@ -33537,6 +33539,7 @@
     method public static boolean isExternalStorageRemovable();
     method public static boolean isExternalStorageRemovable(java.io.File);
     field public static java.lang.String DIRECTORY_ALARMS;
+    field public static java.lang.String DIRECTORY_AUDIOBOOKS;
     field public static java.lang.String DIRECTORY_DCIM;
     field public static java.lang.String DIRECTORY_DOCUMENTS;
     field public static java.lang.String DIRECTORY_DOWNLOADS;
@@ -37296,6 +37299,7 @@
     method public static java.lang.String getVolumeName(android.net.Uri);
     method public static android.provider.MediaStore.PendingSession openPending(android.content.Context, android.net.Uri);
     method public static android.net.Uri setIncludePending(android.net.Uri);
+    method public static android.net.Uri setRequireOriginal(android.net.Uri);
     field public static final java.lang.String ACTION_IMAGE_CAPTURE = "android.media.action.IMAGE_CAPTURE";
     field public static final java.lang.String ACTION_IMAGE_CAPTURE_SECURE = "android.media.action.IMAGE_CAPTURE_SECURE";
     field public static final java.lang.String ACTION_REVIEW = "android.provider.action.REVIEW";
@@ -37393,6 +37397,7 @@
     field public static final java.lang.String COMPOSER = "composer";
     field public static final java.lang.String DURATION = "duration";
     field public static final java.lang.String IS_ALARM = "is_alarm";
+    field public static final java.lang.String IS_AUDIOBOOK = "is_audiobook";
     field public static final java.lang.String IS_MUSIC = "is_music";
     field public static final java.lang.String IS_NOTIFICATION = "is_notification";
     field public static final java.lang.String IS_PODCAST = "is_podcast";
@@ -42898,6 +42903,19 @@
     field public static final int BAND_9 = 9; // 0x9
   }
 
+  public final class AvailableNetworkInfo implements android.os.Parcelable {
+    ctor public AvailableNetworkInfo(int, int, java.util.ArrayList<java.lang.String>);
+    method public int describeContents();
+    method public java.util.List<java.lang.String> getMccMncs();
+    method public int getPriority();
+    method public int getSubId();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.telephony.AvailableNetworkInfo> CREATOR;
+    field public static final int PRIORITY_HIGH = 1; // 0x1
+    field public static final int PRIORITY_LOW = 3; // 0x3
+    field public static final int PRIORITY_MED = 2; // 0x2
+  }
+
   public class CarrierConfigManager {
     method public android.os.PersistableBundle getConfig();
     method public android.os.PersistableBundle getConfigForSubId(int);
@@ -43876,6 +43894,7 @@
     method public boolean setVoiceMailNumber(java.lang.String, java.lang.String);
     method public deprecated void setVoicemailRingtoneUri(android.telecom.PhoneAccountHandle, android.net.Uri);
     method public deprecated void setVoicemailVibrationEnabled(android.telecom.PhoneAccountHandle, boolean);
+    method public boolean updateAvailableNetworks(java.util.List<android.telephony.AvailableNetworkInfo>);
     field public static final java.lang.String ACTION_CONFIGURE_VOICEMAIL = "android.telephony.action.CONFIGURE_VOICEMAIL";
     field public static final java.lang.String ACTION_PHONE_STATE_CHANGED = "android.intent.action.PHONE_STATE";
     field public static final java.lang.String ACTION_RESPOND_VIA_MESSAGE = "android.intent.action.RESPOND_VIA_MESSAGE";
@@ -45847,6 +45866,7 @@
     method public deprecated java.lang.String getLocale();
     method public java.util.Locale getLocaleObject();
     method public int getSpanTypeId();
+    method public int getUnderlineColor();
     method public java.lang.String[] getSuggestions();
     method public void setFlags(int);
     method public void updateDrawState(android.text.TextPaint);
@@ -51963,10 +51983,90 @@
 
 }
 
+package android.view.inspector {
+
+  public abstract interface InspectionCompanion<T> {
+    method public default java.lang.String getNodeName();
+    method public abstract void mapProperties(android.view.inspector.PropertyMapper);
+    method public abstract void readProperties(T, android.view.inspector.PropertyReader);
+  }
+
+  public static class InspectionCompanion.UninitializedPropertyMapException extends java.lang.RuntimeException {
+    ctor public InspectionCompanion.UninitializedPropertyMapException();
+  }
+
+  public final class IntEnumMapping {
+    method public java.lang.String nameOf(int);
+  }
+
+  public static final class IntEnumMapping.Builder {
+    ctor public IntEnumMapping.Builder();
+    method public android.view.inspector.IntEnumMapping.Builder addValue(java.lang.String, int);
+    method public android.view.inspector.IntEnumMapping build();
+    method public void clear();
+  }
+
+  public final class IntFlagMapping {
+    method public java.lang.String[] namesOf(int);
+  }
+
+  public static final class IntFlagMapping.Builder {
+    ctor public IntFlagMapping.Builder();
+    method public android.view.inspector.IntFlagMapping.Builder addFlag(java.lang.String, int);
+    method public android.view.inspector.IntFlagMapping.Builder addFlag(java.lang.String, int, int);
+    method public android.view.inspector.IntFlagMapping build();
+    method public void clear();
+  }
+
+  public abstract interface PropertyMapper {
+    method public abstract int mapBoolean(java.lang.String, int);
+    method public abstract int mapByte(java.lang.String, int);
+    method public abstract int mapChar(java.lang.String, int);
+    method public abstract int mapColor(java.lang.String, int);
+    method public abstract int mapDouble(java.lang.String, int);
+    method public abstract int mapFloat(java.lang.String, int);
+    method public abstract int mapGravity(java.lang.String, int);
+    method public abstract int mapInt(java.lang.String, int);
+    method public abstract int mapIntEnum(java.lang.String, int, android.view.inspector.IntEnumMapping);
+    method public abstract int mapIntFlag(java.lang.String, int, android.view.inspector.IntFlagMapping);
+    method public abstract int mapLong(java.lang.String, int);
+    method public abstract int mapObject(java.lang.String, int);
+    method public abstract int mapShort(java.lang.String, int);
+  }
+
+  public static class PropertyMapper.PropertyConflictException extends java.lang.RuntimeException {
+    ctor public PropertyMapper.PropertyConflictException(java.lang.String, java.lang.String, java.lang.String);
+  }
+
+  public abstract interface PropertyReader {
+    method public abstract void readBoolean(int, boolean);
+    method public abstract void readByte(int, byte);
+    method public abstract void readChar(int, char);
+    method public abstract void readColor(int, int);
+    method public abstract void readColor(int, long);
+    method public abstract void readColor(int, android.graphics.Color);
+    method public abstract void readDouble(int, double);
+    method public abstract void readFloat(int, float);
+    method public abstract void readGravity(int, int);
+    method public abstract void readInt(int, int);
+    method public abstract void readIntEnum(int, int);
+    method public abstract void readIntFlag(int, int);
+    method public abstract void readLong(int, long);
+    method public abstract void readObject(int, java.lang.Object);
+    method public abstract void readShort(int, short);
+  }
+
+  public static class PropertyReader.PropertyTypeMismatchException extends java.lang.RuntimeException {
+    ctor public PropertyReader.PropertyTypeMismatchException(int, java.lang.String, java.lang.String, java.lang.String);
+    ctor public PropertyReader.PropertyTypeMismatchException(int, java.lang.String, java.lang.String);
+  }
+
+}
+
 package android.view.intelligence {
 
-  public final class IntelligenceManager {
-    method public android.content.ComponentName getIntelligenceServiceComponentName();
+  public final class ContentCaptureManager {
+    method public android.content.ComponentName getServiceComponentName();
     method public boolean isContentCaptureEnabled();
     method public android.view.ViewStructure newVirtualViewStructure(android.view.autofill.AutofillId, int);
     method public void notifyViewAppeared(android.view.ViewStructure);
diff --git a/api/system-current.txt b/api/system-current.txt
index 62d446f..6ee7afa 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -25,7 +25,6 @@
     field public static final java.lang.String BIND_DIRECTORY_SEARCH = "android.permission.BIND_DIRECTORY_SEARCH";
     field public static final java.lang.String BIND_EUICC_SERVICE = "android.permission.BIND_EUICC_SERVICE";
     field public static final java.lang.String BIND_IMS_SERVICE = "android.permission.BIND_IMS_SERVICE";
-    field public static final java.lang.String BIND_INTELLIGENCE_SERVICE = "android.permission.BIND_INTELLIGENCE_SERVICE";
     field public static final java.lang.String BIND_KEYGUARD_APPWIDGET = "android.permission.BIND_KEYGUARD_APPWIDGET";
     field public static final java.lang.String BIND_NETWORK_RECOMMENDATION_SERVICE = "android.permission.BIND_NETWORK_RECOMMENDATION_SERVICE";
     field public static final java.lang.String BIND_NOTIFICATION_ASSISTANT_SERVICE = "android.permission.BIND_NOTIFICATION_ASSISTANT_SERVICE";
@@ -34,6 +33,7 @@
     field public static final java.lang.String BIND_RESOLVER_RANKER_SERVICE = "android.permission.BIND_RESOLVER_RANKER_SERVICE";
     field public static final java.lang.String BIND_RUNTIME_PERMISSION_PRESENTER_SERVICE = "android.permission.BIND_RUNTIME_PERMISSION_PRESENTER_SERVICE";
     field public static final java.lang.String BIND_SETTINGS_SUGGESTIONS_SERVICE = "android.permission.BIND_SETTINGS_SUGGESTIONS_SERVICE";
+    field public static final java.lang.String BIND_SMART_SUGGESTIONS_SERVICE = "android.permission.BIND_SMART_SUGGESTIONS_SERVICE";
     field public static final java.lang.String BIND_SOUND_TRIGGER_DETECTION_SERVICE = "android.permission.BIND_SOUND_TRIGGER_DETECTION_SERVICE";
     field public static final java.lang.String BIND_TELEPHONY_DATA_SERVICE = "android.permission.BIND_TELEPHONY_DATA_SERVICE";
     field public static final java.lang.String BIND_TELEPHONY_NETWORK_SERVICE = "android.permission.BIND_TELEPHONY_NETWORK_SERVICE";
@@ -4980,6 +4980,13 @@
 
 package android.service.intelligence {
 
+  public final class ContentCaptureEventsRequest implements android.os.Parcelable {
+    method public int describeContents();
+    method public java.util.List<android.view.intelligence.ContentCaptureEvent> getEvents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.service.intelligence.ContentCaptureEventsRequest> CREATOR;
+  }
+
   public final class FillCallback {
     method public void onSuccess(android.service.intelligence.FillResponse);
   }
@@ -5014,16 +5021,6 @@
     field public static final long FLAG_METADATA_ADDRESS = 1L; // 0x1L
   }
 
-  public abstract class IntelligenceService extends android.app.Service {
-    ctor public IntelligenceService();
-    method public void onActivitySnapshot(android.service.intelligence.InteractionSessionId, android.service.intelligence.SnapshotData);
-    method public abstract void onContentCaptureEvent(android.service.intelligence.InteractionSessionId, java.util.List<android.view.intelligence.ContentCaptureEvent>);
-    method public void onCreateInteractionSession(android.service.intelligence.InteractionContext, android.service.intelligence.InteractionSessionId);
-    method public void onDestroyInteractionSession(android.service.intelligence.InteractionSessionId);
-    method public void onFillRequest(android.service.intelligence.InteractionSessionId, android.service.intelligence.FillRequest, android.os.CancellationSignal, android.service.intelligence.FillController, android.service.intelligence.FillCallback);
-    field public static final java.lang.String SERVICE_INTERFACE = "android.service.intelligence.IntelligenceService";
-  }
-
   public final class InteractionContext implements android.os.Parcelable {
     method public int describeContents();
     method public android.content.ComponentName getActivityComponent();
@@ -5059,6 +5056,21 @@
     method public android.service.intelligence.PresentationParams.Area getSubArea(android.graphics.Rect);
   }
 
+  public abstract class SmartSuggestionsService extends android.app.Service {
+    ctor public SmartSuggestionsService();
+    method public final java.util.Set<android.content.ComponentName> getContentCaptureDisabledActivities();
+    method public final java.util.Set<java.lang.String> getContentCaptureDisabledPackages();
+    method public void onActivitySnapshot(android.service.intelligence.InteractionSessionId, android.service.intelligence.SnapshotData);
+    method public abstract void onContentCaptureEventsRequest(android.service.intelligence.InteractionSessionId, android.service.intelligence.ContentCaptureEventsRequest);
+    method public void onCreateInteractionSession(android.service.intelligence.InteractionContext, android.service.intelligence.InteractionSessionId);
+    method public void onDestroyInteractionSession(android.service.intelligence.InteractionSessionId);
+    method public void onFillRequest(android.service.intelligence.InteractionSessionId, android.service.intelligence.FillRequest, android.os.CancellationSignal, android.service.intelligence.FillController, android.service.intelligence.FillCallback);
+    method public final void setActivityContentCaptureEnabled(android.content.ComponentName, boolean);
+    method public final void setContentCaptureWhitelist(java.util.List<java.lang.String>, java.util.List<android.content.ComponentName>);
+    method public final void setPackageContentCaptureEnabled(java.lang.String, boolean);
+    field public static final java.lang.String SERVICE_INTERFACE = "android.service.intelligence.SmartSuggestionsService";
+  }
+
   public final class SnapshotData implements android.os.Parcelable {
     method public int describeContents();
     method public android.app.assist.AssistContent getAssistContent();
@@ -5699,6 +5711,26 @@
     field public static final int RESULT_SUCCESS = 0; // 0x0
   }
 
+  public abstract interface NumberVerificationCallback {
+    method public default void onCallReceived(java.lang.String);
+    method public default void onVerificationFailed(int);
+    field public static final int REASON_CONCURRENT_REQUESTS = 4; // 0x4
+    field public static final int REASON_IN_ECBM = 5; // 0x5
+    field public static final int REASON_IN_EMERGENCY_CALL = 6; // 0x6
+    field public static final int REASON_NETWORK_NOT_AVAILABLE = 2; // 0x2
+    field public static final int REASON_TIMED_OUT = 1; // 0x1
+    field public static final int REASON_TOO_MANY_CALLS = 3; // 0x3
+    field public static final int REASON_UNSPECIFIED = 0; // 0x0
+  }
+
+  public final class PhoneNumberRange implements android.os.Parcelable {
+    ctor public PhoneNumberRange(java.lang.String, java.lang.String, java.lang.String, java.lang.String);
+    method public int describeContents();
+    method public boolean matches(java.lang.String);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.telephony.PhoneNumberRange> CREATOR;
+  }
+
   public class PhoneStateListener {
     method public void onRadioPowerStateChanged(int);
     method public void onSrvccStateChanged(int);
@@ -5863,6 +5895,7 @@
     method public boolean needsOtaServiceProvisioning();
     method public boolean rebootRadio();
     method public void requestCellInfoUpdate(android.os.WorkSource, java.util.concurrent.Executor, android.telephony.TelephonyManager.CellInfoCallback);
+    method public void requestNumberVerification(android.telephony.PhoneNumberRange, long, java.util.concurrent.Executor, android.telephony.NumberVerificationCallback);
     method public boolean resetRadioConfig();
     method public int setAllowedCarriers(int, java.util.List<android.service.carrier.CarrierIdentifier>);
     method public void setCarrierDataEnabled(boolean);
@@ -5892,6 +5925,7 @@
     field public static final java.lang.String EXTRA_SIM_STATE = "android.telephony.extra.SIM_STATE";
     field public static final java.lang.String EXTRA_VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL = "android.telephony.extra.VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL";
     field public static final java.lang.String EXTRA_VOICEMAIL_SCRAMBLED_PIN_STRING = "android.telephony.extra.VOICEMAIL_SCRAMBLED_PIN_STRING";
+    field public static final long MAX_NUMBER_VERIFICATION_TIMEOUT_MILLIS = 60000L; // 0xea60L
     field public static final int NETWORK_MODE_CDMA_EVDO = 4; // 0x4
     field public static final int NETWORK_MODE_CDMA_NO_EVDO = 5; // 0x5
     field public static final int NETWORK_MODE_EVDO_NO_CDMA = 6; // 0x6
@@ -7243,14 +7277,6 @@
     field public static final int TYPE_VIEW_TEXT_CHANGED = 7; // 0x7
   }
 
-  public final class IntelligenceManager {
-    method public java.util.Set<android.content.ComponentName> getContentCaptureDisabledActivities();
-    method public java.util.Set<java.lang.String> getContentCaptureDisabledPackages();
-    method public void setActivityContentCaptureEnabled(android.content.ComponentName, boolean);
-    method public void setContentCaptureWhitelist(java.util.List<java.lang.String>, java.util.List<android.content.ComponentName>);
-    method public void setPackageContentCaptureEnabled(java.lang.String, boolean);
-  }
-
   public final class ViewNode extends android.app.assist.AssistStructure.ViewNode {
     method public android.view.autofill.AutofillId getParentAutofillId();
   }
diff --git a/cmds/content/src/com/android/commands/content/Content.java b/cmds/content/src/com/android/commands/content/Content.java
index 1597c8c..52a2ab4 100644
--- a/cmds/content/src/com/android/commands/content/Content.java
+++ b/cmds/content/src/com/android/commands/content/Content.java
@@ -77,7 +77,7 @@
                     + "  <BINDING> binds a typed value to a column and is formatted:\n"
                     + "  <COLUMN_NAME>:<TYPE>:<COLUMN_VALUE> where:\n"
                     + "  <TYPE> specifies data type such as:\n"
-                    + "  b - boolean, s - string, i - integer, l - long, f - float, d - double\n"
+                    + "  b - boolean, s - string, i - integer, l - long, f - float, d - double, n - null\n"
                     + "  Note: Omit the value for passing an empty string, e.g column:s:\n"
                     + "  Example:\n"
                     + "  # Add \"new_setting\" secure setting with value \"new_value\".\n"
@@ -153,6 +153,7 @@
         private static final String TYPE_LONG = "l";
         private static final String TYPE_FLOAT = "f";
         private static final String TYPE_DOUBLE = "d";
+        private static final String TYPE_NULL = "n";
         private static final String COLON = ":";
         private static final String ARGUMENT_PREFIX = "--";
 
@@ -410,6 +411,8 @@
                 values.put(column, Long.parseLong(value));
             } else if (TYPE_FLOAT.equalsIgnoreCase(type) || TYPE_DOUBLE.equalsIgnoreCase(type)) {
                 values.put(column, Double.parseDouble(value));
+            } else if (TYPE_NULL.equalsIgnoreCase(type)) {
+                values.putNull(column);
             } else {
                 throw new IllegalArgumentException("Unsupported type: " + type);
             }
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 05bb9a1..f3f065a 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -122,7 +122,7 @@
 import android.view.autofill.AutofillPopupWindow;
 import android.view.autofill.IAutofillWindowPresenter;
 import android.view.intelligence.ContentCaptureEvent;
-import android.view.intelligence.IntelligenceManager;
+import android.view.intelligence.ContentCaptureManager;
 import android.widget.AdapterView;
 import android.widget.Toast;
 import android.widget.Toolbar;
@@ -824,8 +824,8 @@
     /** The autofill manager. Always access via {@link #getAutofillManager()}. */
     @Nullable private AutofillManager mAutofillManager;
 
-    /** The screen observation manager. Always access via {@link #getIntelligenceManager()}. */
-    @Nullable private IntelligenceManager mIntelligenceManager;
+    /** The content capture manager. Always access via {@link #getContentCaptureManager()}. */
+    @Nullable private ContentCaptureManager mContentCaptureManager;
 
     private final ArrayList<Application.ActivityLifecycleCallbacks> mActivityLifecycleCallbacks =
             new ArrayList<Application.ActivityLifecycleCallbacks>();
@@ -1016,39 +1016,39 @@
     }
 
     /**
-     * (Creates, sets, and ) returns the intelligence manager
+     * (Creates, sets, and ) returns the content capture manager
      *
-     * @return The intelligence manager
+     * @return The content capture manager
      */
-    @NonNull private IntelligenceManager getIntelligenceManager() {
-        if (mIntelligenceManager == null) {
-            mIntelligenceManager = getSystemService(IntelligenceManager.class);
+    @NonNull private ContentCaptureManager getContentCaptureManager() {
+        if (mContentCaptureManager == null) {
+            mContentCaptureManager = getSystemService(ContentCaptureManager.class);
         }
-        return mIntelligenceManager;
+        return mContentCaptureManager;
     }
 
-    private void notifyIntelligenceManagerIfNeeded(@ContentCaptureEvent.EventType int event) {
-        final IntelligenceManager im = getIntelligenceManager();
-        if (im == null || !im.isContentCaptureEnabled()) {
+    private void notifyContentCaptureManagerIfNeeded(@ContentCaptureEvent.EventType int event) {
+        final ContentCaptureManager cm = getContentCaptureManager();
+        if (cm == null || !cm.isContentCaptureEnabled()) {
             return;
         }
         switch (event) {
             case ContentCaptureEvent.TYPE_ACTIVITY_CREATED:
                 //TODO(b/111276913): decide whether the InteractionSessionId should be
                 // saved / restored in the activity bundle.
-                im.onActivityCreated(mToken, getComponentName());
+                cm.onActivityCreated(mToken, getComponentName());
                 break;
             case ContentCaptureEvent.TYPE_ACTIVITY_DESTROYED:
-                im.onActivityDestroyed();
+                cm.onActivityDestroyed();
                 break;
             case ContentCaptureEvent.TYPE_ACTIVITY_STARTED:
             case ContentCaptureEvent.TYPE_ACTIVITY_RESUMED:
             case ContentCaptureEvent.TYPE_ACTIVITY_PAUSED:
             case ContentCaptureEvent.TYPE_ACTIVITY_STOPPED:
-                im.onActivityLifecycleEvent(event);
+                cm.onActivityLifecycleEvent(event);
                 break;
             default:
-                Log.w(TAG, "notifyIntelligenceManagerIfNeeded(): invalid type " + event);
+                Log.w(TAG, "notifyContentCaptureManagerIfNeeded(): invalid type " + event);
         }
     }
 
@@ -1057,6 +1057,7 @@
         super.attachBaseContext(newBase);
         if (newBase != null) {
             newBase.setAutofillClient(this);
+            newBase.setContentCaptureSupported(true);
         }
     }
 
@@ -1066,6 +1067,12 @@
         return this;
     }
 
+    /** @hide */
+    @Override
+    public boolean isContentCaptureSupported() {
+        return true;
+    }
+
     /**
      * Register an {@link Application.ActivityLifecycleCallbacks} instance that receives
      * lifecycle callbacks for only this Activity.
@@ -1410,7 +1417,7 @@
         mRestoredFromBundle = savedInstanceState != null;
         mCalled = true;
 
-        notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_CREATED);
+        notifyContentCaptureManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_CREATED);
     }
 
     /**
@@ -1644,7 +1651,7 @@
         if (mAutoFillResetNeeded) {
             getAutofillManager().onVisibleForAutofill();
         }
-        notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_STARTED);
+        notifyContentCaptureManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_STARTED);
     }
 
     /**
@@ -1735,7 +1742,7 @@
                 }
             }
         }
-        notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_RESUMED);
+        notifyContentCaptureManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_RESUMED);
         mCalled = true;
     }
 
@@ -2129,7 +2136,7 @@
                 mAutoFillIgnoreFirstResumePause = false;
             }
         }
-        notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_PAUSED);
+        notifyContentCaptureManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_PAUSED);
         mCalled = true;
     }
 
@@ -2318,7 +2325,7 @@
                 getAutofillManager().onPendingSaveUi(AutofillManager.PENDING_UI_OPERATION_CANCEL,
                         mIntent.getIBinderExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN));
             }
-            notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_STOPPED);
+            notifyContentCaptureManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_STOPPED);
         }
     }
 
@@ -2390,7 +2397,7 @@
 
         dispatchActivityDestroyed();
 
-        notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_DESTROYED);
+        notifyContentCaptureManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_DESTROYED);
 
     }
 
@@ -6806,7 +6813,7 @@
     }
 
     void dumpIntelligenceManager(String prefix, PrintWriter writer) {
-        final IntelligenceManager im = getIntelligenceManager();
+        final ContentCaptureManager im = getContentCaptureManager();
         if (im != null) {
             im.dump(prefix, writer);
         } else {
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java
index 446d98e..2c435a2 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -31,7 +31,6 @@
 import android.util.Log;
 import android.view.IWindowManager;
 import android.view.InputDevice;
-import android.view.InputEvent;
 import android.view.MotionEvent;
 import android.view.Surface;
 import android.view.SurfaceControl;
@@ -291,9 +290,14 @@
         return super.onGenericMotionEvent(event);
     }
 
-    private boolean injectInputEvent(InputEvent event) {
+    private boolean injectInputEvent(MotionEvent event) {
         if (mInputForwarder != null) {
             try {
+                // The touch event that the ActivityView gets is in View space, but the event needs
+                // to get forwarded in screen space. This offsets the touch event by the location
+                // the ActivityView is on screen and sends it to the input forwarder.
+                getLocationOnScreen(mLocationOnScreen);
+                event.offsetLocation(mLocationOnScreen[0], mLocationOnScreen[1]);
                 return mInputForwarder.forwardEvent(event);
             } catch (RemoteException e) {
                 e.rethrowAsRuntimeException();
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 28ecb27..6f0b6c8 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -217,6 +217,8 @@
     private AutofillClient mAutofillClient = null;
     private boolean mIsAutofillCompatEnabled;
 
+    private boolean mIsContentCaptureSupported = false;
+
     private final Object mSync = new Object();
 
     @GuardedBy("mSync")
@@ -2376,6 +2378,18 @@
         mIsAutofillCompatEnabled = autofillCompatEnabled;
     }
 
+    /** @hide */
+    @Override
+    public boolean isContentCaptureSupported() {
+        return mIsContentCaptureSupported;
+    }
+
+    /** @hide */
+    @Override
+    public void setContentCaptureSupported(boolean supported) {
+        mIsContentCaptureSupported = supported;
+    }
+
     @UnsupportedAppUsage
     static ContextImpl createSystemContext(ActivityThread mainThread) {
         LoadedApk packageInfo = new LoadedApk(mainThread);
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index e83bcd0..88fb025 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -96,6 +96,7 @@
             String callingPackage);
     void unregisterUidObserver(in IUidObserver observer);
     boolean isUidActive(int uid, String callingPackage);
+    int getUidProcessState(int uid, in String callingPackage);
     // =============== End of transactions used on native side as well ============================
 
     // Special low-level communication with activity manager.
@@ -379,8 +380,6 @@
     void noteAlarmFinish(in IIntentSender sender, in WorkSource workSource, int sourceUid, in String tag);
     int getPackageProcessState(in String packageName, in String callingPackage);
     void updateDeviceOwner(in String packageName);
-    int getUidProcessState(int uid, in String callingPackage);
-
 
     // Start of N transactions
     // Start Binder transaction tracking for all applications.
diff --git a/core/java/android/app/IUidObserver.aidl b/core/java/android/app/IUidObserver.aidl
index ce88809..e116d98 100644
--- a/core/java/android/app/IUidObserver.aidl
+++ b/core/java/android/app/IUidObserver.aidl
@@ -43,8 +43,6 @@
      */
     void onUidIdle(int uid, boolean disabled);
 
-    // =============== End of transactions used on native side as well ============================
-
     /**
      * General report of a state change of an uid.
      *
@@ -55,6 +53,8 @@
      */
     void onUidStateChanged(int uid, int procState, long procStateSeq);
 
+    // =============== End of transactions used on native side as well ============================
+
     /**
      * Report when the cached state of a uid has changed.
      * If true, a uid has become cached -- that is, it has some active processes that are
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 89ec19b..25fa897 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -1424,7 +1424,62 @@
             return other.priorityCategories == priorityCategories
                     && other.priorityCallSenders == priorityCallSenders
                     && other.priorityMessageSenders == priorityMessageSenders
-                    && other.suppressedVisualEffects == suppressedVisualEffects;
+                    && suppressedVisualEffectsEqual(suppressedVisualEffects,
+                    other.suppressedVisualEffects);
+        }
+
+
+        private boolean suppressedVisualEffectsEqual(int suppressedEffects,
+                int otherSuppressedVisualEffects) {
+            if (suppressedEffects == otherSuppressedVisualEffects) {
+                return true;
+            }
+
+            if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_ON) != 0) {
+                suppressedEffects |= SUPPRESSED_EFFECT_PEEK;
+            }
+            if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_OFF) != 0) {
+                suppressedEffects |= SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
+                suppressedEffects |= SUPPRESSED_EFFECT_LIGHTS;
+                suppressedEffects |= SUPPRESSED_EFFECT_AMBIENT;
+            }
+
+            if ((otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_ON) != 0) {
+                otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_PEEK;
+            }
+            if ((otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_OFF) != 0) {
+                otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
+                otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_LIGHTS;
+                otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_AMBIENT;
+            }
+
+            if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_ON)
+                    != (otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_ON)) {
+                int currSuppressedEffects = (suppressedEffects & SUPPRESSED_EFFECT_SCREEN_ON) != 0
+                        ? otherSuppressedVisualEffects : suppressedEffects;
+                if ((currSuppressedEffects & SUPPRESSED_EFFECT_PEEK) == 0) {
+                    return false;
+                }
+            }
+
+            if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_OFF)
+                    != (otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_OFF)) {
+                int currSuppressedEffects = (suppressedEffects & SUPPRESSED_EFFECT_SCREEN_OFF) != 0
+                        ? otherSuppressedVisualEffects : suppressedEffects;
+                if ((currSuppressedEffects & SUPPRESSED_EFFECT_FULL_SCREEN_INTENT) == 0
+                        || (currSuppressedEffects & SUPPRESSED_EFFECT_LIGHTS) == 0
+                        || (currSuppressedEffects & SUPPRESSED_EFFECT_AMBIENT) == 0) {
+                    return false;
+                }
+            }
+
+            int thisWithoutOldEffects = suppressedEffects
+                    & ~SUPPRESSED_EFFECT_SCREEN_ON
+                    & ~SUPPRESSED_EFFECT_SCREEN_OFF;
+            int otherWithoutOldEffects = otherSuppressedVisualEffects
+                    & ~SUPPRESSED_EFFECT_SCREEN_ON
+                    & ~SUPPRESSED_EFFECT_SCREEN_OFF;
+            return thisWithoutOldEffects == otherWithoutOldEffects;
         }
 
         @Override
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 0123551..dfe371c 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -165,8 +165,8 @@
 import android.view.autofill.AutofillManager;
 import android.view.autofill.IAutoFillManager;
 import android.view.inputmethod.InputMethodManager;
+import android.view.intelligence.ContentCaptureManager;
 import android.view.intelligence.IIntelligenceManager;
-import android.view.intelligence.IntelligenceManager;
 import android.view.textclassifier.TextClassificationManager;
 import android.view.textservice.TextServicesManager;
 
@@ -199,6 +199,7 @@
     private SystemServiceRegistry() { }
 
     static {
+        //CHECKSTYLE:OFF IndentationCheck
         registerService(Context.ACCESSIBILITY_SERVICE, AccessibilityManager.class,
                 new CachedServiceFetcher<AccessibilityManager>() {
             @Override
@@ -1050,15 +1051,20 @@
                 return new AutofillManager(ctx.getOuterContext(), service);
             }});
 
-        registerService(Context.INTELLIGENCE_MANAGER_SERVICE, IntelligenceManager.class,
-                new CachedServiceFetcher<IntelligenceManager>() {
+        registerService(Context.CONTENT_CAPTURE_MANAGER_SERVICE, ContentCaptureManager.class,
+                new CachedServiceFetcher<ContentCaptureManager>() {
             @Override
-            public IntelligenceManager createService(ContextImpl ctx)
+            public ContentCaptureManager createService(ContextImpl ctx)
                     throws ServiceNotFoundException {
                 // Get the services without throwing as this is an optional feature
-                IBinder b = ServiceManager.getService(Context.INTELLIGENCE_MANAGER_SERVICE);
-                IIntelligenceManager service = IIntelligenceManager.Stub.asInterface(b);
-                return new IntelligenceManager(ctx.getOuterContext(), service);
+                Context outerContext = ctx.getOuterContext();
+                if (outerContext.isContentCaptureSupported()) {
+                    IBinder b = ServiceManager
+                            .getService(Context.CONTENT_CAPTURE_MANAGER_SERVICE);
+                    IIntelligenceManager service = IIntelligenceManager.Stub.asInterface(b);
+                    return new ContentCaptureManager(outerContext, service);
+                }
+                return null;
             }});
 
         registerService(Context.VR_SERVICE, VrManager.class, new CachedServiceFetcher<VrManager>() {
@@ -1138,6 +1144,7 @@
                             throws ServiceNotFoundException {
                         return new RoleManager(ctx.getOuterContext());
                     }});
+        //CHECKSTYLE:ON IndentationCheck
     }
 
     /**
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index ff57b03..68aac64 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3933,12 +3933,13 @@
     public static final String AUTOFILL_MANAGER_SERVICE = "autofill";
 
     /**
-     * Official published name of the intelligence service.
+     * Official published name of the smart suggestions service.
      *
      * @hide
      * @see #getSystemService(String)
      */
-    public static final String INTELLIGENCE_MANAGER_SERVICE = "intelligence";
+    // TODO(b/111276913): rename string (will require SELinux change first)
+    public static final String CONTENT_CAPTURE_MANAGER_SERVICE = "intelligence";
 
     /**
      * Use with {@link #getSystemService(String)} to access the
@@ -5223,6 +5224,25 @@
     }
 
     /**
+     * Checks whether this context supports content capture.
+     *
+     * @hide
+     */
+    // NOTE: for now we just need to check if it's supported so we can optimize calls that can be
+    // skipped when it isn't. Eventually, we might need a full
+    // ContentCaptureManager.ContentCaptureClient interface (as it's done with AutofillClient).
+    //
+    public boolean isContentCaptureSupported() {
+        return false;
+    }
+
+    /**
+     * @hide
+     */
+    public void setContentCaptureSupported(@SuppressWarnings("unused") boolean supported) {
+    }
+
+    /**
      * Throws an exception if the Context is using system resources,
      * which are non-runtime-overlay-themable and may show inconsistent UI.
      * @hide
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index 2db44b4..26ed3b7 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -1049,4 +1049,20 @@
             mBase.setAutofillCompatibilityEnabled(autofillCompatEnabled);
         }
     }
+
+    /**
+     * @hide
+     */
+    @Override
+    public boolean isContentCaptureSupported() {
+        return mBase.isContentCaptureSupported();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void setContentCaptureSupported(boolean supported) {
+        mBase.setContentCaptureSupported(supported);
+    }
 }
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 7c3b5e4..98a135f 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -1770,7 +1770,7 @@
      * is on the package whitelist.
      *
      * @param policy configured policy for this app, or {@link #HIDDEN_API_ENFORCEMENT_DEFAULT}
-     *               if nothing configured.
+     *        if nothing configured.
      * @hide
      */
     public void maybeUpdateHiddenApiEnforcementPolicy(@HiddenApiEnforcementPolicy int policy) {
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 0c1aae8..8904ee6 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -657,6 +657,12 @@
     public static String DIRECTORY_SCREENSHOTS = "Screenshots";
 
     /**
+     * Standard directory in which to place any audio files which are
+     * audiobooks.
+     */
+    public static String DIRECTORY_AUDIOBOOKS = "Audiobooks";
+
+    /**
      * List of standard storage directories.
      * <p>
      * Each of its values have its own constant:
@@ -671,6 +677,7 @@
      *   <li>{@link #DIRECTORY_DOWNLOADS}
      *   <li>{@link #DIRECTORY_DCIM}
      *   <li>{@link #DIRECTORY_DOCUMENTS}
+     *   <li>{@link #DIRECTORY_AUDIOBOOKS}
      * </ul>
      * @hide
      */
@@ -684,7 +691,8 @@
             DIRECTORY_MOVIES,
             DIRECTORY_DOWNLOADS,
             DIRECTORY_DCIM,
-            DIRECTORY_DOCUMENTS
+            DIRECTORY_DOCUMENTS,
+            DIRECTORY_AUDIOBOOKS,
     };
 
     /**
@@ -709,6 +717,7 @@
     /** {@hide} */ public static final int HAS_DOWNLOADS = 1 << 7;
     /** {@hide} */ public static final int HAS_DCIM = 1 << 8;
     /** {@hide} */ public static final int HAS_DOCUMENTS = 1 << 9;
+    /** {@hide} */ public static final int HAS_AUDIOBOOKS = 1 << 10;
 
     /** {@hide} */ public static final int HAS_ANDROID = 1 << 16;
     /** {@hide} */ public static final int HAS_OTHER = 1 << 17;
@@ -738,6 +747,7 @@
                 else if (DIRECTORY_DOWNLOADS.equals(name)) res |= HAS_DOWNLOADS;
                 else if (DIRECTORY_DCIM.equals(name)) res |= HAS_DCIM;
                 else if (DIRECTORY_DOCUMENTS.equals(name)) res |= HAS_DOCUMENTS;
+                else if (DIRECTORY_AUDIOBOOKS.equals(name)) res |= HAS_AUDIOBOOKS;
                 else if (DIRECTORY_ANDROID.equals(name)) res |= HAS_ANDROID;
                 else res |= HAS_OTHER;
             }
diff --git a/core/java/android/os/IThermalService.aidl b/core/java/android/os/IThermalService.aidl
index 8160338..9280cb9 100644
--- a/core/java/android/os/IThermalService.aidl
+++ b/core/java/android/os/IThermalService.aidl
@@ -67,7 +67,7 @@
 
     /**
       * Register a listener for thermal status change.
-      * @param listener the IThermalStatusListener to be notified.
+      * @param listener the {@link android.os.IThermalStatusListener} to be notified.
       * @return true if registered successfully.
       * {@hide}
       */
@@ -75,7 +75,7 @@
 
     /**
       * Unregister a previously-registered listener for thermal status.
-      * @param listener the IThermalStatusListener to no longer be notified.
+      * @param listener the {@link android.os.IThermalStatusListener} to no longer be notified.
       * @return true if unregistered successfully.
       * {@hide}
       */
@@ -86,5 +86,5 @@
       * @return status defined in {@link android.os.Temperature}.
       * {@hide}
       */
-    int getCurrentStatus();
+    int getCurrentThermalStatus();
 }
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java
index 44b9e311..6de1ff4 100644
--- a/core/java/android/os/ParcelFileDescriptor.java
+++ b/core/java/android/os/ParcelFileDescriptor.java
@@ -17,12 +17,6 @@
 package android.os;
 
 import static android.system.OsConstants.AF_UNIX;
-import static android.system.OsConstants.O_APPEND;
-import static android.system.OsConstants.O_CREAT;
-import static android.system.OsConstants.O_RDONLY;
-import static android.system.OsConstants.O_RDWR;
-import static android.system.OsConstants.O_TRUNC;
-import static android.system.OsConstants.O_WRONLY;
 import static android.system.OsConstants.SEEK_SET;
 import static android.system.OsConstants.SOCK_SEQPACKET;
 import static android.system.OsConstants.SOCK_STREAM;
@@ -254,8 +248,16 @@
     }
 
     /** {@hide} */
-    public static ParcelFileDescriptor fromFd(
-            FileDescriptor fd, Handler handler, final OnCloseListener listener) throws IOException {
+    public static ParcelFileDescriptor fromPfd(ParcelFileDescriptor pfd, Handler handler,
+            final OnCloseListener listener) throws IOException {
+        final FileDescriptor original = new FileDescriptor();
+        original.setInt$(pfd.detachFd());
+        return fromFd(original, handler, listener);
+    }
+
+    /** {@hide} */
+    public static ParcelFileDescriptor fromFd(FileDescriptor fd, Handler handler,
+            final OnCloseListener listener) throws IOException {
         if (handler == null) {
             throw new IllegalArgumentException("Handler must not be null");
         }
diff --git a/core/java/android/os/RedactingFileDescriptor.java b/core/java/android/os/RedactingFileDescriptor.java
index 60eb5c3..4e5eaac 100644
--- a/core/java/android/os/RedactingFileDescriptor.java
+++ b/core/java/android/os/RedactingFileDescriptor.java
@@ -20,15 +20,18 @@
 import android.os.storage.StorageManager;
 import android.system.ErrnoException;
 import android.system.Os;
-import android.system.OsConstants;
 import android.util.Slog;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 import libcore.io.IoUtils;
+import libcore.util.EmptyArray;
 
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.InterruptedIOException;
+import java.util.Arrays;
 
 /**
  * Variant of {@link FileDescriptor} that allows its creator to specify regions
@@ -40,20 +43,21 @@
     private static final String TAG = "RedactingFileDescriptor";
     private static final boolean DEBUG = true;
 
-    private final long[] mRedactRanges;
+    private volatile long[] mRedactRanges;
 
     private FileDescriptor mInner = null;
     private ParcelFileDescriptor mOuter = null;
 
-    private RedactingFileDescriptor(Context context, File file, long[] redactRanges)
+    private RedactingFileDescriptor(Context context, File file, int mode, long[] redactRanges)
             throws IOException {
         mRedactRanges = checkRangesArgument(redactRanges);
 
         try {
             try {
-                mInner = Os.open(file.getAbsolutePath(), OsConstants.O_RDONLY, 0);
+                mInner = Os.open(file.getAbsolutePath(),
+                        FileUtils.translateModePfdToPosix(mode), 0);
                 mOuter = context.getSystemService(StorageManager.class)
-                        .openProxyFileDescriptor(ParcelFileDescriptor.MODE_READ_ONLY, mCallback);
+                        .openProxyFileDescriptor(mode, mCallback);
             } catch (ErrnoException e) {
                 throw e.rethrowAsIOException();
             }
@@ -78,16 +82,61 @@
 
     /**
      * Open the given {@link File} and returns a {@link ParcelFileDescriptor}
-     * that offers a redacted, read-only view of the underlying data.
+     * that offers a redacted view of the underlying data. If a redacted region
+     * is written to, the newly written data can be read back correctly instead
+     * of continuing to be redacted.
      *
      * @param file The underlying file to open.
+     * @param mode The {@link ParcelFileDescriptor} mode to open with.
      * @param redactRanges List of file offsets that should be redacted, stored
      *            as {@code [start1, end1, start2, end2, ...]}. Start values are
      *            inclusive and end values are exclusive.
      */
-    public static ParcelFileDescriptor open(Context context, File file, long[] redactRanges)
-            throws IOException {
-        return new RedactingFileDescriptor(context, file, redactRanges).mOuter;
+    public static ParcelFileDescriptor open(Context context, File file, int mode,
+            long[] redactRanges) throws IOException {
+        return new RedactingFileDescriptor(context, file, mode, redactRanges).mOuter;
+    }
+
+    /**
+     * Update the given ranges argument to remove any references to the given
+     * offset and length. This is typically used when a caller has written over
+     * a previously redacted region.
+     */
+    @VisibleForTesting
+    public static long[] removeRange(long[] ranges, long start, long end) {
+        if (start == end) {
+            return ranges;
+        } else if (start > end) {
+            throw new IllegalArgumentException();
+        }
+
+        long[] res = EmptyArray.LONG;
+        for (int i = 0; i < ranges.length; i += 2) {
+            if (start <= ranges[i] && end >= ranges[i + 1]) {
+                // Range entirely covered; remove it
+            } else if (start >= ranges[i] && end <= ranges[i + 1]) {
+                // Range partially covered; punch a hole
+                res = Arrays.copyOf(res, res.length + 4);
+                res[res.length - 4] = ranges[i];
+                res[res.length - 3] = start;
+                res[res.length - 2] = end;
+                res[res.length - 1] = ranges[i + 1];
+            } else {
+                // Range might covered; adjust edges if needed
+                res = Arrays.copyOf(res, res.length + 2);
+                if (end >= ranges[i] && end <= ranges[i + 1]) {
+                    res[res.length - 2] = Math.max(ranges[i], end);
+                } else {
+                    res[res.length - 2] = ranges[i];
+                }
+                if (start >= ranges[i] && start <= ranges[i + 1]) {
+                    res[res.length - 1] = Math.min(ranges[i + 1], start);
+                } else {
+                    res[res.length - 1] = ranges[i + 1];
+                }
+            }
+        }
+        return res;
     }
 
     private final ProxyFileDescriptorCallback mCallback = new ProxyFileDescriptorCallback() {
@@ -126,7 +175,24 @@
 
         @Override
         public int onWrite(long offset, int size, byte[] data) throws ErrnoException {
-            throw new ErrnoException(TAG, OsConstants.EBADF);
+            int n = 0;
+            while (n < size) {
+                try {
+                    final int res = Os.pwrite(mInner, data, n, size - n, offset + n);
+                    if (res == 0) {
+                        break;
+                    } else {
+                        n += res;
+                    }
+                } catch (InterruptedIOException e) {
+                    n += e.bytesTransferred;
+                }
+            }
+
+            // Clear any relevant redaction ranges before returning, since the
+            // writer should have access to see the data they just overwrote
+            mRedactRanges = removeRange(mRedactRanges, offset, offset + n);
+            return n;
         }
 
         @Override
diff --git a/core/java/android/os/Temperature.java b/core/java/android/os/Temperature.java
index bf85fbd..21aba59 100644
--- a/core/java/android/os/Temperature.java
+++ b/core/java/android/os/Temperature.java
@@ -28,7 +28,7 @@
  *
  * @hide
  */
-public class Temperature implements Parcelable {
+public final class Temperature implements Parcelable {
     /** Temperature value */
     private float mValue;
     /** A temperature type from ThermalHAL */
diff --git a/core/java/android/provider/FontsContract.java b/core/java/android/provider/FontsContract.java
index 76607e9..8e37559 100644
--- a/core/java/android/provider/FontsContract.java
+++ b/core/java/android/provider/FontsContract.java
@@ -660,7 +660,22 @@
         if (familyBuilder == null) {
             return null;
         }
-        return new Typeface.CustomFallbackBuilder(familyBuilder.build()).build();
+
+        final FontFamily family = familyBuilder.build();
+
+        final FontStyle normal = new FontStyle(FontStyle.FONT_WEIGHT_NORMAL,
+                FontStyle.FONT_SLANT_UPRIGHT);
+        Font bestFont = family.getFont(0);
+        int bestScore = normal.getMatchScore(bestFont.getStyle());
+        for (int i = 1; i < family.getSize(); ++i) {
+            final Font candidate = family.getFont(i);
+            final int score = normal.getMatchScore(candidate.getStyle());
+            if (score < bestScore) {
+                bestFont = candidate;
+                bestScore = score;
+            }
+        }
+        return new Typeface.CustomFallbackBuilder(family).setStyle(bestFont.getStyle()).build();
     }
 
     /**
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index e0e4fe2..9e26a36 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -121,6 +121,8 @@
     public static final String PARAM_INCLUDE_PENDING = "includePending";
     /** {@hide} */
     public static final String PARAM_PROGRESS = "progress";
+    /** {@hide} */
+    public static final String PARAM_REQUIRE_ORIGINAL = "requireOriginal";
 
     /**
      * Activity Action: Launch a music player.
@@ -478,6 +480,24 @@
     }
 
     /**
+     * Update the given {@link Uri} to indicate that the caller requires the
+     * original file contents when calling
+     * {@link ContentResolver#openFileDescriptor(Uri, String)}.
+     * <p>
+     * This can be useful when the caller wants to ensure they're backing up the
+     * exact bytes of the underlying media, without any Exif redaction being
+     * performed.
+     * <p>
+     * If the original file contents cannot be provided, a
+     * {@link UnsupportedOperationException} will be thrown when the returned
+     * {@link Uri} is used, such as when the caller doesn't hold
+     * {@link android.Manifest.permission#ACCESS_MEDIA_LOCATION}.
+     */
+    public static @NonNull Uri setRequireOriginal(@NonNull Uri uri) {
+        return uri.buildUpon().appendQueryParameter(PARAM_REQUIRE_ORIGINAL, "1").build();
+    }
+
+    /**
      * Create a new pending media item using the given parameters. Pending items
      * are expected to have a short lifetime, and owners should either
      * {@link PendingSession#publish()} or {@link PendingSession#abandon()} a
@@ -1673,6 +1693,12 @@
             public static final String IS_NOTIFICATION = "is_notification";
 
             /**
+             * Non-zero if the audio file is an audiobook
+             * <P>Type: INTEGER (boolean)</P>
+             */
+            public static final String IS_AUDIOBOOK = "is_audiobook";
+
+            /**
              * The genre of the audio file, if any
              * <P>Type: TEXT</P>
              * Does not exist in the database - only used by the media scanner for inserts.
diff --git a/core/java/android/provider/TEST_MAPPING b/core/java/android/provider/TEST_MAPPING
deleted file mode 100644
index 8e67ce7..0000000
--- a/core/java/android/provider/TEST_MAPPING
+++ /dev/null
@@ -1,12 +0,0 @@
-{
-    "presubmit": [
-        {
-            "name": "FrameworksCoreTests",
-            "options": [
-                {
-                    "include-filter": "android.provider.SettingsBackupTest"
-                }
-            ]
-        }
-    ]
-}
diff --git a/core/java/android/service/intelligence/ContentCaptureEventsRequest.aidl b/core/java/android/service/intelligence/ContentCaptureEventsRequest.aidl
new file mode 100644
index 0000000..23d607d
--- /dev/null
+++ b/core/java/android/service/intelligence/ContentCaptureEventsRequest.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.service.intelligence;
+
+parcelable ContentCaptureEventsRequest;
diff --git a/core/java/android/service/intelligence/ContentCaptureEventsRequest.java b/core/java/android/service/intelligence/ContentCaptureEventsRequest.java
new file mode 100644
index 0000000..bc5b92b
--- /dev/null
+++ b/core/java/android/service/intelligence/ContentCaptureEventsRequest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.service.intelligence;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.view.intelligence.ContentCaptureEvent;
+
+import java.util.List;
+
+/**
+ * Batch of content capture events.
+ *
+ * @hide
+ */
+@SystemApi
+public final class ContentCaptureEventsRequest implements Parcelable {
+
+    private final List<ContentCaptureEvent> mEvents;
+
+    /** @hide */
+    public ContentCaptureEventsRequest(@NonNull List<ContentCaptureEvent> events) {
+        mEvents = events;
+    }
+
+    /**
+     * Gets the events.
+     */
+    @NonNull
+    public List<ContentCaptureEvent> getEvents() {
+        return mEvents;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeTypedList(mEvents, flags);
+    }
+
+    public static final Parcelable.Creator<ContentCaptureEventsRequest> CREATOR =
+            new Parcelable.Creator<ContentCaptureEventsRequest>() {
+
+        @Override
+        public ContentCaptureEventsRequest createFromParcel(Parcel parcel) {
+            return new ContentCaptureEventsRequest(parcel
+                    .createTypedArrayList(ContentCaptureEvent.CREATOR));
+        }
+
+        @Override
+        public ContentCaptureEventsRequest[] newArray(int size) {
+            return new ContentCaptureEventsRequest[size];
+        }
+    };
+}
diff --git a/core/java/android/service/intelligence/FillController.java b/core/java/android/service/intelligence/FillController.java
index c5e1242..4a9c85d 100644
--- a/core/java/android/service/intelligence/FillController.java
+++ b/core/java/android/service/intelligence/FillController.java
@@ -15,12 +15,12 @@
  */
 package android.service.intelligence;
 
-import static android.service.intelligence.IntelligenceService.DEBUG;
+import static android.service.intelligence.SmartSuggestionsService.DEBUG;
 
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.os.RemoteException;
-import android.service.intelligence.IntelligenceService.AutofillProxy;
+import android.service.intelligence.SmartSuggestionsService.AutofillProxy;
 import android.util.Log;
 import android.util.Pair;
 import android.view.autofill.AutofillId;
diff --git a/core/java/android/service/intelligence/FillRequest.java b/core/java/android/service/intelligence/FillRequest.java
index 95e9224..f68db9d 100644
--- a/core/java/android/service/intelligence/FillRequest.java
+++ b/core/java/android/service/intelligence/FillRequest.java
@@ -18,7 +18,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
-import android.service.intelligence.IntelligenceService.AutofillProxy;
+import android.service.intelligence.SmartSuggestionsService.AutofillProxy;
 import android.view.autofill.AutofillId;
 
 /**
diff --git a/core/java/android/service/intelligence/FillWindow.java b/core/java/android/service/intelligence/FillWindow.java
index 4ea07bf..309f6a1 100644
--- a/core/java/android/service/intelligence/FillWindow.java
+++ b/core/java/android/service/intelligence/FillWindow.java
@@ -15,7 +15,7 @@
  */
 package android.service.intelligence;
 
-import static android.service.intelligence.IntelligenceService.DEBUG;
+import static android.service.intelligence.SmartSuggestionsService.DEBUG;
 
 import android.annotation.LongDef;
 import android.annotation.NonNull;
diff --git a/core/java/android/service/intelligence/IIntelligenceService.aidl b/core/java/android/service/intelligence/IIntelligenceService.aidl
index e2260d7..d6b3107 100644
--- a/core/java/android/service/intelligence/IIntelligenceService.aidl
+++ b/core/java/android/service/intelligence/IIntelligenceService.aidl
@@ -17,6 +17,7 @@
 package android.service.intelligence;
 
 import android.os.IBinder;
+import android.service.intelligence.ContentCaptureEventsRequest;
 import android.service.intelligence.InteractionSessionId;
 import android.service.intelligence.InteractionContext;
 import android.service.intelligence.SnapshotData;
@@ -26,19 +27,19 @@
 
 import java.util.List;
 
-
 /**
  * Interface from the system to an intelligence service.
  *
  * @hide
  */
+ // TODO(b/111276913): rename / update javadoc (once the final name is defined)
 oneway interface IIntelligenceService {
 
     // Called when session is created (context not null) or destroyed (context null)
     void onSessionLifecycle(in InteractionContext context, in InteractionSessionId sessionId);
 
-    void onContentCaptureEvents(in InteractionSessionId sessionId,
-                                in List<ContentCaptureEvent> events);
+    void onContentCaptureEventsRequest(in InteractionSessionId sessionId,
+                                in ContentCaptureEventsRequest request);
 
     void onActivitySnapshot(in InteractionSessionId sessionId,
                             in SnapshotData snapshotData);
diff --git a/core/java/android/service/intelligence/InteractionContext.java b/core/java/android/service/intelligence/InteractionContext.java
index 0cc377b..7f4283d 100644
--- a/core/java/android/service/intelligence/InteractionContext.java
+++ b/core/java/android/service/intelligence/InteractionContext.java
@@ -37,7 +37,7 @@
     /**
      * Flag used to indicate that the app explicitly disabled content capture for the activity
      * (using
-     * {@link android.view.intelligence.IntelligenceManager#setContentCaptureEnabled()}),
+     * {@link android.view.intelligence.ContentCaptureManager#setContentCaptureEnabled()}),
      * in which case the service will just receive activity-level events.
      */
     public static final int FLAG_DISABLED_BY_APP = 0x1;
diff --git a/core/java/android/service/intelligence/PresentationParams.java b/core/java/android/service/intelligence/PresentationParams.java
index c59069b..9530309 100644
--- a/core/java/android/service/intelligence/PresentationParams.java
+++ b/core/java/android/service/intelligence/PresentationParams.java
@@ -20,7 +20,7 @@
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.graphics.Rect;
-import android.service.intelligence.IntelligenceService.AutofillProxy;
+import android.service.intelligence.SmartSuggestionsService.AutofillProxy;
 import android.util.DebugUtils;
 import android.view.View;
 
diff --git a/core/java/android/service/intelligence/IntelligenceService.java b/core/java/android/service/intelligence/SmartSuggestionsService.java
similarity index 71%
rename from core/java/android/service/intelligence/IntelligenceService.java
rename to core/java/android/service/intelligence/SmartSuggestionsService.java
index 040e25e..0e29e70 100644
--- a/core/java/android/service/intelligence/IntelligenceService.java
+++ b/core/java/android/service/intelligence/SmartSuggestionsService.java
@@ -19,8 +19,10 @@
 
 import android.annotation.CallSuper;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.app.Service;
+import android.content.ComponentName;
 import android.content.Intent;
 import android.graphics.Rect;
 import android.os.CancellationSignal;
@@ -43,31 +45,31 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Set;
 
 /**
- * A service used to capture the content of the screen.
- *
- * <p>The data collected by this service can be analyzed and combined with other sources to provide
- * contextual data in other areas of the system such as Autofill.
+ * A service used to capture the content of the screen to provide contextual data in other areas of
+ * the system such as Autofill.
  *
  * @hide
  */
 @SystemApi
-public abstract class IntelligenceService extends Service {
+public abstract class SmartSuggestionsService extends Service {
 
-    private static final String TAG = "IntelligenceService";
+    private static final String TAG = "SmartSuggestionsService";
 
     // TODO(b/111330312): STOPSHIP use dynamic value, or change to false
     static final boolean DEBUG = true;
+    static final boolean VERBOSE = false;
 
     /**
      * The {@link Intent} that must be declared as handled by the service.
      * To be supported, the service must also require the
-     * {@link android.Manifest.permission#BIND_INTELLIGENCE_SERVICE} permission so
+     * {@link android.Manifest.permission#BIND_SMART_SUGGESTIONS_SERVICE} permission so
      * that other applications can not abuse it.
      */
     public static final String SERVICE_INTERFACE =
-            "android.service.intelligence.IntelligenceService";
+            "android.service.intelligence.SmartSuggestionsService";
 
     private Handler mHandler;
 
@@ -80,21 +82,21 @@
                 throws RemoteException {
             if (context != null) {
                 mHandler.sendMessage(
-                        obtainMessage(IntelligenceService::onCreateInteractionSession,
-                                IntelligenceService.this, context, sessionId));
+                        obtainMessage(SmartSuggestionsService::onCreateInteractionSession,
+                                SmartSuggestionsService.this, context, sessionId));
             } else {
                 mHandler.sendMessage(
-                        obtainMessage(IntelligenceService::onDestroyInteractionSession,
-                                IntelligenceService.this, sessionId));
+                        obtainMessage(SmartSuggestionsService::onDestroyInteractionSession,
+                                SmartSuggestionsService.this, sessionId));
             }
         }
 
         @Override
-        public void onContentCaptureEvents(InteractionSessionId sessionId,
-                List<ContentCaptureEvent> events) {
+        public void onContentCaptureEventsRequest(InteractionSessionId sessionId,
+                ContentCaptureEventsRequest request) {
             mHandler.sendMessage(
-                    obtainMessage(IntelligenceService::onContentCaptureEvent,
-                            IntelligenceService.this, sessionId, events));
+                    obtainMessage(SmartSuggestionsService::onContentCaptureEventsRequest,
+                            SmartSuggestionsService.this, sessionId, request));
 
         }
 
@@ -102,22 +104,22 @@
         public void onActivitySnapshot(InteractionSessionId sessionId,
                 SnapshotData snapshotData) {
             mHandler.sendMessage(
-                    obtainMessage(IntelligenceService::onActivitySnapshot,
-                            IntelligenceService.this, sessionId, snapshotData));
+                    obtainMessage(SmartSuggestionsService::onActivitySnapshot,
+                            SmartSuggestionsService.this, sessionId, snapshotData));
         }
 
         @Override
         public void onAutofillRequest(InteractionSessionId sessionId, IBinder client,
                 int autofilSessionId, AutofillId focusedId) {
-            mHandler.sendMessage(obtainMessage(IntelligenceService::handleOnAutofillRequest,
-                    IntelligenceService.this, sessionId, client, autofilSessionId, focusedId));
+            mHandler.sendMessage(obtainMessage(SmartSuggestionsService::handleOnAutofillRequest,
+                    SmartSuggestionsService.this, sessionId, client, autofilSessionId, focusedId));
         }
 
         @Override
         public void onDestroyAutofillWindowsRequest(InteractionSessionId sessionId) {
             mHandler.sendMessage(
-                    obtainMessage(IntelligenceService::handleOnDestroyAutofillWindowsRequest,
-                            IntelligenceService.this, sessionId));
+                    obtainMessage(SmartSuggestionsService::handleOnDestroyAutofillWindowsRequest,
+                            SmartSuggestionsService.this, sessionId));
         }
     };
 
@@ -139,25 +141,92 @@
     }
 
     /**
+     * Explicitly limits content capture to the given packages and activities.
+     *
+     * <p>When the whitelist is set, it overrides the values passed to
+     * {@link #setActivityContentCaptureEnabled(ComponentName, boolean)}
+     * and {@link #setPackageContentCaptureEnabled(String, boolean)}.
+     *
+     * <p>To reset the whitelist, call it passing {@code null} to both arguments.
+     *
+     * <p>Useful when the service wants to restrict content capture to a category of apps, like
+     * chat apps. For example, if the service wants to support view captures on all activities of
+     * app {@code ChatApp1} and just activities {@code act1} and {@code act2} of {@code ChatApp2},
+     * it would call: {@code setContentCaptureWhitelist(Arrays.asList("ChatApp1"),
+     * Arrays.asList(new ComponentName("ChatApp2", "act1"),
+     * new ComponentName("ChatApp2", "act2")));}
+     */
+    public final void setContentCaptureWhitelist(@Nullable List<String> packages,
+            @Nullable List<ComponentName> activities) {
+        //TODO(b/111276913): implement
+    }
+
+    /**
+     * Defines whether content capture should be enabled for activities with such
+     * {@link android.content.ComponentName}.
+     *
+     * <p>Useful to blacklist a particular activity.
+     */
+    public final void setActivityContentCaptureEnabled(@NonNull ComponentName activity,
+            boolean enabled) {
+        //TODO(b/111276913): implement
+    }
+
+    /**
+     * Defines whether content capture should be enabled for activities of the app with such
+     * {@code packageName}.
+     *
+     * <p>Useful to blacklist any activity from a particular app.
+     */
+    public final void setPackageContentCaptureEnabled(@NonNull String packageName,
+            boolean enabled) {
+        //TODO(b/111276913): implement
+    }
+
+    /**
+     * Gets the activities where content capture was disabled by
+     * {@link #setActivityContentCaptureEnabled(ComponentName, boolean)}.
+     */
+    @NonNull
+    public final Set<ComponentName> getContentCaptureDisabledActivities() {
+        //TODO(b/111276913): implement
+        return null;
+    }
+
+    /**
+     * Gets the apps where content capture was disabled by
+     * {@link #setPackageContentCaptureEnabled(String, boolean)}.
+     */
+    @NonNull
+    public final Set<String> getContentCaptureDisabledPackages() {
+        //TODO(b/111276913): implement
+        return null;
+    }
+
+    /**
      * Creates a new interaction session.
      *
      * @param context interaction context
      * @param sessionId the session's Id
      */
     public void onCreateInteractionSession(@NonNull InteractionContext context,
-            @NonNull InteractionSessionId sessionId) {}
+            @NonNull InteractionSessionId sessionId) {
+        if (VERBOSE) {
+            Log.v(TAG, "onCreateInteractionSession(id=" + sessionId + ", ctx=" + context + ")");
+        }
+    }
 
     /**
      * Notifies the service of {@link ContentCaptureEvent events} associated with a content capture
      * session.
      *
      * @param sessionId the session's Id
-     * @param events the events
+     * @param request the events
      */
     // TODO(b/111276913): rename to onContentCaptureEvents or something like that; also, pass a
     // Request object so it can be extended
-    public abstract void onContentCaptureEvent(@NonNull InteractionSessionId sessionId,
-            @NonNull List<ContentCaptureEvent> events);
+    public abstract void onContentCaptureEventsRequest(@NonNull InteractionSessionId sessionId,
+            @NonNull ContentCaptureEventsRequest request);
 
     private void handleOnAutofillRequest(@NonNull InteractionSessionId sessionId,
             @NonNull IBinder client, int autofillSessionId, @NonNull AutofillId focusedId) {
@@ -242,8 +311,7 @@
     }
 
     /**
-     * Notifies the service of {@link IntelligenceSnapshotData snapshot data} associated with a
-     * session.
+     * Notifies the service of {@link SnapshotData snapshot data} associated with a session.
      *
      * @param sessionId the session's Id
      * @param snapshotData the data
@@ -256,7 +324,11 @@
      *
      * @param sessionId the id of the session to destroy
      */
-    public void onDestroyInteractionSession(@NonNull InteractionSessionId sessionId) {}
+    public void onDestroyInteractionSession(@NonNull InteractionSessionId sessionId) {
+        if (VERBOSE) {
+            Log.v(TAG, "onDestroyInteractionSession(id=" + sessionId + ")");
+        }
+    }
 
     /** @hide */
     static final class AutofillProxy {
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index 8371c31b..0e2ae83 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -806,7 +806,7 @@
         if (zenPolicy.isCategoryAllowed(ZenPolicy.PRIORITY_CATEGORY_CALLS,
                 isPriorityCategoryEnabled(Policy.PRIORITY_CATEGORY_CALLS, defaultPolicy))) {
             priorityCategories |= Policy.PRIORITY_CATEGORY_CALLS;
-            messageSenders = getNotificationPolicySenders(zenPolicy.getPriorityCallSenders());
+            callSenders = getNotificationPolicySenders(zenPolicy.getPriorityCallSenders());
         }
 
         if (zenPolicy.isCategoryAllowed(ZenPolicy.PRIORITY_CATEGORY_REPEAT_CALLERS,
diff --git a/core/java/android/service/notification/ZenPolicy.java b/core/java/android/service/notification/ZenPolicy.java
index 43ab8dc..194147c 100644
--- a/core/java/android/service/notification/ZenPolicy.java
+++ b/core/java/android/service/notification/ZenPolicy.java
@@ -859,6 +859,27 @@
     /**
      * @hide
      */
+    public boolean areValuesSet() {
+        return getPriorityCategoryReminders() != STATE_UNSET
+                || getPriorityCategoryEvents() != STATE_UNSET
+                || getPriorityCategoryMessages() != STATE_UNSET
+                || getPriorityCategoryCalls() != STATE_UNSET
+                || getPriorityCategoryRepeatCallers() != STATE_UNSET
+                || getPriorityCategoryAlarms() != STATE_UNSET
+                || getPriorityCategoryMedia() != STATE_UNSET
+                || getPriorityCategorySystem() != STATE_UNSET
+                || getVisualEffectFullScreenIntent() != STATE_UNSET
+                || getVisualEffectLights() != STATE_UNSET
+                || getVisualEffectPeek() != STATE_UNSET
+                || getVisualEffectStatusBar() != STATE_UNSET
+                || getVisualEffectBadge() != STATE_UNSET
+                || getVisualEffectAmbient() != STATE_UNSET
+                || getVisualEffectNotificationList() != STATE_UNSET;
+    }
+
+    /**
+     * @hide
+     */
     public void writeToProto(ProtoOutputStream proto, long fieldId) {
         final long token = proto.start(fieldId);
 
diff --git a/core/java/android/text/style/SuggestionSpan.java b/core/java/android/text/style/SuggestionSpan.java
index be47320..433483f7 100644
--- a/core/java/android/text/style/SuggestionSpan.java
+++ b/core/java/android/text/style/SuggestionSpan.java
@@ -369,10 +369,7 @@
 
     /**
      * @return The color of the underline for that span, or 0 if there is no underline
-     *
-     * @hide
      */
-    @UnsupportedAppUsage
     public int getUnderlineColor() {
         // The order here should match what is used in updateDrawState
         final boolean misspelled = (mFlags & FLAG_MISSPELLED) != 0;
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 5f348c4..dee6d90 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -45,7 +45,6 @@
         DEFAULT_FLAGS.put("settings_systemui_theme", "true");
         DEFAULT_FLAGS.put("settings_dynamic_homepage", "true");
         DEFAULT_FLAGS.put("settings_mobile_network_v2", "true");
-        DEFAULT_FLAGS.put("settings_data_usage_v2", "true");
         DEFAULT_FLAGS.put("settings_seamless_transfer", "false");
         DEFAULT_FLAGS.put(HEARING_AID_SETTINGS, "false");
         DEFAULT_FLAGS.put("settings_network_and_internet_v2", "false");
diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl
index af41b69..5e6d3d1 100644
--- a/core/java/android/view/IWindow.aidl
+++ b/core/java/android/view/IWindow.aidl
@@ -25,6 +25,7 @@
 import android.view.MotionEvent;
 import android.view.DisplayCutout;
 import android.view.InsetsState;
+import android.view.InsetsSourceControl;
 
 import com.android.internal.os.IResultReceiver;
 import android.util.MergedConfiguration;
@@ -60,6 +61,11 @@
      */
     void insetsChanged(in InsetsState insetsState);
 
+    /**
+     * Called when this window retrieved control over a specified set of inset sources.
+     */
+    void insetsControlChanged(in InsetsState insetsState, in InsetsSourceControl[] activeControls);
+
     void moved(int newX, int newY);
     void dispatchAppVisibility(boolean visible);
     void dispatchGetNewSurface();
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 7841d04..ba5340c 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -16,17 +16,30 @@
 
 package android.view;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.graphics.Rect;
+import android.util.ArraySet;
+import android.util.SparseArray;
+import android.view.SurfaceControl.Transaction;
+import android.view.WindowInsets.Type.InsetType;
+import android.view.InsetsState.InternalInsetType;
+
+import com.android.internal.annotations.VisibleForTesting;
 
 import java.io.PrintWriter;
 
 /**
  * Implements {@link WindowInsetsController} on the client.
+ * @hide
  */
-class InsetsController {
+public class InsetsController implements WindowInsetsController {
 
     private final InsetsState mState = new InsetsState();
     private final Rect mFrame = new Rect();
+    private final SparseArray<InsetsSourceConsumer> mSourceConsumers = new SparseArray<>();
+
+    private final SparseArray<InsetsSourceControl> mTmpControlArray = new SparseArray<>();
 
     void onFrameChanged(Rect frame) {
         mFrame.set(frame);
@@ -48,6 +61,61 @@
         return mState.calculateInsets(mFrame, isScreenRound, alwaysConsumeNavBar, cutout);
     }
 
+    /**
+     * Called when the server has dispatched us a new set of inset controls.
+     */
+    public void onControlsChanged(InsetsSourceControl[] activeControls) {
+        if (activeControls != null) {
+            for (InsetsSourceControl activeControl : activeControls) {
+                mTmpControlArray.put(activeControl.getType(), activeControl);
+            }
+        }
+
+        // Ensure to update all existing source consumers
+        for (int i = mSourceConsumers.size() - 1; i >= 0; i--) {
+            final InsetsSourceConsumer consumer = mSourceConsumers.valueAt(i);
+            final InsetsSourceControl control = mTmpControlArray.get(consumer.getType());
+
+            // control may be null, but we still need to update the control to null if it got
+            // revoked.
+            consumer.setControl(control);
+        }
+
+        // Ensure to create source consumers if not available yet.
+        for (int i = mTmpControlArray.size() - 1; i >= 0; i--) {
+            final InsetsSourceControl control = mTmpControlArray.valueAt(i);
+            getSourceConsumer(control.getType()).setControl(control);
+        }
+        mTmpControlArray.clear();
+    }
+
+    @Override
+    public void show(@InsetType int types) {
+        final ArraySet<Integer> internalTypes = InsetsState.toInternalType(types);
+        for (int i = internalTypes.size() - 1; i >= 0; i--) {
+            getSourceConsumer(internalTypes.valueAt(i)).show();
+        }
+    }
+
+    @Override
+    public void hide(@InsetType int types) {
+        final ArraySet<Integer> internalTypes = InsetsState.toInternalType(types);
+        for (int i = internalTypes.size() - 1; i >= 0; i--) {
+            getSourceConsumer(internalTypes.valueAt(i)).hide();
+        }
+    }
+
+    @VisibleForTesting
+    public @NonNull InsetsSourceConsumer getSourceConsumer(@InternalInsetType int type) {
+        InsetsSourceConsumer controller = mSourceConsumers.get(type);
+        if (controller != null) {
+            return controller;
+        }
+        controller = new InsetsSourceConsumer(type, mState, Transaction::new);
+        mSourceConsumers.put(type, controller);
+        return controller;
+    }
+
     void dump(String prefix, PrintWriter pw) {
         pw.println(prefix); pw.println("InsetsController:");
         mState.dump(prefix + "  ", pw);
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
new file mode 100644
index 0000000..e74aa8d
--- /dev/null
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.view;
+
+import android.annotation.Nullable;
+import android.view.SurfaceControl.Transaction;
+import android.view.InsetsState.InternalInsetType;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.function.Supplier;
+
+/**
+ * Controls the visibility and animations of a single window insets source.
+ * @hide
+ */
+public class InsetsSourceConsumer {
+
+    private final Supplier<Transaction> mTransactionSupplier;
+    private final @InternalInsetType int mType;
+    private final InsetsState mState;
+    private @Nullable InsetsSourceControl mControl;
+    private boolean mHidden;
+
+    public InsetsSourceConsumer(@InternalInsetType int type, InsetsState state,
+            Supplier<Transaction> transactionSupplier) {
+        mType = type;
+        mState = state;
+        mTransactionSupplier = transactionSupplier;
+    }
+
+    public void setControl(@Nullable InsetsSourceControl control) {
+        if (mControl == control) {
+            return;
+        }
+        mControl = control;
+        applyHiddenToControl();
+    }
+
+    @VisibleForTesting
+    public InsetsSourceControl getControl() {
+        return mControl;
+    }
+
+    int getType() {
+        return mType;
+    }
+
+    @VisibleForTesting
+    public void show() {
+        setHidden(false);
+    }
+
+    @VisibleForTesting
+    public void hide() {
+        setHidden(true);
+    }
+
+    private void setHidden(boolean hidden) {
+        if (mHidden == hidden) {
+            return;
+        }
+        mHidden = hidden;
+        applyHiddenToControl();
+    }
+
+    private void applyHiddenToControl() {
+        if (mControl == null) {
+            return;
+        }
+
+        // TODO: Animation
+        final Transaction t = mTransactionSupplier.get();
+        if (mHidden) {
+            t.hide(mControl.getLeash());
+        } else {
+            t.show(mControl.getLeash());
+        }
+        t.apply();
+    }
+}
diff --git a/core/java/android/view/InsetsSourceControl.aidl b/core/java/android/view/InsetsSourceControl.aidl
new file mode 100644
index 0000000..755bf45
--- /dev/null
+++ b/core/java/android/view/InsetsSourceControl.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.view;
+
+parcelable InsetsSourceControl;
diff --git a/core/java/android/view/InsetsSourceControl.java b/core/java/android/view/InsetsSourceControl.java
new file mode 100644
index 0000000..9383e6c
--- /dev/null
+++ b/core/java/android/view/InsetsSourceControl.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.view;
+
+import android.graphics.Point;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.view.InsetsState.InternalInsetType;
+
+/**
+ * Represents a parcelable object to allow controlling a single {@link InsetsSource}.
+ * @hide
+ */
+public class InsetsSourceControl implements Parcelable {
+
+    private final @InternalInsetType int mType;
+    private final SurfaceControl mLeash;
+
+    public InsetsSourceControl(@InternalInsetType int type, SurfaceControl leash) {
+        mType = type;
+        mLeash = leash;
+    }
+
+    public int getType() {
+        return mType;
+    }
+
+    public SurfaceControl getLeash() {
+        return mLeash;
+    }
+
+    public InsetsSourceControl(Parcel in) {
+        mType = in.readInt();
+        mLeash = in.readParcelable(null /* loader */);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mType);
+        dest.writeParcelable(mLeash, 0 /* flags*/);
+    }
+
+    public static final Creator<InsetsSourceControl> CREATOR
+            = new Creator<InsetsSourceControl>() {
+        public InsetsSourceControl createFromParcel(Parcel in) {
+            return new InsetsSourceControl(in);
+        }
+
+        public InsetsSourceControl[] newArray(int size) {
+            return new InsetsSourceControl[size];
+        }
+    };
+}
diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java
index 9895adc..689b14f 100644
--- a/core/java/android/view/InsetsState.java
+++ b/core/java/android/view/InsetsState.java
@@ -22,6 +22,9 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.view.WindowInsets.Type;
+import android.view.WindowInsets.Type.InsetType;
 
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
@@ -148,6 +151,22 @@
         }
     }
 
+    public static @InternalInsetType ArraySet<Integer> toInternalType(@InsetType int insetTypes) {
+        final ArraySet<Integer> result = new ArraySet<>();
+        if ((insetTypes & Type.TOP_BAR) != 0) {
+            result.add(TYPE_TOP_BAR);
+        }
+        if ((insetTypes & Type.SIDE_BARS) != 0) {
+            result.add(TYPE_SIDE_BAR_1);
+            result.add(TYPE_SIDE_BAR_2);
+            result.add(TYPE_SIDE_BAR_3);
+        }
+        if ((insetTypes & Type.IME) != 0) {
+            result.add(TYPE_IME);
+        }
+        return result;
+    }
+
     public void dump(String prefix, PrintWriter pw) {
         pw.println(prefix + "InsetsState");
         for (int i = mSources.size() - 1; i >= 0; i--) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index c5d0374..4b9cbff 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -112,7 +112,7 @@
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputConnection;
 import android.view.inputmethod.InputMethodManager;
-import android.view.intelligence.IntelligenceManager;
+import android.view.intelligence.ContentCaptureManager;
 import android.widget.Checkable;
 import android.widget.FrameLayout;
 import android.widget.ScrollBarDrawable;
@@ -8138,7 +8138,7 @@
      * is visible.
      *
      * <p>The populated structure is then passed to the service through
-     * {@link IntelligenceManager#notifyViewAppeared(ViewStructure)}.
+     * {@link ContentCaptureManager#notifyViewAppeared(ViewStructure)}.
      *
      * <p><b>Note: </b>the following methods of the {@code structure} will be ignored:
      * <ul>
@@ -8915,7 +8915,7 @@
     }
 
     /**
-     * Helper used to notify the {@link IntelligenceManager} when the view is removed or
+     * Helper used to notify the {@link ContentCaptureManager} when the view is removed or
      * added, based on whether it's laid out and visible, and without knowing if the parent removed
      * it from the view hierarchy.
      *
@@ -8931,11 +8931,15 @@
      * </ol>
      */
     private void notifyAppearedOrDisappearedForContentCaptureIfNeeded(boolean appeared) {
+        // First check if context has client, so it saves a service lookup when it doesn't
+        if (!mContext.isContentCaptureSupported()) return;
 
-        final IntelligenceManager im = mContext.getSystemService(IntelligenceManager.class);
-        if (im == null || !im.isContentCaptureEnabled()) return;
+        // Then check if it's enabled in the context...
+        final ContentCaptureManager cm = mContext.getSystemService(ContentCaptureManager.class);
+        if (cm == null || !cm.isContentCaptureEnabled()) return;
 
-        // NOTE: isImportantForContentCapture() is more expensive than im.isContentCaptureEnabled()
+        // ... and finally at the view level
+        // NOTE: isImportantForContentCapture() is more expensive than cm.isContentCaptureEnabled()
         if (!isImportantForContentCapture()) return;
 
         if (appeared) {
@@ -8950,9 +8954,9 @@
                 return;
             }
             // All good: notify the manager...
-            final ViewStructure structure = im.newViewStructure(this);
+            final ViewStructure structure = cm.newViewStructure(this);
             onProvideContentCaptureStructure(structure, /* flags= */ 0);
-            im.notifyViewAppeared(structure);
+            cm.notifyViewAppeared(structure);
             // ...and set the flags
             mPrivateFlags4 |= PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED;
             mPrivateFlags4 &= ~PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED;
@@ -8969,7 +8973,7 @@
                 return;
             }
             // All good: notify the manager...
-            im.notifyViewDisappeared(getAutofillId());
+            cm.notifyViewDisappeared(getAutofillId());
             // ...and set the flags
             mPrivateFlags4 |= PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED;
             mPrivateFlags4 &= ~PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED;
@@ -10337,6 +10341,20 @@
     }
 
     /**
+     * Retrieves the single {@link WindowInsetsController} of the window this view is attached to.
+     *
+     * @return The {@link WindowInsetsController} or {@code null} if the view isn't attached to a
+     *         a window.
+     * @hide pending unhide
+     */
+    public @Nullable WindowInsetsController getWindowInsetsController() {
+        if (mAttachInfo != null) {
+            return mAttachInfo.mViewRootImpl.getInsetsController();
+        }
+        return null;
+    }
+
+    /**
      * @hide Compute the insets that should be consumed by this view and the ones
      * that should propagate to those under it.
      *
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 937e238..cb47886 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -170,7 +170,12 @@
      * fully migrated over.
      */
     private static final String USE_NEW_INSETS_PROPERTY = "persist.wm.new_insets";
-    private static final boolean USE_NEW_INSETS =
+
+    /**
+     * @see #USE_NEW_INSETS_PROPERTY
+     * @hide
+     */
+    public static final boolean USE_NEW_INSETS =
             SystemProperties.getBoolean(USE_NEW_INSETS_PROPERTY, false);
 
     /**
@@ -1847,6 +1852,10 @@
         host.dispatchApplyWindowInsets(insets);
     }
 
+    InsetsController getInsetsController() {
+        return mInsetsController;
+    }
+
     private static boolean shouldUseDisplaySize(final WindowManager.LayoutParams lp) {
         return lp.type == TYPE_STATUS_BAR_PANEL
                 || lp.type == TYPE_INPUT_METHOD
@@ -1935,7 +1944,6 @@
             // PixelFormat.hasAlpha(lp.format) || lp.format == PixelFormat.RGBX_8888
             // However, windows are now always 32 bits by default, so choose 32 bits
             mAttachInfo.mUse32BitDrawingCache = true;
-            mAttachInfo.mHasWindowFocus = false;
             mAttachInfo.mWindowVisibility = viewVisibility;
             mAttachInfo.mRecomputeGlobalAttributes = false;
             mLastConfigurationFromResources.setTo(config);
@@ -4208,6 +4216,7 @@
     private final static int MSG_POINTER_CAPTURE_CHANGED = 28;
     private final static int MSG_DRAW_FINISHED = 29;
     private final static int MSG_INSETS_CHANGED = 30;
+    private final static int MSG_INSETS_CONTROL_CHANGED = 31;
 
     final class ViewRootHandler extends Handler {
         @Override
@@ -4371,11 +4380,22 @@
                 case MSG_INSETS_CHANGED:
                     mPendingInsets = (InsetsState) msg.obj;
 
-                    // TODO: Full traversal not needed here
+                    // TODO: Full traversal not needed here.
                     if (USE_NEW_INSETS) {
                         requestLayout();
                     }
                     break;
+                case MSG_INSETS_CONTROL_CHANGED: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    mPendingInsets = (InsetsState) args.arg1;
+                    mInsetsController.onControlsChanged((InsetsSourceControl[]) args.arg2);
+
+                    // TODO: Full traversal not necessarily needed here.
+                    if (USE_NEW_INSETS) {
+                        requestLayout();
+                    }
+                    break;
+                }
                 case MSG_WINDOW_MOVED:
                     if (mAdded) {
                         final int w = mWinFrame.width();
@@ -7116,6 +7136,14 @@
         mHandler.obtainMessage(MSG_INSETS_CHANGED, insetsState).sendToTarget();
     }
 
+    private void dispatchInsetsControlChanged(InsetsState insetsState,
+            InsetsSourceControl[] activeControls) {
+        SomeArgs args = SomeArgs.obtain();
+        args.arg1 = insetsState;
+        args.arg2 = activeControls;
+        mHandler.obtainMessage(MSG_INSETS_CONTROL_CHANGED, args).sendToTarget();
+    }
+
     public void dispatchMoved(int newX, int newY) {
         if (DEBUG_LAYOUT) Log.v(mTag, "Window moved " + this + ": newX=" + newX + " newY=" + newY);
         if (mTranslator != null) {
@@ -8187,6 +8215,15 @@
         }
 
         @Override
+        public void insetsControlChanged(InsetsState insetsState,
+                InsetsSourceControl[] activeControls) {
+            final ViewRootImpl viewAncestor = mViewAncestor.get();
+            if (viewAncestor != null) {
+                viewAncestor.dispatchInsetsControlChanged(insetsState, activeControls);
+            }
+        }
+
+        @Override
         public void moved(int newX, int newY) {
             final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index c1e94d8..58ab817 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -2410,4 +2410,11 @@
     public boolean isCloseOnSwipeEnabled() {
         return mCloseOnSwipeEnabled;
     }
+
+    /**
+     * @return The {@link WindowInsetsController} associated with this window
+     * @see View#getWindowInsetsController()
+     * @hide pending unhide
+     */
+    public abstract @NonNull WindowInsetsController getInsetsController();
 }
diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java
index a8debbd..572d331 100644
--- a/core/java/android/view/WindowInsets.java
+++ b/core/java/android/view/WindowInsets.java
@@ -18,13 +18,17 @@
 package android.view;
 
 import android.annotation.NonNull;
+import android.annotation.IntDef;
 import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
 import android.graphics.Insets;
 import android.graphics.Rect;
+import android.view.inputmethod.InputMethod;
 
 import com.android.internal.util.Preconditions;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.Objects;
 
 /**
@@ -807,4 +811,69 @@
                     mIsRound, mAlwaysConsumeNavBar, mDisplayCutout);
         }
     }
+
+    /**
+     * Class that defines different types of sources causing window insets.
+     * @hide pending unhide
+     */
+    public static final class Type {
+
+        static final int TOP_BAR = 0x1;
+        static final int IME = 0x2;
+        static final int SIDE_BARS = 0x4;
+        static final int WINDOW_DECOR = 0x8;
+
+        private Type() {
+        }
+
+        /** @hide */
+        @Retention(RetentionPolicy.SOURCE)
+        @IntDef(flag = true, value = { TOP_BAR, IME, SIDE_BARS, WINDOW_DECOR })
+        public @interface InsetType {
+        }
+
+        /**
+         * @return An inset type representing the top bar of a window, which can be the status
+         *         bar on handheld-like devices as well as a caption bar.
+         */
+        public static @InsetType int topBar() {
+            return TOP_BAR;
+        }
+
+        /**
+         * @return An inset type representing the window of an {@link InputMethod}.
+         */
+        public static @InsetType int ime() {
+            return IME;
+        }
+
+        /**
+         * @return An inset type representing any system bars that are not {@link #topBar()}.
+         */
+        public static @InsetType int sideBars() {
+            return SIDE_BARS;
+        }
+
+        /**
+         * @return An inset type representing decor that is being app-controlled.
+         */
+        public static @InsetType int windowDecor() {
+            return WINDOW_DECOR;
+        }
+
+        /**
+         * @return All system bars. Includes {@link #topBar()} as well as {@link #sideBars()}, but
+         *         not {@link #ime()}.
+         */
+        public static @InsetType int systemBars() {
+            return TOP_BAR | SIDE_BARS;
+        }
+
+        /**
+         * @return All inset types combined.
+         */
+        public static @InsetType int all() {
+            return 0xFFFFFFFF;
+        }
+    }
 }
diff --git a/core/java/android/view/WindowInsetsController.java b/core/java/android/view/WindowInsetsController.java
new file mode 100644
index 0000000..7be5f2e
--- /dev/null
+++ b/core/java/android/view/WindowInsetsController.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.view;
+
+import android.view.WindowInsets.Type.InsetType;
+
+/**
+ * Interface to control windows that generate insets.
+ *
+ * TODO Needs more information and examples once the API is more baked.
+ * @hide pending unhide
+ */
+public interface WindowInsetsController {
+
+    /**
+     * Makes a set of windows that cause insets appear on screen.
+     * <p>
+     * Note that if the window currently doesn't have control over a certain type, it will apply the
+     * change as soon as the window gains control. The app can listen to the event by observing
+     * {@link View#onApplyWindowInsets} and checking visibility with "TODO at method" in
+     * {@link WindowInsets}.
+     *
+     * @param types A bitmask of {@link WindowInsets.Type.InsetType} specifying what windows the app
+     *              would like to make appear on screen.
+     */
+    void show(@InsetType int types);
+
+    /**
+     * Makes a set of windows causing insets disappear.
+     * <p>
+     * Note that if the window currently doesn't have control over a certain type, it will apply the
+     * change as soon as the window gains control. The app can listen to the event by observing
+     * {@link View#onApplyWindowInsets} and checking visibility with "TODO at method" in
+     * {@link WindowInsets}.
+     *
+     * @param types A bitmask of {@link WindowInsets.Type.InsetType} specifying what windows the app
+     *              would like to make disappear.
+     */
+    void hide(@InsetType int types);
+}
diff --git a/core/java/android/view/inspector/ChildTraverser.java b/core/java/android/view/inspector/ChildTraverser.java
deleted file mode 100644
index b775de5..0000000
--- a/core/java/android/view/inspector/ChildTraverser.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.view.inspector;
-
-import android.annotation.NonNull;
-
-/**
- * Interface for visiting all the child nodes of an inspectable object.
- *
- * Inspectable objects may return a collection of children as an array, an {@link Iterable} or an
- * {@link java.util.Iterator}. This provides a unified API for traversing across all the children
- * of an inspectable node.
- *
- * This interface is consumed by {@link InspectionHelper#traverseChildren(Object, ChildTraverser)}
- * and may be implemented as a lambda.
- *
- * @see InspectionHelper#traverseChildren(Object, ChildTraverser)
- * @hide
- */
-@FunctionalInterface
-public interface ChildTraverser {
-    /**
-     * Visit one child object of a parent inspectable object.
-     *
-     * The iteration interface will filter null values out before passing them to this method, but
-     * some child objects may not be inspectable. It is up to the implementor to determine their
-     * inspectablity and what to do with them.
-     *
-     * @param child A child object, guaranteed not to be null.
-     */
-    void traverseChild(@NonNull Object child);
-}
diff --git a/core/java/android/view/inspector/InspectableChildren.java b/core/java/android/view/inspector/InspectableChildren.java
deleted file mode 100644
index de8fa29..0000000
--- a/core/java/android/view/inspector/InspectableChildren.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.view.inspector;
-
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Marks a getter for an inspectable node's inspectable children.
- *
- * This annotation can be applied to any getter that returns a collection of objects, either an
- * array, an {@link Iterable} or a {@link java.util.Iterator}. The getter may return null, which
- * will be treated as an empty collection. Additionally, the inspector will discard any null
- * entries in the collection.
- *
- * By default, this annotation is inherited. At runtime, the inspector introspects on the class
- * hierachy and uses the annotated getter from the bottommost class, if different from any
- * annoated getters of the parent class. If a class inherits from a parent class with an annotated
- * getter, but does not include this annotation, the child class will be traversed using the
- * getter annotated on the parent. This holds true even if the child class overrides the getter.
- *
- * @see InspectionHelper#traverseChildren(Object, ChildTraverser)
- * @see InspectionHelper#hasChildTraversal()
- * @hide
- */
-@Target({METHOD})
-@Retention(SOURCE)
-public @interface InspectableChildren {
-}
diff --git a/core/java/android/view/inspector/InspectableNodeName.java b/core/java/android/view/inspector/InspectableNodeName.java
index 716409c..ea94ad4 100644
--- a/core/java/android/view/inspector/InspectableNodeName.java
+++ b/core/java/android/view/inspector/InspectableNodeName.java
@@ -34,7 +34,7 @@
  * This annotation does not inherit. If a class extends an annotated parent class, but does not
  * annotate itself, its node name will be inferred from its Java name.
  *
- * @see InspectionHelper#getNodeName()
+ * @see InspectionCompanion#getNodeName()
  * @hide
  */
 @Target({TYPE})
diff --git a/core/java/android/view/inspector/InspectableProperty.java b/core/java/android/view/inspector/InspectableProperty.java
index b0fd503..5b957156 100644
--- a/core/java/android/view/inspector/InspectableProperty.java
+++ b/core/java/android/view/inspector/InspectableProperty.java
@@ -17,8 +17,11 @@
 package android.view.inspector;
 
 import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
+import android.content.res.ResourceId;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 
@@ -31,8 +34,8 @@
  * but on a different getter, the inspector will use the child's getter when inspecting instances
  * of the child, and the parent's otherwise.
  *
- * @see InspectionHelper#mapProperties(PropertyMapper)
- * @see InspectionHelper#readProperties(Object, PropertyReader)
+ * @see InspectionCompanion#mapProperties(PropertyMapper)
+ * @see InspectionCompanion#readProperties(Object, PropertyReader)
  * @hide
  */
 @Target({METHOD})
@@ -46,5 +49,171 @@
      *
      * @return The name of the property.
      */
-    String value() default "";
+    String name() default "";
+
+    /**
+     * If the property is inflated from XML, the resource ID of its XML attribute.
+     *
+     * If left as {ID_NULL}, and {@link #hasAttributeId()} is true, the attribute ID will be
+     * inferred from {@link #name()}.
+     *
+     * @return The attribute ID of the property or {@link ResourceId#ID_NULL}
+     */
+    int attributeId() default ResourceId.ID_NULL;
+
+    /**
+     * If this property has an attribute ID.
+     *
+     * Set to false if the annotated property does not have an attribute ID, that is, it is not
+     * inflated from an XML attribute. This will prevent the automatic inference of the attribute
+     * ID if {@link #attributeId()} is set to {@link ResourceId#ID_NULL}.
+     *
+     * @return Whether to infer an attribute ID if not supplied
+     */
+    boolean hasAttributeId() default true;
+
+    /**
+     * Specify how to interpret a value type packed into a primitive integer.
+     *
+     * @return A {@link ValueType}
+     */
+    ValueType valueType() default ValueType.INFERRED;
+
+    /**
+     * For enumerations packed into primitive {int} properties, map the values to string names.
+     *
+     * Note that {@link #enumMapping()} cannot be used simultaneously with {@link #flagMapping()}.
+     *
+     * @return An array of {@link EnumMap}, empty if not applicable
+     * @see android.annotation.IntDef
+     * @see IntEnumMapping
+     */
+    EnumMap[] enumMapping() default {};
+
+    /**
+     * For flags packed into primitive {int} properties, model the string names of the flags.
+     *
+     * Note that {@link #flagMapping()} cannot be used simultaneously with {@link #enumMapping()}.
+     *
+     * @return An array of {@link FlagMap}, empty if not applicable
+     * @see android.annotation.IntDef
+     * @see IntFlagMapping
+     */
+    FlagMap[] flagMapping() default {};
+
+
+    /**
+     * One entry in an enumeration packed into a primitive {int}.
+     *
+     * @see IntEnumMapping
+     * @hide
+     */
+    @Target({TYPE})
+    @Retention(SOURCE)
+    @interface EnumMap {
+        /**
+         * The string name of this enumeration value.
+         *
+         * @return A string name
+         */
+        String name();
+
+        /**
+         * The integer value of this enumeration value.
+         *
+         * @return An integer value
+         */
+        int value();
+    }
+
+    /**
+     * One flag value of many that may be packed into a primitive {int}.
+     *
+     * @see IntFlagMapping
+     * @hide
+     */
+    @Target({TYPE})
+    @Retention(SOURCE)
+    @interface FlagMap {
+        /**
+         * The string name of this flag.
+         *
+         * @return A string name
+         */
+        String name();
+
+        /**
+         * A target value that the property's value must equal after masking.
+         *
+         * If a mask is not supplied (i.e., {@link #mask()} is 0), the target will be reused as the
+         * mask. This handles the common case where no flags mutually exclude each other.
+         *
+         * @return The target value to compare against
+         */
+        int target();
+
+        /**
+         * A mask that the property will be bitwise anded with before comparing to the target.
+         *
+         * If set to 0 (the default), the value of {@link #target()} will be used as a mask. Zero
+         * was chosen as the default since bitwise and with zero is always zero.
+         *
+         * @return A mask, or 0 to use the target as a mask
+         */
+        int mask() default 0;
+    }
+
+    /**
+     * The type of value packed into a primitive {int}.
+     *
+     * @hide
+     */
+    enum ValueType {
+        /**
+         * No special handling, property is considered to be a numeric value.
+         */
+        NONE,
+
+        /**
+         * The default the annotation processor infers the value type from context.
+         */
+        INFERRED,
+
+        /**
+         * Value packs an enumeration.
+         *
+         * This is inferred if {@link #enumMapping()} is specified.
+         *
+         * @see EnumMap
+         */
+        INT_ENUM,
+
+        /**
+         * Value packs flags, of which many may be enabled at once.
+         *
+         * This is inferred if {@link #flagMapping()} is specified.
+         *
+         * @see FlagMap
+         */
+        INT_FLAG,
+
+        /**
+         * Value packs color information.
+         *
+         * This is inferred from {@link android.annotation.ColorInt}, or
+         * {@link android.annotation.ColorLong} on the getter method.
+         *
+         * @see android.graphics.Color
+         */
+        COLOR,
+
+        /**
+         * Value packs gravity information.
+         *
+         * This type is not inferred, and is non-trivial to represent using {@link FlagMap}.
+         *
+         * @see android.view.Gravity
+         */
+        GRAVITY
+    }
 }
diff --git a/core/java/android/view/inspector/InspectionCompanion.java b/core/java/android/view/inspector/InspectionCompanion.java
new file mode 100644
index 0000000..ce0aee8
--- /dev/null
+++ b/core/java/android/view/inspector/InspectionCompanion.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.view.inspector;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+/**
+ * An interface for companion objects used to inspect views.
+ *
+ * Inspection companions only need to handle the properties and node name of the specific class
+ * they are defined for, not anything from a parent class. At runtime, the inspector instantiates
+ * one instance of each inspection companion, and handles visiting them in the correct inheritance
+ * order for each type it inspects.
+ *
+ * Properties are read from the top of the type tree to the bottom, so that classes that override
+ * a property in their parent class can overwrite it in the reader. In general, properties will
+ * cleanly inherit through their getters, and the inspector runtime will read the properties of a
+ * parent class via the parent's inspection companion, and the child companion will only read
+ * properties added or changed since the parent was defined.
+ *
+ * Only one child traversal is considered for each class. If a descendant class defines a
+ * different child traversal than its parent, only the bottom traversal is used. If a class does
+ * not define its own child traversal, but one of its ancestors does, the bottom-most ancestor's
+ * traversal will be used.
+ *
+ * @param <T> The type of inspectable this is the companion to
+ */
+public interface InspectionCompanion<T> {
+    /**
+     * Map the string names of the properties this companion knows about to integer IDs.
+     *
+     * Each companion is responsible for storing the integer IDs of all its properties. This is the
+     * only method that is allowed to modify the stored IDs.
+     *
+     * Calling {@link #readProperties(T, PropertyReader)} before calling this results in
+     * undefined behavior.
+     *
+     * @param propertyMapper A {@link PropertyMapper} maps string names to IDs.
+     */
+    void mapProperties(@NonNull PropertyMapper propertyMapper);
+
+    /**
+     * Read the values of an instance of this companion's type into a {@link PropertyReader}.
+     *
+     * This method needs to return the property IDs stored by
+     * {@link #mapProperties(PropertyMapper)}. Implementations should track if their properties
+     * have been mapped and throw a {@link UninitializedPropertyMapException} if this method is
+     * called before {mapProperties}.
+     *
+     * @param inspectable A object of type {@link T} to read the properties of.
+     * @param propertyReader An object which receives the property IDs and values.
+     */
+    void readProperties(@NonNull T inspectable, @NonNull PropertyReader propertyReader);
+
+    /**
+     * Get an optional name to display to developers for inspection nodes of this companion's type.
+     *
+     * The default implementation returns null, which will cause the runtime to use the class's
+     * simple name as defined by {@link Class#getSimpleName()} as the node name.
+     *
+     * If the type of this companion is inflated from XML, this method should be overridden to
+     * return the string used as the tag name for this type in XML.
+     *
+     * @return A string to use as the node name, or null to use the simple class name fallback.
+     */
+    @Nullable
+    default String getNodeName() {
+        return null;
+    }
+
+    /**
+     * Thrown by {@link #readProperties(Object, PropertyReader)} if called before
+     * {@link #mapProperties(PropertyMapper)}.
+     */
+    class UninitializedPropertyMapException extends RuntimeException {
+        public UninitializedPropertyMapException() {
+            super("Unable to read properties of an inspectable before mapping their IDs.");
+        }
+    }
+}
diff --git a/core/java/android/view/inspector/InspectionHelper.java b/core/java/android/view/inspector/InspectionHelper.java
deleted file mode 100644
index 27a9704..0000000
--- a/core/java/android/view/inspector/InspectionHelper.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.view.inspector;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-
-/**
- * An interface for companion objects used to inspect views.
- *
- * Inspection helpers only need to handle the properties, name and traversal of the specific class
- * they are defined for, not anything from a parent class. At runtime, the inspector instantiates
- * one instance of each inspection helper, and handles visiting them in the correct inheritance
- * order for each type it inspects.
- *
- * Properties are read from the top of the type tree to the bottom, so that classes that override
- * a property in their parent class can overwrite it in the reader. In general, properties will
- * cleanly inherit through their getters, and the inspector runtime will read the properties of a
- * parent class via the parent's inspection helper, and the child helper will only read properties
- * added or changed since the parent was defined.
- *
- * Only one child traversal is considered for each class. If a descendant class defines a
- * different child traversal than its parent, only the bottom traversal is used. If a class does
- * not define its own child traversal, but one of its ancestors does, the bottom-most ancestor's
- * traversal will be used.
- *
- * @param <T> The type of inspectable this helper operates on
- * @hide
- */
-public interface InspectionHelper<T> {
-    /**
-     * Map the string names of the properties this helper knows about to integer IDs.
-     *
-     * Each helper is responsible for storing the integer IDs of all its properties. This is the
-     * only method that is allowed to modify the stored IDs.
-     *
-     * Calling {@link #readProperties(T, PropertyReader)} before calling this results in
-     * undefined behavior.
-     *
-     * @param propertyMapper A {@link PropertyMapper} or lambda which maps string names to IDs.
-     */
-    void mapProperties(@NonNull PropertyMapper propertyMapper);
-
-    /**
-     * Read the values of an instance of this helper's type into a {@link PropertyReader}.
-     *
-     * This method needs to return the property IDs stored by
-     * {@link #mapProperties(PropertyMapper)}. Implementations should track if their properties
-     * have been mapped and throw a {@link UninitializedPropertyMapException} if this method is
-     * called before {mapProperties}.
-     *
-     * @param inspectable A object of type {@link T} to read the properties of.
-     * @param propertyReader An object which receives the property IDs and values.
-     */
-    void readProperties(@NonNull T inspectable, @NonNull PropertyReader propertyReader);
-
-    /**
-     * Query if this inspectable type can potentially have child nodes.
-     *
-     * E.g.: any descendant of {@link android.view.ViewGroup} can have child nodes, but a leaf
-     * view like {@link android.widget.ImageView} may not.
-     *
-     * The default implementation always returns false. If an implementing class overrides this, it
-     * should also define {@link #traverseChildren(T, ChildTraverser)}.
-     *
-     * @return True if this inspectable type can potentially have child nodes, false otherwise.
-     */
-    default boolean hasChildTraversal() {
-        return false;
-    }
-
-    /**
-     * Traverse the child nodes of an instance of this helper's type into a {@link ChildTraverser}.
-     *
-     * This provides the ability to traverse over a variety of collection APIs (e.g.: arrays,
-     * {@link Iterable}, or {@link java.util.Iterator}) in a uniform fashion. The traversal must be
-     * in the order defined by this helper's type. If the getter returns null, the helper must
-     * treat it as an empty collection.
-     *
-     * The default implementation throws a {@link NoChildTraversalException}. If
-     * {@link #hasChildTraversal()} returns is overriden to return true, it is expected that the
-     * implementing class will also override this method and provide a traversal.
-     *
-     * @param inspectable An object of type {@link T} to traverse the child nodes of.
-     * @param childTraverser A {@link ChildTraverser} or lamba to receive the children in order.
-     * @throws NoChildTraversalException If there is no defined child traversal
-     */
-    default void traverseChildren(
-            @NonNull T inspectable,
-            @SuppressWarnings("unused") @NonNull ChildTraverser childTraverser) {
-        throw new NoChildTraversalException(inspectable.getClass());
-    }
-
-    /**
-     * Get an optional name to display to developers for inspection nodes of this helper's type.
-     *
-     * The default implementation returns null, which will cause the runtime to use the class's
-     * simple name as defined by {@link Class#getSimpleName()} as the node name.
-     *
-     * If the type of this helper is inflated from XML, this method should be overridden to return
-     * the string used as the tag name for this type in XML.
-     *
-     * @return A string to use as the node name, or null to use the simple class name fallback.
-     */
-    @Nullable
-    default String getNodeName() {
-        return null;
-    }
-
-    /**
-     * Thrown by {@link #readProperties(Object, PropertyReader)} if called before
-     * {@link #mapProperties(PropertyMapper)}.
-     */
-    class UninitializedPropertyMapException extends RuntimeException {
-        public UninitializedPropertyMapException() {
-            super("Unable to read properties of an inspectable before mapping their IDs.");
-        }
-    }
-
-    /**
-     * Thrown by {@link #traverseChildren(Object, ChildTraverser)} if no child traversal exists.
-     */
-    class NoChildTraversalException extends RuntimeException {
-        public NoChildTraversalException(Class cls) {
-            super(String.format(
-                    "Class %s does not have a defined child traversal. Cannot traverse children.",
-                    cls.getCanonicalName()
-            ));
-        }
-    }
-}
diff --git a/core/java/android/view/inspector/IntEnumMapping.java b/core/java/android/view/inspector/IntEnumMapping.java
new file mode 100644
index 0000000..69f6dce
--- /dev/null
+++ b/core/java/android/view/inspector/IntEnumMapping.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.view.inspector;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import java.util.ArrayList;
+
+/**
+ * Maps the values of an {int} property to string names for properties that encode enumerations.
+ *
+ * An {@link InspectionCompanion} may provide an instance of this class to a {@link PropertyMapper}
+ * for enumerations packed into primitive {int} properties.
+ *
+ * This class is immutable, and must be constructed by a {@link Builder}.
+ *
+ * @see PropertyMapper#mapIntEnum(String, int, IntEnumMapping)
+ */
+public final class IntEnumMapping {
+    private final Value[] mValues;
+
+    /**
+     * Map from a property value to a string name.
+     *
+     * @param value The value of a property
+     * @return The name of the enumeration value, null if the value is not mapped
+     */
+    @Nullable
+    public String nameOf(int value) {
+        for (Value valueTuple : mValues) {
+            if (valueTuple.mValue == value) {
+                return valueTuple.mName;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Create a new instance from a builder.
+     *
+     * This constructor is private, use {@link Builder#build()} instead.
+     *
+     * @param builder A builder to create from
+     */
+    private IntEnumMapping(Builder builder) {
+        mValues = builder.mValues.toArray(new Value[builder.mValues.size()]);
+    }
+
+    /**
+     * A builder for {@link IntEnumMapping}
+     */
+    public static final class Builder {
+        private final ArrayList<Value> mValues;
+
+        public Builder() {
+            mValues = new ArrayList<>();
+        }
+
+        /**
+         * Add a new entry to this mapping.
+         *
+         * @param name Name of the enumeration value
+         * @param value Int value of the enumeration value
+         * @return This builder
+         */
+        @NonNull
+        public Builder addValue(@NonNull String name, int value) {
+            mValues.add(new Value(name, value));
+            return this;
+        }
+
+        /**
+         * Clear the builder, allowing for recycling.
+         */
+        public void clear() {
+            mValues.clear();
+        }
+
+        /**
+         * Build a new {@link IntEnumMapping} from this builder
+         *
+         * @return A new mapping
+         */
+        @NonNull
+        public IntEnumMapping build() {
+            return new IntEnumMapping(this);
+        }
+    }
+
+    /**
+     * Inner class that holds the name and value of an enumeration value.
+     */
+    private static final class Value {
+        @NonNull private final String mName;
+        private final int mValue;
+
+        private Value(@NonNull String name, int value) {
+            mName = name;
+            mValue = value;
+        }
+    }
+}
diff --git a/core/java/android/view/inspector/IntFlagMapping.java b/core/java/android/view/inspector/IntFlagMapping.java
new file mode 100644
index 0000000..dcb87e1
--- /dev/null
+++ b/core/java/android/view/inspector/IntFlagMapping.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.view.inspector;
+
+import android.annotation.NonNull;
+
+import java.util.ArrayList;
+
+/**
+ * Maps the values of an {int} property to arrays of string for properties that encode flags.
+ *
+ * An {@link InspectionCompanion} may provide an instance of this class to a {@link PropertyMapper}
+ * for flag values packed into primitive {int} properties.
+ *
+ * Each flag has a
+ *
+ * This class is immutable, and must be constructed by a {@link Builder}.
+ *
+ * @see PropertyMapper#mapIntFlag(String, int, IntFlagMapping)
+ */
+public final class IntFlagMapping {
+    private final Flag[] mFlags;
+
+    /**
+     * Get an array of the names of enabled flags for a given property value.
+     *
+     * @param value The value of the property
+     * @return The names of the enabled flags
+     */
+    @NonNull
+    public String[] namesOf(int value) {
+        ArrayList<String> enabledFlagNames = new ArrayList<>(mFlags.length);
+
+        for (Flag flag : mFlags) {
+            if (flag.isEnabledFor(value)) {
+                enabledFlagNames.add(flag.mName);
+            }
+        }
+
+        return enabledFlagNames.toArray(new String[enabledFlagNames.size()]);
+    }
+
+    /**
+     * Create a new instance from a builder.
+     *
+     * This constructor is private, use {@link Builder#build()} instead.
+     *
+     * @param builder A builder to create from
+     */
+    private IntFlagMapping(Builder builder) {
+        mFlags = builder.mFlags.toArray(new Flag[builder.mFlags.size()]);
+    }
+
+    /**
+     * A builder for {@link IntFlagMapping}.
+     */
+    public static final class Builder {
+        private ArrayList<Flag> mFlags;
+
+        public Builder() {
+            mFlags = new ArrayList<>();
+        }
+
+        /**
+         * Add a new flag without a mask.
+         *
+         * The target value will be used as a mask, to handle the common case where flag values
+         * are not mutually exclusive. The flag will be considered enabled for a property value if
+         * the result of bitwise anding the target and the value equals the target, that is:
+         * {(value & target) == target}.
+         *
+         * @param name The name of the flag
+         * @param target The value to compare against
+         * @return This builder
+         */
+        @NonNull
+        public Builder addFlag(@NonNull String name, int target) {
+            mFlags.add(new Flag(name, target, target));
+            return this;
+        }
+
+        /**
+         * Add a new flag with a mask.
+         *
+         * The flag will be considered enabled for a property value if the result of bitwise anding
+         * the value and the mask equals the target, that is: {(value & mask) == target}.
+         *
+         * @param name The name of the flag
+         * @param target The value to compare against
+         * @param mask A bit mask
+         * @return This builder
+         */
+        @NonNull
+        public Builder addFlag(@NonNull String name, int target, int mask) {
+            mFlags.add(new Flag(name, target, mask));
+            return this;
+        }
+
+        /**
+         * Clear the builder, allowing for recycling.
+         */
+        public void clear() {
+            mFlags.clear();
+        }
+
+        /**
+         * Build a new {@link IntFlagMapping} from this builder.
+         *
+         * @return A new mapping
+         */
+        @NonNull
+        public IntFlagMapping build() {
+            return new IntFlagMapping(this);
+        }
+    }
+
+    /**
+     * Inner class that holds the name, mask, and target value of a flag
+     */
+    private static final class Flag {
+        @NonNull private final String mName;
+        private final int mTarget;
+        private final int mMask;
+
+        private Flag(@NonNull String name, int target, int mask) {
+            mName = name;
+            mTarget = target;
+            mMask = mask;
+        }
+
+        /**
+         * Compare the supplied property value against the mask and taget.
+         *
+         * @param value The value to check
+         * @return True if this flag is enabled
+         */
+        private boolean isEnabledFor(int value) {
+            return (value & mMask) == mTarget;
+        }
+    }
+}
diff --git a/core/java/android/view/inspector/PropertyMapper.java b/core/java/android/view/inspector/PropertyMapper.java
index 35550bd..5fb291b 100644
--- a/core/java/android/view/inspector/PropertyMapper.java
+++ b/core/java/android/view/inspector/PropertyMapper.java
@@ -16,102 +16,160 @@
 
 package android.view.inspector;
 
+import android.annotation.AttrRes;
 import android.annotation.NonNull;
 
 /**
  * An interface for mapping the string names of inspectable properties to integer identifiers.
  *
- * This interface is consumed by {@link InspectionHelper#mapProperties(PropertyMapper)}.
+ * This interface is consumed by {@link InspectionCompanion#mapProperties(PropertyMapper)}.
  *
  * Mapping properties to IDs enables quick comparisons against shadow copies of inspectable
  * objects without performing a large number of string comparisons.
  *
- * @see InspectionHelper#mapProperties(PropertyMapper)
- * @hide
+ * @see InspectionCompanion#mapProperties(PropertyMapper)
  */
 public interface PropertyMapper {
     /**
      * Map a string name to an integer ID for a primitive boolean property.
      *
      * @param name The name of the property
+     * @param attributeId If the property is from an XML attribute, the resource ID of the property
      * @return An integer ID for the property
      * @throws PropertyConflictException If the property name is already mapped as another type.
      */
-    int mapBoolean(@NonNull String name);
+    int mapBoolean(@NonNull String name, @AttrRes int attributeId);
 
     /**
      * Map a string name to an integer ID for a primitive byte property.
      *
      * @param name The name of the property
+     * @param attributeId If the property is from an XML attribute, the resource ID of the property
      * @return An integer ID for the property
      * @throws PropertyConflictException If the property name is already mapped as another type.
      */
-    int mapByte(@NonNull String name);
+    int mapByte(@NonNull String name, @AttrRes int attributeId);
 
     /**
      * Map a string name to an integer ID for a primitive char property.
      *
      * @param name The name of the property
+     * @param attributeId If the property is from an XML attribute, the resource ID of the property
      * @return An integer ID for the property
      * @throws PropertyConflictException If the property name is already mapped as another type.
      */
-    int mapChar(@NonNull String name);
+    int mapChar(@NonNull String name, @AttrRes int attributeId);
 
     /**
      * Map a string name to an integer ID for a primitive double property.
      *
      * @param name The name of the property
+     * @param attributeId If the property is from an XML attribute, the resource ID of the property
      * @return An integer ID for the property
      * @throws PropertyConflictException If the property name is already mapped as another type.
      */
-    int mapDouble(@NonNull String name);
+    int mapDouble(@NonNull String name, @AttrRes int attributeId);
 
     /**
      * Map a string name to an integer ID for a primitive float property.
      *
      * @param name The name of the property
+     * @param attributeId If the property is from an XML attribute, the resource ID of the property
      * @return An integer ID for the property
      * @throws PropertyConflictException If the property name is already mapped as another type.
      */
-    int mapFloat(@NonNull String name);
+    int mapFloat(@NonNull String name, @AttrRes int attributeId);
 
     /**
      * Map a string name to an integer ID for a primitive int property.
      *
      * @param name The name of the property
+     * @param attributeId If the property is from an XML attribute, the resource ID of the property
      * @return An integer ID for the property
      * @throws PropertyConflictException If the property name is already mapped as another type.
      */
-    int mapInt(@NonNull String name);
+    int mapInt(@NonNull String name, @AttrRes int attributeId);
 
     /**
      * Map a string name to an integer ID for a primitive long property.
      *
      * @param name The name of the property
+     * @param attributeId If the property is from an XML attribute, the resource ID of the property
      * @return An integer ID for the property
      * @throws PropertyConflictException If the property name is already mapped as another type.
      */
-    int mapLong(@NonNull String name);
+    int mapLong(@NonNull String name, @AttrRes int attributeId);
 
     /**
      * Map a string name to an integer ID for a primitive short property.
      *
      * @param name The name of the property
+     * @param attributeId If the property is from an XML attribute, the resource ID of the property
      * @return An integer ID for the property
      * @throws PropertyConflictException If the property name is already mapped as another type.
      */
-    int mapShort(@NonNull String name);
+    int mapShort(@NonNull String name, @AttrRes int attributeId);
 
     /**
      * Map a string name to an integer ID for an object property.
      *
      * @param name The name of the property
+     * @param attributeId If the property is from an XML attribute, the resource ID of the property
      * @return An integer ID for the property
      * @throws PropertyConflictException If the property name is already mapped as another type.
      */
-    int mapObject(@NonNull String name);
+    int mapObject(@NonNull String name, @AttrRes int attributeId);
 
     /**
+     * Map a string name to an integer ID for a color property.
+     *
+     * @param name The name of the property
+     * @param attributeId If the property is from an XML attribute, the resource ID of the property
+     * @return An integer ID for the property
+     * @throws PropertyConflictException If the property name is already mapped as another type.
+     * @see android.graphics.Color
+     */
+    int mapColor(@NonNull String name, @AttrRes int attributeId);
+
+    /**
+     * Map a string name to an integer ID for a gravity property.
+     *
+     * @param name The name of the property
+     * @param attributeId If the property is from an XML attribute, the resource ID of the property
+     * @return An integer ID for the property
+     * @throws PropertyConflictException If the property name is already mapped as another type.
+     * @see android.view.Gravity
+     */
+    int mapGravity(@NonNull String name, @AttrRes int attributeId);
+
+    /**
+     * Map a string name to an integer ID for an enumeration packed into an int property.
+     *
+     * @param name The name of the property
+     * @param attributeId If the property is from an XML attribute, the resource ID of the property
+     * @param mapping A mapping from int to String
+     * @return An integer ID for the property
+     * @throws PropertyConflictException If the property name is already mapped as another type.
+     */
+    int mapIntEnum(
+            @NonNull String name,
+            @AttrRes int attributeId,
+            @NonNull IntEnumMapping mapping);
+
+    /**
+     * Map a string name to an integer ID for a flag set packed into an int property.
+     *
+     * @param name The name of the property
+     * @param attributeId If the property is from an XML attribute, the resource ID of the property
+     * @param mapping A mapping from int to an array of strings
+     * @return An integer ID for the property
+     * @throws PropertyConflictException If the property name is already mapped as another type.
+     */
+    int mapIntFlag(
+            @NonNull String name,
+            @AttrRes int attributeId,
+            @NonNull IntFlagMapping mapping);
+    /**
      * Thrown from a map method if a property name is already mapped as different type.
      */
     class PropertyConflictException extends RuntimeException {
diff --git a/core/java/android/view/inspector/PropertyReader.java b/core/java/android/view/inspector/PropertyReader.java
index df81c10..fd83e8d 100644
--- a/core/java/android/view/inspector/PropertyReader.java
+++ b/core/java/android/view/inspector/PropertyReader.java
@@ -16,19 +16,21 @@
 
 package android.view.inspector;
 
+import android.annotation.ColorInt;
+import android.annotation.ColorLong;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.graphics.Color;
 
 /**
  * An interface for reading the properties of an inspectable object.
  *
- * Used as the parameter for {@link InspectionHelper#readProperties(Object, PropertyReader)}.
+ * Used as the parameter for {@link InspectionCompanion#readProperties(Object, PropertyReader)}.
  * It has separate methods for all primitive types to avoid autoboxing overhead if a concrete
  * implementation is able to work with primitives. Implementations should be prepared to accept
  * {null} as the value of {@link PropertyReader#readObject(int, Object)}.
  *
- * @see InspectionHelper#readProperties(Object, PropertyReader)
- * @hide
+ * @see InspectionCompanion#readProperties(Object, PropertyReader)
  */
 public interface PropertyReader {
     /**
@@ -115,6 +117,60 @@
     void readObject(int id, @Nullable Object value);
 
     /**
+     * Read a color packed into a {@link ColorInt} as a property.
+     *
+     * @param id Identifier of the property from a {@link PropertyMapper}
+     * @param value Value of the property
+     * @throws PropertyTypeMismatchException If the property ID is not mapped as a color
+     */
+    void readColor(int id, @ColorInt int value);
+
+    /**
+     * Read a color packed into a {@link ColorLong} as a property.
+     *
+     * @param id Identifier of the property from a {@link PropertyMapper}
+     * @param value Value of the property
+     * @throws PropertyTypeMismatchException If the property ID is not mapped as a color
+     */
+    void readColor(int id, @ColorLong long value);
+
+    /**
+     * Read a {@link Color} object as a property.
+     *
+     * @param id Identifier of the property from a {@link PropertyMapper}
+     * @param value Value of the property
+     * @throws PropertyTypeMismatchException If the property ID is not mapped as a color
+     */
+    void readColor(int id, @Nullable Color value);
+
+    /**
+     * Read {@link android.view.Gravity} packed into an primitive {int}.
+     *
+     * @param id Identifier of the property from a {@link PropertyMapper}
+     * @param value Value of the property
+     * @throws PropertyTypeMismatchException If the property ID is not mapped as a gravity property
+     */
+    void readGravity(int id, int value);
+
+    /**
+     * Read an enumeration packed into a primitive {int}.
+     *
+     * @param id Identifier of the property from a {@link PropertyMapper}
+     * @param value Value of the property
+     * @throws PropertyTypeMismatchException If the property ID is not mapped as an object
+     */
+    void readIntEnum(int id, int value);
+
+    /**
+     * Read a flag packed into a primitive {int}.
+     *
+     * @param id Identifier of the property from a {@link PropertyMapper}
+     * @param value Value of the property
+     * @throws PropertyTypeMismatchException If the property ID is not mapped as an object
+     */
+    void readIntFlag(int id, int value);
+
+    /**
      * Thrown if a client calls a typed read method for a property of a different type.
      */
     class PropertyTypeMismatchException extends RuntimeException {
diff --git a/core/java/android/view/intelligence/ContentCaptureEvent.java b/core/java/android/view/intelligence/ContentCaptureEvent.java
index befcb55..f636281 100644
--- a/core/java/android/view/intelligence/ContentCaptureEvent.java
+++ b/core/java/android/view/intelligence/ContentCaptureEvent.java
@@ -163,7 +163,7 @@
      * Gets optional flags associated with the event.
      *
      * @return either {@code 0} or
-     * {@link android.view.intelligence.IntelligenceManager#FLAG_USER_INPUT}.
+     * {@link android.view.intelligence.ContentCaptureManager#FLAG_USER_INPUT}.
      */
     public int getFlags() {
         return mFlags;
diff --git a/core/java/android/view/intelligence/IntelligenceManager.java b/core/java/android/view/intelligence/ContentCaptureManager.java
similarity index 77%
rename from core/java/android/view/intelligence/IntelligenceManager.java
rename to core/java/android/view/intelligence/ContentCaptureManager.java
index 2f3b4ef..45518d5 100644
--- a/core/java/android/view/intelligence/IntelligenceManager.java
+++ b/core/java/android/view/intelligence/ContentCaptureManager.java
@@ -23,7 +23,6 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.content.ComponentName;
 import android.content.Context;
@@ -44,13 +43,8 @@
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
 
-/**
- * TODO(b/111276913): add javadocs / implement
- */
 /*
  * NOTE: all methods in this class should return right away, or do the real work in a handler
  * thread.
@@ -58,10 +52,13 @@
  * Hence, the only field that must be thread-safe is mEnabled, which is called at the beginning
  * of every method.
  */
-@SystemService(Context.INTELLIGENCE_MANAGER_SERVICE)
-public final class IntelligenceManager {
+/**
+ * TODO(b/111276913): add javadocs / implement
+ */
+@SystemService(Context.CONTENT_CAPTURE_MANAGER_SERVICE)
+public final class ContentCaptureManager {
 
-    private static final String TAG = "IntelligenceManager";
+    private static final String TAG = "ContentCaptureManager";
 
     // TODO(b/111276913): define a way to dynamically set them(for example, using settings?)
     private static final boolean VERBOSE = false;
@@ -140,7 +137,7 @@
     private final Handler mHandler;
 
     /** @hide */
-    public IntelligenceManager(@NonNull Context context, @Nullable IIntelligenceManager service) {
+    public ContentCaptureManager(@NonNull Context context, @Nullable IIntelligenceManager service) {
         mContext = Preconditions.checkNotNull(context, "context cannot be null");
         if (VERBOSE) {
             Log.v(TAG, "Constructor for " + context.getPackageName());
@@ -156,7 +153,7 @@
     public void onActivityCreated(@NonNull IBinder token, @NonNull ComponentName componentName) {
         if (!isContentCaptureEnabled()) return;
 
-        mHandler.sendMessage(obtainMessage(IntelligenceManager::handleStartSession, this,
+        mHandler.sendMessage(obtainMessage(ContentCaptureManager::handleStartSession, this,
                 token, componentName));
     }
 
@@ -192,7 +189,7 @@
         }
     }
 
-    private  void handleSessionStarted(int resultCode) {
+    private void handleSessionStarted(int resultCode) {
         mState = resultCode;
         mDisabled.set(mState == STATE_DISABLED);
         if (VERBOSE) {
@@ -264,7 +261,7 @@
             Log.v(TAG, "onActivityLifecycleEvent() for " + getActivityDebugName()
                     + ": " + ContentCaptureEvent.getTypeAsString(type));
         }
-        mHandler.sendMessage(obtainMessage(IntelligenceManager::handleSendEvent, this,
+        mHandler.sendMessage(obtainMessage(ContentCaptureManager::handleSendEvent, this,
                 new ContentCaptureEvent(type), /* forceFlush= */ true));
     }
 
@@ -279,7 +276,7 @@
                     + ", mId=" + mId);
         }
 
-        mHandler.sendMessage(obtainMessage(IntelligenceManager::handleFinishSession, this));
+        mHandler.sendMessage(obtainMessage(ContentCaptureManager::handleFinishSession, this));
     }
 
     private void handleFinishSession() {
@@ -328,7 +325,7 @@
             throw new IllegalArgumentException("Invalid node class: " + node.getClass());
         }
 
-        mHandler.sendMessage(obtainMessage(IntelligenceManager::handleSendEvent, this,
+        mHandler.sendMessage(obtainMessage(ContentCaptureManager::handleSendEvent, this,
                 new ContentCaptureEvent(TYPE_VIEW_APPEARED)
                         .setViewNode(((ViewNode.ViewStructureImpl) node).mNode),
                         /* forceFlush= */ false));
@@ -346,7 +343,7 @@
         Preconditions.checkNotNull(id);
         if (!isContentCaptureEnabled()) return;
 
-        mHandler.sendMessage(obtainMessage(IntelligenceManager::handleSendEvent, this,
+        mHandler.sendMessage(obtainMessage(ContentCaptureManager::handleSendEvent, this,
                 new ContentCaptureEvent(TYPE_VIEW_DISAPPEARED).setAutofillId(id),
                         /* forceFlush= */ false));
     }
@@ -365,7 +362,7 @@
 
         if (!isContentCaptureEnabled()) return;
 
-        mHandler.sendMessage(obtainMessage(IntelligenceManager::handleSendEvent, this,
+        mHandler.sendMessage(obtainMessage(ContentCaptureManager::handleSendEvent, this,
                 new ContentCaptureEvent(TYPE_VIEW_TEXT_CHANGED, flags).setAutofillId(id)
                         .setText(text), /* forceFlush= */ false));
     }
@@ -396,11 +393,11 @@
     }
 
     /**
-     * Returns the component name of the {@code android.service.intelligence.IntelligenceService}
-     * that is enabled for the current user.
+     * Returns the component name of the system service that is consuming the captured events for
+     * the current user.
      */
     @Nullable
-    public ComponentName getIntelligenceServiceComponentName() {
+    public ComponentName getServiceComponentName() {
         //TODO(b/111276913): implement
         return null;
     }
@@ -422,106 +419,6 @@
         //TODO(b/111276913): implement
     }
 
-    /**
-     * Called by the the service {@link android.service.intelligence.IntelligenceService}
-     * to define whether content capture should be enabled for activities with such
-     * {@link android.content.ComponentName}.
-     *
-     * <p>Useful to blacklist a particular activity.
-     *
-     * @throws UnsupportedOperationException if not called by the UID that owns the
-     * {@link android.service.intelligence.IntelligenceService} associated with the
-     * current user.
-     *
-     * @hide
-     */
-    @SystemApi
-    public void setActivityContentCaptureEnabled(@NonNull ComponentName activity,
-            boolean enabled) {
-        //TODO(b/111276913): implement
-    }
-
-    /**
-     * Called by the the service {@link android.service.intelligence.IntelligenceService}
-     * to explicitly limit content capture to the given packages and activities.
-     *
-     * <p>When the whitelist is set, it overrides the values passed to
-     * {@link #setActivityContentCaptureEnabled(ComponentName, boolean)}
-     * and {@link #setPackageContentCaptureEnabled(String, boolean)}.
-     *
-     * <p>To reset the whitelist, call it passing {@code null} to both arguments.
-     *
-     * <p>Useful when the service wants to restrict content capture to a category of apps, like
-     * chat apps. For example, if the service wants to support view captures on all activities of
-     * app {@code ChatApp1} and just activities {@code act1} and {@code act2} of {@code ChatApp2},
-     * it would call: {@code setContentCaptureWhitelist(Arrays.asList("ChatApp1"),
-     * Arrays.asList(new ComponentName("ChatApp2", "act1"),
-     * new ComponentName("ChatApp2", "act2")));}
-     *
-     * @throws UnsupportedOperationException if not called by the UID that owns the
-     * {@link android.service.intelligence.IntelligenceService} associated with the
-     * current user.
-     *
-     * @hide
-     */
-    @SystemApi
-    public void setContentCaptureWhitelist(@Nullable List<String> packages,
-            @Nullable List<ComponentName> activities) {
-        //TODO(b/111276913): implement
-    }
-
-    /**
-     * Called by the the service {@link android.service.intelligence.IntelligenceService}
-     * to define whether content capture should be enabled for activities of the app with such
-     * {@code packageName}.
-     *
-     * <p>Useful to blacklist any activity from a particular app.
-     *
-     * @throws UnsupportedOperationException if not called by the UID that owns the
-     * {@link android.service.intelligence.IntelligenceService} associated with the
-     * current user.
-     *
-     * @hide
-     */
-    @SystemApi
-    public void setPackageContentCaptureEnabled(@NonNull String packageName, boolean enabled) {
-        //TODO(b/111276913): implement
-    }
-
-    /**
-     * Gets the activities where content capture was disabled by
-     * {@link #setActivityContentCaptureEnabled(ComponentName, boolean)}.
-     *
-     * @throws UnsupportedOperationException if not called by the UID that owns the
-     * {@link android.service.intelligence.IntelligenceService} associated with the
-     * current user.
-     *
-     * @hide
-     */
-    @SystemApi
-    @NonNull
-    public Set<ComponentName> getContentCaptureDisabledActivities() {
-        //TODO(b/111276913): implement
-        return null;
-    }
-
-    /**
-     * Gets the apps where content capture was disabled by
-     * {@link #setPackageContentCaptureEnabled(String, boolean)}.
-     *
-     * @throws UnsupportedOperationException if not called by the UID that owns the
-     * {@link android.service.intelligence.IntelligenceService} associated with the
-     * current user.
-     *
-     * @hide
-     */
-    @SystemApi
-    @NonNull
-    public Set<String> getContentCaptureDisabledPackages() {
-        //TODO(b/111276913): implement
-        return null;
-    }
-
     /** @hide */
     public void dump(String prefix, PrintWriter pw) {
         pw.print(prefix); pw.println("IntelligenceManager");
@@ -547,7 +444,7 @@
         }
         if (mEvents != null) {
             final int numberEvents = mEvents.size();
-            pw.print(prefix2); pw.print("batched events: "); pw.print(numberEvents);
+            pw.print(prefix2); pw.print("buffered events: "); pw.print(numberEvents);
             pw.print('/'); pw.println(MAX_BUFFER_SIZE);
             if (VERBOSE && numberEvents > 0) {
                 final String prefix3 = prefix2 + "  ";
diff --git a/core/java/android/view/intelligence/IIntelligenceManager.aidl b/core/java/android/view/intelligence/IIntelligenceManager.aidl
index 7518ff5..882fb26 100644
--- a/core/java/android/view/intelligence/IIntelligenceManager.aidl
+++ b/core/java/android/view/intelligence/IIntelligenceManager.aidl
@@ -28,6 +28,7 @@
 /**
  * {@hide}
  */
+// TODO(b/111276913): rename once the final name is defined
 oneway interface IIntelligenceManager {
     /**
       * Starts a session, sending the "remote" sessionId to the receiver.
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 1deee8a..085f8f1 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -166,7 +166,7 @@
 import android.view.inputmethod.ExtractedTextRequest;
 import android.view.inputmethod.InputConnection;
 import android.view.inputmethod.InputMethodManager;
-import android.view.intelligence.IntelligenceManager;
+import android.view.intelligence.ContentCaptureManager;
 import android.view.textclassifier.TextClassification;
 import android.view.textclassifier.TextClassificationContext;
 import android.view.textclassifier.TextClassificationManager;
@@ -10135,7 +10135,7 @@
     }
 
     /**
-     * Notify managers (such as {@link AutofillManager} and {@link IntelligenceManager}) that are
+     * Notify managers (such as {@link AutofillManager} and {@link ContentCaptureManager}) that are
      * interested on text changes.
      */
     private void notifyListeningManagersAfterTextChanged() {
@@ -10155,10 +10155,10 @@
 
         // ContentCapture
         if (isImportantForContentCapture() && isTextEditable()) {
-            final IntelligenceManager im = mContext.getSystemService(IntelligenceManager.class);
-            if (im != null && im.isContentCaptureEnabled()) {
+            final ContentCaptureManager cm = mContext.getSystemService(ContentCaptureManager.class);
+            if (cm != null && cm.isContentCaptureEnabled()) {
                 // TODO(b/111276913): pass flags when edited by user / add CTS test
-                im.notifyViewTextChanged(getAutofillId(), getText(), /* flags= */ 0);
+                cm.notifyViewTextChanged(getAutofillId(), getText(), /* flags= */ 0);
             }
         }
     }
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 488b991..d8ee643 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -91,6 +91,7 @@
 import android.view.ViewRootImpl;
 import android.view.ViewRootImpl.ActivityConfigCallback;
 import android.view.Window;
+import android.view.WindowInsetsController;
 import android.view.WindowManager;
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
@@ -3877,4 +3878,9 @@
             mDecor.updateLogTag(params);
         }
     }
+
+    @Override
+    public WindowInsetsController getInsetsController() {
+        return mDecor.getWindowInsetsController();
+    }
 }
diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java
index 36fe4fc..c8834a8 100644
--- a/core/java/com/android/internal/view/BaseIWindow.java
+++ b/core/java/com/android/internal/view/BaseIWindow.java
@@ -27,6 +27,7 @@
 import android.view.IWindow;
 import android.view.IWindowSession;
 import android.view.PointerIcon;
+import android.view.InsetsSourceControl;
 import android.view.InsetsState;
 
 import com.android.internal.os.IResultReceiver;
@@ -58,6 +59,11 @@
     }
 
     @Override
+    public void insetsControlChanged(InsetsState insetsState,
+            InsetsSourceControl[] activeControls) throws RemoteException {
+    }
+
+    @Override
     public void moved(int newX, int newY) {
     }
 
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index bdd5f83..31bb1d5 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -34,7 +34,6 @@
     ],
 
     cppflags: ["-Wno-conversion-null"],
-    cpp_std: "c++17",
 
     srcs: [
         "AndroidRuntime.cpp",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index bc1d5cc..f9879cc 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -1056,12 +1056,18 @@
     if (rootDir == NULL) {
         rootDir = "/system";
         if (!hasDir("/system")) {
-            LOG_FATAL("No root directory specified, and /android does not exist.");
+            LOG_FATAL("No root directory specified, and /system does not exist.");
             return;
         }
         setenv("ANDROID_ROOT", rootDir, 1);
     }
 
+    const char* runtimeRootDir = getenv("ANDROID_RUNTIME_ROOT");
+    if (runtimeRootDir == NULL) {
+        LOG_FATAL("No runtime directory specified with ANDROID_RUNTIME_ROOT environment variable.");
+        return;
+    }
+
     //const char* kernelHack = getenv("LD_ASSUME_KERNEL");
     //ALOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack);
 
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
index 1ea4ed1..12a8343b4 100644
--- a/core/jni/android_media_AudioRecord.cpp
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -842,6 +842,18 @@
 }
 
 // ----------------------------------------------------------------------------
+static jint android_media_AudioRecord_get_port_id(JNIEnv *env,  jobject thiz) {
+    sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz);
+    if (lpRecorder == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                          "Unable to retrieve AudioRecord pointer for getId()");
+        return (jint)AUDIO_PORT_HANDLE_NONE;
+    }
+    return (jint)lpRecorder->getPortId();
+}
+
+
+// ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 static const JNINativeMethod gMethods[] = {
     // name,               signature,  funcPtr
@@ -883,6 +895,7 @@
                                        (void *)android_media_AudioRecord_get_timestamp},
     {"native_get_active_microphones", "(Ljava/util/ArrayList;)I",
                                         (void *)android_media_AudioRecord_get_active_microphones},
+    {"native_getPortId", "()I", (void *)android_media_AudioRecord_get_port_id},
 };
 
 // field names found in android/media/AudioRecord.java
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index 04f0a53..d927972 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -1284,6 +1284,17 @@
 }
 
 // ----------------------------------------------------------------------------
+static jint android_media_AudioTrack_get_port_id(JNIEnv *env,  jobject thiz) {
+    sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
+    if (lpTrack == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                          "AudioTrack not initialized");
+        return (jint)AUDIO_PORT_HANDLE_NONE;
+    }
+    return (jint)lpTrack->getPortId();
+}
+
+// ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 static const JNINativeMethod gMethods[] = {
     // name,              signature,     funcPtr
@@ -1354,6 +1365,7 @@
             "(I)Landroid/media/VolumeShaper$State;",
                                         (void *)android_media_AudioTrack_get_volume_shaper_state},
     {"native_setPresentation", "(II)I", (void *)android_media_AudioTrack_setPresentation},
+    {"native_getPortId", "()I", (void *)android_media_AudioTrack_get_port_id},
 };
 
 
@@ -1379,7 +1391,6 @@
     }
 }
 
-
 // ----------------------------------------------------------------------------
 int register_android_media_AudioTrack(JNIEnv *env)
 {
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index b465fb4..0e052fe 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -234,10 +234,14 @@
     }
     optional Location location = 31;
 
+    // How frequently will the user be reminded about location permission grants
     message LocationAccessCheck {
         option (android.msg_privacy).dest = DEST_EXPLICIT;
 
+        // Time in between periodic checks
         optional SettingProto interval_millis = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+
+        // Time in between the user granting a location permission and a check
         optional SettingProto delay_millis = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
     }
     optional LocationAccessCheck location_access_check = 73;
diff --git a/core/proto/android/service/runtime.proto b/core/proto/android/service/runtime.proto
new file mode 100644
index 0000000..ecbccef
--- /dev/null
+++ b/core/proto/android/service/runtime.proto
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+package android.service.runtime;
+
+import "frameworks/base/libs/incident/proto/android/privacy.proto";
+
+option java_multiple_files = true;
+option java_outer_classname = "RuntimeServiceProto";
+
+// Represents dumpsys info from RuntimeService.
+message RuntimeServiceInfoProto {
+  option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+  // Generic debug information to include.
+  repeated DebugEntryProto debug_entry = 1;
+}
+
+// A piece of key / value debug information.
+message DebugEntryProto {
+  option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+  optional string key = 1;
+
+  optional string string_value = 2;
+}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index b4d5f67..83f3057 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -3047,12 +3047,12 @@
     <permission android:name="android.permission.BIND_TEXTCLASSIFIER_SERVICE"
                 android:protectionLevel="signature" />
 
-    <!-- Must be required by a android.service.intelligence.IntelligenceService,
+    <!-- Must be required by a android.service.intelligence.SmartSuggestionsService,
          to ensure that only the system can bind to it.
          @SystemApi @hide This is not a third-party API (intended for OEMs and system apps).
          <p>Protection level: signature
     -->
-    <permission android:name="android.permission.BIND_INTELLIGENCE_SERVICE"
+    <permission android:name="android.permission.BIND_SMART_SUGGESTIONS_SERVICE"
                 android:protectionLevel="signature" />
 
     <!-- Must be required by hotword enrollment application,
@@ -4611,6 +4611,13 @@
             </intent-filter>
         </receiver>
 
+        <receiver android:name="com.android.server.WallpaperUpdateReceiver"
+                  android:permission="android.permission.RECEIVE_DEVICE_CUSTOMIZATION_READY">
+            <intent-filter>
+                <action android:name="android.intent.action.DEVICE_CUSTOMIZATION_READY"/>
+            </intent-filter>
+        </receiver>
+
         <service android:name="android.hardware.location.GeofenceHardwareService"
             android:permission="android.permission.LOCATION_HARDWARE"
             android:exported="false" />
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 2447289..f55e48e 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1915,6 +1915,9 @@
         <enum name="KEYCODE_SYSTEM_NAVIGATION_RIGHT" value="283" />
         <enum name="KEYCODE_ALL_APPS" value="284" />
         <enum name="KEYCODE_REFRESH" value="285" />
+        <enum name="KEYCODE_THUMBS_UP" value="286" />
+        <enum name="KEYCODE_THUMBS_DOWN" value="287" />
+        <enum name="KEYCODE_PROFILE_SWITCH" value="288" />
     </attr>
 
     <!-- ***************************************************************** -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 1d80961..0cd6bc5 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2125,6 +2125,9 @@
          during initialization when the setting is still null. -->
     <bool name="config_dozeAlwaysOnEnabled">true</bool>
 
+    <!-- If AOD can show an ambient version of the wallpaper -->
+    <bool name="config_dozeSupportsAodWallpaper">true</bool>
+
     <!-- Whether the display blanks itself when transitioning from a doze to a non-doze state -->
     <bool name="config_displayBlanksAfterDoze">false</bool>
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 783f1f3..01422c8 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3310,6 +3310,7 @@
   <java-symbol type="integer" name="config_autoGroupAtCount" />
   <java-symbol type="bool" name="config_dozeAlwaysOnDisplayAvailable" />
   <java-symbol type="bool" name="config_dozeAlwaysOnEnabled" />
+  <java-symbol type="bool" name="config_dozeSupportsAodWallpaper" />
   <java-symbol type="bool" name="config_displayBlanksAfterDoze" />
   <java-symbol type="bool" name="config_displayBrightnessBucketsInDoze" />
   <java-symbol type="integer" name="config_storageManagerDaystoRetainDefault" />
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index 3b650e5..46d4a47 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -91,6 +91,8 @@
     <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
     <uses-permission android:name="android.permission.KILL_UID" />
 
+    <uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" />
+
     <!-- location test permissions -->
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
     <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"/>
diff --git a/core/tests/coretests/src/android/os/RedactingFileDescriptorTest.java b/core/tests/coretests/src/android/os/RedactingFileDescriptorTest.java
index c8bc35c..9e15231 100644
--- a/core/tests/coretests/src/android/os/RedactingFileDescriptorTest.java
+++ b/core/tests/coretests/src/android/os/RedactingFileDescriptorTest.java
@@ -16,6 +16,10 @@
 
 package android.os;
 
+import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
+import static android.os.ParcelFileDescriptor.MODE_READ_WRITE;
+import static android.os.RedactingFileDescriptor.removeRange;
+
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 
@@ -58,8 +62,8 @@
 
     @Test
     public void testSingleByte() throws Exception {
-        final FileDescriptor fd = RedactingFileDescriptor
-                .open(mContext, mFile, new long[] { 10, 11 }).getFileDescriptor();
+        final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_ONLY,
+                new long[] { 10, 11 }).getFileDescriptor();
 
         final byte[] buf = new byte[1_000];
         assertEquals(buf.length, Os.read(fd, buf, 0, buf.length));
@@ -74,8 +78,8 @@
 
     @Test
     public void testRanges() throws Exception {
-        final FileDescriptor fd = RedactingFileDescriptor
-                .open(mContext, mFile, new long[] { 100, 200, 300, 400 }).getFileDescriptor();
+        final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_ONLY,
+                new long[] { 100, 200, 300, 400 }).getFileDescriptor();
 
         final byte[] buf = new byte[10];
         assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 90));
@@ -96,8 +100,8 @@
 
     @Test
     public void testEntireFile() throws Exception {
-        final FileDescriptor fd = RedactingFileDescriptor
-                .open(mContext, mFile, new long[] { 0, 5_000_000 }).getFileDescriptor();
+        final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_ONLY,
+                new long[] { 0, 5_000_000 }).getFileDescriptor();
 
         try (FileInputStream in = new FileInputStream(fd)) {
             int val;
@@ -106,4 +110,61 @@
             }
         }
     }
+
+    @Test
+    public void testReadWrite() throws Exception {
+        final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_WRITE,
+                new long[] { 100, 200, 300, 400 }).getFileDescriptor();
+
+        // Redacted at first
+        final byte[] buf = new byte[10];
+        assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 95));
+        assertArrayEquals(new byte[] { 64, 64, 64, 64, 64, 0, 0, 0, 0, 0 }, buf);
+
+        // But we can see data that we've written
+        Os.pwrite(fd, new byte[] { 32, 32 }, 0, 2, 102);
+        assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 95));
+        assertArrayEquals(new byte[] { 64, 64, 64, 64, 64, 0, 0, 32, 32, 0 }, buf);
+    }
+
+    @Test
+    public void testRemoveRange() throws Exception {
+        // Removing outside ranges should have no changes
+        assertArrayEquals(new long[] { 100, 200, 300, 400 },
+                removeRange(new long[] { 100, 200, 300, 400 }, 0, 100));
+        assertArrayEquals(new long[] { 100, 200, 300, 400 },
+                removeRange(new long[] { 100, 200, 300, 400 }, 200, 300));
+        assertArrayEquals(new long[] { 100, 200, 300, 400 },
+                removeRange(new long[] { 100, 200, 300, 400 }, 400, 500));
+
+        // Removing full regions
+        assertArrayEquals(new long[] { 100, 200 },
+                removeRange(new long[] { 100, 200, 300, 400 }, 300, 400));
+        assertArrayEquals(new long[] { 100, 200 },
+                removeRange(new long[] { 100, 200, 300, 400 }, 250, 450));
+        assertArrayEquals(new long[] { 300, 400 },
+                removeRange(new long[] { 100, 200, 300, 400 }, 50, 250));
+        assertArrayEquals(new long[] { },
+                removeRange(new long[] { 100, 200, 300, 400 }, 0, 5_000_000));
+    }
+
+    @Test
+    public void testRemoveRange_Partial() throws Exception {
+        assertArrayEquals(new long[] { 150, 200, 300, 400 },
+                removeRange(new long[] { 100, 200, 300, 400 }, 50, 150));
+        assertArrayEquals(new long[] { 100, 150, 300, 400 },
+                removeRange(new long[] { 100, 200, 300, 400 }, 150, 250));
+        assertArrayEquals(new long[] { 100, 150, 350, 400 },
+                removeRange(new long[] { 100, 200, 300, 400 }, 150, 350));
+        assertArrayEquals(new long[] { 100, 150 },
+                removeRange(new long[] { 100, 200, 300, 400 }, 150, 500));
+    }
+
+    @Test
+    public void testRemoveRange_Hole() throws Exception {
+        assertArrayEquals(new long[] { 100, 125, 175, 200, 300, 400 },
+                removeRange(new long[] { 100, 200, 300, 400 }, 125, 175));
+        assertArrayEquals(new long[] { 100, 200 },
+                removeRange(new long[] { 100, 200 }, 150, 150));
+    }
 }
diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java
new file mode 100644
index 0000000..ed80cd7
--- /dev/null
+++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.view;
+
+import static android.view.InsetsState.TYPE_TOP_BAR;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNull;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.FlakyTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@Presubmit
+@FlakyTest(detail = "Promote once confirmed non-flaky")
+@RunWith(AndroidJUnit4.class)
+public class InsetsControllerTest {
+
+    private InsetsController mController = new InsetsController();
+
+    private SurfaceSession mSession = new SurfaceSession();
+    private SurfaceControl mLeash;
+
+    @Before
+    public void setup() {
+        mLeash = new SurfaceControl.Builder(mSession)
+                .setName("testSurface")
+                .build();
+    }
+
+    @Test
+    public void testControlsChanged() {
+        InsetsSourceControl control = new InsetsSourceControl(TYPE_TOP_BAR, mLeash);
+        mController.onControlsChanged(new InsetsSourceControl[] { control });
+        assertEquals(mLeash,
+                mController.getSourceConsumer(TYPE_TOP_BAR).getControl().getLeash());
+    }
+
+    @Test
+    public void testControlsRevoked() {
+        InsetsSourceControl control = new InsetsSourceControl(TYPE_TOP_BAR, mLeash);
+        mController.onControlsChanged(new InsetsSourceControl[] { control });
+        mController.onControlsChanged(new InsetsSourceControl[0]);
+        assertNull(mController.getSourceConsumer(TYPE_TOP_BAR).getControl());
+    }
+}
diff --git a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
new file mode 100644
index 0000000..5a20ba2
--- /dev/null
+++ b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.view;
+
+import static android.view.InsetsState.TYPE_TOP_BAR;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.FlakyTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.SurfaceControl.Transaction;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@Presubmit
+@FlakyTest(detail = "Promote once confirmed non-flaky")
+@RunWith(AndroidJUnit4.class)
+public class InsetsSourceConsumerTest {
+
+    private InsetsSourceConsumer mConsumer;
+
+    private SurfaceSession mSession = new SurfaceSession();
+    private SurfaceControl mLeash;
+    @Mock Transaction mMockTransaction;
+    @Mock InsetsController mMockController;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        mLeash = new SurfaceControl.Builder(mSession)
+                .setName("testSurface")
+                .build();
+        mConsumer = new InsetsSourceConsumer(TYPE_TOP_BAR, new InsetsState(),
+                () -> mMockTransaction);
+        mConsumer.setControl(new InsetsSourceControl(TYPE_TOP_BAR, mLeash));
+    }
+
+    @Test
+    public void testHide() {
+        mConsumer.hide();
+        verify(mMockTransaction).hide(eq(mLeash));
+    }
+
+    @Test
+    public void testShow() {
+        mConsumer.hide();
+        mConsumer.show();
+        verify(mMockTransaction, atLeastOnce()).show(eq(mLeash));
+    }
+
+    @Test
+    public void testRestore() {
+        mConsumer.setControl(null);
+        reset(mMockTransaction);
+        mConsumer.hide();
+        verifyZeroInteractions(mMockTransaction);
+        mConsumer.setControl(new InsetsSourceControl(TYPE_TOP_BAR, mLeash));
+        verify(mMockTransaction).hide(eq(mLeash));
+    }
+}
diff --git a/graphics/java/android/graphics/ColorSpace.java b/graphics/java/android/graphics/ColorSpace.java
index bf114b9..2227cf5 100644
--- a/graphics/java/android/graphics/ColorSpace.java
+++ b/graphics/java/android/graphics/ColorSpace.java
@@ -1779,6 +1779,36 @@
     }
 
     /**
+     * <p>Computes the chromaticity coordinates of a CIE series D illuminant
+     * from the specified correlated color temperature (CCT). The specified CCT
+     * must be greater than 0. A meaningful CCT range is [4000, 25000].</p>
+     *
+     * <p>The transform is computed using the methods referred to in Kang et
+     * al., <i>Design of Advanced Color - Temperature Control System for HDTV
+     * Applications</i>, Journal of Korean Physical Society 41, 865-871
+     * (2002).</p>
+     *
+     * @param cct The correlated color temperature, in Kelvin
+     * @return Corresponding XYZ values
+     * @throws IllegalArgumentException If cct is invalid
+     */
+    @NonNull
+    @Size(3)
+    public static float[] cctToIlluminantdXyz(@IntRange(from = 1) int cct) {
+        if (cct < 1) {
+            throw new IllegalArgumentException("Temperature must be greater than 0");
+        }
+
+        final float icct = 1.0f / cct;
+        final float icct2 = icct * icct;
+        final float x = cct <= 7000.0f ?
+            0.244063f + 0.09911e3f * icct + 2.9678e6f * icct2 - 4.6070e9f * icct2 * icct :
+            0.237040f + 0.24748e3f * icct + 1.9018e6f * icct2 - 2.0064e9f * icct2 * icct;
+        final float y = -3.0f * x * x + 2.87f * x - 0.275f;
+        return xyYToXyz(new float[] {x, y});
+    }
+
+    /**
      * <p>Computes the chromatic adaptation transform from the specified
      * source white point to the specified destination white point.</p>
      *
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index dbe6e8f..9b86b77 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -249,7 +249,22 @@
             if (familyBuilder == null) {
                 return Typeface.DEFAULT;
             }
-            typeface = new Typeface.CustomFallbackBuilder(familyBuilder.build()).build();
+            final FontFamily family = familyBuilder.build();
+            final FontStyle normal = new FontStyle(FontStyle.FONT_WEIGHT_NORMAL,
+                    FontStyle.FONT_SLANT_UPRIGHT);
+            Font bestFont = family.getFont(0);
+            int bestScore = normal.getMatchScore(bestFont.getStyle());
+            for (int i = 1; i < family.getSize(); ++i) {
+                final Font candidate = family.getFont(i);
+                final int score = normal.getMatchScore(candidate.getStyle());
+                if (score < bestScore) {
+                    bestFont = candidate;
+                    bestScore = score;
+                }
+            }
+            typeface = new Typeface.CustomFallbackBuilder(family)
+                    .setStyle(bestFont.getStyle())
+                    .build();
         } catch (IOException e) {
             typeface = Typeface.DEFAULT;
         }
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 8740234..991847a 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -1571,15 +1571,32 @@
         st.mGradient = a.getInt(
                 R.styleable.GradientDrawableGradient_type, st.mGradient);
 
-        // TODO: Update these to be themeable.
+        final boolean hasGradientColors = st.mGradientColors != null;
+        final boolean hasGradientCenter = st.hasCenterColor();
+        final int prevStart = hasGradientColors ? st.mGradientColors[0] : 0;
+        final int prevCenter = hasGradientCenter ? st.mGradientColors[1] : 0;
+        final int prevEnd;
+
+        if (st.hasCenterColor()) {
+            // if there is a center color, the end color is the last of the 3 values
+            prevEnd = st.mGradientColors[2];
+        } else if (hasGradientColors) {
+            // if there is not a center color but there are already colors configured, then
+            // the end color is the 2nd value in the array
+            prevEnd = st.mGradientColors[1];
+        } else {
+            // otherwise, there isn't a previously configured end color
+            prevEnd = 0;
+        }
+
         final int startColor = a.getColor(
-                R.styleable.GradientDrawableGradient_startColor, 0);
+                R.styleable.GradientDrawableGradient_startColor, prevStart);
         final boolean hasCenterColor = a.hasValue(
-                R.styleable.GradientDrawableGradient_centerColor);
+                R.styleable.GradientDrawableGradient_centerColor) || hasGradientCenter;
         final int centerColor = a.getColor(
-                R.styleable.GradientDrawableGradient_centerColor, 0);
+                R.styleable.GradientDrawableGradient_centerColor, prevCenter);
         final int endColor = a.getColor(
-                R.styleable.GradientDrawableGradient_endColor, 0);
+                R.styleable.GradientDrawableGradient_endColor, prevEnd);
 
         if (hasCenterColor) {
             st.mGradientColors = new int[3];
@@ -1943,6 +1960,10 @@
             }
         }
 
+        public boolean hasCenterColor() {
+            return mGradientColors != null && mGradientColors.length == 3;
+        }
+
         private void applyDensityScaling(int sourceDensity, int targetDensity) {
             if (mInnerRadius > 0) {
                 mInnerRadius = Drawable.scaleFromDensity(
diff --git a/graphics/java/android/graphics/fonts/FontStyle.java b/graphics/java/android/graphics/fonts/FontStyle.java
index 82fc7ac..af517d6 100644
--- a/graphics/java/android/graphics/fonts/FontStyle.java
+++ b/graphics/java/android/graphics/fonts/FontStyle.java
@@ -18,6 +18,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.IntRange;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 
 import com.android.internal.util.Preconditions;
@@ -232,6 +233,16 @@
         return mSlant;
     }
 
+    /**
+     * Compute the matching score for another style.
+     *
+     * The smaller is better.
+     * @hide
+     */
+    public int getMatchScore(@NonNull FontStyle o) {
+        return Math.abs((getWeight() - o.getWeight())) / 100 + (getSlant() == o.getSlant() ? 0 : 2);
+    }
+
     @Override
     public boolean equals(@Nullable Object o) {
         if (o == this) {
diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp
index 7ab12b1..ad9ec02 100644
--- a/libs/androidfw/AssetManager2.cpp
+++ b/libs/androidfw/AssetManager2.cpp
@@ -217,10 +217,19 @@
   ATRACE_NAME("AssetManager::GetResourceConfigurations");
   std::set<ResTable_config> configurations;
   for (const PackageGroup& package_group : package_groups_) {
+    bool found_system_package = false;
     for (const ConfiguredPackage& package : package_group.packages_) {
       if (exclude_system && package.loaded_package_->IsSystem()) {
+        found_system_package = true;
         continue;
       }
+
+      if (exclude_system && package.loaded_package_->IsOverlay() && found_system_package) {
+        // Overlays must appear after the target package to take effect. Any overlay found in the
+        // same package as a system package is able to overlay system resources.
+        continue;
+      }
+
       package.loaded_package_->CollectConfigurations(exclude_mipmap, &configurations);
     }
   }
@@ -232,10 +241,19 @@
   ATRACE_NAME("AssetManager::GetResourceLocales");
   std::set<std::string> locales;
   for (const PackageGroup& package_group : package_groups_) {
+    bool found_system_package = false;
     for (const ConfiguredPackage& package : package_group.packages_) {
       if (exclude_system && package.loaded_package_->IsSystem()) {
+        found_system_package = true;
         continue;
       }
+
+      if (exclude_system && package.loaded_package_->IsOverlay() && found_system_package) {
+        // Overlays must appear after the target package to take effect. Any overlay found in the
+        // same package as a system package is able to overlay system resources.
+        continue;
+      }
+
       package.loaded_package_->CollectLocales(merge_equivalent_languages, &locales);
     }
   }
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 4a5b61a..da77b99 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -9,8 +9,6 @@
         "hwui_lto",
     ],
 
-    cpp_std: "c++17",
-
     cflags: [
         "-DEGL_EGLEXT_PROTOTYPES",
         "-DGL_GLEXT_PROTOTYPES",
diff --git a/libs/hwui/CanvasTransform.cpp b/libs/hwui/CanvasTransform.cpp
index 06e937a..0cfaa8c 100644
--- a/libs/hwui/CanvasTransform.cpp
+++ b/libs/hwui/CanvasTransform.cpp
@@ -146,4 +146,4 @@
     return shouldInvert;
 }
 
-};  // namespace android::uirenderer
\ No newline at end of file
+}  // namespace android::uirenderer
diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h
index a952cc2..dc63e5d 100644
--- a/libs/hwui/DisplayList.h
+++ b/libs/hwui/DisplayList.h
@@ -31,5 +31,5 @@
  */
 using DisplayList = skiapipeline::SkiaDisplayList;
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/FrameMetricsObserver.h b/libs/hwui/FrameMetricsObserver.h
index ba72e93..237fc62 100644
--- a/libs/hwui/FrameMetricsObserver.h
+++ b/libs/hwui/FrameMetricsObserver.h
@@ -26,5 +26,5 @@
     virtual void notify(const int64_t* buffer);
 };
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/FrameMetricsReporter.h b/libs/hwui/FrameMetricsReporter.h
index d920a99..75b8038 100644
--- a/libs/hwui/FrameMetricsReporter.h
+++ b/libs/hwui/FrameMetricsReporter.h
@@ -56,5 +56,5 @@
     std::vector<sp<FrameMetricsObserver> > mObservers;
 };
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/GlFunctorLifecycleListener.h b/libs/hwui/GlFunctorLifecycleListener.h
index 5d07b46..5adc469 100644
--- a/libs/hwui/GlFunctorLifecycleListener.h
+++ b/libs/hwui/GlFunctorLifecycleListener.h
@@ -28,5 +28,5 @@
     virtual void onGlFunctorReleased(Functor* functor) = 0;
 };
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/HardwareBitmapUploader.cpp b/libs/hwui/HardwareBitmapUploader.cpp
index 165fc48..a97c12c 100644
--- a/libs/hwui/HardwareBitmapUploader.cpp
+++ b/libs/hwui/HardwareBitmapUploader.cpp
@@ -256,4 +256,4 @@
     return sk_sp<Bitmap>(new Bitmap(buffer.get(), bitmap.info(), Bitmap::computePalette(bitmap)));
 }
 
-};  // namespace android::uirenderer
+}  // namespace android::uirenderer
diff --git a/libs/hwui/HardwareBitmapUploader.h b/libs/hwui/HardwareBitmapUploader.h
index c0113d8..6298013 100644
--- a/libs/hwui/HardwareBitmapUploader.h
+++ b/libs/hwui/HardwareBitmapUploader.h
@@ -25,4 +25,4 @@
     static sk_sp<Bitmap> allocateHardwareBitmap(const SkBitmap& sourceBitmap);
 };
 
-};  // namespace android::uirenderer
+}  // namespace android::uirenderer
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index d0df200..a15ff22 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -54,5 +54,5 @@
     }
 }
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index 98600db..ea3bfc9 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -144,5 +144,5 @@
 
 };  // struct Layer
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/LayerUpdateQueue.h b/libs/hwui/LayerUpdateQueue.h
index 6857999..2c63af6 100644
--- a/libs/hwui/LayerUpdateQueue.h
+++ b/libs/hwui/LayerUpdateQueue.h
@@ -50,7 +50,7 @@
     std::vector<Entry> mEntries;
 };
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
 
 #endif  // ANDROID_HWUI_LAYER_UPDATE_QUEUE_H
diff --git a/libs/hwui/Lighting.h b/libs/hwui/Lighting.h
index d972c21..ccfbb93 100644
--- a/libs/hwui/Lighting.h
+++ b/libs/hwui/Lighting.h
@@ -34,5 +34,5 @@
     uint8_t spotShadowAlpha;
 };
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/Matrix.cpp b/libs/hwui/Matrix.cpp
index d84ed32..d0dbff03 100644
--- a/libs/hwui/Matrix.cpp
+++ b/libs/hwui/Matrix.cpp
@@ -526,5 +526,5 @@
     ALOGD("]");
 }
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/Matrix.h b/libs/hwui/Matrix.h
index 1b5cb60..b33cfe2 100644
--- a/libs/hwui/Matrix.h
+++ b/libs/hwui/Matrix.h
@@ -245,5 +245,5 @@
 
 typedef Matrix4 mat4;
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/NinePatchUtils.h b/libs/hwui/NinePatchUtils.h
index 082e95f..86d3cb9 100644
--- a/libs/hwui/NinePatchUtils.h
+++ b/libs/hwui/NinePatchUtils.h
@@ -103,5 +103,5 @@
     }
 }
 
-};  // namespace NinePatchUtils
-};  // namespace android
+}  // namespace NinePatchUtils
+}  // namespace android
diff --git a/libs/hwui/PathParser.cpp b/libs/hwui/PathParser.cpp
index ad599e9..808921d 100644
--- a/libs/hwui/PathParser.cpp
+++ b/libs/hwui/PathParser.cpp
@@ -304,5 +304,5 @@
     return;
 }
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/PathParser.h b/libs/hwui/PathParser.h
index 474eb97..f5bebce 100644
--- a/libs/hwui/PathParser.h
+++ b/libs/hwui/PathParser.h
@@ -46,6 +46,6 @@
     static void validateVerbAndPoints(char verb, size_t points, ParseResult* result);
 };
 
-};      // namespace uirenderer
-};      // namespace android
+}      // namespace uirenderer
+}      // namespace android
 #endif  // ANDROID_HWUI_PATHPARSER_H
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index 3f2c616..4a3e10c 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -223,5 +223,5 @@
     sRenderPipelineType = type;
 }
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 542bc71..da53f66 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -289,7 +289,7 @@
     static RenderPipelineType sRenderPipelineType;
 };  // class Caches
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
 
 #endif  // ANDROID_HWUI_PROPERTIES_H
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index f928de9..c63e449 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -1028,5 +1028,5 @@
     fDL->drawVectorDrawable(tree);
 }
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index 099e0be..08cfc62 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -216,5 +216,5 @@
     DisplayListData* fDL;
 };
 
-};  // namespace uirenderer
-};  // namespace android
\ No newline at end of file
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/Rect.h b/libs/hwui/Rect.h
index 0715187..d6362ef 100644
--- a/libs/hwui/Rect.h
+++ b/libs/hwui/Rect.h
@@ -262,5 +262,5 @@
     }
 };  // class Rect
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/UvMapper.h b/libs/hwui/UvMapper.h
index b495e33..833ca4a 100644
--- a/libs/hwui/UvMapper.h
+++ b/libs/hwui/UvMapper.h
@@ -124,7 +124,7 @@
     float mMaxV;
 };
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
 
 #endif  // ANDROID_HWUI_UV_MAPPER_H
diff --git a/libs/hwui/Vector.h b/libs/hwui/Vector.h
index d2c15ad..e6eea1c 100644
--- a/libs/hwui/Vector.h
+++ b/libs/hwui/Vector.h
@@ -113,7 +113,7 @@
     }
 };
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
 
 #endif  // ANDROID_HWUI_VECTOR_H
diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp
index 6cf04bf..dd62bbb 100644
--- a/libs/hwui/VectorDrawable.cpp
+++ b/libs/hwui/VectorDrawable.cpp
@@ -691,7 +691,7 @@
     return BitmapPalette::Unknown;
 }
 
-};  // namespace VectorDrawable
+}  // namespace VectorDrawable
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/Vertex.h b/libs/hwui/Vertex.h
index f091277..28cabb9 100644
--- a/libs/hwui/Vertex.h
+++ b/libs/hwui/Vertex.h
@@ -73,7 +73,7 @@
 
 REQUIRE_COMPATIBLE_LAYOUT(TextureVertex);
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
 
 #endif  // ANDROID_HWUI_VERTEX_H
diff --git a/libs/hwui/VertexBuffer.h b/libs/hwui/VertexBuffer.h
index 613cf4a..6543a22 100644
--- a/libs/hwui/VertexBuffer.h
+++ b/libs/hwui/VertexBuffer.h
@@ -174,7 +174,7 @@
     void (*mCleanupIndexMethod)(void*);
 };
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
 
 #endif  // ANDROID_HWUI_VERTEX_BUFFER_H
diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h
index e99742b..a5f21d8 100644
--- a/libs/hwui/hwui/Canvas.h
+++ b/libs/hwui/hwui/Canvas.h
@@ -76,8 +76,8 @@
 namespace uirenderer {
 namespace VectorDrawable {
 class Tree;
-};
-};
+}
+}
 typedef uirenderer::VectorDrawable::Tree VectorDrawableRoot;
 
 typedef std::function<void(uint16_t* text, float* positions)> ReadGlyphFunc;
@@ -318,4 +318,4 @@
     friend class DrawTextOnPathFunctor;
 };
 
-};  // namespace android
+}  // namespace android
diff --git a/libs/hwui/pipeline/skia/AnimatedDrawables.h b/libs/hwui/pipeline/skia/AnimatedDrawables.h
index efef6de..bf19655 100644
--- a/libs/hwui/pipeline/skia/AnimatedDrawables.h
+++ b/libs/hwui/pipeline/skia/AnimatedDrawables.h
@@ -79,6 +79,6 @@
     sp<uirenderer::CanvasPropertyPaint> mPaint;
 };
 
-};  // namespace skiapipeline
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace skiapipeline
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/pipeline/skia/DumpOpsCanvas.h b/libs/hwui/pipeline/skia/DumpOpsCanvas.h
index e4ba13d..2062194 100644
--- a/libs/hwui/pipeline/skia/DumpOpsCanvas.h
+++ b/libs/hwui/pipeline/skia/DumpOpsCanvas.h
@@ -172,6 +172,6 @@
     std::string mIdent;
 };
 
-};  // namespace skiapipeline
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace skiapipeline
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/pipeline/skia/FunctorDrawable.h b/libs/hwui/pipeline/skia/FunctorDrawable.h
index 162d137..af3a056 100644
--- a/libs/hwui/pipeline/skia/FunctorDrawable.h
+++ b/libs/hwui/pipeline/skia/FunctorDrawable.h
@@ -48,6 +48,6 @@
     const SkRect mBounds;
 };
 
-};  // namespace skiapipeline
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace skiapipeline
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
index 90d5e71..4a87e75 100644
--- a/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
+++ b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
@@ -216,6 +216,6 @@
     }
 }
 
-};  // namespace skiapipeline
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace skiapipeline
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/pipeline/skia/GLFunctorDrawable.h b/libs/hwui/pipeline/skia/GLFunctorDrawable.h
index b06f7f0..215979c 100644
--- a/libs/hwui/pipeline/skia/GLFunctorDrawable.h
+++ b/libs/hwui/pipeline/skia/GLFunctorDrawable.h
@@ -41,6 +41,6 @@
     void onDraw(SkCanvas* canvas) override;
 };
 
-};  // namespace skiapipeline
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace skiapipeline
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/pipeline/skia/LayerDrawable.cpp b/libs/hwui/pipeline/skia/LayerDrawable.cpp
index 9b408fb..f08ac17 100644
--- a/libs/hwui/pipeline/skia/LayerDrawable.cpp
+++ b/libs/hwui/pipeline/skia/LayerDrawable.cpp
@@ -145,6 +145,6 @@
     return layerImage != nullptr;
 }
 
-};  // namespace skiapipeline
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace skiapipeline
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/pipeline/skia/LayerDrawable.h b/libs/hwui/pipeline/skia/LayerDrawable.h
index 5c12590..95dc6d0 100644
--- a/libs/hwui/pipeline/skia/LayerDrawable.h
+++ b/libs/hwui/pipeline/skia/LayerDrawable.h
@@ -45,6 +45,6 @@
     sp<DeferredLayerUpdater> mLayerUpdater;
 };
 
-};  // namespace skiapipeline
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace skiapipeline
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
index d80cb6d..4494cb0 100644
--- a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
@@ -332,6 +332,6 @@
     }
 }
 
-};  // namespace skiapipeline
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace skiapipeline
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.h b/libs/hwui/pipeline/skia/RenderNodeDrawable.h
index d746978..6ba8e59 100644
--- a/libs/hwui/pipeline/skia/RenderNodeDrawable.h
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.h
@@ -150,6 +150,6 @@
     SkiaDisplayList* mProjectedDisplayList = nullptr;
 };
 
-};  // namespace skiapipeline
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace skiapipeline
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
index dba97fe..0a3c8f4 100644
--- a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
+++ b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
@@ -211,6 +211,6 @@
             casterAlpha < 1.0f ? SkShadowFlags::kTransparentOccluder_ShadowFlag : 0);
 }
 
-};  // namespace skiapipeline
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace skiapipeline
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.h b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.h
index 26cfa90..cfc0f9b 100644
--- a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.h
+++ b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.h
@@ -74,6 +74,6 @@
     StartReorderBarrierDrawable* mStartBarrier;
 };
 
-};  // namespace skiapipeline
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace skiapipeline
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
index 3890513..ac6f6a3 100644
--- a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
@@ -141,6 +141,6 @@
     mDisplayList.draw(&canvas);
 }
 
-};  // namespace skiapipeline
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace skiapipeline
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.h b/libs/hwui/pipeline/skia/SkiaDisplayList.h
index ac7bb7b..d7879e7 100644
--- a/libs/hwui/pipeline/skia/SkiaDisplayList.h
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.h
@@ -36,7 +36,7 @@
 
 namespace VectorDrawable {
 class Tree;
-};
+}
 typedef uirenderer::VectorDrawable::Tree VectorDrawableRoot;
 
 namespace skiapipeline {
@@ -179,6 +179,6 @@
     SkMatrix mParentMatrix;
 };
 
-};  // namespace skiapipeline
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace skiapipeline
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
index f5de1c8..b682ab0 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -259,6 +259,6 @@
     return 0;
 }
 
-};  // namespace skiapipeline
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace skiapipeline
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
index 988728d..d6107a9 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
@@ -92,6 +92,6 @@
     PaintCoW&& filterBitmap(PaintCoW&& paint, sk_sp<SkColorFilter> colorSpaceFilter);
 };
 
-};  // namespace skiapipeline
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace skiapipeline
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
index a494e49..3607b23 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
@@ -122,8 +122,9 @@
         mVkSurface = nullptr;
     }
 
+    mSurfaceColorSpace = SkColorSpace::MakeSRGB();
     if (surface) {
-        mVkSurface = mVkManager.createSurface(surface, colorMode);
+        mVkSurface = mVkManager.createSurface(surface, colorMode, mSurfaceColorSpace);
     }
 
     if (colorMode == ColorMode::SRGB) {
diff --git a/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.cpp b/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.cpp
index a594206..004a558 100644
--- a/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.cpp
+++ b/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.cpp
@@ -219,6 +219,6 @@
     });
 }
 
-};  // namespace skiapipeline
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace skiapipeline
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.h b/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.h
index 3269cfb..8fe52c5 100644
--- a/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.h
+++ b/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.h
@@ -51,6 +51,6 @@
     SkImageInfo mFBInfo;
 };
 
-};  // namespace skiapipeline
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace skiapipeline
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/private/hwui/DrawGlInfo.h b/libs/hwui/private/hwui/DrawGlInfo.h
index efa9da2..9e1bb8e 100644
--- a/libs/hwui/private/hwui/DrawGlInfo.h
+++ b/libs/hwui/private/hwui/DrawGlInfo.h
@@ -83,7 +83,7 @@
     };
 };  // struct DrawGlInfo
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
 
 #endif  // ANDROID_HWUI_DRAW_GL_INFO_H
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index f1a522e..6869972 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -323,25 +323,6 @@
             // the deadline for RT animations
             info.out.canDrawThisFrame = false;
         }
-        /* This logic exists to try and recover from a display latch miss, which essentially
-         * results in the bufferqueue being double-buffered instead of triple-buffered.
-         * SurfaceFlinger itself now tries to handle & recover from this situation, so this
-         * logic should no longer be necessary. As it's occasionally triggering when
-         * undesired disable it.
-         * TODO: Remove this entirely if the results are solid.
-        else if (vsyncDelta >= mRenderThread.timeLord().frameIntervalNanos() * 3 ||
-                   (latestVsync - mLastDropVsync) < 500_ms) {
-            // It's been several frame intervals, assume the buffer queue is fine
-            // or the last drop was too recent
-            info.out.canDrawThisFrame = true;
-        } else {
-            info.out.canDrawThisFrame = !isSwapChainStuffed();
-            if (!info.out.canDrawThisFrame) {
-                // dropping frame
-                mLastDropVsync = mRenderThread.timeLord().latestVsync();
-            }
-        }
-        */
     } else {
         info.out.canDrawThisFrame = true;
     }
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 6668c58..d9b789f 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -49,7 +49,7 @@
     Reset = 1 << 1,
     JankStats = 1 << 2,
 };
-};
+}
 
 /*
  * RenderProxy is strictly single threaded. All methods must be invoked on the owning
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp
index 9a6df75..e1f8307 100644
--- a/libs/hwui/renderthread/VulkanManager.cpp
+++ b/libs/hwui/renderthread/VulkanManager.cpp
@@ -472,8 +472,9 @@
     window->query(window, NATIVE_WINDOW_HEIGHT, &windowHeight);
     if (windowWidth != surface->mWindowWidth || windowHeight != surface->mWindowHeight) {
         ColorMode colorMode = surface->mColorMode;
+        sk_sp<SkColorSpace> colorSpace = surface->mColorSpace;
         destroySurface(surface);
-        *surfaceOut = createSurface(window, colorMode);
+        *surfaceOut = createSurface(window, colorMode, colorSpace);
         surface = *surfaceOut;
     }
 
@@ -647,7 +648,7 @@
         imageInfo.mSurface = SkSurface::MakeFromBackendRenderTarget(
                 mRenderThread.getGrContext(), backendRT, kTopLeft_GrSurfaceOrigin,
                 surface->mColorMode == ColorMode::WideColorGamut ? kRGBA_F16_SkColorType
-                : kRGBA_8888_SkColorType, nullptr, &props);
+                : kRGBA_8888_SkColorType, surface->mColorSpace, &props);
     }
 
     SkASSERT(mCommandPool != VK_NULL_HANDLE);
@@ -833,14 +834,15 @@
     return true;
 }
 
-VulkanSurface* VulkanManager::createSurface(ANativeWindow* window, ColorMode colorMode) {
+VulkanSurface* VulkanManager::createSurface(ANativeWindow* window, ColorMode colorMode,
+        sk_sp<SkColorSpace> surfaceColorSpace) {
     initialize();
 
     if (!window) {
         return nullptr;
     }
 
-    VulkanSurface* surface = new VulkanSurface(colorMode, window);
+    VulkanSurface* surface = new VulkanSurface(colorMode, window, surfaceColorSpace);
 
     VkAndroidSurfaceCreateInfoKHR surfaceCreateInfo;
     memset(&surfaceCreateInfo, 0, sizeof(VkAndroidSurfaceCreateInfoKHR));
diff --git a/libs/hwui/renderthread/VulkanManager.h b/libs/hwui/renderthread/VulkanManager.h
index 8594a1b..d67d2c8 100644
--- a/libs/hwui/renderthread/VulkanManager.h
+++ b/libs/hwui/renderthread/VulkanManager.h
@@ -38,8 +38,8 @@
 
 class VulkanSurface {
 public:
-    VulkanSurface(ColorMode colorMode, ANativeWindow* window)
-            : mColorMode(colorMode), mNativeWindow(window) {}
+    VulkanSurface(ColorMode colorMode, ANativeWindow* window, sk_sp<SkColorSpace> colorSpace)
+            : mColorMode(colorMode), mNativeWindow(window), mColorSpace(colorSpace) {}
 
     sk_sp<SkSurface> getBackBufferSurface() { return mBackbuffer; }
 
@@ -79,6 +79,7 @@
     ANativeWindow* mNativeWindow;
     int mWindowWidth = 0;
     int mWindowHeight = 0;
+    sk_sp<SkColorSpace> mColorSpace;
 };
 
 // This class contains the shared global Vulkan objects, such as VkInstance, VkDevice and VkQueue,
@@ -96,7 +97,8 @@
 
     // Given a window this creates a new VkSurfaceKHR and VkSwapchain and stores them inside a new
     // VulkanSurface object which is returned.
-    VulkanSurface* createSurface(ANativeWindow* window, ColorMode colorMode);
+    VulkanSurface* createSurface(ANativeWindow* window, ColorMode colorMode,
+            sk_sp<SkColorSpace> surfaceColorSpace);
 
     // Destroy the VulkanSurface and all associated vulkan objects.
     void destroySurface(VulkanSurface* surface);
diff --git a/libs/hwui/surfacetexture/EGLConsumer.cpp b/libs/hwui/surfacetexture/EGLConsumer.cpp
index c8220c6..85b3917 100644
--- a/libs/hwui/surfacetexture/EGLConsumer.cpp
+++ b/libs/hwui/surfacetexture/EGLConsumer.cpp
@@ -672,4 +672,4 @@
     return image;
 }
 
-};  // namespace android
+}  // namespace android
diff --git a/libs/hwui/surfacetexture/EGLConsumer.h b/libs/hwui/surfacetexture/EGLConsumer.h
index eccb082..7dac3ef 100644
--- a/libs/hwui/surfacetexture/EGLConsumer.h
+++ b/libs/hwui/surfacetexture/EGLConsumer.h
@@ -308,4 +308,4 @@
     sp<EglImage> mReleasedTexImage;
 };
 
-};  // namespace android
+}  // namespace android
diff --git a/libs/hwui/surfacetexture/ImageConsumer.h b/libs/hwui/surfacetexture/ImageConsumer.h
index 5bab0ef5..f0e55bb 100644
--- a/libs/hwui/surfacetexture/ImageConsumer.h
+++ b/libs/hwui/surfacetexture/ImageConsumer.h
@@ -97,4 +97,4 @@
     ImageSlot mImageSlots[BufferQueueDefs::NUM_BUFFER_SLOTS];
 };
 
-}; /* namespace android */
+} /* namespace android */
diff --git a/libs/hwui/surfacetexture/SurfaceTexture.cpp b/libs/hwui/surfacetexture/SurfaceTexture.cpp
index 90f8912..da09444 100644
--- a/libs/hwui/surfacetexture/SurfaceTexture.cpp
+++ b/libs/hwui/surfacetexture/SurfaceTexture.cpp
@@ -491,4 +491,4 @@
     return image;
 }
 
-};  // namespace android
+}  // namespace android
diff --git a/libs/hwui/surfacetexture/SurfaceTexture.h b/libs/hwui/surfacetexture/SurfaceTexture.h
index 96afd82..b5d136f 100644
--- a/libs/hwui/surfacetexture/SurfaceTexture.h
+++ b/libs/hwui/surfacetexture/SurfaceTexture.h
@@ -449,4 +449,4 @@
 };
 
 // ----------------------------------------------------------------------------
-};  // namespace android
+}  // namespace android
diff --git a/libs/hwui/tests/unit/LayerUpdateQueueTests.cpp b/libs/hwui/tests/unit/LayerUpdateQueueTests.cpp
index 217d63f..41714eb 100644
--- a/libs/hwui/tests/unit/LayerUpdateQueueTests.cpp
+++ b/libs/hwui/tests/unit/LayerUpdateQueueTests.cpp
@@ -81,5 +81,5 @@
 
     EXPECT_TRUE(queue.entries().empty());
 }
-};
-};
+}
+}
diff --git a/libs/hwui/tests/unit/VectorDrawableTests.cpp b/libs/hwui/tests/unit/VectorDrawableTests.cpp
index 02f740c..ee6beba 100644
--- a/libs/hwui/tests/unit/VectorDrawableTests.cpp
+++ b/libs/hwui/tests/unit/VectorDrawableTests.cpp
@@ -406,5 +406,5 @@
     EXPECT_TRUE(shader->unique());
 }
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/thread/Barrier.h b/libs/hwui/thread/Barrier.h
index 8faeee6..bb750ca 100644
--- a/libs/hwui/thread/Barrier.h
+++ b/libs/hwui/thread/Barrier.h
@@ -48,7 +48,7 @@
     mutable Condition mCondition;
 };
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
 
 #endif  // ANDROID_HWUI_BARRIER_H
diff --git a/libs/hwui/thread/Future.h b/libs/hwui/thread/Future.h
index 45f3102..df53348e 100644
--- a/libs/hwui/thread/Future.h
+++ b/libs/hwui/thread/Future.h
@@ -53,7 +53,7 @@
     T mResult;
 };
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
 
 #endif  // ANDROID_HWUI_FUTURE_H
diff --git a/libs/hwui/thread/Signal.h b/libs/hwui/thread/Signal.h
index ffcd4b6..6d33ac4 100644
--- a/libs/hwui/thread/Signal.h
+++ b/libs/hwui/thread/Signal.h
@@ -53,7 +53,7 @@
     mutable Condition mCondition;
 };
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
 
 #endif  // ANDROID_HWUI_SIGNAL_H
diff --git a/libs/hwui/thread/Task.h b/libs/hwui/thread/Task.h
index 276a22f..228ce19 100644
--- a/libs/hwui/thread/Task.h
+++ b/libs/hwui/thread/Task.h
@@ -48,7 +48,7 @@
     sp<Future<T> > mFuture;
 };
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
 
 #endif  // ANDROID_HWUI_TASK_H
diff --git a/libs/hwui/thread/TaskManager.cpp b/libs/hwui/thread/TaskManager.cpp
index 54b55e4..26ff6eb 100644
--- a/libs/hwui/thread/TaskManager.cpp
+++ b/libs/hwui/thread/TaskManager.cpp
@@ -129,5 +129,5 @@
     mSignal.signal();
 }
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/thread/TaskManager.h b/libs/hwui/thread/TaskManager.h
index 29b4fcd..c4c1291 100644
--- a/libs/hwui/thread/TaskManager.h
+++ b/libs/hwui/thread/TaskManager.h
@@ -101,7 +101,7 @@
     std::vector<sp<WorkerThread> > mThreads;
 };
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
 
 #endif  // ANDROID_HWUI_TASK_MANAGER_H
diff --git a/libs/hwui/utils/Blur.cpp b/libs/hwui/utils/Blur.cpp
index 1bc5646..763d1aa 100644
--- a/libs/hwui/utils/Blur.cpp
+++ b/libs/hwui/utils/Blur.cpp
@@ -178,5 +178,5 @@
     }
 }
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/utils/Blur.h b/libs/hwui/utils/Blur.h
index bec3837..d6b41b8 100644
--- a/libs/hwui/utils/Blur.h
+++ b/libs/hwui/utils/Blur.h
@@ -41,7 +41,7 @@
                          int32_t width, int32_t height);
 };
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
 
 #endif  // ANDROID_HWUI_BLUR_H
diff --git a/libs/hwui/utils/Color.cpp b/libs/hwui/utils/Color.cpp
index 3fb6a31..dc347f6 100644
--- a/libs/hwui/utils/Color.cpp
+++ b/libs/hwui/utils/Color.cpp
@@ -221,5 +221,5 @@
             static_cast<uint8_t>(rgb.b * 255));
 }
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/utils/FatVector.h b/libs/hwui/utils/FatVector.h
index eafe2f1..8cc4d10 100644
--- a/libs/hwui/utils/FatVector.h
+++ b/libs/hwui/utils/FatVector.h
@@ -99,7 +99,7 @@
     typename InlineStdAllocator<T, SIZE>::Allocation mAllocation;
 };
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
 
 #endif  // ANDROID_FAT_VECTOR_H
diff --git a/libs/hwui/utils/GLUtils.cpp b/libs/hwui/utils/GLUtils.cpp
index fcd036c..c694e93 100644
--- a/libs/hwui/utils/GLUtils.cpp
+++ b/libs/hwui/utils/GLUtils.cpp
@@ -76,5 +76,5 @@
     }
 }
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/utils/LinearAllocator.cpp b/libs/hwui/utils/LinearAllocator.cpp
index 3e5021c..8baa4b77 100644
--- a/libs/hwui/utils/LinearAllocator.cpp
+++ b/libs/hwui/utils/LinearAllocator.cpp
@@ -249,5 +249,5 @@
     ALOGD("%sPages %zu (dedicated %zu)", prefix, mPageCount, mDedicatedPageCount);
 }
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/utils/LinearAllocator.h b/libs/hwui/utils/LinearAllocator.h
index 03f685e..b401fcf 100644
--- a/libs/hwui/utils/LinearAllocator.h
+++ b/libs/hwui/utils/LinearAllocator.h
@@ -201,7 +201,7 @@
             : std::vector<T, LinearStdAllocator<T>>(allocator) {}
 };
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
 
 #endif  // ANDROID_LINEARALLOCATOR_H
diff --git a/libs/hwui/utils/Pair.h b/libs/hwui/utils/Pair.h
index 4bcd576..76f93cb 100644
--- a/libs/hwui/utils/Pair.h
+++ b/libs/hwui/utils/Pair.h
@@ -36,7 +36,7 @@
     inline const S& getSecond() const { return second; }
 };
 
-};  // namespace uirenderer
+}  // namespace uirenderer
 
 template <typename F, typename S>
 struct trait_trivial_ctor<uirenderer::Pair<F, S> > {
@@ -55,6 +55,6 @@
     enum { value = aggregate_traits<F, S>::has_trivial_move };
 };
 
-};  // namespace android
+}  // namespace android
 
 #endif  // ANDROID_HWUI_PAIR_H
diff --git a/libs/hwui/utils/Result.h b/libs/hwui/utils/Result.h
index 7f33f2e..bd20ba6 100644
--- a/libs/hwui/utils/Result.h
+++ b/libs/hwui/utils/Result.h
@@ -51,4 +51,4 @@
     std::variant<R, Error<E>> result;
 };
 
-}; // namespace android::uirenderer
+} // namespace android::uirenderer
diff --git a/libs/hwui/utils/RingBuffer.h b/libs/hwui/utils/RingBuffer.h
index b3e8931..081386a 100644
--- a/libs/hwui/utils/RingBuffer.h
+++ b/libs/hwui/utils/RingBuffer.h
@@ -61,7 +61,7 @@
     size_t mCount = 0;
 };
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
 
 #endif /* RINGBUFFER_H_ */
diff --git a/libs/hwui/utils/StringUtils.cpp b/libs/hwui/utils/StringUtils.cpp
index 5304b76..304982e 100644
--- a/libs/hwui/utils/StringUtils.cpp
+++ b/libs/hwui/utils/StringUtils.cpp
@@ -34,5 +34,5 @@
     return set;
 }
 
-};  // namespace uirenderer
-};  // namespace android
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/utils/TypeLogic.h b/libs/hwui/utils/TypeLogic.h
index dbdad33..1689cce 100644
--- a/libs/hwui/utils/TypeLogic.h
+++ b/libs/hwui/utils/TypeLogic.h
@@ -37,4 +37,4 @@
 template <typename D, typename S> using same_cv = copy_cv<std::remove_cv_t<D>, S>;
 template <typename D, typename S> using same_cv_t = typename same_cv<D, S>::type;
 
-}; // namespace android::uirenderer
\ No newline at end of file
+} // namespace android::uirenderer
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 2a575b6..4b2353c 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -16,16 +16,6 @@
 
 package android.media;
 
-import java.io.IOException;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.ref.WeakReference;
-import java.nio.ByteBuffer;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.ArrayList;
-import java.util.List;
-
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
@@ -39,13 +29,21 @@
 import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.Pair;
 
 import com.android.internal.annotations.GuardedBy;
 
+import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
 /**
  * The AudioRecord class manages the audio resources for Java applications
  * to record audio from the audio input hardware of the platform. This is
@@ -1807,6 +1805,8 @@
     private native final int native_get_active_microphones(
             ArrayList<MicrophoneInfo> activeMicrophones);
 
+    private native int native_getPortId();
+
     //---------------------------------------------------------
     // Utility methods
     //------------------
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index c226d49..2c4ec3a 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -2620,7 +2620,8 @@
      *         to the audio sink.
      *     <BR>With {@link #WRITE_NON_BLOCKING}, the write will return immediately after
      *     queuing as much audio data for playback as possible without blocking.
-     * @param timestamp The timestamp of the first decodable audio frame in the provided audioData.
+     * @param timestamp The timestamp, in nanoseconds, of the first decodable audio frame in the
+     *     provided audioData.
      * @return zero or the positive number of bytes that were written, or one of the following
      *    error codes.
      * <ul>
@@ -3422,6 +3423,8 @@
     private native @Nullable VolumeShaper.State native_getVolumeShaperState(int id);
     private native final int native_setPresentation(int presentationId, int programId);
 
+    private native int native_getPortId();
+
     //---------------------------------------------------------
     // Utility methods
     //------------------
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index 01a0cb6..32c4643 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -2635,13 +2635,18 @@
                     if (size == 0) {
                         return 0;
                     }
-                    // We don't allow read positions after the available bytes,
-                    // the input stream won't be able to seek back then.
-                    if (position < 0 || position >= in.available()) {
+                    if (position < 0) {
                         return -1;
                     }
                     try {
                         if (mPosition != position) {
+                            // We don't allow seek to positions after the available bytes,
+                            // the input stream won't be able to seek back then.
+                            // However, if we hit an exception before (mPosition set to -1),
+                            // let it try the seek in hope it might recover.
+                            if (mPosition >= 0 && position >= mPosition + in.available()) {
+                                return -1;
+                            }
                             in.seek(position);
                             mPosition = position;
                         }
@@ -2649,8 +2654,8 @@
                         // If the read will cause us to go over the available bytes,
                         // reduce the size so that we stay in the available range.
                         // Otherwise the input stream may not be able to seek back.
-                        if (mPosition + size > in.available()) {
-                            size = in.available() - (int)mPosition;
+                        if (size > in.available()) {
+                            size = in.available();
                         }
 
                         int bytesRead = in.read(buffer, offset, size);
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 3a64f43..0950a24 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -156,7 +156,8 @@
     private static final String NOTIFICATIONS_DIR = "/notifications/";
     private static final String ALARMS_DIR = "/alarms/";
     private static final String MUSIC_DIR = "/music/";
-    private static final String PODCAST_DIR = "/podcasts/";
+    private static final String PODCASTS_DIR = "/podcasts/";
+    private static final String AUDIOBOOKS_DIR = "/audiobooks/";
 
     public static final String SCANNED_BUILD_PREFS_NAME = "MediaScanBuild";
     public static final String LAST_INTERNAL_SCAN_FINGERPRINT = "lastScanFingerprint";
@@ -654,7 +655,7 @@
                 // rescan for metadata if file was modified since last scan
                 if (entry != null && (entry.mLastModifiedChanged || scanAlways)) {
                     if (noMedia) {
-                        result = endFile(entry, false, false, false, false, false);
+                        result = endFile(entry, false, false, false, false, false, false);
                     } else {
                         boolean isaudio = MediaFile.isAudioMimeType(mMimeType);
                         boolean isvideo = MediaFile.isVideoMimeType(mMimeType);
@@ -679,11 +680,13 @@
                         boolean notifications = mScanSuccess &&
                                 (lowpath.indexOf(NOTIFICATIONS_DIR) > 0);
                         boolean alarms = mScanSuccess && (lowpath.indexOf(ALARMS_DIR) > 0);
-                        boolean podcasts = mScanSuccess && (lowpath.indexOf(PODCAST_DIR) > 0);
+                        boolean podcasts = mScanSuccess && (lowpath.indexOf(PODCASTS_DIR) > 0);
+                        boolean audiobooks = mScanSuccess && (lowpath.indexOf(AUDIOBOOKS_DIR) > 0);
                         boolean music = mScanSuccess && ((lowpath.indexOf(MUSIC_DIR) > 0) ||
-                            (!ringtones && !notifications && !alarms && !podcasts));
+                            (!ringtones && !notifications && !alarms && !podcasts && !audiobooks));
 
-                        result = endFile(entry, ringtones, notifications, alarms, music, podcasts);
+                        result = endFile(entry, ringtones, notifications, alarms, podcasts,
+                                audiobooks, music);
                     }
                 }
             } catch (RemoteException e) {
@@ -957,7 +960,7 @@
 
         @UnsupportedAppUsage
         private Uri endFile(FileEntry entry, boolean ringtones, boolean notifications,
-                boolean alarms, boolean music, boolean podcasts)
+                boolean alarms, boolean podcasts, boolean audiobooks, boolean music)
                 throws RemoteException {
             // update database
 
@@ -1003,6 +1006,7 @@
                 values.put(Audio.Media.IS_ALARM, alarms);
                 values.put(Audio.Media.IS_MUSIC, music);
                 values.put(Audio.Media.IS_PODCAST, podcasts);
+                values.put(Audio.Media.IS_AUDIOBOOK, audiobooks);
             } else if (MediaFile.isExifMimeType(mMimeType) && !mNoMedia) {
                 ExifInterface exif = null;
                 try {
diff --git a/media/java/android/media/audiofx/Visualizer.java b/media/java/android/media/audiofx/Visualizer.java
index a7bdf4f..89a509f 100644
--- a/media/java/android/media/audiofx/Visualizer.java
+++ b/media/java/android/media/audiofx/Visualizer.java
@@ -18,11 +18,12 @@
 
 import android.annotation.UnsupportedAppUsage;
 import android.app.ActivityThread;
-import android.util.Log;
-import java.lang.ref.WeakReference;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+import android.util.Log;
+
+import java.lang.ref.WeakReference;
 
 /**
  * The Visualizer class enables application to retrieve part of the currently playing audio for
@@ -455,7 +456,7 @@
      *   <li> Rfk, Ifk are respectively  the real and imaginary parts of the kth frequency
      *   component</li>
      *   <li> If Fs is the sampling frequency retuned by getSamplingRate() the kth frequency is:
-     *   (k*Fs)/(n/2) </li>
+     *   k * Fs / n </li>
      * </ul>
      * <table border="0" cellspacing="0" cellpadding="0">
      * <tr><td>Index </p></td>
@@ -476,9 +477,23 @@
      *     <td>Rf2 </p></td>
      *     <td>If2 </p></td>
      *     <td>... </p></td>
-     *     <td>Rf(n-1)/2 </p></td>
-     *     <td>If(n-1)/2 </p></td></tr>
+     *     <td>Rf(n/2-1) </p></td>
+     *     <td>If(n/2-1) </p></td></tr>
      * </table>
+     * <p>In order to obtain magnitude and phase values the following code can
+     * be used:
+     *    <pre class="prettyprint">
+     *       int n = fft.size();
+     *       float[] magnitudes = new float[n / 2 + 1];
+     *       float[] phases = new float[n / 2 + 1];
+     *       magnitudes[0] = (float)Math.abs(fft[0]);      // DC
+     *       magnitudes[n / 2] = (float)Math.abs(fft[1]);  // Nyquist
+     *       phases[0] = phases[n / 2] = 0;
+     *       for (int k = 1; k &lt; n / 2; k++) {
+     *           int i = k * 2;
+     *           magnitudes[k] = (float)Math.hypot(fft[i], fft[i + 1]);
+     *           phases[k] = (float)Math.atan2(fft[i + 1], fft[i]);
+     *       }</pre>
      * @param fft array of bytes where the FFT should be returned
      * @return {@link #SUCCESS} in case of success,
      * {@link #ERROR_NO_MEMORY}, {@link #ERROR_INVALID_OPERATION} or {@link #ERROR_DEAD_OBJECT}
@@ -561,25 +576,11 @@
          * <p>Data in the fft buffer is valid only within the scope of the callback.
          * Applications which need access to the fft data after returning from the callback
          * should make a copy of the data instead of holding a reference.
+         * <p>For the explanation of the fft data array layout, and the example
+         * code for processing it, please see the documentation for {@link #getFft(byte[])} method.
          *
-         * <p>In order to obtain magnitude and phase values the following formulas can
-         * be used:
-         *    <pre class="prettyprint">
-         *       for (int i = 0; i &lt; fft.size(); i += 2) {
-         *           float magnitude = (float)Math.hypot(fft[i], fft[i + 1]);
-         *           float phase = (float)Math.atan2(fft[i + 1], fft[i]);
-         *       }</pre>
          * @param visualizer Visualizer object on which the listener is registered.
          * @param fft array of bytes containing the frequency representation.
-         *    The fft array only contains the first half of the actual
-         *    FFT spectrum (frequencies up to Nyquist frequency), exploiting
-         *    the symmetry of the spectrum. For each frequencies bin <code>i</code>:
-         *    <ul>
-         *      <li>the element at index <code>2*i</code> in the array contains
-         *          the real part of a complex number,</li>
-         *      <li>the element at index <code>2*i+1</code> contains the imaginary
-         *          part of the complex number.</li>
-         *    </ul>
          * @param samplingRate sampling rate of the visualized audio.
          */
         void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate);
diff --git a/packages/CarSystemUI/res/xml/car_volume_items.xml b/packages/CarSystemUI/res/xml/car_volume_items.xml
index 8715946..922b1a7 100644
--- a/packages/CarSystemUI/res/xml/car_volume_items.xml
+++ b/packages/CarSystemUI/res/xml/car_volume_items.xml
@@ -23,8 +23,8 @@
         car:icon="@drawable/car_ic_music"/>
   <item car:usage="media"
         car:icon="@drawable/car_ic_music"/>
-  <item car:usage="voice_communication"
-        car:icon="@*android:drawable/ic_audio_ring_notif"/>
+  <item car:usage="assistance_navigation_guidance"
+        car:icon="@drawable/car_ic_navigation"/>
   <item car:usage="voice_communication_signalling"
         car:icon="@*android:drawable/ic_audio_ring_notif"/>
   <item car:usage="alarm"
@@ -43,8 +43,8 @@
         car:icon="@drawable/car_ic_notification"/>
   <item car:usage="assistance_accessibility"
         car:icon="@drawable/car_ic_notification"/>
-  <item car:usage="assistance_navigation_guidance"
-        car:icon="@drawable/car_ic_navigation"/>
+  <item car:usage="voice_communication"
+        car:icon="@*android:drawable/ic_audio_ring_notif"/>
   <item car:usage="assistance_sonification"
         car:icon="@drawable/car_ic_notification"/>
   <item car:usage="game"
diff --git a/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java b/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java
index b2fc417..892267b 100644
--- a/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java
+++ b/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java
@@ -48,7 +48,7 @@
                     | Notification.FLAG_NO_CLEAR;
     private static final int MAX_ACTION_EXTRACTION_TEXT_LENGTH = 400;
     private static final int MAX_ACTIONS_PER_LINK = 1;
-    private static final int MAX_SMART_ACTIONS = Notification.MAX_ACTION_BUTTONS;
+    private static final int MAX_SMART_ACTIONS = 3;
     private static final int MAX_SUGGESTED_REPLIES = 3;
 
     private static final ConversationActions.TypeConfig TYPE_CONFIG =
@@ -81,12 +81,9 @@
         if (tcm == null) {
             return EMPTY_ACTION_LIST;
         }
-        Notification.Action[] actions = entry.getNotification().actions;
-        int numOfExistingActions = actions == null ? 0: actions.length;
-        int maxSmartActions = MAX_SMART_ACTIONS - numOfExistingActions;
         return suggestActionsFromText(
                 tcm,
-                getMostSalientActionText(entry.getNotification()), maxSmartActions);
+                getMostSalientActionText(entry.getNotification()), MAX_SMART_ACTIONS);
     }
 
     ArrayList<CharSequence> suggestReplies(
diff --git a/packages/PrintSpooler/AndroidManifest.xml b/packages/PrintSpooler/AndroidManifest.xml
index 91e23dd..03eafc4 100644
--- a/packages/PrintSpooler/AndroidManifest.xml
+++ b/packages/PrintSpooler/AndroidManifest.xml
@@ -34,15 +34,23 @@
     <uses-permission android:name="com.android.printspooler.permission.ACCESS_ALL_PRINT_JOBS"/>
     <uses-permission android:name="android.permission.WAKE_LOCK"/>
     <uses-permission android:name="android.permission.START_PRINT_SERVICE_CONFIG_ACTIVITY"/>
-    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
-    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
     <uses-permission android:name="android.permission.READ_PRINT_SERVICES" />
     <uses-permission android:name="android.permission.READ_PRINT_SERVICE_RECOMMENDATIONS" />
 
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"
+                     android:dataSentOffDevice="no"
+                     android:dataSharedWithThirdParty="no"
+                     android:dataUsedForMonetization="no"
+                     android:dataRetentionTime="unlimited"/>
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
+                     android:dataSentOffDevice="no"
+                     android:dataSharedWithThirdParty="no"
+                     android:dataUsedForMonetization="no"
+                     android:dataRetentionTime="unlimited"/>
+
     <application
         android:allowClearUserData="true"
         android:label="@string/app_label"
-        android:allowBackup= "false"
         android:supportsRtl="true">
 
         <service
diff --git a/packages/PrintSpooler/res/layout/print_activity.xml b/packages/PrintSpooler/res/layout/print_activity.xml
index 0ccf13e..9e16f5e 100644
--- a/packages/PrintSpooler/res/layout/print_activity.xml
+++ b/packages/PrintSpooler/res/layout/print_activity.xml
@@ -107,7 +107,7 @@
         android:layout_height="wrap_content"
         android:layout_marginStart="16dip"
         android:elevation="@dimen/preview_controls_elevation"
-        android:tint="?android:attr/textColorPrimaryInverse"
+        android:tint="@android:color/white"
         android:background="@drawable/print_button">
     </ImageButton>
 
diff --git a/packages/SettingsLib/res/layout/preference_checkable_two_target.xml b/packages/SettingsLib/res/layout/preference_checkable_two_target.xml
new file mode 100644
index 0000000..1a47afc
--- /dev/null
+++ b/packages/SettingsLib/res/layout/preference_checkable_two_target.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<!-- Based off preference_material_settings.xml except that ripple on only on the left side. -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:minHeight="?android:attr/listPreferredItemHeightSmall"
+    android:gravity="center_vertical"
+    android:background="@android:color/transparent"
+    android:clipToPadding="false">
+
+    <LinearLayout
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:background="?android:attr/selectableItemBackground"
+        android:gravity="start|center_vertical"
+        android:clipToPadding="false"
+        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
+
+        <LinearLayout
+            android:id="@+id/checkbox_container"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="start|center_vertical"
+            android:minWidth="56dp"
+            android:orientation="horizontal"
+            android:clipToPadding="false"
+            android:paddingTop="4dp"
+            android:paddingBottom="4dp">
+            <include layout="@layout/preference_widget_checkbox" />
+        </LinearLayout>
+
+        <RelativeLayout
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:paddingTop="16dp"
+            android:paddingBottom="16dp">
+
+            <TextView
+                android:id="@android:id/title"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:singleLine="true"
+                android:textAppearance="?android:attr/textAppearanceListItem"
+                android:ellipsize="marquee" />
+
+            <TextView
+                android:id="@android:id/summary"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_below="@android:id/title"
+                android:layout_alignStart="@android:id/title"
+                android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+                android:textColor="?android:attr/textColorSecondary"
+                android:maxLines="10" />
+
+        </RelativeLayout>
+
+    </LinearLayout>
+
+    <include layout="@layout/preference_two_target_divider" />
+
+    <!-- Preference should place its actual preference widget here. -->
+    <LinearLayout
+        android:id="@android:id/widget_frame"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:minWidth="64dp"
+        android:gravity="center"
+        android:orientation="vertical" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
index 92fd868..12b8efb 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
@@ -53,6 +53,8 @@
             "com.android.settings.category.ia.night_display";
     public static final String CATEGORY_PRIVACY =
             "com.android.settings.category.ia.privacy";
+    public static final String CATEGORY_ENTERPRISE_PRIVACY =
+            "com.android.settings.category.ia.enterprise_privacy";
 
     public static final Map<String, String> KEY_COMPAT_MAP;
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/ChartDataLoaderCompat.java b/packages/SettingsLib/src/com/android/settingslib/net/ChartDataLoaderCompat.java
deleted file mode 100644
index e9c5238..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/net/ChartDataLoaderCompat.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net;
-
-import static android.net.NetworkStats.SET_DEFAULT;
-import static android.net.NetworkStats.SET_FOREGROUND;
-import static android.net.NetworkStats.TAG_NONE;
-import static android.net.NetworkStatsHistory.FIELD_RX_BYTES;
-import static android.net.NetworkStatsHistory.FIELD_TX_BYTES;
-import static android.text.format.DateUtils.HOUR_IN_MILLIS;
-
-import android.content.Context;
-import android.net.INetworkStatsSession;
-import android.net.NetworkStatsHistory;
-import android.net.NetworkTemplate;
-import android.os.Bundle;
-import android.os.RemoteException;
-
-import androidx.loader.content.AsyncTaskLoader;
-
-import com.android.settingslib.AppItem;
-
-/**
- * Loader for historical chart data for both network and UID details.
- *
- * Deprecated in favor of {@link NetworkCycleChartDataLoader} and
- * {@link NetworkCycleDataForUidLoader}
- *
- * @deprecated
- */
-@Deprecated
-public class ChartDataLoaderCompat extends AsyncTaskLoader<ChartData> {
-    private static final String KEY_TEMPLATE = "template";
-    private static final String KEY_APP = "app";
-    private static final String KEY_FIELDS = "fields";
-
-    private final INetworkStatsSession mSession;
-    private final Bundle mArgs;
-
-    public static Bundle buildArgs(NetworkTemplate template, AppItem app) {
-        return buildArgs(template, app, FIELD_RX_BYTES | FIELD_TX_BYTES);
-    }
-
-    public static Bundle buildArgs(NetworkTemplate template, AppItem app, int fields) {
-        final Bundle args = new Bundle();
-        args.putParcelable(KEY_TEMPLATE, template);
-        args.putParcelable(KEY_APP, app);
-        args.putInt(KEY_FIELDS, fields);
-        return args;
-    }
-
-    public ChartDataLoaderCompat(Context context, INetworkStatsSession session, Bundle args) {
-        super(context);
-        mSession = session;
-        mArgs = args;
-    }
-
-    @Override
-    protected void onStartLoading() {
-        super.onStartLoading();
-        forceLoad();
-    }
-
-    @Override
-    public ChartData loadInBackground() {
-        final NetworkTemplate template = mArgs.getParcelable(KEY_TEMPLATE);
-        final AppItem app = mArgs.getParcelable(KEY_APP);
-        final int fields = mArgs.getInt(KEY_FIELDS);
-
-        try {
-            return loadInBackground(template, app, fields);
-        } catch (RemoteException e) {
-            // since we can't do much without history, and we don't want to
-            // leave with half-baked UI, we bail hard.
-            throw new RuntimeException("problem reading network stats", e);
-        }
-    }
-
-    private ChartData loadInBackground(NetworkTemplate template, AppItem app, int fields)
-            throws RemoteException {
-        final ChartData data = new ChartData();
-        data.network = mSession.getHistoryForNetwork(template, fields);
-
-        if (app != null) {
-            // load stats for current uid and template
-            final int size = app.uids.size();
-            for (int i = 0; i < size; i++) {
-                final int uid = app.uids.keyAt(i);
-                data.detailDefault = collectHistoryForUid(
-                        template, uid, SET_DEFAULT, data.detailDefault);
-                data.detailForeground = collectHistoryForUid(
-                        template, uid, SET_FOREGROUND, data.detailForeground);
-            }
-
-            if (size > 0) {
-                data.detail = new NetworkStatsHistory(data.detailForeground.getBucketDuration());
-                data.detail.recordEntireHistory(data.detailDefault);
-                data.detail.recordEntireHistory(data.detailForeground);
-            } else {
-                data.detailDefault = new NetworkStatsHistory(HOUR_IN_MILLIS);
-                data.detailForeground = new NetworkStatsHistory(HOUR_IN_MILLIS);
-                data.detail = new NetworkStatsHistory(HOUR_IN_MILLIS);
-            }
-        }
-
-        return data;
-    }
-
-    @Override
-    protected void onStopLoading() {
-        super.onStopLoading();
-        cancelLoad();
-    }
-
-    @Override
-    protected void onReset() {
-        super.onReset();
-        cancelLoad();
-    }
-
-    /**
-     * Collect {@link NetworkStatsHistory} for the requested UID, combining with
-     * an existing {@link NetworkStatsHistory} if provided.
-     */
-    private NetworkStatsHistory collectHistoryForUid(
-            NetworkTemplate template, int uid, int set, NetworkStatsHistory existing)
-            throws RemoteException {
-        final NetworkStatsHistory history = mSession.getHistoryForUid(
-                template, uid, set, TAG_NONE, FIELD_RX_BYTES | FIELD_TX_BYTES);
-
-        if (existing != null) {
-            existing.recordEntireHistory(history);
-            return existing;
-        } else {
-            return history;
-        }
-    }
-}
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
index 183d485..180b77e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
@@ -32,30 +32,24 @@
 import android.net.INetworkStatsSession;
 import android.net.NetworkPolicy;
 import android.net.NetworkPolicyManager;
-import android.net.NetworkStatsHistory;
 import android.net.NetworkTemplate;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.text.format.DateUtils;
-import android.util.FeatureFlagUtils;
 import android.util.Log;
 import android.util.Range;
 
 import com.android.internal.R;
-import com.android.internal.annotations.VisibleForTesting;
 
 import java.time.ZonedDateTime;
-import java.util.Date;
 import java.util.Iterator;
 import java.util.Locale;
 
 public class DataUsageController {
 
     private static final String TAG = "DataUsageController";
-    @VisibleForTesting
-    static final String DATA_USAGE_V2 = "settings_data_usage_v2";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
     private static final int FIELDS = FIELD_RX_BYTES | FIELD_TX_BYTES;
     private static final StringBuilder PERIOD_BUILDER = new StringBuilder(50);
@@ -95,21 +89,6 @@
                 * mContext.getResources().getInteger(R.integer.default_data_warning_level_mb);
     }
 
-    @VisibleForTesting
-    @Deprecated
-    INetworkStatsSession getSession() {
-        if (mSession == null) {
-            try {
-                mSession = mStatsService.openSession();
-            } catch (RemoteException e) {
-                Log.w(TAG, "Failed to open stats session", e);
-            } catch (RuntimeException e) {
-                Log.w(TAG, "Failed to open stats session", e);
-            }
-        }
-        return mSession;
-    }
-
     public void setCallback(Callback callback) {
         mCallback = callback;
     }
@@ -149,13 +128,7 @@
             end = now;
             start = now - DateUtils.WEEK_IN_MILLIS * 4;
         }
-        final long totalBytes;
-        final long callStart = System.currentTimeMillis();
-        if (FeatureFlagUtils.isEnabled(mContext, DATA_USAGE_V2)) {
-            totalBytes = getUsageLevel(template, start, end);
-        } else {
-            totalBytes = getUsageLevel(template, start, end, now);
-        }
+        final long totalBytes = getUsageLevel(template, start, end);
         if (totalBytes < 0L) {
             return warn("no entry data");
         }
@@ -185,32 +158,7 @@
      * retrieving the data.
      */
     public long getHistoricalUsageLevel(NetworkTemplate template) {
-        if (FeatureFlagUtils.isEnabled(mContext, DATA_USAGE_V2)) {
-            return getUsageLevel(template, 0L /* start */, System.currentTimeMillis() /* end */);
-        } else {
-            final long now = System.currentTimeMillis();
-            return getUsageLevel(template, 0L /* start */, now /* end */, now);
-        }
-    }
-
-    @Deprecated
-    private long getUsageLevel(NetworkTemplate template, long start, long end, long now) {
-        final INetworkStatsSession session = getSession();
-        if (session != null) {
-            try {
-                final NetworkStatsHistory history =
-                    session.getHistoryForNetwork(template, FIELDS);
-                final NetworkStatsHistory.Entry entry = history.getValues(
-                        start, end, System.currentTimeMillis() /* now */, null /* recycle */);
-                if (entry != null) {
-                    return entry.rxBytes + entry.txBytes;
-                }
-                Log.w(TAG, "Failed to get data usage, no entry data");
-            } catch (RemoteException e) {
-                Log.w(TAG, "Failed to get data usage, remote call failed");
-            }
-        }
-        return -1L;
+        return getUsageLevel(template, 0L /* start */, System.currentTimeMillis() /* end */);
     }
 
     private long getUsageLevel(NetworkTemplate template, long start, long end) {
@@ -241,20 +189,6 @@
         return null;
     }
 
-    @Deprecated
-    private static String historyEntryToString(NetworkStatsHistory.Entry entry) {
-        return entry == null ? null : new StringBuilder("Entry[")
-                .append("bucketDuration=").append(entry.bucketDuration)
-                .append(",bucketStart=").append(entry.bucketStart)
-                .append(",activeTime=").append(entry.activeTime)
-                .append(",rxBytes=").append(entry.rxBytes)
-                .append(",rxPackets=").append(entry.rxPackets)
-                .append(",txBytes=").append(entry.txBytes)
-                .append(",txPackets=").append(entry.txPackets)
-                .append(",operations=").append(entry.operations)
-                .append(']').toString();
-    }
-
     private static String statsBucketToString(Bucket bucket) {
         return bucket == null ? null : new StringBuilder("Entry[")
             .append("bucketDuration=").append(bucket.getEndTimeStamp() - bucket.getStartTimeStamp())
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/SummaryForAllUidLoaderCompat.java b/packages/SettingsLib/src/com/android/settingslib/net/SummaryForAllUidLoaderCompat.java
deleted file mode 100644
index 82bb011..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/net/SummaryForAllUidLoaderCompat.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net;
-
-import android.content.Context;
-import android.net.INetworkStatsSession;
-import android.net.NetworkStats;
-import android.net.NetworkTemplate;
-import android.os.Bundle;
-import android.os.RemoteException;
-
-import androidx.loader.content.AsyncTaskLoader;
-
-/**
- * Deprecated in favor of {@link NetworkStatsDetailLoader}
- *
- * @deprecated
- */
-@Deprecated
-public class SummaryForAllUidLoaderCompat extends AsyncTaskLoader<NetworkStats> {
-    private static final String KEY_TEMPLATE = "template";
-    private static final String KEY_START = "start";
-    private static final String KEY_END = "end";
-
-    private final INetworkStatsSession mSession;
-    private final Bundle mArgs;
-
-    public static Bundle buildArgs(NetworkTemplate template, long start, long end) {
-        final Bundle args = new Bundle();
-        args.putParcelable(KEY_TEMPLATE, template);
-        args.putLong(KEY_START, start);
-        args.putLong(KEY_END, end);
-        return args;
-    }
-
-    public SummaryForAllUidLoaderCompat(Context context, INetworkStatsSession session,
-            Bundle args) {
-        super(context);
-        mSession = session;
-        mArgs = args;
-    }
-
-    @Override
-    protected void onStartLoading() {
-        super.onStartLoading();
-        forceLoad();
-    }
-
-    @Override
-    public NetworkStats loadInBackground() {
-        final NetworkTemplate template = mArgs.getParcelable(KEY_TEMPLATE);
-        final long start = mArgs.getLong(KEY_START);
-        final long end = mArgs.getLong(KEY_END);
-
-        try {
-            return mSession.getSummaryForAllUid(template, start, end, false);
-        } catch (RemoteException e) {
-            return null;
-        }
-    }
-
-    @Override
-    protected void onStopLoading() {
-        super.onStopLoading();
-        cancelLoad();
-    }
-
-    @Override
-    protected void onReset() {
-        super.onReset();
-        cancelLoad();
-    }
-}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java
index 72ed5e1..acf99a2 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java
@@ -18,7 +18,6 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.anyLong;
@@ -35,12 +34,10 @@
 import android.net.ConnectivityManager;
 import android.net.INetworkStatsSession;
 import android.net.NetworkStatsHistory;
-import android.net.NetworkStatsHistory.Entry;
 import android.net.NetworkTemplate;
 import android.os.RemoteException;
 import android.telephony.TelephonyManager;
 import android.text.format.DateUtils;
-import android.util.FeatureFlagUtils;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -48,7 +45,6 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
 
 @RunWith(RobolectricTestRunner.class)
 public class DataUsageControllerTest {
@@ -61,16 +57,18 @@
     private TelephonyManager mTelephonyManager;
     @Mock
     private NetworkStatsManager mNetworkStatsManager;
-
+    @Mock
     private Context mContext;
+
     private DataUsageController mController;
     private NetworkStatsHistory mNetworkStatsHistory;
 
     @Before
     public void setUp() throws RemoteException {
         MockitoAnnotations.initMocks(this);
-        mContext = RuntimeEnvironment.application;
-        mController = spy(new DataUsageController(mContext));
+        when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
+        when(mContext.getSystemService(NetworkStatsManager.class)).thenReturn(mNetworkStatsManager);
+        mController = new DataUsageController(mContext);
         mNetworkStatsHistory = spy(
                 new NetworkStatsHistory(DateUtils.DAY_IN_MILLIS /* bucketDuration */));
         doReturn(mNetworkStatsHistory)
@@ -79,75 +77,25 @@
     }
 
     @Test
-    public void getHistoricalUsageLevel_v1_noNetworkSession_shouldReturnNegative1() {
-        FeatureFlagUtils.setEnabled(mContext, DataUsageController.DATA_USAGE_V2, false);
-        doReturn(null).when(mController).getSession();
+    public void getHistoricalUsageLevel_shouldQuerySummaryForDevice() throws Exception {
 
-        assertThat(mController.getHistoricalUsageLevel(null /* template */)).isEqualTo(-1L);
-    }
-
-    @Test
-    public void getHistoriclUsageLevel_v1_noUsageData_shouldReturn0() {
-        FeatureFlagUtils.setEnabled(mContext, DataUsageController.DATA_USAGE_V2, false);
-        doReturn(mSession).when(mController).getSession();
-
-        assertThat(mController.getHistoricalUsageLevel(NetworkTemplate.buildTemplateWifiWildcard()))
-                .isEqualTo(0L);
-    }
-
-    @Test
-    public void getHistoricalUsageLevel_v1_hasUsageData_shouldReturnTotalUsage() {
-        FeatureFlagUtils.setEnabled(mContext, DataUsageController.DATA_USAGE_V2, false);
-        doReturn(mSession).when(mController).getSession();
-        final long receivedBytes = 743823454L;
-        final long transmittedBytes = 16574289L;
-        final Entry entry = new Entry();
-        entry.bucketStart = 1521583200000L;
-        entry.rxBytes = receivedBytes;
-        entry.txBytes = transmittedBytes;
-        when(mNetworkStatsHistory.getValues(eq(0L), anyLong(), anyLong(), nullable(Entry.class)))
-                .thenReturn(entry);
-
-        assertThat(mController.getHistoricalUsageLevel(NetworkTemplate.buildTemplateWifiWildcard()))
-                .isEqualTo(receivedBytes + transmittedBytes);
-    }
-
-    @Test
-    public void getHistoricalUsageLevel_v2_shouldQuerySummaryForDevice() throws Exception {
-        final Context context = mock(Context.class);
-        FeatureFlagUtils.setEnabled(context, DataUsageController.DATA_USAGE_V2, true);
-        when(context.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
-        when(context.getSystemService(NetworkStatsManager.class)).thenReturn(mNetworkStatsManager);
-        final DataUsageController controller = new DataUsageController(context);
-
-        controller.getHistoricalUsageLevel(NetworkTemplate.buildTemplateWifiWildcard());
+        mController.getHistoricalUsageLevel(NetworkTemplate.buildTemplateWifiWildcard());
 
         verify(mNetworkStatsManager).querySummaryForDevice(eq(ConnectivityManager.TYPE_WIFI),
                 eq(SUB_ID), eq(0L) /* startTime */, anyLong() /* endTime */);
     }
 
     @Test
-    public void getHistoricalUsageLevel_v2NoUsageData_shouldReturn0() throws Exception {
-        final Context context = mock(Context.class);
-        FeatureFlagUtils.setEnabled(context, DataUsageController.DATA_USAGE_V2, true);
-        when(context.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
-        when(context.getSystemService(NetworkStatsManager.class)).thenReturn(mNetworkStatsManager);
+    public void getHistoricalUsageLevel_noUsageData_shouldReturn0() throws Exception {
         when(mNetworkStatsManager.querySummaryForDevice(eq(ConnectivityManager.TYPE_WIFI),
                 eq(SUB_ID), eq(0L) /* startTime */, anyLong() /* endTime */))
                 .thenReturn(mock(NetworkStats.Bucket.class));
-        final DataUsageController controller = new DataUsageController(context);
-
-        assertThat(controller.getHistoricalUsageLevel(NetworkTemplate.buildTemplateWifiWildcard()))
+        assertThat(mController.getHistoricalUsageLevel(NetworkTemplate.buildTemplateWifiWildcard()))
             .isEqualTo(0L);
     }
 
     @Test
-    public void getHistoricalUsageLevel_v2HasUsageData_shouldReturnTotalUsage()
-            throws Exception {
-        final Context context = mock(Context.class);
-        FeatureFlagUtils.setEnabled(context, DataUsageController.DATA_USAGE_V2, true);
-        when(context.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
-        when(context.getSystemService(NetworkStatsManager.class)).thenReturn(mNetworkStatsManager);
+    public void getHistoricalUsageLevel_hasUsageData_shouldReturnTotalUsage() throws Exception {
         final long receivedBytes = 743823454L;
         final long transmittedBytes = 16574289L;
         final NetworkStats.Bucket bucket = mock(NetworkStats.Bucket.class);
@@ -155,9 +103,8 @@
         when(bucket.getTxBytes()).thenReturn(transmittedBytes);
         when(mNetworkStatsManager.querySummaryForDevice(eq(ConnectivityManager.TYPE_WIFI),
                 eq(SUB_ID), eq(0L) /* startTime */, anyLong() /* endTime */)).thenReturn(bucket);
-        final DataUsageController controller = new DataUsageController(context);
 
-        assertThat(controller.getHistoricalUsageLevel(NetworkTemplate.buildTemplateWifiWildcard()))
+        assertThat(mController.getHistoricalUsageLevel(NetworkTemplate.buildTemplateWifiWildcard()))
                 .isEqualTo(receivedBytes + transmittedBytes);
     }
 }
diff --git a/packages/SystemUI/res/anim/dismiss_all_shape_animation_1.xml b/packages/SystemUI/res/anim/dismiss_all_shape_animation_1.xml
deleted file mode 100644
index 3cc98d8..0000000
--- a/packages/SystemUI/res/anim/dismiss_all_shape_animation_1.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<!-- Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="500"
-        android:propertyXName="translateX"
-        android:propertyYName="translateY"
-        android:pathData="M 0,0 c 31.33333,0 156.66667,0 188,0 "
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/dismiss_all_shape_animation_2.xml b/packages/SystemUI/res/anim/dismiss_all_shape_animation_2.xml
deleted file mode 100644
index eda843d..0000000
--- a/packages/SystemUI/res/anim/dismiss_all_shape_animation_2.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<!-- Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="33"
-            android:propertyXName="translateX"
-            android:propertyYName="translateY"
-            android:pathData="M -12,18 L -12,18" />
-        <objectAnimator
-            android:duration="500"
-            android:propertyXName="translateX"
-            android:propertyYName="translateY"
-            android:pathData="M -12,18 c 31.33333,0 156.66667,0 188,0 "
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/dismiss_all_shape_animation_3.xml b/packages/SystemUI/res/anim/dismiss_all_shape_animation_3.xml
deleted file mode 100644
index cab3d5c..0000000
--- a/packages/SystemUI/res/anim/dismiss_all_shape_animation_3.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<!-- Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="67"
-            android:propertyXName="translateX"
-            android:propertyYName="translateY"
-            android:pathData="M -24,36 L -24,36" />
-        <objectAnimator
-            android:duration="500"
-            android:propertyXName="translateX"
-            android:propertyYName="translateY"
-            android:pathData="M -24,36 c 31.33333,0 156.66667,0 188,0 "
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1.xml b/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1.xml
deleted file mode 100644
index e435d9a..0000000
--- a/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!-- Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="150"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="100"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1_1.xml b/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1_1.xml
deleted file mode 100644
index e31a7db..0000000
--- a/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1_1.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!-- Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="183"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="100"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1_2.xml b/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1_2.xml
deleted file mode 100644
index 2409612..0000000
--- a/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1_2.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!-- Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="217"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="100"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/fab_elevation.xml b/packages/SystemUI/res/anim/fab_elevation.xml
deleted file mode 100644
index 2c76a86..0000000
--- a/packages/SystemUI/res/anim/fab_elevation.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_enabled="true" android:state_pressed="true">
-        <set>
-            <objectAnimator
-                android:duration="@android:integer/config_shortAnimTime"
-                android:propertyName="translationZ"
-                android:valueTo="@dimen/fab_press_translation_z"
-                android:valueType="floatType" />
-        </set>
-    </item>
-    <item>
-        <set>
-            <objectAnimator
-                android:duration="@android:integer/config_shortAnimTime"
-                android:propertyName="translationZ"
-                android:valueTo="0"
-                android:valueType="floatType" />
-        </set>
-    </item>
-</selector>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_rotate_arrows_animation.xml b/packages/SystemUI/res/anim/ic_landscape_to_rotate_arrows_animation.xml
deleted file mode 100644
index 8fdad80..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_to_rotate_arrows_animation.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2017 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="616"
-        android:propertyName="rotation"
-        android:valueFrom="-90.0"
-        android:valueTo="0.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_rotate_bottom_merged_animation.xml b/packages/SystemUI/res/anim/ic_landscape_to_rotate_bottom_merged_animation.xml
deleted file mode 100644
index 3c3c131..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_to_rotate_bottom_merged_animation.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2017 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="50"
-            android:propertyName="fillAlpha"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="fillAlpha"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_rotate_landscape_animation.xml b/packages/SystemUI/res/anim/ic_landscape_to_rotate_landscape_animation.xml
deleted file mode 100644
index 57132e1..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_to_rotate_landscape_animation.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2017 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="466"
-        android:propertyName="scaleX"
-        android:valueFrom="1.0"
-        android:valueTo="0.909"
-        android:valueType="floatType"
-        android:interpolator="@interpolator/ic_landscape_to_rotate_animation_interpolator_0" />
-    <objectAnimator
-        android:duration="466"
-        android:propertyName="scaleY"
-        android:valueFrom="1.0"
-        android:valueTo="0.909"
-        android:valueType="floatType"
-        android:interpolator="@interpolator/ic_landscape_to_rotate_animation_interpolator_0" />
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="50"
-            android:propertyName="rotation"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="400"
-            android:propertyName="rotation"
-            android:valueFrom="0.0"
-            android:valueTo="45.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_0_animation.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_0_animation.xml
deleted file mode 100644
index ad2a5fa..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_0_animation.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2017 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="116"
-            android:propertyName="scaleX"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleX"
-            android:valueFrom="1.0"
-            android:valueTo="0.9"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="116"
-            android:propertyName="scaleY"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleY"
-            android:valueFrom="1.0"
-            android:valueTo="0.9"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_animation.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_animation.xml
deleted file mode 100644
index cdb7890..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_animation.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2017 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="616"
-        android:propertyName="rotation"
-        android:valueFrom="0.0"
-        android:valueTo="-221.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_rotate_bottom_merged_animation.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_bottom_merged_animation.xml
deleted file mode 100644
index 46100b4..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_to_rotate_bottom_merged_animation.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2017 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="400"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_0_animation.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_0_animation.xml
deleted file mode 100644
index 8f6d24d..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_0_animation.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2017 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="400"
-        android:propertyName="rotation"
-        android:valueFrom="0.0"
-        android:valueTo="-135.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_merged_animation.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_merged_animation.xml
deleted file mode 100644
index 300ed53..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_merged_animation.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2017 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="66"
-            android:propertyName="pathData"
-            android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-            android:valueTo="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="216"
-            android:propertyName="pathData"
-            android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-            android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_0_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_0_animation.xml
deleted file mode 100644
index ad2a5fa..0000000
--- a/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_0_animation.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2017 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="116"
-            android:propertyName="scaleX"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleX"
-            android:valueFrom="1.0"
-            android:valueTo="0.9"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="116"
-            android:propertyName="scaleY"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleY"
-            android:valueFrom="1.0"
-            android:valueTo="0.9"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_animation.xml
deleted file mode 100644
index c152152..0000000
--- a/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_animation.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2017 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="616"
-        android:propertyName="rotation"
-        android:valueFrom="0.0"
-        android:valueTo="-180.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_landscape_bottom_merged_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_landscape_bottom_merged_animation.xml
deleted file mode 100644
index b2c1eb8..0000000
--- a/packages/SystemUI/res/anim/ic_rotate_to_landscape_bottom_merged_animation.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2017 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_landscape_landscape_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_landscape_landscape_animation.xml
deleted file mode 100644
index 2a9bbe3..0000000
--- a/packages/SystemUI/res/anim/ic_rotate_to_landscape_landscape_animation.xml
+++ /dev/null
@@ -1,60 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2017 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="116"
-            android:propertyName="scaleX"
-            android:valueFrom="0.909"
-            android:valueTo="0.909"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="166"
-            android:propertyName="scaleX"
-            android:valueFrom="0.909"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/ic_rotate_to_landscape_animation_interpolator_0" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="116"
-            android:propertyName="scaleY"
-            android:valueFrom="0.909"
-            android:valueTo="0.909"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="166"
-            android:propertyName="scaleY"
-            android:valueFrom="0.909"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/ic_rotate_to_landscape_animation_interpolator_0" />
-    </set>
-    <objectAnimator
-        android:duration="616"
-        android:propertyName="rotation"
-        android:valueFrom="45.0"
-        android:valueTo="0.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_0_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_0_animation.xml
deleted file mode 100644
index ce26770..0000000
--- a/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_0_animation.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2017 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="466"
-        android:propertyName="scaleX"
-        android:valueFrom="0.9"
-        android:valueTo="1.0"
-        android:valueType="floatType"
-        android:interpolator="@interpolator/ic_rotate_to_portrait_animation_interpolator_0" />
-    <objectAnimator
-        android:duration="466"
-        android:propertyName="scaleY"
-        android:valueFrom="0.9"
-        android:valueTo="1.0"
-        android:valueType="floatType"
-        android:interpolator="@interpolator/ic_rotate_to_portrait_animation_interpolator_0" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_animation.xml
deleted file mode 100644
index 6e8941d..0000000
--- a/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_animation.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2017 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="616"
-        android:propertyName="rotation"
-        android:valueFrom="-221.0"
-        android:valueTo="0.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_portrait_bottom_merged_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_bottom_merged_animation.xml
deleted file mode 100644
index 3c3c131..0000000
--- a/packages/SystemUI/res/anim/ic_rotate_to_portrait_bottom_merged_animation.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2017 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="50"
-            android:propertyName="fillAlpha"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="fillAlpha"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_0_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_0_animation.xml
deleted file mode 100644
index fd8e4f8..0000000
--- a/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_0_animation.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2017 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="50"
-            android:propertyName="rotation"
-            android:valueFrom="-135.0"
-            android:valueTo="-135.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="400"
-            android:propertyName="rotation"
-            android:valueFrom="-135.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_merged_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_merged_animation.xml
deleted file mode 100644
index a77a536..0000000
--- a/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_merged_animation.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2017 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="50"
-            android:propertyName="pathData"
-            android:valueFrom="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
-            android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="500"
-            android:propertyName="pathData"
-            android:valueFrom="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
-            android:valueTo="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_blink_1.xml b/packages/SystemUI/res/anim/ic_signal_blink_1.xml
deleted file mode 100644
index 64580d1..0000000
--- a/packages/SystemUI/res/anim/ic_signal_blink_1.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<!--
-    Copyright (C) 2015 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:interpolator="@android:anim/linear_interpolator"
-    android:duration="@integer/carrier_network_change_anim_time"
-    android:repeatCount="-1">
-
-    <propertyValuesHolder
-        android:propertyName="fillColor"
-        android:valueType="colorType">
-        <keyframe
-            android:fraction="0.0"
-            android:value="?attr/fillColor"/>
-        <keyframe
-            android:fraction="0.32"
-            android:value="?attr/fillColor"/>
-        <keyframe
-            android:fraction="0.33"
-            android:value="?attr/backgroundColor"/>
-        <keyframe
-            android:fraction="1.0"
-            android:value="?attr/backgroundColor"/>
-    </propertyValuesHolder>
-
-</objectAnimator>
diff --git a/packages/SystemUI/res/anim/ic_signal_blink_2.xml b/packages/SystemUI/res/anim/ic_signal_blink_2.xml
deleted file mode 100644
index f055cd07..0000000
--- a/packages/SystemUI/res/anim/ic_signal_blink_2.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<!--
-    Copyright (C) 2015 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:interpolator="@android:anim/linear_interpolator"
-    android:duration="@integer/carrier_network_change_anim_time"
-    android:repeatCount="-1">
-
-    <propertyValuesHolder
-        android:propertyName="fillColor"
-        android:valueType="colorType">
-        <keyframe
-            android:fraction="0.0"
-            android:value="?attr/backgroundColor"/>
-        <keyframe
-            android:fraction="0.32"
-            android:value="?attr/backgroundColor"/>
-        <keyframe
-            android:fraction="0.33"
-            android:value="?attr/fillColor"/>
-        <keyframe
-            android:fraction="0.66"
-            android:value="?attr/fillColor"/>
-        <keyframe
-            android:fraction="0.67"
-            android:value="?attr/backgroundColor"/>
-        <keyframe
-            android:fraction="1.0"
-            android:value="?attr/backgroundColor"/>
-    </propertyValuesHolder>
-
-</objectAnimator>
diff --git a/packages/SystemUI/res/anim/ic_signal_blink_3.xml b/packages/SystemUI/res/anim/ic_signal_blink_3.xml
deleted file mode 100644
index abcd774..0000000
--- a/packages/SystemUI/res/anim/ic_signal_blink_3.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<!--
-    Copyright (C) 2015 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:interpolator="@android:anim/linear_interpolator"
-    android:duration="@integer/carrier_network_change_anim_time"
-    android:repeatCount="-1">
-
-    <propertyValuesHolder
-        android:propertyName="fillColor"
-        android:valueType="colorType">
-        <keyframe
-            android:fraction="0.0"
-            android:value="?attr/backgroundColor"/>
-        <keyframe
-            android:fraction="0.66"
-            android:value="?attr/backgroundColor"/>
-        <keyframe
-            android:fraction="0.67"
-            android:value="?attr/fillColor"/>
-        <keyframe
-            android:fraction="1.0"
-            android:value="?attr/fillColor"/>
-    </propertyValuesHolder>
-
-</objectAnimator>
diff --git a/packages/SystemUI/res/anim/system_in.xml b/packages/SystemUI/res/anim/system_in.xml
deleted file mode 100644
index 630fd72..0000000
--- a/packages/SystemUI/res/anim/system_in.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-    >
-    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
-        android:duration="@android:integer/config_longAnimTime" 
-        />
-</set>
diff --git a/packages/SystemUI/res/anim/system_out.xml b/packages/SystemUI/res/anim/system_out.xml
deleted file mode 100644
index 4717e47..0000000
--- a/packages/SystemUI/res/anim/system_out.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-    >
-    <alpha android:toAlpha="0.0" android:fromAlpha="1.0"
-        android:duration="@android:integer/config_longAnimTime" 
-        />
-</set>
diff --git a/packages/SystemUI/res/drawable/dismiss_all_shape_animation.xml b/packages/SystemUI/res/drawable/dismiss_all_shape_animation.xml
deleted file mode 100644
index 9e71cbe..0000000
--- a/packages/SystemUI/res/drawable/dismiss_all_shape_animation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/dismiss_all_shape" >
-    <target
-        android:name="3"
-        android:animation="@anim/dismiss_all_shape_animation_3" />
-    <target
-        android:name="rectangle_path_1_2"
-        android:animation="@anim/dismiss_all_shape_animation_rectangle_path_1_2" />
-    <target
-        android:name="2"
-        android:animation="@anim/dismiss_all_shape_animation_2" />
-    <target
-        android:name="rectangle_path_1_1"
-        android:animation="@anim/dismiss_all_shape_animation_rectangle_path_1_1" />
-    <target
-        android:name="1"
-        android:animation="@anim/dismiss_all_shape_animation_1" />
-    <target
-        android:name="rectangle_path_1"
-        android:animation="@anim/dismiss_all_shape_animation_rectangle_path_1" />
-</animated-vector>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AmbientPulseManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/AmbientPulseManager.java
index a5e7f04..8821679 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/AmbientPulseManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/AmbientPulseManager.java
@@ -33,7 +33,7 @@
  * dozing and/or in AOD.  The pulse uses the notification's ambient view and pops in briefly
  * before automatically dismissing the alert.
  */
-public final class AmbientPulseManager extends AlertingNotificationManager {
+public class AmbientPulseManager extends AlertingNotificationManager {
 
     protected final ArraySet<OnAmbientChangedListener> mListeners = new ArraySet<>();
     @VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index e7b4904..ac4abfc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -225,7 +225,7 @@
             }
             viewState.hasItemsInStableShelf = lastViewState.inShelf;
             viewState.hidden = !mAmbientState.isShadeExpanded()
-                    || mAmbientState.isQsCustomizerShowing();
+                    || mAmbientState.isQsCustomizerShowing() || mAmbientState.isFullyDark();
             viewState.maxShelfEnd = maxShelfEnd;
         } else {
             viewState.hidden = true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
index 1616b6d..70d144e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
@@ -952,10 +952,12 @@
 
         // Has a copy of the current UI adjustments.
         ArrayMap<String, NotificationUiAdjustment> oldAdjustments = new ArrayMap<>();
+        ArrayMap<String, Integer> oldImportances = new ArrayMap<>();
         for (NotificationData.Entry entry : entries) {
             NotificationUiAdjustment adjustment =
                     NotificationUiAdjustment.extractFromNotificationEntry(entry);
             oldAdjustments.put(entry.key, adjustment);
+            oldImportances.put(entry.key, entry.importance);
         }
 
         // Populate notification entries from the new rankings.
@@ -978,6 +980,11 @@
                     // Once the RowInflaterTask is done, it will pick up the updated entry, so
                     // no-op here.
                 }
+            } else if (oldImportances.containsKey(entry.key)
+                    && entry.importance != oldImportances.get(entry.key)) {
+                if (entry.rowExists()) {
+                    entry.getRow().onNotificationRankingUpdated();
+                }
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index d4d45ea..63fe04a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -588,6 +588,13 @@
         updateRippleAllowed();
     }
 
+    /** Called when the notification's ranking was changed (but nothing else changed). */
+    public void onNotificationRankingUpdated() {
+        if (mMenuRow != null) {
+            mMenuRow.onNotificationUpdated(mStatusBarNotification);
+        }
+    }
+
     @VisibleForTesting
     void updateShelfIconColor() {
         StatusBarIconView expandedIcon = mEntry.expandedIcon;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
index 948d2a5..50564e3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
@@ -267,7 +267,9 @@
         } else {
             mRightMenuItems.add(mInfoItem);
             mRightMenuItems.add(mAppOpsItem);
-            mRightMenuItems.add(mSnoozeItem);
+            if (!isForeground) {
+                mRightMenuItems.add(mSnoozeItem);
+            }
         }
 
         populateMenuViews();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 626e688..5d640e0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -18,6 +18,8 @@
 
 import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator
         .ExpandAnimationParameters;
+import static com.android.systemui.statusbar.notification.stack.StackStateAnimator
+        .ANIMATION_DURATION_SWIPE;
 import static com.android.systemui.statusbar.phone.NotificationIconAreaController.LOW_PRIORITY;
 
 import android.animation.Animator;
@@ -5093,7 +5095,7 @@
             if (i == 0) {
                 endRunnable = animationFinishAction;
             }
-            dismissViewAnimated(view, endRunnable, totalDelay, 260);
+            dismissViewAnimated(view, endRunnable, totalDelay, ANIMATION_DURATION_SWIPE);
             currentDelay = Math.max(50, currentDelay - rowDelayDecrement);
             totalDelay += currentDelay;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
index fef28cf..d690547 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
@@ -44,6 +44,7 @@
     public static final int ANIMATION_DURATION_WAKEUP = 500;
     public static final int ANIMATION_DURATION_GO_TO_FULL_SHADE = 448;
     public static final int ANIMATION_DURATION_APPEAR_DISAPPEAR = 464;
+    public static final int ANIMATION_DURATION_SWIPE = 260;
     public static final int ANIMATION_DURATION_DIMMED_ACTIVATED = 220;
     public static final int ANIMATION_DURATION_CLOSE_REMOTE_INPUT = 150;
     public static final int ANIMATION_DURATION_HEADS_UP_APPEAR = 550;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationGestureAction.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationGestureAction.java
index 83067f6..a8d00c4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationGestureAction.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationGestureAction.java
@@ -127,6 +127,15 @@
     }
 
     /**
+     * Decide if the controller should not send the current motion event to launcher via
+     * {@link OverviewProxyService}
+     * @return if controller should not proxy
+     */
+    public boolean disableProxyEvents() {
+        return false;
+    }
+
+    /**
      * Tell if action is enabled. Compared to {@link #canPerformAction()} this is based on settings
      * if the action is disabled for a particular gesture. For example a back action can be enabled
      * however if there is nothing to back to then {@link #canPerformAction()} should return false.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubAction.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubAction.java
index 74744f1..2b202eb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubAction.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubAction.java
@@ -212,6 +212,11 @@
     }
 
     @Override
+    public boolean disableProxyEvents() {
+        return true;
+    }
+
+    @Override
     protected void onGestureStart(MotionEvent event) {
         updateHighlight();
         ObjectAnimator trackAnimator = ObjectAnimator.ofPropertyValuesHolder(this,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
index 43e86d6..2cbf27c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
@@ -275,25 +275,21 @@
                         if (mDragVPositive ? (posV < touchDownV) : (posV > touchDownV)) {
                             // Swiping up gesture
                             tryToStartGesture(mGestureActions[ACTION_SWIPE_UP_INDEX],
-                                    false /* alignedWithNavBar */, false /* positiveDirection */,
-                                    event);
+                                    false /* alignedWithNavBar */, event);
                         } else {
                             // Swiping down gesture
                             tryToStartGesture(mGestureActions[ACTION_SWIPE_DOWN_INDEX],
-                                    false /* alignedWithNavBar */, true /* positiveDirection */,
-                                    event);
+                                    false /* alignedWithNavBar */, event);
                         }
                     } else if (exceededSwipeHorizontalTouchSlop) {
                         if (mDragHPositive ? (posH < touchDownH) : (posH > touchDownH)) {
                             // Swiping left (ltr) gesture
                             tryToStartGesture(mGestureActions[ACTION_SWIPE_LEFT_INDEX],
-                                    true /* alignedWithNavBar */, false /* positiveDirection */,
-                                    event);
+                                    true /* alignedWithNavBar */, event);
                         } else {
                             // Swiping right (ltr) gesture
                             tryToStartGesture(mGestureActions[ACTION_SWIPE_RIGHT_INDEX],
-                                    true /* alignedWithNavBar */, true /* positiveDirection */,
-                                    event);
+                                    true /* alignedWithNavBar */, event);
                         }
                     }
                 }
@@ -306,7 +302,6 @@
             case MotionEvent.ACTION_UP:
                 if (mCurrentAction != null) {
                     mCurrentAction.endGesture();
-                    mCurrentAction = null;
                 }
 
                 // Return the hit target back to its original position
@@ -329,6 +324,11 @@
         if (shouldProxyEvents(action)) {
             proxyMotionEvents(event);
         }
+
+        // Clear action when gesture and event proxy finishes
+        if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
+            mCurrentAction = null;
+        }
         return mCurrentAction != null || deadZoneConsumed;
     }
 
@@ -354,8 +354,7 @@
 
     private boolean shouldProxyEvents(int action) {
         final boolean actionValid = (mCurrentAction == null
-                || (mGestureActions[ACTION_SWIPE_UP_INDEX] != null
-                        && mGestureActions[ACTION_SWIPE_UP_INDEX].isActive()));
+                || !mCurrentAction.disableProxyEvents());
         if (actionValid && !mIsInScreenPinning) {
             // Allow down, cancel and up events, move and other events are passed if notifications
             // are not showing and disabled gestures (such as long press) are not executed
@@ -455,7 +454,7 @@
     }
 
     private void tryToStartGesture(NavigationGestureAction action, boolean alignedWithNavBar,
-            boolean positiveDirection, MotionEvent event) {
+            MotionEvent event) {
         if (action == null) {
             return;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index cfd53be..5723948 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -474,8 +474,10 @@
                 return;
             }
             WallpaperInfo info = wallpaperManager.getWallpaperInfo(UserHandle.USER_CURRENT);
-            final boolean supportsAmbientMode = info != null &&
-                    info.supportsAmbientMode();
+            final boolean deviceSupportsAodWallpaper = mContext.getResources().getBoolean(
+                    com.android.internal.R.bool.config_dozeSupportsAodWallpaper);
+            final boolean supportsAmbientMode = deviceSupportsAodWallpaper
+                    && info != null && info.supportsAmbientMode();
 
             mStatusBarWindowController.setWallpaperSupportsAmbientMode(supportsAmbientMode);
             mScrimController.setWallpaperSupportsAmbientMode(supportsAmbientMode);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index 978a72d..53e461d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -49,6 +49,7 @@
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 import android.view.Window;
+import android.view.WindowInsetsController;
 import android.widget.FrameLayout;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -785,6 +786,11 @@
         @Override
         public void reportActivityRelaunched() {
         }
+
+        @Override
+        public WindowInsetsController getInsetsController() {
+            return null;
+        }
     };
 
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
index 8517d90..c2af95e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
@@ -165,7 +165,7 @@
         mClockVisibleByUser = bundle.getBoolean(VISIBLE_BY_USER, true);
         mShowSeconds = bundle.getBoolean(SHOW_SECONDS, false);
         if (bundle.containsKey(VISIBILITY)) {
-            setVisibility(bundle.getInt(VISIBILITY));
+            super.setVisibility(bundle.getInt(VISIBILITY));
         }
     }
 
@@ -203,6 +203,7 @@
 
         // Make sure we update to the current time
         updateClock();
+        updateClockVisibility();
         updateShowSeconds();
     }
 
@@ -247,6 +248,15 @@
         }
     };
 
+    @Override
+    public void setVisibility(int visibility) {
+        if (visibility == View.VISIBLE && !shouldBeVisible()) {
+            return;
+        }
+
+        super.setVisibility(visibility);
+    }
+
     public void setClockVisibleByUser(boolean visible) {
         mClockVisibleByUser = visible;
         updateClockVisibility();
@@ -257,11 +267,15 @@
         updateClockVisibility();
     }
 
+    private boolean shouldBeVisible() {
+        return mClockVisibleByPolicy && mClockVisibleByUser;
+    }
+
     private void updateClockVisibility() {
-        boolean visible = mClockVisibleByPolicy && mClockVisibleByUser;
+        boolean visible = shouldBeVisible();
         Dependency.get(IconLogger.class).onIconVisibility("clock", visible);
         int visibility = visible ? View.VISIBLE : View.GONE;
-        setVisibility(visibility);
+        super.setVisibility(visibility);
     }
 
     final void updateClock() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java
index 4177cd1..8fc15b2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java
@@ -38,12 +38,12 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
-import android.content.Context;
 import com.android.systemui.R;
 import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.shared.recents.IOverviewProxy;
 import com.android.systemui.SysuiTestCase;
 
+import android.content.Context;
 import android.content.res.Resources;
 import android.support.test.filters.SmallTest;
 import android.testing.AndroidTestingRunner;
@@ -395,6 +395,7 @@
         verify(mProxy, times(1)).onQuickScrubStart();
         verify(mProxyService, times(1)).notifyQuickScrubStarted();
         verify(mNavigationBarView, times(1)).updateSlippery();
+        verify(mProxy, never()).onMotionEvent(moveEvent1);
 
         // Move again for scrub
         MotionEvent moveEvent2 = event(MotionEvent.ACTION_MOVE, 200, y);
@@ -402,6 +403,7 @@
         assertEquals(action, mController.getCurrentAction());
         verify(action, times(1)).onGestureMove(200, y);
         verify(mProxy, times(1)).onQuickScrubProgress(1f / 2);
+        verify(mProxy, never()).onMotionEvent(moveEvent2);
 
         // Action up
         MotionEvent upEvent = event(MotionEvent.ACTION_UP, 1, y);
@@ -409,6 +411,7 @@
         assertNull(mController.getCurrentAction());
         verify(action, times(1)).onGestureEnd();
         verify(mProxy, times(1)).onQuickScrubEnd();
+        verify(mProxy, never()).onMotionEvent(upEvent);
     }
 
     @Test
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index 9aa9d7c..af65759 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -40,9 +40,9 @@
 import android.text.format.DateUtils;
 import android.util.Slog;
 
-import com.android.server.AbstractRemoteService;
+import com.android.server.AbstractSinglePendingRequestRemoteService;
 
-final class RemoteFillService extends AbstractRemoteService {
+final class RemoteFillService extends AbstractSinglePendingRequestRemoteService<RemoteFillService> {
 
     private static final long TIMEOUT_IDLE_BIND_MILLIS = 5 * DateUtils.SECOND_IN_MILLIS;
     private static final long TIMEOUT_REMOTE_REQUEST_MILLIS = 5 * DateUtils.SECOND_IN_MILLIS;
@@ -69,8 +69,8 @@
         mCallbacks = callbacks;
     }
 
-    @Override
-    protected void onConnectedStateChanged(boolean state) {
+    @Override // from AbstractRemoteService
+    protected void handleOnConnectedStateChanged(boolean state) {
         if (mAutoFillService == null) {
             Slog.w(mTag, "onConnectedStateChanged(): null service");
             return;
@@ -82,18 +82,18 @@
         }
     }
 
-    @Override
+    @Override // from AbstractRemoteService
     protected IInterface getServiceInterface(IBinder service) {
         mAutoFillService = IAutoFillService.Stub.asInterface(service);
         return mAutoFillService;
     }
 
-    @Override
+    @Override // from AbstractRemoteService
     protected long getTimeoutIdleBindMillis() {
         return TIMEOUT_IDLE_BIND_MILLIS;
     }
 
-    @Override
+    @Override // from AbstractRemoteService
     protected long getRemoteRequestMillis() {
         return TIMEOUT_REMOTE_REQUEST_MILLIS;
     }
@@ -136,6 +136,19 @@
         scheduleRequest(new PendingSaveRequest(request, this));
     }
 
+    private boolean handleResponseCallbackCommon(
+            @NonNull PendingRequest<RemoteFillService> pendingRequest) {
+        if (isDestroyed()) return false;
+
+        if (mPendingRequest == pendingRequest) {
+            mPendingRequest = null;
+        }
+        if (mPendingRequest == null) {
+            scheduleUnbind();
+        }
+        return true;
+    }
+
     private void dispatchOnFillRequestSuccess(@NonNull PendingFillRequest pendingRequest,
             @Nullable FillResponse response, int requestFlags) {
         mHandler.post(() -> {
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 8676f7f..4c64507 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -902,7 +902,7 @@
 
     // VultureCallback
     @Override
-    public void onServiceDied(AbstractRemoteService service) {
+    public void onServiceDied(AbstractRemoteService<? extends AbstractRemoteService<?>> service) {
         Slog.w(TAG, "removing session because service died");
         forceRemoveSelfLocked();
     }
diff --git a/services/core/java/com/android/server/AbstractMultiplePendingRequestsRemoteService.java b/services/core/java/com/android/server/AbstractMultiplePendingRequestsRemoteService.java
new file mode 100644
index 0000000..f532b22
--- /dev/null
+++ b/services/core/java/com/android/server/AbstractMultiplePendingRequestsRemoteService.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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;
+
+import android.annotation.NonNull;
+import android.content.ComponentName;
+import android.content.Context;
+import android.util.Slog;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+/**
+ * Base class representing a remote service that can queue multiple pending requests while not
+ * bound.
+ *
+ * @param <S> the concrete remote service class
+ *
+ * @hide
+ */
+public abstract class AbstractMultiplePendingRequestsRemoteService<
+        S extends AbstractMultiplePendingRequestsRemoteService<S>>
+        extends AbstractRemoteService<S> {
+
+    private final int mInitialCapacity;
+
+    protected ArrayList<PendingRequest<S>> mPendingRequests;
+
+    public AbstractMultiplePendingRequestsRemoteService(@NonNull Context context,
+            @NonNull String serviceInterface, @NonNull ComponentName componentName, int userId,
+            @NonNull VultureCallback callback, boolean bindInstantServiceAllowed, boolean verbose,
+            int initialCapacity) {
+        super(context, serviceInterface, componentName, userId, callback, bindInstantServiceAllowed,
+                verbose);
+        mInitialCapacity = initialCapacity;
+    }
+
+    @Override // from AbstractRemoteService
+    void handlePendingRequests() {
+        if (mPendingRequests != null) {
+            final int size = mPendingRequests.size();
+            if (mVerbose) Slog.v(mTag, "Sending " + size + " pending requests");
+            for (int i = 0; i < size; i++) {
+                mPendingRequests.get(i).run();
+            }
+            mPendingRequests = null;
+        }
+    }
+
+    @Override // from AbstractRemoteService
+    protected void handleOnDestroy() {
+        if (mPendingRequests != null) {
+            final int size = mPendingRequests.size();
+            if (mVerbose) Slog.v(mTag, "Canceling " + size + " pending requests");
+            for (int i = 0; i < size; i++) {
+                mPendingRequests.get(i).cancel();
+            }
+            mPendingRequests = null;
+        }
+    }
+
+    @Override // from AbstractRemoteService
+    public void dump(@NonNull String prefix, @NonNull PrintWriter pw) {
+        super.dump(prefix, pw);
+
+        pw.append(prefix).append("initialCapacity=").append(String.valueOf(mInitialCapacity))
+                .println();
+        final int size = mPendingRequests == null ? 0 : mPendingRequests.size();
+        pw.append(prefix).append("pendingRequests=").append(String.valueOf(size)).println();
+    }
+
+    @Override // from AbstractRemoteService
+    void handlePendingRequestWhileUnBound(@NonNull PendingRequest<S> pendingRequest) {
+        if (mPendingRequests == null) {
+            mPendingRequests = new ArrayList<>(mInitialCapacity);
+        }
+        mPendingRequests.add(pendingRequest);
+        if (mVerbose) {
+            Slog.v(mTag, "queued " + mPendingRequests.size() + " requests; last=" + pendingRequest);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/AbstractPerUserSystemService.java b/services/core/java/com/android/server/AbstractPerUserSystemService.java
index 71d261c..001d85f 100644
--- a/services/core/java/com/android/server/AbstractPerUserSystemService.java
+++ b/services/core/java/com/android/server/AbstractPerUserSystemService.java
@@ -108,7 +108,8 @@
      * <p>Typically called when the service {@link Settings} property or {@link UserManager}
      * restriction changed, which includes the initial creation of the service.
      *
-     * <p>Subclasses can extend this method to provide extra initialization.
+     * <p>Subclasses can extend this method to provide extra initialization, like clearing up
+     * previous state.
      *
      * @param disabled whether the service is disabled (due to {@link UserManager} restrictions).
      *
diff --git a/services/core/java/com/android/server/AbstractRemoteService.java b/services/core/java/com/android/server/AbstractRemoteService.java
index 0d4cf6b..f636487 100644
--- a/services/core/java/com/android/server/AbstractRemoteService.java
+++ b/services/core/java/com/android/server/AbstractRemoteService.java
@@ -45,13 +45,20 @@
  *
  * <p>All state of this class is modified on a handler thread.
  *
+ * <p><b>NOTE: </b>this class should not be extended directly, you should extend either
+ * {@link AbstractSinglePendingRequestRemoteService} or
+ * {@link AbstractMultiplePendingRequestsRemoteService}.
+ *
  * <p>See {@code com.android.server.autofill.RemoteFillService} for a concrete
  * (no pun intended) example of how to use it.
  *
+ * @param <S> the concrete remote service class
+ *
  * @hide
  */
 //TODO(b/117779333): improve javadoc above instead of using Autofill as an example
-public abstract class AbstractRemoteService implements DeathRecipient {
+public abstract class AbstractRemoteService<S extends AbstractRemoteService<S>>
+        implements DeathRecipient {
 
     private static final int MSG_UNBIND = 1;
 
@@ -64,8 +71,6 @@
     protected final Handler mHandler;
     protected final ComponentName mComponentName;
 
-    protected PendingRequest<? extends AbstractRemoteService> mPendingRequest;
-
     private final Context mContext;
     private final Intent mIntent;
     private final VultureCallback mVultureCallback;
@@ -88,10 +93,11 @@
          *
          * @param service service that died!
          */
-        void onServiceDied(AbstractRemoteService service);
+        void onServiceDied(AbstractRemoteService<? extends AbstractRemoteService<?>> service);
     }
 
-    public AbstractRemoteService(@NonNull Context context, @NonNull String serviceInterface,
+    // NOTE: must be package-protected so this class is not extend outside
+    AbstractRemoteService(@NonNull Context context, @NonNull String serviceInterface,
             @NonNull ComponentName componentName, int userId, @NonNull VultureCallback callback,
             boolean bindInstantServiceAllowed, boolean verbose) {
         mContext = context;
@@ -118,12 +124,25 @@
         return mDestroyed;
     }
 
+    private void handleOnConnectedStateChangedInternal(boolean connected) {
+        if (connected) {
+            handlePendingRequests();
+        }
+        handleOnConnectedStateChanged(connected);
+    }
+
     /**
-     * Callback called when the system connected / disconnected to the service.
+     * Handles the pending requests when the connection it bounds to the remote service.
+     */
+    abstract void handlePendingRequests();
+
+    /**
+     * Callback called when the system connected / disconnected to the service and the pending
+     * requests have been handled.
      *
      * @param state {@code true} when connected, {@code false} when disconnected.
      */
-    protected void onConnectedStateChanged(boolean state) {
+    protected void handleOnConnectedStateChanged(boolean state) {
     }
 
     /**
@@ -144,14 +163,18 @@
 
     private void handleDestroy() {
         if (checkIfDestroyed()) return;
-        if (mPendingRequest != null) {
-            mPendingRequest.cancel();
-            mPendingRequest = null;
-        }
-        ensureUnbound();
+        handleOnDestroy();
+        handleEnsureUnbound();
         mDestroyed = true;
     }
 
+    /**
+     * Clears the state when this object is destroyed.
+     *
+     * <p>Typically used to cancel the pending requests.
+     */
+    protected abstract void handleOnDestroy();
+
     @Override // from DeathRecipient
     public void binderDied() {
         mHandler.sendMessage(obtainMessage(AbstractRemoteService::handleBinderDied, this));
@@ -183,9 +206,7 @@
         pw.append(prefix).append(tab).append("destroyed=")
                 .append(String.valueOf(mDestroyed)).println();
         pw.append(prefix).append(tab).append("bound=")
-                .append(String.valueOf(isBound())).println();
-        pw.append(prefix).append(tab).append("hasPendingRequest=")
-                .append(String.valueOf(mPendingRequest != null)).println();
+                .append(String.valueOf(handleIsBound())).println();
         pw.append(prefix).append("mBindInstantServiceAllowed=").println(mBindInstantServiceAllowed);
         pw.append(prefix).append("idleTimeout=")
             .append(Long.toString(getTimeoutIdleBindMillis() / 1000)).append("s").println();
@@ -194,7 +215,7 @@
         pw.println();
     }
 
-    protected void scheduleRequest(PendingRequest<? extends AbstractRemoteService> pendingRequest) {
+    protected void scheduleRequest(@NonNull PendingRequest<S> pendingRequest) {
         mHandler.sendMessage(obtainMessage(
                 AbstractRemoteService::handlePendingRequest, this, pendingRequest));
     }
@@ -215,19 +236,20 @@
     private void handleUnbind() {
         if (checkIfDestroyed()) return;
 
-        ensureUnbound();
+        handleEnsureUnbound();
     }
 
-    private void handlePendingRequest(
-            PendingRequest<? extends AbstractRemoteService> pendingRequest) {
+    /**
+     * Handles a request, either processing it right now when bound, or saving it to be handled when
+     * bound.
+     */
+    protected final void handlePendingRequest(@NonNull PendingRequest<S> pendingRequest) {
         if (checkIfDestroyed() || mCompleted) return;
 
-        if (!isBound()) {
-            if (mPendingRequest != null) {
-                mPendingRequest.cancel();
-            }
-            mPendingRequest = pendingRequest;
-            ensureBound();
+        if (!handleIsBound()) {
+            if (mVerbose) Slog.v(mTag, "handlePendingRequest(): queuing" + pendingRequest);
+            handlePendingRequestWhileUnBound(pendingRequest);
+            handleEnsureBound();
         } else {
             if (mVerbose) Slog.v(mTag, "handlePendingRequest(): " + pendingRequest);
             pendingRequest.run();
@@ -237,12 +259,17 @@
         }
     }
 
-    private boolean isBound() {
+    /**
+     * Defines what to do with a request that arrives while not bound to the service.
+     */
+    abstract void handlePendingRequestWhileUnBound(@NonNull PendingRequest<S> pendingRequest);
+
+    private boolean handleIsBound() {
         return mServiceInterface != null;
     }
 
-    private void ensureBound() {
-        if (isBound() || mBinding) return;
+    private void handleEnsureBound() {
+        if (handleIsBound() || mBinding) return;
 
         if (mVerbose) Slog.v(mTag, "ensureBound()");
         mBinding = true;
@@ -265,13 +292,13 @@
         }
     }
 
-    private void ensureUnbound() {
-        if (!isBound() && !mBinding) return;
+    private void handleEnsureUnbound() {
+        if (!handleIsBound() && !mBinding) return;
 
         if (mVerbose) Slog.v(mTag, "ensureUnbound()");
         mBinding = false;
-        if (isBound()) {
-            onConnectedStateChanged(false);
+        if (handleIsBound()) {
+            handleOnConnectedStateChangedInternal(false);
             if (mServiceInterface != null) {
                 mServiceInterface.asBinder().unlinkToDeath(this, 0);
                 mServiceInterface = null;
@@ -283,6 +310,7 @@
     private class RemoteServiceConnection implements ServiceConnection {
         @Override
         public void onServiceConnected(ComponentName name, IBinder service) {
+            if (mVerbose) Slog.v(mTag, "onServiceConnected()");
             if (mDestroyed || !mBinding) {
                 // This is abnormal. Unbinding the connection has been requested already.
                 Slog.wtf(mTag, "onServiceConnected() was dispatched after unbindService.");
@@ -296,15 +324,7 @@
                 handleBinderDied();
                 return;
             }
-            onConnectedStateChanged(true);
-
-            if (mPendingRequest != null) {
-                final PendingRequest<? extends AbstractRemoteService> pendingRequest =
-                        mPendingRequest;
-                mPendingRequest = null;
-                handlePendingRequest(pendingRequest);
-            }
-
+            handleOnConnectedStateChangedInternal(true);
             mServiceDied = false;
         }
 
@@ -325,25 +345,12 @@
         return mDestroyed;
     }
 
-    protected boolean handleResponseCallbackCommon(
-            PendingRequest<? extends AbstractRemoteService> pendingRequest) {
-        if (isDestroyed()) return false;
-
-        if (mPendingRequest == pendingRequest) {
-            mPendingRequest = null;
-        }
-        if (mPendingRequest == null) {
-            scheduleUnbind();
-        }
-        return true;
-    }
-
     /**
      * Base class for the requests serviced by the remote service.
      *
      * @param <S> the remote service class
      */
-    public abstract static class PendingRequest<S extends AbstractRemoteService>
+    public abstract static class PendingRequest<S extends AbstractRemoteService<S>>
             implements Runnable {
         protected final String mTag = getClass().getSimpleName();
         protected final Object mLock = new Object();
diff --git a/services/core/java/com/android/server/AbstractSinglePendingRequestRemoteService.java b/services/core/java/com/android/server/AbstractSinglePendingRequestRemoteService.java
new file mode 100644
index 0000000..8e1f540
--- /dev/null
+++ b/services/core/java/com/android/server/AbstractSinglePendingRequestRemoteService.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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;
+
+import android.annotation.NonNull;
+import android.content.ComponentName;
+import android.content.Context;
+import android.util.Slog;
+
+import java.io.PrintWriter;
+
+/**
+ * Base class representing a remote service that can have only one pending requests while not bound.
+ *
+ * <p>If another request is received while not bound, the previous one will be canceled.
+ *
+ * @param <S> the concrete remote service class
+ *
+ * @hide
+ */
+public abstract class AbstractSinglePendingRequestRemoteService<
+        S extends AbstractSinglePendingRequestRemoteService<S>> extends AbstractRemoteService<S> {
+
+    protected PendingRequest<S> mPendingRequest;
+
+    public AbstractSinglePendingRequestRemoteService(@NonNull Context context,
+            @NonNull String serviceInterface, @NonNull ComponentName componentName, int userId,
+            @NonNull VultureCallback callback, boolean bindInstantServiceAllowed,
+            boolean verbose) {
+        super(context, serviceInterface, componentName, userId, callback, bindInstantServiceAllowed,
+                verbose);
+    }
+
+    @Override // from AbstractRemoteService
+    void handlePendingRequests() {
+        if (mPendingRequest != null) {
+            final PendingRequest<S> pendingRequest = mPendingRequest;
+            mPendingRequest = null;
+            handlePendingRequest(pendingRequest);
+        }
+    }
+
+    @Override // from AbstractRemoteService
+    protected void handleOnDestroy() {
+        if (mPendingRequest != null) {
+            mPendingRequest.cancel();
+            mPendingRequest = null;
+        }
+    }
+
+    @Override // from AbstractRemoteService
+    public void dump(@NonNull String prefix, @NonNull PrintWriter pw) {
+        super.dump(prefix, pw);
+        pw.append(prefix).append("hasPendingRequest=")
+                .append(String.valueOf(mPendingRequest != null)).println();
+    }
+
+    @Override // from AbstractRemoteService
+    void handlePendingRequestWhileUnBound(@NonNull PendingRequest<S> pendingRequest) {
+        if (mPendingRequest != null) {
+            if (mVerbose) {
+                Slog.v(mTag, "handlePendingRequestWhileUnBound(): cancelling " + mPendingRequest);
+            }
+            mPendingRequest.cancel();
+        }
+        mPendingRequest = pendingRequest;
+    }
+}
diff --git a/services/core/java/com/android/server/BinderCallsStatsService.java b/services/core/java/com/android/server/BinderCallsStatsService.java
index 9820321..01716a0 100644
--- a/services/core/java/com/android/server/BinderCallsStatsService.java
+++ b/services/core/java/com/android/server/BinderCallsStatsService.java
@@ -98,7 +98,7 @@
             mBinderCallsStats.setSamplingInterval(mParser.getInt(
                     SETTINGS_SAMPLING_INTERVAL_KEY,
                     BinderCallsStats.PERIODIC_SAMPLING_INTERVAL_DEFAULT));
-            mBinderCallsStats.setSamplingInterval(mParser.getInt(
+            mBinderCallsStats.setMaxBinderCallStats(mParser.getInt(
                     SETTINGS_MAX_CALL_STATS_KEY,
                     BinderCallsStats.MAX_BINDER_CALL_STATS_COUNT_DEFAULT));
 
diff --git a/services/core/java/com/android/server/RuntimeService.java b/services/core/java/com/android/server/RuntimeService.java
new file mode 100644
index 0000000..ccfac80
--- /dev/null
+++ b/services/core/java/com/android/server/RuntimeService.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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;
+
+import android.content.Context;
+import android.os.Binder;
+import android.service.runtime.DebugEntryProto;
+import android.service.runtime.RuntimeServiceInfoProto;
+import android.util.Slog;
+import android.util.proto.ProtoOutputStream;
+
+import libcore.timezone.TimeZoneDataFiles;
+import libcore.util.CoreLibraryDebug;
+import libcore.util.DebugInfo;
+
+import com.android.internal.util.DumpUtils;
+import com.android.timezone.distro.DistroException;
+import com.android.timezone.distro.DistroVersion;
+import com.android.timezone.distro.FileUtils;
+import com.android.timezone.distro.TimeZoneDistro;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ * This service exists only as a "dumpsys" target which reports information about the status of the
+ * runtime and related libraries.
+ */
+public class RuntimeService extends Binder {
+
+    private static final String TAG = "RuntimeService";
+
+    private final Context mContext;
+
+    public RuntimeService(Context context) {
+        mContext = context;
+    }
+
+    @Override
+    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) {
+            return;
+        }
+
+        boolean protoFormat = hasOption(args, "--proto");
+        ProtoOutputStream proto = null;
+
+        DebugInfo coreLibraryDebugInfo = CoreLibraryDebug.getDebugInfo();
+        addTimeZoneApkDebugInfo(coreLibraryDebugInfo);
+
+        if (protoFormat) {
+            proto = new ProtoOutputStream(fd);
+            reportTimeZoneInfoProto(coreLibraryDebugInfo, proto);
+        } else {
+            reportTimeZoneInfo(coreLibraryDebugInfo, pw);
+        }
+
+        if (protoFormat) {
+            proto.flush();
+        }
+    }
+
+    /** Returns {@code true} if {@code args} contains {@code arg}. */
+    private static boolean hasOption(String[] args, String arg) {
+        for (String opt : args) {
+            if (arg.equals(opt)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Add information to {@link DebugInfo} about the time zone data supplied by the
+     * "Time zone updates via APK" feature.
+     */
+    private static void addTimeZoneApkDebugInfo(DebugInfo coreLibraryDebugInfo) {
+        // Add /data tz data set using the DistroVersion class (which libcore cannot use).
+        // This update mechanism will be removed after the time zone APEX is launched so this
+        // untidiness will disappear with it.
+        String debugKeyPrefix = "core_library.timezone.data_";
+        String versionFileName = TimeZoneDataFiles.getDataTimeZoneFile(
+                TimeZoneDistro.DISTRO_VERSION_FILE_NAME);
+        addDistroVersionDebugInfo(versionFileName, debugKeyPrefix, coreLibraryDebugInfo);
+    }
+
+    /**
+     * Prints {@code coreLibraryDebugInfo} to {@code pw}.
+     *
+     * <p>If you change this method, make sure to modify
+     * {@link #reportTimeZoneInfoProto(DebugInfo, ProtoOutputStream)} as well.
+     */
+    private static void reportTimeZoneInfo(DebugInfo coreLibraryDebugInfo,
+            PrintWriter pw) {
+        pw.println("Core Library Debug Info: ");
+        for (DebugInfo.DebugEntry debugEntry : coreLibraryDebugInfo.getDebugEntries()) {
+            pw.print(debugEntry.getKey());
+            pw.print(": \"");
+            pw.print(debugEntry.getStringValue());
+            pw.println("\"");
+        }
+    }
+
+    /**
+     * Adds {@code coreLibraryDebugInfo} to {@code protoStream}.
+     *
+     * <p>If you change this method, make sure to modify
+     * {@link #reportTimeZoneInfo(DebugInfo, PrintWriter)}.
+     */
+    private static void reportTimeZoneInfoProto(
+            DebugInfo coreLibraryDebugInfo, ProtoOutputStream protoStream) {
+        for (DebugInfo.DebugEntry debugEntry : coreLibraryDebugInfo.getDebugEntries()) {
+            long entryToken = protoStream.start(RuntimeServiceInfoProto.DEBUG_ENTRY);
+            protoStream.write(DebugEntryProto.KEY, debugEntry.getKey());
+            protoStream.write(DebugEntryProto.STRING_VALUE, debugEntry.getStringValue());
+            protoStream.end(entryToken);
+        }
+    }
+
+    /**
+     * Adds version information to {@code debugInfo} from the distro_version file that may exist
+     * at {@code distroVersionFileName}. If the file does not exist or cannot be read this is
+     * reported as debug information too.
+     */
+    private static void addDistroVersionDebugInfo(String distroVersionFileName,
+            String debugKeyPrefix, DebugInfo debugInfo) {
+        File file = new File(distroVersionFileName);
+        String statusKey = debugKeyPrefix + "status";
+        if (file.exists()) {
+            try {
+                byte[] versionBytes =
+                        FileUtils.readBytes(file, DistroVersion.DISTRO_VERSION_FILE_LENGTH);
+                DistroVersion distroVersion = DistroVersion.fromBytes(versionBytes);
+                String formatVersionString = distroVersion.formatMajorVersion + "."
+                        + distroVersion.formatMinorVersion;
+                debugInfo.addStringEntry(statusKey, "OK")
+                        .addStringEntry(debugKeyPrefix + "formatVersion", formatVersionString)
+                        .addStringEntry(debugKeyPrefix + "rulesVersion",
+                                distroVersion.rulesVersion)
+                        .addStringEntry(debugKeyPrefix + "revision",
+                                distroVersion.revision);
+            } catch (IOException | DistroException e) {
+                debugInfo.addStringEntry(statusKey, "ERROR");
+                debugInfo.addStringEntry(debugKeyPrefix + "exception_class",
+                        e.getClass().getName());
+                debugInfo.addStringEntry(debugKeyPrefix + "exception_msg", e.getMessage());
+                logMessage("Error reading " + file, e);
+            }
+        } else {
+            debugInfo.addStringEntry(statusKey, "NOT_FOUND");
+        }
+    }
+
+    private static void logMessage(String msg, Throwable t) {
+        Slog.v(TAG, msg, t);
+    }
+}
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index f0b472b..a2cbfaa 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -47,6 +47,7 @@
 import android.telephony.SignalStrength;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.telephony.emergency.EmergencyNumber;
 import android.util.LocalLog;
 import android.util.StatsLog;
 
@@ -1664,6 +1665,14 @@
     }
 
     @Override
+    public void notifyEmergencyNumberList(List<EmergencyNumber> emergencyNumberList) {
+        // TODO checkPermission, modify Listener constent documentation
+        // TODO implement multisim emergency number list update in listener
+        // TODO implement PhoneStateListenerTest
+    }
+
+
+    @Override
     public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
         final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
 
diff --git a/services/core/java/com/android/server/WallpaperUpdateReceiver.java b/services/core/java/com/android/server/WallpaperUpdateReceiver.java
new file mode 100644
index 0000000..629e882
--- /dev/null
+++ b/services/core/java/com/android/server/WallpaperUpdateReceiver.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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;
+
+import android.app.ActivityThread;
+import android.app.WallpaperManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.os.AsyncTask;
+import android.util.Slog;
+
+/**
+ * Receiver responsible for updating the wallpaper when the device
+ * configuration has changed.
+ *
+ * @hide
+ */
+public class WallpaperUpdateReceiver extends BroadcastReceiver {
+
+    private static final String TAG = "WallpaperUpdateReceiver";
+    private static final boolean DEBUG = false;
+
+    @Override
+    public void onReceive(final Context context, final Intent intent) {
+        if (DEBUG) Slog.d(TAG, "onReceive: " + intent);
+
+        if (intent != null && Intent.ACTION_DEVICE_CUSTOMIZATION_READY.equals(intent.getAction())) {
+            AsyncTask.execute(this::updateWallpaper);
+        }
+    }
+
+    private void updateWallpaper() {
+        try {
+            ActivityThread currentActivityThread = ActivityThread.currentActivityThread();
+            Context uiContext = currentActivityThread.getSystemUiContext();
+            WallpaperManager wallpaperManager = WallpaperManager.getInstance(uiContext);
+            if (DEBUG) Slog.d(TAG, "Set customized default_wallpaper.");
+            Bitmap blank = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8);
+            // set a blank wallpaper to force a redraw of default_wallpaper
+            wallpaperManager.setBitmap(blank);
+            wallpaperManager.setResource(com.android.internal.R.drawable.default_wallpaper);
+        } catch (Exception e) {
+            Slog.w(TAG, "Failed to customize system wallpaper." + e);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 0e354d5..562e80d 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -666,16 +666,50 @@
     final class PidMap {
         private final SparseArray<ProcessRecord> mPidMap = new SparseArray<>();
 
+        /**
+         * Puts the process record in the map.
+         * <p>NOTE: Callers should avoid acquiring the mPidsSelfLocked lock before calling this
+         * method.
+         */
         void put(int key, ProcessRecord value) {
-            mPidMap.put(key, value);
+            synchronized (this) {
+                mPidMap.put(key, value);
+            }
             mAtmInternal.onProcessMapped(key, value.getWindowProcessController());
         }
 
+        /**
+         * Removes the process record from the map.
+         * <p>NOTE: Callers should avoid acquiring the mPidsSelfLocked lock before calling this
+         * method.
+         */
         void remove(int pid) {
-            mPidMap.remove(pid);
+            synchronized (this) {
+                mPidMap.remove(pid);
+            }
             mAtmInternal.onProcessUnMapped(pid);
         }
 
+        /**
+         * Removes the process record from the map if it has a thread.
+         * <p>NOTE: Callers should avoid acquiring the mPidsSelfLocked lock before calling this
+         * method.
+         */
+        boolean removeIfNoThread(int pid) {
+            boolean removed = false;
+            synchronized (this) {
+                final ProcessRecord app = get(pid);
+                if (app != null && app.thread == null) {
+                    mPidMap.remove(pid);
+                    removed = true;
+                }
+            }
+            if (removed) {
+                mAtmInternal.onProcessUnMapped(pid);
+            }
+            return removed;
+        }
+
         ProcessRecord get(int pid) {
             return mPidMap.get(pid);
         }
@@ -1889,9 +1923,7 @@
                 app.getWindowProcessController().setPid(MY_PID);
                 app.maxAdj = ProcessList.SYSTEM_ADJ;
                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
-                synchronized (mPidsSelfLocked) {
-                    mPidsSelfLocked.put(app.pid, app);
-                }
+                mPidsSelfLocked.put(app.pid, app);
                 mProcessList.updateLruProcessLocked(app, false, null);
                 updateOomAdjLocked();
             }
@@ -4254,14 +4286,7 @@
 
     private final void processStartTimedOutLocked(ProcessRecord app) {
         final int pid = app.pid;
-        boolean gone = false;
-        synchronized (mPidsSelfLocked) {
-            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
-            if (knownApp != null && knownApp.thread == null) {
-                mPidsSelfLocked.remove(pid);
-                gone = true;
-            }
-        }
+        boolean gone = mPidsSelfLocked.removeIfNoThread(pid);
 
         if (gone) {
             Slog.w(TAG, "Process " + app + " failed to attach");
@@ -13113,11 +13138,8 @@
             return true;
         } else if (app.pid > 0 && app.pid != MY_PID) {
             // Goodbye!
-            boolean removed;
-            synchronized (mPidsSelfLocked) {
-                mPidsSelfLocked.remove(app.pid);
-                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
-            }
+            mPidsSelfLocked.remove(app.pid);
+            mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
             if (app.isolated) {
                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
diff --git a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
index 2541352..24543b7 100644
--- a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
+++ b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
@@ -25,10 +25,12 @@
 import android.net.wifi.WifiActivityEnergyInfo;
 import android.os.BatteryStats;
 import android.os.Parcelable;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SynchronousResultReceiver;
 import android.os.SystemClock;
+import android.os.ThreadLocalWorkSource;
 import android.telephony.ModemActivityInfo;
 import android.telephony.TelephonyManager;
 import android.util.IntArray;
@@ -43,11 +45,9 @@
 import libcore.util.EmptyArray;
 
 import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
@@ -74,7 +74,12 @@
     private final ScheduledExecutorService mExecutorService =
             Executors.newSingleThreadScheduledExecutor(
                     (ThreadFactory) r -> {
-                        Thread t = new Thread(r, "batterystats-worker");
+                        Thread t = new Thread(
+                                () -> {
+                                    ThreadLocalWorkSource.setUid(Process.myUid());
+                                    r.run();
+                                },
+                                "batterystats-worker");
                         t.setPriority(Thread.NORM_PRIORITY);
                         return t;
                     });
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 7991783..62f1009 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -1246,10 +1246,8 @@
         long startTime = SystemClock.elapsedRealtime();
         if (app.pid > 0 && app.pid != ActivityManagerService.MY_PID) {
             checkSlow(startTime, "startProcess: removing from pids map");
-            synchronized (mService.mPidsSelfLocked) {
-                mService.mPidsSelfLocked.remove(app.pid);
-                mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
-            }
+            mService.mPidsSelfLocked.remove(app.pid);
+            mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
             checkSlow(startTime, "startProcess: done removing from pids map");
             app.setPid(0);
         }
@@ -1767,8 +1765,8 @@
             mService.cleanUpApplicationRecordLocked(oldApp, false, false, -1,
                     true /*replacingPid*/);
         }
+        mService.mPidsSelfLocked.put(pid, app);
         synchronized (mService.mPidsSelfLocked) {
-            mService.mPidsSelfLocked.put(pid, app);
             if (!procAttached) {
                 Message msg = mService.mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
                 msg.obj = app;
@@ -1928,10 +1926,8 @@
                 .pendingStart)) {
             int pid = app.pid;
             if (pid > 0) {
-                synchronized (mService.mPidsSelfLocked) {
-                    mService.mPidsSelfLocked.remove(pid);
-                    mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
-                }
+                mService.mPidsSelfLocked.remove(pid);
+                mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
                 mService.mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
                 if (app.isolated) {
                     mService.mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
index c2f4406..bf95210 100644
--- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
@@ -313,6 +313,7 @@
     private final State mCaptivePortalState = new CaptivePortalState();
     private final State mEvaluatingPrivateDnsState = new EvaluatingPrivateDnsState();
     private final State mProbingState = new ProbingState();
+    private final State mWaitingForNextProbeState = new WaitingForNextProbeState();
 
     private CustomIntentReceiver mLaunchCaptivePortalAppBroadcastReceiver = null;
 
@@ -368,6 +369,7 @@
         addState(mMaybeNotifyState, mDefaultState);
             addState(mEvaluatingState, mMaybeNotifyState);
                 addState(mProbingState, mEvaluatingState);
+                addState(mWaitingForNextProbeState, mEvaluatingState);
             addState(mCaptivePortalState, mMaybeNotifyState);
         addState(mEvaluatingPrivateDnsState, mDefaultState);
         addState(mValidatedState, mDefaultState);
@@ -877,6 +879,11 @@
 
         @Override
         public void enter() {
+            if (mEvaluateAttempts >= BLAME_FOR_EVALUATION_ATTEMPTS) {
+                //Don't continue to blame UID forever.
+                TrafficStats.clearThreadStatsUid();
+            }
+
             final int token = ++mProbeToken;
             mThread = new Thread(() -> sendMessage(obtainMessage(CMD_PROBE_COMPLETE, token, 0,
                     isCaptivePortal())));
@@ -904,29 +911,16 @@
                         mLastPortalProbeResult = probeResult;
                         transitionTo(mCaptivePortalState);
                     } else {
-                        final Message msg = obtainMessage(CMD_REEVALUATE, ++mReevaluateToken, 0);
-                        sendMessageDelayed(msg, mReevaluateDelayMs);
                         logNetworkEvent(NetworkEvent.NETWORK_VALIDATION_FAILED);
                         notifyNetworkTestResultInvalid(probeResult.redirectUrl);
-                        if (mEvaluateAttempts >= BLAME_FOR_EVALUATION_ATTEMPTS) {
-                            // Don't continue to blame UID forever.
-                            TrafficStats.clearThreadStatsUid();
-                        }
-                        mReevaluateDelayMs *= 2;
-                        if (mReevaluateDelayMs > MAX_REEVALUATE_DELAY_MS) {
-                            mReevaluateDelayMs = MAX_REEVALUATE_DELAY_MS;
-                        }
+                        transitionTo(mWaitingForNextProbeState);
                     }
                     return HANDLED;
-                case CMD_REEVALUATE:
-                    // Leave the event to EvaluatingState. Defer this message will result in reset
-                    // of mReevaluateDelayMs and mEvaluateAttempts.
-                case CMD_NETWORK_DISCONNECTED:
                 case EVENT_DNS_NOTIFICATION:
+                    // Leave the event to DefaultState to record correct dns timestamp.
                     return NOT_HANDLED;
                 default:
-                    // TODO: Some events may able to handle in this state, instead of deferring to
-                    // next state.
+                    // Wait for probe result and defer events to next state by default.
                     deferMessage(message);
                     return HANDLED;
             }
@@ -941,6 +935,29 @@
         }
     }
 
+    // Being in the WaitingForNextProbeState indicates that evaluating probes failed and state is
+    // transited from ProbingState. This ensures that the state machine is only in ProbingState
+    // while a probe is in progress, not while waiting to perform the next probe. That allows
+    // ProbingState to defer most messages until the probe is complete, which keeps the code simple
+    // and matches the pre-Q behaviour where probes were a blocking operation performed on the state
+    // machine thread.
+    private class WaitingForNextProbeState extends State {
+        @Override
+        public void enter() {
+            final Message msg = obtainMessage(CMD_REEVALUATE, ++mReevaluateToken, 0);
+            sendMessageDelayed(msg, mReevaluateDelayMs);
+            mReevaluateDelayMs *= 2;
+            if (mReevaluateDelayMs > MAX_REEVALUATE_DELAY_MS) {
+                mReevaluateDelayMs = MAX_REEVALUATE_DELAY_MS;
+            }
+        }
+
+        @Override
+        public boolean processMessage(Message message) {
+            return NOT_HANDLED;
+        }
+    }
+
     // Limits the list of IP addresses returned by getAllByName or tried by openConnection to at
     // most one per address family. This ensures we only wait up to 20 seconds for TCP connections
     // to complete, regardless of how many IP addresses a host has.
diff --git a/services/core/java/com/android/server/intelligence/IntelligenceManagerInternal.java b/services/core/java/com/android/server/intelligence/IntelligenceManagerInternal.java
index 6fe6324..d5be26a 100644
--- a/services/core/java/com/android/server/intelligence/IntelligenceManagerInternal.java
+++ b/services/core/java/com/android/server/intelligence/IntelligenceManagerInternal.java
@@ -27,12 +27,13 @@
  *
  * @hide Only for use within the system server.
  */
+//TODO(b/111276913): rename once the final name is defined
 public abstract class IntelligenceManagerInternal {
 
     /**
      * Checks whether the given {@code uid} owns the
-     * {@link android.service.intelligence.IntelligenceService} implementation associated with the
-     * given {@code userId}.
+     * {@link android.service.intelligence.SmartSuggestionsService} implementation associated with
+     * the given {@code userId}.
      */
     public abstract boolean isIntelligenceServiceForUser(int uid, @UserIdInt int userId);
 
diff --git a/services/core/java/com/android/server/power/ThermalManagerService.java b/services/core/java/com/android/server/power/ThermalManagerService.java
index 79e2688..07bebad 100644
--- a/services/core/java/com/android/server/power/ThermalManagerService.java
+++ b/services/core/java/com/android/server/power/ThermalManagerService.java
@@ -29,8 +29,12 @@
 import android.os.IThermalService;
 import android.os.IThermalStatusListener;
 import android.os.PowerManager;
+import android.os.Process;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.os.ShellCallback;
+import android.os.ShellCommand;
 import android.os.Temperature;
 import android.util.ArrayMap;
 import android.util.Slog;
@@ -77,6 +81,10 @@
     @GuardedBy("mLock")
     private int mStatus;
 
+    /** If override status takes effect*/
+    @GuardedBy("mLock")
+    private boolean mIsStatusOverride;
+
     /** Current thermal map, key as name */
     @GuardedBy("mLock")
     private ArrayMap<String, Temperature> mTemperatureMap = new ArrayMap<>();
@@ -184,13 +192,19 @@
                 newStatus = t.getStatus();
             }
         }
+        // Do not update if override from shell
+        if (!mIsStatusOverride) {
+            setStatusLocked(newStatus);
+        }
+    }
+
+    private void setStatusLocked(int newStatus) {
         if (newStatus != mStatus) {
             mStatus = newStatus;
             notifyStatusListenersLocked();
         }
     }
 
-
     private void postEventListenerCurrentTemperatures(IThermalEventListener listener,
             @Nullable Integer type) {
         synchronized (mLock) {
@@ -241,12 +255,7 @@
             // Thermal Shutdown for Skin temperature
             if (temperature.getStatus() == Temperature.THROTTLING_SHUTDOWN
                     && temperature.getType() == Temperature.TYPE_SKIN) {
-                final long token = Binder.clearCallingIdentity();
-                try {
-                    mPowerManager.shutdown(false, PowerManager.SHUTDOWN_THERMAL_STATE, false);
-                } finally {
-                    Binder.restoreCallingIdentity(token);
-                }
+                mPowerManager.shutdown(false, PowerManager.SHUTDOWN_THERMAL_STATE, false);
             }
 
             Temperature old = mTemperatureMap.put(temperature.getName(), temperature);
@@ -263,8 +272,14 @@
         }
     }
 
+    /* HwBinder callback **/
     private void onTemperatureChangedCallback(Temperature temperature) {
-        onTemperatureChanged(temperature, true);
+        final long token = Binder.clearCallingIdentity();
+        try {
+            onTemperatureChanged(temperature, true);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
     }
 
     private void dumpTemperaturesLocked(PrintWriter pw, String prefix,
@@ -393,7 +408,7 @@
         }
 
         @Override
-        public int getCurrentStatus() {
+        public int getCurrentThermalStatus() {
             synchronized (mLock) {
                 final long token = Binder.clearCallingIdentity();
                 try {
@@ -434,8 +449,93 @@
                 Binder.restoreCallingIdentity(token);
             }
         }
+
+        private boolean isCallerShell() {
+            final int callingUid = Binder.getCallingUid();
+            return callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID;
+        }
+
+        @Override
+        public void onShellCommand(FileDescriptor in, FileDescriptor out,
+                FileDescriptor err, String[] args, ShellCallback callback,
+                ResultReceiver resultReceiver) {
+            if (!isCallerShell()) {
+                Slog.w(TAG, "Only shell is allowed to call thermalservice shell commands");
+                return;
+            }
+            (new ThermalShellCommand()).exec(
+                    this, in, out, err, args, callback, resultReceiver);
+        }
+
     };
 
+    class ThermalShellCommand extends ShellCommand {
+        @Override
+        public int onCommand(String cmd) {
+            switch(cmd != null ? cmd : "") {
+                case "override-status":
+                    return runOverrideStatus();
+                case "reset":
+                    return runReset();
+                default:
+                    return handleDefaultCommands(cmd);
+            }
+        }
+
+        private int runReset() {
+            final long token = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    mIsStatusOverride = false;
+                    onTemperatureMapChangedLocked();
+                    return 0;
+                }
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        private int runOverrideStatus() {
+            final long token = Binder.clearCallingIdentity();
+            try {
+                final PrintWriter pw = getOutPrintWriter();
+                int status;
+                try {
+                    status = Integer.parseInt(getNextArgRequired());
+                } catch (RuntimeException ex) {
+                    pw.println("Error: " + ex.toString());
+                    return -1;
+                }
+                if (!Temperature.isValidStatus(status)) {
+                    pw.println("Invalid status: " + Integer.toString(status));
+                    return -1;
+                }
+                synchronized (mLock) {
+                    mIsStatusOverride = true;
+                    setStatusLocked(status);
+                }
+                return 0;
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
+        public void onHelp() {
+            final PrintWriter pw = getOutPrintWriter();
+            pw.println("Thermal service (thermalservice) commands:");
+            pw.println("  help");
+            pw.println("    Print this help text.");
+            pw.println("");
+            pw.println("  override-status STATUS");
+            pw.println("    sets and locks the thermal status of the device to STATUS.");
+            pw.println("    status code is defined in android.os.Temperature.");
+            pw.println("  reset");
+            pw.println("    unlocks the thermal status of the device.");
+            pw.println();
+        }
+    }
+
     abstract static class ThermalHalWrapper {
         protected static final String TAG = ThermalHalWrapper.class.getSimpleName();
 
diff --git a/services/core/java/com/android/server/role/RoleManagerService.java b/services/core/java/com/android/server/role/RoleManagerService.java
index b065470..b5ad235 100644
--- a/services/core/java/com/android/server/role/RoleManagerService.java
+++ b/services/core/java/com/android/server/role/RoleManagerService.java
@@ -55,6 +55,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
@@ -106,7 +107,7 @@
         intentFilter.addAction(Intent.ACTION_USER_REMOVED);
         getContext().registerReceiverAsUser(new BroadcastReceiver() {
             @Override
-            public void onReceive(Context context, Intent intent) {
+            public void onReceive(@NonNull Context context, @NonNull Intent intent) {
                 if (TextUtils.equals(intent.getAction(), Intent.ACTION_USER_REMOVED)) {
                     int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
                     onRemoveUser(userId);
@@ -129,10 +130,11 @@
             userState = getUserStateLocked(userId);
         }
         String packagesHash = computeComponentStateHash(userId);
-        boolean needGrant;
+        String lastGrantPackagesHash;
         synchronized (mLock) {
-            needGrant = !packagesHash.equals(userState.getLastGrantPackagesHashLocked());
+            lastGrantPackagesHash = userState.getLastGrantPackagesHashLocked();
         }
+        boolean needGrant = !Objects.equals(packagesHash, lastGrantPackagesHash);
         if (needGrant) {
             // Some vital packages state has changed since last role grant
             // Run grants again
@@ -144,7 +146,6 @@
                         public void onSuccess() {
                             result.complete(null);
                         }
-
                         @Override
                         public void onFailure() {
                             result.completeExceptionally(new RuntimeException());
@@ -163,7 +164,8 @@
         }
     }
 
-    private String computeComponentStateHash(int userId) {
+    @Nullable
+    private String computeComponentStateHash(@UserIdInt int userId) {
         PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class);
         ByteArrayOutputStream out = new ByteArrayOutputStream();
 
@@ -198,8 +200,7 @@
     private RoleUserState getUserStateLocked(@UserIdInt int userId) {
         RoleUserState userState = mUserStates.get(userId);
         if (userState == null) {
-            userState = new RoleUserState(userId);
-            userState.readSyncLocked();
+            userState = RoleUserState.newInstanceLocked(userId);
             mUserStates.put(userId, userState);
         }
         return userState;
@@ -386,11 +387,11 @@
         }
 
         @Override
-        public void onShellCommand(FileDescriptor in, FileDescriptor out,
-                FileDescriptor err, String[] args, ShellCallback callback,
-                ResultReceiver resultReceiver) {
-            (new RoleManagerShellCommand(this)).exec(
-                    this, in, out, err, args, callback, resultReceiver);
+        public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
+                @Nullable FileDescriptor err, @NonNull String[] args,
+                @Nullable ShellCallback callback, @NonNull ResultReceiver resultReceiver) {
+            new RoleManagerShellCommand(this).exec(this, in, out, err, args, callback,
+                    resultReceiver);
         }
     }
 }
diff --git a/services/core/java/com/android/server/role/RoleManagerShellCommand.java b/services/core/java/com/android/server/role/RoleManagerShellCommand.java
index e1977ef..336b311 100644
--- a/services/core/java/com/android/server/role/RoleManagerShellCommand.java
+++ b/services/core/java/com/android/server/role/RoleManagerShellCommand.java
@@ -16,6 +16,8 @@
 
 package com.android.server.role;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.role.IRoleManager;
 import android.app.role.IRoleManagerCallback;
 import android.os.RemoteException;
@@ -27,13 +29,17 @@
 import java.util.concurrent.TimeUnit;
 
 class RoleManagerShellCommand extends ShellCommand {
+
+    @NonNull
     private final IRoleManager mRoleManager;
 
-    RoleManagerShellCommand(IRoleManager roleManager) {
+    RoleManagerShellCommand(@NonNull IRoleManager roleManager) {
         mRoleManager = roleManager;
     }
 
     private class Callback extends IRoleManagerCallback.Stub {
+
+        @NonNull
         private final CompletableFuture<Void> mResult = new CompletableFuture<>();
 
         public int waitForResult() {
@@ -58,7 +64,7 @@
     }
 
     @Override
-    public int onCommand(String cmd) {
+    public int onCommand(@Nullable String cmd) {
         if (cmd == null) {
             return handleDefaultCommands(cmd);
         }
diff --git a/services/core/java/com/android/server/role/RoleUserState.java b/services/core/java/com/android/server/role/RoleUserState.java
index f218d3a..3e3e156 100644
--- a/services/core/java/com/android/server/role/RoleUserState.java
+++ b/services/core/java/com/android/server/role/RoleUserState.java
@@ -47,6 +47,7 @@
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * Stores the state of roles for a user.
@@ -70,25 +71,41 @@
     private final int mUserId;
 
     @GuardedBy("RoleManagerService.mLock")
-    private int mVersion;
+    private int mVersion = VERSION_UNDEFINED;
 
     @GuardedBy("RoleManagerService.mLock")
-    private String mLastGrantPackagesHash = null;
+    @Nullable
+    private String mLastGrantPackagesHash;
 
     /**
      * Maps role names to its holders' package names. The values should never be null.
      */
     @GuardedBy("RoleManagerService.mLock")
-    @Nullable
-    private ArrayMap<String, ArraySet<String>> mRoles = null;
+    @NonNull
+    private ArrayMap<String, ArraySet<String>> mRoles = new ArrayMap<>();
 
     @GuardedBy("RoleManagerService.mLock")
     private boolean mDestroyed;
 
+    @NonNull
     private final Handler mWriteHandler = new Handler(BackgroundThread.getHandler().getLooper());
 
-    public RoleUserState(@UserIdInt int userId) {
+    private RoleUserState(@UserIdInt int userId) {
         mUserId = userId;
+
+        readSyncLocked();
+    }
+
+    /**
+     * Create a new instance of user state, and read its state from disk if previously persisted.
+     *
+     * @param userId the user id for the new user state
+     *
+     * @return the new user state
+     */
+    @GuardedBy("RoleManagerService.mLock")
+    public static RoleUserState newInstanceLocked(@UserIdInt int userId) {
+        return new RoleUserState(userId);
     }
 
     /**
@@ -116,7 +133,9 @@
     }
 
     /**
-     * Get the hash representing the state of packages during the last time initial grants was run
+     * Get the hash representing the state of packages during the last time initial grants was run.
+     *
+     * @return the hash representing the state of packages
      */
     @GuardedBy("RoleManagerService.mLock")
     public String getLastGrantPackagesHashLocked() {
@@ -124,10 +143,16 @@
     }
 
     /**
-     * Set the hash representing the state of packages during the last time initial grants was run
+     * Set the hash representing the state of packages during the last time initial grants was run.
+     *
+     * @param lastGrantPackagesHash the hash representing the state of packages
      */
     @GuardedBy("RoleManagerService.mLock")
-    public void setLastGrantPackagesHashLocked(String lastGrantPackagesHash) {
+    public void setLastGrantPackagesHashLocked(@Nullable String lastGrantPackagesHash) {
+        throwIfDestroyedLocked();
+        if (Objects.equals(mLastGrantPackagesHash, lastGrantPackagesHash)) {
+            return;
+        }
         mLastGrantPackagesHash = lastGrantPackagesHash;
         writeAsyncLocked();
     }
@@ -250,9 +275,9 @@
      * Schedule writing the state to file.
      */
     @GuardedBy("RoleManagerService.mLock")
-    void writeAsyncLocked() {
+    private void writeAsyncLocked() {
         throwIfDestroyedLocked();
-        int version = mVersion;
+
         ArrayMap<String, ArraySet<String>> roles = new ArrayMap<>();
         for (int i = 0, size = CollectionUtils.size(mRoles); i < size; ++i) {
             String roleName = mRoles.keyAt(i);
@@ -260,15 +285,16 @@
             roleHolders = new ArraySet<>(roleHolders);
             roles.put(roleName, roleHolders);
         }
+
         mWriteHandler.removeCallbacksAndMessages(null);
         // TODO: Throttle writes.
-        mWriteHandler.sendMessage(PooledLambda.obtainMessage(
-                RoleUserState::writeSync, this, version, roles, mLastGrantPackagesHash));
+        mWriteHandler.sendMessage(PooledLambda.obtainMessage(RoleUserState::writeSync, this,
+                mVersion, mLastGrantPackagesHash, roles));
     }
 
     @WorkerThread
-    private void writeSync(int version, @NonNull ArrayMap<String, ArraySet<String>> roles,
-            String packagesHash) {
+    private void writeSync(int version, @Nullable String packagesHash,
+            @NonNull ArrayMap<String, ArraySet<String>> roles) {
         AtomicFile atomicFile = new AtomicFile(getFile(mUserId), "roles-" + mUserId);
         FileOutputStream out = null;
         try {
@@ -280,7 +306,7 @@
                     "http://xmlpull.org/v1/doc/features.html#indent-output", true);
             serializer.startDocument(null, true);
 
-            serializeRoles(serializer, version, roles, packagesHash);
+            serializeRoles(serializer, version, packagesHash, roles);
 
             serializer.endDocument();
             atomicFile.finishWrite(out);
@@ -296,19 +322,26 @@
 
     @WorkerThread
     private void serializeRoles(@NonNull XmlSerializer serializer, int version,
-            @NonNull ArrayMap<String, ArraySet<String>> roles, String packagesHash)
+            @Nullable String packagesHash, @NonNull ArrayMap<String, ArraySet<String>> roles)
             throws IOException {
         serializer.startTag(null, TAG_ROLES);
+
         serializer.attribute(null, ATTRIBUTE_VERSION, Integer.toString(version));
-        serializer.attribute(null, ATTRIBUTE_PACKAGES_HASH, packagesHash);
+
+        if (packagesHash != null) {
+            serializer.attribute(null, ATTRIBUTE_PACKAGES_HASH, packagesHash);
+        }
+
         for (int i = 0, size = roles.size(); i < size; ++i) {
             String roleName = roles.keyAt(i);
             ArraySet<String> roleHolders = roles.valueAt(i);
+
             serializer.startTag(null, TAG_ROLE);
             serializer.attribute(null, ATTRIBUTE_NAME, roleName);
             serializeRoleHolders(serializer, roleHolders);
             serializer.endTag(null, TAG_ROLE);
         }
+
         serializer.endTag(null, TAG_ROLES);
     }
 
@@ -317,6 +350,7 @@
             @NonNull ArraySet<String> roleHolders) throws IOException {
         for (int i = 0, size = roleHolders.size(); i < size; ++i) {
             String roleHolder = roleHolders.valueAt(i);
+
             serializer.startTag(null, TAG_HOLDER);
             serializer.attribute(null, ATTRIBUTE_NAME, roleHolder);
             serializer.endTag(null, TAG_HOLDER);
@@ -327,11 +361,7 @@
      * Read the state from file.
      */
     @GuardedBy("RoleManagerService.mLock")
-    public void readSyncLocked() {
-        if (mRoles != null) {
-            throw new IllegalStateException("This RoleUserState has already read the roles.xml");
-        }
-
+    private void readSyncLocked() {
         File file = getFile(mUserId);
         try (FileInputStream in = new AtomicFile(file).openRead()) {
             XmlPullParser parser = Xml.newPullParser();
@@ -339,8 +369,6 @@
             parseXmlLocked(parser);
         } catch (FileNotFoundException e) {
             Slog.i(LOG_TAG, "roles.xml not found");
-            mRoles = new ArrayMap<>();
-            mVersion = VERSION_UNDEFINED;
         } catch (XmlPullParserException | IOException e) {
             throw new IllegalStateException("Failed to parse roles.xml: " + file, e);
         }
@@ -362,13 +390,14 @@
                 return;
             }
         }
+        Slog.w(LOG_TAG, "Missing <" + TAG_ROLES + "> in roles.xml");
     }
 
     private void parseRolesLocked(@NonNull XmlPullParser parser) throws IOException,
             XmlPullParserException {
         mVersion = Integer.parseInt(parser.getAttributeValue(null, ATTRIBUTE_VERSION));
         mLastGrantPackagesHash = parser.getAttributeValue(null, ATTRIBUTE_PACKAGES_HASH);
-        mRoles = new ArrayMap<>();
+        mRoles.clear();
 
         int type;
         int depth;
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index f1d77b9..581cec9 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -2834,6 +2834,9 @@
             return 0;
         }
 
+        mDisplayContent.getInsetsStateController().onBarControllingWindowChanged(
+                mTopFullscreenOpaqueWindowState);
+
         int tmpVisibility = PolicyControl.getSystemUiVisibility(win, null)
                 & ~mResettingSystemUiFlags
                 & ~mForceClearedSystemUiFlags;
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index e96f0b1..282838f 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -18,11 +18,18 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.graphics.Point;
 import android.graphics.Rect;
+import android.util.proto.ProtoOutputStream;
+import android.view.SurfaceControl;
+import android.view.SurfaceControl.Transaction;
 import android.view.InsetsSource;
+import android.view.InsetsSourceControl;
 
 import com.android.internal.util.function.TriConsumer;
-import com.android.server.policy.WindowManagerPolicy;
+import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
+
+import java.io.PrintWriter;
 
 /**
  * Controller for a specific inset source on the server. It's called provider as it provides the
@@ -32,11 +39,19 @@
 
     private final Rect mTmpRect = new Rect();
     private final @NonNull InsetsSource mSource;
+    private final DisplayContent mDisplayContent;
+    private final InsetsStateController mStateController;
+    private @Nullable InsetsSourceControl mControl;
+    private @Nullable WindowState mControllingWin;
+    private @Nullable ControlAdapter mAdapter;
     private WindowState mWin;
     private TriConsumer<DisplayFrames, WindowState, Rect> mFrameProvider;
 
-    InsetsSourceProvider(InsetsSource source) {
+    InsetsSourceProvider(InsetsSource source, InsetsStateController stateController,
+            DisplayContent displayContent) {
         mSource = source;
+        mDisplayContent = displayContent;
+        mStateController = stateController;
     }
 
     InsetsSource getSource() {
@@ -84,4 +99,81 @@
         mSource.setVisible(mWin.isVisible() && !mWin.mGivenInsetsPending);
 
     }
+
+    void updateControlForTarget(@Nullable WindowState target) {
+        if (target == mControllingWin) {
+            return;
+        }
+        if (target == null) {
+            revokeControl();
+            return;
+        }
+        mAdapter = new ControlAdapter();
+        mWin.startAnimation(mDisplayContent.getPendingTransaction(), mAdapter,
+                false /* TODO hidden */);
+        mControllingWin = target;
+        mControl = new InsetsSourceControl(mSource.getType(), mAdapter.mCapturedLeash);
+    }
+
+    InsetsSourceControl getControl() {
+        return mControl;
+    }
+
+    void revokeControl() {
+        if (mControllingWin != null) {
+
+            // Cancelling the animation will invoke onAnimationCancelled, resetting all the fields.
+            mWin.cancelAnimation();
+        }
+    }
+
+    private class ControlAdapter implements AnimationAdapter {
+
+        private SurfaceControl mCapturedLeash;
+
+        @Override
+        public boolean getShowWallpaper() {
+            return false;
+        }
+
+        @Override
+        public int getBackgroundColor() {
+            return 0;
+        }
+
+        @Override
+        public void startAnimation(SurfaceControl animationLeash, Transaction t,
+                OnAnimationFinishedCallback finishCallback) {
+            mCapturedLeash = animationLeash;
+            t.setPosition(mCapturedLeash, mSource.getFrame().left, mSource.getFrame().top);
+        }
+
+        @Override
+        public void onAnimationCancelled(SurfaceControl animationLeash) {
+            if (mAdapter == this) {
+                mStateController.notifyControlRevoked(mControllingWin, InsetsSourceProvider.this);
+                mControl = null;
+                mControllingWin = null;
+                mAdapter = null;
+            }
+        }
+
+        @Override
+        public long getDurationHint() {
+            return 0;
+        }
+
+        @Override
+        public long getStatusBarTransitionsStartTime() {
+            return 0;
+        }
+
+        @Override
+        public void dump(PrintWriter pw, String prefix) {
+        }
+
+        @Override
+        public void writeToProto(ProtoOutputStream proto) {
+        }
+    };
 }
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index 1189ee6..592b7fb 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -20,10 +20,17 @@
 import static android.view.InsetsState.TYPE_NAVIGATION_BAR;
 import static android.view.InsetsState.TYPE_TOP_BAR;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.SparseArray;
+import android.view.InsetsSourceControl;
 import android.view.InsetsState;
+import android.view.ViewRootImpl;
 
 import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.function.Consumer;
 
 /**
@@ -34,7 +41,11 @@
     private final InsetsState mLastState = new InsetsState();
     private final InsetsState mState = new InsetsState();
     private final DisplayContent mDisplayContent;
-    private ArrayMap<Integer, InsetsSourceProvider> mControllers = new ArrayMap<>();
+
+    private final ArrayMap<Integer, InsetsSourceProvider> mControllers = new ArrayMap<>();
+    private final ArrayMap<WindowState, ArrayList<Integer>> mWinControlTypeMap = new ArrayMap<>();
+    private final SparseArray<WindowState> mTypeWinControlMap = new SparseArray<>();
+    private final ArraySet<WindowState> mPendingControlChanged = new ArraySet<>();
 
     private final Consumer<WindowState> mDispatchInsetsChanged = w -> {
         if (w.isVisible()) {
@@ -72,12 +83,25 @@
         return state;
     }
 
+    @Nullable InsetsSourceControl[] getControlsForDispatch(WindowState target) {
+        ArrayList<Integer> controlled = mWinControlTypeMap.get(target);
+        if (controlled == null) {
+            return null;
+        }
+        final int size = controlled.size();
+        final InsetsSourceControl[] result = new InsetsSourceControl[size];
+        for (int i = 0; i < size; i++) {
+            result[i] = mControllers.get(controlled.get(i)).getControl();
+        }
+        return result;
+    }
+
     /**
      * @return The provider of a specific type.
      */
     InsetsSourceProvider getSourceProvider(int type) {
         return mControllers.computeIfAbsent(type,
-                key -> new InsetsSourceProvider(mState.getSource(key)));
+                key -> new InsetsSourceProvider(mState.getSource(key), this, mDisplayContent));
     }
 
     /**
@@ -93,6 +117,84 @@
         }
     }
 
+    void onImeTargetChanged(@Nullable WindowState imeTarget) {
+        onControlChanged(TYPE_IME, imeTarget);
+        notifyPendingInsetsControlChanged();
+    }
+
+    /**
+     * Called when the top opaque fullscreen window that is able to control the system bars changes.
+     *
+     * @param controllingWindow The window that is now able to control the system bars appearance
+     *                          and visibility.
+     */
+    void onBarControllingWindowChanged(@Nullable WindowState controllingWindow) {
+        // TODO: Apply policy that determines whether controllingWindow is able to control system
+        // bars
+
+        // TODO: Depending on the form factor, mapping is different
+        onControlChanged(TYPE_TOP_BAR, controllingWindow);
+        onControlChanged(TYPE_NAVIGATION_BAR, controllingWindow);
+        notifyPendingInsetsControlChanged();
+    }
+
+    void notifyControlRevoked(@NonNull WindowState previousControllingWin,
+            InsetsSourceProvider provider) {
+        removeFromControlMaps(previousControllingWin, provider.getSource().getType());
+    }
+
+    private void onControlChanged(int type, @Nullable WindowState win) {
+        if (!ViewRootImpl.USE_NEW_INSETS) {
+            return;
+        }
+        final WindowState previous = mTypeWinControlMap.get(type);
+        if (win == previous) {
+            return;
+        }
+        final InsetsSourceProvider controller = mControllers.get(type);
+        if (controller == null) {
+            return;
+        }
+        controller.updateControlForTarget(win);
+        if (previous != null) {
+            removeFromControlMaps(previous, type);
+            mPendingControlChanged.add(previous);
+        }
+        if (win != null) {
+            addToControlMaps(win, type);
+            mPendingControlChanged.add(win);
+        }
+    }
+
+    private void removeFromControlMaps(@NonNull WindowState win, int type) {
+        final ArrayList<Integer> array = mWinControlTypeMap.get(win);
+        if (array == null) {
+            return;
+        }
+        array.remove((Integer) type);
+        if (array.isEmpty()) {
+            mWinControlTypeMap.remove(win);
+        }
+        mTypeWinControlMap.remove(type);
+    }
+
+    private void addToControlMaps(@NonNull WindowState win, int type) {
+        final ArrayList<Integer> array = mWinControlTypeMap.computeIfAbsent(win,
+                key -> new ArrayList<>());
+        array.add(type);
+        mTypeWinControlMap.put(type, win);
+    }
+
+    private void notifyPendingInsetsControlChanged() {
+        mDisplayContent.mWmService.mAnimator.addAfterPrepareSurfacesRunnable(() -> {
+            for (int i = mPendingControlChanged.size() - 1; i >= 0; i--) {
+                final WindowState controllingWin = mPendingControlChanged.valueAt(i);
+                controllingWin.notifyInsetsControlChanged();
+            }
+            mPendingControlChanged.clear();
+        });
+    }
+
     private void notifyInsetsChanged() {
         mDisplayContent.forAllWindows(mDispatchInsetsChanged, true /* traverseTopToBottom */);
     }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index cdf9118..ef22bb8 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2972,6 +2972,17 @@
         }
     }
 
+    void notifyInsetsControlChanged() {
+        final InsetsStateController stateController =
+                getDisplayContent().getInsetsStateController();
+        try {
+            mClient.insetsControlChanged(stateController.getInsetsForDispatch(this),
+                    stateController.getControlsForDispatch(this));
+        } catch (RemoteException e) {
+            Slog.w(TAG, "Failed to deliver inset state change", e);
+        }
+    }
+
     Rect getBackdropFrame(Rect frame) {
         // When the task is docked, we send fullscreen sized backDropFrame as soon as resizing
         // start even if we haven't received the relayout window, so that the client requests
diff --git a/services/intelligence/java/com/android/server/intelligence/ContentCaptureSession.java b/services/intelligence/java/com/android/server/intelligence/ContentCaptureSession.java
index 08fbf55..108f91c 100644
--- a/services/intelligence/java/com/android/server/intelligence/ContentCaptureSession.java
+++ b/services/intelligence/java/com/android/server/intelligence/ContentCaptureSession.java
@@ -19,9 +19,9 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.os.IBinder;
-import android.service.intelligence.IntelligenceService;
 import android.service.intelligence.InteractionContext;
 import android.service.intelligence.InteractionSessionId;
+import android.service.intelligence.SmartSuggestionsService;
 import android.service.intelligence.SnapshotData;
 import android.util.Slog;
 import android.view.autofill.AutofillId;
@@ -59,7 +59,7 @@
         mService = service;
         mId = Preconditions.checkNotNull(sessionId);
         mRemoteService = new RemoteIntelligenceService(context,
-                IntelligenceService.SERVICE_INTERFACE, serviceComponentName, userId, this,
+                SmartSuggestionsService.SERVICE_INTERFACE, serviceComponentName, userId, this,
                 bindInstantServiceAllowed, verbose);
         mInterationContext = new InteractionContext(appComponentName, taskId, displayId, flags);
     }
@@ -72,7 +72,7 @@
     }
 
     /**
-     * Notifies the {@link IntelligenceService} that the service started.
+     * Notifies the {@link SmartSuggestionsService} that the service started.
      */
     @GuardedBy("mLock")
     public void notifySessionStartedLocked() {
@@ -80,14 +80,14 @@
     }
 
     /**
-     * Notifies the {@link IntelligenceService} of a batch of events.
+     * Notifies the {@link SmartSuggestionsService} of a batch of events.
      */
     public void sendEventsLocked(@NonNull List<ContentCaptureEvent> events) {
         mRemoteService.onContentCaptureEventsRequest(mId, events);
     }
 
     /**
-     * Notifies the {@link IntelligenceService} of a snapshot of an activity.
+     * Notifies the {@link SmartSuggestionsService} of a snapshot of an activity.
      */
     @GuardedBy("mLock")
     public void sendActivitySnapshotLocked(@NonNull SnapshotData snapshotData) {
@@ -110,7 +110,7 @@
      * Cleans up the session and removes it from the service.
      *
      * @param notifyRemoteService whether it should trigger a {@link
-     * IntelligenceService#onDestroyInteractionSession(InteractionSessionId)}
+     * SmartSuggestionsService#onDestroyInteractionSession(InteractionSessionId)}
      * request.
      */
     @GuardedBy("mLock")
@@ -126,7 +126,7 @@
      * Cleans up the session, but not removes it from the service.
      *
      * @param notifyRemoteService whether it should trigger a {@link
-     * IntelligenceService#onDestroyInteractionSession(InteractionSessionId)}
+     * SmartSuggestionsService#onDestroyInteractionSession(InteractionSessionId)}
      * request.
      */
     @GuardedBy("mLock")
diff --git a/services/intelligence/java/com/android/server/intelligence/IntelligenceManagerService.java b/services/intelligence/java/com/android/server/intelligence/IntelligenceManagerService.java
index 9fd797d..e0d47d2 100644
--- a/services/intelligence/java/com/android/server/intelligence/IntelligenceManagerService.java
+++ b/services/intelligence/java/com/android/server/intelligence/IntelligenceManagerService.java
@@ -16,7 +16,7 @@
 
 package com.android.server.intelligence;
 
-import static android.content.Context.INTELLIGENCE_MANAGER_SERVICE;
+import static android.content.Context.CONTENT_CAPTURE_MANAGER_SERVICE;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -50,6 +50,7 @@
  * <p>The data collected by this service can be analyzed and combined with other sources to provide
  * contextual data in other areas of the system such as Autofill.
  */
+//TODO(b/111276913): rename once the final name is defined
 public final class IntelligenceManagerService extends
         AbstractMasterSystemService<IntelligenceManagerService, IntelligencePerUserService> {
 
@@ -67,7 +68,7 @@
     @Override // from AbstractMasterSystemService
     protected String getServiceSettingsProperty() {
         // TODO(b/111276913): STOPSHIP temporary settings, until it's set by resourcs + cmd
-        return "intel_service";
+        return "smart_suggestions_service";
     }
 
     @Override // from AbstractMasterSystemService
@@ -78,7 +79,7 @@
 
     @Override // from SystemService
     public void onStart() {
-        publishBinderService(INTELLIGENCE_MANAGER_SERVICE,
+        publishBinderService(CONTENT_CAPTURE_MANAGER_SERVICE,
                 new IntelligenceManagerServiceStub());
         publishLocalService(IntelligenceManagerInternal.class, mLocalService);
     }
diff --git a/services/intelligence/java/com/android/server/intelligence/IntelligencePerUserService.java b/services/intelligence/java/com/android/server/intelligence/IntelligencePerUserService.java
index 9ab7e58..e3b09c6 100644
--- a/services/intelligence/java/com/android/server/intelligence/IntelligencePerUserService.java
+++ b/services/intelligence/java/com/android/server/intelligence/IntelligencePerUserService.java
@@ -41,7 +41,7 @@
 import android.view.autofill.AutofillId;
 import android.view.autofill.IAutoFillManagerClient;
 import android.view.intelligence.ContentCaptureEvent;
-import android.view.intelligence.IntelligenceManager;
+import android.view.intelligence.ContentCaptureManager;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.IResultReceiver;
@@ -54,6 +54,7 @@
 /**
  * Per-user instance of {@link IntelligenceManagerService}.
  */
+//TODO(b/111276913): rename once the final name is defined
 final class IntelligencePerUserService
         extends AbstractPerUserSystemService<IntelligencePerUserService,
             IntelligenceManagerService> {
@@ -86,16 +87,23 @@
             Slog.w(TAG, "Could not get service for " + serviceComponent + ": " + e);
             return null;
         }
-        if (!Manifest.permission.BIND_INTELLIGENCE_SERVICE.equals(si.permission)) {
-            Slog.w(TAG, "IntelligenceService from '" + si.packageName
+        if (!Manifest.permission.BIND_SMART_SUGGESTIONS_SERVICE.equals(si.permission)) {
+            Slog.w(TAG, "SmartSuggestionsService from '" + si.packageName
                     + "' does not require permission "
-                    + Manifest.permission.BIND_INTELLIGENCE_SERVICE);
+                    + Manifest.permission.BIND_SMART_SUGGESTIONS_SERVICE);
             throw new SecurityException("Service does not require permission "
-                    + Manifest.permission.BIND_INTELLIGENCE_SERVICE);
+                    + Manifest.permission.BIND_SMART_SUGGESTIONS_SERVICE);
         }
         return si;
     }
 
+    @Override // from PerUserSystemService
+    @GuardedBy("mLock")
+    protected boolean updateLocked(boolean disabled) {
+        destroyLocked();
+        return super.updateLocked(disabled);
+    }
+
     // TODO(b/111276913): log metrics
     @GuardedBy("mLock")
     public void startSessionLocked(@NonNull IBinder activityToken,
@@ -103,7 +111,7 @@
             @NonNull InteractionSessionId sessionId, int flags,
             @NonNull IResultReceiver resultReceiver) {
         if (!isEnabledLocked()) {
-            sendToClient(resultReceiver, IntelligenceManager.STATE_DISABLED);
+            sendToClient(resultReceiver, ContentCaptureManager.STATE_DISABLED);
             return;
         }
         final ComponentName serviceComponentName = getServiceComponentName();
@@ -126,7 +134,7 @@
             // TODO(b/111276913): check if local ids match and decide what to do if they don't
             // TODO(b/111276913): should we call session.notifySessionStartedLocked() again??
             // if not, move notifySessionStartedLocked() into session constructor
-            sendToClient(resultReceiver, IntelligenceManager.STATE_ACTIVE);
+            sendToClient(resultReceiver, ContentCaptureManager.STATE_ACTIVE);
             return;
         }
 
@@ -142,7 +150,7 @@
         }
         mSessions.put(sessionId, session);
         session.notifySessionStartedLocked();
-        sendToClient(resultReceiver, IntelligenceManager.STATE_ACTIVE);
+        sendToClient(resultReceiver, ContentCaptureManager.STATE_ACTIVE);
     }
 
     // TODO(b/111276913): log metrics
@@ -192,7 +200,7 @@
             return;
         }
         if (mMaster.verbose) {
-            Slog.v(TAG, "sendEvents(): id=" + sessionId + "; events =" + events.size());
+            Slog.v(TAG, "sendEvents(): id=" + sessionId + ", events=" + events.size());
         }
         session.sendEventsLocked(events);
     }
diff --git a/services/intelligence/java/com/android/server/intelligence/RemoteIntelligenceService.java b/services/intelligence/java/com/android/server/intelligence/RemoteIntelligenceService.java
index 00c5b6a..d9f4f20 100644
--- a/services/intelligence/java/com/android/server/intelligence/RemoteIntelligenceService.java
+++ b/services/intelligence/java/com/android/server/intelligence/RemoteIntelligenceService.java
@@ -23,6 +23,7 @@
 import android.os.IBinder;
 import android.os.IInterface;
 import android.os.RemoteException;
+import android.service.intelligence.ContentCaptureEventsRequest;
 import android.service.intelligence.IIntelligenceService;
 import android.service.intelligence.InteractionContext;
 import android.service.intelligence.InteractionSessionId;
@@ -35,11 +36,13 @@
 import android.view.intelligence.ContentCaptureEvent;
 
 import com.android.internal.os.IResultReceiver;
-import com.android.server.AbstractRemoteService;
+import com.android.server.AbstractMultiplePendingRequestsRemoteService;
 
 import java.util.List;
 
-final class RemoteIntelligenceService extends AbstractRemoteService {
+//TODO(b/111276913): rename once the final name is defined
+final class RemoteIntelligenceService
+        extends AbstractMultiplePendingRequestsRemoteService<RemoteIntelligenceService> {
 
     private static final String TAG = "RemoteIntelligenceService";
 
@@ -54,7 +57,7 @@
             RemoteIntelligenceServiceCallbacks callbacks, boolean bindInstantServiceAllowed,
             boolean verbose) {
         super(context, serviceInterface, componentName, userId, callbacks,
-                bindInstantServiceAllowed, verbose);
+                bindInstantServiceAllowed, verbose, /* initialCapacity= */ 2);
         mCallbacks = callbacks;
     }
 
@@ -194,7 +197,8 @@
 
         @Override // from MyPendingRequest
         public void myRun(@NonNull RemoteIntelligenceService remoteService) throws RemoteException {
-            remoteService.mService.onContentCaptureEvents(mSessionId, mEvents);
+            remoteService.mService.onContentCaptureEventsRequest(mSessionId,
+                    new ContentCaptureEventsRequest(mEvents));
         }
     }
 
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 56f7cff..f3704d8 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1503,6 +1503,14 @@
             }
             traceEnd();
 
+            traceBeginAndSlog("RuntimeService");
+            try {
+                ServiceManager.addService("runtime", new RuntimeService(context));
+            } catch (Throwable e) {
+                reportWtf("starting RuntimeService", e);
+            }
+            traceEnd();
+
             // timezone.RulesManagerService will prevent a device starting up if the chain of trust
             // required for safe time zone updates might be broken. RuleManagerService cannot do
             // this check when mOnlyCore == true, so we don't enable the service in this case.
diff --git a/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java
index 7cf7df13..5077f92 100644
--- a/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java
@@ -271,7 +271,7 @@
         int status = Temperature.THROTTLING_WARNING;
         Temperature newSkin = new Temperature(100, Temperature.TYPE_SKIN, "skin1", status);
         mFakeHal.mCallback.onValues(newSkin);
-        assertEquals(status, mService.mService.getCurrentStatus());
+        assertEquals(status, mService.mService.getCurrentThermalStatus());
     }
 
     @Test
@@ -294,6 +294,6 @@
         assertEquals(0, mService.mService.getCurrentTemperatures().size());
         assertEquals(0,
                 mService.mService.getCurrentTemperaturesWithType(Temperature.TYPE_SKIN).size());
-        assertEquals(Temperature.THROTTLING_NONE, mService.mService.getCurrentStatus());
+        assertEquals(Temperature.THROTTLING_NONE, mService.mService.getCurrentThermalStatus());
     }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
index b94f472..845a09f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
@@ -95,52 +95,6 @@
     }
 
     @Test
-    public void layoutWindowLw_appDrawsBars() {
-        mWindow.mAttrs.flags |= FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
-        addWindow(mWindow);
-
-        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
-        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
-
-        assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
-        assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
-        assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0);
-    }
-
-    @Test
-    public void layoutWindowLw_appWontDrawBars() {
-        mWindow.mAttrs.flags &= ~FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
-        addWindow(mWindow);
-
-        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
-        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
-
-        assertInsetByTopBottom(mWindow.getParentFrame(), 0, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getDecorFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, NAV_BAR_HEIGHT);
-    }
-
-    @Test
-    public void layoutWindowLw_appWontDrawBars_forceStatus() throws Exception {
-        mWindow.mAttrs.flags &= ~FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
-        mWindow.mAttrs.privateFlags |= PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
-        addWindow(mWindow);
-
-        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
-        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
-
-        assertInsetByTopBottom(mWindow.getParentFrame(), 0, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getDecorFrame(), 0, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, NAV_BAR_HEIGHT);
-    }
-
-    @Test
     public void addingWindow_doesNotTamperWithSysuiFlags() {
         mWindow.mAttrs.flags |= FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
         addWindow(mWindow);
@@ -150,253 +104,331 @@
     }
 
     @Test
+    public void layoutWindowLw_appDrawsBars() {
+        synchronized (mWm.mGlobalLock) {
+            mWindow.mAttrs.flags |= FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+            addWindow(mWindow);
+
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+
+            assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
+            assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
+            assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0);
+        }
+    }
+
+    @Test
+    public void layoutWindowLw_appWontDrawBars() {
+        synchronized (mWm.mGlobalLock) {
+            mWindow.mAttrs.flags &= ~FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+            addWindow(mWindow);
+
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+
+            assertInsetByTopBottom(mWindow.getParentFrame(), 0, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getDecorFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, NAV_BAR_HEIGHT);
+        }
+    }
+
+    @Test
+    public void layoutWindowLw_appWontDrawBars_forceStatus() throws Exception {
+        synchronized (mWm.mGlobalLock) {
+            mWindow.mAttrs.flags &= ~FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+            mWindow.mAttrs.privateFlags |= PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
+            addWindow(mWindow);
+
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+
+            assertInsetByTopBottom(mWindow.getParentFrame(), 0, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getDecorFrame(), 0, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, NAV_BAR_HEIGHT);
+        }
+    }
+
+    @Test
     public void layoutWindowLw_withDisplayCutout() {
-        addDisplayCutout();
+        synchronized (mWm.mGlobalLock) {
+            addDisplayCutout();
 
-        addWindow(mWindow);
+            addWindow(mWindow);
 
-        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
-        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
 
-        assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
-        assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
-        assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0);
+            assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
+            assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
+            assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0);
+        }
     }
 
     @Test
     public void layoutWindowLw_withDisplayCutout_never() {
-        addDisplayCutout();
+        synchronized (mWm.mGlobalLock) {
+            addDisplayCutout();
 
-        mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
-        addWindow(mWindow);
+            mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
+            addWindow(mWindow);
 
-        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
-        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
 
-        assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, 0);
-        assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
-        assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, 0);
+            assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, 0);
+            assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
+            assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, 0);
+        }
     }
 
     @Test
     public void layoutWindowLw_withDisplayCutout_layoutFullscreen() {
-        addDisplayCutout();
+        synchronized (mWm.mGlobalLock) {
+            addDisplayCutout();
 
-        mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
-        addWindow(mWindow);
+            mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
+            addWindow(mWindow);
 
-        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
-        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
 
-        assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
-        assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
-        assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0);
+            assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
+            assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
+            assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0);
+        }
     }
 
     @Test
     public void layoutWindowLw_withDisplayCutout_fullscreen() {
-        addDisplayCutout();
+        synchronized (mWm.mGlobalLock) {
+            addDisplayCutout();
 
-        mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_FULLSCREEN;
-        addWindow(mWindow);
+            mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_FULLSCREEN;
+            addWindow(mWindow);
 
-        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
-        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
 
-        assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, 0);
-        assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
-        assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, 0);
+            assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, 0);
+            assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
+            assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, 0);
+        }
     }
 
     @Test
     public void layoutWindowLw_withDisplayCutout_fullscreenInCutout() {
-        addDisplayCutout();
+        synchronized (mWm.mGlobalLock) {
+            addDisplayCutout();
 
-        mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_FULLSCREEN;
-        mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
-        addWindow(mWindow);
+            mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_FULLSCREEN;
+            mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+            addWindow(mWindow);
 
-        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
-        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
 
-        assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
-        assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
-        assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0);
+            assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
+            assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
+            assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0);
+        }
     }
 
 
     @Test
     public void layoutWindowLw_withDisplayCutout_landscape() {
-        addDisplayCutout();
-        setRotation(ROTATION_90);
-        addWindow(mWindow);
+        synchronized (mWm.mGlobalLock) {
+            addDisplayCutout();
+            setRotation(ROTATION_90);
+            addWindow(mWindow);
 
-        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
-        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
 
-        assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
-        assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
-        assertInsetBy(mWindow.getContentFrameLw(),
-                DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
-        assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
-        assertInsetBy(mWindow.getDisplayFrameLw(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
+            assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
+            assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+            assertInsetBy(mWindow.getContentFrameLw(),
+                    DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+            assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
+            assertInsetBy(mWindow.getDisplayFrameLw(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
+        }
     }
 
     @Test
     public void layoutWindowLw_withDisplayCutout_seascape() {
-        addDisplayCutout();
-        setRotation(ROTATION_270);
-        addWindow(mWindow);
+        synchronized (mWm.mGlobalLock) {
+            addDisplayCutout();
+            setRotation(ROTATION_270);
+            addWindow(mWindow);
 
-        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
-        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
 
-        assertInsetBy(mWindow.getParentFrame(), 0, 0, DISPLAY_CUTOUT_HEIGHT, 0);
-        assertInsetBy(mWindow.getStableFrameLw(), NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, 0, 0);
-        assertInsetBy(mWindow.getContentFrameLw(),
-                NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, DISPLAY_CUTOUT_HEIGHT, 0);
-        assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
-        assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, DISPLAY_CUTOUT_HEIGHT, 0);
+            assertInsetBy(mWindow.getParentFrame(), 0, 0, DISPLAY_CUTOUT_HEIGHT, 0);
+            assertInsetBy(mWindow.getStableFrameLw(), NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, 0, 0);
+            assertInsetBy(mWindow.getContentFrameLw(),
+                    NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, DISPLAY_CUTOUT_HEIGHT, 0);
+            assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
+            assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, DISPLAY_CUTOUT_HEIGHT, 0);
+        }
     }
 
     @Test
     public void layoutWindowLw_withDisplayCutout_fullscreen_landscape() {
-        addDisplayCutout();
-        setRotation(ROTATION_90);
+        synchronized (mWm.mGlobalLock) {
+            addDisplayCutout();
+            setRotation(ROTATION_90);
 
-        mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
-        addWindow(mWindow);
+            mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
+            addWindow(mWindow);
 
-        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
-        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
 
-        assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
-        assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
-        assertInsetBy(mWindow.getContentFrameLw(),
-                DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
-        assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
+            assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
+            assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+            assertInsetBy(mWindow.getContentFrameLw(),
+                    DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+            assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
+        }
     }
 
     @Test
     public void layoutWindowLw_withDisplayCutout_floatingInScreen() {
-        addDisplayCutout();
+        synchronized (mWm.mGlobalLock) {
+            addDisplayCutout();
 
-        mWindow.mAttrs.flags = FLAG_LAYOUT_IN_SCREEN;
-        mWindow.mAttrs.type = TYPE_APPLICATION_OVERLAY;
-        mWindow.mAttrs.width = DISPLAY_WIDTH;
-        mWindow.mAttrs.height = DISPLAY_HEIGHT;
-        addWindow(mWindow);
+            mWindow.mAttrs.flags = FLAG_LAYOUT_IN_SCREEN;
+            mWindow.mAttrs.type = TYPE_APPLICATION_OVERLAY;
+            mWindow.mAttrs.width = DISPLAY_WIDTH;
+            mWindow.mAttrs.height = DISPLAY_HEIGHT;
+            addWindow(mWindow);
 
-        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
-        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
 
-        assertInsetByTopBottom(mWindow.getParentFrame(), 0, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getParentFrame(), 0, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+        }
     }
 
     @Test
     public void layoutWindowLw_withDisplayCutout_fullscreenInCutout_landscape() {
-        addDisplayCutout();
-        setRotation(ROTATION_90);
+        synchronized (mWm.mGlobalLock) {
+            addDisplayCutout();
+            setRotation(ROTATION_90);
 
-        mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
-        mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
-        addWindow(mWindow);
+            mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
+            mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+            addWindow(mWindow);
 
-        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
-        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
 
-        assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0);
-        assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
-        assertInsetBy(mWindow.getContentFrameLw(),
-                DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
-        assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
+            assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0);
+            assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+            assertInsetBy(mWindow.getContentFrameLw(),
+                    DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+            assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
+        }
     }
 
     @Test
     public void layoutHint_appWindow() {
-        // Initialize DisplayFrames
-        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+        synchronized (mWm.mGlobalLock) {
+            // Initialize DisplayFrames
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
 
-        final Rect outFrame = new Rect();
-        final Rect outContentInsets = new Rect();
-        final Rect outStableInsets = new Rect();
-        final Rect outOutsets = new Rect();
-        final DisplayCutout.ParcelableWrapper outDisplayCutout =
-                new DisplayCutout.ParcelableWrapper();
+            final Rect outFrame = new Rect();
+            final Rect outContentInsets = new Rect();
+            final Rect outStableInsets = new Rect();
+            final Rect outOutsets = new Rect();
+            final DisplayCutout.ParcelableWrapper outDisplayCutout =
+                    new DisplayCutout.ParcelableWrapper();
 
-        mDisplayPolicy.getLayoutHintLw(mWindow.mAttrs, null, mFrames,
-                false /* floatingStack */, outFrame, outContentInsets, outStableInsets, outOutsets,
-                outDisplayCutout);
+            mDisplayPolicy.getLayoutHintLw(mWindow.mAttrs, null, mFrames,
+                    false /* floatingStack */, outFrame, outContentInsets, outStableInsets,
+                    outOutsets, outDisplayCutout);
 
-        assertThat(outFrame, is(mFrames.mUnrestricted));
-        assertThat(outContentInsets, is(new Rect(0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT)));
-        assertThat(outStableInsets, is(new Rect(0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT)));
-        assertThat(outOutsets, is(new Rect()));
-        assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper()));
+            assertThat(outFrame, is(mFrames.mUnrestricted));
+            assertThat(outContentInsets, is(new Rect(0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT)));
+            assertThat(outStableInsets, is(new Rect(0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT)));
+            assertThat(outOutsets, is(new Rect()));
+            assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper()));
+        }
     }
 
     @Test
     public void layoutHint_appWindowInTask() {
-        // Initialize DisplayFrames
-        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+        synchronized (mWm.mGlobalLock) {
+            // Initialize DisplayFrames
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
 
-        final Rect taskBounds = new Rect(100, 100, 200, 200);
+            final Rect taskBounds = new Rect(100, 100, 200, 200);
 
-        final Rect outFrame = new Rect();
-        final Rect outContentInsets = new Rect();
-        final Rect outStableInsets = new Rect();
-        final Rect outOutsets = new Rect();
-        final DisplayCutout.ParcelableWrapper outDisplayCutout =
-                new DisplayCutout.ParcelableWrapper();
+            final Rect outFrame = new Rect();
+            final Rect outContentInsets = new Rect();
+            final Rect outStableInsets = new Rect();
+            final Rect outOutsets = new Rect();
+            final DisplayCutout.ParcelableWrapper outDisplayCutout =
+                    new DisplayCutout.ParcelableWrapper();
 
-        mDisplayPolicy.getLayoutHintLw(mWindow.mAttrs, taskBounds, mFrames,
-                false /* floatingStack */, outFrame, outContentInsets, outStableInsets, outOutsets,
-                outDisplayCutout);
+            mDisplayPolicy.getLayoutHintLw(mWindow.mAttrs, taskBounds, mFrames,
+                    false /* floatingStack */, outFrame, outContentInsets, outStableInsets,
+                    outOutsets, outDisplayCutout);
 
-        assertThat(outFrame, is(taskBounds));
-        assertThat(outContentInsets, is(new Rect()));
-        assertThat(outStableInsets, is(new Rect()));
-        assertThat(outOutsets, is(new Rect()));
-        assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper()));
+            assertThat(outFrame, is(taskBounds));
+            assertThat(outContentInsets, is(new Rect()));
+            assertThat(outStableInsets, is(new Rect()));
+            assertThat(outOutsets, is(new Rect()));
+            assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper()));
+        }
     }
 
     @Test
     public void layoutHint_appWindowInTask_outsideContentFrame() {
-        // Initialize DisplayFrames
-        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+        synchronized (mWm.mGlobalLock) {
+            // Initialize DisplayFrames
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
 
-        // Task is in the nav bar area (usually does not happen, but this is similar enough to the
-        // possible overlap with the IME)
-        final Rect taskBounds = new Rect(100, mFrames.mContent.bottom + 1,
-                200, mFrames.mContent.bottom + 10);
+            // Task is in the nav bar area (usually does not happen, but this is similar enough to
+            // the possible overlap with the IME)
+            final Rect taskBounds = new Rect(100, mFrames.mContent.bottom + 1,
+                    200, mFrames.mContent.bottom + 10);
 
-        final Rect outFrame = new Rect();
-        final Rect outContentInsets = new Rect();
-        final Rect outStableInsets = new Rect();
-        final Rect outOutsets = new Rect();
-        final DisplayCutout.ParcelableWrapper outDisplayCutout =
-                new DisplayCutout.ParcelableWrapper();
+            final Rect outFrame = new Rect();
+            final Rect outContentInsets = new Rect();
+            final Rect outStableInsets = new Rect();
+            final Rect outOutsets = new Rect();
+            final DisplayCutout.ParcelableWrapper outDisplayCutout =
+                    new DisplayCutout.ParcelableWrapper();
 
-        mDisplayPolicy.getLayoutHintLw(mWindow.mAttrs, taskBounds, mFrames,
-                true /* floatingStack */, outFrame, outContentInsets, outStableInsets, outOutsets,
-                outDisplayCutout);
+            mDisplayPolicy.getLayoutHintLw(mWindow.mAttrs, taskBounds, mFrames,
+                    true /* floatingStack */, outFrame, outContentInsets, outStableInsets,
+                    outOutsets, outDisplayCutout);
 
-        assertThat(outFrame, is(taskBounds));
-        assertThat(outContentInsets, is(new Rect()));
-        assertThat(outStableInsets, is(new Rect()));
-        assertThat(outOutsets, is(new Rect()));
-        assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper()));
+            assertThat(outFrame, is(taskBounds));
+            assertThat(outContentInsets, is(new Rect()));
+            assertThat(outStableInsets, is(new Rect()));
+            assertThat(outOutsets, is(new Rect()));
+            assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper()));
+        }
     }
 
     /**
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
index c11e606..88215449 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
@@ -29,6 +29,7 @@
 import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
+import org.junit.Before;
 import org.junit.Test;
 
 @SmallTest
@@ -36,8 +37,15 @@
 @Presubmit
 public class InsetsSourceProviderTest extends WindowTestsBase {
 
-    private InsetsSourceProvider mProvider = new InsetsSourceProvider(
-            new InsetsSource(TYPE_TOP_BAR));
+    private InsetsSource mSource = new InsetsSource(TYPE_TOP_BAR);
+    private InsetsSourceProvider mProvider;
+
+    @Before
+    public void setUp() throws Exception {
+        mSource.setVisible(true);
+        mProvider = new InsetsSourceProvider(mSource,
+                mDisplayContent.getInsetsStateController(), mDisplayContent);
+    }
 
     @Test
     public void testPostLayout() {
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
index 331622c..11526a8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
@@ -23,8 +23,10 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 
 import android.platform.test.annotations.Presubmit;
+import android.view.InsetsSourceControl;
 import android.view.InsetsState;
 
 import androidx.test.filters.FlakyTest;
@@ -41,12 +43,9 @@
     public void testStripForDispatch_notOwn() {
         final WindowState topBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
         final WindowState app = createWindow(null, TYPE_APPLICATION, "parentWindow");
-        mDisplayContent.getInsetsStateController().getSourceProvider(TYPE_TOP_BAR)
-                .setWindow(topBar, null);
-        topBar.setInsetProvider(
-                mDisplayContent.getInsetsStateController().getSourceProvider(TYPE_TOP_BAR));
-        assertNotNull(mDisplayContent.getInsetsStateController().getInsetsForDispatch(app)
-                .getSource(TYPE_TOP_BAR));
+        getController().getSourceProvider(TYPE_TOP_BAR).setWindow(topBar, null);
+        topBar.setInsetProvider(getController().getSourceProvider(TYPE_TOP_BAR));
+        assertNotNull(getController().getInsetsForDispatch(app).getSource(TYPE_TOP_BAR));
     }
 
     @Test
@@ -54,10 +53,8 @@
         final WindowState topBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
         mDisplayContent.getInsetsStateController().getSourceProvider(TYPE_TOP_BAR)
                 .setWindow(topBar, null);
-        topBar.setInsetProvider(
-                mDisplayContent.getInsetsStateController().getSourceProvider(TYPE_TOP_BAR));
-        assertEquals(new InsetsState(),
-                mDisplayContent.getInsetsStateController().getInsetsForDispatch(topBar));
+        topBar.setInsetProvider(getController().getSourceProvider(TYPE_TOP_BAR));
+        assertEquals(new InsetsState(), getController().getInsetsForDispatch(topBar));
     }
 
     @Test
@@ -65,13 +62,47 @@
         final WindowState navBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
         final WindowState topBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
         final WindowState ime = createWindow(null, TYPE_APPLICATION, "parentWindow");
-        mDisplayContent.getInsetsStateController().getSourceProvider(TYPE_TOP_BAR)
-                .setWindow(topBar, null);
-        mDisplayContent.getInsetsStateController().getSourceProvider(TYPE_NAVIGATION_BAR)
-                .setWindow(navBar, null);
-        mDisplayContent.getInsetsStateController().getSourceProvider(TYPE_IME)
-                .setWindow(ime, null);
-        assertEquals(new InsetsState(),
-                mDisplayContent.getInsetsStateController().getInsetsForDispatch(navBar));
+        getController().getSourceProvider(TYPE_TOP_BAR).setWindow(topBar, null);
+        getController().getSourceProvider(TYPE_NAVIGATION_BAR).setWindow(navBar, null);
+        getController().getSourceProvider(TYPE_IME).setWindow(ime, null);
+        assertEquals(new InsetsState(), getController().getInsetsForDispatch(navBar));
+    }
+
+    @Test
+    public void testBarControllingWinChanged() {
+        final WindowState navBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
+        final WindowState topBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
+        final WindowState app = createWindow(null, TYPE_APPLICATION, "parentWindow");
+        getController().getSourceProvider(TYPE_TOP_BAR).setWindow(topBar, null);
+        getController().getSourceProvider(TYPE_NAVIGATION_BAR).setWindow(navBar, null);
+        getController().onBarControllingWindowChanged(app);
+        InsetsSourceControl[] controls = getController().getControlsForDispatch(app);
+        assertEquals(2, controls.length);
+    }
+
+    @Test
+    public void testControlRevoked() {
+        final WindowState topBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
+        final WindowState app = createWindow(null, TYPE_APPLICATION, "parentWindow");
+        getController().getSourceProvider(TYPE_TOP_BAR).setWindow(topBar, null);
+        getController().onBarControllingWindowChanged(app);
+        assertNotNull(getController().getControlsForDispatch(app));
+        getController().onBarControllingWindowChanged(null);
+        assertNull(getController().getControlsForDispatch(app));
+    }
+
+    @Test
+    public void testControlRevoked_animation() {
+        final WindowState topBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
+        final WindowState app = createWindow(null, TYPE_APPLICATION, "parentWindow");
+        getController().getSourceProvider(TYPE_TOP_BAR).setWindow(topBar, null);
+        getController().onBarControllingWindowChanged(app);
+        assertNotNull(getController().getControlsForDispatch(app));
+        topBar.cancelAnimation();
+        assertNull(getController().getControlsForDispatch(app));
+    }
+
+    private InsetsStateController getController() {
+        return mDisplayContent.getInsetsStateController();
     }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java b/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java
index 432af0d..29738ff 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java
@@ -24,6 +24,7 @@
 import android.view.DisplayCutout;
 import android.view.DragEvent;
 import android.view.IWindow;
+import android.view.InsetsSourceControl;
 import android.view.InsetsState;
 
 import com.android.internal.os.IResultReceiver;
@@ -40,11 +41,17 @@
             Rect backDropFrame, boolean forceLayout, boolean alwaysConsumeNavBar, int displayId,
             DisplayCutout.ParcelableWrapper displayCutout) throws RemoteException {
     }
+
     @Override
     public void insetsChanged(InsetsState insetsState) throws RemoteException {
     }
 
     @Override
+    public void insetsControlChanged(InsetsState insetsState, InsetsSourceControl[] activeControls)
+            throws RemoteException {
+    }
+
+    @Override
     public void moved(int newX, int newY) throws RemoteException {
     }
 
diff --git a/startop/view_compiler/Android.bp b/startop/view_compiler/Android.bp
index 0c40a6b..de40e0d 100644
--- a/startop/view_compiler/Android.bp
+++ b/startop/view_compiler/Android.bp
@@ -24,7 +24,6 @@
         "libdexfile",
         "slicer",
     ],
-    cppflags: ["-std=c++17"],
 }
 
 cc_library_host_static {
diff --git a/telephony/java/android/telephony/AvailableNetworkInfo.aidl b/telephony/java/android/telephony/AvailableNetworkInfo.aidl
new file mode 100644
index 0000000..1d4378c
--- /dev/null
+++ b/telephony/java/android/telephony/AvailableNetworkInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.telephony;
+
+parcelable AvailableNetworkInfo;
diff --git a/telephony/java/android/telephony/AvailableNetworkInfo.java b/telephony/java/android/telephony/AvailableNetworkInfo.java
new file mode 100644
index 0000000..fe07370
--- /dev/null
+++ b/telephony/java/android/telephony/AvailableNetworkInfo.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.telephony;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Defines available network information which includes corresponding subscription id,
+ * network plmns and corresponding priority to be used for network selection by Alternative Network
+ * Service.
+ */
+public final class AvailableNetworkInfo implements Parcelable {
+
+    /*
+     * Defines number of priority level high.
+     */
+    public static final int PRIORITY_HIGH = 1;
+
+    /*
+     * Defines number of priority level medium.
+     */
+    public static final int PRIORITY_MED = 2;
+
+    /*
+     * Defines number of priority level low.
+     */
+    public static final int PRIORITY_LOW = 3;
+
+    /**
+     * subscription Id of the available network. This value must be one of the entry retrieved from
+     * {@link SubscriptionManager#getOpportunisticSubscriptions}
+     */
+    private int mSubId;
+
+    /**
+     * Priority for the subscription id.
+     * Priorities are in the range of 1 to 3 where 1
+     * has the highest priority.
+     */
+    private int mPriority;
+
+    /**
+     * Describes the List of PLMN ids (MCC-MNC) associated with mSubId.
+     * If this entry is left empty, then the platform software will not scan the network
+     * to revalidate the input.
+     */
+    private ArrayList<String> mMccMncs;
+
+    /**
+     * Return subscription Id of the available network.
+     * This value must be one of the entry retrieved from
+     * {@link SubscriptionManager#getOpportunisticSubscriptions}
+     * @return subscription id
+     */
+    public int getSubId() {
+        return mSubId;
+    }
+
+    /**
+     * Return priority for the subscription id. Valid value will be within
+     * [{@link AvailableNetworkInfo#PRIORITY_HIGH}, {@link AvailableNetworkInfo#PRIORITY_LOW}]
+     * @return priority level
+     */
+    public int getPriority() {
+        return mPriority;
+    }
+
+    /**
+     * Return List of PLMN ids (MCC-MNC) associated with the sub ID.
+     * If this entry is left empty, then the platform software will not scan the network
+     * to revalidate the input.
+     * @return list of PLMN ids
+     */
+    public List<String> getMccMncs() {
+        return (List<String>) mMccMncs.clone();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mSubId);
+        dest.writeInt(mPriority);
+        dest.writeStringList(mMccMncs);
+    }
+
+    private AvailableNetworkInfo(Parcel in) {
+        mSubId = in.readInt();
+        mPriority = in.readInt();
+        in.readStringList(mMccMncs);
+    }
+
+    public AvailableNetworkInfo(int subId, int priority, ArrayList<String> mccMncs) {
+        mSubId = subId;
+        mPriority = priority;
+        mMccMncs = new ArrayList<String>(mccMncs);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        AvailableNetworkInfo ani;
+
+        try {
+            ani = (AvailableNetworkInfo) o;
+        } catch (ClassCastException ex) {
+            return false;
+        }
+
+        if (o == null) {
+            return false;
+        }
+
+        return (mSubId == ani.mSubId
+                && mPriority == ani.mPriority
+                && (((mMccMncs != null)
+                && mMccMncs.equals(ani.mMccMncs))));
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mSubId, mPriority, mMccMncs);
+    }
+
+    public static final Parcelable.Creator<AvailableNetworkInfo> CREATOR =
+            new Creator<AvailableNetworkInfo>() {
+                @Override
+                public AvailableNetworkInfo createFromParcel(Parcel in) {
+                    return new AvailableNetworkInfo(in);
+                }
+
+                @Override
+                public AvailableNetworkInfo[] newArray(int size) {
+                    return new AvailableNetworkInfo[size];
+                }
+            };
+
+    @Override
+    public String toString() {
+        return ("AvailableNetworkInfo:"
+                + " mSubId: " + mSubId
+                + " mPriority: " + mPriority
+                + " mMccMncs: " + Arrays.toString(mMccMncs.toArray()));
+    }
+}
+
diff --git a/telephony/java/android/telephony/NumberVerificationCallback.java b/telephony/java/android/telephony/NumberVerificationCallback.java
new file mode 100644
index 0000000..b00c573
--- /dev/null
+++ b/telephony/java/android/telephony/NumberVerificationCallback.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.telephony;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+
+/**
+ * A callback for number verification. After a request for number verification is received,
+ * the system will call {@link #onCallReceived(String)} if a phone call was received from a number
+ * matching the provided {@link PhoneNumberRange} or it will call {@link #onVerificationFailed(int)}
+ * if an error occurs.
+ * @hide
+ */
+@SystemApi
+public interface NumberVerificationCallback {
+    /** @hide */
+    @IntDef(value = {REASON_UNSPECIFIED, REASON_TIMED_OUT, REASON_NETWORK_NOT_AVAILABLE,
+            REASON_TOO_MANY_CALLS, REASON_CONCURRENT_REQUESTS, REASON_IN_ECBM,
+            REASON_IN_EMERGENCY_CALL},
+            prefix = {"REASON_"})
+    @interface NumberVerificationFailureReason {}
+
+    /**
+     * Verification failed for an unspecified reason.
+     */
+    int REASON_UNSPECIFIED = 0;
+
+    /**
+     * Verification failed because no phone call was received from a matching number within the
+     * provided timeout.
+     */
+    int REASON_TIMED_OUT = 1;
+
+    /**
+     * Verification failed because no cellular voice network is available.
+     */
+    int REASON_NETWORK_NOT_AVAILABLE = 2;
+
+    /**
+     * Verification failed because there are currently too many ongoing phone calls for a new
+     * incoming phone call to be received.
+     */
+    int REASON_TOO_MANY_CALLS = 3;
+
+    /**
+     * Verification failed because a previous request for verification has not yet completed.
+     */
+    int REASON_CONCURRENT_REQUESTS = 4;
+
+    /**
+     * Verification failed because the phone is in emergency callback mode.
+     */
+    int REASON_IN_ECBM = 5;
+
+    /**
+     * Verification failed because the phone is currently in an emergency call.
+     */
+    int REASON_IN_EMERGENCY_CALL = 6;
+
+    /**
+     * Called when the device receives a phone call from the provided {@link PhoneNumberRange}.
+     * @param phoneNumber The phone number within the range that called. May or may not contain the
+     *                    country code, but will be entirely numeric.
+     */
+    default void onCallReceived(@NonNull String phoneNumber) { }
+
+    /**
+     * Called when verification fails for some reason.
+     * @param reason The reason for failure.
+     */
+    default void onVerificationFailed(@NumberVerificationFailureReason int reason) { }
+}
diff --git a/telephony/java/android/telephony/PhoneNumberRange.aidl b/telephony/java/android/telephony/PhoneNumberRange.aidl
new file mode 100644
index 0000000..b0727be
--- /dev/null
+++ b/telephony/java/android/telephony/PhoneNumberRange.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.telephony;
+
+parcelable PhoneNumberRange;
diff --git a/telephony/java/android/telephony/PhoneNumberRange.java b/telephony/java/android/telephony/PhoneNumberRange.java
new file mode 100644
index 0000000..d65156f
--- /dev/null
+++ b/telephony/java/android/telephony/PhoneNumberRange.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.telephony;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+import java.util.Objects;
+import java.util.regex.Pattern;
+
+/**
+ * This class is used to represent a range of phone numbers. Each range corresponds to a contiguous
+ * block of phone numbers.
+ *
+ * Example:
+ * {@code
+ * {
+ *     mCountryCode = "1"
+ *     mPrefix = "650555"
+ *     mLowerBound = "0055"
+ *     mUpperBound = "0899"
+ * }
+ * }
+ * would match 16505550089 and 6505550472, but not 63827593759 or 16505550900
+ * @hide
+ */
+@SystemApi
+public final class PhoneNumberRange implements Parcelable {
+    public static final Creator<PhoneNumberRange> CREATOR = new Creator<PhoneNumberRange>() {
+        @Override
+        public PhoneNumberRange createFromParcel(Parcel in) {
+            return new PhoneNumberRange(in);
+        }
+
+        @Override
+        public PhoneNumberRange[] newArray(int size) {
+            return new PhoneNumberRange[size];
+        }
+    };
+
+    private final String mCountryCode;
+    private final String mPrefix;
+    private final String mLowerBound;
+    private final String mUpperBound;
+
+    /**
+     * @param countryCode The country code, omitting the leading "+"
+     * @param prefix A prefix that all numbers matching the range must have.
+     * @param lowerBound When concatenated with the prefix, represents the lower bound of phone
+     *                   numbers that match this range.
+     * @param upperBound When concatenated with the prefix, represents the upper bound of phone
+     *                   numbers that match this range.
+     */
+    public PhoneNumberRange(@NonNull String countryCode, @NonNull String prefix,
+            @NonNull String lowerBound, @NonNull String upperBound) {
+        validateLowerAndUpperBounds(lowerBound, upperBound);
+        if (!Pattern.matches("[0-9]+", countryCode)) {
+            throw new IllegalArgumentException("Country code must be all numeric");
+        }
+        if (!Pattern.matches("[0-9]+", prefix)) {
+            throw new IllegalArgumentException("Prefix must be all numeric");
+        }
+        mCountryCode = countryCode;
+        mPrefix = prefix;
+        mLowerBound = lowerBound;
+        mUpperBound = upperBound;
+    }
+
+    private PhoneNumberRange(Parcel in) {
+        mCountryCode = in.readStringNoHelper();
+        mPrefix = in.readStringNoHelper();
+        mLowerBound = in.readStringNoHelper();
+        mUpperBound = in.readStringNoHelper();
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeStringNoHelper(mCountryCode);
+        dest.writeStringNoHelper(mPrefix);
+        dest.writeStringNoHelper(mLowerBound);
+        dest.writeStringNoHelper(mUpperBound);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        PhoneNumberRange that = (PhoneNumberRange) o;
+        return Objects.equals(mCountryCode, that.mCountryCode)
+                && Objects.equals(mPrefix, that.mPrefix)
+                && Objects.equals(mLowerBound, that.mLowerBound)
+                && Objects.equals(mUpperBound, that.mUpperBound);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mCountryCode, mPrefix, mLowerBound, mUpperBound);
+    }
+
+    @Override
+    public String toString() {
+        return "PhoneNumberRange{"
+                + "mCountryCode='" + mCountryCode + '\''
+                + ", mPrefix='" + mPrefix + '\''
+                + ", mLowerBound='" + mLowerBound + '\''
+                + ", mUpperBound='" + mUpperBound + '\''
+                + '}';
+    }
+
+    private void validateLowerAndUpperBounds(String lowerBound, String upperBound) {
+        if (lowerBound.length() != upperBound.length()) {
+            throw new IllegalArgumentException("Lower and upper bounds must have the same length");
+        }
+        if (!Pattern.matches("[0-9]+", lowerBound)) {
+            throw new IllegalArgumentException("Lower bound must be all numeric");
+        }
+        if (!Pattern.matches("[0-9]+", upperBound)) {
+            throw new IllegalArgumentException("Upper bound must be all numeric");
+        }
+        if (Integer.parseInt(lowerBound) > Integer.parseInt(upperBound)) {
+            throw new IllegalArgumentException("Lower bound must be lower than upper bound");
+        }
+    }
+
+    /**
+     * Checks to see if the provided phone number matches this range.
+     * @param number A phone number, with or without separators or a country code.
+     * @return {@code true} if the number matches, {@code false} otherwise.
+     */
+    public boolean matches(String number) {
+        // Check the prefix, make sure it matches either with or without the country code.
+        String normalizedNumber = number.replaceAll("[^0-9]", "");
+        String prefixWithCountryCode = mCountryCode + mPrefix;
+        String numberPostfix;
+        if (normalizedNumber.startsWith(prefixWithCountryCode)) {
+            numberPostfix = normalizedNumber.substring(prefixWithCountryCode.length());
+        } else if (normalizedNumber.startsWith(mPrefix)) {
+            numberPostfix = normalizedNumber.substring(mPrefix.length());
+        } else {
+            return false;
+        }
+
+        // Next check the postfix to make sure it lies within the bounds.
+        try {
+            int lower = Integer.parseInt(mLowerBound);
+            int upper = Integer.parseInt(mUpperBound);
+            int numberToCheck = Integer.parseInt(numberPostfix);
+            return numberToCheck <= upper && numberToCheck >= lower;
+        } catch (NumberFormatException e) {
+            Log.e(PhoneNumberRange.class.getSimpleName(), "Invalid bounds or number.", e);
+            return false;
+        }
+    }
+}
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index b41e14e..bacfe61a 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -150,6 +150,11 @@
     private String mGroupUUID;
 
     /**
+     *  A property in opportunistic subscription to indicate whether it is metered or not.
+     */
+    private boolean mIsMetered;
+
+    /**
      * @hide
      */
     public SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName,
@@ -158,7 +163,7 @@
             @Nullable UiccAccessRule[] accessRules, String cardId) {
         this(id, iccId, simSlotIndex, displayName, carrierName, nameSource, iconTint, number,
                 roaming, icon, mcc, mnc, countryIso, isEmbedded, accessRules, cardId,
-                false, null);
+                false, null, true);
     }
 
     /**
@@ -168,7 +173,7 @@
             CharSequence carrierName, int nameSource, int iconTint, String number, int roaming,
             Bitmap icon, String mcc, String mnc, String countryIso, boolean isEmbedded,
             @Nullable UiccAccessRule[] accessRules, String cardId, boolean isOpportunistic,
-            @Nullable String groupUUID) {
+            @Nullable String groupUUID, boolean isMetered) {
         this.mId = id;
         this.mIccId = iccId;
         this.mSimSlotIndex = simSlotIndex;
@@ -187,8 +192,10 @@
         this.mCardId = cardId;
         this.mIsOpportunistic = isOpportunistic;
         this.mGroupUUID = groupUUID;
+        this.mIsMetered = isMetered;
     }
 
+
     /**
      * @return the subscription ID.
      */
@@ -403,6 +410,18 @@
     }
 
     /**
+     * Used in opportunistic subscription ({@link #isOpportunistic()}) to indicate whether it's
+     * metered or not.This is one of the factors when deciding to switch to the subscription.
+     * (a non-metered subscription, for example, would likely be preferred over a metered one).
+     *
+     * @return whether subscription is metered.
+     * @hide
+     */
+    public boolean isMetered() {
+        return mIsMetered;
+    }
+
+    /**
      * Checks whether the app with the given context is authorized to manage this subscription
      * according to its metadata. Only supported for embedded subscriptions (if {@link #isEmbedded}
      * returns true).
@@ -496,10 +515,11 @@
             String cardId = source.readString();
             boolean isOpportunistic = source.readBoolean();
             String groupUUID = source.readString();
+            boolean isMetered = source.readBoolean();
 
             return new SubscriptionInfo(id, iccId, simSlotIndex, displayName, carrierName,
                     nameSource, iconTint, number, dataRoaming, iconBitmap, mcc, mnc, countryIso,
-                    isEmbedded, accessRules, cardId, isOpportunistic, groupUUID);
+                    isEmbedded, accessRules, cardId, isOpportunistic, groupUUID, isMetered);
         }
 
         @Override
@@ -528,6 +548,7 @@
         dest.writeString(mCardId);
         dest.writeBoolean(mIsOpportunistic);
         dest.writeString(mGroupUUID);
+        dest.writeBoolean(mIsMetered);
     }
 
     @Override
@@ -561,14 +582,14 @@
                 + " mnc " + mMnc + "mCountryIso=" + mCountryIso + " isEmbedded " + mIsEmbedded
                 + " accessRules " + Arrays.toString(mAccessRules)
                 + " cardId=" + cardIdToPrint + " isOpportunistic " + mIsOpportunistic
-                + " mGroupUUID=" + mGroupUUID + "}";
+                + " mGroupUUID=" + mGroupUUID + " isMetered=" + mIsMetered + "}";
     }
 
     @Override
     public int hashCode() {
         return Objects.hash(mId, mSimSlotIndex, mNameSource, mIconTint, mDataRoaming, mIsEmbedded,
-                mIsOpportunistic, mGroupUUID, mIccId, mNumber, mMcc, mMnc, mCountryIso,
-                mCardId, mDisplayName, mCarrierName, mAccessRules);
+                mIsOpportunistic, mGroupUUID, mIsMetered, mIccId, mNumber, mMcc, mMnc,
+                mCountryIso, mCardId, mDisplayName, mCarrierName, mAccessRules);
     }
 
     @Override
@@ -591,6 +612,7 @@
                 && mIsEmbedded == toCompare.mIsEmbedded
                 && mIsOpportunistic == toCompare.mIsOpportunistic
                 && Objects.equals(mGroupUUID, toCompare.mGroupUUID)
+                && mIsMetered == toCompare.mIsMetered
                 && Objects.equals(mIccId, toCompare.mIccId)
                 && Objects.equals(mNumber, toCompare.mNumber)
                 && Objects.equals(mMcc, toCompare.mMcc)
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 45cfe1e..4b24646 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -576,7 +576,12 @@
      * @hide
      */
     public static final String GROUP_UUID = "group_uuid";
-
+    /**
+     * TelephonyProvider column name for whether a subscription is metered or not, that is, whether
+     * the network it connects to charges for subscription or not. For example, paid CBRS or unpaid.
+     * @hide
+     */
+    public static final String IS_METERED = "is_metered";
     /**
      * Broadcast Action: The user has changed one of the default subs related to
      * data, phone calls, or sms</p>
@@ -2403,6 +2408,21 @@
         return groupUUID;
     }
 
+    /**
+     * Set metered by simInfo index
+     *
+     * @param isMetered whether it’s a metered subscription.
+     * @param subId the unique SubscriptionInfo index in database
+     * @return the number of records updated
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    public int setMetered(boolean isMetered, int subId) {
+        if (VDBG) logd("[setIsMetered]+ isMetered:" + isMetered + " subId:" + subId);
+        return setSubscriptionPropertyHelper(subId, "setIsMetered",
+                (iSub)-> iSub.setMetered(isMetered, subId));
+    }
+
     private interface CallISubMethodHelper {
         int callMethod(ISub iSub) throws RemoteException;
     }
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index d54da09..45d914e 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -77,6 +77,7 @@
 import com.android.internal.telecom.ITelecomService;
 import com.android.internal.telephony.CellNetworkScanResult;
 import com.android.internal.telephony.IAns;
+import com.android.internal.telephony.INumberVerificationCallback;
 import com.android.internal.telephony.IPhoneSubInfo;
 import com.android.internal.telephony.ITelephony;
 import com.android.internal.telephony.ITelephonyRegistry;
@@ -1341,6 +1342,13 @@
      */
     public static final String EXTRA_RECOVERY_ACTION = "recoveryAction";
 
+    /**
+     * The max value for the timeout passed in {@link #requestNumberVerification}.
+     * @hide
+     */
+    @SystemApi
+    public static final long MAX_NUMBER_VERIFICATION_TIMEOUT_MILLIS = 60000;
+
     //
     //
     // Device Info
@@ -5372,7 +5380,7 @@
 
     /**
      * Rollback modem configurations to factory default except some config which are in whitelist.
-     * Used for device configuration by some CDMA operators.
+     * Used for device configuration by some carriers.
      *
      * <p>Requires Permission:
      * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling
@@ -5399,7 +5407,7 @@
     }
 
     /**
-     * Generate a radio modem reset. Used for device configuration by some CDMA operators.
+     * Generate a radio modem reset. Used for device configuration by some carriers.
      *
      * <p>Requires Permission:
      * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling
@@ -5503,6 +5511,52 @@
     }
 
     /**
+     * Request that the next incoming call from a number matching {@code range} be intercepted.
+     *
+     * This API is intended for OEMs to provide a service for apps to verify the device's phone
+     * number. When called, the Telephony stack will store the provided {@link PhoneNumberRange} and
+     * intercept the next incoming call from a number that lies within the range, within a timeout
+     * specified by {@code timeoutMillis}.
+     *
+     * If such a phone call is received, the caller will be notified via
+     * {@link NumberVerificationCallback#onCallReceived(String)} on the provided {@link Executor}.
+     * If verification fails for any reason, the caller will be notified via
+     * {@link NumberVerificationCallback#onVerificationFailed(int)}
+     * on the provided {@link Executor}.
+     *
+     * In addition to the {@link Manifest.permission#MODIFY_PHONE_STATE} permission, callers of this
+     * API must also be listed in the device configuration as an authorized app in
+     * {@code packages/services/Telephony/res/values/config.xml} under the
+     * {@code config_number_verification_package_name} key.
+     *
+     * @hide
+     * @param range The range of phone numbers the caller expects a phone call from.
+     * @param timeoutMillis The amount of time to wait for such a call, or
+     *                      {@link #MAX_NUMBER_VERIFICATION_TIMEOUT_MILLIS}, whichever is lesser.
+     * @param executor The {@link Executor} that callbacks should be executed on.
+     * @param callback The callback to use for delivering results.
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    public void requestNumberVerification(@NonNull PhoneNumberRange range, long timeoutMillis,
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull NumberVerificationCallback callback) {
+        INumberVerificationCallback internalCallback = new INumberVerificationCallback.Stub() {
+            @Override
+            public void onCallReceived(String phoneNumber) throws RemoteException {
+                Binder.withCleanCallingIdentity(() -> callback.onCallReceived(phoneNumber));
+            }
+
+            @Override
+            public void onVerificationFailed(int reason) throws RemoteException {
+                Binder.withCleanCallingIdentity(() -> callback.onVerificationFailed(reason));
+            }
+        };
+
+        // TODO -- call the aidl method
+    }
+
+    /**
      * Sets a per-phone telephony property with the value specified.
      *
      * @hide
@@ -9533,4 +9587,34 @@
         }
         return subId;
     }
+
+    /**
+     * Update availability of a list of networks in the current location.
+     *
+     * This api should be called to inform AlternativeNetwork Service about the availability
+     * of a network at the current location. This information will be used by AlternativeNetwork
+     * service to decide to attach to the network opportunistically. If an empty list is passed,
+     * it is assumed that no network is available.
+     * Requires that the calling app has carrier privileges on both primary and
+     * secondary subscriptions (see {@link #hasCarrierPrivileges}), or has permission
+     * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
+     * @param availableNetworks is a list of available network information.
+     * @return true if request is accepted
+     *
+     */
+    @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
+    public boolean updateAvailableNetworks(List<AvailableNetworkInfo> availableNetworks) {
+        String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
+        boolean ret = false;
+        try {
+            IAns iAlternativeNetworkService = getIAns();
+            if (iAlternativeNetworkService != null) {
+                ret = iAlternativeNetworkService.updateAvailableNetworks(availableNetworks,
+                        pkgForDebug);
+            }
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "updateAvailableNetworks RemoteException", ex);
+        }
+        return ret;
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/IAns.aidl b/telephony/java/com/android/internal/telephony/IAns.aidl
index e9a4649..98bcd41 100755
--- a/telephony/java/com/android/internal/telephony/IAns.aidl
+++ b/telephony/java/com/android/internal/telephony/IAns.aidl
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.telephony.AvailableNetworkInfo;
 
 interface IAns {
 
@@ -78,4 +79,23 @@
      *
      */
     int getPreferredData(String callingPackage);
+
+    /**
+     * Update availability of a list of networks in the current location.
+     *
+     * This api should be called if the caller is aware of the availability of a network
+     * at the current location. This information will be used by AlternativeNetwork service
+     * to decide to attach to the network. If an empty list is passed,
+     * it is assumed that no network is available.
+     * Requires that the calling app has carrier privileges on both primary and
+     * secondary subscriptions (see
+     * {@link #hasCarrierPrivileges}), or has permission
+     * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
+     *  @param availableNetworks is a list of available network information.
+     *  @param callingPackage caller's package name
+     *  @return true if request is accepted
+     *
+     */
+    boolean updateAvailableNetworks(in List<AvailableNetworkInfo> availableNetworks,
+            String callingPackage);
 }
diff --git a/telephony/java/com/android/internal/telephony/INumberVerificationCallback.aidl b/telephony/java/com/android/internal/telephony/INumberVerificationCallback.aidl
new file mode 100644
index 0000000..76918af
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/INumberVerificationCallback.aidl
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+oneway interface INumberVerificationCallback {
+    void onCallReceived(String phoneNumber);
+    void onVerificationFailed(int reason);
+}
diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl
index bc44519..f9db4b0 100755
--- a/telephony/java/com/android/internal/telephony/ISub.aidl
+++ b/telephony/java/com/android/internal/telephony/ISub.aidl
@@ -184,6 +184,15 @@
     String setSubscriptionGroup(in int[] subIdList, String callingPackage);
 
     /**
+     * Set whether a subscription is metered
+     *
+     * @param isMetered whether it’s a metered subscription.
+     * @param subId the unique SubscriptionInfo index in database
+     * @return the number of records updated
+     */
+    int setMetered(boolean isMetered, int subId);
+
+    /**
      * Set which subscription is preferred for cellular data. It's
      * designed to overwrite default data subscription temporarily.
      *
diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index 923ab06..76e7509 100644
--- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -25,6 +25,7 @@
 import android.telephony.PhysicalChannelConfig;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
+import android.telephony.emergency.EmergencyNumber;
 import com.android.internal.telephony.IPhoneStateListener;
 import com.android.internal.telephony.IOnSubscriptionsChangedListener;
 
@@ -80,4 +81,5 @@
     void notifyPhoneCapabilityChanged(in PhoneCapability capability);
     void notifyPreferredDataSubIdChanged(int preferredSubId);
     void notifyRadioPowerStateChanged(in int state);
+    void notifyEmergencyNumberList(in List<EmergencyNumber> emergencyNumberList);
 }
diff --git a/tools/aapt2/java/JavaClassGenerator.cpp b/tools/aapt2/java/JavaClassGenerator.cpp
index d1a70a7..31d205e 100644
--- a/tools/aapt2/java/JavaClassGenerator.cpp
+++ b/tools/aapt2/java/JavaClassGenerator.cpp
@@ -298,19 +298,20 @@
                          "<colgroup align=\"left\" />\n"
                          "<tr><th>Attribute</th><th>Description</th></tr>\n";
 
-    // Build the table of attributes with their links and names.
-    for (const StyleableAttr& entry : sorted_attributes) {
-      if (SkipSymbol(entry.symbol)) {
-        continue;
-      }
-
+    // Removed and hidden attributes are public but hidden from the documentation, so don't emit
+    // them as part of the class documentation.
+    std::vector<StyleableAttr> documentation_attrs = sorted_attributes;
+    auto documentation_remove_iter = std::remove_if(documentation_attrs.begin(),
+                                                    documentation_attrs.end(),
+                                                    [&](StyleableAttr entry) -> bool {
       StringPiece attr_comment_line = entry.symbol.value().attribute->GetComment();
-      if (attr_comment_line.contains("@removed")) {
-        // Removed attributes are public but hidden from the documentation, so
-        // don't emit them as part of the class documentation.
-        continue;
-      }
+      return SkipSymbol(entry.symbol) || attr_comment_line.contains("@removed")
+                                      || attr_comment_line.contains("@hide");
+    });
+    documentation_attrs.erase(documentation_remove_iter, documentation_attrs.end());
 
+    // Build the table of attributes with their links and names.
+    for (const StyleableAttr& entry : documentation_attrs) {
       const ResourceName& attr_name = entry.attr_ref->name.value();
       styleable_comment << "<tr><td><code>{@link #" << entry.field_name << " "
                         << (!attr_name.package.empty() ? attr_name.package
@@ -320,16 +321,14 @@
       // Only use the comment up until the first '.'. This is to stay compatible with
       // the way old AAPT did it (presumably to keep it short and to avoid including
       // annotations like @hide which would affect this Styleable).
+      StringPiece attr_comment_line = entry.symbol.value().attribute->GetComment();
       styleable_comment << "<td>" << AnnotationProcessor::ExtractFirstSentence(attr_comment_line)
                         << "</td></tr>\n";
     }
     styleable_comment << "</table>\n";
 
     // Generate the @see lines for each attribute.
-    for (const StyleableAttr& entry : sorted_attributes) {
-      if (SkipSymbol(entry.symbol)) {
-        continue;
-      }
+    for (const StyleableAttr& entry : documentation_attrs) {
       styleable_comment << "@see #" << entry.field_name << "\n";
     }
 
diff --git a/tools/aapt2/java/JavaClassGenerator_test.cpp b/tools/aapt2/java/JavaClassGenerator_test.cpp
index fa208be..4f51fc4 100644
--- a/tools/aapt2/java/JavaClassGenerator_test.cpp
+++ b/tools/aapt2/java/JavaClassGenerator_test.cpp
@@ -366,6 +366,46 @@
   ASSERT_TRUE(generator.Generate("android", &out));
   out.Flush();
 
+  EXPECT_THAT(output, HasSubstr("#Container_one android:one"));
+  EXPECT_THAT(output, HasSubstr("@see #Container_one"));
+  EXPECT_THAT(output, HasSubstr("attr name android:one"));
+  EXPECT_THAT(output, HasSubstr("attr description"));
+  EXPECT_THAT(output, HasSubstr(attr.GetComment()));
+  EXPECT_THAT(output, HasSubstr(styleable.GetComment()));
+}
+
+TEST(JavaClassGeneratorTest, CommentsForStyleableHiddenAttributesAreNotPresent) {
+  Attribute attr;
+  attr.SetComment(StringPiece("This is an attribute @hide"));
+
+  Styleable styleable;
+  styleable.entries.push_back(Reference(test::ParseNameOrDie("android:attr/one")));
+  styleable.SetComment(StringPiece("This is a styleable"));
+
+  std::unique_ptr<ResourceTable> table =
+      test::ResourceTableBuilder()
+          .SetPackageId("android", 0x01)
+          .AddValue("android:attr/one", util::make_unique<Attribute>(attr))
+          .AddValue("android:styleable/Container",
+                    std::unique_ptr<Styleable>(styleable.Clone(nullptr)))
+          .Build();
+
+  std::unique_ptr<IAaptContext> context =
+      test::ContextBuilder()
+          .AddSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get()))
+          .SetNameManglerPolicy(NameManglerPolicy{"android"})
+          .Build();
+  JavaClassGeneratorOptions options;
+  options.use_final = false;
+  JavaClassGenerator generator(context.get(), table.get(), options);
+
+  std::string output;
+  StringOutputStream out(&output);
+  ASSERT_TRUE(generator.Generate("android", &out));
+  out.Flush();
+
+  EXPECT_THAT(output, Not(HasSubstr("#Container_one android:one")));
+  EXPECT_THAT(output, Not(HasSubstr("@see #Container_one")));
   EXPECT_THAT(output, HasSubstr("attr name android:one"));
   EXPECT_THAT(output, HasSubstr("attr description"));
   EXPECT_THAT(output, HasSubstr(attr.GetComment()));
diff --git a/tools/aosp/aosp_sha.sh b/tools/aosp/aosp_sha.sh
index e50c70d..f25fcdc 100755
--- a/tools/aosp/aosp_sha.sh
+++ b/tools/aosp/aosp_sha.sh
@@ -19,6 +19,6 @@
         echo "If your change contains no confidential details (such as security fixes), please"
         echo "upload and merge this change at https://android-review.googlesource.com/."
         echo
-        exit 77
+        exit 1
     fi
 fi
diff --git a/tools/hiddenapi/generate_hiddenapi_lists.py b/tools/hiddenapi/generate_hiddenapi_lists.py
index 2f1e53c..01728fa1 100755
--- a/tools/hiddenapi/generate_hiddenapi_lists.py
+++ b/tools/hiddenapi/generate_hiddenapi_lists.py
@@ -26,6 +26,7 @@
 FLAG_GREYLIST = "greylist"
 FLAG_BLACKLIST = "blacklist"
 FLAG_GREYLIST_MAX_O = "greylist-max-o"
+FLAG_GREYLIST_MAX_P = "greylist-max-p"
 
 # List of all known flags.
 FLAGS = [
@@ -33,6 +34,7 @@
     FLAG_GREYLIST,
     FLAG_BLACKLIST,
     FLAG_GREYLIST_MAX_O,
+    FLAG_GREYLIST_MAX_P,
 ]
 FLAGS_SET = set(FLAGS)
 
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 9789319..8e0d4ac 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -953,8 +953,12 @@
      * establish a connection to a remembered access point that is
      * within range, and will do periodic scans if there are remembered
      * access points but none are in range.
+     *
+     * @deprecated This API is non-functional and will have no impact.
      */
+    @Deprecated
     public static final int WIFI_MODE_FULL = 1;
+
     /**
      * In this Wi-Fi lock mode, Wi-Fi will be kept active,
      * but the only operation that will be supported is initiation of
@@ -963,28 +967,62 @@
      * nor will periodic scans be automatically performed looking for
      * remembered access points. Scans must be explicitly requested by
      * an application in this mode.
+     *
+     * @deprecated This API is non-functional and will have no impact.
      */
+    @Deprecated
     public static final int WIFI_MODE_SCAN_ONLY = 2;
+
     /**
-     * In this Wi-Fi lock mode, Wi-Fi will be kept active as in mode
-     * {@link #WIFI_MODE_FULL} but it operates at high performance
-     * with minimum packet loss and low packet latency even when
-     * the device screen is off. This mode will consume more power
-     * and hence should be used only when there is a need for such
-     * an active connection.
+     * In this Wi-Fi lock mode, Wi-Fi will not go to power save.
+     * This results in operating with low packet latency.
+     * The lock is active  even when the device screen is off or
+     * the acquiring application is running in the background.
+     * This mode will consume more power and hence should be used only
+     * when there is a need for this tradeoff.
      * <p>
      * An example use case is when a voice connection needs to be
-     * kept active even after the device screen goes off. Holding the
-     * regular {@link #WIFI_MODE_FULL} lock will keep the wifi
-     * connection active, but the connection can be lossy.
+     * kept active even after the device screen goes off.
      * Holding a {@link #WIFI_MODE_FULL_HIGH_PERF} lock for the
-     * duration of the voice call will improve the call quality.
+     * duration of the voice call may improve the call quality.
      * <p>
-     * When there is no support from the hardware, this lock mode
-     * will have the same behavior as {@link #WIFI_MODE_FULL}
+     * When there is no support from the hardware, the {@link #WIFI_MODE_FULL_HIGH_PERF}
+     * lock will have no impact.
      */
     public static final int WIFI_MODE_FULL_HIGH_PERF = 3;
 
+    /**
+     * In this Wi-Fi lock mode, Wi-Fi will operate with a priority to achieve low latency.
+     * {@link #WIFI_MODE_FULL_LOW_LATENCY} lock has the following limitations:
+     * <ol>
+     * <li>The lock is only active when the screen is on.</li>
+     * <li>The lock is only active when the acquiring app is running in the foreground.</li>
+     * </ol>
+     * Low latency mode optimizes for reduced packet latency,
+     * and as a result other performance measures may suffer when there are trade-offs to make:
+     * <ol>
+     * <li>Battery life may be reduced.</li>
+     * <li>Throughput may be reduced.</li>
+     * <li>Frequency of Wi-Fi scanning may be reduced. This may result in: </li>
+     * <ul>
+     * <li>The device may not roam or switch to the AP with highest signal quality.</li>
+     * <li>Location accuracy may be reduced.</li>
+     * </ul>
+     * </ol>
+     * <p>
+     * Example use cases are real time gaming or virtual reality applications where
+     * low latency is a key factor for user experience.
+     * <p>
+     * When there is no support from the hardware, the {@link #WIFI_MODE_FULL_LOW_LATENCY}
+     * lock will cause the device not to go power save.
+     * <p>
+     * Note: For an app which acquires both {@link #WIFI_MODE_FULL_LOW_LATENCY} and
+     * {@link #WIFI_MODE_FULL_HIGH_PERF} locks, {@link #WIFI_MODE_FULL_LOW_LATENCY}
+     * lock will be effective when app is running in foreground and screen is on,
+     * while the {@link #WIFI_MODE_FULL_HIGH_PERF} lock will take effect otherwise.
+     */
+    public static final int WIFI_MODE_FULL_LOW_LATENCY = 4;
+
     /** Anything worse than or equal to this will show 0 bars. */
     @UnsupportedAppUsage
     private static final int MIN_RSSI = -100;
@@ -3830,9 +3868,8 @@
     /**
      * Creates a new WifiLock.
      *
-     * @param lockType the type of lock to create. See {@link #WIFI_MODE_FULL},
-     * {@link #WIFI_MODE_FULL_HIGH_PERF} and {@link #WIFI_MODE_SCAN_ONLY} for
-     * descriptions of the types of Wi-Fi locks.
+     * @param lockType the type of lock to create. See {@link #WIFI_MODE_FULL_HIGH_PERF}
+     * and {@link #WIFI_MODE_FULL_LOW_LATENCY} for descriptions of the types of Wi-Fi locks.
      * @param tag a tag for the WifiLock to identify it in debugging messages.  This string is
      *            never shown to the user under normal conditions, but should be descriptive
      *            enough to identify your application and the specific WifiLock within it, if it
@@ -3857,12 +3894,14 @@
      * @return a new, unacquired WifiLock with the given tag.
      *
      * @see WifiLock
+     *
+     * @deprecated This API is non-functional.
      */
+    @Deprecated
     public WifiLock createWifiLock(String tag) {
         return new WifiLock(WIFI_MODE_FULL, tag);
     }
 
-
     /**
      * Create a new MulticastLock
      *