From c64e86c2b7184d43adcc15e48971bf9f40c13377 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Wed, 21 Feb 2018 23:38:41 +0800 Subject: [PATCH] Update Javadoc --- docs/allclasses-frame.html | 12 +- docs/allclasses-noframe.html | 12 +- docs/com/topjohnwu/superuser/BusyBox.html | 318 +++++++++++ .../com/topjohnwu/superuser/CallbackList.html | 8 +- .../topjohnwu/superuser/NoShellException.html | 4 +- .../superuser/Shell.Async.Callback.html | 4 +- docs/com/topjohnwu/superuser/Shell.Async.html | 4 +- .../topjohnwu/superuser/Shell.Container.html | 4 +- .../superuser/Shell.ContainerApp.html | 4 +- .../superuser/Shell.GetShellCallback.html | 4 +- .../superuser/Shell.Initializer.html | 6 +- docs/com/topjohnwu/superuser/Shell.Sync.html | 8 +- docs/com/topjohnwu/superuser/Shell.Task.html | 240 +++++++++ docs/com/topjohnwu/superuser/Shell.html | 303 ++++++++--- docs/com/topjohnwu/superuser/ShellUtils.html | 494 +++++++++++++++++ docs/com/topjohnwu/superuser/io/SuFile.html | 152 ++++-- .../superuser/io/SuFileInputStream.html | 304 +++++++++++ .../superuser/io/SuFileOutputStream.html | 391 ++++++++++++++ .../io/SuProcessFileInputStream.html | 351 ++++++++++++ .../io/SuProcessFileOutputStream.html | 417 ++++++++++++++ .../superuser/io/SuRandomAccessFile.html | 510 ++++++++++++++++++ .../topjohnwu/superuser/io/package-frame.html | 9 +- .../superuser/io/package-summary.html | 34 +- .../topjohnwu/superuser/io/package-tree.html | 25 +- .../topjohnwu/superuser/package-frame.html | 7 +- .../topjohnwu/superuser/package-summary.html | 32 +- .../com/topjohnwu/superuser/package-tree.html | 7 +- docs/constant-values.html | 4 +- docs/deprecated-list.html | 4 +- docs/help-doc.html | 4 +- docs/index-all.html | 210 +++++++- docs/index.html | 2 +- docs/overview-frame.html | 4 +- docs/overview-summary.html | 4 +- docs/overview-tree.html | 28 +- docs/serialized-form.html | 18 +- .../java/com/topjohnwu/superuser/BusyBox.java | 50 +- .../com/topjohnwu/superuser/ShellUtils.java | 69 ++- .../internal/RandomAccessFileWrapper.java | 2 +- .../superuser/internal/ShellFileIO.java | 4 +- .../com/topjohnwu/superuser/io/SuFile.java | 2 +- .../superuser/io/SuFileInputStream.java | 15 + .../superuser/io/SuFileOutputStream.java | 23 +- .../io/SuProcessFileInputStream.java | 18 + .../io/SuProcessFileOutputStream.java | 24 + .../superuser/io/SuRandomAccessFile.java | 17 + 46 files changed, 3986 insertions(+), 180 deletions(-) create mode 100644 docs/com/topjohnwu/superuser/BusyBox.html create mode 100644 docs/com/topjohnwu/superuser/Shell.Task.html create mode 100644 docs/com/topjohnwu/superuser/ShellUtils.html create mode 100644 docs/com/topjohnwu/superuser/io/SuFileInputStream.html create mode 100644 docs/com/topjohnwu/superuser/io/SuFileOutputStream.html create mode 100644 docs/com/topjohnwu/superuser/io/SuProcessFileInputStream.html create mode 100644 docs/com/topjohnwu/superuser/io/SuProcessFileOutputStream.html create mode 100644 docs/com/topjohnwu/superuser/io/SuRandomAccessFile.html diff --git a/docs/allclasses-frame.html b/docs/allclasses-frame.html index f1687440..8bf1fc7c 100644 --- a/docs/allclasses-frame.html +++ b/docs/allclasses-frame.html @@ -2,9 +2,9 @@ - + All Classes (libsu API) - + @@ -12,6 +12,7 @@

All Classes

diff --git a/docs/allclasses-noframe.html b/docs/allclasses-noframe.html index 10815b78..a6d1ba64 100644 --- a/docs/allclasses-noframe.html +++ b/docs/allclasses-noframe.html @@ -2,9 +2,9 @@ - + All Classes (libsu API) - + @@ -12,6 +12,7 @@

All Classes

diff --git a/docs/com/topjohnwu/superuser/BusyBox.html b/docs/com/topjohnwu/superuser/BusyBox.html new file mode 100644 index 00000000..36882df4 --- /dev/null +++ b/docs/com/topjohnwu/superuser/BusyBox.html @@ -0,0 +1,318 @@ + + + + + +BusyBox (libsu API) + + + + + + + + +
+ + + + + + + +
+ + + +
+
com.topjohnwu.superuser
+

Class BusyBox

