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