1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.os;
import android.compat.annotation.UnsupportedAppUsage;
import android.util.Slog;
import com.android.modules.utils.BasicShellCommandHandler;
import java.io.FileDescriptor;
/**
* Helper for implementing {@link Binder#onShellCommand Binder.onShellCommand}.
* @hide
*/
public abstract class ShellCommand extends BasicShellCommandHandler {
private ShellCallback mShellCallback;
private ResultReceiver mResultReceiver;
public int exec(Binder target, FileDescriptor in, FileDescriptor out, FileDescriptor err,
String[] args, ShellCallback callback, ResultReceiver resultReceiver) {
mShellCallback = callback;
mResultReceiver = resultReceiver;
final int result = super.exec(target, in, out, err, args);
if (mResultReceiver != null) {
mResultReceiver.send(result, null);
}
return result;
}
/**
* Adopt the ResultReceiver that was given to this shell command from it, taking
* it over. Primarily used to dispatch to another shell command. Once called,
* this shell command will no longer return its own result when done.
*/
public ResultReceiver adoptResultReceiver() {
ResultReceiver rr = mResultReceiver;
mResultReceiver = null;
return rr;
}
/**
* Helper for just system services to ask the shell to open an output file.
* @hide
*/
public ParcelFileDescriptor openFileForSystem(String path, String mode) {
if (DEBUG) Slog.d(TAG, "openFileForSystem: " + path + " mode=" + mode);
try {
ParcelFileDescriptor pfd = getShellCallback().openFile(path,
"u:r:system_server:s0", mode);
if (pfd != null) {
if (DEBUG) Slog.d(TAG, "Got file: " + pfd);
return pfd;
}
} catch (RuntimeException e) {
if (DEBUG) Slog.d(TAG, "Failure opening file: " + e.getMessage());
getErrPrintWriter().println("Failure opening file: " + e.getMessage());
}
if (DEBUG) Slog.d(TAG, "Error: Unable to open file: " + path);
getErrPrintWriter().println("Error: Unable to open file: " + path);
String suggestedPath = "/data/local/tmp/";
if (path == null || !path.startsWith(suggestedPath)) {
getErrPrintWriter().println("Consider using a file under " + suggestedPath);
}
return null;
}
public int handleDefaultCommands(String cmd) {
if ("dump".equals(cmd)) {
String[] newArgs = new String[getAllArgs().length-1];
System.arraycopy(getAllArgs(), 1, newArgs, 0, getAllArgs().length-1);
getTarget().doDump(getOutFileDescriptor(), getOutPrintWriter(), newArgs);
return 0;
}
return super.handleDefaultCommands(cmd);
}
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public String peekNextArg() {
return super.peekNextArg();
}
/**
* Return the {@link ShellCallback} for communicating back with the calling shell.
*/
public ShellCallback getShellCallback() {
return mShellCallback;
}
}
|