+
+
+ +
+
    +
  • +
    +
    +
    public final class BusyBox
    +extends Object
    +
    A class that handles the bundled BusyBox. +

    + libsu bundles with busybox binaries for both arm and x86 (arm64 and x64 are also covered). + Developers using libsu can easily access busybox applets by calling setup(Context) + before any new shell is created (place this in the same place where you call + Shell.setFlags(int)) and Shell.setInitializer(Shell.Initializer). + After calling setup(Context), busybox will be installed in the app's internal storage, + and all new shells created will have the path to busybox prepended to PATH. + This makes sure all commands are using the applets from busybox, providing predictable + behavior so that developers can have less headache handling different implementation of the + common shell utilities. Some operations in com.topjohnwu.superuser.io depends on a + busybox to work properly, check before using them. +

    + Note: the busybox binaries will add around 1.6MB to your APK, for developers not willing + to use the busybox binaries bundled in libsu, you can use proguard to remove it: + remember to NOT call setup(Context) anywhere in your code, and enable both + minifyEnabled and shrinkResources in your release builds. For more info, please + check the official documentation.

    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Field Detail

      + + + +
        +
      • +

        BB_PATH

        +
        public static File BB_PATH
        +
        The path pointing to the folder where busybox is installed. +

        + If your app would like to rely on external busybox, you can directly assign the path to this field. + All new shell instances created will have this directory prepended to PATH. +

        + For example: Magisk Manager relies on the Magisk's internal busybox (located in + /sbin/.core/busybox). So instead of calling setup(Context), it can directly + assign the busybox path to this field to discard the bundled busybox binaries. + (BusyBox.BB_PATH = new File("/sbin/.core/busybox")).

        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        setup

        +
        public static void setup(Context context)
        +
        Setup a busybox environment using the bundled busybox binaries. +

        + Busybox will be installed to the internal data of the application. On Android 7.0+, it + will install busybox to Device Protected Storage, so developers willing to support + Direct Boot + can use it without an issue. +

        + After calling this method, BB_PATH will point to the folder where the busybox is + installed. +

        + If you are willing to let proguard to remove the bundled busybox binary to reduce the APK + size, do NOT call this method.

        +
        +
        Parameters:
        +
        context - a Context of the current app.
        +
        +
      • +
      +
    • +
    +
  • +
+
+
+ + +
+ + + + + + + +
+ + + + diff --git a/docs/com/topjohnwu/superuser/CallbackList.html b/docs/com/topjohnwu/superuser/CallbackList.html index 0af5ba86..db3a1438 100644 --- a/docs/com/topjohnwu/superuser/CallbackList.html +++ b/docs/com/topjohnwu/superuser/CallbackList.html @@ -2,9 +2,9 @@ - + CallbackList (libsu API) - + @@ -48,7 +48,7 @@
Parameters:
-
shell - the newly constructed shell
+
shell - the newly constructed shell.
diff --git a/docs/com/topjohnwu/superuser/Shell.Sync.html b/docs/com/topjohnwu/superuser/Shell.Sync.html index d7b29214..87ea1fa5 100644 --- a/docs/com/topjohnwu/superuser/Shell.Sync.html +++ b/docs/com/topjohnwu/superuser/Shell.Sync.html @@ -2,9 +2,9 @@ - + Shell.Sync (libsu API) - + @@ -49,7 +49,7 @@
Parameters:
-
output - the list to store STDOUT outputs.
-
error - the list to store STDERR outputs.
+
outList - the list storing STDOUT outputs. null to ignore outputs.
+
errList - the list storing STDERR outputs. null to ignore outputs.
callback - the callback when all commands are ran and the outputs are done.
commands - the commands to run in the shell.
@@ -891,18 +1062,20 @@

