Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f8f55027 authored by Makoto Onuki's avatar Makoto Onuki
Browse files

Add SystemApi to handle "adb shell cmd"

This will be used by mainline system services.

TODO: Maybe add more APIs to register subcommands

Bug: 142751512
Test: adb shell cmd jobscheduler help
Change-Id: Ie6d4b9aa4df426d64270d114d694f042b2600cce
parent 3e4c9c46
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -2689,7 +2689,7 @@ public class JobSchedulerService extends com.android.server.SystemService
        }

        @Override
        protected int handleShellCommand(@NonNull ParcelFileDescriptor in,
        public int handleShellCommand(@NonNull ParcelFileDescriptor in,
                @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err,
                @NonNull String[] args) {
            return (new JobSchedulerShellCommand(JobSchedulerService.this)).exec(
+1 −0
Original line number Diff line number Diff line
@@ -5993,6 +5993,7 @@ package android.os {
  }
  public class Binder implements android.os.IBinder {
    method public int handleShellCommand(@NonNull android.os.ParcelFileDescriptor, @NonNull android.os.ParcelFileDescriptor, @NonNull android.os.ParcelFileDescriptor, @NonNull String[]);
    method public static void setProxyTransactListener(@Nullable android.os.Binder.ProxyTransactListener);
  }
+22 −9
Original line number Diff line number Diff line
@@ -896,8 +896,11 @@ public class Binder implements IBinder {
    }

    /**
     * Handle a call to {@link #shellCommand}.  The default implementation simply prints
     * an error message.  Override and replace with your own.
     * Handle a call to {@link #shellCommand}.
     *
     * <p>The default implementation performs a caller check to make sure the caller UID is of
     * SHELL or ROOT, and then call {@link #handleShellCommand}.
     *
     * <p class="caution">Note: no permission checking is done before calling this method; you must
     * apply any security checks as appropriate for the command being executed.
     * Consider using {@link ShellCommand} to help in the implementation.</p>
@@ -908,6 +911,12 @@ public class Binder implements IBinder {
            @NonNull String[] args, @Nullable ShellCallback callback,
            @NonNull ResultReceiver resultReceiver) throws RemoteException {

        final int callingUid = Binder.getCallingUid();
        if (callingUid != Process.ROOT_UID && callingUid != Process.SHELL_UID) {
            resultReceiver.send(-1, null);
            throw new SecurityException("Shell commands are only callable by ADB");
        }

        // First, convert in, out and err to @NonNull, by redirecting any that's null to /dev/null.
        try {
            if (in == null) {
@@ -948,19 +957,23 @@ public class Binder implements IBinder {
    /**
     * System services can implement this method to implement ADB shell commands.
     *
     * TODO More Javadoc.
     * TODO Add a generic way to define subcommands and their permissions.
     * <p>A system binder service can implement it to handle shell commands on ADB. For example,
     * the Job Scheduler service implements it to handle <code>adb shell cmd jobscheduler</code>.
     *
     * @param in standard input.
     * @param out standard output.
     * @param err standard error.
     * <p>Commands are only executable by ADB shell; i.e. only {@link Process#SHELL_UID} and
     * {@link Process#ROOT_UID} can call them.
     *
     * @param in standard input
     * @param out standard output
     * @param err standard error
     * @param args arguments passed to the command. Can be empty. The first argument is typically
     *             a subcommand, such as {@code run} for {@code adb shell cmd jobscheduler run}.
     * @return the status code returned from the <code>cmd</code> command.
     *
     * @hide
     */
    // @SystemApi TODO Make it a system API.
    protected int handleShellCommand(@NonNull ParcelFileDescriptor in,
    @SystemApi
    public int handleShellCommand(@NonNull ParcelFileDescriptor in,
            @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err,
            @NonNull String[] args) {
        FileOutputStream ferr = new FileOutputStream(err.getFileDescriptor());