diff options
| -rw-r--r-- | services/core/java/com/android/server/recoverysystem/RecoverySystemService.java | 28 | ||||
| -rw-r--r-- | services/core/java/com/android/server/recoverysystem/RecoverySystemShellCommand.java | 90 |
2 files changed, 118 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java index c36d5ef0415c..7164a303121a 100644 --- a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java +++ b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java @@ -24,8 +24,11 @@ import android.os.Binder; import android.os.IRecoverySystem; import android.os.IRecoverySystemProgressListener; import android.os.PowerManager; +import android.os.Process; import android.os.RecoverySystem; import android.os.RemoteException; +import android.os.ResultReceiver; +import android.os.ShellCallback; import android.os.SystemProperties; import android.util.Slog; @@ -39,6 +42,7 @@ import libcore.io.IoUtils; import java.io.DataInputStream; import java.io.DataOutputStream; +import java.io.FileDescriptor; import java.io.FileWriter; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -550,4 +554,28 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo IoUtils.closeQuietly(mLocalSocket); } } + + private boolean isCallerShell() { + final int callingUid = Binder.getCallingUid(); + return callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID; + } + + private void enforceShell() { + if (!isCallerShell()) { + throw new SecurityException("Caller must be shell"); + } + } + + @Override + public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, + String[] args, ShellCallback callback, ResultReceiver resultReceiver) { + enforceShell(); + final long origId = Binder.clearCallingIdentity(); + try { + new RecoverySystemShellCommand(this).exec( + this, in, out, err, args, callback, resultReceiver); + } finally { + Binder.restoreCallingIdentity(origId); + } + } } diff --git a/services/core/java/com/android/server/recoverysystem/RecoverySystemShellCommand.java b/services/core/java/com/android/server/recoverysystem/RecoverySystemShellCommand.java new file mode 100644 index 000000000000..c6905b5c7dd2 --- /dev/null +++ b/services/core/java/com/android/server/recoverysystem/RecoverySystemShellCommand.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2019 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 com.android.server.recoverysystem; + +import android.os.IRecoverySystem; +import android.os.RemoteException; +import android.os.ShellCommand; + +import java.io.PrintWriter; + +/** + * Shell commands to call to {@link RecoverySystemService} from ADB. + */ +public class RecoverySystemShellCommand extends ShellCommand { + private final IRecoverySystem mService; + + public RecoverySystemShellCommand(RecoverySystemService service) { + mService = service; + } + + @Override + public int onCommand(String cmd) { + if (cmd == null) { + return handleDefaultCommands(cmd); + } + try { + switch (cmd) { + case "request-lskf": + return requestLskf(); + case "clear-lskf": + return clearLskf(); + case "reboot-and-apply": + return rebootAndApply(); + default: + return handleDefaultCommands(cmd); + } + } catch (Exception e) { + getErrPrintWriter().println("Error while executing command: " + cmd); + e.printStackTrace(getErrPrintWriter()); + return -1; + } + } + + private int requestLskf() throws RemoteException { + String updateToken = getNextArgRequired(); + boolean success = mService.requestLskf(updateToken, null); + PrintWriter pw = getOutPrintWriter(); + pw.println("Request LSKF status: " + (success ? "success" : "failure")); + return 0; + } + + private int clearLskf() throws RemoteException { + boolean success = mService.clearLskf(); + PrintWriter pw = getOutPrintWriter(); + pw.println("Clear LSKF: " + (success ? "success" : "failure")); + return 0; + } + + private int rebootAndApply() throws RemoteException { + String updateToken = getNextArgRequired(); + String rebootReason = getNextArgRequired(); + boolean success = mService.rebootWithLskf(updateToken, rebootReason); + PrintWriter pw = getOutPrintWriter(); + pw.println("Reboot and apply status: " + (success ? "success" : "failure")); + return 0; + } + + @Override + public void onHelp() { + PrintWriter pw = getOutPrintWriter(); + pw.println("Recovery system commands:"); + pw.println(" request-lskf <token>"); + pw.println(" clear-lskf"); + pw.println(" reboot-and-apply <token> <reason>"); + } +} |