#29: Remove superuser module and import it from the new repo

This commit is contained in:
Joshua Ott 2017-08-22 20:43:31 +02:00
parent aa42259163
commit 7211eaf2cf
18 changed files with 13 additions and 925 deletions

View file

@ -10,7 +10,6 @@
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/playmusicexporter" />
<option value="$PROJECT_DIR$/playmusiclib" />
<option value="$PROJECT_DIR$/superuser" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />

View file

@ -5,7 +5,6 @@
<module fileurl="file://$PROJECT_DIR$/PlayMusicExporter.iml" filepath="$PROJECT_DIR$/PlayMusicExporter.iml" />
<module fileurl="file://$PROJECT_DIR$/playmusicexporter/playmusicexporter.iml" filepath="$PROJECT_DIR$/playmusicexporter/playmusicexporter.iml" />
<module fileurl="file://$PROJECT_DIR$/playmusiclib/playmusiclib.iml" filepath="$PROJECT_DIR$/playmusiclib/playmusiclib.iml" />
<module fileurl="file://$PROJECT_DIR$/superuser/superuser.iml" filepath="$PROJECT_DIR$/superuser/superuser.iml" />
</modules>
</component>
</project>

View file

@ -25,6 +25,7 @@
buildscript {
repositories {
jcenter()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.0-beta2'
@ -35,11 +36,7 @@ buildscript {
allprojects {
repositories {
jcenter()
maven {
url 'https://maven.google.com'
}
maven {
url 'https://jitpack.io'
}
google()
maven { url 'https://jitpack.io' }
}
}

View file

@ -50,9 +50,8 @@ android {
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile project(':superuser')
compile project(':playmusiclib')
compile 'com.github.playmusicexporter:superuserlib:v1.0.0'
compile 'com.android.support:appcompat-v7:26.0.1'
compile 'com.android.support:support-v13:26.0.1'
compile 'com.android.support:design:26.0.1'
@ -63,4 +62,4 @@ dependencies {
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.1'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1'
testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1'
}
}

View file

@ -18,7 +18,7 @@ import com.github.paolorotolo.appintro.AppIntroFragment;
import java.util.Optional;
import rc.jcg.superuser.SuperUser;
import re.jcg.superuser.SuperUser;
import re.jcg.playmusicexporter.R;
import re.jcg.playmusicexporter.settings.PlayMusicExporterPreferences;

View file

@ -27,7 +27,7 @@ android {
buildToolsVersion '26.0.1'
defaultConfig {
minSdkVersion 14
minSdkVersion 21
targetSdkVersion 26
versionCode 1
versionName '1.0'
@ -45,6 +45,7 @@ android {
}
dependencies {
compile project(':superuser')
compile 'com.github.playmusicexporter:superuserlib:v1.0.0'
compile 'com.android.support:appcompat-v7:26.0.1'
compile 'com.mpatric:mp3agic:0.9.0'
}

View file

@ -29,7 +29,7 @@ import android.text.TextUtils;
import java.net.URL;
import rc.jcg.superuser.SuperUserTools;
import re.jcg.superuser.SuperUserTools;
import de.arcus.playmusiclib.utils.ImageTools;
import de.arcus.playmusiclib.items.ArtworkEntry;

View file

@ -56,8 +56,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import rc.jcg.superuser.SuperUser;
import rc.jcg.superuser.SuperUserTools;
import re.jcg.superuser.SuperUser;
import re.jcg.superuser.SuperUserTools;
import de.arcus.playmusiclib.utils.FileTools;
import de.arcus.playmusiclib.enums.ID3v2Version;
import de.arcus.playmusiclib.exceptions.CouldNotOpenDatabaseException;

View file

@ -22,4 +22,4 @@
include ':playmusicexporter', ':superuser', ':playmusiclib'
include ':playmusicexporter', ':playmusiclib'

View file

@ -1,50 +0,0 @@
/*
* Copyright (c) 2015 David Schulte
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
apply plugin: 'com.android.library'
android {
compileSdkVersion 26
buildToolsVersion '26.0.1'
defaultConfig {
minSdkVersion 14
targetSdkVersion 26
versionCode 1
versionName '1.0'
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
targetCompatibility 1.8
sourceCompatibility 1.8
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:26.0.1'
}

View file

@ -1,17 +0,0 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /home/david/android-sdks/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

View file

@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2015 David Schulte
~
~ Permission is hereby granted, free of charge, to any person obtaining a copy
~ of this software and associated documentation files (the "Software"), to deal
~ in the Software without restriction, including without limitation the rights
~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
~ copies of the Software, and to permit persons to whom the Software is
~ furnished to do so, subject to the following conditions:
~
~ The above copyright notice and this permission notice shall be included in
~ all copies or substantial portions of the Software.
~
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
~ THE SOFTWARE.
-->
<manifest package="re.icg.superuser">
</manifest>

View file

@ -1,129 +0,0 @@
/*
* Copyright (c) 2015 David Schulte
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package rc.jcg.superuser;
import java.util.ArrayList;
import java.util.List;
/**
* A dynamic growing byte buffer
*/
public class ByteBuffer {
private int mChunkSize = 4096;
private int mSize = 0;
private List<byte[]> mChunks = new ArrayList<>();
/**
* Creates a byte buffer
*/
public ByteBuffer() {
}
/**
* Creates a byte buffer
* @param chunkSize Sets the chunks size
*/
public ByteBuffer(int chunkSize) {
mChunkSize = chunkSize;
}
/**
* @return Returns the size of the buffer
*/
public long size() {
return mSize;
}
/**
* Clears the buffer
*/
public void clear() {
mSize = 0;
mChunks.clear();
}
/**
* Adds bytes to the buffer
* @param bytes The bytes to add
*/
public void append(byte[] bytes, int offset, int length) {
while(length > 0) {
int freeSpaceInEndChunk = mChunks.size() * mChunkSize - mSize;
int positionInEndChunk = mChunkSize - freeSpaceInEndChunk;
// Adds a new chunk
if (freeSpaceInEndChunk == 0) {
mChunks.add(new byte[mChunkSize]);
freeSpaceInEndChunk = mChunkSize;
positionInEndChunk = 0;
}
byte[] endChunk = mChunks.get(mChunks.size() - 1);
// We want to add more bytes the chunk can contain
if (length > freeSpaceInEndChunk) {
// Copies to end of chunk
System.arraycopy(bytes, offset, endChunk, positionInEndChunk, freeSpaceInEndChunk);
// Adds the size
mSize += freeSpaceInEndChunk;
offset += freeSpaceInEndChunk;
length -= freeSpaceInEndChunk;
} else {
// Copies the rest of the data
System.arraycopy(bytes, offset, endChunk, positionInEndChunk, length);
// Adds the size
mSize += length;
offset += length;
length = 0;
}
}
}
/**
* @return Returns the bytes as array
*/
public byte[] toByteArray() {
byte[] bytes = new byte[mSize];
int pos = 0;
// Copies all chunks
for(byte[] subBytes : mChunks) {
int chunkSize = mChunkSize;
// Last segment
if (pos + chunkSize > mSize)
chunkSize = mSize - pos;
// Copies the bytes
System.arraycopy(subBytes, 0, bytes, pos, chunkSize);
pos += chunkSize;
}
return bytes;
}
}

View file

@ -1,148 +0,0 @@
/*
* Copyright (c) 2015 David Schulte
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package rc.jcg.superuser;
import android.os.AsyncTask;
import java.io.IOException;
/**
* The superuser managers
*
* This static class handles the superuser session.
* Start the session with {@link #askForPermissions() askForPermissions}.
* To run a command create an instance of {@link SuperUserCommand SuperUserCommand} and {@link SuperUserCommand#execute() execute} it.
*/
public class SuperUser {
/**
* The su process
*/
private static Process mProcess;
/**
* Gets the active su process
* @return Process
*/
static Process getProcess() {
return mProcess;
}
/**
* Starts the superuser session
* To start the session in your app use {@link #askForPermissions()}
*/
private static boolean sessionStart() {
// Starts the su process
try {
mProcess = Runtime.getRuntime().exec("su");
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
/**
* Stops the superuser session
*/
public static void sessionStop() {
if (mProcess == null) return;
// End the process
mProcess.destroy();
mProcess = null;
}
/**
* Gets whether the su session is running
* @return Return whether the su session is running
*/
public static boolean sessionIsRunning() {
if (mProcess == null) return false;
// Hack to see if the process is running
// This is not nice, but there is no other way to check this
try {
mProcess.exitValue();
return false;
} catch(IllegalThreadStateException ex) {
// Could not get the return value => process is running
return true;
}
}
/**
* Checks whether superuser permissions were granted
* @return Return whether superuser permissions were granted
*/
public static boolean hasPermissions() {
// Just check whether the session is running
return sessionIsRunning();
}
/**
* This is like hasPermissions() but asks for the superuser permissions
* and give the user a change to grant it now.
* Use this to start you session
* @return Return whether superuser permissions were granted
*/
public static boolean askForPermissions() {
// We already have superuser permissions
if (hasPermissions()) return true;
// Starts the process
if (sessionStart()) {
// Test for superuser
SuperUserCommand superUserCommand = new SuperUserCommand("echo 'root'");
if (superUserCommand.execute()) {
// Gets the whoami username
String[] output = superUserCommand.getStandardOutput();
if (output.length >= 1 && output[0].equals("root")) {
// We are root
return true;
}
}
}
// We don't have superuser permissions; abort session
sessionStop();
return false;
}
public static void askForPermissionInBackground(final SuperUserPermissionRequestListener listener) {
new AsyncTask<Void, Void, Void>() {
boolean hasPermissions;
@Override
protected Void doInBackground(Void... params) {
hasPermissions = askForPermissions();
return null;
}
@Override
protected void onPostExecute(Void result) {
listener.superUserGranted(hasPermissions);
}
}.execute();
}
}

View file

@ -1,383 +0,0 @@
/*
* Copyright (c) 2015 David Schulte
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package rc.jcg.superuser;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
/**
* This class executes superuser commands.
*/
public class SuperUserCommand {
/**
* The default timeout for each command in milliseconds
*/
private static final long DEFAULT_COMMAND_TIMEOUT = 30 * 1000; // 30 seconds
private String[] mCommands = new String[] {};
private String[] mOutputStandard = new String[] {};
private String[] mOutputError = new String[] {};
// If we want to get a binary return
private byte[] mOutputStandardBinary = new byte[] {};
/**
* Command failed?
*/
private boolean mSuperUserFailed;
/**
* If this value is set, the command will not store any input to the logger
*/
private boolean mHideInput = false;
/**
* If this value is set, the command will not store any standard output to the logger
*/
private boolean mHideStandardOutput = false;
/**
* If this value is set, the command will not store any error output to the logger
*/
private boolean mHideErrorOutput = false;
/**
* @return Gets whether the command hides the input log
*/
public boolean getHideInput() {
return mHideInput;
}
/**
* @param hideInput Set this to hide the input to the logger
*/
public void setHideInput(boolean hideInput) {
mHideInput = hideInput;
}
/**
* @return Gets whether the command hides the standard output log
*/
public boolean getHideStandardOutput() {
return mHideStandardOutput;
}
/**
* @param hideStandardOutput Set this to hide the standard output to the logger
*/
public void setHideStandardOutput(boolean hideStandardOutput) {
mHideStandardOutput = hideStandardOutput;
}
/**
* @return Gets whether the command hides the error output log
*/
public boolean getHideErrorOutput() {
return mHideErrorOutput;
}
/**
* @param hideErrorOutput Set this to hide the error output to the logger
*/
public void setHideErrorOutput(boolean hideErrorOutput) {
mHideErrorOutput = hideErrorOutput;
}
/**
* If this value is set the command will read the standard output as binary
*/
private boolean mBinaryStandardOutput = false;
/**
* @return Gets whether the output will be binary
*/
public boolean getBinaryStandardOutput() {
return mBinaryStandardOutput;
}
/**
* @param binaryStandardOutput Set this if you want a binary output
*/
public void setBinaryStandardOutput(boolean binaryStandardOutput) {
mBinaryStandardOutput = binaryStandardOutput;
}
/**
* The timeout for this command in milliseconds
*/
private long mTimeout;
/**
* @return Gets the timeout for this command in milliseconds
*/
public long getTimeout() {
return mTimeout;
}
/**
* Set the timeout for this command in milliseconds
* @param timeout Timeout
* @return Itself
*/
public SuperUserCommand setTimeout(long timeout) {
mTimeout = timeout;
return this;
}
/**
* @return Gets the executed commands
*/
public String[] getCommands() {
return mCommands;
}
/**
* @return Gets the standard output
*/
public String[] getStandardOutput() {
return mOutputStandard;
}
/**
* @return Gets the error output
*/
public String[] getErrorOutput() {
return mOutputError;
}
/**
* @return Gets the standard output as binary
*/
public byte[] getStandardOutputBinary() {
return mOutputStandardBinary;
}
/**
* @return Gets whether the command was executed without errors, even without error outputs from the command.
*/
public boolean commandWasSuccessful() {
return (!mSuperUserFailed && mOutputError.length == 0);
}
/**
* @return Gets whether the command was granted superuser permissions, but maybe has some error outputs.
*/
public boolean superuserWasSuccessful() {
return (!mSuperUserFailed);
}
/**
* The async execution thread
*/
private SuperUserCommandThread mThread;
/**
* The async callback
*/
private SuperUserCommandCallback mCallback;
/**
* Creates a command with one command line
* @param command The command
*/
public SuperUserCommand(String command) {
this(new String[] {command});
}
/**
* Creates a command with multiple command lines
* @param commands The command lines
*/
public SuperUserCommand(String[] commands) {
mCommands = commands;
// Default timeout
mTimeout = DEFAULT_COMMAND_TIMEOUT;
}
/**
* Execute the command asynchronously.
* Please notice that the commands will only executed one after another.
* The command will wait until the su process is free.
* @param callback The callback instance
*/
public void executeAsync(SuperUserCommandCallback callback) {
mCallback = callback;
// Thread is running
if (mThread != null) return;
// Create a new thread
mThread = new SuperUserCommandThread();
// Starts a thread
mThread.start();
}
/**
* Execute the command and return whether the command was executed.
* It will only return false if the app wasn't granted superuser permissions, like {@link #superuserWasSuccessful()}.
* It will also return true if the command itself returns error outputs. To check this case you should use {@link #commandWasSuccessful()} instead.
* Please consider to use {@link #executeAsync} instead of this and execute the command asynchronously.
* @return Gets whether the execution was successful.
*/
public boolean execute() {
String tmpLine;
List<String> tmpList = new ArrayList<>();
mSuperUserFailed = false;
// Opps, we don't have superuser permissions
// Did you run SuperUser.askForPermissions()?
if (!SuperUser.hasPermissions()) {
mSuperUserFailed = true;
return false;
}
// Thread safe
synchronized (SuperUser.getProcess()) {
try {
// Gets the streams
DataOutputStream dataOutputStream = new DataOutputStream(SuperUser.getProcess().getOutputStream());
BufferedReader bufferedInputReader = new BufferedReader(new InputStreamReader(SuperUser.getProcess().getInputStream()));
BufferedReader bufferedErrorReader = new BufferedReader(new InputStreamReader(SuperUser.getProcess().getErrorStream()));
// Sends the command
for (String command : mCommands) {
dataOutputStream.writeBytes(command + "\n");
}
dataOutputStream.flush();
// TODO: This class cannot execute commands without any output (standard and error). These commands will run until the timeout will kill them!
// Start waiting
long timeStarted = System.currentTimeMillis();
// Wait for first data
while (!bufferedInputReader.ready() && !bufferedErrorReader.ready()) {
try {
// Waiting
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
long timeNow = System.currentTimeMillis();
// TimeOut
if (timeNow - timeStarted >= mTimeout) break;
}
// We want to read the data as binary
if (mBinaryStandardOutput) {
int len;
byte[] buffer = new byte[1024];
// Byte buffer
ByteBuffer byteBuffer = new ByteBuffer();
// Need the direct input stream
InputStream inputStream = SuperUser.getProcess().getInputStream();
do {
while (bufferedInputReader.ready()) {
// Read to buffer
len = inputStream.read(buffer);
// Write to buffer
byteBuffer.append(buffer, 0, len);
}
// Fix: Wait for the buffer and try again
try {
// Sometimes cat is to slow.
// If there is no data anymore we will wait 100ms and check again.
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (bufferedInputReader.ready());
mOutputStandardBinary = byteBuffer.toByteArray();
} else {
// Reads the standard output as text
tmpList.clear();
while (bufferedInputReader.ready()) {
tmpLine = bufferedInputReader.readLine();
// End of data
if (tmpLine == null) break;
tmpList.add(tmpLine);
}
// Convert list to array
mOutputStandard = tmpList.toArray(new String[tmpList.size()]);
}
// Reads the error output
tmpList.clear();
while (bufferedErrorReader.ready()) {
tmpLine = bufferedErrorReader.readLine();
// End of data
if (tmpLine == null) break;
tmpList.add(tmpLine);
}
// Convert list to array
mOutputError = tmpList.toArray(new String[tmpList.size()]);
// Done
return true;
} catch (IOException e) {
e.printStackTrace();
mSuperUserFailed = true;
// Command failed
return false;
}
}
}
/**
* Thread to executes the command asynchronously
*/
private class SuperUserCommandThread extends Thread {
@Override
public void run() {
super.run();
// Executes the command
execute();
if (mCallback != null)
mCallback.onFinished(SuperUserCommand.this);
}
}
}

View file

@ -1,35 +0,0 @@
/*
* Copyright (c) 2015 David Schulte
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package rc.jcg.superuser;
/**
* Callback class if the async execution is finish
*/
public interface SuperUserCommandCallback {
/**
* Callback event
* @param command The command that finished
*/
void onFinished(SuperUserCommand command);
}

View file

@ -1,5 +0,0 @@
package rc.jcg.superuser;
public interface SuperUserPermissionRequestListener {
void superUserGranted(boolean granted);
}

View file

@ -1,115 +0,0 @@
/*
* Copyright (c) 2015 David Schulte
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package rc.jcg.superuser;
/**
* Tools for the superuser
*/
public class SuperUserTools {
/**
* Private constructor
*/
private SuperUserTools() {}
/**
* Copy a file with root permissions
* @param src Source file
* @param dest Destination file
* @return Returns whether the command was successful
*/
public static boolean fileCopy(String src, String dest) {
SuperUserCommand superUserCommand = new SuperUserCommand(new String[] {
"rm -f '" + dest + "'", // Remove destination file
"cat '" + src + "' >> '" + dest + "'", // Using cat to copy file instead of cp, because you can use it without busybox
"chmod 0777 '" + dest + "'", // Change the access mode to all users (chown sdcard_r will fail on some devices)
"echo 'done'" // Fix to prevent the 'no output' bug in SuperUserCommand
});
// Don't spam the log
superUserCommand.setHideStandardOutput(true);
// Executes the command
superUserCommand.execute();
// Superuser permissions and command are successful
return superUserCommand.commandWasSuccessful();
}
/**
* Checks if the file exists
* @param path The path to check
* @return Returns whether the path exists
*/
public static boolean fileExists(String path) {
SuperUserCommand superUserCommand = new SuperUserCommand("ls '" + path + "'");
// Don't spam the log
superUserCommand.setHideStandardOutput(true);
// Executes the command
superUserCommand.execute();
// Superuser permissions and command are successful
return superUserCommand.commandWasSuccessful();
}
/**
* Gets all bytes from one file
* @param path The path to the file
* @return Returns the byte array or null if the file doesn't exists
*/
public static byte[] fileReadToByteArray(String path) {
SuperUserCommand superUserCommand = new SuperUserCommand("cat '" + path + "'");
// Don't spam the log with binary code
superUserCommand.setHideInput(true);
superUserCommand.setHideStandardOutput(true);
superUserCommand.setBinaryStandardOutput(true);
// Executes the command
superUserCommand.execute();
// Failed
if (!superUserCommand.commandWasSuccessful())
return null;
return superUserCommand.getStandardOutputBinary();
}
/**
* Gets all bytes from one file
* @param path The path to the file
* @param callback The callback
*/
public static void fileReadToByteArrayAsync(String path, SuperUserCommandCallback callback) {
SuperUserCommand superUserCommand = new SuperUserCommand("cat '" + path + "'");
// Don't spam the log with binary code
superUserCommand.setHideInput(true);
superUserCommand.setHideStandardOutput(true);
superUserCommand.setBinaryStandardOutput(true);
superUserCommand.executeAsync(callback);
}
}