Welcome to XDA

Search to go directly to your device's forum

Register an account

Unlock full posting privileges

Ask a question

No registration required
Post Reply

[Library] Cmd library: Execute Your Java Codes With Root Access Privileges

OP Bassel Bakr

20th August 2014, 02:10 PM   |  #1  
Bassel Bakr's Avatar
OP Senior Member
Flag Cairo
Thanks Meter: 323
 
207 posts
Join Date:Joined: May 2013
More
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:
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:

Code:
...
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:

Code:
...
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):

Code:
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:

Code:
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:
    Code:
    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
Last edited by Bassel Bakr; 21st August 2014 at 10:28 AM.
The Following User Says Thank You to Bassel Bakr For This Useful Post: [ View ]
Post Reply Subscribe to Thread
Previous Thread Next Thread
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes