Merge "Support RRO for system wallpaper"
diff --git a/Android.bp b/Android.bp
index 41d5f28..cbc67d0 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",
diff --git a/api/current.txt b/api/current.txt
index 079539e..3967896 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -29062,7 +29062,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 +29124,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
@@ -37296,6 +37297,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";
@@ -51965,8 +51967,8 @@
 
 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..7a2c233 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();
@@ -7243,14 +7255,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/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/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/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/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..ec8db1c 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
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/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/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/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 fcdbbf4..83f3057 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -655,7 +655,8 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_readContacts"
         android:description="@string/permdesc_readContacts"
-        android:protectionLevel="dangerous" />
+        android:protectionLevel="dangerous"
+        android:usageInfoRequired="true" />
 
     <!-- Allows an application to write the user's contacts data.
          <p>Protection level: dangerous
@@ -686,7 +687,8 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_readCalendar"
         android:description="@string/permdesc_readCalendar"
-        android:protectionLevel="dangerous" />
+        android:protectionLevel="dangerous"
+        android:usageInfoRequired="true" />
 
     <!-- Allows an application to write the user's calendar data.
          <p>Protection level: dangerous
@@ -727,7 +729,8 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_receiveSms"
         android:description="@string/permdesc_receiveSms"
-        android:protectionLevel="dangerous"/>
+        android:protectionLevel="dangerous"
+        android:usageInfoRequired="true" />
 
     <!-- Allows an application to read SMS messages.
          <p>Protection level: dangerous
@@ -736,7 +739,8 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_readSms"
         android:description="@string/permdesc_readSms"
-        android:protectionLevel="dangerous" />
+        android:protectionLevel="dangerous"
+        android:usageInfoRequired="true" />
 
     <!-- Allows an application to receive WAP push messages.
          <p>Protection level: dangerous
@@ -745,7 +749,8 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_receiveWapPush"
         android:description="@string/permdesc_receiveWapPush"
-        android:protectionLevel="dangerous" />
+        android:protectionLevel="dangerous"
+        android:usageInfoRequired="true" />
 
     <!-- Allows an application to monitor incoming MMS messages.
         <p>Protection level: dangerous
@@ -754,7 +759,8 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_receiveMms"
         android:description="@string/permdesc_receiveMms"
-        android:protectionLevel="dangerous" />
+        android:protectionLevel="dangerous"
+        android:usageInfoRequired="true" />
 
     <!-- @SystemApi @TestApi Allows an application to read previously received cell broadcast
          messages and to register a content observer to get notifications when
@@ -772,7 +778,8 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_readCellBroadcasts"
         android:description="@string/permdesc_readCellBroadcasts"
-        android:protectionLevel="dangerous" />
+        android:protectionLevel="dangerous"
+        android:usageInfoRequired="true" />
 
     <!-- ====================================================================== -->
     <!-- Permissions for accessing external storage                             -->
@@ -853,7 +860,8 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_audioRead"
         android:description="@string/permdesc_audioRead"
-        android:protectionLevel="dangerous" />
+        android:protectionLevel="dangerous"
+        android:usageInfoRequired="true" />
 
     <!-- Runtime permission controlling access to the user's shared visual media
          collection, including images and videos. -->
@@ -869,14 +877,16 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_imagesRead"
         android:description="@string/permdesc_imagesRead"
-        android:protectionLevel="dangerous" />
+        android:protectionLevel="dangerous"
+        android:usageInfoRequired="true" />
 
     <!-- Allows an application to read the user's shared video collection. -->
     <permission android:name="android.permission.READ_MEDIA_VIDEO"
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_videoRead"
         android:description="@string/permdesc_videoRead"
-        android:protectionLevel="dangerous" />
+        android:protectionLevel="dangerous"
+        android:usageInfoRequired="true" />
 
     <!-- Allows an application to access any geographic locations persisted in the
          user's shared collection. -->
@@ -884,7 +894,8 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_mediaLocation"
         android:description="@string/permdesc_mediaLocation"
-        android:protectionLevel="dangerous" />
+        android:protectionLevel="dangerous"
+        android:usageInfoRequired="true" />
 
     <!-- @hide @SystemApi
          Allows an application to modify OBB files visible to other apps. -->
@@ -916,7 +927,8 @@
         android:label="@string/permlab_accessFineLocation"
         android:description="@string/permdesc_accessFineLocation"
         android:backgroundPermission="android.permission.ACCESS_BACKGROUND_LOCATION"
