These repositories do not keep the actual projects in the top level directory.
This is because they contain tests, libs, and samples.
+Make sure the SDK Platform for API 17 is installed, through the Android SDK Manager. Install NDK Revision 8e from [here](http://developer.android.com/tools/sdk/ndk/index.html).
+
## Eclipse
In Eclipse, import Widgets/Widgets and Superuser/Superuser. It should Just Work (TM).
* $ cd /path/to/src
* $ cd Superuser/Superuser
-In this directory, create a file called local.properties. This file is used by ant for custom properties. You need to specify the location of the ndk directory:
+In this directory, create a file called local.properties. This file is used by ant for custom properties. You need to specify the location of the ndk directory and your keystore parameters:
```
ndk.dir=/Users/koush/src/android-ndk
+key.store=/Users/koush/.keystore
+key.alias=mykey
```
+If you do not have a release key yet, [create one using keytool](http://developer.android.com/tools/publishing/app-signing.html).
+
+Set up your SDK path (this is the directory containing platform-tools/, tools/, etc.):
+
+* $ export ANDROID_HOME=/Users/koush/src/sdk
+
Then you can build:
* $ ant release
Outputs:
* bin/update.zip - Recovery installable zip
-* bin/Superuser.apk - Superuser Android app
+* bin/Superuser-release.apk - Superuser Android app
* libs/armeabi/su - ARM su binary
* libs/x86/su - x86 su binary
+* libs/mips/su - MIPS su binary
## Building the su binary
echo -n -e 'ui_print\n' > /proc/self/fd/$2
# detect binary versions to install
-X86=$(uname -a | grep x86)
-I686=$(uname -a | grep i686)
-I386=$(uname -a | grep i386)
-if [ ! -z "$X86" -o ! -z "$I686" -o ! -z "$I386" ]
-then
+ARCH=$(uname -m)
+
+# x86 needs to match: i486, i686, x86_64, ...
+if echo "$ARCH" | grep -q 86; then
PLATFORM=x86
+elif [ "$ARCH" = "mips" -o "$ARCH" = "mips64" ]; then
+ PLATFORM=mips
else
PLATFORM=armeabi
fi
# if the system is at least 4.3, and there is no su daemon built in,
# let's try to install it using install-recovery.sh
-BUILD_RELEASE_VERSION=$(cat /system/build.prop | grep ro\\.build\\.version\\.release)
-IS_43=$(echo $BUILD_RELEASE_VERSION | grep 4\\.3)
-if [ ! -z "$IS_43" ]
+BUILD_RELEASE_VERSION="$(grep 'ro\.build\.version\.release' /system/build.prop)"
+VERSION="${BUILD_RELEASE_VERSION##*=}"
+MAJ=${VERSION%%.*}
+MIN=${VERSION#*.}
+MIN=${MIN//.*}
+
+if [ "$MAJ" -ge 4 -a "$MIN" -ge 3 ]
then
- if [ "$IS_43" \> "4.3" -o "$IS_43" == "4.3" ]
+ # check for rom su daemon before clobbering install-recovery.sh
+ if [ ! -f "/system/etc/.has_su_daemon" ]
then
- # check for rom su daemon before clobbering install-recovery.sh
- if [ ! -f "/system/etc/.has_su_daemon" ]
- then
- echo -n -e 'ui_print Installing Superuser daemon...\n' > /proc/self/fd/$2
- echo -n -e 'ui_print\n' > /proc/self/fd/$2
- chattr -i /system/etc/install-recovery.sh
- cp install-recovery.sh /system/etc/install-recovery.sh
- chmod 755 /system/etc/install-recovery.sh
- # note that an post install su daemon was installed
- # so recovery doesn't freak out and recommend you disable
- # the install-recovery.sh execute bit.
- touch /system/etc/.installed_su_daemon
- fi
+ echo -n -e 'ui_print Installing Superuser daemon...\n' > /proc/self/fd/$2
+ echo -n -e 'ui_print\n' > /proc/self/fd/$2
+ chattr -i /system/etc/install-recovery.sh
+ cp install-recovery.sh /system/etc/install-recovery.sh
+ chmod 755 /system/etc/install-recovery.sh
+ # note that an post install su daemon was installed
+ # so recovery doesn't freak out and recommend you disable
+ # the install-recovery.sh execute bit.
+ touch /system/etc/.installed_su_daemon
fi
fi
<arg value="../bin/update.zip"/>
<arg value="armeabi"/>
<arg value="x86"/>
+ <arg value="mips"/>
</exec>
</target>
include $(CLEAR_VARS)
+LOCAL_MODULE := reboot
+LOCAL_LDFLAGS := -llog
+LOCAL_STATIC_LIBRARIES := sqlite3
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/sqlite3
+LOCAL_SRC_FILES := reboot/reboot.c
+include $(BUILD_EXECUTABLE)
+
+
+include $(CLEAR_VARS)
+
LOCAL_MODULE := sqlite3
LOCAL_SRC_FILES := sqlite3/sqlite3.c
LOCAL_CFLAGS := -DSQLITE_OMIT_LOAD_EXTENSION
-APP_ABI := x86 armeabi
+APP_ABI := x86 armeabi mips
NDK_TOOLCHAIN_VERSION=4.7
APP_PIE = false
\ No newline at end of file
--- /dev/null
+/*
+** Copyright 2013, Kevin Cernekee <cernekee@gmail.com>
+**
+** This was reverse engineered from an HTC "reboot" binary and is an attempt
+** to remain bug-compatible with the original.
+**
+** 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.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <sqlite3.h>
+#include <sys/reboot.h>
+#include <android/log.h>
+
+#define SETTINGS_DB "/data/data/com.android.providers.settings/databases/settings.db"
+#define SCREEN_LOCK_STATUS "/data/misc/screen_lock_status"
+
+int pattern_lock;
+
+int sqlcallback(void *private, int n_columns, char **col_values, char **col_names)
+{
+ pattern_lock = 0;
+
+ if (n_columns == 0 || !col_values[0])
+ return 0;
+
+ if (!strcmp(col_values[0], "1"))
+ pattern_lock = 1;
+
+ __android_log_print(ANDROID_LOG_INFO, NULL,
+ "sqlcallback %s = %s, pattern_locks= %d\n",
+ col_names[0], col_values[0], pattern_lock);
+ return 0;
+}
+
+int checkPatternLock(void)
+{
+ sqlite3 *pDb = NULL;
+ char *errmsg = NULL;
+
+ if (sqlite3_open(SETTINGS_DB, &pDb) != 0) {
+ __android_log_print(ANDROID_LOG_ERROR, NULL,
+ "sqlite3_open error");
+ /* BUG? probably shouldn't call sqlite3_close() if open failed */
+ goto out;
+ }
+
+ if (sqlite3_exec(pDb,
+ "select value from system where name= \"lock_pattern_autolock\"",
+ sqlcallback, "checkPatternLock", &errmsg) != 0) {
+ __android_log_print(ANDROID_LOG_ERROR, NULL,
+ "SQL error: %s\n", errmsg);
+ sqlite3_free(errmsg);
+ goto out;
+ }
+
+out:
+ sqlite3_close(pDb);
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ int no_sync = 0, power_off = 0;
+ int ret;
+
+ opterr = 0;
+ while ((ret = getopt(argc, argv, "np")) != -1) {
+ switch (ret) {
+ case 'n':
+ no_sync = 1;
+ break;
+ case 'p':
+ power_off = 1;
+ break;
+ case '?':
+ fprintf(stderr, "usage: %s [-n] [-p] [rebootcommand]\n",
+ argv[0]);
+ exit(1);
+ break;
+ }
+ }
+
+ if (argc > (optind + 1)) {
+ fprintf(stderr, "%s: too many arguments\n", argv[0]);
+ exit(1);
+ }
+
+ /* BUG: this should use optind */
+ if (argc > 1 && !strcmp(argv[1], "oem-78")) {
+ /* HTC RUU mode: "reboot oem-78" */
+
+ FILE *f;
+ char buf[5];
+
+ checkPatternLock();
+ f = fopen(SCREEN_LOCK_STATUS, "r");
+ if (!f) {
+ fputs("5\n", stderr);
+ exit(0);
+ }
+ fgets(buf, 5, f);
+ if (atoi(buf) == 1) {
+ if (pattern_lock != 0) {
+ fputs("1\n", stderr);
+ exit(0);
+ }
+ }
+ fputs("0\n", stderr);
+ }
+
+ if (!no_sync)
+ sync();
+
+ if (power_off) {
+ ret = __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
+ LINUX_REBOOT_CMD_POWER_OFF, 0);
+ } else if (optind >= argc) {
+ ret = reboot(LINUX_REBOOT_CMD_RESTART);
+ } else {
+ ret = __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
+ LINUX_REBOOT_CMD_RESTART2, argv[optind]);
+ }
+
+ if (ret < 0) {
+ perror("reboot");
+ exit(1);
+ } else {
+ fputs("reboot returned\n", stderr);
+ exit(0);
+ }
+}
return super.onCreateOptionsMenu(menu);
}
+
+ private String getArch() {
+ String prop = System.getProperty("os.arch");
+ if (prop.contains("x86") || prop.contains("i686") || prop.contains("i386")) {
+ return "x86";
+ } else if (prop.contains("mips")) {
+ return "mips";
+ } else {
+ return "armeabi";
+ }
+ }
File extractSu() throws IOException, InterruptedException {
- String arch = "armeabi";
- if (System.getProperty("os.arch").contains("x86") || System.getProperty("os.arch").contains("i686") || System.getProperty("os.arch").contains("i386"))
- arch = "x86";
ZipFile zf = new ZipFile(getPackageCodePath());
- ZipEntry su = zf.getEntry("assets/" + arch + "/su");
+ ZipEntry su = zf.getEntry("assets/" + getArch() + "/su");
InputStream zin = zf.getInputStream(su);
File ret = getFileStreamPath("su");
FileOutputStream fout = new FileOutputStream(ret);
zout.close();
ZipFile zf = new ZipFile(getPackageCodePath());
- ZipEntry ze = zf.getEntry("assets/reboot");
+ ZipEntry ze = zf.getEntry("assets/" + getArch() + "/reboot");
InputStream in;
FileOutputStream reboot;
StreamUtility.copyStream(in = zf.getInputStream(ze), reboot = openFileOutput("reboot", MODE_PRIVATE));