diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..9f95d99 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +* text=auto eol=lf +*.bat text eol=crlf +*.jar binary diff --git a/README.md b/README.md index 2f6c5ad..c5b0f4c 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ class Entrypoint { ```kotlin plugins { id("com.android.application") // required - id("com.github.kr328.gradle.zygote") version "2.5" // apply plugin + id("com.github.kr328.gradle.zygote") version "2.7" // apply plugin // ... other plugins } ``` diff --git a/build.gradle.kts b/build.gradle.kts index ff52b38..e654fcd 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,21 +1,10 @@ -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile - plugins { - kotlin("jvm") version "1.7.20" apply false id("com.android.library") version "7.3.1" apply false } subprojects { group = "com.github.kr328.gradle.zygote" - version = "2.6" - - plugins.withId("org.jetbrains.kotlin.jvm") { - tasks.withType(KotlinCompile::class) { - kotlinOptions { - jvmTarget = "11" - } - } - } + version = "2.7" plugins.withId("java") { extensions.configure { diff --git a/gradle-plugin/build.gradle.kts b/gradle-plugin/build.gradle.kts index 61387a6..85581ad 100644 --- a/gradle-plugin/build.gradle.kts +++ b/gradle-plugin/build.gradle.kts @@ -1,7 +1,5 @@ -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile - plugins { - kotlin("jvm") + java `java-gradle-plugin` `maven-publish` } @@ -38,7 +36,6 @@ task("generateDynamicSources") { inputs.property("moduleVersion", project.version) outputs.dir(dynamicSources) tasks.withType(JavaCompile::class.java).forEach { it.dependsOn(this) } - tasks.withType(KotlinCompile::class.java).forEach { it.dependsOn(this) } tasks["sourcesJar"].dependsOn(this) doFirst { diff --git a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/ZygoteLoaderDecorator.java b/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/ZygoteLoaderDecorator.java new file mode 100644 index 0000000..4dbf663 --- /dev/null +++ b/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/ZygoteLoaderDecorator.java @@ -0,0 +1,219 @@ +package com.github.kr328.gradle.zygote; + +import com.android.build.api.variant.ApplicationVariant; +import com.android.build.api.variant.VariantOutput; +import com.github.kr328.gradle.zygote.tasks.ChecksumTask; +import com.github.kr328.gradle.zygote.tasks.CustomizeTask; +import com.github.kr328.gradle.zygote.tasks.PackagesTask; +import com.github.kr328.gradle.zygote.tasks.PropertiesTask; +import com.github.kr328.gradle.zygote.util.StringUtils; + +import org.apache.tools.ant.filters.FixCrLfFilter; +import org.gradle.api.Project; +import org.gradle.api.Task; +import org.gradle.api.file.FileCollection; +import org.gradle.api.provider.Provider; +import org.gradle.api.tasks.Sync; +import org.gradle.api.tasks.TaskProvider; +import org.gradle.api.tasks.bundling.Zip; +import org.gradle.api.tasks.bundling.ZipEntryCompression; + +import java.io.File; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Stream; + +import javax.annotation.Nullable; + +public final class ZygoteLoaderDecorator { + private final Project project; + private final ZygoteLoaderExtension extension; + + public ZygoteLoaderDecorator(Project project, ZygoteLoaderExtension extension) { + this.project = project; + this.extension = extension; + } + + public void decorateVariant(final Loader loader, final ApplicationVariant variant) { + final TaskProvider pack = project.getTasks().named("package" + StringUtils.capitalize(variant.getName())); + final VariantOutput variantOutput = variant.getOutputs().stream().findAny().orElseThrow(); + + final Map moduleProp = new LinkedHashMap<>(); + + moduleProp.put("version", variantOutput.getVersionName().getOrElse("")); + moduleProp.put("versionCode", variantOutput.getVersionCode().getOrElse(0).toString()); + moduleProp.put("minSdkVersion", String.valueOf(variant.getMinSdkVersion().getApiLevel())); + if (variant.getMaxSdkVersion() != null) { + moduleProp.put("maxSdkVersion", String.valueOf(variant.getMaxSdkVersion())); + } + + if (loader == Loader.Riru) { + moduleProp.putAll(extension.getRiru()); + } else if (loader == Loader.Zygisk) { + moduleProp.putAll(extension.getZygisk()); + } + + final TaskProvider generateModuleProp = project.getTasks().register( + "generateModuleProp" + StringUtils.capitalize(variant.getName()), + PropertiesTask.class, + task -> { + task.getDestinationFile().set( + project.getLayout().getBuildDirectory() + .dir("generated/properties/" + variant.getName()) + .map(p -> p.file("module.prop")) + ); + task.getProperties().set(moduleProp); + } + ); + + final TaskProvider generateInitialPackages = project.getTasks().register( + "generateInitialPackages" + StringUtils.capitalize(variant.getName()), + PackagesTask.class, + task -> { + task.getDestinationDirectory().set( + project.getLayout().getBuildDirectory() + .dir("generated/packages/" + variant.getName()) + ); + task.getPackages().set(extension.getPackages()); + } + ); + + final TaskProvider mergeMagisk = project.getTasks().register( + "mergeMagisk" + StringUtils.capitalize(variant.getName()), + Sync.class, + task -> { + task.setDestinationDir(new File(project.getBuildDir(), "intermediates/merged_magisk/" + variant.getName())); + + final Provider apkFile = pack.map(p -> + p.getOutputs().getFiles().getFiles().stream() + .flatMap(f -> { + if (f.isDirectory()) { + return Stream.of(Objects.requireNonNull(f.listFiles())); + } else { + return Stream.of(f); + } + }) + .filter(f -> f.getName().endsWith(".apk")) + .findAny() + .orElseThrow() + ); + + final Provider apk = apkFile.map(project::zipTree); + + task.getInputs().file(apkFile); + + // module prop + task.from(generateModuleProp); + + // initial packages + task.from(generateInitialPackages, sp -> sp.into("packages")); + + // classes.dex + task.from(apk, sp -> sp.include("classes.dex")); + + // native libraries + task.from(apk, sp -> { + sp.include("lib/*/*.so"); + sp.eachFile(file -> { + final String abi = file.getPath().split("/")[1]; + + if (loader == Loader.Riru) { + file.setPath("riru/" + abi + "/lib" + moduleProp.get("id") + ".so"); + } else if (loader == Loader.Zygisk) { + file.setPath("zygisk/" + abi + ".so"); + } + }); + }); + + // assets + task.from(apk, sp -> { + sp.include("assets/**"); + sp.eachFile(file -> file.setPath(file.getPath().substring("assets/".length()))); + }); + } + ); + + final TaskProvider generateChecksum = project.getTasks().register( + "generateChecksum" + StringUtils.capitalize(variant.getName()), + ChecksumTask.class, + task -> { + task.getDestinationFile().set( + project.getLayout().getBuildDirectory() + .dir("generated/checksum/" + variant.getName()) + .map(p -> p.file("00-verify-resources.sh")) + ); + task.getRootDirectory().set(mergeMagisk.map(m -> + project.getLayout().getProjectDirectory() + .dir(m.getDestinationDir().getAbsolutePath())) + ); + } + ); + + final TaskProvider generateCustomize = project.getTasks().register( + "generateCustomize" + StringUtils.capitalize(variant.getName()), + CustomizeTask.class, + task -> { + task.getDestinationFile().set( + project.getLayout().getBuildDirectory() + .dir("generated/customize/" + variant.getName()) + .map(p -> p.file("customize.sh")) + ); + task.getMergedDirectory().set(mergeMagisk.map(m -> + project.getLayout().getProjectDirectory() + .dir(m.getDestinationDir().getAbsolutePath())) + ); + task.getChecksumFileName().set(generateChecksum.map(c -> c.getDestinationFile().get().getAsFile().getName())); + } + ); + + final TaskProvider zipMagisk = project.getTasks().register( + "zipMagisk" + StringUtils.capitalize(variant.getName()), + Zip.class, + zip -> { + zip.getDestinationDirectory().set( + project.getLayout().getBuildDirectory() + .dir("outputs/magisk/" + variant.getFlavorName() + "/" + variant.getBuildType()) + ); + + zip.getArchiveBaseName().set(project.getName()); + if (loader == Loader.Riru && extension.getRiru().containsKey("archiveName")) { + zip.getArchiveBaseName().set(extension.getRiru().get("archiveName")); + } else if (loader == Loader.Zygisk && extension.getZygisk().containsKey("archiveName")) { + zip.getArchiveBaseName().set(extension.getZygisk().get("archiveName")); + } + + zip.setIncludeEmptyDirs(false); + zip.setEntryCompression(ZipEntryCompression.DEFLATED); + zip.setPreserveFileTimestamps(false); + + zip.from(mergeMagisk); + zip.from(generateChecksum, sp -> sp.into("customize.d")); + zip.from(generateCustomize); + } + ); + + project.getTasks().named( + "assemble" + StringUtils.capitalize(variant.getName()), + t -> t.dependsOn(zipMagisk) + ); + } + + enum Loader { + Riru("riru"), Zygisk("zygisk"); + + final String flavorName; + + Loader(String flavorName) { + this.flavorName = flavorName; + } + + @Nullable + public static Loader fromFlavorName(final String flavorName) { + return Arrays.stream(Loader.values()) + .filter(l -> l.flavorName.equals(flavorName)) + .findFirst().orElse(null); + } + } +} diff --git a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/ZygoteLoaderDecorator.kt b/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/ZygoteLoaderDecorator.kt deleted file mode 100644 index bcfa26a..0000000 --- a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/ZygoteLoaderDecorator.kt +++ /dev/null @@ -1,160 +0,0 @@ -package com.github.kr328.gradle.zygote - -import com.android.build.api.variant.ApplicationVariant -import com.android.build.gradle.internal.scope.InternalArtifactType -import com.android.build.gradle.internal.scope.InternalMultipleArtifactType -import com.github.kr328.gradle.zygote.compat.resolveImpl -import com.github.kr328.gradle.zygote.tasks.* -import com.github.kr328.gradle.zygote.util.* -import org.gradle.api.Project -import org.gradle.api.tasks.Sync -import org.gradle.api.tasks.bundling.Zip -import org.gradle.api.tasks.bundling.ZipEntryCompression - -object ZygoteLoaderDecorator { - enum class Loader(val flavorName: String) { - Riru("riru"), Zygisk("zygisk") - } - - fun decorateVariant( - loader: Loader, - project: Project, - variant: ApplicationVariant, - extension: ZygoteLoaderExtension, - ): Unit = with(project) { - val artifacts = variant.artifacts.resolveImpl() - val capitalized = variant.name.toCapitalized() - val packing = tasks.named("package$capitalized") - - val moduleProp = sequence { - val output = variant.outputs.single() - - yield("version" to (output.versionName.orNull ?: "")) - yield("versionCode" to (output.versionCode.orNull ?: 0).toString()) - yield("minSdkVersion" to (variant.minSdkVersion.apiLevel.toString())) - if (variant.maxSdkVersion != null) { - yield("maxSdkVersion" to variant.maxSdkVersion!!.toString()) - } - }.toMap() + when (loader) { - Loader.Riru -> extension.riru - Loader.Zygisk -> extension.zygisk - } - - val generateModuleProp = tasks.registerKtx( - "generateModuleProp$capitalized", - PropertiesTask::class, - ) { - properties.putAll(moduleProp) - - fileName.set("module.prop") - - destinationDir.set(buildDir.resolve("generated/properties/${variant.name}")) - } - - val generateInitialPackages = tasks.registerKtx( - "generateInitialPackages$capitalized", - PackagesTask::class, - ) { - packages.addAll(extension.packages) - - destinationDir.set(buildDir.resolve("generated/packages/${variant.name}")) - } - - val flattenAssets = tasks.registerKtx( - "flattenAssets$capitalized", - FlattenTask::class - ) { - dependsOn(packing) - - composedDir.set(artifacts.get(InternalArtifactType.COMPRESSED_ASSETS)) - - destinationDir.set(buildDir.resolve("intermediates/flatten_assets/${variant.name}")) - } - - val mergeMagisk = tasks.registerKtx( - "mergeMagisk$capitalized", - Sync::class - ) { - val nativeLibs = artifacts.get(InternalArtifactType.MERGED_NATIVE_LIBS) - val dex = artifacts.getAll(InternalMultipleArtifactType.DEX).map { it.single() } - - dependsOn(packing) - - destinationDir = buildDir.resolve("intermediates/merged_magisk/${variant.name}") - - fromKtx(nativeLibs.asFile().resolve("lib")) { - when (loader) { - Loader.Riru -> { - include("**/libriru_loader.so") - into("riru") - rename { - if (it == "libriru_loader.so") "lib${moduleProp["id"]}.so" else it - } - } - Loader.Zygisk -> { - include("**/libzygisk_loader.so") - into("zygisk") - eachFile { - it.path = it.path.replace("/libzygisk_loader", "") - } - } - } - } - fromKtx(dex) { - include("classes.dex") - } - fromKtx(flattenAssets.flatMap { it.destinationDir.dir("assets") }) - fromKtx(generateInitialPackages.flatMap { it.destinationDir }) - fromKtx(generateModuleProp.flatMap { it.destinationDir }) - } - - val generateChecksum = tasks.registerKtx( - "generateChecksum$capitalized", - ChecksumTask::class - ) { - dependsOn(mergeMagisk) - - inputDir.set(mergeMagisk.get().destinationDir) - destinationDir.set(buildDir.resolve("generated/checksum/${variant.name}")) - } - - val generateCustomize = tasks.registerKtx( - "generateCustomize$capitalized", - CustomizeTask::class, - ) { - dependsOn(mergeMagisk) - - destinationDir.set(buildDir.resolve("generated/customize_sh/${variant.name}")) - - customizeFiles.set(mergeMagisk.get().destinationDir.resolve("customize.d")) - checksumFiles.set(generateChecksum.flatMap { it.destinationDir.dir("customize.d") }) - } - - val packagingMagisk = tasks.registerKtx( - "packageMagisk$capitalized", - Zip::class - ) { - dependsOn(mergeMagisk) - - val destinationDir = buildDir.resolve("outputs/magisk") - .resolve("${variant.flavorName}") - .resolve("${variant.buildType}") - val archiveName = when (loader) { - Loader.Riru -> extension.riru["archiveName"] - Loader.Zygisk -> extension.zygisk["archiveName"] - } ?: project.name - - destinationDirectory.set(destinationDir) - archiveBaseName.set(archiveName) - includeEmptyDirs = false - entryCompression = ZipEntryCompression.DEFLATED - isPreserveFileTimestamps = false - - fromKtx(mergeMagisk.get().destinationDir) - fromKtx(generateCustomize.flatMap { it.destinationDir }) - fromKtx(generateChecksum.flatMap { it.destinationDir }) - } - - tasks.getByName("assemble$capitalized").dependsOn(packagingMagisk) - } -} \ No newline at end of file diff --git a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/ZygoteLoaderExtension.java b/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/ZygoteLoaderExtension.java new file mode 100644 index 0000000..bdb9922 --- /dev/null +++ b/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/ZygoteLoaderExtension.java @@ -0,0 +1,123 @@ +package com.github.kr328.gradle.zygote; + +import org.gradle.api.Action; + +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Set; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public class ZygoteLoaderExtension { + private final Properties zygisk = new Properties(); + private final Properties riru = new Properties(); + private final Set packages = new HashSet<>(); + + @Nonnull + public Properties getZygisk() { + return zygisk; + } + + @Nonnull + public Properties getRiru() { + return riru; + } + + @Nonnull + public Set getPackages() { + return packages; + } + + public void zygisk(@Nonnull final Action action) { + action.execute(zygisk); + } + + public void riru(@Nonnull final Action action) { + action.execute(riru); + } + + public void all(@Nonnull final Action action) { + action.execute(zygisk); + action.execute(riru); + } + + public void packages(@Nonnull final String... pkgs) { + packages.addAll(List.of(pkgs)); + } + + public static class Properties extends LinkedHashMap { + @Override + public String put(String key, String value) { + if (value == null) { + remove(key); + } + + return super.put(key, value); + } + + @Nullable + public String getId() { + return get("id"); + } + + public void setId(@Nullable final String id) { + put("id", id); + } + + @Nullable + public String getName() { + return get("name"); + } + + public void setName(@Nullable final String name) { + put("name", name); + } + + @Nullable + public String getAuthor() { + return get("author"); + } + + public void setAuthor(@Nullable final String author) { + put("author", author); + } + + @Nullable + public String getDescription() { + return get("description"); + } + + public void setDescription(@Nullable final String description) { + put("description", description); + } + + @Nullable + public String getEntrypoint() { + return get("entrypoint"); + } + + public void setEntrypoint(@Nullable final String entrypoint) { + put("entrypoint", entrypoint); + } + + @Nullable + public String getArchiveName() { + return get("archiveName"); + } + + public void setArchiveName(@Nullable final String archiveName) { + put("archiveName", archiveName); + } + + @Nullable + public String getUpdateJson() { + return get("updateJson"); + } + + public void setUpdateJson(@Nullable final String updateJson) { + put("updateJson", updateJson); + } + } +} diff --git a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/ZygoteLoaderExtension.kt b/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/ZygoteLoaderExtension.kt deleted file mode 100644 index 41a86d5..0000000 --- a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/ZygoteLoaderExtension.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.github.kr328.gradle.zygote - -import org.gradle.api.Action - -abstract class ZygoteLoaderExtension { - class Properties : HashMap() { - var id: String by this - var name: String by this - var author: String by this - var description: String by this - var entrypoint: String by this - var archiveName: String by this - var updateJson: String by this - } - - val zygisk: Properties = Properties() - val riru: Properties = Properties() - val packages: MutableSet = mutableSetOf() - - fun zygisk(block: Properties.() -> Unit) { - zygisk.block() - } - - fun zygisk(block: Action) { - block.execute(zygisk) - } - - fun riru(block: Properties.() -> Unit) { - riru.block() - } - - fun riru(block: Action) { - block.execute(riru) - } - - fun all(block: Properties.() -> Unit) { - zygisk(block) - riru(block) - } - - fun all(block: Action) { - zygisk(block) - riru(block) - } - - fun packages(vararg pkgs: String) { - packages.addAll(pkgs) - } -} \ No newline at end of file diff --git a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/ZygoteLoaderPlugin.java b/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/ZygoteLoaderPlugin.java new file mode 100644 index 0000000..19a04cf --- /dev/null +++ b/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/ZygoteLoaderPlugin.java @@ -0,0 +1,82 @@ +package com.github.kr328.gradle.zygote; + +import com.android.build.api.dsl.ProductFlavor; +import com.android.build.api.variant.ApplicationAndroidComponentsExtension; + +import org.gradle.api.GradleException; +import org.gradle.api.Plugin; +import org.gradle.api.Project; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; + +import javax.annotation.Nonnull; + +import kotlin.Unit; + +@SuppressWarnings("UnstableApiUsage") +public class ZygoteLoaderPlugin implements Plugin { + public static final String LOADER_FLAVOR_DIMENSION = "loader"; + + @Override + public void apply(@Nonnull Project target) { + if (!target.getPlugins().hasPlugin("com.android.application")) { + throw new GradleException("com.android.application not applied"); + } + + final ZygoteLoaderExtension extension = target.getExtensions() + .create("zygote", ZygoteLoaderExtension.class); + + target.getDependencies().add("implementation", BuildConfig.RUNTIME_DEPENDENCY); + + target.getExtensions().configure(ApplicationAndroidComponentsExtension.class, components -> { + components.finalizeDsl(dsl -> { + dsl.getFlavorDimensions().add(LOADER_FLAVOR_DIMENSION); + + final MethodHandle flavorSetDimension; + try { + flavorSetDimension = MethodHandles.lookup().findVirtual( + ProductFlavor.class, + "setDimension", + MethodType.methodType(void.class, String.class) + ); + } catch (final Exception e) { + throw new RuntimeException(e); + } + + dsl.productFlavors(flavors -> { + flavors.create(ZygoteLoaderDecorator.Loader.Zygisk.flavorName, flavor -> { + try { + flavorSetDimension.invoke(flavor, LOADER_FLAVOR_DIMENSION); + } catch (final Throwable e) { + throw new RuntimeException(e); + } + + flavor.setMultiDexEnabled(false); + }); + + flavors.create(ZygoteLoaderDecorator.Loader.Riru.flavorName, flavor -> { + try { + flavorSetDimension.invoke(flavor, LOADER_FLAVOR_DIMENSION); + } catch (final Throwable e) { + throw new RuntimeException(e); + } + + flavor.setMultiDexEnabled(false); + }); + + return Unit.INSTANCE; + }); + }); + + final ZygoteLoaderDecorator decorator = new ZygoteLoaderDecorator(target, extension); + components.onVariants(components.selector().all(), variant -> { + target.afterEvaluate(prj -> decorator.decorateVariant( + ZygoteLoaderDecorator.Loader.fromFlavorName(variant.getFlavorName()), + variant + )); + }); + }); + } +} diff --git a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/ZygoteLoaderPlugin.kt b/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/ZygoteLoaderPlugin.kt deleted file mode 100644 index fefa987..0000000 --- a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/ZygoteLoaderPlugin.kt +++ /dev/null @@ -1,63 +0,0 @@ -package com.github.kr328.gradle.zygote - -import com.android.build.api.variant.ApplicationAndroidComponentsExtension -import com.github.kr328.gradle.zygote.util.configureKtx -import com.github.kr328.gradle.zygote.util.createKtx -import com.github.kr328.gradle.zygote.util.finalizeDslKtx -import com.github.kr328.gradle.zygote.util.onVariantsKtx -import org.gradle.api.GradleException -import org.gradle.api.Plugin -import org.gradle.api.Project - -@Suppress("UnstableApiUsage") -class ZygoteLoaderPlugin : Plugin { - override fun apply(target: Project) = with(target) { - if (!target.plugins.hasPlugin("com.android.application")) { - throw GradleException("Android application plugin not applied") - } - - val zygote = extensions.create("zygote", ZygoteLoaderExtension::class.java) - - dependencies.add("implementation", BuildConfig.RUNTIME_DEPENDENCY) - - extensions.configureKtx(ApplicationAndroidComponentsExtension::class) { - finalizeDslKtx { - flavorDimensions += LOADER_FLAVOR_DIMENSION - productFlavors { - createKtx(ZygoteLoaderDecorator.Loader.Riru.flavorName) { - dimension = LOADER_FLAVOR_DIMENSION - multiDexEnabled = false - } - createKtx(ZygoteLoaderDecorator.Loader.Zygisk.flavorName) { - dimension = LOADER_FLAVOR_DIMENSION - multiDexEnabled = false - } - } - } - onVariantsKtx { - val loader = when (flavorName) { - ZygoteLoaderDecorator.Loader.Riru.flavorName -> - ZygoteLoaderDecorator.Loader.Riru - ZygoteLoaderDecorator.Loader.Zygisk.flavorName -> - ZygoteLoaderDecorator.Loader.Zygisk - else -> null - } - - afterEvaluate { - if (loader != null) { - ZygoteLoaderDecorator.decorateVariant( - loader, - target, - this, - zygote - ) - } - } - } - } - } - - companion object { - private const val LOADER_FLAVOR_DIMENSION = "loader" - } -} \ No newline at end of file diff --git a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/compat/Artifacts.kt b/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/compat/Artifacts.kt deleted file mode 100644 index d90fd3f..0000000 --- a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/compat/Artifacts.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.github.kr328.gradle.zygote.compat - -import com.android.build.api.artifact.Artifacts -import com.android.build.api.artifact.impl.ArtifactsImpl -import com.android.build.api.component.analytics.AnalyticsEnabledArtifacts - -fun Artifacts.resolveImpl(): ArtifactsImpl { - return when (this) { - is AnalyticsEnabledArtifacts -> delegate.resolveImpl() - is ArtifactsImpl -> this - else -> error("Unsupported artifacts: $this") - } -} \ No newline at end of file diff --git a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/tasks/ChecksumTask.java b/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/tasks/ChecksumTask.java new file mode 100644 index 0000000..0d7a4da --- /dev/null +++ b/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/tasks/ChecksumTask.java @@ -0,0 +1,101 @@ +package com.github.kr328.gradle.zygote.tasks; + +import org.gradle.api.DefaultTask; +import org.gradle.api.file.DirectoryProperty; +import org.gradle.api.file.RegularFileProperty; +import org.gradle.api.tasks.InputDirectory; +import org.gradle.api.tasks.OutputFile; +import org.gradle.api.tasks.TaskAction; + +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.MessageDigest; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import javax.annotation.Nonnull; + +public abstract class ChecksumTask extends DefaultTask { + private static final String VERIFY_HEADER = String.join("\n", + "# Generated by ZygoteLoader. DO NOT EDIT.", + "", + "ui_print \"- Verify module resources\"", + "", + "function do_verify() {", + " [ -f \"$MODPATH/$1\" ] || abort \"! Module resource '$1' not found\"", + "", + " (echo \"$2 $MODPATH/$1\" | sha256sum -c -s -) || abort \"! Module resource '$1' verify failed\"", + "", + " ui_print \" '$1' verified\"", + "}" + ); + + private static final String VERIFY_TAIL = String.join("\n", + "unset -f do_verify" + ); + + private static String checksum(final Path path) { + try { + final MessageDigest sha256 = MessageDigest.getInstance("SHA-256"); + + final OutputStream stream = new OutputStream() { + @Override + public void write(int i) throws IOException { + this.write(new byte[]{(byte) i}); + } + + @Override + public void write(@Nonnull byte[] b, int off, int len) { + sha256.update(b, off, len); + } + }; + + Files.copy(path, stream); + + final StringBuilder sb = new StringBuilder(); + for (final byte b : sha256.digest()) { + sb.append(String.format("%02x", ((int) b) & 0xff)); + } + return sb.toString(); + } catch (final Exception e) { + throw new RuntimeException(e); + } + } + + @InputDirectory + public abstract DirectoryProperty getRootDirectory(); + + @OutputFile + public abstract RegularFileProperty getDestinationFile(); + + @TaskAction + public void doAction() throws Exception { + final Path root = getRootDirectory().getAsFile().get().toPath(); + + final List> checksums = Files.walk(root) + .filter(Files::isRegularFile) + .map(p -> root.relativize(p).toString()) + .filter(p -> !p.startsWith("META-INF")) + .map(p -> Map.entry(p.replace('\\', '/'), checksum(root.resolve(p)))) + .sorted(Map.Entry.comparingByKey()) + .collect(Collectors.toList()); + + final StringBuilder sb = new StringBuilder(); + sb.append(VERIFY_HEADER).append("\n\n"); + + for (final Map.Entry checksum : checksums) { + sb.append("do_verify ") + .append(checksum.getKey()) + .append(" ") + .append(checksum.getValue()) + .append('\n'); + } + + sb.append("\n\n").append(VERIFY_TAIL); + + Files.writeString(getDestinationFile().getAsFile().get().toPath(), sb); + } +} diff --git a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/tasks/ChecksumTask.kt b/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/tasks/ChecksumTask.kt deleted file mode 100644 index 9401cb2..0000000 --- a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/tasks/ChecksumTask.kt +++ /dev/null @@ -1,65 +0,0 @@ -package com.github.kr328.gradle.zygote.tasks - -import com.github.kr328.gradle.zygote.util.digestHexString -import org.gradle.api.DefaultTask -import org.gradle.api.file.DirectoryProperty -import org.gradle.api.tasks.InputDirectory -import org.gradle.api.tasks.OutputDirectory -import org.gradle.api.tasks.TaskAction -import java.security.MessageDigest - -abstract class ChecksumTask : DefaultTask() { - @get:InputDirectory - abstract val inputDir: DirectoryProperty - - @get:OutputDirectory - abstract val destinationDir: DirectoryProperty - - @TaskAction - fun doAction() { - val root = inputDir.get().asFile - val sha256 = MessageDigest.getInstance("SHA-256") - - val script = root.walk() - .filter { it.isFile } - .map { it.relativeTo(root).invariantSeparatorsPath } - .filterNot { it.startsWith("META-INF") } - .sorted() - .map { - it to sha256.digestHexString(root.resolve(it).readBytes()) - } - .joinToString("\n") { - "do_verify ${it.first} ${it.second}" - } - - destinationDir.get().asFile.resolve("customize.d").apply { - mkdirs() - - resolve("00-verify-resources.sh").writeText(buildString { - appendLine( - """ - # Generated by ZygoteLoader. DO NOT EDIT. - - ui_print "- Verify module resources" - - function do_verify() { - [ -f "${'$'}MODPATH/$1" ] || abort "! Module resource '${'$'}1' not found" - - (echo "$2 ${'$'}MODPATH/$1" | sha256sum -c -s -) || abort "! Module resource '$1' verify failed" - - ui_print " '$1' verified" - } - """.trimIndent() - ) - appendLine() - appendLine(script) - appendLine() - appendLine( - """ - unset -f do_verify - """.trimIndent() - ) - }) - } - } -} \ No newline at end of file diff --git a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/tasks/CustomizeTask.java b/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/tasks/CustomizeTask.java new file mode 100644 index 0000000..26431d1 --- /dev/null +++ b/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/tasks/CustomizeTask.java @@ -0,0 +1,55 @@ +package com.github.kr328.gradle.zygote.tasks; + +import org.gradle.api.DefaultTask; +import org.gradle.api.file.DirectoryProperty; +import org.gradle.api.file.RegularFileProperty; +import org.gradle.api.provider.Property; +import org.gradle.api.tasks.Input; +import org.gradle.api.tasks.InputDirectory; +import org.gradle.api.tasks.OutputFile; +import org.gradle.api.tasks.TaskAction; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.stream.Stream; + +public abstract class CustomizeTask extends DefaultTask { + private static final String CUSTOMIZE_HEADER = String.join("\n", + "# Generated by ZygoteLoader. DO NOT EDIT." + ); + private static final String CUSTOMIZE_TAIL = String.join("\n", + "rm -rf $MODPATH/customize.d" + ); + + @InputDirectory + public abstract DirectoryProperty getMergedDirectory(); + + @Input + public abstract Property getChecksumFileName(); + + @OutputFile + public abstract RegularFileProperty getDestinationFile(); + + @TaskAction + public void doAction() throws Exception { + final StringBuilder sb = new StringBuilder(); + + sb.append(CUSTOMIZE_HEADER).append("\n\n"); + + final Stream customizes = Stream.concat( + Stream.of(getChecksumFileName().get()), + Files.list(getMergedDirectory().getAsFile().get().toPath().resolve("customize.d")) + .map(Path::getFileName) + .map(Path::toString) + ).sorted(); + + customizes.forEach(f -> { + sb.append(String.format("[ -f \"$MODPATH/customize.d/%1$s\" ] || abort \"! Part '%1$s' not found\"", f)).append('\n'); + sb.append(String.format(". \"$MODPATH/customize.d/%1$s\"", f)).append('\n'); + }); + + sb.append("\n\n").append(CUSTOMIZE_TAIL); + + Files.writeString(getDestinationFile().getAsFile().get().toPath(), sb); + } +} diff --git a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/tasks/CustomizeTask.kt b/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/tasks/CustomizeTask.kt deleted file mode 100644 index 0fddea7..0000000 --- a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/tasks/CustomizeTask.kt +++ /dev/null @@ -1,43 +0,0 @@ -package com.github.kr328.gradle.zygote.tasks - -import org.gradle.api.DefaultTask -import org.gradle.api.file.DirectoryProperty -import org.gradle.api.tasks.InputDirectory -import org.gradle.api.tasks.OutputDirectory -import org.gradle.api.tasks.TaskAction - -abstract class CustomizeTask : DefaultTask() { - @get:InputDirectory - abstract val customizeFiles: DirectoryProperty - - @get:InputDirectory - abstract val checksumFiles: DirectoryProperty - - @get:OutputDirectory - abstract val destinationDir: DirectoryProperty - - @TaskAction - fun doAction() { - val customizes = customizeFiles.get().asFile.listFiles()?.toList() ?: emptyList() - val checksums = checksumFiles.get().asFile.listFiles()?.toList() ?: emptyList() - - val files = (customizes + checksums).map { it.name }.sorted() - - val customizeText = buildString { - appendLine("# Generated by ZygoteLoader. DO NOT EDIT.") - appendLine() - files.forEach { - appendLine("[ -f \"\$MODPATH/customize.d/$it\" ] || abort \"! Part '$it' not found\"") - appendLine(". \"\$MODPATH/customize.d/$it\"") - } - appendLine() - appendLine("rm -rf \"\$MODPATH/customize.d\"") - } - - destinationDir.asFile.get().apply { - mkdirs() - - resolve("customize.sh").writeText(customizeText) - } - } -} \ No newline at end of file diff --git a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/tasks/FlattenTask.kt b/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/tasks/FlattenTask.kt deleted file mode 100644 index dbd2136..0000000 --- a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/tasks/FlattenTask.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.github.kr328.gradle.zygote.tasks - -import com.github.kr328.gradle.zygote.util.fromKtx -import com.github.kr328.gradle.zygote.util.syncKtx -import org.apache.tools.ant.filters.FixCrLfFilter -import org.gradle.api.DefaultTask -import org.gradle.api.file.DirectoryProperty -import org.gradle.api.tasks.InputDirectory -import org.gradle.api.tasks.OutputDirectory -import org.gradle.api.tasks.TaskAction - -abstract class FlattenTask : DefaultTask() { - @get:InputDirectory - abstract val composedDir: DirectoryProperty - - @get:OutputDirectory - abstract val destinationDir: DirectoryProperty - - @TaskAction - fun doAction() { - project.syncKtx { - includeEmptyDirs = false - - into(destinationDir) - - fromKtx(composedDir) { - exclude("**/*.jar") - } - - composedDir.asFile.get().walk() - .filter { it.extension == "jar" } - .forEach { jar -> - from(project.zipTree(jar)) - } - - val crlf: Map = mapOf("eol" to FixCrLfFilter.CrLf.newInstance("lf")) - eachFile { - if (it.relativePath.startsWith("assets/META-INF") || it.name.endsWith(".sh")) { - it.filter(crlf, FixCrLfFilter::class.java) - } - } - } - } -} diff --git a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/tasks/PackagesTask.java b/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/tasks/PackagesTask.java new file mode 100644 index 0000000..b6d35b0 --- /dev/null +++ b/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/tasks/PackagesTask.java @@ -0,0 +1,30 @@ +package com.github.kr328.gradle.zygote.tasks; + +import org.gradle.api.DefaultTask; +import org.gradle.api.file.DirectoryProperty; +import org.gradle.api.provider.SetProperty; +import org.gradle.api.tasks.Input; +import org.gradle.api.tasks.OutputDirectory; +import org.gradle.api.tasks.TaskAction; + +import java.io.File; +import java.nio.file.Files; + +public abstract class PackagesTask extends DefaultTask { + @Input + public abstract SetProperty getPackages(); + + @OutputDirectory + public abstract DirectoryProperty getDestinationDirectory(); + + @TaskAction + public void doAction() throws Exception { + for (final File file : getDestinationDirectory().getAsFileTree()) { + Files.delete(file.toPath()); + } + + for (final String pkg : getPackages().get()) { + Files.createFile(getDestinationDirectory().file(pkg).get().getAsFile().toPath()); + } + } +} diff --git a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/tasks/PackagesTask.kt b/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/tasks/PackagesTask.kt deleted file mode 100644 index 4fd7c4b..0000000 --- a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/tasks/PackagesTask.kt +++ /dev/null @@ -1,29 +0,0 @@ -package com.github.kr328.gradle.zygote.tasks - -import org.gradle.api.DefaultTask -import org.gradle.api.file.DirectoryProperty -import org.gradle.api.provider.SetProperty -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.OutputDirectory -import org.gradle.api.tasks.TaskAction - -abstract class PackagesTask : DefaultTask() { - @get:Input - abstract val packages: SetProperty - - @get:OutputDirectory - abstract val destinationDir: DirectoryProperty - - @TaskAction - fun doAction() { - destinationDir.asFile.get().resolve("packages").apply { - deleteRecursively() - - mkdirs() - - packages.get().forEach { - resolve(it).createNewFile() - } - } - } -} \ No newline at end of file diff --git a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/tasks/PropertiesTask.java b/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/tasks/PropertiesTask.java new file mode 100644 index 0000000..71cc11b --- /dev/null +++ b/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/tasks/PropertiesTask.java @@ -0,0 +1,28 @@ +package com.github.kr328.gradle.zygote.tasks; + +import org.gradle.api.DefaultTask; +import org.gradle.api.file.RegularFileProperty; +import org.gradle.api.provider.MapProperty; +import org.gradle.api.tasks.Input; +import org.gradle.api.tasks.OutputFile; +import org.gradle.api.tasks.TaskAction; + +import java.nio.file.Files; +import java.util.stream.Collectors; + +public abstract class PropertiesTask extends DefaultTask { + @Input + public abstract MapProperty getProperties(); + + @OutputFile + public abstract RegularFileProperty getDestinationFile(); + + @TaskAction + public void doAction() throws Exception { + final String text = getProperties().get().entrySet().stream() + .map(kv -> kv.getKey() + "=" + kv.getValue()) + .collect(Collectors.joining("\n", "# Generated by ZygoteLoader. DO NOT EDIT.\n", "\n")); + + Files.writeString(getDestinationFile().get().getAsFile().toPath(), text); + } +} diff --git a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/tasks/PropertiesTask.kt b/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/tasks/PropertiesTask.kt deleted file mode 100644 index 2105e62..0000000 --- a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/tasks/PropertiesTask.kt +++ /dev/null @@ -1,33 +0,0 @@ -package com.github.kr328.gradle.zygote.tasks - -import org.gradle.api.DefaultTask -import org.gradle.api.file.DirectoryProperty -import org.gradle.api.provider.MapProperty -import org.gradle.api.provider.Property -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.OutputDirectory -import org.gradle.api.tasks.TaskAction - -abstract class PropertiesTask : DefaultTask() { - @get:Input - abstract val properties: MapProperty - - @get:Input - abstract val fileName: Property - - @get:OutputDirectory - abstract val destinationDir: DirectoryProperty - - @TaskAction - fun doAction() { - val text = properties.get().toList().joinToString(separator = "\n", postfix = "\n") { - "${it.first}=${it.second}" - } - - destinationDir.get().asFile.apply { - mkdirs() - - resolve(fileName.get()).writeText(text) - } - } -} diff --git a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/util/Capitalized.kt b/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/util/Capitalized.kt deleted file mode 100644 index 6c5265b..0000000 --- a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/util/Capitalized.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.github.kr328.gradle.zygote.util - -fun String.toCapitalized(): String { - return replaceFirstChar { it.uppercase() } -} \ No newline at end of file diff --git a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/util/Digest.kt b/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/util/Digest.kt deleted file mode 100644 index 37af25a..0000000 --- a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/util/Digest.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.github.kr328.gradle.zygote.util - -import java.security.MessageDigest - -fun MessageDigest.digestHexString(bytes: ByteArray): String { - return digest(bytes).joinToString("") { b -> - String.format("%02x", b.toInt() and 0xff) - } -} \ No newline at end of file diff --git a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/util/GradkeKtx.kt b/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/util/GradkeKtx.kt deleted file mode 100644 index b53e30e..0000000 --- a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/util/GradkeKtx.kt +++ /dev/null @@ -1,72 +0,0 @@ -package com.github.kr328.gradle.zygote.util - -import com.android.build.api.dsl.CommonExtension -import com.android.build.api.variant.AndroidComponentsExtension -import com.android.build.api.variant.Variant -import com.android.build.api.variant.VariantBuilder -import org.gradle.api.NamedDomainObjectContainer -import org.gradle.api.Project -import org.gradle.api.Task -import org.gradle.api.file.CopySpec -import org.gradle.api.plugins.ExtensionContainer -import org.gradle.api.provider.Provider -import org.gradle.api.tasks.AbstractCopyTask -import org.gradle.api.tasks.TaskContainer -import kotlin.reflect.KClass - -fun TaskContainer.registerKtx( - name: String, - clazz: KClass, - configure: T.() -> Unit -): Provider { - return register(name, clazz.java, configure) -} - -fun AbstractCopyTask.fromKtx(vararg objs: Any, block: CopySpec.() -> Unit) { - from(objs, block) -} - -fun AbstractCopyTask.fromKtx(vararg objs: Any) { - from(objs) -} - -fun Project.syncKtx(block: CopySpec.() -> Unit) { - sync(block) -} - -fun CopySpec.fromKtx(vararg objs: Any, block: CopySpec.() -> Unit) { - from(objs, block) -} - -fun ExtensionContainer.configureKtx(clazz: KClass, configure: T.() -> Unit) { - configure(clazz.java) { - it.configure() - } -} - -fun , VariantBuilderT : VariantBuilder, VariantT : Variant> - AndroidComponentsExtension.finalizeDslKtx(block: DslExtensionT.() -> Unit) { - finalizeDsl { - it.block() - } -} - -fun , VariantBuilderT : VariantBuilder, VariantT : Variant> - AndroidComponentsExtension.beforeVariantsKtx(block: VariantBuilderT.() -> Unit) { - beforeVariants { - it.block() - } -} - -fun , VariantBuilderT : VariantBuilder, VariantT : Variant> - AndroidComponentsExtension.onVariantsKtx(block: VariantT.() -> Unit) { - onVariants { - it.block() - } -} - -fun NamedDomainObjectContainer.createKtx(name: String, block: T.() -> Unit) { - create(name) { - it.block() - } -} diff --git a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/util/Provider.kt b/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/util/Provider.kt deleted file mode 100644 index 43d5180..0000000 --- a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/util/Provider.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.github.kr328.gradle.zygote.util - -import org.gradle.api.file.Directory -import org.gradle.api.provider.Provider -import java.io.File - -fun Provider.resolve(path: String): Provider { - return map { it.resolve(path) } -} - -fun Provider.asFile(): Provider { - return map { it.asFile } -} diff --git a/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/util/StringUtils.java b/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/util/StringUtils.java new file mode 100644 index 0000000..279b970 --- /dev/null +++ b/gradle-plugin/src/main/java/com/github/kr328/gradle/zygote/util/StringUtils.java @@ -0,0 +1,13 @@ +package com.github.kr328.gradle.zygote.util; + +import javax.annotation.Nonnull; + +public final class StringUtils { + public static String capitalize(@Nonnull final String in) { + if (in.isEmpty()) { + return ""; + } + + return Character.toUpperCase(in.charAt(0)) + in.substring(1); + } +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 41d9927..249e583 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradlew b/gradlew old mode 100755 new mode 100644 index 1b6c787..a69d9cb --- a/gradlew +++ b/gradlew @@ -205,6 +205,12 @@ set -- \ org.gradle.wrapper.GradleWrapperMain \ "$@" +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. diff --git a/gradlew.bat b/gradlew.bat index ac1b06f..f127cfd 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,89 +1,91 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/runtime/src/main/assets/customize.d/40-initialize-data-directory.sh b/runtime/src/main/assets/customize.d/40-initialize-data-directory.sh index 515d6d8..d018b13 100644 --- a/runtime/src/main/assets/customize.d/40-initialize-data-directory.sh +++ b/runtime/src/main/assets/customize.d/40-initialize-data-directory.sh @@ -14,7 +14,7 @@ if [ ! -f "$DATA_PATH_FILE" ]; then echo -n "/data/system/zloader-$RANDOM_SUFFIX" > "$DATA_PATH_FILE" fi -DATA_PATH="$(cat "$DATA_PATH_FILE" | head -n 1 | xargs printf)" +DATA_PATH="$(head -n 1 "$DATA_PATH_FILE")" MODULE_DATA_PATH="$DATA_PATH/$(grep_prop id "$MODPATH/module.prop")" ui_print "- Initialize module data directory" diff --git a/runtime/src/riru/assets/customize.d/21-enforce-riru-env.sh b/runtime/src/riru/assets/customize.d/21-enforce-riru-env.sh index e937544..ba2bcba 100644 --- a/runtime/src/riru/assets/customize.d/21-enforce-riru-env.sh +++ b/runtime/src/riru/assets/customize.d/21-enforce-riru-env.sh @@ -2,7 +2,7 @@ MAGISK_CURRENT_RIRU_MODULE_PATH=$(magisk --path)/.magisk/modules/riru-core -if [ ! -d $MAGISK_CURRENT_RIRU_MODULE_PATH ]; then +if [ ! -d "$MAGISK_CURRENT_RIRU_MODULE_PATH" ]; then ui_print "*********************************************************" ui_print "! Riru is not installed" ui_print "! Please install Riru from Magisk Manager or https://github.com/RikkaApps/Riru/releases" @@ -16,10 +16,9 @@ if [ -f "$MAGISK_CURRENT_RIRU_MODULE_PATH/disable" ] || [ -f "$MAGISK_CURRENT_RI abort "*********************************************************" fi -if [ -f $MAGISK_CURRENT_RIRU_MODULE_PATH/util_functions.sh ]; then +if [ -f "$MAGISK_CURRENT_RIRU_MODULE_PATH"/util_functions.sh ]; then ui_print "- Load $MAGISK_CURRENT_RIRU_MODULE_PATH/util_functions.sh" - # shellcheck disable=SC1090 - . $MAGISK_CURRENT_RIRU_MODULE_PATH/util_functions.sh + . "$MAGISK_CURRENT_RIRU_MODULE_PATH/util_functions.sh" else ui_print "*********************************************************" ui_print "! Riru $RIRU_MODULE_MIN_RIRU_VERSION_NAME or above is required"