/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package com.android.server.autofill;

import static android.view.autofill.AutofillManager.FLAG_MANUAL_REQUEST;
import static android.view.autofill.AutofillManager.FLAG_START_SESSION;
import static android.view.autofill.AutofillManager.FLAG_VALUE_CHANGED;
import static android.view.autofill.AutofillManager.FLAG_VIEW_ENTERED;
import static android.view.autofill.AutofillManager.FLAG_VIEW_EXITED;

import static com.android.server.autofill.Helper.DEBUG;
import static com.android.server.autofill.Helper.VERBOSE;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.assist.AssistStructure;
import android.app.assist.AssistStructure.AutofillOverlay;
import android.app.assist.AssistStructure.ViewNode;
import android.app.assist.AssistStructure.WindowNode;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.graphics.Rect;
import android.metrics.LogMaker;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcelable;
import android.os.RemoteException;
import android.service.autofill.AutofillService;
import android.service.autofill.Dataset;
import android.service.autofill.FillResponse;
import android.service.autofill.SaveInfo;
import android.util.ArrayMap;
import android.util.DebugUtils;
import android.util.Slog;
import android.view.autofill.AutofillId;
import android.view.autofill.AutofillManager;
import android.view.autofill.AutofillValue;
import android.view.autofill.IAutoFillManagerClient;
import android.view.autofill.IAutofillWindowPresenter;

import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.os.HandlerCaller;
import com.android.server.autofill.ui.AutoFillUI;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Map;
import java.util.Map.Entry;

/**
 * A session for a given activity.
 *
 * <p>This class manages the multiple {@link ViewState}s for each view it has, and keeps track
 * of the current {@link ViewState} to display the appropriate UI.
 *
 * <p>Although the autofill requests and callbacks are stateless from the service's point of
 * view, we need to keep state in the framework side for cases such as authentication. For
 * example, when service return a {@link FillResponse} that contains all the fields needed
 * to fill the activity but it requires authentication first, that response need to be held
 * until the user authenticates or it times out.
 */
