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
Modifier and TypeClassDescriptionstatic class
Builder class forShell
instances.static interface
The callback used ingetShell(GetShellCallback)
.static class
The initializer when a newShell
is constructed.static class
Represents a shell Job that could later be executed or submitted to background threads.static class
The result of aShell.Job
.static interface
The callback to receive a result inShell.Job.submit(Shell.ResultCallback)
.static interface
A task that can be executed by a shell with the methodexecTask(Task)
. -
Field Summary
Modifier and TypeFieldDescriptionstatic boolean
This flag exists for compatibility reasons.static boolean
Set totrue
to enable verbose logging throughout the library.static Executor
TheExecutor
that manages all worker threads used inlibsu
.static final int
If set, create a root shell with the--mount-master
option.static final int
If set, create a non-root shell.static final int
Shell status: Non-root shell.static final int
Shell status: Root shell.static final int
Shell status: Unknown. -
Constructor Summary
-
Method Summary
Modifier and TypeMethodDescriptionstatic Shell.Job
cmd
(InputStream in) Create a pendingShell.Job
of the main shell with anInputStream
.static Shell.Job
Create a pendingShell.Job
of the main shell with commands.abstract void
execTask
(Shell.Task task) Execute a low-levelShell.Task
using the shell.static Shell
Get the cached main shell.static Shell
getShell()
Get the main shell instance.static void
getShell
(Shell.GetShellCallback callback) Get the main shell instance asynchronously via a callback.static void
getShell
(Executor executor, Shell.GetShellCallback callback) Get the main shell instance asynchronously via a callback.abstract int
Get the status of the shell.abstract boolean
isAlive()
Return whether the shell is still alive.static Boolean
Whether the application has access to root.boolean
isRoot()
Return whether the shell has root access.abstract Shell.Job
newJob()
Construct a newShell.Job
that uses the shell for execution.static void
setDefaultBuilder
(Shell.Builder builder) Override the defaultShell.Builder
.abstract void
submitTask
(Shell.Task task) Submits a low-levelShell.Task
for execution in a queue of the shell.void
Wait indefinitely for any current/pending tasks to finish before closing this shell and release any system resources associated with the shell.abstract boolean
waitAndClose
(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-master
option.Constant value 2.
- See Also:
-
EXECUTOR
TheExecutor
that manages all worker threads used inlibsu
.Note: If the developer decides to replace the default Executor, keep in mind that each
Shell
instance requires at least 3 threads to operate properly. -
enableVerboseLogging
public static boolean enableVerboseLoggingSet totrue
to 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.Job
is 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.Builder
will 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.Builder
will be used to construct a newShell
in 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.Builder
will be used to construct a newShell
in 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. Ifnull
is passed, the callback can run on any thread.callback
- invoked when a shell is acquired.
-
getCachedShell
Get the cached main shell.- Returns:
- a
Shell
instance.null
can 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
null
when 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
null
when undetermined.
-
cmd
Create a pendingShell.Job
of 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.Job
s 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.Job
of 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.Job
s before the program has created any root shell.- See Also:
-
isAlive
public abstract boolean isAlive()Return whether the shell is still alive.- Returns:
true
if the shell is still alive.
-
execTask
Execute a low-levelShell.Task
using 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.Task
for execution in a queue of the shell.- Parameters:
task
- the desired task.- See Also:
-
newJob
Construct a newShell.Job
that 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:
true
if 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:
true
if this shell is terminated andfalse
if 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.
-