fix the selinux issue in galaxy s4

This commit is contained in:
Max Lv
2014-03-02 10:42:47 +08:00
parent cb31dd2a8e
commit 185f32aa63
16 changed files with 2005 additions and 794 deletions
@@ -1,67 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.shadowsocks;
import java.io.FileDescriptor;
/**
* Utility methods for creating and managing a subprocess.
* <p/>
* Note: The native methods access a package-private java.io.FileDescriptor
* field to get and set the raw Linux file descriptor. This might break if the
* implementation of java.io.FileDescriptor is changed.
*/
public class Exec {
static {
java.lang.System.loadLibrary("exec");
}
/** Close a given file descriptor. */
public static native void close(FileDescriptor fd);
/**
* Create a subprocess. Differs from java.lang.ProcessBuilder in that a pty
* is used to communicate with the subprocess.
* <p/>
* Callers are responsible for calling Exec.close() on the returned file
* descriptor.
*
* @param rdt Whether redirect stdout and stderr
* @param cmd The command to execute.
* @param args An array of arguments to the command.
* @param envVars An array of strings of the form "VAR=value" to be added to the
* environment of the process.
* @param scripts The scripts to execute.
* @param processId A one-element array to which the process ID of the started
* process will be written.
* @return File descriptor
*/
public static native FileDescriptor createSubprocess(int rdt, String cmd, String[] args,
String[] envVars, String scripts, int[] processId);
/** Send SIGHUP to a process group. */
public static native void hangupProcessGroup(int processId);
/**
* Causes the calling thread to wait for the process associated with the
* receiver to finish executing.
*
* @return The exit value of the Process being waited on
*/
public static native int waitFor(int processId);
}
@@ -0,0 +1,79 @@
/*
* Copyright (C) 2012-2013 Jorrit "Chainfire" Jongma
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.chainfire.libsuperuser;
import android.content.Context;
import android.os.Handler;
import android.widget.Toast;
/**
* Base application class to extend from, solving some issues with
* toasts and AsyncTasks you are likely to run into
*/
public class Application extends android.app.Application {
/**
* Shows a toast message
*
* @param context Any context belonging to this application
* @param message The message to show
*/
public static void toast(Context context, String message) {
// this is a static method so it is easier to call,
// as the context checking and casting is done for you
if (context == null) return;
if (!(context instanceof Application)) {
context = context.getApplicationContext();
}
if (context instanceof Application) {
final Context c = context;
final String m = message;
((Application)context).runInApplicationThread(new Runnable() {
@Override
public void run() {
Toast.makeText(c, m, Toast.LENGTH_LONG).show();
}
});
}
}
private static Handler mApplicationHandler = new Handler();
/**
* Run a runnable in the main application thread
*
* @param r Runnable to run
*/
public void runInApplicationThread(Runnable r) {
mApplicationHandler.post(r);
}
@Override
public void onCreate() {
super.onCreate();
try {
// workaround bug in AsyncTask, can show up (for example) when you toast from a service
// this makes sure AsyncTask's internal handler is created from the right (main) thread
Class.forName("android.os.AsyncTask");
} catch (ClassNotFoundException e) {
}
}
}
@@ -0,0 +1,241 @@
/*
* Copyright (C) 2012-2013 Jorrit "Chainfire" Jongma
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.chainfire.libsuperuser;
import android.os.Looper;
import android.util.Log;
import com.github.shadowsocks.BuildConfig;
/**
* Utility class for logging and debug features that (by default) does nothing when not in debug mode
*/
public class Debug {
// ----- DEBUGGING -----
private static boolean debug = BuildConfig.DEBUG;
/**
* <p>Enable or disable debug mode</p>
*
* <p>By default, debug mode is enabled for development
* builds and disabled for exported APKs - see
* BuildConfig.DEBUG</p>
*
* @param enabled Enable debug mode ?
*/
public static void setDebug(boolean enable) {
debug = enable;
}
/**
* <p>Is debug mode enabled ?</p>
*
* @return Debug mode enabled
*/
public static boolean getDebug() {
return debug;
}
// ----- LOGGING -----
public interface OnLogListener {
public void onLog(int type, String typeIndicator, String message);
}
public static final String TAG = "libsuperuser";
public static final int LOG_GENERAL = 0x0001;
public static final int LOG_COMMAND = 0x0002;
public static final int LOG_OUTPUT = 0x0004;
public static final int LOG_NONE = 0x0000;
public static final int LOG_ALL = 0xFFFF;
private static int logTypes = LOG_ALL;
private static OnLogListener logListener = null;
/**
* <p>Log a message (internal)</p>
*
* <p>Current debug and enabled logtypes decide what gets logged -
* even if a custom callback is registered</p>
*
* @param type Type of message to log
* @param typeIndicator String indicator for message type
* @param message The message to log
*/
private static void logCommon(int type, String typeIndicator, String message) {
if (debug && ((logTypes & type) == type)) {
if (logListener != null) {
logListener.onLog(type, typeIndicator, message);
} else {
Log.d(TAG, "[" + TAG + "][" + typeIndicator + "]" + (!message.startsWith("[") && !message.startsWith(" ") ? " " : "") + message);
}
}
}
/**
* <p>Log a "general" message</p>
*
* <p>These messages are infrequent and mostly occur at startup/shutdown or on error</p>
*
* @param message The message to log
*/
public static void log(String message) {
logCommon(LOG_GENERAL, "G", message);
}
/**
* <p>Log a "per-command" message</p>
*
* <p>This could produce a lot of output if the client runs many commands in the session</p>
*
* @param message The message to log
*/
public static void logCommand(String message) {
logCommon(LOG_COMMAND, "C", message);
}
/**
* <p>Log a line of stdout/stderr output</p>
*
* <p>This could produce a lot of output if the shell commands are noisy</p>
*
* @param message The message to log
*/
public static void logOutput(String message) {
logCommon(LOG_OUTPUT, "O", message);
}
/**
* <p>Enable or disable logging specific types of message</p>
*
* <p>You may | (or) LOG_* constants together. Note that
* debug mode must also be enabled for actual logging to
* occur.</p>
*
* @param type LOG_* constants
* @param enabled Enable or disable
*/
public static void setLogTypeEnabled(int type, boolean enable) {
if (enable) {
logTypes |= type;
} else {
logTypes &= ~type;
}
}
/**
* <p>Is logging for specific types of messages enabled ?</p>
*
* <p>You may | (or) LOG_* constants together, to learn if
* <b>all</b> passed message types are enabled for logging. Note
* that debug mode must also be enabled for actual logging
* to occur.</p>
*
* @param type LOG_* constants
*/
public static boolean getLogTypeEnabled(int type) {
return ((logTypes & type) == type);
}
/**
* <p>Is logging for specific types of messages enabled ?</p>
*
* <p>You may | (or) LOG_* constants together, to learn if
* <b>all</b> message types are enabled for logging. Takes
* debug mode into account for the result.</p>
*
* @param type LOG_* constants
*/
public static boolean getLogTypeEnabledEffective(int type) {
return getDebug() && getLogTypeEnabled(type);
}
/**
* <p>Register a custom log handler</p>
*
* <p>Replaces the log method (write to logcat) with your own
* handler. Whether your handler gets called is still dependent
* on debug mode and message types being enabled for logging.</p>
*
* @param onLogListener Custom log listener or NULL to revert to default
*/
public static void setOnLogListener(OnLogListener onLogListener) {
logListener = onLogListener;
}
/**
* <p>Get the currently registered custom log handler</p>
*
* @return Current custom log handler or NULL if none is present
*/
public static OnLogListener getOnLogListener() {
return logListener;
}
// ----- SANITY CHECKS -----
private static boolean sanityChecks = true;
/**
* <p>Enable or disable sanity checks</p>
*
* <p>Enables or disables the library crashing when su is called
* from the main thread.</p>
*
* @param enabled Enable or disable
*/
public static void setSanityChecksEnabled(boolean enable) {
sanityChecks = enable;
}
/**
* <p>Are sanity checks enabled ?</p>
*
* <p>Note that debug mode must also be enabled for actual
* sanity checks to occur.</p>
*
* @return True if enabled
*/
public static boolean getSanityChecksEnabled() {
return sanityChecks;
}
/**
* <p>Are sanity checks enabled ?</p>
*
* <p>Takes debug mode into account for the result.</p>
*
* @return True if enabled
*/
public static boolean getSanityChecksEnabledEffective() {
return getDebug() && getSanityChecksEnabled();
}
/**
* <p>Are we running on the main thread ?</p>
*
* @return Running on main thread ?
*/
public static boolean onMainThread() {
return ((Looper.myLooper() != null) && (Looper.myLooper() == Looper.getMainLooper()));
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,29 @@
/*
* Copyright (C) 2012-2013 Jorrit "Chainfire" Jongma
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.chainfire.libsuperuser;
/**
* Exception class used to notify developer that a shell was not close()d
*/
@SuppressWarnings("serial")
public class ShellNotClosedException extends RuntimeException {
public static final String EXCEPTION_NOT_CLOSED = "Application did not close() interactive shell";
public ShellNotClosedException() {
super(EXCEPTION_NOT_CLOSED);
}
}
@@ -0,0 +1,32 @@
/*
* Copyright (C) 2012-2013 Jorrit "Chainfire" Jongma
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.chainfire.libsuperuser;
/**
* Exception class used to crash application when shell commands are executed
* from the main thread, and we are in debug mode.
*/
@SuppressWarnings("serial")
public class ShellOnMainThreadException extends RuntimeException {
public static final String EXCEPTION_COMMAND = "Application attempted to run a shell command from the main thread";
public static final String EXCEPTION_NOT_IDLE = "Application attempted to wait for a non-idle shell to close on the main thread";
public static final String EXCEPTION_WAIT_IDLE = "Application attempted to wait for a shell to become idle on the main thread";
public ShellOnMainThreadException(String message) {
super(message);
}
}
@@ -0,0 +1,103 @@
/*
* Copyright (C) 2012-2013 Jorrit "Chainfire" Jongma
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.chainfire.libsuperuser;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
/**
* Thread utility class continuously reading from an InputStream
*/
public class StreamGobbler extends Thread {
/**
* Line callback interface
*/
public interface OnLineListener {
/**
* <p>Line callback</p>
*
* <p>This callback should process the line as quickly as possible.
* Delays in this callback may pause the native process or even
* result in a deadlock</p>
*
* @param line String that was gobbled
*/
public void onLine(String line);
}
private String shell = null;
private BufferedReader reader = null;
private List<String> writer = null;
private OnLineListener listener = null;
/**
* <p>StreamGobbler constructor</p>
*
* <p>We use this class because shell STDOUT and STDERR should be read as quickly as
* possible to prevent a deadlock from occurring, or Process.waitFor() never
* returning (as the buffer is full, pausing the native process)</p>
*
* @param shell Name of the shell
* @param inputStream InputStream to read from
* @param outputList List<String> to write to, or null
*/
public StreamGobbler(String shell, InputStream inputStream, List<String> outputList) {
this.shell = shell;
reader = new BufferedReader(new InputStreamReader(inputStream));
writer = outputList;
}
/**
* <p>StreamGobbler constructor</p>
*
* <p>We use this class because shell STDOUT and STDERR should be read as quickly as
* possible to prevent a deadlock from occurring, or Process.waitFor() never
* returning (as the buffer is full, pausing the native process)</p>
*
* @param shell Name of the shell
* @param inputStream InputStream to read from
* @param onLineListener OnLineListener callback
*/
public StreamGobbler(String shell, InputStream inputStream, OnLineListener onLineListener) {
this.shell = shell;
reader = new BufferedReader(new InputStreamReader(inputStream));
listener = onLineListener;
}
@Override
public void run() {
// keep reading the InputStream until it ends (or an error occurs)
try {
String line = null;
while ((line = reader.readLine()) != null) {
Debug.logOutput(String.format("[%s] %s", shell, line));
if (writer != null) writer.add(line);
if (listener != null) listener.onLine(line);
}
} catch (IOException e) {
}
// make sure our stream is closed and resources will be freed
try {
reader.close();
} catch (IOException e) {
}
}
}