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 17 package com.android.server.wifi.aware; 18 19 import android.os.Binder; 20 import android.os.ShellCommand; 21 import android.text.TextUtils; 22 import android.util.Log; 23 24 import java.io.PrintWriter; 25 import java.util.HashMap; 26 import java.util.Map; 27 28 /** 29 * Interprets and executes 'adb shell cmd wifiaware [args]'. 30 */ 31 public 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 */ register(String command, DelegatedShellCommand shellCommand)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 onCommand(String cmd)49 public int onCommand(String cmd) { 50 checkRootPermission(); 51 52 final PrintWriter pw = getErrPrintWriter(); 53 try { 54 if ("reset".equals(cmd)) { 55 for (DelegatedShellCommand dsc: mDelegatedCommands.values()) { 56 dsc.onReset(); 57 } 58 return 0; 59 } else { 60 DelegatedShellCommand delegatedCmd = null; 61 if (!TextUtils.isEmpty(cmd)) { 62 delegatedCmd = mDelegatedCommands.get(cmd); 63 } 64 65 if (delegatedCmd != null) { 66 return delegatedCmd.onCommand(this); 67 } else { 68 return handleDefaultCommands(cmd); 69 } 70 } 71 } catch (Exception e) { 72 pw.println("Exception: " + e); 73 } 74 return -1; 75 } 76 checkRootPermission()77 private void checkRootPermission() { 78 final int uid = Binder.getCallingUid(); 79 if (uid == 0) { 80 // Root can do anything. 81 return; 82 } 83 throw new SecurityException("Uid " + uid + " does not have access to wifiaware commands"); 84 } 85 86 @Override onHelp()87 public void onHelp() { 88 final PrintWriter pw = getOutPrintWriter(); 89 90 pw.println("Wi-Fi Aware (wifiaware) commands:"); 91 pw.println(" help"); 92 pw.println(" Print this help text."); 93 pw.println(" reset"); 94 pw.println(" Reset parameters to default values."); 95 for (Map.Entry<String, DelegatedShellCommand> sce: mDelegatedCommands.entrySet()) { 96 sce.getValue().onHelp(sce.getKey(), this); 97 } 98 pw.println(); 99 } 100 101 /** 102 * Interface that delegated command targets must implement. They are passed the parent shell 103 * command (the real command interpreter) from which they can obtain arguments. 104 */ 105 public interface DelegatedShellCommand { 106 /** 107 * Execute the specified command. Use the parent shell to obtain arguments. Note that the 108 * first argument (which specified the delegated shell) has already been extracted. 109 */ onCommand(ShellCommand parentShell)110 int onCommand(ShellCommand parentShell); 111 112 /** 113 * Reset all parameters to their default values. 114 */ onReset()115 void onReset(); 116 117 /** 118 * Print out help for the delegated command. The name of the delegated command is passed 119 * as a first argument as an assist (prevents hard-coding of that string in multiple 120 * places). 121 */ onHelp(String command, ShellCommand parentShell)122 void onHelp(String command, ShellCommand parentShell); 123 124 } 125 } 126