/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT 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.contentcapture;

import static android.service.contentcapture.ContentCaptureService.setClientState;
import static android.view.contentcapture.ContentCaptureSession.NO_SESSION_ID;
import static android.view.contentcapture.ContentCaptureSession.STATE_DISABLED;
import static android.view.contentcapture.ContentCaptureSession.STATE_DUPLICATED_ID;
import static android.view.contentcapture.ContentCaptureSession.STATE_INTERNAL_ERROR;
import static android.view.contentcapture.ContentCaptureSession.STATE_NOT_WHITELISTED;
import static android.view.contentcapture.ContentCaptureSession.STATE_NO_SERVICE;

import static com.android.server.contentcapture.ContentCaptureMetricsLogger.writeServiceEvent;
import static com.android.server.contentcapture.ContentCaptureMetricsLogger.writeSessionEvent;
import static com.android.server.contentcapture.ContentCaptureMetricsLogger.writeSetWhitelistEvent;
import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA;
import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManagerInternal;
import android.app.assist.AssistContent;
import android.app.assist.AssistStructure;
import android.content.ComponentName;
import android.content.ContentCaptureOptions;
import android.content.pm.ActivityPresentationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ServiceInfo;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.UserHandle;
import android.provider.Settings;
import android.service.contentcapture.ActivityEvent;
import android.service.contentcapture.ActivityEvent.ActivityEventType;
import android.service.contentcapture.ContentCaptureService;
import android.service.contentcapture.ContentCaptureServiceInfo;
import android.service.contentcapture.FlushMetrics;
import android.service.contentcapture.IContentCaptureServiceCallback;
import android.service.contentcapture.IDataShareCallback;
import android.service.contentcapture.SnapshotData;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.view.contentcapture.ContentCaptureCondition;
import android.view.contentcapture.DataRemovalRequest;
import android.view.contentcapture.DataShareRequest;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.IResultReceiver;
import com.android.internal.util.FrameworkStatsLog;
import com.android.server.LocalServices;
import com.android.server.contentcapture.RemoteContentCaptureService.ContentCaptureServiceCallbacks;
import com.android.server.infra.AbstractPerUserSystemService;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

/**
 * Per-user instance of {@link ContentCaptureManagerService}.
 */