run

  • loadInputStream

    -
    public abstract void loadInputStream(List<String> output,
    -                                     List<String> error,
    -                                     InputStream in)
    +
    public void loadInputStream(List<String> outList,
    +                            List<String> errList,
    +                            InputStream in)
    Synchronously load an input stream to the shell and stores outputs to the two lists.

    This command is useful for loading a script stored in the APK. An InputStream can be opened from assets with AssetManager.open(String) or from raw resources - with Resources.openRawResource(int).

    + with Resources.openRawResource(int). +

    + Simply performs execSyncTask(outList, errList, createLoadStreamTask(in))

    Parameters:
    -
    output - the list to store STDOUT outputs.
    -
    error - the list to store STDERR outputs.
    +
    outList - the list storing STDOUT outputs. null to ignore outputs.
    +
    errList - the list storing STDERR outputs. null to ignore outputs.
    in - the InputStream to load
  • @@ -910,42 +1083,30 @@

    loadInputStream

    -
      +
      • loadInputStream

        -
        public abstract void loadInputStream(List<String> output,
        -                                     List<String> error,
        -                                     Shell.Async.Callback callback,
        -                                     InputStream in)
        +
        public void loadInputStream(List<String> outList,
        +                            List<String> errList,
        +                            Shell.Async.Callback callback,
        +                            InputStream in)
        Asynchronously load an input stream to the shell, stores outputs to the two lists, and call the callback when the InputStream is loaded and the outputs are done.

        This command is useful for loading a script stored in the APK. An InputStream can be opened from assets with AssetManager.open(String) or from raw resources - with Resources.openRawResource(int).

        + with Resources.openRawResource(int). +

        + Simply performs execAsyncTask(outList, errList, callback, createLoadStreamTask(in))

        Parameters:
        -
        output - the list to store STDOUT outputs.
        -
        error - the list to store STDERR outputs.
        +
        outList - the list storing STDOUT outputs. null to ignore outputs.
        +
        errList - the list storing STDERR outputs. null to ignore outputs.
        callback - the callback when the InputStream is loaded and the outputs are done.
        in - the InputStream to load
      - - - -
        -
      • -

        isAlive

        -
        public abstract boolean isAlive()
        -
        Return whether the Shell is still alive.
        -
        -
        Returns:
        -
        true if the Shell is still alive.
        -
        -
      • -
    diff --git a/docs/com/topjohnwu/superuser/ShellUtils.html b/docs/com/topjohnwu/superuser/ShellUtils.html new file mode 100644 index 00000000..d0df6864 --- /dev/null +++ b/docs/com/topjohnwu/superuser/ShellUtils.html @@ -0,0 +1,494 @@ + + + + + +ShellUtils (libsu API) + + + + + + + + + + + + +
    +
    com.topjohnwu.superuser
    +

    Class ShellUtils

    +
    +
    + +
    +
      +
    • +
      +
      +
      public final class ShellUtils
      +extends Object
      +
      Some handy utility methods that are used in libsu.
      +
    • +
    +
    +
    + +
    +
    +
      +
    • + +
        +
      • + + +

        Method Detail

        + + + +
          +
        • +

          genRandomAlphaNumString

          +
          public static CharSequence genRandomAlphaNumString(int length)
          +
          Generate a random string containing only alphabet and numbers.
          +
          +
          Parameters:
          +
          length - the length of the desired random string.
          +
          Returns:
          +
          the random string.
          +
          +
        • +
        + + + +
          +
        • +

          isValidOutput

          +
          public static boolean isValidOutput(List<String> out)
          +
          Test whether the list is null or empty or all elements are empty strings.
          +
          +
          Parameters:
          +
          out - the output of a shell command.
          +
          Returns:
          +
          false if the list is null or empty or all elements are empty strings.
          +
          +
        • +
        + + + +
          +
        • +

          fastCmd

          +
          public static String fastCmd(Shell shell,
          +                             String cmd)
          +
          Run a single line command and get a single line output.
          +
          +
          Parameters:
          +
          shell - a shell instance.
          +
          cmd - the single line command.
          +
          Returns:
          +
          the last line of the output of the command, null if no output is available.
          +
          +
        • +
        + + + +
          +
        • +

          fastCmdResult

          +
          public static boolean fastCmdResult(Shell shell,
          +                                    String cmd)
          +
          Run a single line command and return whether the command returns 0 (success).
          +
          +
          Parameters:
          +
          shell - a shell instance.
          +
          cmd - the single line command.
          +
          Returns:
          +
          true if the command succeed.
          +
          +
        • +
        + + + + + + + +
          +
        • +

          checkSum

          +
          public static boolean checkSum(String alg,
          +                               File file,
          +                               String reference)
          +
          Check the checksum of a file using a specific algorithm and compare it with a reference.
          +
          +
          Parameters:
          +
          alg - the algorithm name used in MessageDigest.getInstance(String).
          +
          file - the file to be tested.
          +
          reference - the reference checksum.
          +
          Returns:
          +
          true if the file's checksum matches reference.
          +
          +
        • +
        + + + +
          +
        • +

          onMainThread

          +
          public static boolean onMainThread()
          +
          Check if current thread is main thread.
          +
          +
          Returns:
          +
          true if the current thread is the main thread.
          +
          +
        • +
        + + + +
          +
        • +

          cleanInputStream

          +
          public static void cleanInputStream(InputStream in)
          +
          Discard all data currently available in an InputStream.
          +
          +
          Parameters:
          +
          in - the InputStream to be cleaned.
          +
          +
        • +
        + + + +
          +
        • +

          readFully

          +
          public static void readFully(InputStream in,
          +                             byte[] b)
          +                      throws IOException
          +
          Same as readFully(in, b, 0, b.length)
          +
          +
          Throws:
          +
          IOException
          +
          +
        • +
        + + + +
          +
        • +

          readFully

          +
          public static void readFully(InputStream in,
          +                             byte[] b,
          +                             int off,
          +                             int len)
          +                      throws IOException
          +
          Read exactly len bytes from the InputStream.
          +
          +
          Parameters:
          +
          in - source.
          +
          b - the byte array to store the data.
          +
          off - the start offset in the data.
          +
          len - the number of bytes to be read.
          +
          Throws:
          +
          EOFException - if this stream reaches the end before reading all the bytes.
          +
          IOException - if an I/O error occurs.
          +
          +
        • +
        + + + +
          +
        • +

          gcd

          +
          public static long gcd(long u,
          +                       long v)
          +
          Get the greatest common divisor of 2 integers with binary algorithm.
          +
          +
          Parameters:
          +
          u - an integer.
          +
          v - an integer.
          +
          Returns:
          +
          the greatest common divisor.
          +
          +
        • +
        +
      • +
      +
    • +
    +
    +
    + + + + + + + diff --git a/docs/com/topjohnwu/superuser/io/SuFile.html b/docs/com/topjohnwu/superuser/io/SuFile.html index f9398aea..56171f9e 100644 --- a/docs/com/topjohnwu/superuser/io/SuFile.html +++ b/docs/com/topjohnwu/superuser/io/SuFile.html @@ -2,9 +2,9 @@ - + SuFile (libsu API) - + @@ -18,7 +18,7 @@ catch(err) { } //--> -var methods = {"i0":10,"i1":10,"i2":10,"i3":10,"i4":10,"i5":10,"i6":10,"i7":10,"i8":10,"i9":10,"i10":10,"i11":10,"i12":10,"i13":10,"i14":10,"i15":10,"i16":10,"i17":10,"i18":10,"i19":10,"i20":10,"i21":10,"i22":10,"i23":10,"i24":10,"i25":10,"i26":10,"i27":10,"i28":10,"i29":10,"i30":10}; +var methods = {"i0":10,"i1":10,"i2":10,"i3":10,"i4":10,"i5":10,"i6":10,"i7":10,"i8":10,"i9":10,"i10":10,"i11":10,"i12":10,"i13":10,"i14":10,"i15":10,"i16":10,"i17":10,"i18":10,"i19":10,"i20":10,"i21":10,"i22":10,"i23":10,"i24":10,"i25":10,"i26":10,"i27":10,"i28":10,"i29":10,"i30":10,"i31":10,"i32":10}; var tabs = {65535:["t0","All Methods"],2:["t2","Instance Methods"],8:["t4","Concrete Methods"]}; var altColor = "altColor"; var rowColor = "rowColor"; @@ -49,7 +49,7 @@ + If a root shell is required, it will get a Shell instance via Shell.getShell(). + The shell backed operations require: rm, rmdir, readlink, mv, + ls, mkdir, touch, or optionally for better support, + blockdev and stat. + All required tools are available on modern Android versions (tested on Lollipop+), + older versions might need to install busybox to make things work properly. + Some operations could have oddities due to the very limited tools available, check the method + descriptions for more info before using it.
    See Also:
    -
    Serialized Form
    +
    BusyBox, +Serialized Form
