From 38ca4105565a66761ff9170bf092ea096d40315d Mon Sep 17 00:00:00 2001 From: Vladimir Stolyarov Date: Sun, 22 Jan 2017 19:32:10 +0300 Subject: [PATCH] Add LOKI support add LOKI as submodules add "lokiaboot" and "lokipatch" partition properties to fstab patch partitions marked as "lokipatch" before flashing --- .gitmodules | 3 ++ app/build.gradle | 9 ++++ app/src/main/cpp/Android.mk | 10 ++++ app/src/main/cpp/loki_wrapper.c | 35 ++++++++++++++ .../efidroid/efidroidmanager/LokiTool.java | 46 ++++++++++++++++++ .../tasks/EFIDroidInstallServiceTask.java | 48 +++++++++++++++++-- .../efidroidmanager/types/FSTabEntry.java | 20 ++++++++ sub_projects/Loki | 1 + 8 files changed, 167 insertions(+), 5 deletions(-) create mode 100644 .gitmodules create mode 100644 app/src/main/cpp/Android.mk create mode 100644 app/src/main/cpp/loki_wrapper.c create mode 100644 app/src/main/java/org/efidroid/efidroidmanager/LokiTool.java create mode 160000 sub_projects/Loki diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..2198eaf --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "sub_projects/Loki"] + path = sub_projects/Loki + url = https://github.com/efidroid/modules_loki.git diff --git a/app/build.gradle b/app/build.gradle index 9fef9a2..86c79a8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -25,6 +25,10 @@ android { buildConfigField "long", "TIMESTAMP", System.currentTimeMillis() + "L" buildConfigField "String", "USERNAME", "\""+System.getProperty("user.name")+"\"" buildConfigField "String", "HOSTNAME", "\""+InetAddress.getLocalHost().getHostName()+"\"" + + ndk { + abiFilters "armeabi-v7a" + } } buildTypes { release { @@ -36,6 +40,11 @@ android { versionNameSuffix "-debug" } } + externalNativeBuild { + ndkBuild { + path 'src/main/cpp/Android.mk' + } + } } dependencies { diff --git a/app/src/main/cpp/Android.mk b/app/src/main/cpp/Android.mk new file mode 100644 index 0000000..de850da --- /dev/null +++ b/app/src/main/cpp/Android.mk @@ -0,0 +1,10 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) +LOCAL_MODULE := loki-wrapper +LOCAL_SRC_FILES := loki_wrapper.c +LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../../../sub_projects/Loki +LOCAL_STATIC_LIBRARIES := libloki_static +include $(BUILD_SHARED_LIBRARY) + +include $(LOCAL_PATH)/../../../../sub_projects/Loki/Android.mk diff --git a/app/src/main/cpp/loki_wrapper.c b/app/src/main/cpp/loki_wrapper.c new file mode 100644 index 0000000..3ee641d --- /dev/null +++ b/app/src/main/cpp/loki_wrapper.c @@ -0,0 +1,35 @@ +#include +#include + +JNIEXPORT jint JNICALL +Java_org_efidroid_efidroidmanager_LokiTool_lokiPatch(JNIEnv *env, jobject instance, + jstring partitionLabel_, jstring abootImage_, + jstring inImage_, jstring outImage_) { + const char *partitionLabel = (*env)->GetStringUTFChars(env, partitionLabel_, 0); + const char *abootImage = (*env)->GetStringUTFChars(env, abootImage_, 0); + const char *inImage = (*env)->GetStringUTFChars(env, inImage_, 0); + const char *outImage = (*env)->GetStringUTFChars(env, outImage_, 0); + + int ret = loki_patch(partitionLabel,abootImage,inImage,outImage); + + (*env)->ReleaseStringUTFChars(env, partitionLabel_, partitionLabel); + (*env)->ReleaseStringUTFChars(env, abootImage_, abootImage); + (*env)->ReleaseStringUTFChars(env, inImage_, inImage); + (*env)->ReleaseStringUTFChars(env, outImage_, outImage); + + return ret; +} + +JNIEXPORT jint JNICALL +Java_org_efidroid_efidroidmanager_LokiTool_lokiFlash(JNIEnv *env, jobject instance, + jstring partitionLabel_, jstring image_) { + const char *partitionLabel = (*env)->GetStringUTFChars(env, partitionLabel_, 0); + const char *image = (*env)->GetStringUTFChars(env, image_, 0); + + int ret = loki_flash(partitionLabel, image); + + (*env)->ReleaseStringUTFChars(env, partitionLabel_, partitionLabel); + (*env)->ReleaseStringUTFChars(env, image_, image); + + return ret; +} diff --git a/app/src/main/java/org/efidroid/efidroidmanager/LokiTool.java b/app/src/main/java/org/efidroid/efidroidmanager/LokiTool.java new file mode 100644 index 0000000..b2bd214 --- /dev/null +++ b/app/src/main/java/org/efidroid/efidroidmanager/LokiTool.java @@ -0,0 +1,46 @@ +package org.efidroid.efidroidmanager; + +import android.util.Log; + +import com.stericson.roottools.RootTools; +import static com.android.volley.VolleyLog.TAG; + +public class LokiTool { + public enum PartitionLabel { + BOOT("boot"), + RECOVERY("recovery"); + + String mLabel; + PartitionLabel(String s) { + mLabel=s; + } + public String getLabel() { + return mLabel; + } + } + + static { + System.loadLibrary("loki-wrapper"); + } + + private LokiTool() {} + + private static native int lokiPatch(String partitionLabel, String bootloaderImage, + String inImage, String outImage); + private static native int lokiFlash(String partitionLabel, String image); + + public static boolean patchImage(PartitionLabel label, String bootloaderImage, + String inImage, String outImage) { + return lokiPatch(label.getLabel(),bootloaderImage,inImage,outImage) == 0; + } + + public static boolean flashImage(PartitionLabel label, String image) { + //root required for flashing + boolean isRootAccess = RootTools.isAccessGiven(); + if (!isRootAccess) { + Log.e(TAG, "flashImage: cannot get root privileges"); + return false; + } + return lokiFlash(label.getLabel(), image) == 0; + } +} diff --git a/app/src/main/java/org/efidroid/efidroidmanager/tasks/EFIDroidInstallServiceTask.java b/app/src/main/java/org/efidroid/efidroidmanager/tasks/EFIDroidInstallServiceTask.java index 6c47dec..b73f412 100644 --- a/app/src/main/java/org/efidroid/efidroidmanager/tasks/EFIDroidInstallServiceTask.java +++ b/app/src/main/java/org/efidroid/efidroidmanager/tasks/EFIDroidInstallServiceTask.java @@ -3,7 +3,10 @@ import android.os.Bundle; import android.support.annotation.Keep; +import com.stericson.roottools.RootTools; + import org.efidroid.efidroidmanager.AppConstants; +import org.efidroid.efidroidmanager.LokiTool; import org.efidroid.efidroidmanager.R; import org.efidroid.efidroidmanager.RootToolsEx; import org.efidroid.efidroidmanager.Util; @@ -17,6 +20,7 @@ import org.json.JSONObject; import java.io.BufferedInputStream; +import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; @@ -114,6 +118,17 @@ private String downloadUpdate(String urlString) throws Exception { return downloadDir; } + private static void lokiPatchAndFlash(LokiTool.PartitionLabel partition, + String bootloaderImage, String fileToPatch) throws Exception { + if (bootloaderImage == null) + throw new FileNotFoundException("Cannot find backed up bootloader"); + String patchedFile = fileToPatch + ".lok"; + if (!LokiTool.patchImage(partition,bootloaderImage,fileToPatch,patchedFile)) + throw new Exception("Loki patching error"); + if (!LokiTool.flashImage(partition,patchedFile)) + throw new Exception("Loki flashing patched image error"); + } + private void doInstall(String updateDir) throws Exception { // get esp parent directory String espParent = mDeviceInfo.getESPDir(false); @@ -161,13 +176,36 @@ private void doInstall(String updateDir) throws Exception { } } - // install + //dump bootloader to temporary folder + String bootloaderImage = null; for (FSTabEntry entry : mDeviceInfo.getFSTab().getFSTabEntries()) { - if (!entry.isUEFI()) - continue; + if (entry.isLokiAboot()) { + bootloaderImage = getService().getCacheDir().getCanonicalPath() + "/bootloader.img"; + RootToolsEx.createPartitionBackup(getService(),entry.getBlkDevice(),bootloaderImage,-1); + } + } - String file = updateDir + "/" + entry.getName() + ".img"; - RootToolsEx.dd(file, entry.getBlkDevice()); + // install + try { + for (FSTabEntry entry : mDeviceInfo.getFSTab().getFSTabEntries()) { + if (!entry.isUEFI()) + continue; + + String file = updateDir + "/" + entry.getName() + ".img"; + + //if needed, apply LOKI patch to boot and recovery partitions + if (entry.isLokiPatch() && + entry.getName().equals(LokiTool.PartitionLabel.BOOT.getLabel())) + lokiPatchAndFlash(LokiTool.PartitionLabel.BOOT, bootloaderImage, file); + else if (entry.isLokiPatch() && + entry.getName().equals(LokiTool.PartitionLabel.RECOVERY.getLabel())) + lokiPatchAndFlash(LokiTool.PartitionLabel.RECOVERY, bootloaderImage, file); + else + RootToolsEx.dd(file, entry.getBlkDevice()); + } + } finally { + //remove bootloader dump + RootTools.deleteFileOrDirectory(bootloaderImage, true); } } diff --git a/app/src/main/java/org/efidroid/efidroidmanager/types/FSTabEntry.java b/app/src/main/java/org/efidroid/efidroidmanager/types/FSTabEntry.java index c40d8e6..2dc32ff 100644 --- a/app/src/main/java/org/efidroid/efidroidmanager/types/FSTabEntry.java +++ b/app/src/main/java/org/efidroid/efidroidmanager/types/FSTabEntry.java @@ -105,6 +105,26 @@ public boolean isMultiboot() { return false; } + public boolean isLokiAboot() { + String[] parts = mFfMgrFlags.split(","); + for (String part : parts) { + if (part.equals("lokiaboot")) { + return true; + } + } + return false; + } + + public boolean isLokiPatch() { + String[] parts = mFfMgrFlags.split(","); + for (String part : parts) { + if (part.equals("lokipatch")) { + return true; + } + } + return false; + } + public boolean isUEFI() { String[] parts = mFfMgrFlags.split(","); for (String part : parts) { diff --git a/sub_projects/Loki b/sub_projects/Loki new file mode 160000 index 0000000..784e86f --- /dev/null +++ b/sub_projects/Loki @@ -0,0 +1 @@ +Subproject commit 784e86f981b7b1c30bd0d6b401f071e47e738eb8