Merge changes Ie8685a12,I87abde9f

* changes:
  am: Add unit tests for ActivityMetricsLaunchObserver
  am: Add new LaunchObserver to track app launch sequences
diff --git a/api/system-current.txt b/api/system-current.txt
index d8da475..24bdd9b 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -6041,6 +6041,7 @@
     method public void setCallExtra(java.lang.String, java.lang.String);
     method public void setCallExtraBoolean(java.lang.String, boolean);
     method public void setCallExtraInt(java.lang.String, int);
+    method public void setCallRestrictCause(int);
     method public void updateCallExtras(android.telephony.ims.ImsCallProfile);
     method public void updateCallType(android.telephony.ims.ImsCallProfile);
     method public void updateMediaProfile(android.telephony.ims.ImsCallProfile);
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index 065f49e..f0f5993 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -272,7 +272,7 @@
 }
 
 /*
- * onDumpReport dumps serialized ConfigMetricsReportList into outData.
+ * onDumpReport dumps serialized ConfigMetricsReportList into proto.
  */
 void StatsLogProcessor::onDumpReport(const ConfigKey& key, const int64_t dumpTimeStampNs,
                                      const bool include_current_partial_bucket,
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 8d54e91..86ed267 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -120,6 +120,7 @@
 import android.view.autofill.AutofillManager.AutofillClient;
 import android.view.autofill.AutofillPopupWindow;
 import android.view.autofill.IAutofillWindowPresenter;
+import android.view.intelligence.ContentCaptureEvent;
 import android.view.intelligence.IntelligenceManager;
 import android.widget.AdapterView;
 import android.widget.Toast;
@@ -1023,6 +1024,31 @@
         return mIntelligenceManager;
     }
 
+    private void notifyIntelligenceManagerIfNeeded(@ContentCaptureEvent.EventType int event) {
+        final IntelligenceManager im = getIntelligenceManager();
+        if (im == null || !im.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());
+                break;
+            case ContentCaptureEvent.TYPE_ACTIVITY_DESTROYED:
+                im.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);
+                break;
+            default:
+                Log.w(TAG, "notifyIntelligenceManagerIfNeeded(): invalid type " + event);
+        }
+    }
+
     @Override
     protected void attachBaseContext(Context newBase) {
         super.attachBaseContext(newBase);
@@ -1099,11 +1125,7 @@
         mRestoredFromBundle = savedInstanceState != null;
         mCalled = true;
 
-        if (getIntelligenceManager() != null) {
-            //TODO(b/111276913): decide whether the screen_obs session id should be saved / restored
-            // in the activity bundle.
-            mIntelligenceManager.onActivityCreated(mToken, getComponentName());
-        }
+        notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_CREATED);
     }
 
     /**
@@ -1337,6 +1359,7 @@
         if (mAutoFillResetNeeded) {
             getAutofillManager().onVisibleForAutofill();
         }
+        notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_STARTED);
     }
 
     /**
@@ -1419,6 +1442,7 @@
                 }
             }
         }
+        notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_RESUMED);
         mCalled = true;
     }
 
@@ -1812,6 +1836,7 @@
                 mAutoFillIgnoreFirstResumePause = false;
             }
         }
+        notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_PAUSED);
         mCalled = true;
     }
 
@@ -2000,6 +2025,7 @@
                 getAutofillManager().onPendingSaveUi(AutofillManager.PENDING_UI_OPERATION_CANCEL,
                         mIntent.getIBinderExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN));
             }
+            notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_STOPPED);
         }
     }
 
@@ -2071,9 +2097,8 @@
 
         getApplication().dispatchActivityDestroyed(this);
 
-        if (getIntelligenceManager() != null) {
-            mIntelligenceManager.onActivityDestroyed();
-        }
+        notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_DESTROYED);
+
     }
 
     /**
diff --git a/core/java/android/service/intelligence/IIntelligenceService.aidl b/core/java/android/service/intelligence/IIntelligenceService.aidl
index ee93326..bacad8b 100644
--- a/core/java/android/service/intelligence/IIntelligenceService.aidl
+++ b/core/java/android/service/intelligence/IIntelligenceService.aidl
@@ -19,6 +19,11 @@
 import android.service.intelligence.InteractionSessionId;
 import android.service.intelligence.InteractionContext;
 
+import android.view.intelligence.ContentCaptureEvent;
+
+import java.util.List;
+
+
 /**
  * Interface from the system to an intelligence service.
  *
@@ -28,4 +33,7 @@
 
     // 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);
 }
diff --git a/core/java/android/service/intelligence/IntelligenceService.java b/core/java/android/service/intelligence/IntelligenceService.java
index ce0a88a..a2b60f0 100644
--- a/core/java/android/service/intelligence/IntelligenceService.java
+++ b/core/java/android/service/intelligence/IntelligenceService.java
@@ -70,6 +70,14 @@
                                 IntelligenceService.this, sessionId));
             }
         }
+        @Override
+        public void onContentCaptureEvents(InteractionSessionId sessionId,
+                List<ContentCaptureEvent> events) {
+            mHandler.sendMessage(
+                    obtainMessage(IntelligenceService::onContentCaptureEvent,
+                            IntelligenceService.this, sessionId, events));
+
+        }
     };
 
     @CallSuper
@@ -105,6 +113,7 @@
      * @param sessionId the session's Id
      * @param events the events
      */
+     // TODO(b/111276913): rename to onContentCaptureEvents
     public abstract void onContentCaptureEvent(@NonNull InteractionSessionId sessionId,
             @NonNull List<ContentCaptureEvent> events);
 
diff --git a/core/java/android/service/intelligence/InteractionSessionId.java b/core/java/android/service/intelligence/InteractionSessionId.java
index ca68f8e..a2971ae 100644
--- a/core/java/android/service/intelligence/InteractionSessionId.java
+++ b/core/java/android/service/intelligence/InteractionSessionId.java
@@ -16,43 +16,85 @@
 
 package android.service.intelligence;
 
+import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
 import java.io.PrintWriter;