@@ -191,10 +198,16 @@

Constructor Summary

SuFile(String pathname)  +SuFile(String pathname, + boolean shell) +
Create a new SuFile using a path.
+ + + SuFile(String parent, String child)  - + SuFile(URI uri)  @@ -249,94 +262,104 @@

Method Summary

getAbsoluteFile()  +String +getAbsolutePath()  + + SuFile getCanonicalFile()  - + +String +getCanonicalPath()  + + long getFreeSpace()  - + SuFile getParentFile()  - + long getTotalSpace()  - + long getUsableSpace()  - + boolean isDirectory()  - + boolean isFile()  - + long lastModified()  - + long -length()  +length() +
Returns the length of the file denoted by this abstract pathname.
+ - + String[] list()  - + String[] list(FilenameFilter filter)  - + SuFile[] listFiles()  - + SuFile[] listFiles(FileFilter filter)  - + SuFile[] listFiles(FilenameFilter filter)  - + boolean mkdir()  - + boolean mkdirs()  - + boolean renameTo(File dest)  - + boolean setExecutable(boolean executable, boolean ownerOnly)  - + boolean setLastModified(long time)
Sets the last-modified time of the file or directory named by this abstract pathname.
- + boolean setReadable(boolean readable, boolean ownerOnly)  - + boolean setReadOnly()  - + boolean setWritable(boolean writable, boolean ownerOnly)  @@ -347,7 +370,7 @@

Method Summary

Methods inherited from class java.io.File

