themes: convert theme copying to a golang module

Change-Id: I0a1e4b79109cf9db93acb0575200f4ec8f72d3a2
diff --git a/Android.bp b/Android.bp
index 5afdbfd..ffb4f1a 100755
--- a/Android.bp
+++ b/Android.bp
@@ -23,7 +23,8 @@
         "soong-cc"
     ],
     srcs: [
-        "libaosprecovery_defaults.go"
+        "libaosprecovery_defaults.go",
+        "soong/makevars.go"
     ],
     pluginFor: ["soong_build"]
 }
diff --git a/gui/Android.bp b/gui/Android.bp
index e5b97d8..c66cae4 100644
--- a/gui/Android.bp
+++ b/gui/Android.bp
@@ -7,7 +7,9 @@
         "soong-cc"
     ],
     srcs: [
-        "libguitwrp_defaults.go"
+        "libguitwrp_defaults.go",
+        "../soong/copy.go",
+        "../soong/makevars.go"
     ],
     pluginFor: ["soong_build"]
 }
@@ -22,7 +24,8 @@
     cflags: [
         "-fno-strict-aliasing", 
         "-Wno-implicit-fallthrough",
-        "-D_USE_SYSTEM_ZIPARCHIVE"
+        "-D_USE_SYSTEM_ZIPARCHIVE",
+        "-DTWRES=\"/twres/\""
     ],
     include_dirs: [
         "bootable/recovery/crypto/scrypt/lib/util",
diff --git a/gui/libguitwrp_defaults.go b/gui/libguitwrp_defaults.go
index 2d8b3de..3e00347 100644
--- a/gui/libguitwrp_defaults.go
+++ b/gui/libguitwrp_defaults.go
@@ -1,122 +1,291 @@
-package libgui_defaults

-

-import (

-	"android/soong/android"

-	"android/soong/cc"

-)

-

-func globalFlags(ctx android.BaseContext) []string {

-	var cflags []string

-

-	if ctx.AConfig().Getenv("TW_DELAY_TOUCH_INIT_MS") != "" {

-		cflags = append(cflags, "-DTW_DELAY_TOUCH_INIT_MS="+ctx.AConfig().Getenv("TW_DELAY_TOUCH_INIT_MS"))

-	}

-

-	if ctx.AConfig().Getenv("TW_EVENT_LOGGING") == "true" {

-		cflags = append(cflags, "-D_EVENT_LOGGING")

-	}

-

-	if ctx.AConfig().Getenv("TW_USE_KEY_CODE_TOUCH_SYNC") != "" {

-		cflags = append(cflags, "-DTW_USE_KEY_CODE_TOUCH_SYNC="+ctx.AConfig().Getenv("TW_USE_KEY_CODE_TOUCH_SYNC"))

-	}

-

-	if ctx.AConfig().Getenv("TW_SCREEN_BLANK_ON_BOOT") != "" {

-		cflags = append(cflags, "-DTW_SCREEN_BLANK_ON_BOOT")

-	}

-

-	if ctx.AConfig().Getenv("TW_OZIP_DECRYPT_KEY") != "" {

-		cflags = append(cflags, "-DTW_OZIP_DECRYPT_KEY=\""+ctx.AConfig().Getenv("TW_OZIP_DECRYPT_KEY")+"\"")

-	} else {

-		cflags = append(cflags, "-DTW_OZIP_DECRYPT_KEY=0")

-	}

-

-	if ctx.AConfig().Getenv("TW_NO_SCREEN_BLANK") != "" {

-		cflags = append(cflags, "-DTW_NO_SCREEN_BLANK")

-	}

-

-	if ctx.AConfig().Getenv("TW_NO_SCREEN_TIMEOUT") != "" {

-		cflags = append(cflags, "-DTW_NO_SCREEN_TIMEOUT")

-	}

-

-	if ctx.AConfig().Getenv("TW_OEM_BUILD") != "" {

-		cflags = append(cflags, "-DTW_OEM_BUILD")

-	}

-

-	if ctx.AConfig().Getenv("TW_X_OFFSET") != "" {

-		cflags = append(cflags, "-DTW_X_OFFSET="+ctx.AConfig().Getenv("TW_X_OFFSET"))

-	}

-

-	if ctx.AConfig().Getenv("TW_Y_OFFSET") != "" {

-		cflags = append(cflags, "-DTW_Y_OFFSET="+ctx.AConfig().Getenv("TW_Y_OFFSET"))

-	}

-

-	if ctx.AConfig().Getenv("TW_W_OFFSET") != "" {

-		cflags = append(cflags, "-DTW_W_OFFSET="+ctx.AConfig().Getenv("TW_W_OFFSET"))

-	}

-

-	if ctx.AConfig().Getenv("TW_H_OFFSET") != "" {

-		cflags = append(cflags, "-DTW_H_OFFSET="+ctx.AConfig().Getenv("TW_H_OFFSET"))

-	}

-

-	if ctx.AConfig().Getenv("TW_ROUND_SCREEN") == "true" {

-		cflags = append(cflags, "-DTW_ROUND_SCREEN")

-	}

-

-	cflags = append(cflags, "-DTWRES=\""+ctx.AConfig().Getenv("TWRES_PATH")+"\"")

-

-	return cflags

-}

-

-func globalSrcs(ctx android.BaseContext) []string {

-	var srcs []string

-

-	if ctx.AConfig().Getenv("TWRP_CUSTOM_KEYBOARD") != "" {

-		srcs = append(srcs, ctx.AConfig().Getenv("TWRP_CUSTOM_KEYBOARD"))

-	} else {

-		srcs = append(srcs, "hardwarekeyboard.cpp")

-	}

-	return srcs

-}

-

-func globalIncludes(ctx android.BaseContext) []string {

-	var includes []string

-

-	if ctx.AConfig().Getenv("TW_INCLUDE_CRYPTO") != "" {

-		includes = append(includes, "bootable/recovery/crypto/fscrypt")

-	}

-

-	return includes

-}

-

-func libGuiDefaults(ctx android.LoadHookContext) {

-	type props struct {

-		Target struct {

-			Android struct {

-				Cflags  []string

-				Enabled *bool

-			}

-		}

-		Cflags       []string

-		Srcs         []string

-		Include_dirs []string

-	}

-

-	p := &props{}

-	p.Cflags = globalFlags(ctx)

-	s := globalSrcs(ctx)

-	p.Srcs = s

-	i := globalIncludes(ctx)

-	p.Include_dirs = i

-	ctx.AppendProperties(p)

-}

-

-func init() {

-	android.RegisterModuleType("libguitwrp_defaults", libGuiDefaultsFactory)

-}

-

-func libGuiDefaultsFactory() android.Module {

-	module := cc.DefaultsFactory()

-	android.AddLoadHook(module, libGuiDefaults)

-

-	return module

-}

+package twrp
+
+import (
+	"android/soong/android"
+	"android/soong/cc"
+	"fmt"
+	"os"
+	"path"
+	"strconv"
+	"strings"
+)
+
+func printThemeWarning(theme string) {
+	if theme == "" {
+		theme = "not set"
+	}
+	themeWarning := "***************************************************************************\n"
+	themeWarning += "Could not find ui.xml for TW_THEME: "
+	themeWarning += theme
+	themeWarning += "\nSet TARGET_SCREEN_WIDTH and TARGET_SCREEN_HEIGHT to automatically select\n"
+	themeWarning += "an appropriate theme, or set TW_THEME to one of the following:\n"
+	themeWarning += "landscape_hdpi landscape_mdpi portrait_hdpi portrait_mdpi watch_mdpi\n"
+	themeWarning += "****************************************************************************\n"
+	themeWarning += "(theme selection failed; exiting)\n"
+
+	fmt.Printf(themeWarning)
+}
+
+func printCustomThemeWarning(theme string, location string) {
+	customThemeWarning := "****************************************************************************\n"
+	customThemeWarning += "Could not find ui.xml for TW_CUSTOM_THEME: "
+	customThemeWarning += theme + "\n"
+	customThemeWarning += "Expected to find custom theme's ui.xml at: "
+	customThemeWarning += location
+	customThemeWarning += "Please fix this or set TW_THEME to one of the following:\n"
+	customThemeWarning += "landscape_hdpi landscape_mdpi portrait_hdpi portrait_mdpi watch_mdpi\n"
+	customThemeWarning += "****************************************************************************\n"
+	customThemeWarning += "(theme selection failed; exiting)\n"
+	fmt.Printf(customThemeWarning)
+}
+
+func copyThemeResources(ctx android.BaseContext, dirs []string, files []string) {
+	outDir := ctx.Config().Getenv("OUT")
+	twRes := outDir + "/recovery/root/twres/"
+	recoveryDir := getRecoveryAbsDir(ctx)
+	theme := determineTheme(ctx)
+	for idx, dir := range dirs {
+		_ = idx
+		dirToCopy := ""
+		destDir := twRes + path.Base(dir)
+		baseDir := path.Base(dir)
+		if baseDir == theme {
+			destDir = twRes
+			dirToCopy = recoveryDir + dir
+		} else {
+			dirToCopy = recoveryDir + dir
+		}
+		copyDir(dirToCopy, destDir)
+	}
+	for idx, file := range files {
+		_ = idx
+		fileToCopy := recoveryDir + file
+		fileDest := twRes + path.Base(file)
+		copyFile(fileToCopy, fileDest)
+	}
+}
+
+func copyCustomTheme(ctx android.BaseContext, customTheme string) {
+	outDir := ctx.Config().Getenv("OUT")
+	twRes := outDir + "/recovery/root/twres/"
+	fileDest := twRes + path.Base(customTheme)
+	fileToCopy := fmt.Sprintf("%s%s", getBuildAbsDir(ctx), customTheme)
+	copyFile(fileToCopy, fileDest)
+}
+
+func determineTheme(ctx android.BaseContext) string {
+	guiWidth := 0
+	guiHeight := 0
+	if getMakeVars(ctx, "TW_CUSTOM_THEME") == "" {
+		if getMakeVars(ctx, "TW_THEME") == "" {
+			if getMakeVars(ctx, "DEVICE_RESOLUTION") == "" {
+				width, err := strconv.Atoi(getMakeVars(ctx, "TARGET_SCREEN_WIDTH"))
+				if err == nil {
+					guiWidth = width
+				}
+				height, err := strconv.Atoi(getMakeVars(ctx, "TARGET_SCREEN_HEIGHT"))
+				if err == nil {
+					guiHeight = height
+				}
+			} else {
+				deviceRes := getMakeVars(ctx, "DEVICE_RESOLUTION")
+				width, err := strconv.Atoi(strings.Split(deviceRes, "x")[0])
+				if err == nil {
+					guiWidth = width
+				}
+				height, err := strconv.Atoi(strings.Split(deviceRes, "x")[1])
+				if err == nil {
+					guiHeight = height
+				}
+			}
+		}
+		if guiWidth > 100 {
+			if guiHeight > 100 {
+				if guiWidth > guiHeight {
+					if guiWidth > 1280 {
+						return "landscape_hdpi"
+					} else {
+						return "landscape_mdpi"
+					}
+				} else if guiWidth < guiHeight {
+					if guiWidth > 720 {
+						return "portrait_hdpi"
+					} else {
+						return "portrait_mdpi"
+					}
+				} else if guiWidth == guiHeight {
+					return "watch_mdpi"
+				}
+			}
+		}
+	}
+
+	return getMakeVars(ctx, "TW_THEME")
+}
+
+func copyTheme(ctx android.BaseContext) bool {
+	var directories []string
+	var files []string
+	var customThemeLoc string
+	localPath := ctx.ModuleDir()
+	directories = append(directories, "gui/theme/common/fonts/")
+	directories = append(directories, "gui/theme/common/languages/")
+	if getMakeVars(ctx, "TW_EXTRA_LANGUAGES") == "true" {
+		directories = append(directories, "gui/theme/extra-languages/fonts/")
+		directories = append(directories, "gui/theme/extra-languages/languages/")
+	}
+	var theme = determineTheme(ctx)
+	directories = append(directories, "gui/theme/"+theme)
+	themeXML := fmt.Sprintf("gui/theme/common/%s.xml", strings.Split(theme, "_")[0])
+	files = append(files, themeXML)
+	if getMakeVars(ctx, "TW_CUSTOM_THEME") == "" {
+		defaultTheme := fmt.Sprintf("%s/theme/%s/ui.xml", localPath, theme)
+		if android.ExistentPathForSource(ctx, defaultTheme).Valid() {
+			fullDefaultThemePath := fmt.Sprintf("gui/theme/%s/ui.xml", theme)
+			files = append(files, fullDefaultThemePath)
+		} else {
+			printThemeWarning(theme)
+			return false
+		}
+	} else {
+		customThemeLoc = getMakeVars(ctx, "TW_CUSTOM_THEME")
+		if android.ExistentPathForSource(ctx, customThemeLoc).Valid() {
+		} else {
+			printCustomThemeWarning(customThemeLoc, getMakeVars(ctx, "TW_CUSTOM_THEME"))
+			return false
+		}
+	}
+	copyThemeResources(ctx, directories, files)
+	if customThemeLoc != "" {
+		copyCustomTheme(ctx, customThemeLoc)
+	}
+	return true
+}
+
+func globalFlags(ctx android.BaseContext) []string {
+	var cflags []string
+
+	if getMakeVars(ctx, "TW_DELAY_TOUCH_INIT_MS") != "" {
+		cflags = append(cflags, "-DTW_DELAY_TOUCH_INIT_MS="+getMakeVars(ctx, "TW_DELAY_TOUCH_INIT_MS"))
+	}
+
+	if getMakeVars(ctx, "TW_EVENT_LOGGING") == "true" {
+		cflags = append(cflags, "-D_EVENT_LOGGING")
+	}
+
+	if getMakeVars(ctx, "TW_USE_KEY_CODE_TOUCH_SYNC") != "" {
+		cflags = append(cflags, "DTW_USE_KEY_CODE_TOUCH_SYNC="+getMakeVars(ctx, "TW_USE_KEY_CODE_TOUCH_SYNC"))
+	}
+
+	if ctx.AConfig().Getenv("TW_SCREEN_BLANK_ON_BOOT") != "" {
+		cflags = append(cflags, "-DTW_SCREEN_BLANK_ON_BOOT")
+	}
+
+	if getMakeVars(ctx, "TW_OZIP_DECRYPT_KEY") != "" {
+		cflags = append(cflags, "-DTW_OZIP_DECRYPT_KEY=\""+getMakeVars(ctx, "TW_OZIP_DECRYPT_KEY")+"\"")
+	} else {
+		cflags = append(cflags, "-DTW_OZIP_DECRYPT_KEY=0")
+	}
+
+	if getMakeVars(ctx, "TW_NO_SCREEN_BLANK") != "" {
+		cflags = append(cflags, "-DTW_NO_SCREEN_BLANK")
+	}
+
+	if getMakeVars(ctx, "TW_NO_SCREEN_TIMEOUT") != "" {
+		cflags = append(cflags, "-DTW_NO_SCREEN_TIMEOUT")
+	}
+
+	if getMakeVars(ctx, "TW_OEM_BUILD") != "" {
+		cflags = append(cflags, "-DTW_OEM_BUILD")
+	}
+
+	if getMakeVars(ctx, "TW_X_OFFSET") != "" {
+		cflags = append(cflags, "-DTW_X_OFFSET="+getMakeVars(ctx, "TW_X_OFFSET"))
+	}
+
+	if getMakeVars(ctx, "TW_Y_OFFSET") != "" {
+		cflags = append(cflags, "-DTW_Y_OFFSET="+getMakeVars(ctx, "TW_Y_OFFSET"))
+	}
+
+	if getMakeVars(ctx, "TW_W_OFFSET") != "" {
+		cflags = append(cflags, "-DTW_W_OFFSET="+getMakeVars(ctx, "TW_W_OFFSET"))
+	}
+
+	if getMakeVars(ctx, "TW_H_OFFSET") != "" {
+		cflags = append(cflags, "-DTW_H_OFFSET="+getMakeVars(ctx, "TW_H_OFFSET"))
+	}
+
+	if getMakeVars(ctx, "TW_ROUND_SCREEN") == "true" {
+		cflags = append(cflags, "-DTW_ROUND_SCREEN")
+	}
+
+	if getMakeVars(ctx, "TW_EXCLUDE_NANO") == "true" {
+		cflags = append(cflags, "-DTW_EXCLUDE_NANO")
+	}
+
+	if getMakeVars(ctx, "AB_OTA_UPDATER") == "true" {
+		cflags = append(cflags, "-DAB_OTA_UPDATER=1")
+	}
+
+	if getMakeVars(ctx, "TW_SCREEN_BLANK_ON_BOOT") == "true" {
+		cflags = append(cflags, "-DTW_NO_SCREEN_BLANK")
+	}
+
+	return cflags
+}
+
+func globalSrcs(ctx android.BaseContext) []string {
+	var srcs []string
+
+	if getMakeVars(ctx, "TWRP_CUSTOM_KEYBOARD") != "" {
+		srcs = append(srcs, getMakeVars(ctx, "TWRP_CUSTOM_KEYBOARD"))
+	} else {
+		srcs = append(srcs, "hardwarekeyboard.cpp")
+	}
+	return srcs
+}
+
+func globalIncludes(ctx android.BaseContext) []string {
+	var includes []string
+
+	if getMakeVars(ctx, "TW_INCLUDE_CRYPTO") != "" {
+		includes = append(includes, "bootable/recovery/crypto/fscrypt")
+	}
+	return includes
+}
+
+func libGuiDefaults(ctx android.LoadHookContext) {
+	type props struct {
+		Target struct {
+			Android struct {
+				Cflags  []string
+				Enabled *bool
+			}
+		}
+		Cflags       []string
+		Srcs         []string
+		Include_dirs []string
+	}
+
+	p := &props{}
+	p.Cflags = globalFlags(ctx)
+	s := globalSrcs(ctx)
+	p.Srcs = s
+	i := globalIncludes(ctx)
+	p.Include_dirs = i
+	ctx.AppendProperties(p)
+	if copyTheme(ctx) == false {
+		os.Exit(-1)
+	}
+}
+
+func init() {
+	android.RegisterModuleType("libguitwrp_defaults", libGuiDefaultsFactory)
+}
+
+func libGuiDefaultsFactory() android.Module {
+	module := cc.DefaultsFactory()
+	android.AddLoadHook(module, libGuiDefaults)
+
+	return module
+}
diff --git a/libaosprecovery_defaults.go b/libaosprecovery_defaults.go
index 608942b..765814e 100644
--- a/libaosprecovery_defaults.go
+++ b/libaosprecovery_defaults.go
@@ -1,4 +1,4 @@
-package liba_defaults

+package twrp

 

 import (

 	"android/soong/android"

@@ -8,7 +8,7 @@
 func globalFlags(ctx android.BaseContext) []string {

 	var cflags []string

 

-	if ctx.AConfig().Getenv("AB_OTA_UPDATER") == "true" {

+	if getMakeVars(ctx, "AB_OTA_UPDATER") == "true" {

 		cflags = append(cflags, "-DAB_OTA_UPDATER=1")

 	}

 	return cflags

@@ -17,8 +17,8 @@
 func globalSrcs(ctx android.BaseContext) []string {

 	var srcs []string

 

-	if ctx.AConfig().Getenv("TWRP_CUSTOM_KEYBOARD") != "" {

-		srcs = append(srcs, ctx.AConfig().Getenv("TWRP_CUSTOM_KEYBOARD"))

+	if getMakeVars(ctx, "TWRP_CUSTOM_KEYBOARD") != "" {

+		srcs = append(srcs, getMakeVars(ctx, "TWRP_CUSTOM_KEYBOARD"))

 	}

 

 	return srcs

@@ -27,7 +27,7 @@
 func globalIncludes(ctx android.BaseContext) []string {

 	var includes []string

 

-	if ctx.AConfig().Getenv("TW_INCLUDE_CRYPTO") != "" {

+	if getMakeVars(ctx, "TW_INCLUDE_CRYPTO") != "" {

 		includes = append(includes, "bootable/recovery/crypto/fscrypt")

 	}

 

diff --git a/libpixelflinger/libpixelflingertwrp_defaults.go.del b/libpixelflinger/libpixelflingertwrp_defaults.go.del
deleted file mode 100644
index e7c1410..0000000
--- a/libpixelflinger/libpixelflingertwrp_defaults.go.del
+++ /dev/null
@@ -1,117 +0,0 @@
-package libtwrp_defaults

-

-import (

-	"android/soong/android"

-	"android/soong/cc"

-	"fmt"

-	"path/filepath"

-)

-

-func globalFlags(ctx android.BaseContext) []string {

-	var cflags []string

-

-	if ctx.AConfig().Getenv("ARCH_ARM_HAVE_NEON") == "true" {

-		cflags = append(cflags, "-D__ARM_HAVE_NEON")

-	}

-	return cflags

-}

-

-func globalSrcs(ctx android.BaseContext) []string {

-	var srcs []string

-

-	matches, err := filepath.Glob("system/core/libpixelflinger/codeflinger/tinyutils/VectorImpl.cpp")

-	_ = matches

-	if err != nil {

-		srcs = append(srcs, "codeflinger/tinyutils/SharedBuffer.cpp")

-		srcs = append(srcs, "codeflinger/tinyutils/VectorImpl.cpp")

-	}

-

-	var arch = ctx.DeviceConfig().DeviceArch()

-	fmt.Println("arch: " + arch)

-

-	if arch != "x86" {

-		srcs = append(srcs, "codeflinger/ARMAssemblerInterface.cpp")

-		srcs = append(srcs, "codeflinger/ARMAssemblerProxy.cpp")

-		srcs = append(srcs, "codeflinger/GGLAssembler.cpp")

-		srcs = append(srcs, "codeflinger/load_store.cpp")

-		srcs = append(srcs, "codeflinger/blending.cpp")

-		srcs = append(srcs, "codeflinger/texturing.cpp")

-		srcs = append(srcs, "fixed.cpp")

-		srcs = append(srcs, "picker.cpp")

-		srcs = append(srcs, "pixelflinger.cpp")

-		srcs = append(srcs, "trap.cpp")

-		srcs = append(srcs, "scanline.cpp")

-	} else {

-		srcs = append(srcs, "codeflinger/x86/X86Assembler.cpp")

-		srcs = append(srcs, "codeflinger/x86/GGLX86Assembler.cpp")

-		srcs = append(srcs, "codeflinger/x86/load_store.cpp")

-		srcs = append(srcs, "codeflinger/x86/blending.cpp")

-		srcs = append(srcs, "codeflinger/x86/texturing.cpp")

-		srcs = append(srcs, "fixed.cpp")

-		srcs = append(srcs, "picker.cpp")

-		srcs = append(srcs, "pixelflinger.cpp")

-		srcs = append(srcs, "trap.cpp")

-		srcs = append(srcs, "scanline.cpp")

-	}

-

-	switch arch {

-	case "arm":

-		if ctx.AConfig().Getenv("ARCH_ARM_HAVE_NEON") == "true" {

-			srcs = append(srcs, "col32cb16blend_neon.S")

-		}

-		srcs = append(srcs, "codeflinger/ARMAssembler.cpp")

-		srcs = append(srcs, "codeflinger/disassem.c")

-		srcs = append(srcs, "col32cb16blend.S")

-		srcs = append(srcs, "t32cb16blend.S")

-		break

-	case "arm64":

-		srcs = append(srcs, "codeflinger/Arm64Assembler.cpp")

-		srcs = append(srcs, "codeflinger/Arm64Disassembler.cpp")

-		srcs = append(srcs, "arch-arm64/col32cb16blend.S")

-		srcs = append(srcs, "arch-arm64/t32cb16blend.S")

-	}

-	return srcs

-}

-

-func globalIncludes(ctx android.BaseContext) []string {

-	var includes []string

-

-	if ctx.AConfig().Getenv("TARGET_ARCH") == "arm" {

-		includes = append(includes, "external/libenc")

-	}

-

-	return includes

-}

-

-func libPixelflingerTwrpDefaults(ctx android.LoadHookContext) {

-	type props struct {

-		Target struct {

-			Android struct {

-				Cflags  []string

-				Enabled *bool

-			}

-		}

-		Cflags       []string

-		Srcs         []string

-		Include_dirs []string

-	}

-

-	p := &props{}

-	p.Cflags = globalFlags(ctx)

-	s := globalSrcs(ctx)

-	p.Srcs = s

-	i := globalIncludes(ctx)

-	p.Include_dirs = i

-	ctx.AppendProperties(p)

-}

-

-func init() {

-	android.RegisterModuleType("libpixelflingertwrp_defaults", libPixelflingerTwrpDefaultsFactory)

-}

-

-func libPixelflingerTwrpDefaultsFactory() android.Module {

-	module := cc.DefaultsFactory()

-	android.AddLoadHook(module, libPixelflingerTwrpDefaults)

-

-	return module

-}

diff --git a/minuitwrp/Android.bp b/minuitwrp/Android.bp
index ad66477..8005e02 100644
--- a/minuitwrp/Android.bp
+++ b/minuitwrp/Android.bp
@@ -7,7 +7,8 @@
         "soong-cc"
     ],
     srcs: [
-        "libminuitwrp_defaults.go"
+        "libminuitwrp_defaults.go",
+        "../soong/makevars.go"
     ],
     pluginFor: ["soong_build"]
 }
diff --git a/minuitwrp/libminuitwrp_defaults.go b/minuitwrp/libminuitwrp_defaults.go
index e56dbf3..bcb2e88 100644
--- a/minuitwrp/libminuitwrp_defaults.go
+++ b/minuitwrp/libminuitwrp_defaults.go
@@ -11,11 +11,11 @@
 func globalFlags(ctx android.BaseContext) []string {
 	var cflags []string
 
-	if ctx.AConfig().Getenv("TW_SUPPORT_INPUT_1_2_HAPTICS") == "true" {
+	if getMakeVars(ctx, "TW_SUPPORT_INPUT_1_2_HAPTICS") == "true" {
 		cflags = append(cflags, "-DUSE_QTI_HAPTICS")
 	}
 
-	if ctx.AConfig().Getenv("TW_TARGET_USES_QCOM_BSP") == "true" {
+	if getMakeVars(ctx, "TW_TARGET_USES_QCOM_BSP") == "true" {
 		cflags = append(cflags, "-DMSM_BSP")
 	}
 
@@ -25,7 +25,7 @@
 		cflags = append(cflags, "-DHAS_ADF")
 	}
 
-	if ctx.AConfig().Getenv("TW_NEW_ION_HEAP") == "true" {
+	if getMakeVars(ctx, "TW_NEW_ION_HEAP") == "true" {
 		cflags = append(cflags, "-DNEW_ION_HEAP")
 	}
 
@@ -35,35 +35,35 @@
 		cflags = append(cflags, "-DHAS_DRM")
 	}
 
-	if ctx.AConfig().Getenv("TW_INCLUDE_JPEG") != "" {
+	if getMakeVars(ctx, "TW_INCLUDE_JPEG") != "" {
 		cflags = append(cflags, "-DTW_INCLUDE_JPEG")
 	}
 
-	if ctx.AConfig().Getenv("RECOVERY_TOUCHSCREEN_SWAP_XY") == "true" {
+	if getMakeVars(ctx, "RECOVERY_TOUCHSCREEN_SWAP_XY") == "true" {
 		cflags = append(cflags, "-DRECOVERY_TOUCHSCREEN_SWAP_XY")
 	}
 
-	if ctx.AConfig().Getenv("RECOVERY_TOUCHSCREEN_FLIP_X") == "true" {
+	if getMakeVars(ctx, "RECOVERY_TOUCHSCREEN_FLIP_X") == "true" {
 		cflags = append(cflags, "-DRECOVERY_TOUCHSCREEN_FLIP_X")
 	}
 
-	if ctx.AConfig().Getenv("RECOVERY_TOUCHSCREEN_FLIP_Y") == "true" {
+	if getMakeVars(ctx, "RECOVERY_TOUCHSCREEN_FLIP_Y") == "true" {
 		cflags = append(cflags, "-DRECOVERY_TOUCHSCREEN_FLIP_Y")
 	}
 
-	if ctx.AConfig().Getenv("RECOVERY_GRAPHICS_FORCE_USE_LINELENGTH") == "true" {
+	if getMakeVars(ctx, "RECOVERY_GRAPHICS_FORCE_USE_LINELENGTH") == "true" {
 		cflags = append(cflags, "-DRECOVERY_GRAPHICS_FORCE_USE_LINELENGTH")
 	}
 
-	if ctx.AConfig().Getenv("RECOVERY_GRAPHICS_FORCE_SINGLE_BUFFER") == "true" {
+	if getMakeVars(ctx, "RECOVERY_GRAPHICS_FORCE_SINGLE_BUFFER") == "true" {
 		cflags = append(cflags, "-DRECOVERY_GRAPHICS_FORCE_SINGLE_BUFFER")
 	}
 
-	if ctx.AConfig().Getenv("TWRP_EVENT_LOGGING") == "true" {
+	if getMakeVars(ctx, "TWRP_EVENT_LOGGING") == "true" {
 		cflags = append(cflags, "-D_EVENT_LOGGING")
 	}
 
-	var pixelFormat = strings.Replace(ctx.AConfig().Getenv("TARGET_RECOVERY_FORCE_PIXEL_FORMAT"), "\"", "", -1)
+	var pixelFormat = strings.Replace(getMakeVars(ctx, "TARGET_RECOVERY_FORCE_PIXEL_FORMAT"), "\"", "", -1)
 
 	switch pixelFormat {
 	case "RGBA_8888":
@@ -92,7 +92,7 @@
 		break
 	}
 
-	pixelFormat = strings.Replace(ctx.AConfig().Getenv("TWRP_EVENT_LOGGING"), "\"", "", -1)
+	pixelFormat = strings.Replace(getMakeVars(ctx, "TARGET_RECOVERY_PIXEL_FORMAT"), "\"", "", -1)
 	switch pixelFormat {
 	case "ABGR_8888":
 		cflags = append(cflags, "-DRECOVERY_ABGR")
@@ -107,21 +107,21 @@
 		break
 	}
 
-	if ctx.AConfig().Getenv("TARGET_RECOVERY_OVERSCAN_PERCENT") != "" {
-		cflags = append(cflags, "-DDOVERSCAN_PERCENT="+ctx.AConfig().Getenv("TARGET_RECOVERY_OVERSCAN_PERCENT"))
+	if getMakeVars(ctx, "TARGET_RECOVERY_OVERSCAN_PERCENT") != "" {
+		cflags = append(cflags, "-DDOVERSCAN_PERCENT="+getMakeVars(ctx, "TARGET_RECOVERY_OVERSCAN_PERCENT"))
 	} else {
 		cflags = append(cflags, "-DOVERSCAN_PERCENT=0")
 	}
 
-	if ctx.AConfig().Getenv("TW_SCREEN_BLANK_ON_BOOT") == "true" {
+	if getMakeVars(ctx, "TW_SCREEN_BLANK_ON_BOOT") == "true" {
 		cflags = append(cflags, "-DTW_SCREEN_BLANK_ON_BOOT")
 	}
 
-	if ctx.AConfig().Getenv("TW_FBIOPAN") == "true" {
+	if getMakeVars(ctx, "TW_FBIOPAN") == "true" {
 		cflags = append(cflags, "-DTW_FBIOPAN")
 	}
 
-	var tw_rotation = ctx.AConfig().Getenv("TW_ROTATION")
+	var tw_rotation = getMakeVars(ctx, "TW_ROTATION")
 	switch tw_rotation {
 	case "0":
 	case "90":
@@ -129,34 +129,34 @@
 	case "270":
 		cflags = append(cflags, "-DTW_ROTATION="+tw_rotation)
 	default:
-		if ctx.AConfig().Getenv("BOARD_HAS_FLIPPED_SCREEN") == "true" {
+		if getMakeVars(ctx, "BOARD_HAS_FLIPPED_SCREEN") == "true" {
 			cflags = append(cflags, "-DTW_ROTATION=180")
 		} else {
 			cflags = append(cflags, "-DTW_ROTATION=0")
 		}
 	}
 
-	if ctx.AConfig().Getenv("TW_IGNORE_MAJOR_AXIS_0") == "true" {
+	if getMakeVars(ctx, "TW_IGNORE_MAJOR_AXIS_0") == "true" {
 		cflags = append(cflags, "-DTW_IGNORE_MAJOR_AXIS_0")
 	}
 
-	if ctx.AConfig().Getenv("TW_IGNORE_MT_POSITION_0") == "true" {
+	if getMakeVars(ctx, "TW_IGNORE_MT_POSITION_0") == "true" {
 		cflags = append(cflags, "-DTW_IGNORE_MT_POSITION_0")
 	}
 
-	if ctx.AConfig().Getenv("TW_IGNORE_ABS_MT_TRACKING_ID") == "true" {
+	if getMakeVars(ctx, "TW_IGNORE_ABS_MT_TRACKING_ID") == "true" {
 		cflags = append(cflags, "-DTW_IGNORE_ABS_MT_TRACKING_ID")
 	}
 
-	if ctx.AConfig().Getenv("TW_INPUT_BLACKLIST") != "" {
-		cflags = append(cflags, "-DTW_INPUT_BLACKLIST="+ctx.AConfig().Getenv("TW_INPUT_BLACKLIST"))
+	if getMakeVars(ctx, "TW_INPUT_BLACKLIST") != "" {
+		cflags = append(cflags, "-DTW_INPUT_BLACKLIST="+getMakeVars(ctx, "TW_INPUT_BLACKLIST"))
 	}
 
-	if ctx.AConfig().Getenv("TW_WHITELIST_INPUT") != "" {
-		cflags = append(cflags, "-DWHITELIST_INPUT="+ctx.AConfig().Getenv("TW_WHITELIST_INPUT"))
+	if getMakeVars(ctx, "TW_WHITELIST_INPUT") != "" {
+		cflags = append(cflags, "-DWHITELIST_INPUT="+getMakeVars(ctx, "TW_WHITELIST_INPUT"))
 	}
 
-	if ctx.AConfig().Getenv("TW_HAPTICS_TSPDRV") == "true" {
+	if getMakeVars(ctx, "TW_HAPTICS_TSPDRV") == "true" {
 		cflags = append(cflags, "-DTW_HAPTICS_TSPDRV")
 	}
 
@@ -166,7 +166,7 @@
 func globalSrcs(ctx android.BaseContext) []string {
 	var srcs []string
 
-	if ctx.AConfig().Getenv("TW_TARGET_USES_QCOM_BSP") == "true" {
+	if getMakeVars(ctx, "TW_TARGET_USES_QCOM_BSP") == "true" {
 		srcs = append(srcs, "graphics_overlay.cpp")
 	}
 
@@ -181,7 +181,7 @@
 		srcs = append(srcs, "graphics_drm.cpp")
 	}
 
-	if ctx.AConfig().Getenv("TW_HAPTICS_TSPDRV") == "true" {
+	if getMakeVars(ctx, "TW_HAPTICS_TSPDRV") == "true" {
 		srcs = append(srcs, "tspdrv.cpp")
 	}
 	return srcs
@@ -190,25 +190,25 @@
 func globalIncludes(ctx android.BaseContext) []string {
 	var includes []string
 
-	if ctx.AConfig().Getenv("TW_INCLUDE_CRYPTO") != "" {
+	if getMakeVars(ctx, "TW_INCLUDE_CRYPTO") != "" {
 		includes = append(includes, "bootable/recovery/crypto/fscrypt")
 	}
 
-	if ctx.AConfig().Getenv("TW_TARGET_USES_QCOM_BSP") == "true" {
-		if ctx.AConfig().Getenv("TARGET_PREBUILT_KERNEL") != "" {
-			includes = append(includes, ctx.AConfig().Getenv("TARGET_OUT_INTERMEDIATES")+"/KERNEL_OBJ/usr/include")
+	if getMakeVars(ctx, "TW_TARGET_USES_QCOM_BSP") == "true" {
+		if getMakeVars(ctx, "TARGET_PREBUILT_KERNEL") != "" {
+			includes = append(includes, getMakeVars(ctx, "TARGET_OUT_INTERMEDIATES")+"/KERNEL_OBJ/usr/include")
 		} else {
-			if ctx.AConfig().Getenv("TARGET_CUSTOM_KERNEL_HEADERS") != "" {
+			if getMakeVars(ctx, "TARGET_CUSTOM_KERNEL_HEADERS") != "" {
 				includes = append(includes, "bootable/recovery/minuitwrp")
 			} else {
-				includes = append(includes, ctx.AConfig().Getenv("TARGET_CUSTOM_KERNEL_HEADERS"))
+				includes = append(includes, getMakeVars(ctx, "TARGET_CUSTOM_KERNEL_HEADERS"))
 			}
 		}
 	} else {
 		includes = append(includes, "bootable/recovery/minuitwrp")
 	}
 
-	if ctx.AConfig().Getenv("TW_INCLUDE_JPEG") != "" {
+	if getMakeVars(ctx, "TW_INCLUDE_JPEG") != "" {
 		includes = append(includes, "external/jpeg")
 	}
 
@@ -240,12 +240,12 @@
 func globalSharedLibs(ctx android.BaseContext) []string {
 	var sharedLibs []string
 
-	if ctx.AConfig().Getenv("TW_SUPPORT_INPUT_1_2_HAPTICS") == "true" {
+	if getMakeVars(ctx, "TW_SUPPORT_INPUT_1_2_HAPTICS") == "true" {
 		sharedLibs = append(sharedLibs, "android.hardware.vibrator@1.2")
 		sharedLibs = append(sharedLibs, "libhidlbase")
 	}
 
-	if ctx.AConfig().Getenv("TW_INCLUDE_JPEG") != "" {
+	if getMakeVars(ctx, "TW_INCLUDE_JPEG") != "" {
 		sharedLibs = append(sharedLibs, "libjpeg")
 	}
 	return sharedLibs
@@ -254,8 +254,8 @@
 func globalRequiredModules(ctx android.BaseContext) []string {
 	var requiredModules []string
 
-	if ctx.AConfig().Getenv("TARGET_PREBUILT_KERNEL") != "" {
-		var kernelDir = ctx.AConfig().Getenv("TARGET_OUT_INTERMEDIATES") + ")/KERNEL_OBJ/usr"
+	if getMakeVars(ctx, "TARGET_PREBUILT_KERNEL") != "" {
+		var kernelDir = getMakeVars(ctx, "TARGET_OUT_INTERMEDIATES") + ")/KERNEL_OBJ/usr"
 		requiredModules = append(requiredModules, kernelDir)
 	}
 	return requiredModules
diff --git a/soong/copy.go b/soong/copy.go
new file mode 100755
index 0000000..c6b07b4
--- /dev/null
+++ b/soong/copy.go
@@ -0,0 +1,79 @@
+package twrp
+
+import (
+	"android/soong/android"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"os"
+	"path"
+	"strings"
+)
+
+func getRecoveryAbsDir(ctx android.BaseContext) string {
+	return getBuildAbsDir(ctx) + "bootable/recovery/"
+}
+
+func getBuildAbsDir(ctx android.BaseContext) string {
+	outDir := ctx.Config().Getenv("OUT")
+	absIndex := strings.Index(outDir, "out")
+	return string(outDir[0:absIndex])
+}
+
+func copyDir(src string, dest string) error {
+	var err error
+	var fds []os.FileInfo
+	var srcinfo os.FileInfo
+
+	if srcinfo, err = os.Stat(src); err != nil {
+		return err
+	}
+
+	if err = os.MkdirAll(dest, srcinfo.Mode()); err != nil {
+		return err
+	}
+
+	if fds, err = ioutil.ReadDir(src); err != nil {
+		return err
+	}
+	for _, fd := range fds {
+		srcfp := path.Join(src, fd.Name())
+		dstfp := path.Join(dest, fd.Name())
+
+		if fd.IsDir() {
+			if err = copyDir(srcfp, dstfp); err != nil {
+				fmt.Println(err)
+			}
+		} else {
+			if err = copyFile(srcfp, dstfp); err != nil {
+				fmt.Println(err)
+			}
+		}
+	}
+	return nil
+}
+
+func copyFile(src string, dest string) error {
+	var err error
+	var srcfd *os.File
+	var dstfd *os.File
+	var srcinfo os.FileInfo
+
+	if srcfd, err = os.Open(src); err != nil {
+		return err
+	}
+	defer srcfd.Close()
+
+	if dstfd, err = os.Create(dest); err != nil {
+		return err
+	}
+	defer dstfd.Close()
+
+	if _, err = io.Copy(dstfd, srcfd); err != nil {
+		return err
+	}
+	if srcinfo, err = os.Stat(src); err != nil {
+		return err
+	}
+	return os.Chmod(dest, srcinfo.Mode())
+}
diff --git a/soong/makevars.go b/soong/makevars.go
new file mode 100644
index 0000000..f453ed0
--- /dev/null
+++ b/soong/makevars.go
@@ -0,0 +1,14 @@
+package twrp
+
+import (
+	"android/soong/android"
+)
+
+func getMakeVars(ctx android.BaseContext, mVar string) string {
+	makeVars := ctx.Config().VendorConfig("makeVarsPlugin")
+	var makeVar = ""
+	if makeVars.IsSet(mVar) {
+		makeVar = makeVars.String(mVar)
+	}
+	return makeVar
+}