+import java.util.UUID;
 
 // TODO(b/111276913): add javadocs / implement equals/hashcode/string
 /** @hide */
 @SystemApi
 public final class InteractionSessionId implements Parcelable {
 
-    private final int mGlobalId;
+    private final @NonNull String mValue;
 
-    // TODO(b/111276913): remove if not needed
-    private final int mLocalId;
-
-    /** @hide */
-    public InteractionSessionId(int globalId, int localId) {
-        mGlobalId = globalId;
-        mLocalId = localId;
+    /**
+     * Creates a new instance.
+     *
+     * @hide
+     */
+    public InteractionSessionId() {
+        this(UUID.randomUUID().toString());
     }
 
-    /** @hide */
-    public int getGlobalId() {
-        return mGlobalId;
+    /**
+     * Creates a new instance.
+     *
+     * @param value The internal value.
+     *
+     * @hide
+     */
+    public InteractionSessionId(@NonNull String value) {
+        mValue = value;
+    }
+
+    /**
+     * @hide
+     */
+    public String getValue() {
+        return mValue;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((mValue == null) ? 0 : mValue.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+        if (obj == null) return false;
+        if (getClass() != obj.getClass()) return false;
+        final InteractionSessionId other = (InteractionSessionId) obj;
+        if (mValue == null) {
+            if (other.mValue != null) return false;
+        } else if (!mValue.equals(other.mValue)) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * @inheritdoc
+     *
+     * <p><b>NOTE: </b>this method is only useful for debugging purposes and is not guaranteed to
+     * be stable, hence it should not be used to identify the session.
+     */
+    @Override
+    public String toString() {
+        return mValue;
     }
 
     /** @hide */
     // TODO(b/111276913): dump to proto as well
     public void dump(PrintWriter pw) {
-        pw.print("globalId="); pw.print(mGlobalId);
-        pw.print("localId="); pw.print(mLocalId);
-    }
-
-    @Override
-    public String toString() {
-        return "SessionId[globalId=" + mGlobalId + ", localId=" + mLocalId + "]";
+        pw.print(mValue);
     }
 
     @Override
@@ -62,8 +104,7 @@
 
     @Override
     public void writeToParcel(Parcel parcel, int flags) {
-        parcel.writeInt(mGlobalId);
-        parcel.writeInt(mLocalId);
+        parcel.writeString(mValue);
     }
 
     public static final Parcelable.Creator<InteractionSessionId> CREATOR =
@@ -71,9 +112,7 @@
 
         @Override
         public InteractionSessionId createFromParcel(Parcel parcel) {
-            final int globalId = parcel.readInt();
-            final int localId = parcel.readInt();
-            return new InteractionSessionId(globalId, localId);
+            return new InteractionSessionId(parcel.readString());
         }
 
         @Override
diff --git a/core/java/android/view/intelligence/ContentCaptureEvent.aidl b/core/java/android/view/intelligence/ContentCaptureEvent.aidl
new file mode 100644
index 0000000..c66a6cb
--- /dev/null
+++ b/core/java/android/view/intelligence/ContentCaptureEvent.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.intelligence;
+
+parcelable ContentCaptureEvent;
diff --git a/core/java/android/view/intelligence/ContentCaptureEvent.java b/core/java/android/view/intelligence/ContentCaptureEvent.java
index d6aec34..2530ae3 100644
--- a/core/java/android/view/intelligence/ContentCaptureEvent.java
+++ b/core/java/android/view/intelligence/ContentCaptureEvent.java
@@ -30,6 +30,11 @@
 @SystemApi
 public final class ContentCaptureEvent implements Parcelable {
 
+    /** @hide */
+    public static final int TYPE_ACTIVITY_DESTROYED = -2;
+    /** @hide */
+    public static final int TYPE_ACTIVITY_CREATED = -1;
+
     /**
      * Called when the activity is started.
      */
@@ -85,10 +90,18 @@
             TYPE_VIEW_TEXT_CHANGED
     })
     @Retention(RetentionPolicy.SOURCE)
-    @interface EventType{}
+    public @interface EventType{}
+
+    private final int mType;
+    private final long mEventTime;
+    private final int mFlags;
+
 
     /** @hide */
-    ContentCaptureEvent() {
+    public ContentCaptureEvent(int type, long eventTime, int flags) {
+        mType = type;
+        mEventTime = eventTime;
+        mFlags = flags;
     }
 
     /**
@@ -99,14 +112,14 @@
      * {@link #TYPE_VIEW_ADDED}, {@link #TYPE_VIEW_REMOVED}, or {@link #TYPE_VIEW_TEXT_CHANGED}.
      */
     public @EventType int getType() {
-        return 42;
+        return mType;
     }
 
     /**
      * Gets when the event was generated, in ms.
      */
     public long getEventTime() {
-        return 48151623;
+        return mEventTime;
     }
 
     /**
@@ -116,7 +129,7 @@
      * {@link android.view.intelligence.IntelligenceManager#FLAG_USER_INPUT}.
      */
     public int getFlags() {
-        return 0;
+        return mFlags;
     }
 
     /**
@@ -150,13 +163,25 @@
     }
 
     @Override
+    public String toString() {
+        final StringBuilder string = new StringBuilder("ContentCaptureEvent[type=")
+                .append(getTypeAsString(mType)).append(", time=").append(mEventTime);
+        if (mFlags > 0) {
+            string.append(", flags=").append(mFlags);
+        }
+        return string.append(']').toString();
+    }
+
+    @Override
     public int describeContents() {
         return 0;
     }
 
     @Override
     public void writeToParcel(Parcel parcel, int flags) {
-        // TODO(b/111276913): implement
+        parcel.writeInt(mType);
+        parcel.writeLong(mEventTime);
+        parcel.writeInt(mFlags);
     }
 
     public static final Parcelable.Creator<ContentCaptureEvent> CREATOR =
@@ -164,8 +189,10 @@
 
         @Override
         public ContentCaptureEvent createFromParcel(Parcel parcel) {
-            // TODO(b/111276913): implement
-            return null;
+            final int type = parcel.readInt();
+            final long eventTime  = parcel.readLong();
+            final int flags = parcel.readInt();
+            return new ContentCaptureEvent(type, eventTime, flags);
         }
 
         @Override
@@ -173,4 +200,27 @@
             return new ContentCaptureEvent[size];
         }
     };
+
+
+    /** @hide */
+    public static String getTypeAsString(@EventType int type) {
+        switch (type) {
+            case TYPE_ACTIVITY_STARTED:
+                return "ACTIVITY_STARTED";
+            case TYPE_ACTIVITY_RESUMED:
+                return "ACTIVITY_RESUMED";
+            case TYPE_ACTIVITY_PAUSED:
+                return "ACTIVITY_PAUSED";
+            case TYPE_ACTIVITY_STOPPED:
+                return "ACTIVITY_STOPPED";
+            case TYPE_VIEW_ADDED:
+                return "VIEW_ADDED";
+            case TYPE_VIEW_REMOVED:
+                return "VIEW_REMOVED";
+            case TYPE_VIEW_TEXT_CHANGED:
+                return "VIEW_TEXT_CHANGED";
+            default:
+                return "UKNOWN_TYPE: " + type;
+        }
+    }
 }
diff --git a/core/java/android/view/intelligence/IIntelligenceManager.aidl b/core/java/android/view/intelligence/IIntelligenceManager.aidl
index f4901c3..2f128de 100644
--- a/core/java/android/view/intelligence/IIntelligenceManager.aidl
+++ b/core/java/android/view/intelligence/IIntelligenceManager.aidl
@@ -18,8 +18,13 @@
 
 import android.content.ComponentName;
 import android.os.IBinder;
+import android.service.intelligence.InteractionSessionId;
+import android.view.intelligence.ContentCaptureEvent;
+
 import com.android.internal.os.IResultReceiver;
 
+import java.util.List;
+
 /**
  * {@hide}
  */
@@ -28,11 +33,16 @@
       * Starts a session, sending the "remote" sessionId to the receiver.
       */
     void startSession(int userId, IBinder activityToken, in ComponentName componentName,
-                      int localSessionId, int flags, in IResultReceiver result);
+                      in InteractionSessionId sessionId, int flags, in IResultReceiver result);
 
     /**
       * Finishes a session.
       */
-    void finishSession(int userId, IBinder activityToken, in ComponentName componentName,
-                       int localSessionId, int globalSessionId);
+    void finishSession(int userId, in InteractionSessionId sessionId);
+
+    /**
+      * Sends a batch of events
+      */
+    void sendEvents(int userId, in InteractionSessionId sessionId,
+                    in List<ContentCaptureEvent> events);
 }
diff --git a/core/java/android/view/intelligence/IntelligenceManager.java b/core/java/android/view/intelligence/IntelligenceManager.java
index b1d06f7..9bf6c2c 100644
--- a/core/java/android/view/intelligence/IntelligenceManager.java
+++ b/core/java/android/view/intelligence/IntelligenceManager.java
@@ -24,13 +24,18 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.SystemClock;
+import android.service.intelligence.InteractionSessionId;
 import android.util.Log;
+import android.view.intelligence.ContentCaptureEvent.EventType;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.IResultReceiver;
 import com.android.internal.util.Preconditions;
 
 import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.List;
 import java.util.Set;
 
 /**
@@ -51,9 +56,6 @@
     public static final int FLAG_USER_INPUT = 0x1;
 
 
-    /** @hide */
-    public static final int NO_SESSION = 0;
-
     /**
      * Initial state, when there is no session.
      *
@@ -62,11 +64,11 @@
     public static final int STATE_UNKNOWN = 0;
 
     /**
-     * Service's startSession() was called, but remote session id was not returned yet.
+     * Service's startSession() was called, but server didn't confirm it was created yet.
      *
      * @hide
      */
-    public static final int STATE_WAITING_FOR_SESSION_ID = 1;
+    public static final int STATE_WAITING_FOR_SERVER = 1;
 
     /**
      * Session is active.
@@ -75,8 +77,6 @@
      */
     public static final int STATE_ACTIVE = 2;
 
-    private static int sNextSessionId;
-
     private final Context mContext;
 
     @Nullable
@@ -84,14 +84,9 @@
 
     private final Object mLock = new Object();
 
-    // TODO(b/111276913): localSessionId might be an overkill, perhaps just the global id is enough.
-    // Let's keep both for now, and revisit once we decide whether the session id will be persisted
-    // when the activity's process is killed
+    @Nullable
     @GuardedBy("mLock")
-    private int mLocalSessionId = NO_SESSION;
-
-    @GuardedBy("mLock")
-    private int mRemoteSessionId = NO_SESSION;
+    private InteractionSessionId mId;
 
     @GuardedBy("mLock")
     private int mState = STATE_UNKNOWN;
@@ -120,27 +115,25 @@
                         + getStateAsStringLocked());
                 return;
             }
