diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java
new file mode 100644
index 0000000..ea6f2fe
--- /dev/null
+++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java
@@ -0,0 +1,509 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.contentcapture;
+
+import static android.view.contentcapture.ContentCaptureEvent.TYPE_SESSION_FINISHED;
+import static android.view.contentcapture.ContentCaptureEvent.TYPE_SESSION_STARTED;
+import static android.view.contentcapture.ContentCaptureEvent.TYPE_VIEW_APPEARED;
+import static android.view.contentcapture.ContentCaptureEvent.TYPE_VIEW_DISAPPEARED;
+import static android.view.contentcapture.ContentCaptureEvent.TYPE_VIEW_TEXT_CHANGED;
+import static android.view.contentcapture.ContentCaptureManager.DEBUG;
+import static android.view.contentcapture.ContentCaptureManager.VERBOSE;
+
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.ParceledListSlice;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.IBinder.DeathRecipient;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.util.Log;
+import android.util.TimeUtils;
+import android.view.autofill.AutofillId;
+import android.view.contentcapture.ViewNode.ViewStructureImpl;
+
+import com.android.internal.os.IResultReceiver;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Main session associated with a context.
+ *
+ * <p>This session is created when the activity starts and finished when it stops; clients can use
+ * it to create children activities.
+ *
+ * <p><b>NOTE: all methods in this class should return right away, or do the real work in a handler
+ * thread. Hence, the only field that must be thread-safe is {@code mEnabled}, which is called at
+ * the beginning of every method.
+ *
+ * @hide
+ */
+public final class MainContentCaptureSession extends ContentCaptureSession {
+
+    /**
+     * Handler message used to flush the buffer.
+     */
+    private static final int MSG_FLUSH = 1;
+
+    /**
+     * Maximum number of events that are buffered before sent to the app.
+     */
+    // TODO(b/121044064): use settings
+    private static final int MAX_BUFFER_SIZE = 100;
+
+    /**
+     * Frequency the buffer is flushed if stale.
+     */
+    // TODO(b/121044064): use settings
+    private static final int FLUSHING_FREQUENCY_MS = 5_000;
+
+    /**
+     * Name of the {@link IResultReceiver} extra used to pass the binder interface to the service.
+     * @hide
+     */
+    public static final String EXTRA_BINDER = "binder";
+
+    @NonNull
+    private final AtomicBoolean mDisabled;
+
+    @NonNull
+    private final Context mContext;
+
+    @NonNull
+    private final Handler mHandler;
+
+    /**
+     * Interface to the system_server binder object - it's only used to start the session (and
+     * notify when the session is finished).
+     */
+    @Nullable
+    private final IContentCaptureManager mSystemServerInterface;
+
+    /**
+     * Direct interface to the service binder object - it's used to send the events, including the
+     * last ones (when the session is finished)
+     */
+    @Nullable
+    private IContentCaptureDirectManager mDirectServiceInterface;
+    @Nullable
+    private DeathRecipient mDirectServiceVulture;
+
+    private int mState = STATE_UNKNOWN;
+
+    @Nullable
+    private IBinder mApplicationToken;
+
+    @Nullable
+    private ComponentName mComponentName;
+
+    /**
+     * List of events held to be sent as a batch.
+     */
+    @Nullable
+    private ArrayList<ContentCaptureEvent> mEvents;
+
+    // Used just for debugging purposes (on dump)
+    private long mNextFlush;
+
+    // Lazily created on demand.
+    private ContentCaptureSessionId mContentCaptureSessionId;
+
+    /** @hide */
+    protected MainContentCaptureSession(@NonNull Context context, @NonNull Handler handler,
+            @Nullable IContentCaptureManager systemServerInterface,
+            @NonNull AtomicBoolean disabled) {
+        mContext = context;
+        mHandler = handler;
+        mSystemServerInterface = systemServerInterface;
+        mDisabled = disabled;
+    }
+
+    @Override
+    ContentCaptureSession newChild(@NonNull ContentCaptureContext clientContext) {
+        final ContentCaptureSession child = new ChildContentCaptureSession(this, clientContext);
+        notifyChildSessionStarted(mId, child.mId, clientContext);
+        return child;
+    }
+
+    /**
+     * Starts this session.
+     *
+     * @hide
+     */
+    void start(@NonNull IBinder applicationToken, @NonNull ComponentName activityComponent) {
+        if (!isContentCaptureEnabled()) return;
+
+        if (VERBOSE) {
+            Log.v(mTag, "start(): token=" + applicationToken + ", comp="
+                    + ComponentName.flattenToShortString(activityComponent));
+        }
+
+        mHandler.sendMessage(obtainMessage(MainContentCaptureSession::handleStartSession, this,
+                applicationToken, activityComponent));
+    }
+
+    @Override
+    void flush() {
+        mHandler.sendMessage(obtainMessage(MainContentCaptureSession::handleForceFlush, this));
+    }
+
+    @Override
+    void onDestroy() {
+        mHandler.sendMessage(
+                obtainMessage(MainContentCaptureSession::handleDestroySession, this));
+    }
+
+    private void handleStartSession(@NonNull IBinder token, @NonNull ComponentName componentName) {
+        if (mState != STATE_UNKNOWN) {
+            // TODO(b/111276913): revisit this scenario
+            Log.w(mTag, "ignoring handleStartSession(" + token + ") while on state "
+                    + getStateAsString(mState));
+            return;
+        }
+        mState = STATE_WAITING_FOR_SERVER;
+        mApplicationToken = token;
+        mComponentName = componentName;
+
+        if (VERBOSE) {
+            Log.v(mTag, "handleStartSession(): token=" + token + ", act="
+                    + getActivityDebugName() + ", id=" + mId);
+        }
+        final int flags = 0; // TODO(b/111276913): get proper flags
+
+        try {
+            mSystemServerInterface.startSession(mContext.getUserId(), mApplicationToken,
+                    componentName, mId, flags, new IResultReceiver.Stub() {
+                        @Override
+                        public void send(int resultCode, Bundle resultData) {
+                            IBinder binder = null;
+                            if (resultData != null) {
+                                binder = resultData.getBinder(EXTRA_BINDER);
+                                if (binder == null) {
+                                    Log.wtf(mTag, "No " + EXTRA_BINDER + " extra result");
+                                    handleResetState();
+                                    return;
+                                }
+                            }
+                            handleSessionStarted(resultCode, binder);
+                        }
+                    });
+        } catch (RemoteException e) {
+            Log.w(mTag, "Error starting session for " + componentName.flattenToShortString() + ": "
+                    + e);
+        }
+    }
+
+    /**
+     * Callback from {@code system_server} after call to
+     * {@link IContentCaptureManager#startSession(int, IBinder, ComponentName, String,
+     * ContentCaptureContext, int, IResultReceiver)}.
+     *
+     * @param resultCode session state
+     * @param binder handle to {@code IContentCaptureDirectManager}
+     */
+    private void handleSessionStarted(int resultCode, @Nullable IBinder binder) {
+        mState = resultCode;
+        if (binder != null) {
+            mDirectServiceInterface = IContentCaptureDirectManager.Stub.asInterface(binder);
+            mDirectServiceVulture = () -> {
+                Log.w(mTag, "Destroying session " + mId + " because service died");
+                destroy();
+            };
+            try {
+                binder.linkToDeath(mDirectServiceVulture, 0);
+            } catch (RemoteException e) {
+                Log.w(mTag, "Failed to link to death on " + binder + ": " + e);
+            }
+        }
+        if (resultCode == STATE_DISABLED || resultCode == STATE_DISABLED_DUPLICATED_ID) {
+            mDisabled.set(true);
+            handleResetSession(/* resetState= */ false);
+        } else {
+            mDisabled.set(false);
+        }
+        if (VERBOSE) {
+            Log.v(mTag, "handleSessionStarted() result: code=" + resultCode + ", id=" + mId
+                    + ", state=" + getStateAsString(mState) + ", disabled=" + mDisabled.get()
+                    + ", binder=" + binder);
+        }
+    }
+
+    private void handleSendEvent(@NonNull ContentCaptureEvent event, boolean forceFlush) {
+        if (mEvents == null) {
+            if (VERBOSE) {
+                Log.v(mTag, "Creating buffer for " + MAX_BUFFER_SIZE + " events");
+            }
+            mEvents = new ArrayList<>(MAX_BUFFER_SIZE);
+        }
+        mEvents.add(event);
+
+        final int numberEvents = mEvents.size();
+
+        // TODO(b/120784831): need to optimize it so we buffer changes until a number of X are
+        // buffered (either total or per autofillid). For
+        // example, if the user typed "a", "b", "c" and the threshold is 3, we should buffer
+        // "a" and "b" then send "abc".
+        final boolean bufferEvent = numberEvents < MAX_BUFFER_SIZE;
+
+        if (bufferEvent && !forceFlush) {
+            handleScheduleFlush(/* checkExisting= */ true);
+            return;
+        }
+
+        if (mState != STATE_ACTIVE) {
+            // Callback from startSession hasn't been called yet - typically happens on system
+            // apps that are started before the system service
+            // TODO(b/111276913): try to ignore session while system is not ready / boot
+            // not complete instead. Similarly, the manager service should return right away
+            // when the user does not have a service set
+            if (VERBOSE) {
+                Log.v(mTag, "Closing session for " + getActivityDebugName()
+                        + " after " + numberEvents + " delayed events and state "
+                        + getStateAsString(mState));
+            }
+            handleResetState();
+            // TODO(b/111276913): blacklist activity / use special flag to indicate that
+            // when it's launched again
+            return;
+        }
+
+        handleForceFlush();
+    }
+
+    private void handleScheduleFlush(boolean checkExisting) {
+        if (checkExisting && mHandler.hasMessages(MSG_FLUSH)) {
+            // "Renew" the flush message by removing the previous one
+            mHandler.removeMessages(MSG_FLUSH);
+        }
+        mNextFlush = SystemClock.elapsedRealtime() + FLUSHING_FREQUENCY_MS;
+        if (VERBOSE) {
+            Log.v(mTag, "Scheduled to flush in " + FLUSHING_FREQUENCY_MS + "ms: " + mNextFlush);
+        }
+        mHandler.sendMessageDelayed(
+                obtainMessage(MainContentCaptureSession::handleFlushIfNeeded, this)
+                .setWhat(MSG_FLUSH), FLUSHING_FREQUENCY_MS);
+    }
+
+    private void handleFlushIfNeeded() {
+        if (mEvents.isEmpty()) {
+            if (VERBOSE) Log.v(mTag, "Nothing to flush");
+            return;
+        }
+        handleForceFlush();
+    }
+
+    private void handleForceFlush() {
+        if (mEvents == null) return;
+
+        if (mDirectServiceInterface == null) {
+            if (DEBUG) Log.d(mTag, "handleForceFlush(): hold your horses, client not ready yet!");
+            if (!mHandler.hasMessages(MSG_FLUSH)) {
+                handleScheduleFlush(/* checkExisting= */ false);
+            }
+            return;
+        }
+
+        final int numberEvents = mEvents.size();
+        try {
+            if (DEBUG) {
+                Log.d(mTag, "Flushing " + numberEvents + " event(s) for " + getActivityDebugName());
+            }
+            mHandler.removeMessages(MSG_FLUSH);
+
+            final ParceledListSlice<ContentCaptureEvent> events = handleClearEvents();
+            mDirectServiceInterface.sendEvents(events);
+        } catch (RemoteException e) {
+            Log.w(mTag, "Error sending " + numberEvents + " for " + getActivityDebugName()
+                    + ": " + e);
+        }
+    }
+
+    /**
+     * Resets the buffer and return a {@link ParceledListSlice} with the previous events.
+     */
+    @NonNull
+    private ParceledListSlice<ContentCaptureEvent> handleClearEvents() {
+        // NOTE: we must save a reference to the current mEvents and then set it to to null,
+        // otherwise clearing it would clear it in the receiving side if the service is also local.
+        final List<ContentCaptureEvent> events = mEvents == null
+                ? Collections.emptyList()
+                : mEvents;
+        mEvents = null;
+        return new ParceledListSlice<>(events);
+    }
+
+    private void handleDestroySession() {
+        if (DEBUG) {
+            Log.d(mTag, "Destroying session (ctx=" + mContext + ", id=" + mId + ") with "
+                    + (mEvents == null ? 0 : mEvents.size()) + " event(s) for "
+                    + getActivityDebugName());
+        }
+
+        try {
+            mSystemServerInterface.finishSession(mContext.getUserId(), mId);
+        } catch (RemoteException e) {
+            Log.e(mTag, "Error destroying system-service session " + mId + " for "
+                    + getActivityDebugName() + ": " + e);
+        }
+    }
+
+    private void handleResetState() {
+        handleResetSession(/* resetState= */ true);
+    }
+
+    // TODO(b/121033016): once we support multiple sessions, we might need to move some of these
+    // clearings out.
+    private void handleResetSession(boolean resetState) {
+        if (resetState) {
+            mState = STATE_UNKNOWN;
+        }
+
+        // TODO(b/121033016): must reset children (which currently is owned by superclass)
+
+        mContentCaptureSessionId = null;
+        mApplicationToken = null;
+        mComponentName = null;
+        mEvents = null;
+        if (mDirectServiceInterface != null) {
+            mDirectServiceInterface.asBinder().unlinkToDeath(mDirectServiceVulture, 0);
+        }
+        mDirectServiceInterface = null;
+        mHandler.removeMessages(MSG_FLUSH);
+    }
+
+    @Override
+    void internalNotifyViewAppeared(@NonNull ViewStructureImpl node) {
+        notifyViewAppeared(mId, node);
+    }
+
+    @Override
+    void internalNotifyViewDisappeared(@NonNull AutofillId id) {
+        notifyViewDisappeared(mId, id);
+    }
+
+    @Override
+    void internalNotifyViewTextChanged(@NonNull AutofillId id, @Nullable CharSequence text,
+            int flags) {
+        notifyViewTextChanged(mId, id, text, flags);
+    }
+
+    @Override
+    boolean isContentCaptureEnabled() {
+        return mSystemServerInterface != null && !mDisabled.get();
+    }
+
+    // TODO(b/121033016): refactor "notifyXXXX" methods below to a common "Buffer" object that is
+    // shared between ActivityContentCaptureSession and ChildContentCaptureSession objects. Such
+    // change should also get get rid of the "internalNotifyXXXX" methods above
+    void notifyChildSessionStarted(@NonNull String parentSessionId,
+            @NonNull String childSessionId, @NonNull ContentCaptureContext clientContext) {
+        mHandler.sendMessage(obtainMessage(MainContentCaptureSession::handleSendEvent, this,
+                new ContentCaptureEvent(childSessionId, TYPE_SESSION_STARTED)
+                        .setParentSessionId(parentSessionId)
+                        .setClientContext(clientContext),
+                        /* forceFlush= */ false));
+    }
+
+    void notifyChildSessionFinished(@NonNull String parentSessionId,
+            @NonNull String childSessionId) {
+        mHandler.sendMessage(obtainMessage(MainContentCaptureSession::handleSendEvent, this,
+                new ContentCaptureEvent(childSessionId, TYPE_SESSION_FINISHED)
+                        .setParentSessionId(parentSessionId), /* forceFlush= */ false));
+    }
+
+    void notifyViewAppeared(@NonNull String sessionId, @NonNull ViewStructureImpl node) {
+        mHandler.sendMessage(obtainMessage(MainContentCaptureSession::handleSendEvent, this,
+                new ContentCaptureEvent(sessionId, TYPE_VIEW_APPEARED)
+                        .setViewNode(node.mNode), /* forceFlush= */ false));
+    }
+
+    void notifyViewDisappeared(@NonNull String sessionId, @NonNull AutofillId id) {
+        mHandler.sendMessage(obtainMessage(MainContentCaptureSession::handleSendEvent, this,
+                new ContentCaptureEvent(sessionId, TYPE_VIEW_DISAPPEARED).setAutofillId(id),
+                        /* forceFlush= */ false));
+    }
+
+    void notifyViewTextChanged(@NonNull String sessionId, @NonNull AutofillId id,
+            @Nullable CharSequence text, int flags) {
+        mHandler.sendMessage(obtainMessage(MainContentCaptureSession::handleSendEvent, this,
+                new ContentCaptureEvent(sessionId, TYPE_VIEW_TEXT_CHANGED, flags).setAutofillId(id)
+                        .setText(text), /* forceFlush= */ false));
+    }
+
+    @Override
+    void dump(@NonNull String prefix, @NonNull PrintWriter pw) {
+        pw.print(prefix); pw.print("id: "); pw.println(mId);
+        pw.print(prefix); pw.print("mContext: "); pw.println(mContext);
+        pw.print(prefix); pw.print("user: "); pw.println(mContext.getUserId());
+        if (mSystemServerInterface != null) {
+            pw.print(prefix); pw.print("mSystemServerInterface: ");
+            pw.println(mSystemServerInterface);
+        }
+        if (mDirectServiceInterface != null) {
+            pw.print(prefix); pw.print("mDirectServiceInterface: ");
+            pw.println(mDirectServiceInterface);
+        }
+        pw.print(prefix); pw.print("mDisabled: "); pw.println(mDisabled.get());
+        pw.print(prefix); pw.print("isEnabled(): "); pw.println(isContentCaptureEnabled());
+        if (mContentCaptureSessionId != null) {
+            pw.print(prefix); pw.print("public id: "); pw.println(mContentCaptureSessionId);
+        }
+        pw.print(prefix); pw.print("state: "); pw.print(mState); pw.print(" (");
+        pw.print(getStateAsString(mState)); pw.println(")");
+        if (mApplicationToken != null) {
+            pw.print(prefix); pw.print("app token: "); pw.println(mApplicationToken);
+        }
+        if (mComponentName != null) {
+            pw.print(prefix); pw.print("component name: ");
+            pw.println(mComponentName.flattenToShortString());
+        }
+        if (mEvents != null && !mEvents.isEmpty()) {
+            final int numberEvents = mEvents.size();
+            pw.print(prefix); pw.print("buffered events: "); pw.print(numberEvents);
+            pw.print('/'); pw.println(MAX_BUFFER_SIZE);
+            if (VERBOSE && numberEvents > 0) {
+                final String prefix3 = prefix + "  ";
+                for (int i = 0; i < numberEvents; i++) {
+                    final ContentCaptureEvent event = mEvents.get(i);
+                    pw.print(prefix3); pw.print(i); pw.print(": "); event.dump(pw);
+                    pw.println();
+                }
+            }
+            pw.print(prefix); pw.print("flush frequency: "); pw.println(FLUSHING_FREQUENCY_MS);
+            pw.print(prefix); pw.print("next flush: ");
+            TimeUtils.formatDuration(mNextFlush - SystemClock.elapsedRealtime(), pw); pw.println();
+        }
+        super.dump(prefix, pw);
+    }
+
+    /**
+     * Gets a string that can be used to identify the activity on logging statements.
+     */
+    private String getActivityDebugName() {
+        return mComponentName == null ? mContext.getPackageName()
+                : mComponentName.flattenToShortString();
+    }
+}
