mirror of
https://github.com/topjohnwu/libsu.git
synced 2024-10-07 09:13:23 +00:00
Finalize APIs
This commit is contained in:
parent
9811c009cb
commit
d9bcf78bc8
@ -8,7 +8,6 @@ buildscript {
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.0.1'
|
||||
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0'
|
||||
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
|
@ -1,39 +1,12 @@
|
||||
package com.topjohnwu.libsuexample;
|
||||
|
||||
import android.app.Application;
|
||||
|
||||
import com.topjohnwu.superuser.Shell;
|
||||
import com.topjohnwu.superuser.ShellContainer;
|
||||
|
||||
/**
|
||||
* The {@link Application} of the Example app.
|
||||
* <p>
|
||||
* We implement {@link ShellContainer} to the {@link Application} of
|
||||
* the app, which means that we would love our root shell to live as long as the
|
||||
* application itself.
|
||||
*/
|
||||
public class ExampleApp extends Application implements ShellContainer {
|
||||
public class ExampleApp extends Shell.ContainerApp {
|
||||
|
||||
/**
|
||||
* A shell instance living alongside the lifecycle of {@link ExampleApp}
|
||||
*/
|
||||
public Shell mShell;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
// Enable verbose logging flags
|
||||
Shell.addFlags(Shell.FLAG_VERBOSE_LOGGING | Shell.FLAG_REDIRECT_STDERR);
|
||||
Shell.setGlobalContainer(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Shell getShell() {
|
||||
return mShell;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setShell(Shell shell) {
|
||||
mShell = shell;
|
||||
public ExampleApp() {
|
||||
// Set flags
|
||||
Shell.setFlags(Shell.FLAG_REDIRECT_STDERR);
|
||||
Shell.verboseLogging(BuildConfig.DEBUG);
|
||||
}
|
||||
}
|
||||
|
@ -2,15 +2,16 @@ package com.topjohnwu.libsuexample;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.topjohnwu.superuser.CallbackList;
|
||||
import com.topjohnwu.superuser.NoShellException;
|
||||
import com.topjohnwu.superuser.Shell;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public class MainActivity extends Activity {
|
||||
@ -20,7 +21,7 @@ public class MainActivity extends Activity {
|
||||
private TextView console;
|
||||
private EditText input;
|
||||
private ScrollView sv;
|
||||
private List<String> callback;
|
||||
private List<String> consoleList;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@ -32,57 +33,51 @@ public class MainActivity extends Activity {
|
||||
|
||||
Button sync_cmd = findViewById(R.id.sync_cmd);
|
||||
Button async_cmd = findViewById(R.id.async_cmd);
|
||||
Button raw_cmd = findViewById(R.id.raw_cmd);
|
||||
Button close_shell = findViewById(R.id.close_shell);
|
||||
Button sync_script = findViewById(R.id.sync_script);
|
||||
Button async_script = findViewById(R.id.async_script);
|
||||
Button clear = findViewById(R.id.clear);
|
||||
|
||||
// Run the shell command in the input box synchronously
|
||||
sync_cmd.setOnClickListener(v -> {
|
||||
Shell.su(callback, input.getText().toString());
|
||||
Shell.Sync.su(consoleList, input.getText().toString());
|
||||
input.setText("");
|
||||
});
|
||||
|
||||
// Run the shell command in the input box asynchronously
|
||||
// Run the shell command in the input box asynchronously.
|
||||
// Also demonstrates that Async.Callback works
|
||||
async_cmd.setOnClickListener(v -> {
|
||||
Shell.su_async(callback, input.getText().toString());
|
||||
Shell.Async.su(consoleList, consoleList,
|
||||
(out, err) -> Log.d(TAG, "in_async_callback"),
|
||||
input.getText().toString());
|
||||
input.setText("");
|
||||
});
|
||||
|
||||
// Run the shell command in the input box ignoring output asynchronously
|
||||
raw_cmd.setOnClickListener(v -> {
|
||||
Shell.su_raw(input.getText().toString());
|
||||
input.setText("");
|
||||
});
|
||||
|
||||
// Load a script from raw resources
|
||||
sync_script.setOnClickListener(v -> {
|
||||
// Closing a shell is always synchronous
|
||||
close_shell.setOnClickListener(v -> {
|
||||
try {
|
||||
Shell.getShell().loadInputStream(callback, callback,
|
||||
getResources().openRawResource(R.raw.info));
|
||||
} catch (NoShellException e) {
|
||||
Shell.getShell().close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
|
||||
// Load a script from raw resources
|
||||
async_script.setOnClickListener(v -> {
|
||||
try {
|
||||
Shell.getShell().loadInputStreamAsync(callback, callback,
|
||||
getResources().openRawResource(R.raw.count));
|
||||
} catch (NoShellException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
// Load a script from raw resources synchronously
|
||||
sync_script.setOnClickListener(v ->
|
||||
Shell.Sync.loadScript(consoleList,
|
||||
getResources().openRawResource(R.raw.info)));
|
||||
|
||||
clear.setOnClickListener(v -> {
|
||||
callback.clear();
|
||||
console.setText("");
|
||||
});
|
||||
// Load a script from raw resources asynchronously
|
||||
async_script.setOnClickListener(v ->
|
||||
Shell.Async.loadScript(consoleList,
|
||||
getResources().openRawResource(R.raw.count))
|
||||
);
|
||||
|
||||
// We create a ShellCallback to update the UI with the Shell output
|
||||
callback = new CallbackList<String>() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
clear.setOnClickListener(v -> consoleList.clear());
|
||||
|
||||
// We create a CallbackList to update the UI with the Shell output
|
||||
consoleList = new CallbackList<String>() {
|
||||
private StringBuilder builder = new StringBuilder();
|
||||
|
||||
@Override
|
||||
public void onAddElement(String s) {
|
||||
@ -94,6 +89,7 @@ public class MainActivity extends Activity {
|
||||
@Override
|
||||
public void clear() {
|
||||
builder = new StringBuilder();
|
||||
handler.post(() -> console.setText(""));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -63,12 +63,12 @@
|
||||
android:text="Async CMD" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/raw_cmd"
|
||||
android:id="@+id/close_shell"
|
||||
style="?android:borderlessButtonStyle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Raw CMD" />
|
||||
android:text="Close Shell" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -18,8 +18,6 @@ android {
|
||||
defaultConfig {
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 27
|
||||
versionCode 10
|
||||
versionName "0.1.0"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
@ -32,6 +30,7 @@ android {
|
||||
|
||||
task javadoc(type: Javadoc) {
|
||||
failOnError false
|
||||
title = 'libsu API'
|
||||
source = android.sourceSets.main.java.sourceFiles
|
||||
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
|
||||
classpath += configurations.compile
|
||||
@ -42,4 +41,5 @@ task javadoc(type: Javadoc) {
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation 'com.android.support:support-annotations:27.0.2'
|
||||
}
|
||||
|
@ -26,8 +26,13 @@ import java.util.List;
|
||||
|
||||
public abstract class CallbackList<E> extends AbstractList<E> {
|
||||
|
||||
private Handler handler = null;
|
||||
private List<E> mBase = null;
|
||||
/**
|
||||
* The internal handler to run the callback on the main thread.
|
||||
* It will only get created when the constructor is called on the main thread.
|
||||
*/
|
||||
protected Handler handler = null;
|
||||
|
||||
protected List<E> mBase = null;
|
||||
|
||||
/**
|
||||
* Sole constructor. Will setup a {@link Handler} if constructed in the main thread.
|
||||
|
@ -1,12 +1,13 @@
|
||||
package com.topjohnwu.superuser;
|
||||
|
||||
/**
|
||||
* Created by topjohnwu on 2018/1/19.
|
||||
* Thrown when it is impossible to construct {@code Shell}.
|
||||
* This is a runtime exception, and should happen very rarely.
|
||||
*/
|
||||
|
||||
public class NoShellException extends Exception {
|
||||
public class NoShellException extends RuntimeException {
|
||||
|
||||
public NoShellException() {
|
||||
super("Unable to start a shell!");
|
||||
super("Impossible to create a shell!");
|
||||
}
|
||||
}
|
||||
|
@ -1,67 +0,0 @@
|
||||
package com.topjohnwu.superuser;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
|
||||
/**
|
||||
* Created by topjohnwu on 2018/1/22.
|
||||
*/
|
||||
|
||||
public abstract class PoolThread {
|
||||
|
||||
private static final int NOT_STARTED = 0;
|
||||
private static final int RUNNING = 1;
|
||||
private static final int DONE = 2;
|
||||
|
||||
private int status;
|
||||
|
||||
PoolThread() {
|
||||
status = NOT_STARTED;
|
||||
}
|
||||
|
||||
abstract void run();
|
||||
|
||||
PoolThread start() {
|
||||
AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
notifyRunning();
|
||||
PoolThread.this.run();
|
||||
notifyDone();
|
||||
}
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
synchronized void waitTillStart() {
|
||||
while (status == NOT_STARTED) {
|
||||
try {
|
||||
wait();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void join() throws InterruptedException {
|
||||
join(0, 0);
|
||||
}
|
||||
|
||||
public void join(long millis) throws InterruptedException {
|
||||
join(millis, 0);
|
||||
}
|
||||
|
||||
public synchronized void join(long millis, int nanos) throws InterruptedException {
|
||||
while (status != DONE)
|
||||
wait(millis, nanos);
|
||||
}
|
||||
|
||||
private synchronized void notifyRunning() {
|
||||
status = RUNNING;
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
private synchronized void notifyDone() {
|
||||
status = DONE;
|
||||
notifyAll();
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,10 +0,0 @@
|
||||
package com.topjohnwu.superuser;
|
||||
|
||||
/**
|
||||
* Created by topjohnwu on 2018/1/19.
|
||||
*/
|
||||
|
||||
public interface ShellContainer {
|
||||
Shell getShell();
|
||||
void setShell(Shell shell);
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
package com.topjohnwu.superuser;
|
||||
|
||||
/**
|
||||
* Created by topjohnwu on 2018/1/21.
|
||||
*/
|
||||
|
||||
public class ShellInitializer {
|
||||
public void onShellInit(Shell shell) {}
|
||||
public void onRootShellInit(Shell shell) {}
|
||||
}
|
@ -9,10 +9,6 @@ import java.io.InputStreamReader;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by topjohnwu on 2018/1/19.
|
||||
*/
|
||||
|
||||
class StreamGobbler extends Thread {
|
||||
|
||||
private static final String TAG = "SHELLOUT";
|
||||
|
Loading…
Reference in New Issue
Block a user