-            mState = STATE_WAITING_FOR_SESSION_ID;
-            mLocalSessionId = ++sNextSessionId;
-            mRemoteSessionId = NO_SESSION;
+            mState = STATE_WAITING_FOR_SERVER;
+            mId = new InteractionSessionId();
             mApplicationToken = token;
             mComponentName = componentName;
 
             if (VERBOSE) {
                 Log.v(TAG, "onActivityStarted(): token=" + token + ", act=" + componentName
-                        + ", localSessionId=" + mLocalSessionId);
+                        + ", id=" + mId);
             }
             final int flags = 0; // TODO(b/111276913): get proper flags
 
             try {
                 mService.startSession(mContext.getUserId(), mApplicationToken, componentName,
-                        mLocalSessionId, flags, new IResultReceiver.Stub() {
+                        mId, flags, new IResultReceiver.Stub() {
                             @Override
                             public void send(int resultCode, Bundle resultData)
                                     throws RemoteException {
                                 synchronized (mLock) {
                                     if (resultCode > 0) {
-                                        mRemoteSessionId = resultCode;
                                         mState = STATE_ACTIVE;
                                     } else {
                                         // TODO(b/111276913): handle other cases like disabled by
@@ -149,7 +142,7 @@
                                     }
                                     if (VERBOSE) {
                                         Log.v(TAG, "onActivityStarted() result: code=" + resultCode
-                                                + ", remoteSession=" + mRemoteSessionId
+                                                + ", id=" + mId
                                                 + ", state=" + getStateAsStringLocked());
                                     }
                                 }
@@ -161,6 +154,37 @@
         }
     }
 
+    /**
+     * Used for intermediate events (i.e, other than created and destroyed).
+     *
+     * @hide
+     */
+    public void onActivityLifecycleEvent(@EventType int type) {
+        if (!isContentCaptureEnabled()) return;
+
+        //TODO(b/111276913): should buffer event (and call service on handler thread), instead of
+        // calling right away
+        final ContentCaptureEvent event = new ContentCaptureEvent(type, SystemClock.uptimeMillis(),
+                0);
+        final List<ContentCaptureEvent> events = Arrays.asList(event);
+
+        synchronized (mLock) {
+            //TODO(b/111276913): check session state; for example, how to handle if it's waiting for
+            // remote id
+
+            if (VERBOSE) {
+                Log.v(TAG, "onActivityLifecycleEvent() for " + mComponentName.flattenToShortString()
+                        + ": " + ContentCaptureEvent.getTypeAsString(type));
+            }
+
+            try {
+                mService.sendEvents(mContext.getUserId(), mId, events);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+    }
+
     /** @hide */
     public void onActivityDestroyed() {
         if (!isContentCaptureEnabled()) return;
@@ -171,15 +195,13 @@
 
             if (VERBOSE) {
                 Log.v(TAG, "onActivityDestroyed(): state=" + getStateAsStringLocked()
-                        + ", localSessionId=" + mLocalSessionId
-                        + ", mRemoteSessionId=" + mRemoteSessionId);
+                        + ", mId=" + mId);
             }
 
             try {
-                mService.finishSession(mContext.getUserId(), mApplicationToken, mComponentName,
-                        mLocalSessionId, mRemoteSessionId);
+                mService.finishSession(mContext.getUserId(), mId);
                 mState = STATE_UNKNOWN;
-                mLocalSessionId = mRemoteSessionId = NO_SESSION;
+                mId = null;
                 mApplicationToken = null;
                 mComponentName = null;
             } catch (RemoteException e) {
@@ -298,12 +320,11 @@
             pw.print(prefix2); pw.print("mService: "); pw.println(mService);
             pw.print(prefix2); pw.print("user: "); pw.println(mContext.getUserId());
             pw.print(prefix2); pw.print("enabled: "); pw.println(isContentCaptureEnabled());
-            pw.print(prefix2); pw.print("mLocalSessionId: "); pw.println(mLocalSessionId);
-            pw.print(prefix2); pw.print("mRemoteSessionId: "); pw.println(mRemoteSessionId);
-            pw.print(prefix2); pw.print("mState: "); pw.print(mState); pw.print(" (");
+            pw.print(prefix2); pw.print("id: "); pw.println(mId);
+            pw.print(prefix2); pw.print("state: "); pw.print(mState); pw.print(" (");
             pw.print(getStateAsStringLocked()); pw.println(")");
-            pw.print(prefix2); pw.print("mAppToken: "); pw.println(mApplicationToken);
-            pw.print(prefix2); pw.print("mComponentName: "); pw.println(mComponentName);
+            pw.print(prefix2); pw.print("appToken: "); pw.println(mApplicationToken);
+            pw.print(prefix2); pw.print("componentName: "); pw.println(mComponentName);
         }
     }
 
@@ -317,8 +338,8 @@
         switch (state) {
             case STATE_UNKNOWN:
                 return "UNKNOWN";
-            case STATE_WAITING_FOR_SESSION_ID:
-                return "WAITING_FOR_SESSION_ID";
+            case STATE_WAITING_FOR_SERVER:
+                return "WAITING_FOR_SERVER";
             case STATE_ACTIVE:
                 return "ACTIVE";
             default:
diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp
index 7cf8828..8637ada 100644
--- a/media/jni/android_media_MediaDrm.cpp
+++ b/media/jni/android_media_MediaDrm.cpp
@@ -543,7 +543,7 @@
     import jav.util.Iterator;
 
     HashMap<k, v> hm;
-    Set<Entry<k, v> > s = hm.entrySet();
+    Set<Entry<k, v>> s = hm.entrySet();
     Iterator i = s.iterator();
     Entry e = s.next();
 */
@@ -613,10 +613,10 @@
 }
 
 static jobject ListOfVectorsToArrayListOfByteArray(JNIEnv *env,
-                                                   List<Vector<uint8_t> > list) {
+                                                   List<Vector<uint8_t>> list) {
     jclass clazz = gFields.arraylistClassId;
     jobject arrayList = env->NewObject(clazz, gFields.arraylist.init);
-    List<Vector<uint8_t> >::iterator iter = list.begin();
+    List<Vector<uint8_t>>::iterator iter = list.begin();
     while (iter != list.end()) {
         jbyteArray byteArray = VectorToJByteArray(env, *iter);
         env->CallBooleanMethod(arrayList, gFields.arraylist.add, byteArray);
@@ -1216,7 +1216,7 @@
         return NULL;
     }
 
-    List<Vector<uint8_t> > secureStops;
+    List<Vector<uint8_t>> secureStops;
 
     status_t err = drm->getSecureStops(secureStops);
 
@@ -1237,7 +1237,7 @@
         return NULL;
     }
 
-    List<Vector<uint8_t> > secureStopIds;
+    List<Vector<uint8_t>> secureStopIds;
 
     status_t err = drm->getSecureStopIds(secureStopIds);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
index b5f67c0..098fa62 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
@@ -15,22 +15,13 @@
 
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertNotNull;
 import static junit.framework.Assert.assertTrue;
 
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.mockitoSession;
-import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -38,49 +29,34 @@
 
 import android.animation.Animator;
 import android.animation.ValueAnimator.AnimatorUpdateListener;
-import android.content.Context;
-import android.graphics.Rect;
 import android.os.Handler;
-import android.os.IPowerManager;
-import android.os.Looper;
-import android.os.PowerManager;
 import android.service.notification.StatusBarNotification;
-import android.support.test.annotation.UiThreadTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
-import android.testing.TestableLooper.RunWithLooper;
+import android.testing.UiThreadTest;
 import android.view.MotionEvent;
-import android.view.VelocityTracker;
 import android.view.View;
-import android.view.MotionEvent;
 
 import com.android.systemui.SwipeHelper;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
-import com.android.systemui.statusbar.notification.row.NotificationMenuRow;
 
-import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoSession;
-import org.mockito.invocation.InvocationOnMock;
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 import org.mockito.stubbing.Answer;
 
-import java.util.ArrayList;
-
 /**
  * Tests for {@link NotificationSwipeHelper}.
  */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
+@UiThreadTest
 public class NotificationSwipeHelperTest extends SysuiTestCase {
 
     private NotificationSwipeHelper mSwipeHelper;
@@ -96,7 +72,6 @@
     @Rule public MockitoRule mockito = MockitoJUnit.rule();
 
     @Before
-    @UiThreadTest
     public void setUp() throws Exception {
         mCallback = mock(NotificationSwipeHelper.NotificationCallback.class);
         mListener = mock(NotificationMenuRowPlugin.OnMenuEventListener.class);
diff --git a/services/autofill/java/com/android/server/intelligence/ContentCaptureSession.java b/services/autofill/java/com/android/server/intelligence/ContentCaptureSession.java
index a437a39..9cab1ed 100644
--- a/services/autofill/java/com/android/server/intelligence/ContentCaptureSession.java
+++ b/services/autofill/java/com/android/server/intelligence/ContentCaptureSession.java
@@ -23,12 +23,15 @@
 import android.service.intelligence.InteractionContext;
 import android.service.intelligence.InteractionSessionId;
 import android.util.Slog;
+import android.view.intelligence.ContentCaptureEvent;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Preconditions;
 import com.android.server.AbstractRemoteService;
 import com.android.server.intelligence.RemoteIntelligenceService.RemoteIntelligenceServiceCallbacks;
 
 import java.io.PrintWriter;
+import java.util.List;
 
 final class ContentCaptureSession implements RemoteIntelligenceServiceCallbacks {
 
@@ -45,15 +48,15 @@
     ContentCaptureSession(@NonNull Context context, int userId, @NonNull Object lock,
             @NonNull IBinder activityToken, @NonNull IntelligencePerUserService service,
             @NonNull ComponentName serviceComponentName, @NonNull ComponentName appComponentName,
-            int taskId, int displayId, int localSessionId, int globalSessionId, int flags,
+            int taskId, int displayId, @NonNull InteractionSessionId sessionId, int flags,
             boolean bindInstantServiceAllowed, boolean verbose) {
         mLock = lock;
         mActivityToken = activityToken;
         mService = service;
+        mId = Preconditions.checkNotNull(sessionId);
         mRemoteService = new RemoteIntelligenceService(context,
                 IntelligenceService.SERVICE_INTERFACE, serviceComponentName, userId, this,
                 bindInstantServiceAllowed, verbose);
-        mId = new InteractionSessionId(globalSessionId, localSessionId);
         mInterationContext = new InteractionContext(appComponentName, taskId, displayId, flags);
     }
 
@@ -66,6 +69,13 @@
     }
 
     /**
+     * Notifies the {@link IntelligenceService} of a batch of events.
+     */
+    public void sendEventsLocked(List<ContentCaptureEvent> events) {
+        mRemoteService.onContentCaptureEventsRequest(mId, events);
+    }
+
+    /**
      * Cleans up the session and remove itself from the service.
      *
      * @param notifyRemoteService whether it should trigger a {@link
@@ -79,7 +89,7 @@
                 mRemoteService.onSessionLifecycleRequest(/* context= */ null, mId);
             }
         } finally {
-            mService.removeSessionLocked(mInterationContext.getActivityComponent());
+            mService.removeSessionLocked(mId);
         }
     }
 
@@ -95,27 +105,25 @@
     }
 
     @Override // from RemoteScreenObservationServiceCallbacks
-    public void onSessionLifecycleRequestFailureOrTimeout(boolean timedOut) {
+    public void onFailureOrTimeout(boolean timedOut) {
         // TODO(b/111276913): log metrics on whether timed out or not
         if (mService.isDebug()) {
-            Slog.d(TAG, "onSessionLifecycleRequestFailure(" + mId + "): timed out=" + timedOut);
+            Slog.d(TAG, "onFailureOrTimeout(" + mId + "): timed out=" + timedOut);
         }
         synchronized (mLock) {
             removeSelfLocked(/* notifyRemoteService= */ false);
         }
     }
 
-    /**
-     * Gets global id, unique per {@link IntelligencePerUserService}.
-     */
-    public int getGlobalSessionId() {
-        return mId.getGlobalId();
-    }
-
     @GuardedBy("mLock")
     public void dumpLocked(@NonNull String prefix, @NonNull PrintWriter pw) {
         pw.print(prefix); pw.print("id: ");  mId.dump(pw); pw.println();
         pw.print(prefix); pw.print("context: ");  mInterationContext.dump(pw); pw.println();
         pw.print(prefix); pw.print("activity token: "); pw.println(mActivityToken);
     }
+
+    @Override
+    public String toString() {
+        return "ContentCaptureSession[id=" + mId.getValue() + ", act=" + mActivityToken + "]";
+    }
 }
diff --git a/services/autofill/java/com/android/server/intelligence/IntelligenceManagerService.java b/services/autofill/java/com/android/server/intelligence/IntelligenceManagerService.java
index 4ea9036..43d4a44 100644
--- a/services/autofill/java/com/android/server/intelligence/IntelligenceManagerService.java
+++ b/services/autofill/java/com/android/server/intelligence/IntelligenceManagerService.java
@@ -24,6 +24,8 @@
 import android.content.Context;
 import android.os.IBinder;
 import android.os.UserManager;
+import android.service.intelligence.InteractionSessionId;
+import android.view.intelligence.ContentCaptureEvent;
 import android.view.intelligence.IIntelligenceManager;
 
 import com.android.internal.annotations.GuardedBy;
@@ -35,6 +37,7 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.List;
 
 /**
  * A service used to observe the contents of the screen.
@@ -85,9 +88,11 @@
 
         @Override
         public void startSession(int userId, @NonNull IBinder activityToken,
-                @NonNull ComponentName componentName, int localSessionId, int flags,
-                @NonNull IResultReceiver result) {
+                @NonNull ComponentName componentName, @NonNull InteractionSessionId sessionId,
+                int flags, @NonNull IResultReceiver result) {
             Preconditions.checkNotNull(activityToken);
+            Preconditions.checkNotNull(componentName);
+            Preconditions.checkNotNull(sessionId);
 
             // TODO(b/111276913): refactor getTaskIdForActivity() to also return ComponentName,
             // so we don't pass it on startSession (same for Autofill)
@@ -99,19 +104,29 @@
             synchronized (mLock) {
                 final IntelligencePerUserService service = getServiceForUserLocked(userId);
                 service.startSessionLocked(activityToken, componentName, taskId, displayId,
-                        localSessionId, flags, result);
+                        sessionId, flags, result);
             }
         }
 
         @Override
-        public void finishSession(int userId, @NonNull IBinder activityToken,
-                @NonNull ComponentName componentName, int localSessionId, int globalSessionId) {
-            Preconditions.checkNotNull(activityToken);
+        public void sendEvents(int userId, @NonNull InteractionSessionId sessionId,
+                @NonNull List<ContentCaptureEvent> events) {
+            Preconditions.checkNotNull(sessionId);
+            Preconditions.checkNotNull(events);
 
             synchronized (mLock) {
                 final IntelligencePerUserService service = getServiceForUserLocked(userId);
-                service.finishSessionLocked(activityToken, componentName, localSessionId,
-                        globalSessionId);
+                service.sendEventsLocked(sessionId, events);
+            }
+        }
+
+        @Override
+        public void finishSession(int userId, @NonNull InteractionSessionId sessionId) {
+            Preconditions.checkNotNull(sessionId);
+
+            synchronized (mLock) {
+                final IntelligencePerUserService service = getServiceForUserLocked(userId);
+                service.finishSessionLocked(sessionId);
             }
         }
 
diff --git a/services/autofill/java/com/android/server/intelligence/IntelligencePerUserService.java b/services/autofill/java/com/android/server/intelligence/IntelligencePerUserService.java
index b62b239..584b872 100644
--- a/services/autofill/java/com/android/server/intelligence/IntelligencePerUserService.java
+++ b/services/autofill/java/com/android/server/intelligence/IntelligencePerUserService.java
@@ -25,14 +25,18 @@
 import android.content.pm.ServiceInfo;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.service.intelligence.InteractionSessionId;
 import android.util.ArrayMap;
 import android.util.Slog;
+import android.view.intelligence.ContentCaptureEvent;
+import android.view.intelligence.IntelligenceManager;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.IResultReceiver;
 import com.android.server.AbstractPerUserSystemService;
 
 import java.io.PrintWriter;
+import java.util.List;
 
 /**
  * Per-user instance of {@link IntelligenceManagerService}.
@@ -42,11 +46,9 @@
 
     private static final String TAG = "IntelligencePerUserService";
 
-    private static int sNextSessionId;
-
-    // TODO(b/111276913): should key by componentName + taskId or ActivityToken
     @GuardedBy("mLock")
-    private final ArrayMap<ComponentName, ContentCaptureSession> mSessions = new ArrayMap<>();
+    private final ArrayMap<InteractionSessionId, ContentCaptureSession> mSessions =
+            new ArrayMap<>();
 
     // TODO(b/111276913): add mechanism to prune stale sessions, similar to Autofill's
 
@@ -83,8 +85,9 @@
     // TODO(b/111276913): log metrics
     @GuardedBy("mLock")
     public void startSessionLocked(@NonNull IBinder activityToken,
-            @NonNull ComponentName componentName, int taskId, int displayId, int localSessionId,
-            int flags, @NonNull IResultReceiver resultReceiver) {
+            @NonNull ComponentName componentName, int taskId, int displayId,
+            @NonNull InteractionSessionId sessionId, int flags,
+            @NonNull IResultReceiver resultReceiver) {
         final ComponentName serviceComponentName = getServiceComponentName();
         if (serviceComponentName == null) {
             // TODO(b/111276913): this happens when the system service is starting, we should
@@ -94,16 +97,16 @@
             return;
         }
 
-        ContentCaptureSession session = mSessions.get(componentName);
+        ContentCaptureSession session = mSessions.get(sessionId);
         if (session != null) {
             if (mMaster.debug) {
-                Slog.d(TAG, "startSession(): reusing session " + session.getGlobalSessionId()
-                        + " for " + componentName);
+                Slog.d(TAG, "startSession(): reusing session " + sessionId + " for "
+                        + componentName);
             }
             // 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, session.getGlobalSessionId());
+            sendToClient(resultReceiver, IntelligenceManager.STATE_ACTIVE);
             return;
         }
 
@@ -111,45 +114,53 @@
         final boolean bindInstantServiceAllowed = false;
 
         session = new ContentCaptureSession(getContext(), mUserId, mLock, activityToken,
-                this, serviceComponentName, componentName, taskId, displayId, localSessionId,
-                ++sNextSessionId, flags, bindInstantServiceAllowed, mMaster.verbose);
+                this, serviceComponentName, componentName, taskId, displayId, sessionId, flags,
+                bindInstantServiceAllowed, mMaster.verbose);
         if (mMaster.verbose) {
-            Slog.v(TAG, "startSession(): new session for " + componentName + "; globalId ="
-                    + session.getGlobalSessionId());
+            Slog.v(TAG, "startSession(): new session for " + componentName + " and id "
+                    + sessionId);
         }
-        mSessions.put(componentName, session);
+        mSessions.put(sessionId, session);
         session.notifySessionStartedLocked();
-        sendToClient(resultReceiver, session.getGlobalSessionId());
+        sendToClient(resultReceiver, IntelligenceManager.STATE_ACTIVE);
     }
 
     // TODO(b/111276913): log metrics
     @GuardedBy("mLock")
-    public void finishSessionLocked(@NonNull IBinder activityToken,
-            @NonNull ComponentName componentName, int localSessionId, int globalSessionId) {
-        final ContentCaptureSession session = mSessions.get(componentName);
+    public void finishSessionLocked(@NonNull InteractionSessionId sessionId) {
+        final ContentCaptureSession session = mSessions.get(sessionId);
         if (session == null) {
-            Slog.w(TAG, "finishSession(): no session for " + componentName);
+            Slog.w(TAG, "finishSession(): no session with id" + sessionId);
             return;
         }
         if (mMaster.verbose) {
-            Slog.v(TAG, "finishSession(): comp=" + componentName + "; globalId ="
-                    + session.getGlobalSessionId());
+            Slog.v(TAG, "finishSession(): " + session);
         }
-        // TODO(b/111276913): check if all arguments match existing session and throw exception if
-        // not. Or just use componentName if we change AIDL to pass just ApplicationToken and
-        // retrieve componentName from AMInternal
         session.removeSelfLocked(true);
     }
 
     @GuardedBy("mLock")
-    public void removeSessionLocked(@NonNull ComponentName key) {
-        mSessions.remove(key);
+    public void sendEventsLocked(@NonNull InteractionSessionId sessionId,
+            @NonNull List<ContentCaptureEvent> events) {
+        final ContentCaptureSession session = mSessions.get(sessionId);
+        if (session == null) {
+            Slog.w(TAG, "sendEvents(): no session for " + sessionId);
+            return;
+        }
+        if (mMaster.verbose) {
+            Slog.v(TAG, "sendEvents(): id=" + sessionId + "; events =" + events.size());
+        }
+        session.sendEventsLocked(events);
+    }
+
+    @GuardedBy("mLock")
+    public void removeSessionLocked(@NonNull InteractionSessionId sessionId) {
+        mSessions.remove(sessionId);
     }
 
     @Override
     protected void dumpLocked(String prefix, PrintWriter pw) {
         super.dumpLocked(prefix, pw);
-        pw.print(prefix); pw.print("next id: "); pw.println(sNextSessionId);
         if (mSessions.isEmpty()) {
             pw.print(prefix); pw.println("no sessions");
         } else {
diff --git a/services/autofill/java/com/android/server/intelligence/RemoteIntelligenceService.java b/services/autofill/java/com/android/server/intelligence/RemoteIntelligenceService.java
index ee66b4e..9d241fb 100644
--- a/services/autofill/java/com/android/server/intelligence/RemoteIntelligenceService.java
+++ b/services/autofill/java/com/android/server/intelligence/RemoteIntelligenceService.java
@@ -27,9 +27,12 @@
 import android.service.intelligence.InteractionSessionId;
 import android.text.format.DateUtils;
 import android.util.Slog;
+import android.view.intelligence.ContentCaptureEvent;
 
 import com.android.server.AbstractRemoteService;
 
+import java.util.List;
+
 final class RemoteIntelligenceService extends AbstractRemoteService {
 
     private static final String TAG = "RemoteIntelligenceService";
@@ -79,44 +82,89 @@
         scheduleRequest(new PendingSessionLifecycleRequest(this, context, sessionId));
     }
 
-    private static final class PendingSessionLifecycleRequest
+    /**
+     * Called by {@link ContentCaptureSession} to send a batch of events to the service.
+     */
+    public void onContentCaptureEventsRequest(@NonNull InteractionSessionId sessionId,
+            @NonNull List<ContentCaptureEvent> events) {
+        cancelScheduledUnbind();
+        scheduleRequest(new PendingOnContentCaptureEventsRequest(this, sessionId, events));
+    }
+
+
+    private abstract static class MyPendingRequest
             extends PendingRequest<RemoteIntelligenceService> {
+        protected final InteractionSessionId mSessionId;
 
-        private final InteractionContext mContext;
-        private final InteractionSessionId mSessionId;
-
-        protected PendingSessionLifecycleRequest(@NonNull RemoteIntelligenceService service,
-                @Nullable InteractionContext context, @NonNull InteractionSessionId sessionId) {
+        private MyPendingRequest(@NonNull RemoteIntelligenceService service,
+                @NonNull InteractionSessionId sessionId) {
             super(service);
-            mContext = context;
             mSessionId = sessionId;
         }
 
         @Override // from PendingRequest
-        public void run() {
+        protected final void onTimeout(RemoteIntelligenceService remoteService) {
+            Slog.w(TAG, "timed out handling " + getClass().getSimpleName() + " for "
+                    + mSessionId);
+            remoteService.mCallbacks.onFailureOrTimeout(/* timedOut= */ true);
+        }
+
+        @Override // from PendingRequest
+        public final void run() {
             final RemoteIntelligenceService remoteService = getService();
             if (remoteService != null) {
                 try {
-                    remoteService.mService.onSessionLifecycle(mContext, mSessionId);
+                    myRun(remoteService);
+                    // We don't expect the service to call us back, so we finish right away.
+                    finish();
                 } catch (RemoteException e) {
-                    Slog.w(TAG, "exception handling PendingSessionLifecycleRequest for "
+                    Slog.w(TAG, "exception handling " + getClass().getSimpleName() + " for "
                             + mSessionId + ": " + e);
-                    remoteService.mCallbacks
-                        .onSessionLifecycleRequestFailureOrTimeout(/* timedOut= */ false);
+                    remoteService.mCallbacks.onFailureOrTimeout(/* timedOut= */ false);
                 }
             }
         }
 
-        @Override // from PendingRequest
-        protected void onTimeout(RemoteIntelligenceService remoteService) {
-            Slog.w(TAG, "timed out handling PendingSessionLifecycleRequest for "
-                    + mSessionId);
-            remoteService.mCallbacks
-                .onSessionLifecycleRequestFailureOrTimeout(/* timedOut= */ true);
+        protected abstract void myRun(@NonNull RemoteIntelligenceService service)
+                throws RemoteException;
+
+    }
+
+    private static final class PendingSessionLifecycleRequest extends MyPendingRequest {
+
+        private final InteractionContext mContext;
+
+        protected PendingSessionLifecycleRequest(@NonNull RemoteIntelligenceService service,
+                @Nullable InteractionContext context, @NonNull InteractionSessionId sessionId) {
+            super(service, sessionId);
+            mContext = context;
+        }
+
+        @Override // from MyPendingRequest
+        public void myRun(@NonNull RemoteIntelligenceService remoteService) throws RemoteException {
+            remoteService.mService.onSessionLifecycle(mContext, mSessionId);
+        }
+    }
+
+    private static final class PendingOnContentCaptureEventsRequest extends MyPendingRequest {
+
+        private final List<ContentCaptureEvent> mEvents;
+
+        protected PendingOnContentCaptureEventsRequest(@NonNull RemoteIntelligenceService service,
+                @NonNull InteractionSessionId sessionId,
+                @NonNull List<ContentCaptureEvent> events) {
+            super(service, sessionId);
+            mEvents = events;
+        }
+
+        @Override // from MyPendingRequest
+        public void myRun(@NonNull RemoteIntelligenceService remoteService) throws RemoteException {
+            remoteService.mService.onContentCaptureEvents(mSessionId, mEvents);
         }
     }
 
     public interface RemoteIntelligenceServiceCallbacks extends VultureCallback {
-        void onSessionLifecycleRequestFailureOrTimeout(boolean timedOut);
+        // To keep it simple, we use the same callback for all failures / timeouts.
+        void onFailureOrTimeout(boolean timedOut);
     }
 }
diff --git a/services/core/java/com/android/server/AbstractRemoteService.java b/services/core/java/com/android/server/AbstractRemoteService.java
index 1d3a34c..181d7fd 100644
--- a/services/core/java/com/android/server/AbstractRemoteService.java
+++ b/services/core/java/com/android/server/AbstractRemoteService.java
@@ -366,11 +366,12 @@
                     mCompleted = true;
                 }
 
-                Slog.w(mTag, "timed out");
                 final S remoteService = mWeakService.get();
                 if (remoteService != null) {
-                    Slog.w(mTag, " timed out after " + service.getRemoteRequestMillis() + " ms");
+                    Slog.w(mTag, "timed out after " + service.getRemoteRequestMillis() + " ms");
                     onTimeout(remoteService);
+                } else {
+                    Slog.w(mTag, "timed out (no service)");
                 }
             };
             mServiceHandler.postAtTime(mTimeoutTrigger,
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index aae7b95..9d1a301 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -40,7 +40,6 @@
 import android.content.pm.ResolveInfo;
 import android.media.RingtoneManager;
 import android.net.Uri;
-import android.os.Binder;
 import android.os.Build;
 import android.os.Environment;
 import android.os.Handler;
@@ -880,9 +879,8 @@
     }
 
     private String getDefaultSystemHandlerActivityPackage(Intent intent, int userId) {
-        ResolveInfo handler = mServiceInternal.resolveIntent(intent,
-                intent.resolveType(mContext.getContentResolver()), DEFAULT_INTENT_QUERY_FLAGS,
-                userId, false, Binder.getCallingUid());
+        ResolveInfo handler = mContext.getPackageManager().resolveActivityAsUser(
+                intent, DEFAULT_INTENT_QUERY_FLAGS, userId);
         if (handler == null || handler.activityInfo == null) {
             return null;
         }
@@ -899,8 +897,8 @@
 
     private String getDefaultSystemHandlerServicePackage(
             Intent intent, int userId) {
-        List<ResolveInfo> handlers = mServiceInternal.queryIntentServices(
-                intent, DEFAULT_INTENT_QUERY_FLAGS, Binder.getCallingUid(), userId);
+        List<ResolveInfo> handlers = mContext.getPackageManager().queryIntentServicesAsUser(
+                intent, DEFAULT_INTENT_QUERY_FLAGS, userId);
         if (handlers == null) {
             return null;
         }
@@ -924,10 +922,8 @@
         for (String syncAdapterPackageName : syncAdapterPackageNames) {
             homeIntent.setPackage(syncAdapterPackageName);
 
-            ResolveInfo homeActivity = mServiceInternal.resolveIntent(homeIntent,
-                    homeIntent.resolveType(mContext.getContentResolver()),
-                    DEFAULT_INTENT_QUERY_FLAGS,
-                    userId, false, Binder.getCallingUid());
+            ResolveInfo homeActivity = mContext.getPackageManager().resolveActivityAsUser(
+                    homeIntent, DEFAULT_INTENT_QUERY_FLAGS, userId);
             if (homeActivity != null) {
                 continue;
             }
@@ -941,7 +937,7 @@
     }
 
     private String getDefaultProviderAuthorityPackage(String authority, int userId) {
-        ProviderInfo provider = mServiceInternal.resolveContentProvider(
+        ProviderInfo provider = mContext.getPackageManager().resolveContentProviderAsUser(
                 authority, DEFAULT_INTENT_QUERY_FLAGS, userId);
         if (provider != null) {
             return provider.packageName;
@@ -980,8 +976,9 @@
                 continue;
             }
 
-            final int flags = mServiceInternal.getPermissionFlagsTEMP(
-                    permission, packageName, userId);
+            UserHandle user = UserHandle.of(userId);
+            final int flags = mContext.getPackageManager()
+                    .getPermissionFlags(permission, packageName, user);
 
             // We didn't get this through the default grant policy. Move along.
             if ((flags & PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT) == 0) {
@@ -997,7 +994,7 @@
             if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0 && !systemFixed) {
                 continue;
             }
-            mServiceInternal.revokeRuntimePermission(packageName, permission, userId, false);
+            mContext.getPackageManager().revokeRuntimePermission(packageName, permission, user);
 
             if (DEBUG) {
                 Log.i(TAG, "revoked " + (systemFixed ? "fixed " : "not fixed ")
@@ -1007,8 +1004,8 @@
             // Remove the GRANTED_BY_DEFAULT flag without touching the others.
             // Note that we do not revoke FLAG_PERMISSION_SYSTEM_FIXED. That bit remains
             // sticky once set.
-            mServiceInternal.updatePermissionFlagsTEMP(permission, packageName,
-                    PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT, 0, userId);
+            mContext.getPackageManager().updatePermissionFlags(permission, packageName,
+                    PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT, 0, user);
         }
     }
 
@@ -1077,8 +1074,9 @@
             }
 
             if (permissions.contains(permission)) {
-                final int flags = mServiceInternal.getPermissionFlagsTEMP(
-                        permission, pkg.packageName, userId);
+                UserHandle user = UserHandle.of(userId);
+                final int flags = mContext.getPackageManager().getPermissionFlags(
+                        permission, pkg.packageName, user);
 
                 // If any flags are set to the permission, then it is either set in
                 // its current state by the system or device/profile owner or the user.
@@ -1094,8 +1092,8 @@
                         continue;
                     }
 
-                    mServiceInternal.grantRuntimePermission(
-                            pkg.packageName, permission, userId, false);
+                    mContext.getPackageManager()
+                            .grantRuntimePermission(pkg.packageName, permission, user);
                     if (DEBUG) {
                         Log.i(TAG, "Granted " + (systemFixed ? "fixed " : "not fixed ")
                                 + permission + " to default handler " + pkg);
@@ -1106,8 +1104,8 @@
                         newFlags |= PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
                     }
 
-                    mServiceInternal.updatePermissionFlagsTEMP(permission, pkg.packageName,
-                            newFlags, newFlags, userId);
+                    mContext.getPackageManager().updatePermissionFlags(permission, pkg.packageName,
+                            newFlags, newFlags, user);
                 }
 
                 // If a component gets a permission for being the default handler A
@@ -1119,8 +1117,8 @@
                         Log.i(TAG, "Granted not fixed " + permission + " to default handler "
                                 + pkg);
                     }
-                    mServiceInternal.updatePermissionFlagsTEMP(permission, pkg.packageName,
-                            PackageManager.FLAG_PERMISSION_SYSTEM_FIXED, 0, userId);
+                    mContext.getPackageManager().updatePermissionFlags(permission, pkg.packageName,
+                            PackageManager.FLAG_PERMISSION_SYSTEM_FIXED, 0, user);
                 }
             }
         }
