Class Shell
- All Implemented Interfaces:
Closeable,AutoCloseable
Similar to threads where there is a special "main thread", libsu also has the
concept of the "main shell". For each process, there is a single globally shared
"main shell" that is constructed on-demand and cached.
To obtain/create the main shell, use the static Shell.getShell(...) methods.
Developers can use these high level APIs to access the main shell:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic classBuilder class forShellinstances.static interfaceThe callback used ingetShell(GetShellCallback).static classThe initializer when a newShellis constructed.static classRepresents a shell Job that could later be executed or submitted to background threads.static classThe result of aShell.Job.static interfaceThe callback to receive a result inShell.Job.submit(Shell.ResultCallback).static interfaceA task that can be executed by a shell with the methodexecTask(Task). -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic booleanThis flag exists for compatibility reasons.static booleanSet totrueto enable verbose logging throughout the library.static ExecutorTheExecutorthat manages all worker threads used inlibsu.static final intIf set, create a root shell with the--mount-masteroption.static final intIf set, create a non-root shell.static final intShell status: Non-root shell.static final intShell status: Root shell.static final intShell status: Unknown. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionstatic Shell.Jobcmd(InputStream in) Create a pendingShell.Jobof the main shell with anInputStream.static Shell.JobCreate a pendingShell.Jobof the main shell with commands.abstract voidexecTask(Shell.Task task) Execute a low-levelShell.Taskusing the shell.static ShellGet the cached main shell.static ShellgetShell()Get the main shell instance.static voidgetShell(Shell.GetShellCallback callback) Get the main shell instance asynchronously via a callback.static voidgetShell(Executor executor, Shell.GetShellCallback callback) Get the main shell instance asynchronously via a callback.abstract intGet the status of the shell.abstract booleanisAlive()Return whether the shell is still alive.static BooleanWhether the application has access to root.booleanisRoot()Return whether the shell has root access.abstract Shell.JobnewJob()Construct a newShell.Jobthat uses the shell for execution.static voidsetDefaultBuilder(Shell.Builder builder) Override the defaultShell.Builder.abstract voidsubmitTask(Shell.Task task) Submits a low-levelShell.Taskfor execution in a queue of the shell.voidWait indefinitely for any current/pending tasks to finish before closing this shell and release any system resources associated with the shell.abstract booleanwaitAndClose(long timeout, TimeUnit unit) Wait for any current/pending tasks to finish before closing this shell and release any system resources associated with the shell.
-
Field Details
-
UNKNOWN
public static final int UNKNOWNShell status: Unknown. One possible result ofgetStatus().Constant value -1.
- See Also:
-
NON_ROOT_SHELL
public static final int NON_ROOT_SHELLShell status: Non-root shell. One possible result ofgetStatus().Constant value 0.
- See Also:
-
ROOT_SHELL
public static final int ROOT_SHELLShell status: Root shell. One possible result ofgetStatus().Constant value 1.
- See Also:
-
FLAG_NON_ROOT_SHELL
public static final int FLAG_NON_ROOT_SHELLIf set, create a non-root shell.Constant value 1.
- See Also:
-
FLAG_MOUNT_MASTER
public static final int FLAG_MOUNT_MASTERIf set, create a root shell with the--mount-masteroption.Constant value 2.
- See Also:
-
EXECUTOR
TheExecutorthat manages all worker threads used inlibsu.Note: If the developer decides to replace the default Executor, keep in mind that each
Shellinstance requires at least 3 threads to operate properly. -
enableVerboseLogging
public static boolean enableVerboseLoggingSet totrueto enable verbose logging throughout the library. -
enableLegacyStderrRedirection
public static boolean enableLegacyStderrRedirectionThis flag exists for compatibility reasons. DO NOT use unless necessary.If enabled, STDERR outputs will be redirected to the STDOUT output list when a
Shell.Jobis configured withShell.Job.to(List). Since theShell.cmd(...)methods are functionally equivalent toShell.getShell().newJob().add(...).to(new ArrayList<>()), this variable also affects the behavior of those methods.Note: The recommended way to redirect STDERR output to STDOUT is to assign the same list to both STDOUT and STDERR with
Shell.Job.to(List, List). The behavior of this flag is unintuitive and error prone.
-
-
Constructor Details
-
Shell
public Shell()
-
-
Method Details
-
setDefaultBuilder
Override the defaultShell.Builder.This shell builder will be used to construct the main shell. Set this before the main shell is created anywhere in the program.
-
getShell
Get the main shell instance.If
getCachedShell()returns null, the defaultShell.Builderwill be used to construct a newShell.Unless already cached, this method blocks until the main shell is created. The process could take a very long time (e.g. root permission request prompt), so be extra careful when calling this method from the main thread!
A good practice is to "preheat" the main shell during app initialization (e.g. the splash screen) by either calling this method in a background thread or calling
getShell(GetShellCallback)so subsequent calls to this function returns immediately.- Returns:
- the cached/created main shell instance.
- See Also:
-
getShell
Get the main shell instance asynchronously via a callback.If
getCachedShell()returns null, the defaultShell.Builderwill be used to construct a newShellin a background thread. The cached/created shell instance is returned to the callback on the main thread.- Parameters:
callback- invoked when a shell is acquired.
-
getShell
Get the main shell instance asynchronously via a callback.If
getCachedShell()returns null, the defaultShell.Builderwill be used to construct a newShellin a background thread. The cached/created shell instance is returned to the callback executed by provided executor.- Parameters:
executor- the executor used to handle the result callback event. Ifnullis passed, the callback can run on any thread.callback- invoked when a shell is acquired.
-
getCachedShell
Get the cached main shell.- Returns:
- a
Shellinstance.nullcan be returned either when no main shell has been cached, or the cached shell is no longer active.
-
isAppGrantedRoot
Whether the application has access to root.This method returns
nullwhen it is currently unable to determine whether root access has been granted to the application. A non-null value meant that the root permission grant state has been accurately determined and finalized. The application must have at least 1 root shell created to have this method returntrue. This method will not block the calling thread; results will be returned immediately.- Returns:
- whether the application has access to root, or
nullwhen undetermined.
-
cmd
Create a pendingShell.Jobof the main shell with commands.This method can be treated as functionally equivalent to
Shell.getShell().newJob().add(commands).to(new ArrayList<>()), but the internal implementation is specialized for this use case and does not run this exact code. The developer can manually override output destination(s) with eitherShell.Job.to(List)orShell.Job.to(List, List).The main shell will NOT be requested until the developer invokes either
Shell.Job.exec(),Shell.Job.enqueue(), orJob.submit(...). This makes it possible to constructShell.Jobs before the program has created any root shell.- Returns:
- a job that the developer can execute or submit later.
- See Also:
-
cmd
Create a pendingShell.Jobof the main shell with anInputStream.This method can be treated as functionally equivalent to
Shell.getShell().newJob().add(in).to(new ArrayList<>()), but the internal implementation is specialized for this use case and does not run this exact code. The developer can manually override output destination(s) with eitherShell.Job.to(List)orShell.Job.to(List, List).The main shell will NOT be requested until the developer invokes either
Shell.Job.exec(),Shell.Job.enqueue(), orJob.submit(...). This makes it possible to constructShell.Jobs before the program has created any root shell.- See Also:
-
isAlive
public abstract boolean isAlive()Return whether the shell is still alive.- Returns:
trueif the shell is still alive.
-
execTask
Execute a low-levelShell.Taskusing the shell. USE THIS METHOD WITH CAUTION!This method exposes raw STDIN/STDOUT/STDERR directly to the developer. This is meant for implementing low-level operations. The shell may stall if the buffer of STDOUT/STDERR is full. It is recommended to use additional threads to consume STDOUT/STDERR in parallel.
STDOUT/STDERR is cleared before executing the task. No output from any previous tasks should be left over. It is the developer's responsibility to make sure all operations are done; the shell should be in idle and waiting for further input when the task returns.
- Parameters:
task- the desired task.- Throws:
IOException- I/O errors when doing operations with STDIN/STDOUT/STDERR
-
submitTask
Submits a low-levelShell.Taskfor execution in a queue of the shell.- Parameters:
task- the desired task.- See Also:
-
newJob
Construct a newShell.Jobthat uses the shell for execution.Unlike
cmd(String...)andcmd(InputStream), NO output will be collected if the developer did not set the output destination withShell.Job.to(List)orShell.Job.to(List, List).- Returns:
- a job that the developer can execute or submit later.
-
getStatus
public abstract int getStatus()Get the status of the shell.- Returns:
- the status of the shell.
Value is either
UNKNOWN,NON_ROOT_SHELL, orROOT_SHELL
-
isRoot
public boolean isRoot()Return whether the shell has root access.- Returns:
trueif the shell has root access.
-
waitAndClose
public abstract boolean waitAndClose(long timeout, @NonNull TimeUnit unit) throws IOException, InterruptedException Wait for any current/pending tasks to finish before closing this shell and release any system resources associated with the shell.Blocks until all current/pending tasks have completed execution, or the timeout occurs, or the current thread is interrupted, whichever happens first.
- Parameters:
timeout- the maximum time to waitunit- the time unit of the timeout argument- Returns:
trueif this shell is terminated andfalseif the timeout elapsed before termination, in which the shell can still to be used afterwards.- Throws:
IOException- if an I/O error occurs.InterruptedException- if interrupted while waiting.
-
waitAndClose
Wait indefinitely for any current/pending tasks to finish before closing this shell and release any system resources associated with the shell.- Throws:
IOException- if an I/O error occurs.
-