blob: f3a6869687dc35925d57ce4a83948c41d7684bcc [file] [log] [blame]
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001/*
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
17package android.os;
18
Andrei Onea24ec3212019-03-15 17:35:05 +000019import android.annotation.UnsupportedAppUsage;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -070020import android.util.Slog;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070021
Dianne Hackborn9461b6f2015-10-07 17:33:16 -070022import com.android.internal.util.FastPrintWriter;
23
Todd Kennedy72cfcd02015-11-03 17:08:55 -080024import java.io.BufferedInputStream;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -070025import java.io.FileDescriptor;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080026import java.io.FileInputStream;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -070027import java.io.FileOutputStream;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080028import java.io.InputStream;
Dianne Hackborn2e931f52016-01-28 12:21:17 -080029import java.io.OutputStream;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -070030import java.io.PrintWriter;
31
32/**
Dianne Hackborn2e931f52016-01-28 12:21:17 -080033 * Helper for implementing {@link Binder#onShellCommand Binder.onShellCommand}.
Dianne Hackborn9461b6f2015-10-07 17:33:16 -070034 * @hide
35 */
Makoto Onuki4c7073b2019-11-04 10:37:15 -080036public abstract class ShellCommand extends BasicShellCommandHandler {
Dianne Hackborn354736e2016-08-22 17:00:05 -070037 private ShellCallback mShellCallback;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -070038 private ResultReceiver mResultReceiver;
39
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -080040 public int exec(Binder target, FileDescriptor in, FileDescriptor out, FileDescriptor err,
Dianne Hackborn354736e2016-08-22 17:00:05 -070041 String[] args, ShellCallback callback, ResultReceiver resultReceiver) {
Makoto Onuki4c7073b2019-11-04 10:37:15 -080042 mShellCallback = callback;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -080043 mResultReceiver = resultReceiver;
Makoto Onuki4c7073b2019-11-04 10:37:15 -080044 final int result = super.exec(target, in, out, err, args);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -070045
Makoto Onuki4c7073b2019-11-04 10:37:15 -080046 if (mResultReceiver != null) {
47 mResultReceiver.send(result, null);
Dianne Hackborn1704e3c2017-10-31 19:55:42 +000048 }
Makoto Onuki4c7073b2019-11-04 10:37:15 -080049
50 return result;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -070051 }
52
Dianne Hackborn2e931f52016-01-28 12:21:17 -080053 /**
Dianne Hackbornc81983a2017-10-20 16:16:32 -070054 * 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 */
58 public ResultReceiver adoptResultReceiver() {
59 ResultReceiver rr = mResultReceiver;
60 mResultReceiver = null;
61 return rr;
62 }
63
64 /**
Dianne Hackborn331084d2016-10-07 17:57:00 -070065 * Helper for just system services to ask the shell to open an output file.
66 * @hide
67 */
Dianne Hackbornca3872c2017-10-30 14:19:32 -070068 public ParcelFileDescriptor openFileForSystem(String path, String mode) {
Dianne Hackborn1704e3c2017-10-31 19:55:42 +000069 if (DEBUG) Slog.d(TAG, "openFileForSystem: " + path + " mode=" + mode);
Dianne Hackborn331084d2016-10-07 17:57:00 -070070 try {
Dianne Hackbornca3872c2017-10-30 14:19:32 -070071 ParcelFileDescriptor pfd = getShellCallback().openFile(path,
72 "u:r:system_server:s0", mode);
Dianne Hackborn331084d2016-10-07 17:57:00 -070073 if (pfd != null) {
Dianne Hackborn1704e3c2017-10-31 19:55:42 +000074 if (DEBUG) Slog.d(TAG, "Got file: " + pfd);
Dianne Hackborn331084d2016-10-07 17:57:00 -070075 return pfd;
76 }
77 } catch (RuntimeException e) {
Dianne Hackborn1704e3c2017-10-31 19:55:42 +000078 if (DEBUG) Slog.d(TAG, "Failure opening file: " + e.getMessage());
Dianne Hackborn331084d2016-10-07 17:57:00 -070079 getErrPrintWriter().println("Failure opening file: " + e.getMessage());
80 }
Dianne Hackborn1704e3c2017-10-31 19:55:42 +000081 if (DEBUG) Slog.d(TAG, "Error: Unable to open file: " + path);
Dianne Hackborn331084d2016-10-07 17:57:00 -070082 getErrPrintWriter().println("Error: Unable to open file: " + path);
Robin Lee56be27c2017-09-14 14:28:26 +020083
84 String suggestedPath = "/data/local/tmp/";
85 if (path == null || !path.startsWith(suggestedPath)) {
86 getErrPrintWriter().println("Consider using a file under " + suggestedPath);
87 }
Dianne Hackborn331084d2016-10-07 17:57:00 -070088 return null;
89 }
90
Makoto Onuki4c7073b2019-11-04 10:37:15 -080091 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;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -070097 }
Makoto Onuki4c7073b2019-11-04 10:37:15 -080098 return super.handleDefaultCommands(cmd);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -070099 }
100
Andrei Onea24ec3212019-03-15 17:35:05 +0000101 @UnsupportedAppUsage
Filip Gruszczynskic17d8b72016-02-03 16:52:59 -0800102 public String peekNextArg() {
Makoto Onuki4c7073b2019-11-04 10:37:15 -0800103 return super.peekNextArg();
Dianne Hackborn9461b6f2015-10-07 17:33:16 -0700104 }
105
Dianne Hackborn354736e2016-08-22 17:00:05 -0700106 /**
107 * Return the {@link ShellCallback} for communicating back with the calling shell.
108 */
109 public ShellCallback getShellCallback() {
110 return mShellCallback;
111 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -0700112}