1 /* 2 * Copyright (C) 2015 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 android.os; 18 19 import android.compat.annotation.UnsupportedAppUsage; 20 import android.util.Slog; 21 22 import com.android.internal.util.FastPrintWriter; 23 24 import java.io.BufferedInputStream; 25 import java.io.FileDescriptor; 26 import java.io.FileInputStream; 27 import java.io.FileOutputStream; 28 import java.io.InputStream; 29 import java.io.OutputStream; 30 import java.io.PrintWriter; 31 32 /** 33 * Helper for implementing {@link Binder#onShellCommand Binder.onShellCommand}. 34 * @hide 35 */ 36 public abstract class ShellCommand extends BasicShellCommandHandler { 37 private ShellCallback mShellCallback; 38 private ResultReceiver mResultReceiver; 39 exec(Binder target, FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)40 public int exec(Binder target, FileDescriptor in, FileDescriptor out, FileDescriptor err, 41 String[] args, ShellCallback callback, ResultReceiver resultReceiver) { 42 mShellCallback = callback; 43 mResultReceiver = resultReceiver; 44 final int result = super.exec(target, in, out, err, args); 45 46 if (mResultReceiver != null) { 47 mResultReceiver.send(result, null); 48 } 49 50 return result; 51 } 52 53 /** 54 * Adopt the ResultReceiver that was given to this shell command from it, taking 55 * it over. Primarily used to dispatch to another shell command. Once called, 56 * this shell command will no longer return its own result when done. 57 */ adoptResultReceiver()58 public ResultReceiver adoptResultReceiver() { 59 ResultReceiver rr = mResultReceiver; 60 mResultReceiver = null; 61 return rr; 62 } 63 64 /** 65 * Helper for just system services to ask the shell to open an output file. 66 * @hide 67 */ openFileForSystem(String path, String mode)68 public ParcelFileDescriptor openFileForSystem(String path, String mode) { 69 if (DEBUG) Slog.d(TAG, "openFileForSystem: " + path + " mode=" + mode); 70 try { 71 ParcelFileDescriptor pfd = getShellCallback().openFile(path, 72 "u:r:system_server:s0", mode); 73 if (pfd != null) { 74 if (DEBUG) Slog.d(TAG, "Got file: " + pfd); 75 return pfd; 76 } 77 } catch (RuntimeException e) { 78 if (DEBUG) Slog.d(TAG, "Failure opening file: " + e.getMessage()); 79 getErrPrintWriter().println("Failure opening file: " + e.getMessage()); 80 } 81 if (DEBUG) Slog.d(TAG, "Error: Unable to open file: " + path); 82 getErrPrintWriter().println("Error: Unable to open file: " + path); 83 84 String suggestedPath = "/data/local/tmp/"; 85 if (path == null || !path.startsWith(suggestedPath)) { 86 getErrPrintWriter().println("Consider using a file under " + suggestedPath); 87 } 88 return null; 89 } 90 handleDefaultCommands(String cmd)91 public int handleDefaultCommands(String cmd) { 92 if ("dump".equals(cmd)) { 93 String[] newArgs = new String[getAllArgs().length-1]; 94 System.arraycopy(getAllArgs(), 1, newArgs, 0, getAllArgs().length-1); 95 getTarget().doDump(getOutFileDescriptor(), getOutPrintWriter(), newArgs); 96 return 0; 97 } 98 return super.handleDefaultCommands(cmd); 99 } 100 101 @UnsupportedAppUsage peekNextArg()102 public String peekNextArg() { 103 return super.peekNextArg(); 104 } 105 106 /** 107 * Return the {@link ShellCallback} for communicating back with the calling shell. 108 */ getShellCallback()109 public ShellCallback getShellCallback() { 110 return mShellCallback; 111 } 112 } 113