// TODO(b/33197203): make sure sessions are removed (and tested by CTS):
// - On all authentication scenarios.
// - When user does not interact back after a while.
// - When service is unbound.
final class Session implements RemoteFillService.FillServiceCallbacks, ViewState.Listener,
        AutoFillUI.AutoFillUiCallback {
    private static final String TAG = "AutofillSession";

    private final AutofillManagerServiceImpl mService;
    private final HandlerCaller mHandlerCaller;
    private final Object mLock;
    private final AutoFillUI mUi;

    private final MetricsLogger mMetricsLogger = new MetricsLogger();

    /** Id of the session */
    public final int id;

    /** uid the session is for */
    public final int uid;

    @GuardedBy("mLock")
    @NonNull private IBinder mActivityToken;

    @GuardedBy("mLock")
    @NonNull private IBinder mWindowToken;

    /** Package name of the app that is auto-filled */
    @NonNull private final String mPackageName;

    @GuardedBy("mLock")
    private final ArrayMap<AutofillId, ViewState> mViewStates = new ArrayMap<>();

    /**
     * Id of the View currently being displayed.
     */
    @GuardedBy("mLock")
    @Nullable private AutofillId mCurrentViewId;

    @GuardedBy("mLock")
    private IAutoFillManagerClient mClient;

    @GuardedBy("mLock")
    RemoteFillService mRemoteFillService;

    @GuardedBy("mLock")
    private ArrayList<FillResponse> mResponses;

    /**
     * Response that requires a service authentitcation request.
     */
    @GuardedBy("mLock")
    private FillResponse mResponseWaitingAuth;

    /**
     * Dataset that when tapped launched a service authentication request.
     */
    @GuardedBy("mLock")
    private Dataset mDatasetWaitingAuth;

    /**
     * Assist structure sent by the app; it will be updated (sanitized, change values for save)
     * before sent to {@link AutofillService}.
     */
    @GuardedBy("mLock")
    private AssistStructure mStructure;

    /**
     * Whether the client has an {@link android.view.autofill.AutofillManager.AutofillCallback}.
     */
    private boolean mHasCallback;

    /**
     * Extras sent by service on {@code onFillRequest()} calls; the first non-null extra is saved
     * and used on subsequent {@code onFillRequest()} and {@code onSaveRequest()} calls.
     */
    @GuardedBy("mLock")
    private Bundle mExtras;

    /**
     * Flags used to start the session.
     */
    int mFlags;

    Session(@NonNull AutofillManagerServiceImpl service, @NonNull AutoFillUI ui,
            @NonNull Context context, @NonNull HandlerCaller handlerCaller, int userId,
            @NonNull Object lock, int sessionId, int uid, @NonNull IBinder activityToken,
            @Nullable IBinder windowToken, @NonNull IBinder client, boolean hasCallback,
            int flags, @NonNull ComponentName componentName, @NonNull String packageName) {
        id = sessionId;
        this.uid = uid;
        mService = service;
        mLock = lock;
        mUi = ui;
        mHandlerCaller = handlerCaller;
        mRemoteFillService = new RemoteFillService(context, componentName, userId, this);
        mActivityToken = activityToken;
        mWindowToken = windowToken;
        mHasCallback = hasCallback;
        mPackageName = packageName;
        mFlags = flags;
        mClient = IAutoFillManagerClient.Stub.asInterface(client);

        mMetricsLogger.action(MetricsEvent.AUTOFILL_SESSION_STARTED, mPackageName);
    }

    /**
     * Gets the currently registered activity token
     *
     * @return The activity token
     */
    public IBinder getActivityTokenLocked() {
        return mActivityToken;
    }

    /**
     * Sets new window  for this session.
     *
     * @param newWindow The window the Ui should be attached to. Can be {@code null} if no
     *                  further UI is needed.
     */
    void switchWindow(@NonNull IBinder newWindow) {
        synchronized (mLock) {
            mWindowToken = newWindow;
        }
    }

    /**
     * Sets new activity and client for this session.
     *
     * @param newActivity The token of the new activity
     * @param newClient The client receiving autofill callbacks
     */
    void switchActivity(@NonNull IBinder newActivity, @NonNull IBinder newClient) {
        synchronized (mLock) {
            mActivityToken = newActivity;
            mClient = IAutoFillManagerClient.Stub.asInterface(newClient);
        }
    }

    // FillServiceCallbacks
    @Override
    public void onFillRequestSuccess(@Nullable FillResponse response,
            @NonNull String servicePackageName) {
        if (response == null) {
            if ((mFlags & FLAG_MANUAL_REQUEST) != 0) {
                getUiForShowing().showError(R.string.autofill_error_cannot_autofill);
            }
            // Nothing to be done, but need to notify client.
            notifyUnavailableToClient();
            removeSelf();
            return;
        }

        if ((response.getDatasets() == null || response.getDatasets().isEmpty())
                        && response.getAuthentication() == null) {
            // Response is "empty" from an UI point of view, need to notify client.
            notifyUnavailableToClient();
        }
        synchronized (mLock) {
            if (response.getAuthentication() != null) {
                // TODO(b/33197203 , b/35707731): make sure it's ignored if there is one already
                mResponseWaitingAuth = response;
            }
            processResponseLocked(response);
        }

        final LogMaker log = (new LogMaker(MetricsEvent.AUTOFILL_REQUEST))
                .setType(MetricsEvent.TYPE_SUCCESS)
                .setPackageName(mPackageName)
                .addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_DATASETS,
                        response.getDatasets() == null ? 0 : response.getDatasets().size())
                .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SERVICE,
                        servicePackageName);
        mMetricsLogger.write(log);
    }

    // FillServiceCallbacks
    @Override
    public void onFillRequestFailure(@Nullable CharSequence message,
            @NonNull String servicePackageName) {
        LogMaker log = (new LogMaker(MetricsEvent.AUTOFILL_REQUEST))
                .setType(MetricsEvent.TYPE_FAILURE)
                .setPackageName(mPackageName)
                .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SERVICE, servicePackageName);
        mMetricsLogger.write(log);

        getUiForShowing().showError(message);
        removeSelf();
    }

    // FillServiceCallbacks
    @Override
    public void onSaveRequestSuccess(@NonNull String servicePackageName) {
        LogMaker log = (new LogMaker(
                MetricsEvent.AUTOFILL_DATA_SAVE_REQUEST))
                .setType(MetricsEvent.TYPE_SUCCESS)
                .setPackageName(mPackageName)
                .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SERVICE, servicePackageName);
        mMetricsLogger.write(log);

        // Nothing left to do...
        removeSelf();
    }

    // FillServiceCallbacks
    @Override
    public void onSaveRequestFailure(@Nullable CharSequence message,
            @NonNull String servicePackageName) {
        LogMaker log = (new LogMaker(
                MetricsEvent.AUTOFILL_DATA_SAVE_REQUEST))
                .setType(MetricsEvent.TYPE_FAILURE)
                .setPackageName(mPackageName)
                .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SERVICE, servicePackageName);
        mMetricsLogger.write(log);

        getUiForShowing().showError(message);
        removeSelf();
    }

    // FillServiceCallbacks
    @Override
    public void authenticate(IntentSender intent, Bundle extras) {
        final Intent fillInIntent;
        synchronized (mLock) {
            fillInIntent = createAuthFillInIntent(mStructure, extras);
        }
        mHandlerCaller.getHandler().post(() -> startAuthentication(intent, fillInIntent));
    }

    // FillServiceCallbacks
    @Override
    public void onServiceDied(RemoteFillService service) {
        // TODO(b/33197203): implement
    }

    // AutoFillUiCallback
    @Override
    public void fill(Dataset dataset) {
        mHandlerCaller.getHandler().post(() -> autoFill(dataset));
    }

    // AutoFillUiCallback
    @Override
    public void save() {
        mHandlerCaller.getHandler()
                .obtainMessage(AutofillManagerServiceImpl.MSG_SERVICE_SAVE, id, 0)
                .sendToTarget();
    }

    // AutoFillUiCallback
    @Override
    public void cancelSave() {
        mHandlerCaller.getHandler().post(() -> removeSelf());
    }

    // AutoFillUiCallback
    @Override
    public void requestShowFillUi(AutofillId id, int width, int height,
            IAutofillWindowPresenter presenter) {
        synchronized (mLock) {
            if (id.equals(mCurrentViewId)) {
                try {
                    final ViewState view = mViewStates.get(id);
                    mClient.requestShowFillUi(mWindowToken, id, width, height,
                            view.getVirtualBounds(),
                            presenter);
                } catch (RemoteException e) {
                    Slog.e(TAG, "Error requesting to show fill UI", e);
                }
            } else {
                if (DEBUG) {
                    Slog.d(TAG, "Do not show full UI on " + id + " as it is not the current view ("
                            + mCurrentViewId + ") anymore");
                }
            }
        }
    }

    // AutoFillUiCallback
    @Override
    public void requestHideFillUi(AutofillId id) {
        synchronized (mLock) {
            try {
                mClient.requestHideFillUi(mWindowToken, id);
            } catch (RemoteException e) {
                Slog.e(TAG, "Error requesting to hide fill UI", e);
            }
        }
    }

    public void setAuthenticationResultLocked(Bundle data) {
        if ((mResponseWaitingAuth == null && mDatasetWaitingAuth == null) || data == null) {
            removeSelf();
        } else {
            final Parcelable result = data.getParcelable(
                    AutofillManager.EXTRA_AUTHENTICATION_RESULT);
            if (result instanceof FillResponse) {
                mMetricsLogger.action(MetricsEvent.AUTOFILL_AUTHENTICATED, mPackageName);
                mResponseWaitingAuth = null;
                processResponseLocked((FillResponse) result);
            } else if (result instanceof Dataset) {
                final Dataset dataset = (Dataset) result;
                for (int i = 0; i < mResponses.size(); i++) {
                    final FillResponse response = mResponses.get(i);
                    final int index = response.getDatasets().indexOf(mDatasetWaitingAuth);
                    if (index >= 0) {
                        response.getDatasets().set(index, dataset);
                        mDatasetWaitingAuth = null;
                        autoFill(dataset);
                        resetViewStatesLocked(dataset, ViewState.STATE_WAITING_DATASET_AUTH);
                        return;
                    }
                }
            }
        }
    }

    public void setHasCallback(boolean hasIt) {
        mHasCallback = hasIt;
    }

    public void setStructureLocked(AssistStructure structure) {
        mStructure = structure;
    }

    /**
     * Shows the save UI, when session can be saved.
     *
     * @return {@code true} if session is done, or {@code false} if it's pending user action.
     */
    public boolean showSaveLocked() {
        if (mStructure == null) {
            Slog.wtf(TAG, "showSaveLocked(): no mStructure");
            return true;
        }
        if (mResponses == null) {
            // Happens when the activity / session was finished before the service replied, or
            // when the service cannot autofill it (and returned a null response).
            if (DEBUG) {
                Slog.d(TAG, "showSaveLocked(): no responses on session");
            }
            return true;
        }

        final FillResponse response = mResponses.get(mResponses.size() - 1);

        final SaveInfo saveInfo = response.getSaveInfo();
        if (DEBUG) {
            Slog.d(TAG,
                    "showSaveLocked(): mResponses=" + mResponses + ", mViewStates=" + mViewStates);
        }

        /*
         * The Save dialog is only shown if all conditions below are met:
         *
         * - saveInfo is not null
         * - autofillValue of all required ids is not null
         * - autofillValue of at least one id (required or optional) has changed.
         */

        if (saveInfo == null) {
            return true;
        }

        final AutofillId[] requiredIds = saveInfo.getRequiredIds();
        if (requiredIds == null || requiredIds.length == 0) {
            Slog.w(TAG, "showSaveLocked(): no required ids on saveInfo");
            return true;
        }

        boolean allRequiredAreNotEmpty = true;
        boolean atLeastOneChanged = false;
        for (int i = 0; i < requiredIds.length; i++) {
            final AutofillId id = requiredIds[i];
            final ViewState viewState = mViewStates.get(id);
            if (viewState == null) {
                Slog.w(TAG, "showSaveLocked(): no ViewState for required " + id);
                allRequiredAreNotEmpty = false;
                break;
            }

            final AutofillValue currentValue = viewState.getCurrentValue();
            if (currentValue == null || currentValue.isEmpty()) {
                if (DEBUG) {
                    Slog.d(TAG, "showSaveLocked(): empty value for required " + id );
                }
                allRequiredAreNotEmpty = false;
                break;
            }
            final AutofillValue filledValue = viewState.getAutofilledValue();

            if (!currentValue.equals(filledValue)) {
                if (DEBUG) {
                    Slog.d(TAG, "showSaveLocked(): found a change on required " + id + ": "
                            + filledValue + " => " + currentValue);
                }
                atLeastOneChanged = true;
            }
        }

        final AutofillId[] optionalIds = saveInfo.getOptionalIds();
        if (allRequiredAreNotEmpty) {
            if (!atLeastOneChanged && optionalIds != null) {
                // No change on required ids yet, look for changes on optional ids.
                for (int i = 0; i < optionalIds.length; i++) {
                    final AutofillId id = optionalIds[i];
                    final ViewState viewState = mViewStates.get(id);
                    if (viewState == null) {
                        Slog.w(TAG, "showSaveLocked(): no ViewState for optional " + id);
                        continue;
                    }
                    if ((viewState.getState() & ViewState.STATE_CHANGED) != 0) {
                        final AutofillValue currentValue = viewState.getCurrentValue();
                        final AutofillValue filledValue = viewState.getAutofilledValue();
                        if (currentValue != null && !currentValue.equals(filledValue)) {
                            if (DEBUG) {
                                Slog.d(TAG, "finishSessionLocked(): found a change on optional "
                                        + id + ": " + filledValue + " => " + currentValue);
                            }
                            atLeastOneChanged = true;
                            break;
                        }
                    }
                }
            }
            if (atLeastOneChanged) {
                getUiForShowing().showSaveUi(mService.getServiceLabel(), saveInfo, mPackageName);
                return false;
            }
        }
        // Nothing changed...
        if (DEBUG) {
            Slog.d(TAG, "showSaveLocked(): with no changes, comes no responsibilities."
                    + "allRequiredAreNotNull=" + allRequiredAreNotEmpty
                    + ", atLeastOneChanged=" + atLeastOneChanged);
        }
        return true;
    }

    /**
     * Calls service when user requested save.
     */
    void callSaveLocked() {
        if (DEBUG) {
            Slog.d(TAG, "callSaveLocked(): mViewStates=" + mViewStates);
        }

        for (Entry<AutofillId, ViewState> entry : mViewStates.entrySet()) {
            final AutofillValue value = entry.getValue().getCurrentValue();
            if (value == null) {
                if (VERBOSE) {
                    Slog.v(TAG, "callSaveLocked(): skipping " + entry.getKey());
                }
                continue;
            }
            final AutofillId id = entry.getKey();
            final ViewNode node = findViewNodeByIdLocked(id);
            if (node == null) {
                Slog.w(TAG, "callSaveLocked(): did not find node with id " + id);
                continue;
            }
            if (VERBOSE) {
                Slog.v(TAG, "callSaveLocked(): updating " + id + " to " + value);
            }

            node.updateAutofillValue(value);
        }

        // Sanitize structure before it's sent to service.
        mStructure.sanitizeForParceling(false);

        if (VERBOSE) {
            Slog.v(TAG, "Dumping " + mStructure + " before calling service.save()");
            mStructure.dump();
        }

        mRemoteFillService.onSaveRequest(mStructure, mExtras);
    }

    void updateLocked(AutofillId id, Rect virtualBounds, AutofillValue value, int flags) {
        ViewState viewState = mViewStates.get(id);

        if (viewState == null) {
            if ((flags & (FLAG_START_SESSION | FLAG_VALUE_CHANGED)) != 0) {
                if (DEBUG) {
                    Slog.d(TAG, "Creating viewState for " + id + " on " + getFlagAsString(flags));
                }
                viewState = new ViewState(this, id, value, this, ViewState.STATE_INITIAL);
                mViewStates.put(id, viewState);
            } else if (mStructure != null && (flags & FLAG_VIEW_ENTERED) != 0) {
                viewState = startPartitionLocked(id, value);
            } else {
                if (VERBOSE) Slog.v(TAG, "Ignored " + getFlagAsString(flags) + " for " + id);
                return;
            }
        }

        if ((flags & FLAG_START_SESSION) != 0) {
            // View is triggering autofill.
            mCurrentViewId = viewState.id;
            viewState.update(value, virtualBounds);
            viewState.setState(ViewState.STATE_STARTED_SESSION);
            return;
        }

        if ((flags & FLAG_VALUE_CHANGED) != 0) {
            if (value != null && !value.equals(viewState.getCurrentValue())) {
                // Always update the internal state.
                viewState.setCurrentValue(value);

                // Must check if this update was caused by autofilling the view, in which
                // case we just update the value, but not the UI.
                final AutofillValue filledValue = viewState.getAutofilledValue();
                if (value.equals(filledValue)) {
                    return;
                }
                // Update the internal state...
                viewState.setState(ViewState.STATE_CHANGED);

                //..and the UI
                if (value.isText()) {
                    getUiForShowing().filterFillUi(value.getTextValue().toString());
                } else {
                    getUiForShowing().filterFillUi(null);
                }
            }

            return;
        }

        if ((flags & FLAG_VIEW_ENTERED) != 0) {
            // Remove the UI if the ViewState has changed.
            if (mCurrentViewId != viewState.id) {
                mUi.hideFillUi(mCurrentViewId != null ? mCurrentViewId : null);
                mCurrentViewId = viewState.id;
            }

            // If the ViewState is ready to be displayed, onReady() will be called.
            viewState.update(value, virtualBounds);

            return;
        }

        if ((flags & FLAG_VIEW_EXITED) != 0) {
            if (mCurrentViewId == viewState.id) {
                mUi.hideFillUi(viewState.id);
                mCurrentViewId = null;
            }
            return;
        }

        Slog.w(TAG, "updateLocked(): unknown flags " + flags + ": " + getFlagAsString(flags));
    }

    private ViewState startPartitionLocked(AutofillId id, AutofillValue value) {
        // TODO(b/33197203 , b/35707731): temporary workaround until partitioning supports auth
        if (mResponseWaitingAuth != null) {
            final ViewState viewState =
                    new ViewState(this, id, value, this, ViewState.STATE_WAITING_RESPONSE_AUTH);
            mViewStates.put(id, viewState);
            return viewState;
        }
        if (DEBUG) {
            Slog.d(TAG, "Starting partition for view id " + id);
        }
        final ViewState newViewState =
                new ViewState(this, id, value, this,ViewState.STATE_STARTED_PARTITION);
        mViewStates.put(id, newViewState);

        // Must update value of nodes so:
        // - proper node is focused
        // - autofillValue is sent back to service when it was previously autofilled
        for (int i = 0; i < mViewStates.size(); i++) {
            final ViewState viewState = mViewStates.valueAt(i);

            final ViewNode node = findViewNodeByIdLocked(viewState.id);
            if (node == null) {
                Slog.w(TAG, "startPartitionLocked(): no node for " + viewState.id);
                continue;
            }

            final AutofillValue initialValue = viewState.getInitialValue();
            final AutofillValue filledValue = viewState.getAutofilledValue();
            final AutofillOverlay overlay = new AutofillOverlay();
            if (filledValue != null && !filledValue.equals(initialValue)) {
                overlay.value = filledValue;
            }
            overlay.focused = id.equals(viewState.id);
            node.setAutofillOverlay(overlay);
        }
        mRemoteFillService.onFillRequest(mStructure, mExtras, 0);

        return newViewState;
    }

    @Override
    public void onFillReady(FillResponse response, AutofillId filledId,
            @Nullable AutofillValue value) {
        String filterText = null;
        if (value != null && value.isText()) {
            filterText = value.getTextValue().toString();
        }

        getUiForShowing().showFillUi(filledId, response, filterText, mPackageName);
    }

    String getFlagAsString(int flag) {
        return DebugUtils.flagsToString(AutofillManager.class, "FLAG_", flag);
    }

    private void notifyUnavailableToClient() {
        synchronized (mLock) {
            if (mCurrentViewId == null) {
                // TODO(b/33197203): temporary sanity check; should never happen
                Slog.w(TAG, "notifyUnavailable(): mCurrentViewId is null");
                return;
            }
            if (!mHasCallback) return;
            try {
                mClient.notifyNoFillUi(mWindowToken, mCurrentViewId);
            } catch (RemoteException e) {
                Slog.e(TAG, "Error notifying client no fill UI: windowToken=" + mWindowToken
                        + " id=" + mCurrentViewId, e);
            }
        }
    }

    private void processResponseLocked(FillResponse response) {
        if (DEBUG) {
            Slog.d(TAG, "processResponseLocked(mCurrentViewId=" + mCurrentViewId + "):" + response);
        }

        if (mResponses == null) {
            mResponses = new ArrayList<>(4);
        }
        mResponses.add(response);
        if (response != null) {
            mExtras = response.getExtras();
        }

        setViewStatesLocked(response, ViewState.STATE_FILLABLE);

        if (mCurrentViewId == null) {
            return;
        }

        if ((mFlags & FLAG_MANUAL_REQUEST) != 0 && response.getDatasets() != null
                && response.getDatasets().size() == 1) {
            Slog.d(TAG, "autofilling manual request directly");
            autoFill(response.getDatasets().get(0));
            return;
        }

        // Updates the UI, if necessary.
        final ViewState currentView = mViewStates.get(mCurrentViewId);
        currentView.maybeCallOnFillReady();
    }

    /**
     * Sets the state of all views in the given response.
     */
    private void setViewStatesLocked(FillResponse response, int state) {
        final ArrayList<Dataset> datasets = response.getDatasets();
        if (datasets != null) {
            for (int i = 0; i < datasets.size(); i++) {
                final Dataset dataset = datasets.get(i);
                if (dataset == null) {
                    Slog.w(TAG, "Ignoring null dataset on " + datasets);
                    continue;
                }
                setViewStatesLocked(response, dataset, state);
            }
        }
    }

    /**
     * Sets the state of all views in the given dataset and response.
     */
    private void setViewStatesLocked(@Nullable FillResponse response, @NonNull Dataset dataset,
            int state) {
        final ArrayList<AutofillId> ids = dataset.getFieldIds();
        final ArrayList<AutofillValue> values = dataset.getFieldValues();
        for (int j = 0; j < ids.size(); j++) {
            final AutofillId id = ids.get(j);
            ViewState viewState = mViewStates.get(id);
            if (viewState != null)  {
                viewState.setState(state);
            } else {
                viewState = new ViewState(this, id, null, this, state);
                if (DEBUG) { // TODO(b/33197203): change to VERBOSE once stable
                    Slog.d(TAG, "Adding autofillable view with id " + id + " and state " + state);
                }
                mViewStates.put(id, viewState);
            }
            if ((state & ViewState.STATE_AUTOFILLED) != 0) {
                viewState.setAutofilledValue(values.get(j));
            }

            if (response != null) {
                viewState.setResponse(response);
            }
        }
    }

    /**
     * Resets the given state from all existing views in the given dataset.
     */
    private void resetViewStatesLocked(@NonNull Dataset dataset, int state) {
        final ArrayList<AutofillId> ids = dataset.getFieldIds();
        for (int j = 0; j < ids.size(); j++) {
            final AutofillId id = ids.get(j);
            final ViewState viewState = mViewStates.get(id);
            if (viewState != null)  {
                viewState.resetState(state);
            }
        }
    }

    void autoFill(Dataset dataset) {
        synchronized (mLock) {
            // Autofill it directly...
            if (dataset.getAuthentication() == null) {
                autoFillApp(dataset);
                return;
            }

            // ...or handle authentication.
            // TODO(b/33197203 , b/35707731): make sure it's ignored if there is one already
            mDatasetWaitingAuth = dataset;
            setViewStatesLocked(null, dataset, ViewState.STATE_WAITING_DATASET_AUTH);
            final Intent fillInIntent = createAuthFillInIntent(mStructure, null);
            startAuthentication(dataset.getAuthentication(), fillInIntent);
        }
    }

    CharSequence getServiceName() {
        return mService.getServiceName();
    }

    FillResponse getResponseWaitingAuth() {
        return mResponseWaitingAuth;
    }

    private Intent createAuthFillInIntent(AssistStructure structure, Bundle extras) {
        final Intent fillInIntent = new Intent();
        fillInIntent.putExtra(AutofillManager.EXTRA_ASSIST_STRUCTURE, structure);
        if (extras != null) {
            fillInIntent.putExtra(AutofillManager.EXTRA_DATA_EXTRAS, extras);
        }
        return fillInIntent;
    }

    private void startAuthentication(IntentSender intent, Intent fillInIntent) {
        try {
            synchronized (mLock) {
                mClient.authenticate(intent, fillInIntent);
            }
        } catch (RemoteException e) {
            Slog.e(TAG, "Error launching auth intent", e);
        }
    }

    void dumpLocked(String prefix, PrintWriter pw) {
        pw.print(prefix); pw.print("id: "); pw.println(id);
        pw.print(prefix); pw.print("uid: "); pw.println(uid);
        pw.print(prefix); pw.print("mActivityToken: "); pw.println(mActivityToken);
        pw.print(prefix); pw.print("mFlags: "); pw.println(mFlags);
        pw.print(prefix); pw.print("mResponses: "); pw.println(mResponses);
        pw.print(prefix); pw.print("mResponseWaitingAuth: "); pw.println(mResponseWaitingAuth);
        pw.print(prefix); pw.print("mDatasetWaitingAuth: "); pw.println(mDatasetWaitingAuth);
        pw.print(prefix); pw.print("mCurrentViewId: "); pw.println(mCurrentViewId);
        pw.print(prefix); pw.print("mViewStates size: "); pw.println(mViewStates.size());
        final String prefix2 = prefix + "  ";
        for (Map.Entry<AutofillId, ViewState> entry : mViewStates.entrySet()) {
            pw.print(prefix); pw.print("State for id "); pw.println(entry.getKey());
            entry.getValue().dump(prefix2, pw);
        }
        if (VERBOSE) {
            pw.print(prefix); pw.print("mStructure: " );
            // TODO(b/33197203): add method do dump AssistStructure on pw
            if (mStructure != null) {
                pw.println("look at logcat" );
                mStructure.dump(); // dumps to logcat
            } else {
                pw.println("null");
            }
        }
        pw.print(prefix); pw.print("mHasCallback: "); pw.println(mHasCallback);
        pw.print(prefix); pw.print("mExtras: "); pw.println(Helper.bundleToString(mExtras));
        mRemoteFillService.dump(prefix, pw);
    }

    void autoFillApp(Dataset dataset) {
        synchronized (mLock) {
            try {
                if (DEBUG) {
                    Slog.d(TAG, "autoFillApp(): the buck is on the app: " + dataset);
                }
                mClient.autofill(mWindowToken, dataset.getFieldIds(), dataset.getFieldValues());
                setViewStatesLocked(null, dataset, ViewState.STATE_AUTOFILLED);
            } catch (RemoteException e) {
                Slog.w(TAG, "Error autofilling activity: " + e);
            }
        }
    }

    private AutoFillUI getUiForShowing() {
        synchronized (mLock) {
            mUi.setCallback(this);
            return mUi;
        }
    }

    private ViewNode findViewNodeByIdLocked(AutofillId id) {
        final int size = mStructure.getWindowNodeCount();
        for (int i = 0; i < size; i++) {
            final WindowNode window = mStructure.getWindowNodeAt(i);
            final ViewNode root = window.getRootViewNode();
            if (id.equals(root.getAutofillId())) {
                return root;
            }
            final ViewNode child = findViewNodeByIdLocked(root, id);
            if (child != null) {
                return child;
            }
        }
        return null;
    }

    private ViewNode findViewNodeByIdLocked(ViewNode parent, AutofillId id) {
        final int childrenSize = parent.getChildCount();
        if (childrenSize > 0) {
            for (int i = 0; i < childrenSize; i++) {
                final ViewNode child = parent.getChildAt(i);
                if (id.equals(child.getAutofillId())) {
                    return child;
                }
                final ViewNode grandChild = findViewNodeByIdLocked(child, id);
                if (grandChild != null && id.equals(grandChild.getAutofillId())) {
                    return grandChild;
                }
            }
        }
        return null;
    }

    void destroyLocked() {
        mRemoteFillService.destroy();
        mUi.setCallback(null);
        mMetricsLogger.action(MetricsEvent.AUTOFILL_SESSION_FINISHED, mPackageName);
    }

    void removeSelf() {
        synchronized (mLock) {
            removeSelfLocked();
        }
    }

    void removeSelfLocked() {
        if (VERBOSE) {
            Slog.v(TAG, "removeSelfLocked()");
        }
        destroyLocked();
        mService.removeSessionLocked(id);
    }
}
