[IDEs, Libraries, & Programming Tools] Bassel Bakr:
Synopsis:

Have you ever wanted as root apps developer to use your favourite Java codes instead of bash/shell commands?

Have you grown tired of Runtime.getRuntime.exec("su") and ProcessBuilder("su").start()?

I did and still do, that's why I've been searching for a solution for my problem until I found out in AOSP source code that some of *.java files run with root access, tracking the way they execute them with root access led me to make this simple library.

Description:

Cmd library -short for Command- is an open source (licensed under Apache licence V2) that allows you to execute java commands with root access privileges by passing package name, full class name and whether your app is a system app or not in just two lines of codes.

For instance, suppose you want to flash a *.img recovery image, the first thing comes to your mind is this code:

busybox dd if=/path/to/recovery.img of=/path/to/recoveryPartition

lets say

/sdcard/recovery.img

is the file path and

/dev/block/mmcblk0p12

is the partition (Samsung GALAXY Ace Plus GT-S7500)

Here is how to implement it:

...
Proccess proc = Runtime.getRuntime().exec("su");
OutputStream stream = proc.getOutputStream();
stream.write("busybox dd if=/sdcard/recovery.img of=/dev/block/mmcblk0p12".getBytes());
stream.flush();
...

Pretty simple isn't it, now suppose you don't know anything about bash codes, what will you do?

Let me answer this question:

1) Learn some bash.

2) Use Cmd library with java codes.

Here is the same implementaion with Cmd library:

...
JavaRoot root = JavaRoot.newInstance(getPackageName(), RootCommands.class.getName(), false);
root.execute("/sdcard/recovery.img", "/dev/block/mmcblk0p12")
...

And in RootCommands.java file (should not be an inner class):

package com.bassel.example;

import com.bassel.cmd.Command;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class Main extends Command
{
private byte[] buffer;

private File recovery, partition;

private FileInputStream in;

private FileOutputStream out;

//static main method implementation is a must
@Override
public static void main(String[] args)
{
//required to start
new Main().run(args);
}

//the begging just like onCreate
@Override
public void onRun()
{
if(argsCount() < 2) showUsage();

System.out.println(String.format("Flashing %s to %s", getArg(0), getArg(1)));

recovery = new File(nextArg());
partition = new File(nextArg());
buffer = new byte[1024 * 1024];

try
{
in = new FileInputStream(recovery);
out = new FileOutputStream(partition);

while(in.read(buffer) > 0)
{
out.write(buffer);
out.flush();
}

in.close();
out.close();

System.out.println("Flashed successfully!");
}
catch (Exception e)
{e.printStackTrace(System.err);}
}

//called upon calling showUsage()
@Override
public void onShowUsage()
{
System.err.println("Two args are needed!");
}

//called once an exception is caught
@Override
public void onExceptionCaught(Exception exception)
{
exception.printStackTrace(System.err);
}
}

Quite lengthy but sometimes we prefer using Java codes to bash ones, don't we?

Here is another example for listing /data files:

package com.bassel. example;

import java.io.File;

//Without extending Command.class
public class Main
{

@Override
public static void main(String[] args)
{
String[] files = new File("/data").list();

for(String file : files)
{
System.out.println(file);
}
}

}

Usage in depth:

Check root access:

Cmd.root();

No root:

Cmd.SH.ex(String command, String... args);

Cmd.SH.ex(String[] commands);

Cmd.SH.ex(List commands);

With root access:

Cmd.SU.ex(String command, String... args);

Cmd.SU.ex(String[] commands);

Cmd.SU.ex(List commands);

JavaRoot java = JavaRoot.newInstance(String packageName, String className, boolean isSystemApp);

java.execute(String... args);

java.executeInBackground(String... args);

All previous methods aside of the last one:

java.executeInBackground(String... args);

return an instance of type Output that has the following methods:

boolean success() //returns true if process exit value = 0 else false
String getString() //returns output in String format
String[] getArray() //returns output in String Array format
List getList() //returns output in String List format
int getExitValue() //returns process exit value
String toString() //returns process status and output in String format

Converting:

String string = ...;

String[] array = ...;

List list = ...;

String s1 = Convert.array2string(array);

String s2 = Convert.list2string(list);

String[] a1 = Convert.list2array(list);

String[] a2 = Convert.string2array(string);

List l1 = Convert.array2list(array);

List l2 = Convert.string2list(string);

Library GitHub link:

Cmd (licensed under Apache License, Version 2.0)

Examples:

Window Manipulator