• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.atest.run;
17 
18 import com.android.atest.AtestUtils;
19 import com.android.atest.Constants;
20 import com.android.atest.commandAdapter.CommandRunner;
21 import com.android.atest.dialog.MessageDialog;
22 import com.android.atest.toolWindow.AtestToolWindow;
23 import com.android.atest.widget.AtestNotification;
24 import com.google.common.base.Strings;
25 import com.intellij.execution.ExecutionException;
26 import com.intellij.execution.Executor;
27 import com.intellij.execution.configurations.*;
28 import com.intellij.execution.runners.ExecutionEnvironment;
29 import com.intellij.notification.Notifications;
30 import com.intellij.openapi.diagnostic.Logger;
31 import com.intellij.openapi.options.SettingsEditor;
32 import com.intellij.openapi.project.Project;
33 import com.intellij.openapi.util.InvalidDataException;
34 import com.intellij.openapi.util.text.StringUtil;
35 import com.intellij.openapi.wm.ToolWindow;
36 import com.intellij.openapi.wm.ToolWindowManager;
37 import org.jdom.Element;
38 import org.jetbrains.annotations.NotNull;
39 import org.jetbrains.annotations.Nullable;
40 
41 /** Runs configurations which can be managed by a user and displayed in the UI. */
42 public class AtestRunConfiguration extends LocatableConfigurationBase {
43 
44     private static final Logger LOG = Logger.getInstance(AtestRunConfiguration.class);
45     public static final String TEST_TARGET_KEY = "testTarget";
46     public static final String LUNCH_TARGET_KEY = "lunchTarget";
47     private String mTestTarget = "";
48     private String mLunchTarget = "";
49 
AtestRunConfiguration(Project project, ConfigurationFactory factory, String name)50     protected AtestRunConfiguration(Project project, ConfigurationFactory factory, String name) {
51         super(project, factory, name);
52     }
53 
54     /**
55      * Reads the run configuration settings from the file system.
56      *
57      * @param element an Element object to read.
58      * @throws InvalidDataException if the data is invalid.
59      */
60     @Override
readExternal(@otNull Element element)61     public void readExternal(@NotNull Element element) throws InvalidDataException {
62         Element child = element.getChild(TEST_TARGET_KEY);
63         if (hasValue(child)) {
64             mTestTarget = child.getTextTrim();
65         }
66         child = element.getChild(LUNCH_TARGET_KEY);
67         if (hasValue(child)) {
68             mLunchTarget = child.getTextTrim();
69         }
70     }
71 
72     /**
73      * Checks the element has value or not.
74      *
75      * @param element an Element object to check.
76      * @return true if the element has value.
77      */
hasValue(Element element)78     private boolean hasValue(Element element) {
79         return element != null && !Strings.isNullOrEmpty(element.getTextTrim());
80     }
81 
82     /**
83      * Stores the run configuration settings at file system.
84      *
85      * @param element an Element object to write.
86      */
87     @Override
writeExternal(@otNull Element element)88     public void writeExternal(@NotNull Element element) {
89         setElementChild(element, TEST_TARGET_KEY, mTestTarget);
90         setElementChild(element, LUNCH_TARGET_KEY, mLunchTarget);
91         super.writeExternal(element);
92     }
93 
94     /**
95      * Sets the child element for an element.
96      *
97      * @param element an Element object to set.
98      * @param key the key of the child Element object.
99      * @param value the value of the child Element object.
100      */
setElementChild(@otNull Element element, String key, String value)101     private void setElementChild(@NotNull Element element, String key, String value) {
102         Element child = new Element(key);
103         child.setText(value);
104         element.addContent(child);
105     }
106 
107     /**
108      * Returns the UI control for editing the run configuration settings. If additional control over
109      * validation is required, the object returned from this method may also implement {@link
110      * com.intellij.execution.impl.CheckableRunConfigurationEditor}. The returned object can also
111      * implement {@link com.intellij.openapi.options.SettingsEditorGroup} if the settings it
112      * provides need to be displayed in multiple tabs.
113      *
114      * @return Atest settings editor component.
115      */
116     @NotNull
117     @Override
getConfigurationEditor()118     public SettingsEditor<? extends RunConfiguration> getConfigurationEditor() {
119         return new AtestSettingsEditor();
120     }
121 
122     /**
123      * Checks whether the run configuration settings are valid. Note that this check may be invoked
124      * on every change (i.e. after each character typed in an input field).
125      *
126      * @throws RuntimeConfigurationException if the configuration settings contain a non-fatal
127      *     problem which the user should be warned about but the execution should still be allowed.
128      */
129     @Override
checkConfiguration()130     public void checkConfiguration() throws RuntimeConfigurationException {
131         if (StringUtil.isEmptyOrSpaces(mTestTarget)) {
132             throw new RuntimeConfigurationWarning("Test target not defined");
133         }
134         if (StringUtil.isEmptyOrSpaces(mLunchTarget)) {
135             throw new RuntimeConfigurationWarning("Lunch target not defined");
136         }
137     }
138 
139     /**
140      * Prepares for executing a specific instance of the run configuration.
141      *
142      * <p>Since Atest plugin uses tool window to output the message. It always returns null to
143      * handle the process inside Atest plugin.
144      *
145      * @param executor the execution mode selected by the user (run, debug, profile etc.)
146      * @param executionEnvironment the environment object containing additional settings for
147      *     executing the configuration.
148      * @throws ExecutionException if exception happens when executing.
149      * @return the RunProfileState describing the process which is about to be started, or null if
150      *     it won't start the process.
151      */
152     @Nullable
153     @Override
getState( @otNull Executor executor, @NotNull ExecutionEnvironment executionEnvironment)154     public RunProfileState getState(
155             @NotNull Executor executor, @NotNull ExecutionEnvironment executionEnvironment)
156             throws ExecutionException {
157         AtestToolWindow atestToolWindow =
158                 AtestToolWindow.getInstance(executionEnvironment.getProject());
159 
160         if (!showAtestTW(executionEnvironment.getProject())) {
161             return null;
162         }
163         String workPath =
164                 AtestUtils.getAndroidRoot(executionEnvironment.getProject().getBasePath());
165         atestToolWindow.setLunchTarget(mLunchTarget);
166         atestToolWindow.setTestTarget(mTestTarget);
167         try {
168             CommandRunner runner =
169                     new CommandRunner(
170                             mLunchTarget,
171                             mTestTarget,
172                             workPath,
173                             atestToolWindow,
174                             executionEnvironment.getProject());
175             runner.run();
176         } catch (IllegalArgumentException exception) {
177             String errorMessage = AtestUtils.checkError(mLunchTarget, mTestTarget, workPath);
178             MessageDialog.showMessageDialog(errorMessage);
179         }
180         return null;
181     }
182 
183     /**
184      * Shows the Atest tool window.
185      *
186      * @param project the project in which the run configuration will be used.
187      * @return true if show Atest tool window successful.
188      */
showAtestTW(@otNull Project project)189     private boolean showAtestTW(@NotNull Project project) {
190         boolean result = false;
191         ToolWindow atestTWController =
192                 ToolWindowManager.getInstance(project).getToolWindow(Constants.ATEST_TOOL_WINDOW);
193         if (atestTWController != null) {
194             atestTWController.show(null);
195             result = true;
196         } else {
197             Notifications.Bus.notify(new AtestNotification(Constants.ATEST_WINDOW_FAIL));
198             LOG.error("Can't get Atest tool window.");
199         }
200         return result;
201     }
202 
getTestTarget()203     public String getTestTarget() {
204         return mTestTarget;
205     }
206 
setTestTarget(@otNull String testTarget)207     public void setTestTarget(@NotNull String testTarget) {
208         mTestTarget = testTarget;
209     }
210 
getLaunchTarget()211     public String getLaunchTarget() {
212         return mLunchTarget;
213     }
214 
setLaunchTarget(@otNull String launchTarget)215     public void setLaunchTarget(@NotNull String launchTarget) {
216         mLunchTarget = launchTarget;
217     }
218 }
219