Atest plugin: link the test target with fast input checkboxes

Bug: 149261743
Test: 1. In atest_plugin folder: ./gradlew :runIde
      2. In atest ToolWindow -> select the Run on host checkbox:
         current test command will append " --host".
      3. Unselect the Run on host checkbox:
         current test command will delete " --host".
      4. Append " --host" in test command:
         the Run on host checkbox will be selected.
      5. Delete " --host" in test command:
         the Run on host checkbox will be unselected.
Change-Id: Icc1902d393c6c043fbcf664b67c90424f0ecdc00
diff --git a/asuite_plugin/src/java/com/android/atest/toolWindow/AtestToolWindow.java b/asuite_plugin/src/java/com/android/atest/toolWindow/AtestToolWindow.java
index f5a6a82..5f8fd34 100644
--- a/asuite_plugin/src/java/com/android/atest/toolWindow/AtestToolWindow.java
+++ b/asuite_plugin/src/java/com/android/atest/toolWindow/AtestToolWindow.java
@@ -19,6 +19,7 @@
 import com.android.atest.Constants;
 import com.android.atest.commandAdapter.CommandRunner;
 import com.android.atest.dialog.MessageDialog;
+import com.android.atest.widget.AtestFastInputController;
 import com.android.atest.widget.AtestNotification;
 import com.intellij.notification.Notifications;
 import com.intellij.openapi.diagnostic.Logger;
@@ -60,6 +61,9 @@
         setInitialWidth((ToolWindowEx) toolWindow);
         setRunButton(basePath);
         initTestTarget(basePath);
+        AtestFastInputController fastInputController =
+                new AtestFastInputController(mTestTarget, mRunOnHost, mTestMapping, mSkipBuild);
+        fastInputController.linkCheckBoxWithTestTarget();
         mAtestOutput.setMargin(new Insets(0, 10, 0, 0));
     }
 
diff --git a/asuite_plugin/src/java/com/android/atest/widget/AtestFastInputController.java b/asuite_plugin/src/java/com/android/atest/widget/AtestFastInputController.java
new file mode 100644
index 0000000..3893ce6
--- /dev/null
+++ b/asuite_plugin/src/java/com/android/atest/widget/AtestFastInputController.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2020 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.atest.widget;
+
+import javax.swing.*;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.text.JTextComponent;
+
+/** A controller for Atest target with checkboxes. */
+public class AtestFastInputController {
+
+    public static final String RUN_ON_HOST_POST = " --host";
+    public static final String TEST_MAPPING_POST = " --test-mapping";
+    public static final String SKIP_BUILD_POST = " -it";
+    private JComboBox mTestTarget;
+    private JCheckBox mRunOnHost;
+    private JCheckBox mTestMapping;
+    private JCheckBox mSkipBuild;
+
+    /**
+     * Initializes the UI components.
+     *
+     * @param testTarget a JComboBox used to input test command.
+     * @param runOnHost a JCheckBox used to turn on/off run on host.
+     * @param testMapping a JCheckBox used to turn on/off test mapping.
+     * @param skipBuild a JCheckBox used to turn on/off skip build.
+     */
+    public AtestFastInputController(
+            JComboBox testTarget, JCheckBox runOnHost, JCheckBox testMapping, JCheckBox skipBuild) {
+        mTestTarget = testTarget;
+        mRunOnHost = runOnHost;
+        mTestMapping = testMapping;
+        mSkipBuild = skipBuild;
+    }
+    /**
+     * Links all checkbox to test target.
+     *
+     * <p>e.g. if users select run on host check box, the test target appends --host. if users type
+     * "--host" in test target, the run on host check box is selected.
+     */
+    public void linkCheckBoxWithTestTarget() {
+        mRunOnHost.addActionListener(e -> setCheckbox(mRunOnHost, RUN_ON_HOST_POST));
+        mTestMapping.addActionListener(e -> setCheckbox(mTestMapping, TEST_MAPPING_POST));
+        mSkipBuild.addActionListener(e -> setCheckbox(mSkipBuild, SKIP_BUILD_POST));
+        final JTextComponent tc = (JTextComponent) mTestTarget.getEditor().getEditorComponent();
+        tc.getDocument()
+                .addDocumentListener(
+                        new DocumentListener() {
+
+                            /**
+                             * Gives notification that there was an insert into the document. The
+                             * range given by the DocumentEvent bounds the freshly inserted region.
+                             *
+                             * @param e the document event
+                             */
+                            @Override
+                            public void insertUpdate(DocumentEvent e) {
+                                checkAllTestTarget();
+                            }
+
+                            /**
+                             * Gives notification that a portion of the document has been removed.
+                             * The range is given in terms of what the view last saw (that is,
+                             * before updating sticky positions).
+                             *
+                             * @param e the document event
+                             */
+                            @Override
+                            public void removeUpdate(DocumentEvent e) {
+                                checkAllTestTarget();
+                            }
+
+                            /**
+                             * Gives notification that an attribute or set of attributes changed.
+                             *
+                             * @param e the document event
+                             */
+                            @Override
+                            public void changedUpdate(DocumentEvent e) {
+                                checkAllTestTarget();
+                            }
+                        });
+    }
+
+    /** Checks test target if it contains key words of all checkboxes. */
+    private void checkAllTestTarget() {
+        String testTarget = mTestTarget.getEditor().getItem().toString();
+        checkTestTarget(testTarget, mRunOnHost, RUN_ON_HOST_POST);
+        checkTestTarget(testTarget, mTestMapping, TEST_MAPPING_POST);
+        checkTestTarget(testTarget, mSkipBuild, SKIP_BUILD_POST);
+    }
+
+    /**
+     * Sets the checkbox behavior.
+     *
+     * <p>if users select check box, the test target appends the corresponding postfix.
+     *
+     * @param checkbox the JCheckBox to set.
+     * @param postfix the corresponding postfix of the JCheckBox.
+     */
+    private void setCheckbox(JCheckBox checkbox, String postfix) {
+        String testTarget = mTestTarget.getEditor().getItem().toString();
+        if (checkbox.isSelected()) {
+            testTarget = testTarget.concat(postfix);
+        } else {
+            testTarget = testTarget.replace(postfix, "");
+        }
+        mTestTarget.setSelectedItem(testTarget);
+    }
+
+    /**
+     * Checks test target if it contains key words of checkbox.
+     *
+     * <p>if users type the keyword in test target, the corresponding checkbox is selected.
+     *
+     * @param testTarget the string in test target.
+     * @param checkbox the JCheckBox to set.
+     * @param postfix the corresponding postfix of the JCheckBox.
+     */
+    private void checkTestTarget(String testTarget, JCheckBox checkbox, String postfix) {
+        if (testTarget.contains(postfix)) {
+            checkbox.setSelected(true);
+        } else {
+            checkbox.setSelected(false);
+        }
+    }
+}