├── .idea
├── .name
├── copyright
│ └── profiles_settings.xml
├── scopes
│ └── scope_settings.xml
├── encodings.xml
├── vcs.xml
├── modules.xml
├── misc.xml
├── compiler.xml
└── workspace.xml
├── assets
└── .gitignore
├── libs
└── android-support-v4.jar
├── res
├── drawable-hdpi
│ └── ic_launcher.png
├── drawable-ldpi
│ └── ic_launcher.png
├── drawable-mdpi
│ └── ic_launcher.png
├── drawable-xhdpi
│ └── ic_launcher.png
├── drawable-xxhdpi
│ └── ic_launcher.png
├── values
│ └── strings.xml
└── layout
│ └── main.xml
├── .gitignore
├── project.properties
├── .classpath
├── Safestrap.iml
├── AndroidManifest.xml
├── .project
├── proguard.cfg
└── src
└── com
└── hashcode
└── safestrap
└── ics
├── UninstallDialogThread.java
├── InstallDialogThread.java
├── ExecuteAsRootBase.java
├── AssetControl.java
└── SafestrapActivity.java
/.idea/.name:
--------------------------------------------------------------------------------
1 | Safestrap
--------------------------------------------------------------------------------
/assets/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 |
--------------------------------------------------------------------------------
/libs/android-support-v4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stargo/android_packages_apps_Safestrap/HEAD/libs/android-support-v4.jar
--------------------------------------------------------------------------------
/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stargo/android_packages_apps_Safestrap/HEAD/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-ldpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stargo/android_packages_apps_Safestrap/HEAD/res/drawable-ldpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stargo/android_packages_apps_Safestrap/HEAD/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stargo/android_packages_apps_Safestrap/HEAD/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stargo/android_packages_apps_Safestrap/HEAD/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/scopes/scope_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # built application files
2 | *.apk
3 | *.ap_
4 |
5 | # files for the dex VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | bin/
12 | gen/
13 | out/
14 |
15 | # Local configuration file (sdk path, etc)
16 | local.properties
17 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system use,
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 |
10 | # Project target.
11 | target=android-19
12 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Safestrap.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
13 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | Safestrap
4 |
5 |
6 |
7 |
8 |
9 | com.android.ide.eclipse.adt.ResourceManagerBuilder
10 |
11 |
12 |
13 |
14 | com.android.ide.eclipse.adt.PreCompilerBuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.jdt.core.javabuilder
20 |
21 |
22 |
23 |
24 | com.android.ide.eclipse.adt.ApkBuilder
25 |
26 |
27 |
28 |
29 |
30 | com.android.ide.eclipse.adt.AndroidNature
31 | org.eclipse.jdt.core.javanature
32 |
33 |
34 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/proguard.cfg:
--------------------------------------------------------------------------------
1 | -optimizationpasses 5
2 | -dontusemixedcaseclassnames
3 | -dontskipnonpubliclibraryclasses
4 | -dontpreverify
5 | -verbose
6 | -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
7 |
8 | -keep public class * extends android.app.Activity
9 | -keep public class * extends android.app.Application
10 | -keep public class * extends android.app.Service
11 | -keep public class * extends android.content.BroadcastReceiver
12 | -keep public class * extends android.content.ContentProvider
13 | -keep public class * extends android.app.backup.BackupAgentHelper
14 | -keep public class * extends android.preference.Preference
15 | -keep public class com.android.vending.licensing.ILicensingService
16 |
17 | -keepclasseswithmembernames class * {
18 | native ;
19 | }
20 |
21 | -keepclasseswithmembers class * {
22 | public (android.content.Context, android.util.AttributeSet);
23 | }
24 |
25 | -keepclasseswithmembers class * {
26 | public (android.content.Context, android.util.AttributeSet, int);
27 | }
28 |
29 | -keepclassmembers class * extends android.app.Activity {
30 | public void *(android.view.View);
31 | }
32 |
33 | -keepclassmembers enum * {
34 | public static **[] values();
35 | public static ** valueOf(java.lang.String);
36 | }
37 |
38 | -keep class * implements android.os.Parcelable {
39 | public static final android.os.Parcelable$Creator *;
40 | }
41 |
--------------------------------------------------------------------------------
/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Safestrap
4 | Install Recovery
5 | Uninstall Recovery
6 | Reboot to Recovery
7 | Upgrade Recovery
8 | State:
9 | Installed
10 | Not Installed
11 | Safe System:
12 | Not Active
13 | Recovery Disabled
14 |
15 | 3.75
16 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
17 | #66FF99
18 | #FF0000
19 | #FFFF00
20 | Reboot to Write Protect Off Mode
21 |
22 |
--------------------------------------------------------------------------------
/src/com/hashcode/safestrap/ics/UninstallDialogThread.java:
--------------------------------------------------------------------------------
1 | package com.hashcode.safestrap.ics;
2 |
3 | import java.io.File;
4 |
5 | import android.os.Handler;
6 | import android.os.Message;
7 |
8 | public class UninstallDialogThread extends Thread implements Runnable {
9 | public Handler handler = null;
10 | public String packageCodePath = "";
11 | public File mAppRoot = null;
12 | public String LOGTAG = "";
13 |
14 | protected void pause(int milli) {
15 | try {
16 | Thread.sleep(milli);
17 | }
18 | catch(Exception ex) { }
19 | }
20 |
21 | protected void reply(int arg1, int arg2, String text) {
22 | Message msg = new Message();
23 | msg.arg1 = arg1;
24 | msg.arg2 = arg2;
25 | msg.obj = (Object)text;
26 | if (handler != null) { handler.sendMessage(msg); }
27 | }
28 |
29 | @Override
30 | public void run() {
31 | try {
32 | reply(1,0,"Preparing Uninstall...");
33 | pause(2000);
34 | AssetControl unzip = new AssetControl();
35 | unzip.apkPath= packageCodePath;
36 | unzip.mAppRoot = mAppRoot.toString();
37 | unzip.LOGTAG = LOGTAG;
38 | reply(1,0,"Unpacking Files...");
39 | unzip.unzipAssets();
40 | reply(1,50,"Checking Busybox...");
41 | String filesDir = mAppRoot.getAbsolutePath();
42 | ExecuteAsRootBase.executecmd("chmod 755 " + filesDir + "/busybox");
43 | ExecuteAsRootBase.executecmd("chmod 755 " + filesDir + "/*.sh");
44 | reply(1,60,"Uninstalling...");
45 | ExecuteAsRootBase.executecmd("sh " + filesDir + "/recovery-uninstall.sh " + filesDir);
46 | reply(1,90,"Cleaning Up...");
47 | ExecuteAsRootBase.executecmd(filesDir + "/busybox rm -r " + filesDir + "/install-files");
48 | reply(0,0,"Uninstall Complete.");
49 | }
50 | catch(Exception ex) {
51 | reply(0,1,ex.getMessage());
52 | }
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/src/com/hashcode/safestrap/ics/InstallDialogThread.java:
--------------------------------------------------------------------------------
1 | package com.hashcode.safestrap.ics;
2 |
3 | import java.io.File;
4 |
5 | import android.os.Handler;
6 | import android.os.Message;
7 |
8 | public class InstallDialogThread extends Thread {
9 |
10 |
11 | public Handler handler = null;
12 | public String packageCodePath = "";
13 | public File mAppRoot = null;
14 | public String LOGTAG = "";
15 |
16 | protected void pause(int milli) {
17 | try {
18 | Thread.sleep(milli);
19 | }
20 | catch(Exception ex) { }
21 | }
22 |
23 | protected void reply(int arg1, int arg2, String text) {
24 | Message msg = new Message();
25 | msg.arg1 = arg1;
26 | msg.arg2 = arg2;
27 | msg.obj = (Object)text;
28 | if (handler != null) { handler.sendMessage(msg); }
29 | }
30 |
31 | @Override
32 | public void run() {
33 | try {
34 | reply(1,0,"Preparing Installation...");
35 | pause(2000);
36 | AssetControl unzip = new AssetControl();
37 | unzip.apkPath= packageCodePath;
38 | unzip.mAppRoot = mAppRoot.toString();
39 | unzip.LOGTAG = LOGTAG;
40 | reply(1,0,"Unpacking Files...");
41 | unzip.unzipAssets();
42 | reply(1,50,"Checking Busybox...");
43 | String filesDir = mAppRoot.getAbsolutePath();
44 | ExecuteAsRootBase.executecmd("chmod 755 " + filesDir + "/busybox");
45 | ExecuteAsRootBase.executecmd("chmod 755 " + filesDir + "/*.sh");
46 | reply(1,60,"Running Installation Script...");
47 | ExecuteAsRootBase.executecmd("sh " + filesDir + "/recovery-install.sh " + filesDir);
48 | reply(1,90,"Cleaning Up...");
49 | ExecuteAsRootBase.executecmd(filesDir + "/busybox rm -r " + filesDir + "/install-files");
50 | pause(1000);
51 | reply(0,0,"Installation Complete.");
52 | }
53 | catch(Exception ex) {
54 | reply(0,1,ex.getMessage());
55 | }
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/res/layout/main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/com/hashcode/safestrap/ics/ExecuteAsRootBase.java:
--------------------------------------------------------------------------------
1 | package com.hashcode.safestrap.ics;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.DataOutputStream;
5 | import java.io.IOException;
6 | import java.io.InputStreamReader;
7 | import java.io.OutputStreamWriter;
8 | import java.util.ArrayList;
9 | import android.util.Log;
10 |
11 | public abstract class ExecuteAsRootBase
12 | {
13 | public static boolean canRunRootCommands()
14 | {
15 | boolean retval = false;
16 | Process suProcess;
17 |
18 | try
19 | {
20 | suProcess = Runtime.getRuntime().exec("su");
21 |
22 | DataOutputStream os = new DataOutputStream(suProcess.getOutputStream());
23 | BufferedReader osRes = new BufferedReader(new InputStreamReader(suProcess.getInputStream()));
24 |
25 | if (null != os && null != osRes)
26 | {
27 | // Getting the id of the current user to check if this is root
28 | os.writeBytes("id\n");
29 | os.flush();
30 |
31 | String currUid = osRes.readLine();
32 | boolean exitSu = false;
33 | if (null == currUid)
34 | {
35 | retval = false;
36 | exitSu = false;
37 | Log.d("ROOT", "Can't get root access or denied by user");
38 | }
39 | else if (true == currUid.contains("uid=0"))
40 | {
41 | retval = true;
42 | exitSu = true;
43 | Log.d("ROOT", "Root access granted");
44 | }
45 | else
46 | {
47 | retval = false;
48 | exitSu = true;
49 | Log.d("ROOT", "Root access rejected: " + currUid);
50 | }
51 |
52 | if (exitSu)
53 | {
54 | os.writeBytes("exit\n");
55 | os.flush();
56 | }
57 | }
58 | }
59 | catch (Exception e)
60 | {
61 | // Can't get root !
62 | // Probably broken pipe exception on trying to write to output stream (os) after su failed, meaning that the device is not rooted
63 |
64 | retval = false;
65 | Log.d("ROOT", "Root access rejected [" + e.getClass().getName() + "] : " + e.getMessage());
66 | }
67 |
68 | return retval;
69 | }
70 |
71 | public static final String executecmd(String cmd) {
72 | String result = "";
73 | try {
74 | Process zuul = Runtime.getRuntime().exec("su");
75 | OutputStreamWriter osw = new OutputStreamWriter(zuul.getOutputStream());
76 | osw.write(cmd + "\n");
77 | osw.flush();
78 | osw.close();
79 | BufferedReader in = new BufferedReader(new InputStreamReader(zuul.getInputStream()));
80 | if (in != null) { result = in.readLine(); }
81 | } catch(Exception e){ e.printStackTrace(); }
82 | return result;
83 | }
84 |
85 | public final boolean execute()
86 | {
87 | boolean retval = false;
88 |
89 | try
90 | {
91 | ArrayList commands = getCommandsToExecute();
92 | if (null != commands && commands.size() > 0)
93 | {
94 | Process suProcess = Runtime.getRuntime().exec("su");
95 |
96 | DataOutputStream os = new DataOutputStream(suProcess.getOutputStream());
97 |
98 | // Execute commands that require root access
99 | for (String currCommand : commands)
100 | {
101 | os.writeBytes(currCommand + "\n");
102 | os.flush();
103 | }
104 |
105 | os.writeBytes("exit\n");
106 | os.flush();
107 |
108 | try
109 | {
110 | int suProcessRetval = suProcess.waitFor();
111 | if (255 != suProcessRetval)
112 | {
113 | // Root access granted
114 | retval = true;
115 | }
116 | else
117 | {
118 | // Root access denied
119 | retval = false;
120 | }
121 | }
122 | catch (Exception ex)
123 | {
124 | Log.e("Error executing root action", ex.getMessage());
125 | }
126 | }
127 | }
128 | catch (IOException ex)
129 | {
130 | Log.w("ROOT", "Can't get root access", ex);
131 | }
132 | catch (SecurityException ex)
133 | {
134 | Log.w("ROOT", "Can't get root access", ex);
135 | }
136 | catch (Exception ex)
137 | {
138 | Log.w("ROOT", "Error executing internal operation", ex);
139 | }
140 |
141 | return retval;
142 | }
143 |
144 | protected abstract ArrayList getCommandsToExecute();
145 | }
146 |
--------------------------------------------------------------------------------
/src/com/hashcode/safestrap/ics/AssetControl.java:
--------------------------------------------------------------------------------
1 | package com.hashcode.safestrap.ics;
2 |
3 | import java.io.BufferedOutputStream;
4 | import java.io.File;
5 | import java.io.FileOutputStream;
6 | import java.io.IOException;
7 | import java.io.InputStream;
8 | import java.util.Enumeration;
9 | import java.util.Vector;
10 | import java.util.zip.ZipEntry;
11 | import java.util.zip.ZipFile;
12 | import android.util.Log;
13 |
14 | public class AssetControl {
15 | public String LOGTAG = "Unknown App";
16 | public String apkPath = "";
17 | public String mAppRoot = "";
18 | final static String ZIP_FILTER = "assets";
19 |
20 | void unzipAsset(String filename) {
21 | try {
22 | File zipFile = new File(apkPath);
23 | long zipLastModified = zipFile.lastModified();
24 | ZipFile zip = new ZipFile(apkPath);
25 | Vector files = getAssets(zip);
26 | int zipFilterLength = ZIP_FILTER.length();
27 |
28 | Enumeration> entries = files.elements();
29 | while (entries.hasMoreElements()) {
30 | ZipEntry entry = (ZipEntry) entries.nextElement();
31 | String path = entry.getName().substring(zipFilterLength);
32 | if (filename.equals(path)) {
33 | File outputFile = new File(mAppRoot, path);
34 | outputFile.getParentFile().mkdirs();
35 |
36 | if (outputFile.exists() && entry.getSize() == outputFile.length() && zipLastModified < outputFile.lastModified())
37 | continue;
38 | FileOutputStream fos = new FileOutputStream(outputFile);
39 | copyStreams(zip.getInputStream(entry), fos);
40 | Runtime.getRuntime().exec("chmod 755 " + outputFile.getAbsolutePath());
41 | }
42 | }
43 | } catch (IOException e) {
44 | Log.e(LOGTAG, "Error: " + e.getMessage());
45 | }
46 | }
47 |
48 | void unzipAssets() {
49 | try {
50 | File zipFile = new File(apkPath);
51 | long zipLastModified = zipFile.lastModified();
52 | ZipFile zip = new ZipFile(apkPath);
53 | Vector files = getAssets(zip);
54 | int zipFilterLength = ZIP_FILTER.length();
55 |
56 | Enumeration> entries = files.elements();
57 | while (entries.hasMoreElements()) {
58 | ZipEntry entry = (ZipEntry) entries.nextElement();
59 | String path = entry.getName().substring(zipFilterLength);
60 | File outputFile = new File(mAppRoot, path);
61 | outputFile.getParentFile().mkdirs();
62 |
63 | if (outputFile.exists() && entry.getSize() == outputFile.length() && zipLastModified < outputFile.lastModified())
64 | continue;
65 | FileOutputStream fos = new FileOutputStream(outputFile);
66 | copyStreams(zip.getInputStream(entry), fos);
67 | Runtime.getRuntime().exec("chmod 755 " + outputFile.getAbsolutePath());
68 | }
69 | } catch (IOException e) {
70 | Log.e(LOGTAG, "Error: " + e.getMessage());
71 | }
72 | }
73 |
74 | static final int BUFSIZE = 5192;
75 |
76 | void copyStreams(InputStream is, FileOutputStream fos) {
77 | BufferedOutputStream os = null;
78 | try {
79 | byte data[] = new byte[BUFSIZE];
80 | int count;
81 | os = new BufferedOutputStream(fos, BUFSIZE);
82 | while ((count = is.read(data, 0, BUFSIZE)) != -1) {
83 | os.write(data, 0, count);
84 | }
85 | os.flush();
86 | } catch (IOException e) {
87 | Log.e(LOGTAG, "Exception while copying: " + e);
88 | } finally {
89 | try {
90 | if (os != null) {
91 | os.close();
92 | }
93 | } catch (IOException e2) {
94 | Log.e(LOGTAG, "Exception while closing the stream: " + e2);
95 | }
96 | }
97 | }
98 |
99 | public Vector getAssets(ZipFile zip) {
100 | Vector list = new Vector();
101 | Enumeration> entries = zip.entries();
102 | while (entries.hasMoreElements()) {
103 | ZipEntry entry = (ZipEntry) entries.nextElement();
104 | if (entry.getName().startsWith(ZIP_FILTER)) {
105 | list.add(entry);
106 | }
107 | }
108 | return list;
109 | }
110 |
111 | }
112 |
--------------------------------------------------------------------------------
/src/com/hashcode/safestrap/ics/SafestrapActivity.java:
--------------------------------------------------------------------------------
1 | package com.hashcode.safestrap.ics;
2 |
3 | import com.hashcode.safestrap.R;
4 | import com.hashcode.safestrap.ics.AssetControl;
5 | import com.hashcode.safestrap.ics.ExecuteAsRootBase;
6 | import com.hashcode.safestrap.ics.InstallDialogThread;
7 | import com.hashcode.safestrap.ics.UninstallDialogThread;
8 |
9 | import android.app.Activity;
10 | import android.app.AlertDialog;
11 | import android.app.Dialog;
12 | import android.app.ProgressDialog;
13 | import android.content.DialogInterface;
14 | import android.content.SharedPreferences;
15 | import android.os.Bundle;
16 | import android.os.Handler;
17 | import android.os.Message;
18 | import android.view.View;
19 | import android.widget.Button;
20 | import android.widget.TextView;
21 | import android.widget.Toast;
22 |
23 | import java.util.Properties;
24 |
25 | public class SafestrapActivity extends Activity {
26 | final static public String PREFS_NAME = "disclaimer";
27 |
28 | private TextView statusText = null;
29 | private TextView messageText = null;
30 | private TextView textSystemStatus = null;
31 | private Button buttonInstall = null;
32 | private Button buttonUninstall = null;
33 | private Button buttonReboot = null;
34 | private Button buttonRebootWriteProtect = null;
35 | private InstallDialogThread installDialogThread = null;
36 | private UninstallDialogThread uninstallDialogThread = null;
37 | private ProgressDialog pDialog = null;
38 | private Boolean rootCheck = false;
39 | private Boolean writeProtect = false;
40 |
41 | /** Setup the Widgets */
42 | protected void setupControls() {
43 | /* Setup button */
44 | try {
45 | buttonRebootWriteProtect.setVisibility(View.GONE);
46 | if (rootCheck) {
47 | /* Check Version */
48 | String inText = ExecuteAsRootBase.executecmd("sh " + getFilesDir().toString() + "/recovery-check.sh " + getFilesDir().toString());
49 | String parts[] = inText.split(":");
50 | String vers_s = null;
51 | float vers = 0;
52 | Boolean altbootmode = false;
53 | if (parts != null) {
54 | if (parts.length >= 1) { vers_s = parts[0]; }
55 | if (parts.length >= 2) {
56 | if (parts[1].equals("1"))
57 | altbootmode = true;
58 | }
59 | if (parts.length >=3) {
60 | if (parts[2].equals("1")) {
61 | writeProtect = true;
62 | }
63 | }
64 | }
65 | if (vers_s != null) {
66 | vers = Float.valueOf(vers_s);
67 | }
68 | buttonUninstall.setEnabled(true);
69 | buttonInstall.setEnabled(true);
70 | buttonReboot.setEnabled(true);
71 | if (vers == 0) {
72 | statusText.setText("Not installed");
73 | buttonReboot.setEnabled(false);
74 | } else {
75 | float check_vers = Float.valueOf(this.getString(R.string.version));
76 | if (vers == check_vers) {
77 | statusText.setText("Installed");
78 | } else if (vers > check_vers) {
79 | statusText.setText("Newer Version Installed");
80 | buttonInstall.setEnabled(false);
81 | } else {
82 | statusText.setText("Old Version");
83 | }
84 | }
85 | textSystemStatus.setText("Not Active");
86 | /* setMessage(check); */
87 | if (altbootmode) {
88 | textSystemStatus.setText("Active");
89 | }
90 | if (writeProtect) {
91 | statusText.setText("Write Protect Enabled");
92 | buttonUninstall.setEnabled(false);
93 | buttonInstall.setEnabled(false);
94 | buttonReboot.setEnabled(true);
95 | buttonRebootWriteProtect.setVisibility(View.VISIBLE);
96 | }
97 | }
98 | else {
99 | statusText.setText("Not Rooted");
100 | buttonUninstall.setEnabled(false);
101 | buttonInstall.setEnabled(false);
102 | buttonReboot.setEnabled(false);
103 | }
104 | }
105 | finally {
106 | }
107 | }
108 |
109 | protected Dialog onCreateDialog(int id) {
110 | // show disclaimer....
111 | // for example, you can show a dialog box...
112 | AlertDialog.Builder builder = new AlertDialog.Builder(this);
113 | builder.setMessage(R.string.disclaimer);
114 | builder.setCancelable(false);
115 | builder.setPositiveButton("Agree", new DialogInterface.OnClickListener() {
116 | public void onClick(DialogInterface dialog, int id) {
117 | // and, if the user accept, you can execute something like this:
118 | // We need an Editor object to make preference changes.
119 | // All objects are from android.context.Context
120 | SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
121 | SharedPreferences.Editor editor = settings.edit();
122 | editor.putBoolean("accepted", true);
123 | // Commit the edits!
124 | editor.commit();
125 | }
126 | })
127 | .setNegativeButton("Disagree", new DialogInterface.OnClickListener() {
128 | public void onClick(DialogInterface dialog, int id) {
129 | //nm.cancel(R.notification.running); // cancel the NotificationManager (icon)
130 | System.exit(0);
131 | }
132 | });
133 | AlertDialog alert = builder.create();
134 | return alert;
135 | }
136 |
137 | /** Called when the activity is first created. */
138 | @Override
139 | public void onCreate(Bundle savedInstanceState) {
140 | statusText = (TextView)findViewById(R.id.textInstallStatus);
141 | super.onCreate(savedInstanceState);
142 | setContentView(R.layout.main);
143 |
144 | SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
145 | if ( settings.getBoolean("accepted", false) == false ) {
146 | showDialog(0);
147 | }
148 |
149 | buttonInstall = (Button)findViewById(R.id.buttonInstall);
150 | buttonUninstall = (Button)findViewById(R.id.buttonUninstall);
151 | buttonReboot = (Button)findViewById(R.id.buttonReboot);
152 | buttonRebootWriteProtect = (Button)findViewById(R.id.buttonRebootWriteProtect);
153 | statusText = (TextView)findViewById(R.id.textInstallStatus);
154 | messageText = (TextView)findViewById(R.id.textView1);
155 | textSystemStatus = (TextView)findViewById(R.id.textSystemStatus);
156 |
157 | rootCheck = ExecuteAsRootBase.canRunRootCommands();
158 | if (rootCheck) {
159 | /* For new MotoX we need to check write_protect=1 in cmdline */
160 | AssetControl unzip = new AssetControl();
161 | unzip.apkPath= getPackageCodePath();
162 | unzip.mAppRoot = getFilesDir().toString();
163 | unzip.unzipAsset("/busybox");
164 | unzip.unzipAsset("/recovery-check.sh");
165 | unzip.unzipAsset("/recovery-reboot.sh");
166 | unzip.unzipAsset("/ss_function.sh");
167 | unzip.unzipAsset("/ss.config");
168 | unzip = null;
169 | ExecuteAsRootBase.executecmd("chmod 755 " + getFilesDir() + "/busybox");
170 | ExecuteAsRootBase.executecmd("chmod 755 " + getFilesDir() + "/*.sh");
171 |
172 | buttonInstall.setOnClickListener(new View.OnClickListener() {
173 | public void onClick(View v) {
174 | try {
175 | pDialog = new ProgressDialog(v.getRootView().getContext());
176 | pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
177 | pDialog.setMessage("Installing...");
178 | pDialog.setCancelable(false);
179 | pDialog.show();
180 | pDialog.getCurrentFocus();
181 | installDialogThread = new InstallDialogThread();
182 | installDialogThread.packageCodePath = getPackageCodePath();
183 | installDialogThread.mAppRoot = getFilesDir();
184 | installDialogThread.LOGTAG = "Safestrap";
185 | installDialogThread.handler = new Handler() {
186 | @Override
187 | public void handleMessage(Message msg) {
188 | if (msg.arg1 == 0) {
189 | pDialog.dismiss();
190 | pDialog = null;
191 | Toast.makeText(buttonInstall.getRootView().getContext(), (String)msg.obj, Toast.LENGTH_LONG).show();
192 | setupControls();
193 | } else {
194 | pDialog.setProgress(msg.arg2);
195 | pDialog.setMessage((String)msg.obj);
196 | }
197 | }
198 | };
199 | installDialogThread.start();
200 | } catch(Exception ex) {
201 | messageText.setText(ex.getMessage());
202 | }
203 | }
204 | });
205 |
206 | buttonUninstall.setOnClickListener(new View.OnClickListener() {
207 | public void onClick(View v) {
208 | try {
209 | pDialog = new ProgressDialog(v.getRootView().getContext());
210 | pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
211 | pDialog.setMessage("Loading...");
212 | pDialog.setCancelable(false);
213 | pDialog.show();
214 | pDialog.getCurrentFocus();
215 | uninstallDialogThread = new UninstallDialogThread();
216 | uninstallDialogThread.packageCodePath = getPackageCodePath();
217 | uninstallDialogThread.mAppRoot = getFilesDir();
218 | uninstallDialogThread.LOGTAG = "Safestrap";
219 | uninstallDialogThread.handler = new Handler() {
220 | @Override
221 | public void handleMessage(Message msg) {
222 | if (msg.arg1 == 0) {
223 | pDialog.dismiss();
224 | pDialog = null;
225 | Toast.makeText(buttonUninstall.getRootView().getContext(), (String)msg.obj, Toast.LENGTH_LONG).show();
226 | setupControls();
227 | } else {
228 | pDialog.setProgress(msg.arg2);
229 | pDialog.setMessage((String)msg.obj);
230 | }
231 | }
232 | };
233 | uninstallDialogThread.start();
234 | } catch(Exception ex) {
235 | messageText.setText(ex.getMessage());
236 | }
237 | }
238 | });
239 |
240 | buttonReboot.setOnClickListener(new View.OnClickListener() {
241 | public void onClick(View v) {
242 | try {
243 | ExecuteAsRootBase.executecmd("sh " + getFilesDir().toString() + "/recovery-reboot.sh " + getFilesDir().toString());
244 | Runtime.getRuntime().exec(new String[]{"su","-c","reboot now"});
245 | } catch(Exception ex) {
246 | messageText.setText(ex.getMessage());
247 | }
248 | }
249 | });
250 |
251 | buttonRebootWriteProtect.setOnClickListener(new View.OnClickListener() {
252 | public void onClick(View v) {
253 | try {
254 | ExecuteAsRootBase.executecmd("reboot recovery");
255 | } catch(Exception ex) {
256 | messageText.setText(ex.getMessage());
257 | }
258 | }
259 | });
260 | }
261 |
262 | setupControls();
263 | }
264 | }
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
10 |
11 | android-17
12 |
13 |
14 |
15 |
16 |
17 | Galaxy Nexus
18 | @android:style/Theme.DeviceDefault
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 | localhost
390 | 5050
391 |
392 |
393 |
394 |
395 |
396 |
397 | 1368649641987
398 | 1368649641987
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 |
534 |
535 |
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 |
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 |
576 |
577 |
578 |
579 |
580 |
581 |
582 |
583 |
584 |
585 |
586 |
587 |
588 |
589 |
590 |
591 |
592 |
593 |
594 |
595 |
596 | Android
597 |
598 |
599 |
600 |
601 |
602 |
603 |
604 |
605 |
606 |
607 |
608 |
609 |
610 |
611 |
612 |
613 |
614 |
615 |
616 |
617 |
618 |
619 | 1.6
620 |
621 |
622 |
623 |
624 |
625 |
626 |
627 |
628 |
629 |
630 |
631 | Safestrap
632 |
633 |
634 |
635 |
636 |
637 |
638 |
639 |
640 |
641 |
642 |
643 |
644 | Android 4.0 Platform
645 |
646 |
647 |
648 |
649 |
650 |
651 |
652 |
653 |
654 |
655 |
656 |
657 |
658 |
659 |
660 |
661 |
662 |
663 |
664 |
665 |
666 |
667 |
668 |
669 |
--------------------------------------------------------------------------------