12491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu/*
22491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu * Copyright (C) 2012 The Android Open Source Project
32491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu *
42491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu * Licensed under the Apache License, Version 2.0 (the "License");
52491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu * you may not use this file except in compliance with the License.
62491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu * You may obtain a copy of the License at
72491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu *
82491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu *      http://www.apache.org/licenses/LICENSE-2.0
92491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu *
102491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu * Unless required by applicable law or agreed to in writing, software
112491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu * distributed under the License is distributed on an "AS IS" BASIS,
122491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu * See the License for the specific language governing permissions and
142491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu * limitations under the License.
152491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu */
162491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu
172491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhupackage com.android.commands.uiautomator;
182491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu
192491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhuimport android.os.Process;
202491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu
212491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhuimport java.util.Arrays;
222491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu
232491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu/**
242491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu * Entry point into the uiautomator command line
252491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu *
262491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu * This class maintains the list of sub commands, and redirect the control into it based on the
272491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu * command line arguments. It also prints out help arguments for each sub commands.
282491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu *
292491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu * To add a new sub command, implement {@link Command} and add an instance into COMMANDS array
302491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu */
312491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhupublic class Launcher {
322491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu
332491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu    /**
342491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu     * A simple abstraction class for supporting generic sub commands
352491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu     */
362491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu    public static abstract class Command {
372491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu        private String mName;
382491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu
392491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu        public Command(String name) {
402491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu            mName = name;
412491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu        }
422491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu
432491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu        /**
442491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu         * Returns the name of the sub command
452491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu         * @return
462491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu         */
472491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu        public String name() {
482491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu            return mName;
492491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu        }
502491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu
512491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu        /**
522491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu         * Returns a one-liner of the function of this command
532491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu         * @return
542491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu         */
552491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu        public abstract String shortHelp();
562491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu
572491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu        /**
582491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu         * Returns a detailed explanation of the command usage
592491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu         *
602491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu         * Usage may have multiple lines, indentation of 4 spaces recommended.
612491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu         * @return
622491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu         */
632491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu        public abstract String detailedOptions();
642491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu
652491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu        /**
662491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu         * Starts the command with the provided arguments
672491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu         * @param args
682491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu         */
692491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu        public abstract void run(String args[]);
702491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu    }
712491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu
722491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu    public static void main(String[] args) {
732491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu        // show a meaningful process name in `ps`
742491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu        Process.setArgV0("uiautomator");
752491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu        if (args.length >= 1) {
762491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu            Command command = findCommand(args[0]);
772491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu            if (command != null) {
782491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu                String[] args2 = {};
792491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu                if (args.length > 1) {
802491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu                    // consume the first arg
812491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu                    args2 = Arrays.copyOfRange(args, 1, args.length);
822491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu                }
832491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu                command.run(args2);
842491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu                return;
852491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu            }
862491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu        }
872491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu        HELP_COMMAND.run(args);
882491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu    }
892491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu
902491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu    private static Command findCommand(String name) {
912491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu        for (Command command : COMMANDS) {
922491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu            if (command.name().equals(name)) {
932491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu                return command;
942491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu            }
952491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu        }
962491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu        return null;
972491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu    }
982491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu
992491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu    private static Command HELP_COMMAND = new Command("help") {
1002491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu        @Override
1012491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu        public void run(String[] args) {
1022491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu            System.err.println("Usage: uiautomator <subcommand> [options]\n");
1032491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu            System.err.println("Available subcommands:\n");
1042491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu            for (Command command : COMMANDS) {
1052491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu                String shortHelp = command.shortHelp();
1062491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu                String detailedOptions = command.detailedOptions();
1072491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu                if (shortHelp == null) {
1082491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu                    shortHelp = "";
1092491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu                }
1102491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu                if (detailedOptions == null) {
1112491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu                    detailedOptions = "";
1122491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu                }
1132491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu                System.err.println(String.format("%s: %s", command.name(), shortHelp));
1142491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu                System.err.println(detailedOptions);
1152491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu            }
1162491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu        }
1172491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu
1182491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu        @Override
1192491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu        public String detailedOptions() {
1202491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu            return null;
1212491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu        }
1222491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu
1232491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu        @Override
1242491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu        public String shortHelp() {
1252491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu            return "displays help message";
1262491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu        }
1272491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu    };
1282491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu
1292491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu    private static Command[] COMMANDS = new Command[] {
1302491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu        HELP_COMMAND,
1312491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu        new RunTestCommand(),
132a5c65de4744dca37b46de0acf8be11a9c24cc91bGuang Zhu        new DumpCommand(),
133a5c65de4744dca37b46de0acf8be11a9c24cc91bGuang Zhu        new EventsCommand(),
1342491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu    };
1352491b47c6e86523a7b373cc4d5aeaa5fc7be609dGuang Zhu}