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}