WifiAwareShellCommand.java revision c760a66378bbd844eb421658799b4d55c76b98fa
1/*
2 * Copyright (C) 2017 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
17package com.android.server.wifi.aware;
18
19import android.os.Binder;
20import android.os.ShellCommand;
21import android.text.TextUtils;
22import android.util.Log;
23
24import java.io.PrintWriter;
25import java.util.HashMap;
26import java.util.Map;
27
28/**
29 * Interprets and executes 'adb shell cmd wifiaware [args]'.
30 */
31public class WifiAwareShellCommand extends ShellCommand {
32    private static final String TAG = "WifiAwareShellCommand";
33
34    private Map<String, DelegatedShellCommand> mDelegatedCommands = new HashMap<>();
35
36    /**
37     * Register an delegated command interpreter for the specified 'command'. Each class can
38     * interpret and execute their own commands.
39     */
40    public void register(String command, DelegatedShellCommand shellCommand) {
41        if (mDelegatedCommands.containsKey(command)) {
42            Log.e(TAG, "register: overwriting existing command -- '" + command + "'");
43        }
44
45        mDelegatedCommands.put(command, shellCommand);
46    }
47
48    @Override
49    public int onCommand(String cmd) {
50        checkRootPermission();
51
52        final PrintWriter pw = getErrPrintWriter();
53        try {
54            DelegatedShellCommand delegatedCmd = null;
55            if (!TextUtils.isEmpty(cmd)) {
56                delegatedCmd = mDelegatedCommands.get(cmd);
57            }
58
59            if (delegatedCmd != null) {
60                return delegatedCmd.onCommand(this);
61            } else {
62                return handleDefaultCommands(cmd);
63            }
64        } catch (Exception e) {
65            pw.println("Exception: " + e);
66        }
67        return -1;
68    }
69
70    private void checkRootPermission() {
71        final int uid = Binder.getCallingUid();
72        if (uid == 0) {
73            // Root can do anything.
74            return;
75        }
76        throw new SecurityException("Uid " + uid + " does not have access to wifiaware commands");
77    }
78
79    @Override
80    public void onHelp() {
81        final PrintWriter pw = getOutPrintWriter();
82
83        pw.println("Wi-Fi Aware (wifiaware) commands:");
84        pw.println("  help");
85        pw.println("    Print this help text.");
86        for (Map.Entry<String, DelegatedShellCommand> sce: mDelegatedCommands.entrySet()) {
87            sce.getValue().onHelp(sce.getKey(), this);
88        }
89        pw.println();
90    }
91
92    /**
93     * Interface that delegated command targets must implement. They are passed the parent shell
94     * command (the real command interpreter) from which they can obtain arguments.
95     */
96    public interface DelegatedShellCommand {
97        /**
98         * Execute the specified command. Use the parent shell to obtain arguments. Note that the
99         * first argument (which specified the delegated shell) has already been extracted.
100         */
101        int onCommand(ShellCommand parentShell);
102
103        /**
104         * Print out help for the delegated command. The name of the delegated command is passed
105         * as a first argument as an assist (prevents hard-coding of that string in multiple
106         * places).
107         */
108        void onHelp(String command, ShellCommand parentShell);
109    }
110}
111