16ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu/* 26ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu * Copyright (C) 2012 The Android Open Source Project 36ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu * 46ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu * Licensed under the Apache License, Version 2.0 (the "License"); 56ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu * you may not use this file except in compliance with the License. 66ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu * You may obtain a copy of the License at 76ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu * 86ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu * http://www.apache.org/licenses/LICENSE-2.0 96ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu * 106ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu * Unless required by applicable law or agreed to in writing, software 116ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu * distributed under the License is distributed on an "AS IS" BASIS, 126ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu * See the License for the specific language governing permissions and 146ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu * limitations under the License. 156ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu */ 166ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu 176ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhupackage com.android.commands.uiautomator; 186ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu 196ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhuimport android.os.Process; 206ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu 216ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhuimport java.util.Arrays; 226ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu 236ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu/** 246ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu * Entry point into the uiautomator command line 256ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu * 266ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu * This class maintains the list of sub commands, and redirect the control into it based on the 276ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu * command line arguments. It also prints out help arguments for each sub commands. 286ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu * 296ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu * To add a new sub command, implement {@link Command} and add an instance into COMMANDS array 306ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu */ 316ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhupublic class Launcher { 326ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu 336ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu /** 346ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu * A simple abstraction class for supporting generic sub commands 356ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu */ 366ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu public static abstract class Command { 376ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu private String mName; 386ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu 396ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu public Command(String name) { 406ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu mName = name; 416ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu } 426ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu 436ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu /** 446ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu * Returns the name of the sub command 456ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu * @return 466ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu */ 476ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu public String name() { 486ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu return mName; 496ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu } 506ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu 516ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu /** 526ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu * Returns a one-liner of the function of this command 536ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu * @return 546ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu */ 556ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu public abstract String shortHelp(); 566ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu 576ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu /** 586ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu * Returns a detailed explanation of the command usage 596ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu * 606ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu * Usage may have multiple lines, indentation of 4 spaces recommended. 616ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu * @return 626ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu */ 636ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu public abstract String detailedOptions(); 646ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu 656ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu /** 666ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu * Starts the command with the provided arguments 676ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu * @param args 686ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu */ 696ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu public abstract void run(String args[]); 706ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu } 716ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu 726ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu public static void main(String[] args) { 736ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu // show a meaningful process name in `ps` 746ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu Process.setArgV0("uiautomator"); 756ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu if (args.length >= 1) { 766ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu Command command = findCommand(args[0]); 776ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu if (command != null) { 786ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu String[] args2 = {}; 796ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu if (args.length > 1) { 806ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu // consume the first arg 816ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu args2 = Arrays.copyOfRange(args, 1, args.length); 826ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu } 836ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu command.run(args2); 846ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu return; 856ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu } 866ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu } 876ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu HELP_COMMAND.run(args); 886ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu } 896ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu 906ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu private static Command findCommand(String name) { 916ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu for (Command command : COMMANDS) { 926ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu if (command.name().equals(name)) { 936ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu return command; 946ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu } 956ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu } 966ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu return null; 976ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu } 986ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu 996ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu private static Command HELP_COMMAND = new Command("help") { 1006ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu @Override 1016ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu public void run(String[] args) { 1026ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu System.err.println("Usage: uiautomator <subcommand> [options]\n"); 1036ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu System.err.println("Available subcommands:\n"); 1046ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu for (Command command : COMMANDS) { 1056ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu String shortHelp = command.shortHelp(); 1066ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu String detailedOptions = command.detailedOptions(); 1076ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu if (shortHelp == null) { 1086ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu shortHelp = ""; 1096ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu } 1106ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu if (detailedOptions == null) { 1116ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu detailedOptions = ""; 1126ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu } 1136ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu System.err.println(String.format("%s: %s", command.name(), shortHelp)); 1146ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu System.err.println(detailedOptions); 1156ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu } 1166ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu } 1176ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu 1186ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu @Override 1196ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu public String detailedOptions() { 1206ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu return null; 1216ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu } 1226ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu 1236ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu @Override 1246ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu public String shortHelp() { 1256ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu return "displays help message"; 1266ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu } 1276ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu }; 1286ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu 1296ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu private static Command[] COMMANDS = new Command[] { 1306ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu HELP_COMMAND, 1316ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu new RunTestCommand(), 1322da677e322f0d46b8ea4f882d780f5ee4e97647aGuang Zhu new DumpCommand(), 1332da677e322f0d46b8ea4f882d780f5ee4e97647aGuang Zhu new EventsCommand(), 1346ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu }; 1356ac3f28e72bc05dce35a3f8d2b6b095a3f4056daGuang Zhu}