final class ContentCapturePerUserService
        extends
        AbstractPerUserSystemService<ContentCapturePerUserService, ContentCaptureManagerService>
        implements ContentCaptureServiceCallbacks {

    private static final String TAG = ContentCapturePerUserService.class.getSimpleName();

    @GuardedBy("mLock")
    private final SparseArray<ContentCaptureServerSession> mSessions = new SparseArray<>();

    /**
     * Reference to the remote service.
     *
     * <p>It's set in the constructor, but it's also updated when the service's updated in the
     * master's cache (for example, because a temporary service was set).
     */
    @GuardedBy("mLock")
    @Nullable
    RemoteContentCaptureService mRemoteService;

    private final ContentCaptureServiceRemoteCallback mRemoteServiceCallback =
            new ContentCaptureServiceRemoteCallback();

    /**
     * List of conditions keyed by package.
     */
    @GuardedBy("mLock")
    private final ArrayMap<String, ArraySet<ContentCaptureCondition>> mConditionsByPkg =
            new ArrayMap<>();

    /**
     * When {@code true}, remote service died but service state is kept so it's restored after
     * the system re-binds to it.
     */
    @GuardedBy("mLock")
    private boolean mZombie;

    @GuardedBy("mLock")
    private ContentCaptureServiceInfo mInfo;

    // TODO(b/111276913): add mechanism to prune stale sessions, similar to Autofill's

    ContentCapturePerUserService(@NonNull ContentCaptureManagerService master,
            @NonNull Object lock, boolean disabled, @UserIdInt int userId) {
        super(master, lock, userId);
        updateRemoteServiceLocked(disabled);
    }

    /**
     * Updates the reference to the remote service.
     */
    private void updateRemoteServiceLocked(boolean disabled) {
        if (mMaster.verbose) Slog.v(TAG, "updateRemoteService(disabled=" + disabled + ")");
        if (mRemoteService != null) {
            if (mMaster.debug) Slog.d(TAG, "updateRemoteService(): destroying old remote service");
            mRemoteService.destroy();
            mRemoteService = null;
            resetContentCaptureWhitelistLocked();
        }

        // Updates the component name
        final ComponentName serviceComponentName = updateServiceInfoLocked();

        if (serviceComponentName == null) {
            if (mMaster.debug) Slog.d(TAG, "updateRemoteService(): no service component name");
            return;
        }

        if (!disabled) {
            if (mMaster.debug) {
                Slog.d(TAG, "updateRemoteService(): creating new remote service for "
                        + serviceComponentName);
            }
            mRemoteService = new RemoteContentCaptureService(mMaster.getContext(),
                    ContentCaptureService.SERVICE_INTERFACE, serviceComponentName,
                    mRemoteServiceCallback, mUserId, this, mMaster.isBindInstantServiceAllowed(),
                    mMaster.verbose, mMaster.mDevCfgIdleUnbindTimeoutMs);
        }
    }

    @Override // from PerUserSystemService
    protected ServiceInfo newServiceInfoLocked(@NonNull ComponentName serviceComponent)
            throws NameNotFoundException {
        mInfo = new ContentCaptureServiceInfo(getContext(), serviceComponent,
                isTemporaryServiceSetLocked(), mUserId);
        return mInfo.getServiceInfo();
    }

    @Override // from PerUserSystemService
    @GuardedBy("mLock")
    protected boolean updateLocked(boolean disabled) {
        final boolean disabledStateChanged = super.updateLocked(disabled);
        if (disabledStateChanged) {
            // update session content capture enabled state.
            for (int i = 0; i < mSessions.size(); i++) {
                mSessions.valueAt(i).setContentCaptureEnabledLocked(!disabled);
            }
        }
        destroyLocked();
        updateRemoteServiceLocked(disabled);
        return disabledStateChanged;
    }

    @Override // from ContentCaptureServiceCallbacks
    public void onServiceDied(@NonNull RemoteContentCaptureService service) {
        // Don't do anything; eventually the system will bind to it again...
        Slog.w(TAG, "remote service died: " + service);
        synchronized (mLock) {
            mZombie = true;
        }
    }

    /**
     * Called after the remote service connected, it's used to restore state from a 'zombie'
     * service (i.e., after it died).
     */
    void onConnected() {
        synchronized (mLock) {
            if (mZombie) {
                // Sanity check - shouldn't happen
                if (mRemoteService == null) {
                    Slog.w(TAG, "Cannot ressurect sessions because remote service is null");
                    return;
                }

                mZombie = false;
                resurrectSessionsLocked();
            }
        }
    }

    private void resurrectSessionsLocked() {
        final int numSessions = mSessions.size();
        if (mMaster.debug) {
            Slog.d(TAG, "Ressurrecting remote service (" + mRemoteService + ") on "
                    + numSessions + " sessions");
        }

        for (int i = 0; i < numSessions; i++) {
            final ContentCaptureServerSession session = mSessions.valueAt(i);
            session.resurrectLocked();
        }
    }

    void onPackageUpdatingLocked() {
        final int numSessions = mSessions.size();
        if (mMaster.debug) {
            Slog.d(TAG, "Pausing " + numSessions + " sessions while package is updating");
        }
        for (int i = 0; i < numSessions; i++) {
            final ContentCaptureServerSession session = mSessions.valueAt(i);
            session.pauseLocked();
        }
    }

    void onPackageUpdatedLocked() {
        updateRemoteServiceLocked(!isEnabledLocked());
        resurrectSessionsLocked();
    }

    @GuardedBy("mLock")
    public void startSessionLocked(@NonNull IBinder activityToken,
            @NonNull ActivityPresentationInfo activityPresentationInfo, int sessionId, int uid,
            int flags, @NonNull IResultReceiver clientReceiver) {
        if (activityPresentationInfo == null) {
            Slog.w(TAG, "basic activity info is null");
            setClientState(clientReceiver, STATE_DISABLED | STATE_INTERNAL_ERROR,
                    /* binder= */ null);
            return;
        }
        final int taskId = activityPresentationInfo.taskId;
        final int displayId = activityPresentationInfo.displayId;
        final ComponentName componentName = activityPresentationInfo.componentName;
        final boolean whiteListed = mMaster.mGlobalContentCaptureOptions.isWhitelisted(mUserId,
                componentName) || mMaster.mGlobalContentCaptureOptions.isWhitelisted(mUserId,
                        componentName.getPackageName());
        final ComponentName serviceComponentName = getServiceComponentName();
        final boolean enabled = isEnabledLocked();
        if (mMaster.mRequestsHistory != null) {
            final String historyItem =
                    "id=" + sessionId + " uid=" + uid
                    + " a=" + ComponentName.flattenToShortString(componentName)
                    + " t=" + taskId + " d=" + displayId
                    + " s=" + ComponentName.flattenToShortString(serviceComponentName)
                    + " u=" + mUserId + " f=" + flags + (enabled ? "" : " (disabled)")
                    + " w=" + whiteListed;
            mMaster.mRequestsHistory.log(historyItem);
        }

        if (!enabled) {
            // TODO: it would be better to split in differet reasons, like
            // STATE_DISABLED_NO and STATE_DISABLED_BY_DEVICE_POLICY
            setClientState(clientReceiver, STATE_DISABLED | STATE_NO_SERVICE,
                    /* binder= */ null);
            // Log metrics.
            writeSessionEvent(sessionId,
                    FrameworkStatsLog.CONTENT_CAPTURE_SESSION_EVENTS__EVENT__SESSION_NOT_CREATED,
                    STATE_DISABLED | STATE_NO_SERVICE, serviceComponentName,
                    componentName, /* isChildSession= */ false);
            return;
        }
        if (serviceComponentName == null) {
            // TODO(b/111276913): this happens when the system service is starting, we should
            // probably handle it in a more elegant way (like waiting for boot_complete or
            // something like that
            if (mMaster.debug) {
                Slog.d(TAG, "startSession(" + activityToken + "): hold your horses");
            }
            return;
        }

        if (!whiteListed) {
            if (mMaster.debug) {
                Slog.d(TAG, "startSession(" + componentName + "): package or component "
                        + "not whitelisted");
            }
            setClientState(clientReceiver, STATE_DISABLED | STATE_NOT_WHITELISTED,
                    /* binder= */ null);
            // Log metrics.
            writeSessionEvent(sessionId,
                    FrameworkStatsLog.CONTENT_CAPTURE_SESSION_EVENTS__EVENT__SESSION_NOT_CREATED,
                    STATE_DISABLED | STATE_NOT_WHITELISTED, serviceComponentName,
                    componentName, /* isChildSession= */ false);
            return;
        }

        final ContentCaptureServerSession existingSession = mSessions.get(sessionId);
        if (existingSession != null) {
            Slog.w(TAG, "startSession(id=" + existingSession + ", token=" + activityToken
                    + ": ignoring because it already exists for " + existingSession.mActivityToken);
            setClientState(clientReceiver, STATE_DISABLED | STATE_DUPLICATED_ID,
                    /* binder=*/ null);
            // Log metrics.
            writeSessionEvent(sessionId,
                    FrameworkStatsLog.CONTENT_CAPTURE_SESSION_EVENTS__EVENT__SESSION_NOT_CREATED,
                    STATE_DISABLED | STATE_DUPLICATED_ID,
                    serviceComponentName, componentName, /* isChildSession= */ false);
            return;
        }

        if (mRemoteService == null) {
            updateRemoteServiceLocked(/* disabled= */ false); // already checked for isEnabled
        }

        if (mRemoteService == null) {
            Slog.w(TAG, "startSession(id=" + existingSession + ", token=" + activityToken
                    + ": ignoring because service is not set");
            setClientState(clientReceiver, STATE_DISABLED | STATE_NO_SERVICE,
                    /* binder= */ null);
            // Log metrics.
            writeSessionEvent(sessionId,
                    FrameworkStatsLog.CONTENT_CAPTURE_SESSION_EVENTS__EVENT__SESSION_NOT_CREATED,
                    STATE_DISABLED | STATE_NO_SERVICE, serviceComponentName,
                    componentName, /* isChildSession= */ false);
            return;
        }

        // Make sure service is bound, just in case the initial connection failed somehow
        mRemoteService.ensureBoundLocked();

        final ContentCaptureServerSession newSession = new ContentCaptureServerSession(mLock,
                activityToken, this, componentName, clientReceiver, taskId, displayId, sessionId,
                uid, flags);
        if (mMaster.verbose) {
            Slog.v(TAG, "startSession(): new session for "
                    + ComponentName.flattenToShortString(componentName) + " and id " + sessionId);
        }
        mSessions.put(sessionId, newSession);
        newSession.notifySessionStartedLocked(clientReceiver);
    }

    @GuardedBy("mLock")
    public void finishSessionLocked(int sessionId) {
        if (!isEnabledLocked()) {
            return;
        }

        final ContentCaptureServerSession session = mSessions.get(sessionId);
        if (session == null) {
            if (mMaster.debug) {
                Slog.d(TAG, "finishSession(): no session with id" + sessionId);
            }
            return;
        }
        if (mMaster.verbose) Slog.v(TAG, "finishSession(): id=" + sessionId);
        session.removeSelfLocked(/* notifyRemoteService= */ true);
    }

    @GuardedBy("mLock")
    public void removeDataLocked(@NonNull DataRemovalRequest request) {
        if (!isEnabledLocked()) {
            return;
        }
        assertCallerLocked(request.getPackageName());
        mRemoteService.onDataRemovalRequest(request);
    }

    @GuardedBy("mLock")
    public void onDataSharedLocked(@NonNull DataShareRequest request,
            IDataShareCallback.Stub dataShareCallback) {
        if (!isEnabledLocked()) {
            return;
        }
        assertCallerLocked(request.getPackageName());
        mRemoteService.onDataShareRequest(request, dataShareCallback);
    }

    @GuardedBy("mLock")
    @Nullable
    public ComponentName getServiceSettingsActivityLocked() {
        if (mInfo == null) return null;

        final String activityName = mInfo.getSettingsActivity();
        if (activityName == null) return null;

        final String packageName = mInfo.getServiceInfo().packageName;
        return new ComponentName(packageName, activityName);
    }

    /**
     * Asserts the component is owned by the caller.
     */
    @GuardedBy("mLock")
    private void assertCallerLocked(@NonNull String packageName) {
        final PackageManager pm = getContext().getPackageManager();
        final int callingUid = Binder.getCallingUid();
        final int packageUid;
        try {
            packageUid = pm.getPackageUidAsUser(packageName, UserHandle.getCallingUserId());
        } catch (NameNotFoundException e) {
            throw new SecurityException("Could not verify UID for " + packageName);
        }
        if (callingUid != packageUid && !LocalServices.getService(ActivityManagerInternal.class)
                .hasRunningActivity(callingUid, packageName)) {
            final String[] packages = pm.getPackagesForUid(callingUid);
            final String callingPackage = packages != null ? packages[0] : "uid-" + callingUid;
            Slog.w(TAG, "App (package=" + callingPackage + ", UID=" + callingUid
                    + ") passed package (" + packageName + ") owned by UID " + packageUid);

            throw new SecurityException("Invalid package: " + packageName);
        }
    }

    @GuardedBy("mLock")
    public boolean sendActivityAssistDataLocked(@NonNull IBinder activityToken,
            @NonNull Bundle data) {
        final int id = getSessionId(activityToken);
        if (id != NO_SESSION_ID) {
            final ContentCaptureServerSession session = mSessions.get(id);
            final Bundle assistData = data.getBundle(ASSIST_KEY_DATA);
            final AssistStructure assistStructure = data.getParcelable(ASSIST_KEY_STRUCTURE);
            final AssistContent assistContent = data.getParcelable(ASSIST_KEY_CONTENT);
            final SnapshotData snapshotData = new SnapshotData(assistData,
                    assistStructure, assistContent);
            session.sendActivitySnapshotLocked(snapshotData);
            return true;
        } else {
            Slog.e(TAG, "Failed to notify activity assist data for activity: " + activityToken);
        }
        return false;
    }

    @GuardedBy("mLock")
    public void removeSessionLocked(int sessionId) {
        mSessions.remove(sessionId);
    }

    @GuardedBy("mLock")
    public boolean isContentCaptureServiceForUserLocked(int uid) {
        return uid == getServiceUidLocked();
    }

    @GuardedBy("mLock")
    private ContentCaptureServerSession getSession(@NonNull IBinder activityToken) {
        for (int i = 0; i < mSessions.size(); i++) {
            final ContentCaptureServerSession session = mSessions.valueAt(i);
            if (session.mActivityToken.equals(activityToken)) {
                return session;
            }
        }
        return null;
    }

    /**
     * Destroys the service and all state associated with it.
     *
     * <p>Called when the service was disabled (for example, if the settings change).
     */
    @GuardedBy("mLock")
    public void destroyLocked() {
        if (mMaster.debug) Slog.d(TAG, "destroyLocked()");
        if (mRemoteService != null) {
            mRemoteService.destroy();
        }
        destroySessionsLocked();
    }

    @GuardedBy("mLock")
    void destroySessionsLocked() {
        final int numSessions = mSessions.size();
        for (int i = 0; i < numSessions; i++) {
            final ContentCaptureServerSession session = mSessions.valueAt(i);
            session.destroyLocked(/* notifyRemoteService= */ true);
        }
        mSessions.clear();
    }

    @GuardedBy("mLock")
    void listSessionsLocked(ArrayList<String> output) {
        final int numSessions = mSessions.size();
        for (int i = 0; i < numSessions; i++) {
            final ContentCaptureServerSession session = mSessions.valueAt(i);
            output.add(session.toShortString());
        }
    }

    @GuardedBy("mLock")
    @Nullable
    ArraySet<ContentCaptureCondition> getContentCaptureConditionsLocked(
            @NonNull String packageName) {
        return mConditionsByPkg.get(packageName);
    }

    @GuardedBy("mLock")
    void onActivityEventLocked(@NonNull ComponentName componentName, @ActivityEventType int type) {
        if (mRemoteService == null) {
            if (mMaster.debug) Slog.d(mTag, "onActivityEvent(): no remote service");
            return;
        }
        final ActivityEvent event = new ActivityEvent(componentName, type);

        if (mMaster.verbose) Slog.v(mTag, "onActivityEvent(): " + event);

        mRemoteService.onActivityLifecycleEvent(event);
    }

    @Override
    protected void dumpLocked(String prefix, PrintWriter pw) {
        super.dumpLocked(prefix, pw);

        final String prefix2 = prefix + "  ";
        pw.print(prefix); pw.print("Service Info: ");
        if (mInfo == null) {
            pw.println("N/A");
        } else {
            pw.println();
            mInfo.dump(prefix2, pw);
        }
        pw.print(prefix); pw.print("Zombie: "); pw.println(mZombie);

        if (mRemoteService != null) {
            pw.print(prefix); pw.println("remote service:");
            mRemoteService.dump(prefix2, pw);
        }

        if (mSessions.size() == 0) {
            pw.print(prefix); pw.println("no sessions");
        } else {
            final int sessionsSize = mSessions.size();
            pw.print(prefix); pw.print("number sessions: "); pw.println(sessionsSize);
            for (int i = 0; i < sessionsSize; i++) {
                pw.print(prefix); pw.print("#"); pw.println(i);
                final ContentCaptureServerSession session = mSessions.valueAt(i);
                session.dumpLocked(prefix2, pw);
                pw.println();
            }
        }
    }

    /**
     * Returns the session id associated with the given activity.
     */
    @GuardedBy("mLock")
    private int getSessionId(@NonNull IBinder activityToken) {
        for (int i = 0; i < mSessions.size(); i++) {
            ContentCaptureServerSession session = mSessions.valueAt(i);
            if (session.isActivitySession(activityToken)) {
                return mSessions.keyAt(i);
            }
        }
        return NO_SESSION_ID;
    }

    /**
     * Resets the content capture whitelist.
     */
    @GuardedBy("mLock")
    private void resetContentCaptureWhitelistLocked() {
        if (mMaster.verbose) {
            Slog.v(TAG, "resetting content capture whitelist");
        }
        mMaster.mGlobalContentCaptureOptions.resetWhitelist(mUserId);
    }

    private final class ContentCaptureServiceRemoteCallback extends
            IContentCaptureServiceCallback.Stub {

        @Override
        public void setContentCaptureWhitelist(List<String> packages,
                List<ComponentName> activities) {
            // TODO(b/122595322): add CTS test for when it's null
            if (mMaster.verbose) {
                Slog.v(TAG, "setContentCaptureWhitelist(" + (packages == null
                        ? "null_packages" : packages.size() + " packages")
                        + ", " + (activities == null
                        ? "null_activities" : activities.size() + " activities") + ")"
                        + " for user " + mUserId);
            }
            mMaster.mGlobalContentCaptureOptions.setWhitelist(mUserId, packages, activities);
            writeSetWhitelistEvent(getServiceComponentName(), packages, activities);

            // Must disable session that are not the whitelist anymore...
            final int numSessions = mSessions.size();
            if (numSessions <= 0) return;

            // ...but without holding the lock on mGlobalContentCaptureOptions
            final SparseBooleanArray blacklistedSessions = new SparseBooleanArray(numSessions);

            for (int i = 0; i < numSessions; i++) {
                final ContentCaptureServerSession session = mSessions.valueAt(i);
                final boolean whitelisted = mMaster.mGlobalContentCaptureOptions
                        .isWhitelisted(mUserId, session.appComponentName);
                if (!whitelisted) {
                    final int sessionId = mSessions.keyAt(i);
                    if (mMaster.debug) {
                        Slog.d(TAG, "marking session " + sessionId + " (" + session.appComponentName
                                + ") for un-whitelisting");
                    }
                    blacklistedSessions.append(sessionId, true);
                }
            }
            final int numBlacklisted = blacklistedSessions.size();

            if (numBlacklisted <= 0) return;

            synchronized (mLock) {
                for (int i = 0; i < numBlacklisted; i++) {
                    final int sessionId = blacklistedSessions.keyAt(i);
                    if (mMaster.debug) Slog.d(TAG, "un-whitelisting " + sessionId);
                    final ContentCaptureServerSession session = mSessions.get(sessionId);
                    session.setContentCaptureEnabledLocked(false);
                }
            }
        }

        @Override
        public void setContentCaptureConditions(String packageName,
                List<ContentCaptureCondition> conditions) {
            if (mMaster.verbose) {
                Slog.v(TAG, "setContentCaptureConditions(" + packageName + "): "
                        + (conditions == null ? "null" : conditions.size() + " conditions"));
            }
            synchronized (mLock) {
                if (conditions == null) {
                    mConditionsByPkg.remove(packageName);
                } else {
                    mConditionsByPkg.put(packageName, new ArraySet<>(conditions));
                }
            }
        }

        @Override
        public void disableSelf() {
            if (mMaster.verbose) Slog.v(TAG, "disableSelf()");

            final long token = Binder.clearCallingIdentity();
            try {
                Settings.Secure.putStringForUser(getContext().getContentResolver(),
                        Settings.Secure.CONTENT_CAPTURE_ENABLED, "0", mUserId);
            } finally {
                Binder.restoreCallingIdentity(token);
            }
            writeServiceEvent(FrameworkStatsLog.CONTENT_CAPTURE_SERVICE_EVENTS__EVENT__SET_DISABLED,
                    getServiceComponentName());
        }

        @Override
        public void writeSessionFlush(int sessionId, ComponentName app, FlushMetrics flushMetrics,
                ContentCaptureOptions options, int flushReason) {
            ContentCaptureMetricsLogger.writeSessionFlush(sessionId, getServiceComponentName(), app,
                    flushMetrics, options, flushReason);
        }
    }
}