@@ -1137,10 +1135,12 @@
 
     private PackageInfo getPackageInfo(String pkg,
             @PackageManager.PackageInfoFlags int extraFlags) {
-        return mServiceInternal.getPackageInfo(pkg,
-                DEFAULT_PACKAGE_INFO_QUERY_FLAGS | extraFlags,
-                //TODO is this the right filterCallingUid?
-                UserHandle.USER_SYSTEM, UserHandle.USER_SYSTEM);
+        try {
+            return mContext.getPackageManager().getPackageInfo(pkg,
+                    DEFAULT_PACKAGE_INFO_QUERY_FLAGS | extraFlags);
+        } catch (NameNotFoundException e) {
+            return null;
+        }
     }
 
     private boolean isSysComponentOrPersistentPlatformSignedPrivApp(PackageInfo pkg) {
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java
index ae0e35b..4018eef 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java
@@ -70,7 +70,8 @@
 
     private NotificationRecord getNotificationRecord(NotificationChannel c) {
         StatusBarNotification sbn = mock(StatusBarNotification.class);
-        when(sbn.getNotification()).thenReturn(mock(Notification.class));
+        Notification notification = mock(Notification.class);
+        when(sbn.getNotification()).thenReturn(notification);
         return new NotificationRecord(mContext, sbn, c);
     }
 
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 983e766..99de4ca 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1231,6 +1231,47 @@
     public static final String KEY_SHOW_PRECISE_FAILED_CAUSE_BOOL =
             "show_precise_failed_cause_bool";
 
+    /**
+     * Boolean to decide whether lte is enabled.
+     * @hide
+     */
+    public static final String KEY_LTE_ENABLED_BOOL = "lte_enabled_bool";
+
+    /**
+     * Boolean to decide whether TD-SCDMA is supported.
+     * @hide
+     */
+    public static final String KEY_SUPPORT_TDSCDMA_BOOL = "support_tdscdma_bool";
+
+    /**
+     * A list of mcc/mnc that support TD-SCDMA for device when connect to the roaming network.
+     * @hide
+     */
+    public static final String KEY_SUPPORT_TDSCDMA_ROAMING_NETWORKS_STRING_ARRAY =
+            "support_tdscdma_roaming_networks_string_array";
+
+    /**
+     * Boolean to decide whether world mode is enabled.
+     * @hide
+     */
+    public static final String KEY_WORLD_MODE_ENABLED_BOOL = "world_mode_enabled_bool";
+
+    /**
+     * Package name of the carrier settings activity.
+     * @see {@link #KEY_CARRIER_SETTINGS_ACTIVITY_CLASS_NAME_STRING}.
+     * @hide
+     */
+    public static final String KEY_CARRIER_SETTINGS_ACTIVITY_PACKAGE_NAME_STRING =
+            "carrier_settings_activity_package_name_string";
+
+    /**
+     * Class name of the carrier settings activity.
+     * @see {@link #KEY_CARRIER_SETTINGS_ACTIVITY_PACKAGE_NAME_STRING}.
+     * @hide
+     */
+    public static final String KEY_CARRIER_SETTINGS_ACTIVITY_CLASS_NAME_STRING =
+            "carrier_settings_activity_class_name_string";
+
     // These variables are used by the MMS service and exposed through another API,
     // SmsManager. The variable names and string values are copied from there.
     public static final String KEY_MMS_ALIAS_ENABLED_BOOL = "aliasEnabled";
@@ -2570,6 +2611,12 @@
         sDefaults.putBoolean(KEY_ALWAYS_SHOW_DATA_RAT_ICON_BOOL, false);
         sDefaults.putBoolean(KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL, false);
         sDefaults.putBoolean(KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL, true);
+        sDefaults.putBoolean(KEY_LTE_ENABLED_BOOL, true);
+        sDefaults.putBoolean(KEY_SUPPORT_TDSCDMA_BOOL, false);
+        sDefaults.putStringArray(KEY_SUPPORT_TDSCDMA_ROAMING_NETWORKS_STRING_ARRAY, null);
+        sDefaults.putBoolean(KEY_WORLD_MODE_ENABLED_BOOL, false);
+        sDefaults.putString(KEY_CARRIER_SETTINGS_ACTIVITY_PACKAGE_NAME_STRING, "");
+        sDefaults.putString(KEY_CARRIER_SETTINGS_ACTIVITY_CLASS_NAME_STRING, "");
         sDefaults.putBoolean(KEY_CARRIER_CONFIG_APPLIED_BOOL, false);
         sDefaults.putBoolean(KEY_CHECK_PRICING_WITH_CARRIER_FOR_DATA_ROAMING_BOOL, false);
         sDefaults.putIntArray(KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY,
diff --git a/telephony/java/android/telephony/DisconnectCause.java b/telephony/java/android/telephony/DisconnectCause.java
index d7169b2..c6887ab 100644
--- a/telephony/java/android/telephony/DisconnectCause.java
+++ b/telephony/java/android/telephony/DisconnectCause.java
@@ -342,6 +342,12 @@
      */
     public static final int TOO_MANY_ONGOING_CALLS = 75;
 
+    /**
+     * Indicates that a new outgoing call cannot be placed because OTASP provisioning is currently
+     * in process.
+     */
+    public static final int OTASP_PROVISIONING_IN_PROCESS = 76;
+
     //*********************************************************************************************
     // When adding a disconnect type:
     // 1) Update toString() with the newly added disconnect type.
@@ -505,6 +511,8 @@
             return "CALLING_DISABLED";
         case TOO_MANY_ONGOING_CALLS:
             return "TOO_MANY_ONGOING_CALLS";
+        case OTASP_PROVISIONING_IN_PROCESS:
+            return "OTASP_PROVISIONING_IN_PROCESS";
         default:
             return "INVALID: " + cause;
         }
diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java
index 89ef339..f73036e 100644
--- a/telephony/java/android/telephony/ims/ImsCallProfile.java
+++ b/telephony/java/android/telephony/ims/ImsCallProfile.java
@@ -16,17 +16,20 @@
 
 package android.telephony.ims;
 
+import android.annotation.IntDef;
 import android.annotation.SystemApi;
 import android.annotation.UnsupportedAppUsage;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.PersistableBundle;
 import android.telecom.VideoProfile;
 import android.util.Log;
 
 import com.android.internal.telephony.PhoneConstants;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Parcelable object to handle IMS call profile.
  * It is created from GSMA IR.92/IR.94, 3GPP TS 24.229/TS 26.114/TS26.111.
@@ -206,17 +209,36 @@
     public static final int DIALSTRING_USSD = 2;
 
     /**
-     * Values for causes that restrict call types
+     * Call is not restricted on peer side and High Definition media is supported
      */
-    // Default cause not restricted at peer and HD is supported
     public static final int CALL_RESTRICT_CAUSE_NONE = 0;
-    // Service not supported by RAT at peer
+
+    /**
+     * High Definition media is not supported on the peer side due to the Radio Access Technology
+     * (RAT) it is are connected to.
+     */
     public static final int CALL_RESTRICT_CAUSE_RAT = 1;
-    // Service Disabled at peer
+
+    /**
+     * The service has been disabled on the peer side.
+     */
     public static final int CALL_RESTRICT_CAUSE_DISABLED = 2;
-    // HD is not supported
+
+    /**
+     * High definition media is not currently supported.
+     */
     public static final int CALL_RESTRICT_CAUSE_HD = 3;
 
+    /**@hide*/
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = "CALL_RESTRICT_CAUSE_", value = {
+            CALL_RESTRICT_CAUSE_NONE,
+            CALL_RESTRICT_CAUSE_RAT,
+            CALL_RESTRICT_CAUSE_DISABLED,
+            CALL_RESTRICT_CAUSE_HD
+    })
+    public @interface CallRestrictCause {}
+
     /**
      * String extra properties
      *  oi : Originating identity (number), MT only
@@ -270,7 +292,7 @@
     public int mCallType;
     /** @hide */
     @UnsupportedAppUsage
