chromium/components/android_autofill/browser/test_support/java/src/org/chromium/components/autofill/TestViewStructure.java

// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.components.autofill;

import android.graphics.Matrix;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.LocaleList;
import android.os.Parcel;
import android.util.Pair;
import android.view.View;
import android.view.ViewStructure;
import android.view.autofill.AutofillId;
import android.view.autofill.AutofillValue;

import java.util.ArrayList;
import java.util.List;

/** This class only implements the necessary methods of ViewStructure for testing. */
public class TestViewStructure extends ViewStructure {
    /** Test implementation of {@link HtmlInfo}. */
    public static class TestHtmlInfo extends HtmlInfo {
        private String mTag;
        private List<Pair<String, String>> mAttributes;

        public TestHtmlInfo(String tag, List<Pair<String, String>> attributes) {
            mTag = tag;
            mAttributes = attributes;
        }

        @Override
        public List<Pair<String, String>> getAttributes() {
            return mAttributes;
        }

        public String getAttribute(String attribute) {
            for (Pair<String, String> pair : mAttributes) {
                if (attribute.equals(pair.first)) {
                    return pair.second;
                }
            }
            return null;
        }

        @Override
        public String getTag() {
            return mTag;
        }
    }

    /** Test implementation of {@link HtmlInfo.Builder}. */
    public static class TestBuilder extends HtmlInfo.Builder {
        private String mTag;
        private ArrayList<Pair<String, String>> mAttributes;

        public TestBuilder(String tag) {
            mTag = tag;
            mAttributes = new ArrayList<Pair<String, String>>();
        }

        @Override
        public HtmlInfo.Builder addAttribute(String name, String value) {
            mAttributes.add(new Pair<String, String>(name, value));
            return this;
        }

        @Override
        public HtmlInfo build() {
            return new TestHtmlInfo(mTag, mAttributes);
        }
    }

    public TestViewStructure() {
        mChildren = new ArrayList<TestViewStructure>();
    }

    @Override
    public void setAlpha(float alpha) {}

    @Override
    public void setAccessibilityFocused(boolean state) {}

    @Override
    public void setCheckable(boolean state) {}

    @Override
    public void setChecked(boolean state) {
        mChecked = state;
    }

    public boolean getChecked() {
        return mChecked;
    }

    @Override
    public void setActivated(boolean state) {}

    @Override
    public CharSequence getText() {
        return null;
    }

    @Override
    public int getTextSelectionStart() {
        return 0;
    }

    @Override
    public int getTextSelectionEnd() {
        return 0;
    }

    @Override
    public CharSequence getHint() {
        return mHint;
    }

    @Override
    public Bundle getExtras() {
        if (mBundle == null) mBundle = new Bundle();
        return mBundle;
    }

    @Override
    public boolean hasExtras() {
        return mBundle != null;
    }

    @Override
    public void setChildCount(int num) {}

    @Override
    public int addChildCount(int num) {
        int index = mChildCount;
        mChildCount += num;
        mChildren.ensureCapacity(mChildCount);
        return index;
    }

    @Override
    public int getChildCount() {
        return mChildren.size();
    }

    @Override
    public ViewStructure newChild(int index) {
        TestViewStructure viewStructure = new TestViewStructure();
        if (index < mChildren.size()) {
            mChildren.set(index, viewStructure);
        } else if (index == mChildren.size()) {
            mChildren.add(viewStructure);
        } else {
            // Failed intentionally, we shouldn't run into this case.
            mChildren.add(index, viewStructure);
        }
        return viewStructure;
    }

    public TestViewStructure getChild(int index) {
        return mChildren.get(index);
    }

    @Override
    public ViewStructure asyncNewChild(int index) {
        return null;
    }

    @Override
    public void asyncCommit() {}

    @Override
    public AutofillId getAutofillId() {
        // Check AutofillId.java for more information:
        // https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/view/autofill/AutofillId.java
        Parcel parcel = Parcel.obtain();
        // The host View - set to 0 by default.
        parcel.writeInt(0);
        // Corresponds to FLAG_IS_VIRTUAL_INT and indicates that the virtual id
        // that comes next is an int.
        parcel.writeInt(1);
        // The actual virtual id.
        parcel.writeInt(mId);
        parcel.setDataPosition(0);

        return AutofillId.CREATOR.createFromParcel(parcel);
    }

    @Override
    public HtmlInfo.Builder newHtmlInfoBuilder(String tag) {
        return new TestBuilder(tag);
    }