-compareTo, createTempFile, createTempFile, equals, getAbsolutePath, getCanonicalPath, getName, getParent, getPath, hashCode, isAbsolute, isHidden, listRoots, setExecutable, setReadable, setWritable, toPath, toString, toURI, toURL +compareTo, createTempFile, createTempFile, equals, getName, getParent, getPath, hashCode, isAbsolute, isHidden, listRoots, setExecutable, setReadable, setWritable, toPath, toString, toURI, toURL
  • @@ -425,7 +448,7 @@

    SuFile

    -
      +
      • SuFile

        public SuFile(File file,
        @@ -438,6 +461,22 @@ 

        SuFile

      + + + +
        +
      • +

        SuFile

        +
        public SuFile(String pathname,
        +              boolean shell)
        +
        Create a new SuFile using a path.
        +
        +
        Parameters:
        +
        pathname - the path to the file.
        +
        shell - whether use shell for operations.
        +
        +
      • +
    @@ -549,6 +588,19 @@

    exists

+ + + + @@ -562,6 +614,22 @@

getAbsoluteFile

+ + + + @@ -676,9 +744,17 @@

lastModified

  • length

    public long length()
    +
    Returns the length of the file denoted by this abstract pathname. +

    + Note: If there is no blockdev and stat in PATH, the file size is + the value reported from ls -ld, which will not correctly report the size of block files.

    Overrides:
    length in class File
    +
    Returns:
    +
    the size in bytes of the underlying file.
    +
    See Also:
    +
    File.length()
  • @@ -892,7 +968,7 @@

    listFiles

    diff --git a/docs/com/topjohnwu/superuser/io/package-summary.html b/docs/com/topjohnwu/superuser/io/package-summary.html index 5d2ba639..8e2a1fd8 100644 --- a/docs/com/topjohnwu/superuser/io/package-summary.html +++ b/docs/com/topjohnwu/superuser/io/package-summary.html @@ -2,9 +2,9 @@ - + com.topjohnwu.superuser.io (libsu API) - + @@ -87,6 +87,36 @@

    Package com.topjohnwu.superuser.io

    A File implementation with root access.
    + +SuFileInputStream + +
    An InputStream that read files using the global shell instance.
    + + + +SuFileOutputStream + +
    An OutputStream that read files using the global shell instance.
    + + + +SuProcessFileInputStream + +
    An InputStream that read files by opening a new root process.
    + + + +SuProcessFileOutputStream + +
    An OutputStream that write files by opening a new root process.
    + + + +SuRandomAccessFile + +
    Access files using the global shell instance and mimics RandomAccessFile.
    + + diff --git a/docs/com/topjohnwu/superuser/io/package-tree.html b/docs/com/topjohnwu/superuser/io/package-tree.html index 263f20a0..4aa225b6 100644 --- a/docs/com/topjohnwu/superuser/io/package-tree.html +++ b/docs/com/topjohnwu/superuser/io/package-tree.html @@ -2,9 +2,9 @@ - + com.topjohnwu.superuser.io Class Hierarchy (libsu API) - + @@ -85,6 +85,27 @@

    Class Hierarchy

  • com.topjohnwu.superuser.io.SuFile
  • +
  • java.io.InputStream (implements java.io.Closeable) + +
  • +
  • java.io.OutputStream (implements java.io.Closeable, java.io.Flushable) + +
  • +
  • com.topjohnwu.superuser.io.SuRandomAccessFile (implements java.io.Closeable, java.io.DataInput, java.io.DataOutput)
  • diff --git a/docs/com/topjohnwu/superuser/package-frame.html b/docs/com/topjohnwu/superuser/package-frame.html index 60c6c642..79575eff 100644 --- a/docs/com/topjohnwu/superuser/package-frame.html +++ b/docs/com/topjohnwu/superuser/package-frame.html @@ -2,9 +2,9 @@ - + com.topjohnwu.superuser (libsu API) - + @@ -16,15 +16,18 @@

    Interfaces

  • Shell.Async.Callback
  • Shell.Container
  • Shell.GetShellCallback
  • +
  • Shell.Task
  • Classes

    Exceptions

      diff --git a/docs/com/topjohnwu/superuser/package-summary.html b/docs/com/topjohnwu/superuser/package-summary.html index ca56ef98..2ad2eb80 100644 --- a/docs/com/topjohnwu/superuser/package-summary.html +++ b/docs/com/topjohnwu/superuser/package-summary.html @@ -2,9 +2,9 @@ - + com.topjohnwu.superuser (libsu API) - + @@ -99,6 +99,12 @@

      Package com.topjohnwu.superuser

      The callback used in Shell.getShell(GetShellCallback).
      + +Shell.Task + +
      A task that can be executed by a shell with the method Shell.execTask(Task).
      + + @@ -111,41 +117,53 @@

      Package com.topjohnwu.superuser

      +BusyBox + +
      A class that handles the bundled BusyBox.
      + + + CallbackList<E>
      An AbstractList that calls onAddElement when a new element is added to the list.
      - + Shell
      A class providing an API to an interactive (root) shell.
      - + Shell.Async
      High level API for asynchronous operations
      - + Shell.ContainerApp
      A subclass of Application that implements Shell.Container.
      - + Shell.Initializer
      The initializer when a new Shell is constructed.
      - + Shell.Sync
      High level API for synchronous operations
      + +ShellUtils + +
      Some handy utility methods that are used in libsu.
      + + diff --git a/docs/com/topjohnwu/superuser/package-tree.html b/docs/com/topjohnwu/superuser/package-tree.html index 1282563a..0e35e449 100644 --- a/docs/com/topjohnwu/superuser/package-tree.html +++ b/docs/com/topjohnwu/superuser/package-tree.html @@ -2,9 +2,9 @@ - + com.topjohnwu.superuser Class Hierarchy (libsu API) - + @@ -89,6 +89,7 @@

      Class Hierarchy

    +
  • com.topjohnwu.superuser.BusyBox
  • android.content.Context
  • +
  • com.topjohnwu.superuser.BusyBox
  • android.content.Context
    • android.content.ContextWrapper @@ -108,10 +109,32 @@

      Class Hierarchy

    • com.topjohnwu.superuser.io.SuFile
  • +
  • java.io.InputStream (implements java.io.Closeable) + +
  • +
  • java.io.OutputStream (implements java.io.Closeable, java.io.Flushable) + +
  • com.topjohnwu.superuser.Shell (implements java.io.Closeable)
  • com.topjohnwu.superuser.Shell.Async
  • com.topjohnwu.superuser.Shell.Initializer
  • com.topjohnwu.superuser.Shell.Sync
  • +
  • com.topjohnwu.superuser.ShellUtils
  • +
  • com.topjohnwu.superuser.io.SuRandomAccessFile (implements java.io.Closeable, java.io.DataInput, java.io.DataOutput)
  • java.lang.Throwable (implements java.io.Serializable) diff --git a/docs/serialized-form.html b/docs/serialized-form.html index 36ef8c78..bec54881 100644 --- a/docs/serialized-form.html +++ b/docs/serialized-form.html @@ -2,9 +2,9 @@ - + Serialized Form (libsu API) - + @@ -94,10 +94,22 @@

    Class

    Serialized Fields

  • diff --git a/superuser/src/main/java/com/topjohnwu/superuser/BusyBox.java b/superuser/src/main/java/com/topjohnwu/superuser/BusyBox.java index f9581fc1..a390d3c4 100644 --- a/superuser/src/main/java/com/topjohnwu/superuser/BusyBox.java +++ b/superuser/src/main/java/com/topjohnwu/superuser/BusyBox.java @@ -27,13 +27,61 @@ import java.util.Arrays; import java.util.List; -public class BusyBox { +/** + * A class that handles the bundled BusyBox. + *

    + * {@code libsu} bundles with busybox binaries for both arm and x86 (arm64 and x64 are also covered). + * Developers using {@code libsu} can easily access busybox applets by calling {@link #setup(Context)} + * before any new shell is created (place this in the same place where you call + * {@link Shell#setFlags(int)}) and {@link Shell#setInitializer(Shell.Initializer)}. + * After calling {@link #setup(Context)}, busybox will be installed in the app's internal storage, + * and all new shells created will have the path to busybox prepended to {@code PATH}. + * This makes sure all commands are using the applets from busybox, providing predictable + * behavior so that developers can have less headache handling different implementation of the + * common shell utilities. Some operations in {@link com.topjohnwu.superuser.io} depends on a + * busybox to work properly, check before using them. + *

    + * Note: the busybox binaries will add around 1.6MB to your APK, for developers not willing + * to use the busybox binaries bundled in {@code libsu}, you can use proguard to remove it: + * remember to NOT call {@link #setup(Context)} anywhere in your code, and enable both + * minifyEnabled and shrinkResources in your release builds. For more info, please + * check the official documentation. + */ +public final class BusyBox { + + private BusyBox() {} + /** + * The path pointing to the folder where busybox is installed. + *

    + * If your app would like to rely on external busybox, you can directly assign the path to this field. + * All new shell instances created will have this directory prepended to {@code PATH}. + *

    + * For example: Magisk Manager relies on the Magisk's internal busybox (located in + * {@code /sbin/.core/busybox}). So instead of calling {@link #setup(Context)}, it can directly + * assign the busybox path to this field to discard the bundled busybox binaries. + * ({@code BusyBox.BB_PATH = new File("/sbin/.core/busybox")}). + */ public static File BB_PATH = null; private static final String ARM_MD5 = "9adae2e0993fb6f233cd750f13393695"; private static final String X86_MD5 = "498d1ec0b47e31b58074e533e664bd13"; + /** + * Setup a busybox environment using the bundled busybox binaries. + *

    + * Busybox will be installed to the internal data of the application. On Android 7.0+, it + * will install busybox to Device Protected Storage, so developers willing to support + * Direct Boot + * can use it without an issue. + *

    + * After calling this method, {@link #BB_PATH} will point to the folder where the busybox is + * installed. + *

    + * If you are willing to let proguard to remove the bundled busybox binary to reduce the APK + * size, do NOT call this method. + * @param context a {@link Context} of the current app. + */ public static void setup(Context context) { Context de = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ? context.createDeviceProtectedStorageContext() : context; diff --git a/superuser/src/main/java/com/topjohnwu/superuser/ShellUtils.java b/superuser/src/main/java/com/topjohnwu/superuser/ShellUtils.java index 52c26634..4d51adb5 100644 --- a/superuser/src/main/java/com/topjohnwu/superuser/ShellUtils.java +++ b/superuser/src/main/java/com/topjohnwu/superuser/ShellUtils.java @@ -34,6 +34,9 @@ import java.util.ArrayList; import java.util.List; +/** + * Some handy utility methods that are used in {@code libsu}. + */ public final class ShellUtils { private ShellUtils() {} @@ -43,6 +46,11 @@ private ShellUtils() {} private static final String NUMBERS = "0123456789"; private static final String ALPHANUM = LOWER_CASE + UPPER_CASE + NUMBERS; + /** + * Generate a random string containing only alphabet and numbers. + * @param length the length of the desired random string. + * @return the random string. + */ public static CharSequence genRandomAlphaNumString(int length) { SecureRandom random = new SecureRandom(); StringBuilder builder = new StringBuilder(); @@ -52,6 +60,11 @@ public static CharSequence genRandomAlphaNumString(int length) { return builder; } + /** + * Test whether the list is {@code null} or empty or all elements are empty strings. + * @param out the output of a shell command. + * @return {@code false} if the list is {@code null} or empty or all elements are empty strings. + */ public static boolean isValidOutput(List out) { if (out != null && out.size() != 0) { // Check if all empty @@ -62,6 +75,12 @@ public static boolean isValidOutput(List out) { return false; } + /** + * Run a single line command and get a single line output. + * @param shell a shell instance. + * @param cmd the single line command. + * @return the last line of the output of the command, {@code null} if no output is available. + */ @Nullable public static String fastCmd(Shell shell, String cmd) { ArrayList out = new ArrayList<>(); @@ -69,10 +88,23 @@ public static String fastCmd(Shell shell, String cmd) { return isValidOutput(out) ? out.get(out.size() - 1) : null; } + /** + * Run a single line command and return whether the command returns 0 (success). + * @param shell a shell instance. + * @param cmd the single line command. + * @return {@code true} if the command succeed. + */ public static boolean fastCmdResult(Shell shell, String cmd) { return Boolean.parseBoolean(fastCmd(shell, cmd + " >/dev/null 2>&1 && echo true || echo false")); } + /** + * Pump all data from an {@link InputStream} to an {@link OutputStream}. + * @param in source. + * @param out target. + * @return the total bytes transferred. + * @throws IOException when any read/write operations throws an error. + */ public static long pump(InputStream in, OutputStream out) throws IOException { int read; long total = 0; @@ -85,7 +117,14 @@ public static long pump(InputStream in, OutputStream out) throws IOException { return total; } - public static boolean checkSum(String alg, File file, String test) { + /** + * Check the checksum of a file using a specific algorithm and compare it with a reference. + * @param alg the algorithm name used in {@link MessageDigest#getInstance(String)}. + * @param file the file to be tested. + * @param reference the reference checksum. + * @return {@code true} if the file's checksum matches reference. + */ + public static boolean checkSum(String alg, File file, String reference) { // Verify checksum try (FileInputStream in = new FileInputStream(file)) { MessageDigest digest = MessageDigest.getInstance(alg); @@ -101,16 +140,24 @@ public void write(@NonNull byte[] b, int off, int len) throws IOException {} for (byte b : chksum) { sb.append(String.format("%02x", b & 0xff)); } - return TextUtils.equals(sb, test); + return TextUtils.equals(sb, reference); } catch (NoSuchAlgorithmException | IOException e) { return false; } } + /** + * Check if current thread is main thread. + * @return {@code true} if the current thread is the main thread. + */ public static boolean onMainThread() { return ((Looper.myLooper() != null) && (Looper.myLooper() == Looper.getMainLooper())); } + /** + * Discard all data currently available in an {@link InputStream}. + * @param in the {@link InputStream} to be cleaned. + */ public static void cleanInputStream(InputStream in) { try { while (in.available() != 0) @@ -118,10 +165,22 @@ public static void cleanInputStream(InputStream in) { } catch (IOException ignored) {} } + /** + * Same as {@code readFully(in, b, 0, b.length)} + */ public static void readFully(InputStream in, byte[] b) throws IOException { readFully(in, b, 0, b.length); } + /** + * Read exactly len bytes from the {@link InputStream}. + * @param in source. + * @param b the byte array to store the data. + * @param off the start offset in the data. + * @param len the number of bytes to be read. + * @throws EOFException if this stream reaches the end before reading all the bytes. + * @throws IOException if an I/O error occurs. + */ public static void readFully(InputStream in, byte[] b, int off, int len) throws IOException { int n = 0; while (n < len) { @@ -132,6 +191,12 @@ public static void readFully(InputStream in, byte[] b, int off, int len) throws } } + /** + * Get the greatest common divisor of 2 integers with binary algorithm. + * @param u an integer. + * @param v an integer. + * @return the greatest common divisor. + */ public static long gcd(long u, long v) { if (u == 0) return v; if (v == 0) return u; diff --git a/superuser/src/main/java/com/topjohnwu/superuser/internal/RandomAccessFileWrapper.java b/superuser/src/main/java/com/topjohnwu/superuser/internal/RandomAccessFileWrapper.java index 3f0a0d90..84c70340 100644 --- a/superuser/src/main/java/com/topjohnwu/superuser/internal/RandomAccessFileWrapper.java +++ b/superuser/src/main/java/com/topjohnwu/superuser/internal/RandomAccessFileWrapper.java @@ -64,7 +64,7 @@ public void write(byte[] b) throws IOException { } @Override - public void write(byte[] b, int off, int len) throws IOException { + public void write(@NonNull byte[] b, int off, int len) throws IOException { raf.write(b, off, len); } diff --git a/superuser/src/main/java/com/topjohnwu/superuser/internal/ShellFileIO.java b/superuser/src/main/java/com/topjohnwu/superuser/internal/ShellFileIO.java index 76e949f5..a9b2a24c 100644 --- a/superuser/src/main/java/com/topjohnwu/superuser/internal/ShellFileIO.java +++ b/superuser/src/main/java/com/topjohnwu/superuser/internal/ShellFileIO.java @@ -16,6 +16,8 @@ package com.topjohnwu.superuser.internal; +import android.support.annotation.NonNull; + import com.topjohnwu.superuser.Shell; import com.topjohnwu.superuser.ShellUtils; import com.topjohnwu.superuser.io.SuFile; @@ -53,7 +55,7 @@ class ShellFileIO extends SuRandomAccessFile implements DataInputImpl, DataOutpu } @Override - public void write(byte[] b, int off, int len) throws IOException { + public void write(@NonNull byte[] b, int off, int len) throws IOException { if (off < 0 || len < 0 || off + len > b.length) throw new IndexOutOfBoundsException(); Throwable t = Shell.getShell().execTask((in, out, err) -> { diff --git a/superuser/src/main/java/com/topjohnwu/superuser/io/SuFile.java b/superuser/src/main/java/com/topjohnwu/superuser/io/SuFile.java index f0e33a59..7e7fe057 100644 --- a/superuser/src/main/java/com/topjohnwu/superuser/io/SuFile.java +++ b/superuser/src/main/java/com/topjohnwu/superuser/io/SuFile.java @@ -301,7 +301,7 @@ public long lastModified() { * Returns the length of the file denoted by this abstract pathname. *

    * Note: If there is no {@code blockdev} and {@code stat} in {@code PATH}, the file size is - * the value reported from {@code ls -l}, which will not correctly report the size of block files. + * the value reported from {@code ls -ld}, which will not correctly report the size of block files. * @return the size in bytes of the underlying file. * @see File#length() */ diff --git a/superuser/src/main/java/com/topjohnwu/superuser/io/SuFileInputStream.java b/superuser/src/main/java/com/topjohnwu/superuser/io/SuFileInputStream.java index 5bda2391..fdb29bff 100644 --- a/superuser/src/main/java/com/topjohnwu/superuser/io/SuFileInputStream.java +++ b/superuser/src/main/java/com/topjohnwu/superuser/io/SuFileInputStream.java @@ -24,12 +24,27 @@ import java.io.FileNotFoundException; import java.io.FilterInputStream; +/** + * An {@link java.io.InputStream} that read files using the global shell instance. + *

    + * This class always checks whether using a shell is necessary. If not, it simply opens a new + * {@link FileInputStream}. + *

    + * Note: this class is always buffered internally, do not add another layer of + * {@link BufferedInputStream} to add more overhead! + */ public class SuFileInputStream extends FilterInputStream { + /** + * @see FileInputStream#FileInputStream(String) + */ public SuFileInputStream(String path) throws FileNotFoundException { this(new SuFile(path)); } + /** + * @see FileInputStream#FileInputStream(File) + */ public SuFileInputStream(File file) throws FileNotFoundException { super(null); SuFile f; diff --git a/superuser/src/main/java/com/topjohnwu/superuser/io/SuFileOutputStream.java b/superuser/src/main/java/com/topjohnwu/superuser/io/SuFileOutputStream.java index 2d4d62ef..dc08d3a7 100644 --- a/superuser/src/main/java/com/topjohnwu/superuser/io/SuFileOutputStream.java +++ b/superuser/src/main/java/com/topjohnwu/superuser/io/SuFileOutputStream.java @@ -27,20 +27,41 @@ import java.io.FilterOutputStream; import java.io.IOException; +/** + * An {@link java.io.OutputStream} that read files using the global shell instance. + *

    + * This class always checks whether using a shell is necessary. If not, it simply opens a new + * {@link FileOutputStream}. + *

    + * Note: this class is always buffered internally, do not add another layer of + * {@link BufferedOutputStream} to add more overhead! + */ public class SuFileOutputStream extends FilterOutputStream { + /** + * @see FileOutputStream#FileOutputStream(String) + */ public SuFileOutputStream(String path) throws FileNotFoundException { this(path, false); } + /** + * @see FileOutputStream#FileOutputStream(String, boolean) + */ public SuFileOutputStream(String path, boolean append) throws FileNotFoundException { - this(new File(path), append); + this(new SuFile(path), append); } + /** + * @see FileOutputStream#FileOutputStream(File) + */ public SuFileOutputStream(File file) throws FileNotFoundException { this(file, false); } + /** + * @see FileOutputStream#FileOutputStream(File, boolean) + */ public SuFileOutputStream(File file, boolean append) throws FileNotFoundException { super(null); SuFile f; diff --git a/superuser/src/main/java/com/topjohnwu/superuser/io/SuProcessFileInputStream.java b/superuser/src/main/java/com/topjohnwu/superuser/io/SuProcessFileInputStream.java index 8c4fd853..07a716a6 100644 --- a/superuser/src/main/java/com/topjohnwu/superuser/io/SuProcessFileInputStream.java +++ b/superuser/src/main/java/com/topjohnwu/superuser/io/SuProcessFileInputStream.java @@ -19,18 +19,36 @@ import com.topjohnwu.superuser.ShellUtils; import java.io.File; +import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FilterInputStream; import java.io.IOException; +/** + * An {@link java.io.InputStream} that read files by opening a new root process. + *

    + * The difference between this class and {@link SuFileInputStream} is that this class does not + * use a shell to do the I/O operations; instead it directly creates a new process to read the file. + * In most cases, {@link SuFileInputStream} is sufficient; however if you expect a very high I/O + * throughput (e.g. dumping large partitions), this class is created for this purpose. + *

    + * Note: this class is always buffered internally, do not add another layer of + * {@link java.io.BufferedInputStream} to add more overhead! + */ public class SuProcessFileInputStream extends FilterInputStream { private Process process; + /** + * @see FileInputStream#FileInputStream(String) + */ public SuProcessFileInputStream(String path) throws FileNotFoundException { this(new File(path)); } + /** + * @see FileInputStream#FileInputStream(File) + */ public SuProcessFileInputStream(File file) throws FileNotFoundException { super(null); try { diff --git a/superuser/src/main/java/com/topjohnwu/superuser/io/SuProcessFileOutputStream.java b/superuser/src/main/java/com/topjohnwu/superuser/io/SuProcessFileOutputStream.java index d1209e0d..03a2b9b5 100644 --- a/superuser/src/main/java/com/topjohnwu/superuser/io/SuProcessFileOutputStream.java +++ b/superuser/src/main/java/com/topjohnwu/superuser/io/SuProcessFileOutputStream.java @@ -22,26 +22,50 @@ import java.io.File; import java.io.FileNotFoundException; +import java.io.FileOutputStream; import java.io.FilterOutputStream; import java.io.IOException; import java.io.InputStream; +/** + * An {@link java.io.OutputStream} that write files by opening a new root process. + *

    + * The difference between this class and {@link SuFileOutputStream} is that this class does not + * use a shell to do the I/O operations; instead it directly creates a new process to write the file. + * In most cases, {@link SuFileOutputStream} is sufficient; however if you expect a very high I/O + * throughput (e.g. restoring large partitions), this class is created for this purpose. + *

    + * Note: this class is always buffered internally, do not add another layer of + * {@link java.io.BufferedOutputStream} to add more overhead! + */ public class SuProcessFileOutputStream extends FilterOutputStream { private Process process; + /** + * @see FileOutputStream#FileOutputStream(String) + */ public SuProcessFileOutputStream(String path) throws FileNotFoundException { this(path, false); } + /** + * @see FileOutputStream#FileOutputStream(String, boolean) + */ public SuProcessFileOutputStream(String path, boolean append) throws FileNotFoundException { this(new File(path), append); } + /** + * @see FileOutputStream#FileOutputStream(File) + */ public SuProcessFileOutputStream(File file) throws FileNotFoundException { this(file, false); } + /** + * @see FileOutputStream#FileOutputStream(File, boolean) + */ public SuProcessFileOutputStream(File file, boolean append) throws FileNotFoundException { super(null); try { diff --git a/superuser/src/main/java/com/topjohnwu/superuser/io/SuRandomAccessFile.java b/superuser/src/main/java/com/topjohnwu/superuser/io/SuRandomAccessFile.java index d556c3f4..00fdd747 100644 --- a/superuser/src/main/java/com/topjohnwu/superuser/io/SuRandomAccessFile.java +++ b/superuser/src/main/java/com/topjohnwu/superuser/io/SuRandomAccessFile.java @@ -28,6 +28,23 @@ import java.io.FileNotFoundException; import java.io.IOException; +/** + * Access files using the global shell instance and mimics {@link java.io.RandomAccessFile}. + *

    + * This class always checks whether using a shell is necessary. If not, it simply opens a new + * {@link java.io.RandomAccessFile} with mode {@code "rw"} and behaves as a wrapper. + *

    + * File random access via shell is extremely limited, each I/O operation comes with a relatively + * large overhead. For optimal performance, please consider using {@link SuFileInputStream} and + * {@link SuFileOutputStream}, since these classes are specifically optimized for I/O using + * shell commands. + *

    + * Note: All write/writeXXX commands require {@code busybox} to work properly, as currently + * no existing Android version ships with a command {@code dd} that supports {@code notrunc} option. + * If you need root file output but unwilling to use {@code busybox}, please use + * {@link SuFileOutputStream} as it uses a special workaround that does not require {@code busybox}. + * @see java.io.RandomAccessFile + */ public abstract class SuRandomAccessFile implements DataInput, DataOutput, Closeable { public static SuRandomAccessFile open(String path) throws FileNotFoundException {