-        android:protectionLevel="dangerous|instant" />
+        android:protectionLevel="dangerous|instant"
+        android:usageInfoRequired="true" />
 
     <!-- Allows an app to access approximate location.
          Alternatively, you might want {@link #ACCESS_FINE_LOCATION}.
@@ -927,7 +939,8 @@
         android:label="@string/permlab_accessCoarseLocation"
         android:description="@string/permdesc_accessCoarseLocation"
         android:backgroundPermission="android.permission.ACCESS_BACKGROUND_LOCATION"
-        android:protectionLevel="dangerous|instant" />
+        android:protectionLevel="dangerous|instant"
+        android:usageInfoRequired="true" />
 
     <!-- Allows an app to access location in the background.  If you
          are requesting this, you should also request {@link #ACCESS_FINE_LOCATION}.
@@ -939,7 +952,8 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_accessBackgroundLocation"
         android:description="@string/permdesc_accessBackgroundLocation"
-        android:protectionLevel="dangerous|instant" />
+        android:protectionLevel="dangerous|instant"
+        android:usageInfoRequired="true" />
 
     <!-- ====================================================================== -->
     <!-- Permissions for accessing the call log                                 -->
@@ -980,7 +994,8 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_readCallLog"
         android:description="@string/permdesc_readCallLog"
-        android:protectionLevel="dangerous" />
+        android:protectionLevel="dangerous"
+        android:usageInfoRequired="true" />
 
     <!-- Allows an application to write (but not read) the user's
          call log data.
@@ -1010,7 +1025,8 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_processOutgoingCalls"
         android:description="@string/permdesc_processOutgoingCalls"
-        android:protectionLevel="dangerous" />
+        android:protectionLevel="dangerous"
+        android:usageInfoRequired="true" />
 
     <!-- ====================================================================== -->
     <!-- Permissions for accessing the device telephony                         -->
@@ -1042,7 +1058,8 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_readPhoneState"
         android:description="@string/permdesc_readPhoneState"
-        android:protectionLevel="dangerous" />
+        android:protectionLevel="dangerous"
+        android:usageInfoRequired="true" />
 
     <!-- Allows read access to the device's phone number(s). This is a subset of the capabilities
          granted by {@link #READ_PHONE_STATE} but is exposed to instant applications.
@@ -1051,7 +1068,8 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_readPhoneNumbers"
         android:description="@string/permdesc_readPhoneNumbers"
-        android:protectionLevel="dangerous|instant" />
+        android:protectionLevel="dangerous|instant"
+        android:usageInfoRequired="true" />
 
     <!-- Allows an application to initiate a phone call without going through
         the Dialer user interface for the user to confirm the call.
@@ -1141,7 +1159,8 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_recordAudio"
         android:description="@string/permdesc_recordAudio"
-        android:protectionLevel="dangerous|instant"/>
+        android:protectionLevel="dangerous|instant"
+        android:usageInfoRequired="true" />
 
     <!-- ====================================================================== -->
     <!-- Permissions for activity recognition                        -->
@@ -1163,7 +1182,8 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_activityRecognition"
         android:description="@string/permdesc_activityRecognition"
-        android:protectionLevel="dangerous|instant" />
+        android:protectionLevel="dangerous|instant"
+        android:usageInfoRequired="true" />
 
     <!-- ====================================================================== -->
     <!-- Permissions for accessing the UCE Service                              -->
@@ -1212,7 +1232,8 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_camera"
         android:description="@string/permdesc_camera"
-        android:protectionLevel="dangerous|instant" />
+        android:protectionLevel="dangerous|instant"
+        android:usageInfoRequired="true" />
 
 
     <!-- ====================================================================== -->
@@ -1236,7 +1257,8 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_bodySensors"
         android:description="@string/permdesc_bodySensors"
-        android:protectionLevel="dangerous" />
+        android:protectionLevel="dangerous"
+        android:usageInfoRequired="true" />
 
     <!-- Allows an app to use fingerprint hardware.
          <p>Protection level: normal
@@ -1723,7 +1745,8 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:protectionLevel="dangerous"
         android:description="@string/permdesc_getAccounts"
-        android:label="@string/permlab_getAccounts" />
+        android:label="@string/permlab_getAccounts"
+        android:usageInfoRequired="true" />
     <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
 
     <!-- @SystemApi Allows applications to call into AccountAuthenticators.
@@ -3024,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,
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/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/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/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/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/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/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/AudioTrack.java b/media/java/android/media/AudioTrack.java
index c226d49..71736dd 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>
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/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/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/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/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/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/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/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/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/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/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/DragDropController.java b/services/core/java/com/android/server/wm/DragDropController.java
index e3ddadc..a667d67 100644
--- a/services/core/java/com/android/server/wm/DragDropController.java
+++ b/services/core/java/com/android/server/wm/DragDropController.java
@@ -31,13 +31,12 @@
 import android.view.Display;
 import android.view.IWindow;
 import android.view.SurfaceControl;
-import android.view.SurfaceControl.Transaction;
 import android.view.SurfaceSession;
 import android.view.View;
 
 import com.android.internal.util.Preconditions;
-import android.view.InputWindowHandle;
 import com.android.server.wm.WindowManagerInternal.IDragDropCallback;
+
 import java.util.concurrent.atomic.AtomicReference;
 
 /**
@@ -71,7 +70,7 @@
             new IDragDropCallback() {});
 
     boolean dragDropActiveLocked() {
-        return mDragState != null;
+        return mDragState != null && !mDragState.isClosing();
     }
 
     void showInputSurface(SurfaceControl.Transaction t, int displayId) {
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index 8f6ed85..607ee76 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -31,25 +31,24 @@
 import android.annotation.Nullable;
 import android.content.ClipData;
 import android.content.ClipDescription;
-import android.content.Context;
-import android.graphics.Rect;
 import android.graphics.Point;
+import android.graphics.Rect;
 import android.hardware.input.InputManager;
-import android.os.Build;
 import android.os.Binder;
+import android.os.Build;
 import android.os.IBinder;
 import android.os.Process;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.os.IUserManager;
 import android.os.UserManagerInternal;
 import android.util.Slog;
 import android.view.Display;
 import android.view.DragEvent;
+import android.view.InputApplicationHandle;
 import android.view.InputChannel;
 import android.view.InputDevice;
+import android.view.InputWindowHandle;
 import android.view.PointerIcon;
 import android.view.SurfaceControl;
 import android.view.View;
@@ -59,8 +58,6 @@
 
 import com.android.internal.view.IDragAndDropPermissions;
 import com.android.server.LocalServices;
-import android.view.InputApplicationHandle;
-import android.view.InputWindowHandle;
 
 import java.util.ArrayList;
 
@@ -125,6 +122,12 @@
 
     private final Rect mTmpClipRect = new Rect();
 
+    /**
+     * Whether we are finishing this drag and drop. This starts with {@code false}, and is set to
+     * {@code true} when {@link #closeLocked()} is called.
+     */
+    private boolean mIsClosing;
+
     DragState(WindowManagerService service, DragDropController controller, IBinder token,
             SurfaceControl surface, int flags, IBinder localWin) {
         mService = service;
@@ -137,6 +140,10 @@
 
     }
 
+    boolean isClosing() {
+        return mIsClosing;
+    }
+
     void hideInputSurface(SurfaceControl.Transaction t, int displayId) {
         if (displayId != mDisplayContent.getDisplayId()) {
             return;
@@ -177,6 +184,7 @@
      * DragDropController#mDragState becomes null.
      */
     void closeLocked() {
+        mIsClosing = true;
         // Unregister the input interceptor.
         if (mInputInterceptor != null) {
             if (DEBUG_DRAG)
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/TaskPositioningController.java b/services/core/java/com/android/server/wm/TaskPositioningController.java
index 5a70325..e15bf5b 100644
--- a/services/core/java/com/android/server/wm/TaskPositioningController.java
+++ b/services/core/java/com/android/server/wm/TaskPositioningController.java
@@ -28,12 +28,12 @@
 import android.os.RemoteException;
 import android.util.Slog;
 import android.view.Display;
-import android.view.SurfaceControl;
 import android.view.IWindow;
+import android.view.InputWindowHandle;
+import android.view.SurfaceControl;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.server.input.InputManagerService;
-import android.view.InputWindowHandle;
 
 /**
  * Controller for task positioning by drag.
@@ -184,9 +184,7 @@
         if (!mInputManager.transferTouchFocus(
                 transferFocusFromWin.mInputChannel, mTaskPositioner.mServerChannel)) {
             Slog.e(TAG_WM, "startPositioningLocked: Unable to transfer touch focus");
-            mTaskPositioner.unregister();
-            mTaskPositioner = null;
-            displayContent.getInputMonitor().updateInputWindowsLw(true /*force*/);
+            cleanUpTaskPositioner();
             return false;
         }
 
@@ -199,12 +197,21 @@
             if (DEBUG_TASK_POSITIONING) Slog.d(TAG_WM, "finishPositioning");
 
             synchronized (mService.mGlobalLock) {
-                if (mTaskPositioner != null) {
-                    mTaskPositioner.unregister();
-                    mTaskPositioner = null;
-                }
+                cleanUpTaskPositioner();
                 mPositioningDisplay = null;
             }
         });
     }
+
+    private void cleanUpTaskPositioner() {
+        final TaskPositioner positioner = mTaskPositioner;
+        if (positioner == null) {
+            return;
+        }
+
+        // We need to assign task positioner to null first to indicate that we're finishing task
+        // positioning.
+        mTaskPositioner = null;
+        positioner.unregister();
+    }
 }
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/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/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index d54da09..7a6647c 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -5372,7 +5372,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 +5399,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
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
      *