    @Override
    public void setAutofillHints(String[] arg0) {
        mAutofillHints = arg0.clone();
    }

    public String[] getAutofillHints() {
        if (mAutofillHints == null) return null;
        return mAutofillHints.clone();
    }

    @Override
    public void setAutofillId(AutofillId arg0) {}

    @Override
    public void setAutofillId(AutofillId arg0, int arg1) {
        mId = arg1;
    }

    public int getId() {
        return mId;
    }

    @Override
    public void setAutofillOptions(CharSequence[] arg0) {
        mAutofillOptions = arg0.clone();
    }

    public CharSequence[] getAutofillOptions() {
        if (mAutofillOptions == null) return null;
        return mAutofillOptions.clone();
    }

    @Override
    public void setAutofillType(int arg0) {
        mAutofillType = arg0;
    }

    public int getAutofillType() {
        return mAutofillType;
    }

    @Override
    public void setAutofillValue(AutofillValue arg0) {
        mAutofillValue = arg0;
    }

    public AutofillValue getAutofillValue() {
        return mAutofillValue;
    }

    @Override
    public void setId(int id, String packageName, String typeName, String entryName) {}

    @Override
    public void setDimens(int left, int top, int scrollX, int scrollY, int width, int height) {
        mDimensRect = new Rect(left, top, width + left, height + top);
        mDimensScrollX = scrollX;
        mDimensScrollY = scrollY;
    }

    public Rect getDimensRect() {
        return mDimensRect;
    }

    public int getDimensScrollX() {
        return mDimensScrollX;
    }

    public int getDimensScrollY() {
        return mDimensScrollY;
    }

    @Override
    public void setElevation(float elevation) {}

    @Override
    public void setEnabled(boolean state) {}

    @Override
    public void setClickable(boolean state) {}

    @Override
    public void setLongClickable(boolean state) {}

    @Override
    public void setContextClickable(boolean state) {}

    @Override
    public void setFocusable(boolean state) {}

    @Override
    public void setFocused(boolean state) {
        mFocused = state;
    }

    public boolean getFocused() {
        return mFocused;
    }

    @Override
    public void setClassName(String className) {
        mClassName = className;
    }

    public String getClassName() {
        return mClassName;
    }

    @Override
    public void setContentDescription(CharSequence contentDescription) {}

    @Override
    public void setDataIsSensitive(boolean arg0) {
        mDataIsSensitive = arg0;
    }

    public boolean getDataIsSensitive() {
        return mDataIsSensitive;
    }

    @Override
    public void setHint(CharSequence hint) {
        mHint = hint;
    }

    @Override
    public void setHtmlInfo(HtmlInfo arg0) {
        mHtmlInfo = (TestHtmlInfo) arg0;
    }

    public TestHtmlInfo getHtmlInfo() {
        return mHtmlInfo;
    }

    @Override
    public void setInputType(int arg0) {}

    @Override
    public void setLocaleList(LocaleList arg0) {}

    @Override
    public void setOpaque(boolean arg0) {}

    @Override
    public void setTransformation(Matrix matrix) {}

    @Override
    public void setVisibility(int visibility) {
        mVisibility = visibility;
    }

    public int getVisibility() {
        return mVisibility;
    }

    @Override
    public void setSelected(boolean state) {}

    @Override
    public void setText(CharSequence text) {}

    @Override
    public void setText(CharSequence text, int selectionStart, int selectionEnd) {}

    @Override
    public void setTextStyle(float size, int fgColor, int bgColor, int style) {}

    @Override
    public void setTextLines(int[] charOffsets, int[] baselines) {}

    @Override
    public void setWebDomain(String webDomain) {
        mWebDomain = webDomain;
    }

    public String getWebDomain() {
        return mWebDomain;
    }

    private int mAutofillType;
    private CharSequence mHint;
    private String[] mAutofillHints;
    private int mId;
    private boolean mFocused;
    private String mClassName;
    private String mWebDomain;
    private int mChildCount;
    private ArrayList<TestViewStructure> mChildren;
    private CharSequence[] mAutofillOptions;
    private AutofillValue mAutofillValue;
    private boolean mDataIsSensitive;
    private TestHtmlInfo mHtmlInfo;
    private boolean mChecked;
    private Rect mDimensRect;
    private int mDimensScrollX;
    private int mDimensScrollY;
    private Bundle mBundle;
    // Initializes to the value AutofillProvider will never use.
    private int mVisibility = View.GONE;
}