From bb542e2e1bb175faf9463c05672bf5cf76986be5 Mon Sep 17 00:00:00 2001 From: X1nto Date: Thu, 27 Jan 2022 15:11:27 +0400 Subject: [PATCH 01/10] update deps --- app/build.gradle.kts | 8 ++++---- build.gradle.kts | 2 +- buildSrc/src/main/kotlin/Constants.kt | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index e16980d2b..ee7de31a2 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -28,15 +28,15 @@ val ivKey = ByteArray(16).apply { } android { - compileSdkVersion(30) + compileSdk = 30 defaultConfig { // If you're planning to change up the package name, ensure you have read the readme // thoroughly! - applicationId("substratum.theme.template") + applicationId = "substratum.theme.template" // We are only supporting Nougat and above, all new changes will incorporate Nougat changes // to the substratum repo rather than anything lower. Keep targetSdkVersion the same. - minSdkVersion(24) + minSdk = 24 // Both versions must be changed to increment on Play Store/user's devices versionCode = 2 versionName = "2.0" @@ -81,7 +81,7 @@ dependencies { //implementation(fileTree(include = ["*.jar"], dir = "libs")) implementation("com.github.javiersantos:PiracyChecker:1.2.5") implementation(kotlin("stdlib-jdk8")) - implementation("androidx.appcompat:appcompat:1.2.0") + implementation("androidx.appcompat:appcompat:1.4.1") } // Themers: DO NOT MODIFY ANYTHING BELOW diff --git a/build.gradle.kts b/build.gradle.kts index 00ee807f4..1e22b1b95 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,7 +9,7 @@ buildscript { } dependencies { - classpath("com.android.tools.build:gradle:4.2.1") + classpath("com.android.tools.build:gradle:7.1.0") classpath(kotlin("gradle-plugin", version = Constants.kotlinVersion)) } } diff --git a/buildSrc/src/main/kotlin/Constants.kt b/buildSrc/src/main/kotlin/Constants.kt index 6ae4a3344..0c34d6dd6 100644 --- a/buildSrc/src/main/kotlin/Constants.kt +++ b/buildSrc/src/main/kotlin/Constants.kt @@ -1,5 +1,5 @@ object Constants { - const val kotlinVersion = "1.5.0" + const val kotlinVersion = "1.6.10" } \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 7bb130fa6..b83ec5c1c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sun May 16 11:34:40 GET 2021 +#Thu Jan 27 15:07:27 GET 2022 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME From 00dc53a58b770c401d681473da660dfe64096f16 Mon Sep 17 00:00:00 2001 From: X1nto Date: Thu, 27 Jan 2022 16:14:37 +0400 Subject: [PATCH 02/10] update buildscript --- app/build.gradle.kts | 88 ++++++++++++++------------------ build.gradle.kts | 32 +++++------- buildSrc/src/main/kotlin/Util.kt | 27 ++++++++++ 3 files changed, 78 insertions(+), 69 deletions(-) create mode 100644 buildSrc/src/main/kotlin/Util.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index ee7de31a2..b92621337 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -5,30 +5,31 @@ import ThemerConstants.ENABLE_APP_BLACKLIST_CHECK import ThemerConstants.ENFORCE_GOOGLE_PLAY_INSTALL import ThemerConstants.SHOULD_ENCRYPT_ASSETS import ThemerConstants.SUPPORTS_THIRD_PARTY_SYSTEMS - -import java.util.Random +import Util.copyEncryptedTo import java.io.FileInputStream import java.io.FileOutputStream - +import java.util.* import javax.crypto.Cipher import javax.crypto.spec.IvParameterSpec import javax.crypto.spec.SecretKeySpec plugins { id("com.android.application") - id("kotlin-android") + kotlin("android") } +// Themers: DO NOT MODIFY val key = ByteArray(16).apply { Random().nextBytes(this) } +// Themers: DO NOT MODIFY val ivKey = ByteArray(16).apply { Random().nextBytes(this) } android { - compileSdk = 30 + compileSdk = 31 defaultConfig { // If you're planning to change up the package name, ensure you have read the readme @@ -80,7 +81,7 @@ android { dependencies { //implementation(fileTree(include = ["*.jar"], dir = "libs")) implementation("com.github.javiersantos:PiracyChecker:1.2.5") - implementation(kotlin("stdlib-jdk8")) + implementation(kotlin("stdlib-jdk8", version = Constants.kotlinVersion)) implementation("androidx.appcompat:appcompat:1.4.1") } @@ -91,52 +92,43 @@ tasks.register("encryptAssets") { return@register } - val tempAssets = File(projectDir, "/src/main/assets-temp") - if (!tempAssets.exists()) { + // Check if temp assets exist + if (File(projectDir, "/src/main/assets-temp").exists()) { println("Encrypting duplicated assets, don't worry, your original assets are safe...") + val list = mutableListOf() - val dir = File(projectDir, "/src/main/assets") - dir.listFiles()?.filter { it.isFile }?.forEach { file -> + + // Encrypt every single file in the assets dir recursively + File(projectDir, "/src/main/assets").listFiles()?.filter { it.isFile }?.forEach { file -> list.add(file) - val fis = FileInputStream(file) val fo = File(file.absolutePath.replace("assets", "assets-temp")) - fo.parentFile.mkdirs() - val fos = FileOutputStream(fo) - val buffer = ByteArray(4096) - var n: Int - while (fis.read(buffer).also { n = it } != -1) { - fos.write(buffer, 0, n) + .apply { + parentFile.mkdirs() + } + + FileInputStream(file).use { fis -> + FileOutputStream(fo).use { fos -> + fis.copyTo(fos, bufferSize = 4096) + } } - fis.close() - fos.close() } list.forEach { file -> if (file.absolutePath.contains("overlays")) { - val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding") val secret = SecretKeySpec(key, "AES") val iv = IvParameterSpec(ivKey) - cipher.init(Cipher.ENCRYPT_MODE, secret, iv) - val fis = FileInputStream(file) - val fos = FileOutputStream(file.absolutePath + ".enc") + val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding") + .apply { + init(Cipher.ENCRYPT_MODE, secret, iv) + } - val input = ByteArray(64) - var bytesRead: Int - while (fis.read(input).also {bytesRead = it } != -1) { - val output = cipher.update(input, 0, bytesRead) - if (output != null) { - fos.write(output) + FileInputStream(file).use { fis -> + FileOutputStream(file.absolutePath + ".enc").use { fos -> + fis.copyEncryptedTo(fos, cipher, bufferSize = 64) } } - val output = cipher.doFinal() - if (output != null) { - fos.write(output) - } - fis.close() - fos.flush() - fos.close() file.delete() } @@ -147,7 +139,7 @@ tasks.register("encryptAssets") { } project.afterEvaluate { - tasks.named("preBuild"){ + tasks.named("preBuild") { dependsOn("encryptAssets") } } @@ -156,21 +148,19 @@ gradle.buildFinished { val tempAssets = File(projectDir, "/src/main/assets-temp") if (tempAssets.exists()) { println("Cleaning duplicated encrypted assets, not your decrypted assets...") - val encryptedAssets = File(projectDir, "src/main/assets") - encryptedAssets.delete() - tempAssets.listFiles()?.filter{ it.isFile }?.forEach { file -> - val fis = FileInputStream(file) + // Delete encrypted assets + File(projectDir, "src/main/assets").delete() + + tempAssets.listFiles()?.filter { it.isFile }?.forEach { file -> val fo = File(file.absolutePath.replace("assets-temp", "assets")) fo.parentFile.mkdirs() - val fos = FileOutputStream(fo) - val buffer = ByteArray(4096) - var n: Int - while (fis.read(buffer).also { n = it } != -1) { - fos.write(buffer, 0, n) + + FileInputStream(file).use { fis -> + FileOutputStream(fo).use { fos -> + fis.copyTo(fos, bufferSize = 4096) + } } - fis.close() - fos.close() } tempAssets.delete() } @@ -178,5 +168,5 @@ gradle.buildFinished { fun shouldEncrypt(): Boolean { val tasks = project.gradle.startParameter.taskNames - return SHOULD_ENCRYPT_ASSETS && tasks.joinToString { it.toLowerCase() }.contains("release") + return SHOULD_ENCRYPT_ASSETS && tasks.joinToString().contains("release", ignoreCase = true) } diff --git a/build.gradle.kts b/build.gradle.kts index 1e22b1b95..3d9c1f264 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,7 +2,6 @@ import java.io.FileInputStream import java.io.FileOutputStream buildscript { - extra["kotlin_version"] = Constants.kotlinVersion repositories { google() mavenCentral() @@ -14,41 +13,34 @@ buildscript { } } -tasks { - wrapper { - gradleVersion = "7.0.2" - distributionType = Wrapper.DistributionType.ALL - } -} - allprojects { repositories { google() - maven("https://jitpack.io") + maven(url = "https://jitpack.io") mavenCentral() } } tasks.register("clean") { delete(rootProject.buildDir) + val tempAssets = File(projectDir, "/src/main/assets-temp") if (tempAssets.exists()) { println("cleaning encrypted assets...") - val encryptedAssets = File(projectDir, "src/main/assets") - encryptedAssets.delete() + + File(projectDir, "src/main/assets").delete() tempAssets.listFiles()?.filter { it.isFile }?.forEach { file -> - val fis = FileInputStream(file) val fo = File(file.absolutePath.replace("assets-temp", "assets")) - fo.parentFile.mkdirs() - val fos = FileOutputStream(fo) - val buffer = ByteArray(4096) - var n: Int - while (fis.read(buffer).also { n = it } != -1) { - fos.write(buffer, 0, n) + .apply { + parentFile.mkdirs() + } + + FileInputStream(file).use { fis -> + FileOutputStream(fo).use { fos -> + fis.copyTo(fos, bufferSize = 4096) + } } - fis.close() - fos.close() } tempAssets.delete() } diff --git a/buildSrc/src/main/kotlin/Util.kt b/buildSrc/src/main/kotlin/Util.kt new file mode 100644 index 000000000..48eb601e2 --- /dev/null +++ b/buildSrc/src/main/kotlin/Util.kt @@ -0,0 +1,27 @@ +import java.io.InputStream +import java.io.OutputStream +import javax.crypto.Cipher + +object Util { + + fun InputStream.copyEncryptedTo( + out: OutputStream, + cipher: Cipher, + bufferSize: Int = DEFAULT_BUFFER_SIZE + ) { + val buffer = ByteArray(bufferSize) + var bytesRead = read(buffer) + while (bytesRead != -1) { + val output = cipher.update(buffer, 0, bytesRead) + if (output != null) { + out.write(output) + } + bytesRead = read(buffer) + } + val output = cipher.doFinal() + if (output != null) { + out.write(output) + } + } + +} \ No newline at end of file From 22184070eef65f2c6c58f052651a69cbf0b22859 Mon Sep 17 00:00:00 2001 From: X1nto Date: Thu, 27 Jan 2022 16:15:05 +0400 Subject: [PATCH 03/10] possibly fix the encryption issue --- app/build.gradle.kts | 4 ++-- build.gradle.kts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index b92621337..328bd8d3b 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -99,7 +99,7 @@ tasks.register("encryptAssets") { val list = mutableListOf() // Encrypt every single file in the assets dir recursively - File(projectDir, "/src/main/assets").listFiles()?.filter { it.isFile }?.forEach { file -> + File(projectDir, "/src/main/assets").walkTopDown().filter { it.isFile }.forEach { file -> list.add(file) val fo = File(file.absolutePath.replace("assets", "assets-temp")) @@ -152,7 +152,7 @@ gradle.buildFinished { // Delete encrypted assets File(projectDir, "src/main/assets").delete() - tempAssets.listFiles()?.filter { it.isFile }?.forEach { file -> + tempAssets.walkTopDown().filter { it.isFile }.forEach { file -> val fo = File(file.absolutePath.replace("assets-temp", "assets")) fo.parentFile.mkdirs() diff --git a/build.gradle.kts b/build.gradle.kts index 3d9c1f264..83cbcc429 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -30,7 +30,7 @@ tasks.register("clean") { File(projectDir, "src/main/assets").delete() - tempAssets.listFiles()?.filter { it.isFile }?.forEach { file -> + tempAssets.walkTopDown().filter { it.isFile }.forEach { file -> val fo = File(file.absolutePath.replace("assets-temp", "assets")) .apply { parentFile.mkdirs() From f7db04b4f0da71d5ab2a515aaa6ac1342b465f9f Mon Sep 17 00:00:00 2001 From: X1nto Date: Thu, 27 Jan 2022 16:31:08 +0400 Subject: [PATCH 04/10] fixed exception throwing incorrectly --- app/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 328bd8d3b..d234ef4b0 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -93,7 +93,7 @@ tasks.register("encryptAssets") { } // Check if temp assets exist - if (File(projectDir, "/src/main/assets-temp").exists()) { + if (!File(projectDir, "/src/main/assets-temp").exists()) { println("Encrypting duplicated assets, don't worry, your original assets are safe...") val list = mutableListOf() From 899afccadff40fa19daf4009b2a9724f92146f01 Mon Sep 17 00:00:00 2001 From: X1nto Date: Thu, 27 Jan 2022 16:31:08 +0400 Subject: [PATCH 05/10] fix exception throwing incorrectly --- app/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 328bd8d3b..d234ef4b0 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -93,7 +93,7 @@ tasks.register("encryptAssets") { } // Check if temp assets exist - if (File(projectDir, "/src/main/assets-temp").exists()) { + if (!File(projectDir, "/src/main/assets-temp").exists()) { println("Encrypting duplicated assets, don't worry, your original assets are safe...") val list = mutableListOf() From d3139ed96146e89b43d1a88462044d6b0df5c7e0 Mon Sep 17 00:00:00 2001 From: X1nto Date: Thu, 27 Jan 2022 16:40:08 +0400 Subject: [PATCH 06/10] update readme to match project structure --- README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index e4e833b30..dd9e74127 100644 --- a/README.md +++ b/README.md @@ -27,11 +27,11 @@ Disable activity launch on theme: ## Step 1: Package Naming The FIRST thing you need to change is the package identifier (the name the app identifies as) to something more meaningful to you. Open up [build.gradle.kts](app/build.gradle.kts) and look for this line ```kt -applicationId("substratum.theme.template") +applicationId = "substratum.theme.template" ``` Change this to anything you want, for instance: ```kt -applicationId("com.yourname.themename") +applicationId = "com.yourname.themename" ``` Change Package Name in the project structure (optional): @@ -130,26 +130,26 @@ If you take a look at the aforementioned theme_configurations.xml, you will see ## Step 6: Safeguard your theme! Don't let the pirates win! ### If you want to enable the Substratum theme for other Theme Managers (e.g. Slim) -In ThemerConstants.gradle, change the [SUPPORTS_THIRD_PARTY_SYSTEMS](app/ThemerConstants.gradle#L9) on line 9. +In ThemerConstants.kt, change the [SUPPORTS_THIRD_PARTY_SYSTEMS](buildSrc/src/main/kotlin/ThemerConstants.kt#L8) on line 8. ### If you don't want to activate AntiPiracy Then you can stop reading and get your theme published! Good luck! ### Getting started with AntiPiracy -If you are ready to get AntiPiracy set up, all you need to look at is [ThemerConstants.gradle](app/ThemerConstants.gradle)! +If you are ready to get AntiPiracy set up, all you need to look at is [ThemerConstants.kt](buildSrc/src/main/kotlin/ThemerConstants.kt)! -Compile your theme as a SIGNED release APK from Android Studio (Build -> Generate Signed APK). Then launch the signed apk on your device and your log will spit out an error log under the name "SubstratumThemeReport", and you want to copy and paste that into [APK_SIGNATURE_PRODUCTION](app/ThemerConstants.gradle#L13) on line 13. +Compile your theme as a SIGNED release APK from Android Studio (Build -> Generate Signed APK). Then launch the signed apk on your device and your log will spit out an error log under the name "SubstratumThemeReport", and you want to copy and paste that into [APK_SIGNATURE_PRODUCTION](buildSrc/src/main/kotlin/ThemerConstants.kt#L12) on line 12. -**NOTE**: If you are planning to make use of [Google Play App Signing](https://developer.android.com/studio/publish/app-signing.html#google-play-app-signing), **DO NOT** fill the `APK_SIGNATURE_PRODUCTION` field in [ThemerConstants.gradle](app/ThemerConstants.gradle). +**NOTE**: If you are planning to make use of [Google Play App Signing](https://developer.android.com/studio/publish/app-signing.html#google-play-app-signing), **DO NOT** fill the `APK_SIGNATURE_PRODUCTION` field in [ThemerConstants.kt](buildSrc/src/main/kotlin/ThemerConstants.kt). -Then you would need to go to Play Developer Console. Then access to your app -> Services and APIs, generate a new API key for your app and then paste it into [BASE_64_LICENSE_KEY](app/ThemerConstants.gradle#L12) on line 12. +Then you would need to go to Play Developer Console. Then access to your app -> Services and APIs, generate a new API key for your app and then paste it into [BASE_64_LICENSE_KEY](buildSrc/src/main/kotlin/ThemerConstants.kt#L11) on line 12. Third, if you would like to change where it checks for various things such as Amazon App Store Enforcement or Play Store Enforcement, you have options listed on line 16 and lines below it, simply change from `true` to `false` and vice versa to make your desired configuration. -Finally, if you would like to enable intensive mode anti-piracy (App package blacklist), add as many package names as you want under [BLACKLISTED_APPLICATIONS](app/src/main/kotlin/substratum/theme/template/AdvancedConstants.kt#L12) on line 12. Then make sure to enable [ENABLE_APP_BLACKLIST_CHECK](app/ThemerConstants.gradle#L16) on line 16. +Finally, if you would like to enable intensive mode anti-piracy (App package blacklist), add as many package names as you want under [BLACKLISTED_APPLICATIONS](app/src/main/kotlin/substratum/theme/template/AdvancedConstants.kt#L12) on line 12. Then make sure to enable [ENABLE_APP_BLACKLIST_CHECK](buildSrc/src/main/kotlin/ThemerConstants.kt#L15) on line 15. -**Under no circumstances should you share your ThemerConstants.gradle file, unless specifically asked by an [official substratum developer](https://github.com/substratum/documentation#team-info-and-responsibilities)**! +**Under no circumstances should you share your ThemerConstants.kt file, unless specifically asked by an [official substratum developer](https://github.com/substratum/documentation#team-info-and-responsibilities)**! ### Encrypted Assets As of template version 11.0.0, all theme assets are duplicated are encrypted within the APK by default, not your original assets! @@ -159,14 +159,14 @@ Always use a version control tool listed below to host your private themes! BitBucket: https://bitbucket.org/ GitLab: https://about.gitlab.com/ -If you want to keep your theme assets unencrypted, just change the value [here](app/ThemerConstants.gradle#L4) to false. +If you want to keep your theme assets unencrypted, just change the value [here](buildSrc/src/main/kotlin/ThemerConstants.kt#L3) to false. ### Enforcing security As of template version 11.0.0, themes have an additional check on the build of substratum your users should be running. What this means is that themes can ensure their themes ONLY function with our full release cycle with debug and Play Store releases. -If you would like to enable this feature (only allow your theme to be used with official substratum builds), all you have to do is to flip `true` to `false` [here](app/ThemerConstants.gradle#L20)! +If you would like to enable this feature (only allow your theme to be used with official substratum builds), all you have to do is to flip `true` to `false` [here](buildSrc/src/main/kotlin/ThemerConstants.kt#L19)! ### Now what? Nothing. Now you're set to publish your theme! From dd0291f036e4134a0443c480b04af97ff8a4f2fb Mon Sep 17 00:00:00 2001 From: X1nto Date: Thu, 27 Jan 2022 17:22:13 +0400 Subject: [PATCH 07/10] fix directory deletion --- app/build.gradle.kts | 4 ++-- build.gradle.kts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index d234ef4b0..ae4165dbe 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -150,7 +150,7 @@ gradle.buildFinished { println("Cleaning duplicated encrypted assets, not your decrypted assets...") // Delete encrypted assets - File(projectDir, "src/main/assets").delete() + File(projectDir, "src/main/assets").deleteRecursively() tempAssets.walkTopDown().filter { it.isFile }.forEach { file -> val fo = File(file.absolutePath.replace("assets-temp", "assets")) @@ -162,7 +162,7 @@ gradle.buildFinished { } } } - tempAssets.delete() + tempAssets.deleteRecursively() } } diff --git a/build.gradle.kts b/build.gradle.kts index 83cbcc429..b7435e727 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -28,7 +28,7 @@ tasks.register("clean") { if (tempAssets.exists()) { println("cleaning encrypted assets...") - File(projectDir, "src/main/assets").delete() + File(projectDir, "src/main/assets").deleteRecursively() tempAssets.walkTopDown().filter { it.isFile }.forEach { file -> val fo = File(file.absolutePath.replace("assets-temp", "assets")) @@ -42,7 +42,7 @@ tasks.register("clean") { } } } - tempAssets.delete() + tempAssets.deleteRecursively() } } From 4cab02c2fede51a5f0f1f4c26d620830017abca0 Mon Sep 17 00:00:00 2001 From: X1nto Date: Thu, 27 Jan 2022 17:54:51 +0400 Subject: [PATCH 08/10] extracted duplicate encrypted asset deletion to a function --- app/build.gradle.kts | 21 ++------------------- app/release/output-metadata.json | 20 ++++++++++++++++++++ build.gradle.kts | 25 ++----------------------- buildSrc/src/main/kotlin/Util.kt | 25 +++++++++++++++++++++++-- 4 files changed, 47 insertions(+), 44 deletions(-) create mode 100644 app/release/output-metadata.json diff --git a/app/build.gradle.kts b/app/build.gradle.kts index ae4165dbe..2413ebed8 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -5,6 +5,7 @@ import ThemerConstants.ENABLE_APP_BLACKLIST_CHECK import ThemerConstants.ENFORCE_GOOGLE_PLAY_INSTALL import ThemerConstants.SHOULD_ENCRYPT_ASSETS import ThemerConstants.SUPPORTS_THIRD_PARTY_SYSTEMS +import Util.cleanEncryptedAssets import Util.copyEncryptedTo import java.io.FileInputStream import java.io.FileOutputStream @@ -145,25 +146,7 @@ project.afterEvaluate { } gradle.buildFinished { - val tempAssets = File(projectDir, "/src/main/assets-temp") - if (tempAssets.exists()) { - println("Cleaning duplicated encrypted assets, not your decrypted assets...") - - // Delete encrypted assets - File(projectDir, "src/main/assets").deleteRecursively() - - tempAssets.walkTopDown().filter { it.isFile }.forEach { file -> - val fo = File(file.absolutePath.replace("assets-temp", "assets")) - fo.parentFile.mkdirs() - - FileInputStream(file).use { fis -> - FileOutputStream(fo).use { fos -> - fis.copyTo(fos, bufferSize = 4096) - } - } - } - tempAssets.deleteRecursively() - } + cleanEncryptedAssets(projectDir) } fun shouldEncrypt(): Boolean { diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json new file mode 100644 index 000000000..efa4f9d1b --- /dev/null +++ b/app/release/output-metadata.json @@ -0,0 +1,20 @@ +{ + "version": 3, + "artifactType": { + "type": "APK", + "kind": "Directory" + }, + "applicationId": "substratum.theme.template", + "variantName": "release", + "elements": [ + { + "type": "SINGLE", + "filters": [], + "attributes": [], + "versionCode": 2, + "versionName": "2.0", + "outputFile": "app-release.apk" + } + ], + "elementType": "File" +} \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index b7435e727..b3d4e7d3d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,4 @@ -import java.io.FileInputStream -import java.io.FileOutputStream +import Util.cleanEncryptedAssets buildscript { repositories { @@ -23,26 +22,6 @@ allprojects { tasks.register("clean") { delete(rootProject.buildDir) - - val tempAssets = File(projectDir, "/src/main/assets-temp") - if (tempAssets.exists()) { - println("cleaning encrypted assets...") - - File(projectDir, "src/main/assets").deleteRecursively() - - tempAssets.walkTopDown().filter { it.isFile }.forEach { file -> - val fo = File(file.absolutePath.replace("assets-temp", "assets")) - .apply { - parentFile.mkdirs() - } - - FileInputStream(file).use { fis -> - FileOutputStream(fo).use { fos -> - fis.copyTo(fos, bufferSize = 4096) - } - } - } - tempAssets.deleteRecursively() - } + cleanEncryptedAssets(projectDir) } diff --git a/buildSrc/src/main/kotlin/Util.kt b/buildSrc/src/main/kotlin/Util.kt index 48eb601e2..404c45f8b 100644 --- a/buildSrc/src/main/kotlin/Util.kt +++ b/buildSrc/src/main/kotlin/Util.kt @@ -1,5 +1,4 @@ -import java.io.InputStream -import java.io.OutputStream +import java.io.* import javax.crypto.Cipher object Util { @@ -24,4 +23,26 @@ object Util { } } + fun cleanEncryptedAssets(projectDir: File) { + val tempAssets = File(projectDir, "/src/main/assets-temp") + if (tempAssets.exists()) { + println("Cleaning duplicated encrypted assets, not your decrypted assets...") + File(projectDir, "src/main/assets").deleteRecursively() + + tempAssets.walkTopDown().filter { it.isFile }.forEach { file -> + val fo = File(file.absolutePath.replace("assets-temp", "assets")) + .apply { + parentFile.mkdirs() + } + + FileInputStream(file).use { fis -> + FileOutputStream(fo).use { fos -> + fis.copyTo(fos, bufferSize = 4096) + } + } + } + tempAssets.deleteRecursively() + } + } + } \ No newline at end of file From 2e6273031f3601ae4d614015a5e34c4a19eb09a6 Mon Sep 17 00:00:00 2001 From: X1nto Date: Thu, 27 Jan 2022 18:11:37 +0400 Subject: [PATCH 09/10] remove output-metadata.json --- app/release/output-metadata.json | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 app/release/output-metadata.json diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json deleted file mode 100644 index efa4f9d1b..000000000 --- a/app/release/output-metadata.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "version": 3, - "artifactType": { - "type": "APK", - "kind": "Directory" - }, - "applicationId": "substratum.theme.template", - "variantName": "release", - "elements": [ - { - "type": "SINGLE", - "filters": [], - "attributes": [], - "versionCode": 2, - "versionName": "2.0", - "outputFile": "app-release.apk" - } - ], - "elementType": "File" -} \ No newline at end of file From 7a0f7fe451b004e75f665c765f76805cbf171aed Mon Sep 17 00:00:00 2001 From: X1nto Date: Thu, 3 Feb 2022 20:42:53 +0400 Subject: [PATCH 10/10] further clean up build.gradle --- app/build.gradle.kts | 66 ++++++++++++-------------------- build.gradle.kts | 2 +- buildSrc/src/main/kotlin/Util.kt | 57 ++++++++++++++++++++------- 3 files changed, 69 insertions(+), 56 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 2413ebed8..a635ba8f4 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -5,14 +5,19 @@ import ThemerConstants.ENABLE_APP_BLACKLIST_CHECK import ThemerConstants.ENFORCE_GOOGLE_PLAY_INSTALL import ThemerConstants.SHOULD_ENCRYPT_ASSETS import ThemerConstants.SUPPORTS_THIRD_PARTY_SYSTEMS + +import Util.assets import Util.cleanEncryptedAssets import Util.copyEncryptedTo +import Util.generateRandomByteArray +import Util.tempAssets +import Util.twistAsset + import java.io.FileInputStream import java.io.FileOutputStream -import java.util.* import javax.crypto.Cipher -import javax.crypto.spec.IvParameterSpec import javax.crypto.spec.SecretKeySpec +import javax.crypto.spec.IvParameterSpec plugins { id("com.android.application") @@ -20,14 +25,8 @@ plugins { } // Themers: DO NOT MODIFY -val key = ByteArray(16).apply { - Random().nextBytes(this) -} - -// Themers: DO NOT MODIFY -val ivKey = ByteArray(16).apply { - Random().nextBytes(this) -} +val secretKey = generateRandomByteArray() +val ivKey = generateRandomByteArray() android { compileSdk = 31 @@ -47,8 +46,7 @@ android { buildConfigField("boolean", "SUPPORTS_THIRD_PARTY_SYSTEMS", "$SUPPORTS_THIRD_PARTY_SYSTEMS") buildConfigField("boolean", "ENABLE_APP_BLACKLIST_CHECK", "$ENABLE_APP_BLACKLIST_CHECK") buildConfigField("boolean", "ALLOW_THIRD_PARTY_SUBSTRATUM_BUILDS", "$ALLOW_THIRD_PARTY_SUBSTRATUM_BUILDS") - buildConfigField("String", "IV_KEY", "\"$ivKey\"") - buildConfigField("byte[]", "DECRYPTION_KEY", key.joinToString(prefix = "{", postfix = "}")) + buildConfigField("byte[]", "DECRYPTION_KEY", secretKey.joinToString(prefix = "{", postfix = "}")) buildConfigField("byte[]", "IV_KEY", ivKey.joinToString(prefix = "{", postfix = "}")) resValue("string", "encryption_status", if (shouldEncrypt()) "onCompileVerify" else "false") } @@ -80,10 +78,10 @@ android { } dependencies { - //implementation(fileTree(include = ["*.jar"], dir = "libs")) - implementation("com.github.javiersantos:PiracyChecker:1.2.5") implementation(kotlin("stdlib-jdk8", version = Constants.kotlinVersion)) + implementation("androidx.appcompat:appcompat:1.4.1") + implementation("com.github.javiersantos:PiracyChecker:1.2.5") } // Themers: DO NOT MODIFY ANYTHING BELOW @@ -94,43 +92,27 @@ tasks.register("encryptAssets") { } // Check if temp assets exist - if (!File(projectDir, "/src/main/assets-temp").exists()) { + if (!projectDir.tempAssets.exists()) { println("Encrypting duplicated assets, don't worry, your original assets are safe...") - val list = mutableListOf() + val secretKeySpec = SecretKeySpec(secretKey, "AES") + val ivParameterSpec = IvParameterSpec(ivKey) + val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding") + .apply { + init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec) + } // Encrypt every single file in the assets dir recursively - File(projectDir, "/src/main/assets").walkTopDown().filter { it.isFile }.forEach { file -> - list.add(file) - - val fo = File(file.absolutePath.replace("assets", "assets-temp")) - .apply { - parentFile.mkdirs() - } + projectDir.assets.walkTopDown().filter { it.isFile }.forEach { file -> + file.twistAsset("assets", "assets-temp") - FileInputStream(file).use { fis -> - FileOutputStream(fo).use { fos -> - fis.copyTo(fos, bufferSize = 4096) - } - } - } - - list.forEach { file -> + //Encrypt assets if (file.absolutePath.contains("overlays")) { - val secret = SecretKeySpec(key, "AES") - val iv = IvParameterSpec(ivKey) - - val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding") - .apply { - init(Cipher.ENCRYPT_MODE, secret, iv) - } - FileInputStream(file).use { fis -> - FileOutputStream(file.absolutePath + ".enc").use { fos -> + FileOutputStream("${file.absolutePath}.enc").use { fos -> fis.copyEncryptedTo(fos, cipher, bufferSize = 64) } } - file.delete() } } @@ -146,7 +128,7 @@ project.afterEvaluate { } gradle.buildFinished { - cleanEncryptedAssets(projectDir) + projectDir.cleanEncryptedAssets() } fun shouldEncrypt(): Boolean { diff --git a/build.gradle.kts b/build.gradle.kts index b3d4e7d3d..2b833bc31 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -22,6 +22,6 @@ allprojects { tasks.register("clean") { delete(rootProject.buildDir) - cleanEncryptedAssets(projectDir) + projectDir.cleanEncryptedAssets() } diff --git a/buildSrc/src/main/kotlin/Util.kt b/buildSrc/src/main/kotlin/Util.kt index 404c45f8b..eaaa4541d 100644 --- a/buildSrc/src/main/kotlin/Util.kt +++ b/buildSrc/src/main/kotlin/Util.kt @@ -1,8 +1,24 @@ import java.io.* +import java.util.* import javax.crypto.Cipher object Util { + /** + * @receiver Gradle project directory. + * @return Assets directory. + */ + val File.assets get() = File(this, "/src/main/assets") + + /** + * @receiver Gradle project directory. + * @return Assets directory. + */ + val File.tempAssets get() = File(this, "/src/main/assets-temp") + + /** + * Copies this [InputStream] to the given [OutputStream] and encrypts the content of it. + */ fun InputStream.copyEncryptedTo( out: OutputStream, cipher: Cipher, @@ -23,26 +39,41 @@ object Util { } } - fun cleanEncryptedAssets(projectDir: File) { - val tempAssets = File(projectDir, "/src/main/assets-temp") + /** + * Cleans the encrypted assets in the project. + * @receiver Gradle project directory. + */ + fun File.cleanEncryptedAssets() { + val tempAssets = tempAssets if (tempAssets.exists()) { println("Cleaning duplicated encrypted assets, not your decrypted assets...") - File(projectDir, "src/main/assets").deleteRecursively() + assets.deleteRecursively() tempAssets.walkTopDown().filter { it.isFile }.forEach { file -> - val fo = File(file.absolutePath.replace("assets-temp", "assets")) - .apply { - parentFile.mkdirs() - } - - FileInputStream(file).use { fis -> - FileOutputStream(fo).use { fos -> - fis.copyTo(fos, bufferSize = 4096) - } - } + file.twistAsset("assets-temp", "assets") } tempAssets.deleteRecursively() } } + /** + * Copies the asset to a new destination by changing its [oldName] in the path with [newName]. + */ + fun File.twistAsset(oldName: String, newName: String) { + val fo = File(absolutePath.replace(oldName, newName)) + .apply { + parentFile.mkdirs() + } + + FileInputStream(this).use { fis -> + FileOutputStream(fo).use { fos -> + fis.copyTo(fos, bufferSize = 4096) + } + } + } + + fun generateRandomByteArray() = + ByteArray(16).apply { + Random().nextBytes(this) + } } \ No newline at end of file