-    public int mRestrictCause = CALL_RESTRICT_CAUSE_NONE;
+    public @CallRestrictCause int mRestrictCause = CALL_RESTRICT_CAUSE_NONE;
 
     /**
      * Extras associated with this {@link ImsCallProfile}.
@@ -285,7 +307,7 @@
      *     <li>{@code long[]}</li>
      *     <li>{@code double[]}</li>
      *     <li>{@code String[]}</li>
-     *     <li>{@link PersistableBundle}</li>
+     *     <li>{@link android.os.PersistableBundle}</li>
      *     <li>{@link Boolean} (and boolean)</li>
      *     <li>{@code boolean[]}</li>
      *     <li>Other {@link Parcelable} classes in the {@code android.*} namespace.</li>
@@ -426,6 +448,14 @@
         }
     }
 
+    /**
+     * Set the call restrict cause, which provides the reason why a call has been restricted from
+     * using High Definition media.
+     */
+    public void setCallRestrictCause(@CallRestrictCause int cause) {
+        mRestrictCause = cause;
+    }
+
     public void updateCallType(ImsCallProfile profile) {
         mCallType = profile.mCallType;
     }
@@ -494,7 +524,11 @@
         return mCallType;
     }
 
-    public int getRestrictCause() {
+    /**
+     * @return The call restrict cause, which provides the reason why a call has been restricted
+     * from using High Definition media.
+     */
+    public @CallRestrictCause int getRestrictCause() {
         return mRestrictCause;
     }