diff --git a/app/src/main/java/jp/co/cyberagent/stf/Service.java b/app/src/main/java/jp/co/cyberagent/stf/Service.java index aab3365..70af29a 100644 --- a/app/src/main/java/jp/co/cyberagent/stf/Service.java +++ b/app/src/main/java/jp/co/cyberagent/stf/Service.java @@ -51,6 +51,7 @@ import jp.co.cyberagent.stf.query.GetDisplayResponder; import jp.co.cyberagent.stf.query.GetPropertiesResponder; import jp.co.cyberagent.stf.query.GetRingerModeResponder; +import jp.co.cyberagent.stf.query.GetRootStatusResponder; import jp.co.cyberagent.stf.query.GetSdStatusResponder; import jp.co.cyberagent.stf.query.GetVersionResponder; import jp.co.cyberagent.stf.query.GetWifiStatusResponder; @@ -340,6 +341,9 @@ public void run() { router.register(Wire.MessageType.GET_BLUETOOTH_STATUS, new GetBluetoothStatusResponder(getBaseContext())); + router.register(Wire.MessageType.GET_ROOT_STATUS, + new GetRootStatusResponder(getBaseContext())); + router.register(Wire.MessageType.SET_CLIPBOARD, new SetClipboardResponder(getBaseContext())); diff --git a/app/src/main/java/jp/co/cyberagent/stf/query/GetRootStatusResponder.java b/app/src/main/java/jp/co/cyberagent/stf/query/GetRootStatusResponder.java new file mode 100644 index 0000000..dd929d0 --- /dev/null +++ b/app/src/main/java/jp/co/cyberagent/stf/query/GetRootStatusResponder.java @@ -0,0 +1,77 @@ +package jp.co.cyberagent.stf.query; + +import android.content.Context; + +import com.google.protobuf.GeneratedMessageLite; + +import java.io.BufferedReader; +import java.io.File; +import java.io.InputStreamReader; + +import jp.co.cyberagent.stf.proto.Wire; + +public class GetRootStatusResponder extends AbstractResponder { + public GetRootStatusResponder(Context context) { + super(context); + } + + @Override + public GeneratedMessageLite respond(Wire.Envelope envelope) { + boolean rootFlag = isDeviceRooted(); + + return Wire.Envelope.newBuilder() + .setId(envelope.getId()) + .setType(Wire.MessageType.GET_ROOT_STATUS) + .setMessage(Wire.GetRootStatusResponse.newBuilder() + .setSuccess(true) + .setStatus(rootFlag) + .build() + .toByteString()) + .build(); + } + + @Override + public void cleanup() { + // No-op + } + + public static boolean isDeviceRooted() { + return checkRootMethod1() || checkRootMethod2() || checkRootMethod3(); + } + + private static boolean checkRootMethod1() { + String buildTags = android.os.Build.TAGS; + return buildTags != null && buildTags.contains("test-keys"); + } + + private static boolean checkRootMethod2() { + String[] paths = { "/system/app/Superuser.apk", "/sbin/su", "/system/bin/su", "/system/xbin/su", "/data/local/xbin/su", "/data/local/bin/su", "/system/sd/xbin/su", + "/system/bin/failsafe/su", "/data/local/su", "/su/bin/su"}; + for (String path : paths) { + if (new File(path).exists()) return true; + } + return false; + } + + private static boolean checkRootMethod3() { + Process process = null; + BufferedReader in = null; + try { + process = Runtime.getRuntime().exec(new String[] { "/system/xbin/which", "su" }); + in = new BufferedReader(new InputStreamReader(process.getInputStream())); + if (in.readLine() != null) return true; + return false; + } catch (Throwable t) { + return false; + } finally { + if (in != null) { + try { + in.close(); + } catch (Exception ignore) { + // Nothing to do + } + } + if (process != null) process.destroy(); + } + } +} diff --git a/app/src/main/proto/wire.proto b/app/src/main/proto/wire.proto index 26e4c33..a0e12c7 100644 --- a/app/src/main/proto/wire.proto +++ b/app/src/main/proto/wire.proto @@ -21,6 +21,7 @@ enum MessageType { GET_VERSION = 8; GET_WIFI_STATUS = 23; GET_BLUETOOTH_STATUS = 29; + GET_ROOT_STATUS = 31; SET_CLIPBOARD = 9; SET_KEYGUARD_STATE = 10; SET_RINGER_MODE = 21; @@ -248,6 +249,14 @@ message GetWifiStatusResponse { required bool status = 2; } +message GetRootStatusRequest { +} + +message GetRootStatusResponse { + required bool success = 1; + required bool status = 2; +} + message SetBluetoothEnabledRequest { required bool enabled = 1; }