Skip to content
This repository has been archived by the owner on Sep 17, 2023. It is now read-only.

Commit

Permalink
feat: Use startup library to initialize some components
Browse files Browse the repository at this point in the history
  • Loading branch information
aikrq committed Aug 22, 2023
1 parent d70466e commit 0a1b94c
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 39 deletions.
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ dependencies {
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.2.0-alpha01")
implementation("androidx.viewpager2:viewpager2:1.1.0-beta02")
implementation("androidx.activity:activity-ktx:1.8.0-alpha06")
implementation("androidx.startup:startup-runtime:1.1.1")

val editorVersion = "0.22.0"
//noinspection GradleDependency
Expand Down
10 changes: 10 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,16 @@
android:resource="@xml/file_paths" />
</provider>

<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<meta-data
android:name="org.cosmicide.rewrite.startup.MainInitializer"
android:value="androidx.startup" />
</provider>

<activity
android:name=".MainActivity"
android:exported="true">
Expand Down
66 changes: 27 additions & 39 deletions app/src/main/kotlin/org/cosmicide/rewrite/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import android.app.Application
import android.app.UiModeManager
import android.content.res.Configuration
import android.os.Build
import android.os.StrictMode
import android.util.Log
import androidx.appcompat.app.AppCompatDelegate
import androidx.recyclerview.widget.LinearLayoutManager
Expand All @@ -37,10 +36,13 @@ import org.jetbrains.kotlin.utils.addToStdlib.ifTrue
import org.lsposed.hiddenapibypass.HiddenApiBypass
import rikka.sui.Sui
import java.io.File
import java.io.FileInputStream
import java.io.FileNotFoundException
import java.io.InputStream
import java.lang.ref.WeakReference
import java.math.BigInteger
import java.security.MessageDigest
import java.time.ZonedDateTime
import java.util.concurrent.Executors

class App : Application() {

Expand All @@ -62,39 +64,9 @@ class App : Application() {
instance = WeakReference(this)
HookManager.context = WeakReference(this)

val externalStorage = getExternalFilesDir(null)!!

Prefs.init(applicationContext)
FileUtil.init(externalStorage)

setupHooks()
loadPlugins()

if (BuildConfig.DEBUG) {
StrictMode.setVmPolicy(
StrictMode.VmPolicy.Builder().apply {
detectLeakedRegistrationObjects()
detectActivityLeaks()
detectContentUriWithoutPermission()
detectFileUriExposure()
detectCleartextNetwork()
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
penaltyLog()
return@apply
}
permitNonSdkApiUsage()
penaltyListener(Executors.newSingleThreadExecutor()) { violation ->
Log.e("StrictMode", "VM violation", violation)
violation.printStackTrace()
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
detectIncorrectContextUse()
detectUnsafeIntentLaunch()
}
}.build()
)
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
HiddenApiBypass.addHiddenApiExemptions("L")
}
Expand Down Expand Up @@ -142,9 +114,6 @@ class App : Application() {
* Extracts kotlin stdlib and stdlib-common from assets.
*/
fun extractFiles() {
FileUtil.classpathDir.resolve("kotlin-stdlib-1.8.0.jar").apply {
if (exists()) delete()
}
extractAsset(
"kotlin-stdlib-1.9.0.jar",
FileUtil.classpathDir.resolve("kotlin-stdlib-1.9.0.jar")
Expand All @@ -156,7 +125,10 @@ class App : Application() {
}

fun extractAsset(assetName: String, targetFile: File) {
targetFile.exists().ifTrue { return }
if (targetFile.exists() && assetNeedsUpdate(assetName, targetFile)) {
targetFile.delete()
}

try {
assets.open(assetName).use { inputStream ->
targetFile.outputStream().use { outputStream ->
Expand All @@ -168,6 +140,25 @@ class App : Application() {
}
}

fun assetNeedsUpdate(assetName: String, targetFile: File): Boolean {
val assetInputStream = assets.open(assetName)
val targetFileInputStream = FileInputStream(targetFile)
val assetChecksum = calculateChecksum(assetInputStream)
val targetFileChecksum = calculateChecksum(targetFileInputStream)
return assetChecksum != targetFileChecksum
}

fun calculateChecksum(inputStream: InputStream): String {
val md = MessageDigest.getInstance("SHA-256")
val buffer = ByteArray(8192)
var bytesRead: Int
while (inputStream.read(buffer).also { bytesRead = it } != -1) {
md.update(buffer, 0, bytesRead)
}
val digest = md.digest()
return BigInteger(1, digest).toString(16)
}

fun disableModules() {
JavacConfigProvider.disableModules()
}
Expand All @@ -186,7 +177,6 @@ class App : Application() {
}

private fun setupHooks() {

// Some libraries may call System.exit() to exit the app, which crashes the app.
// Currently, only JGit does this.
HookManager.registerHook(object : Hook(
Expand Down Expand Up @@ -223,8 +213,6 @@ class App : Application() {
param.result = null
}
})


}

override fun onConfigurationChanged(newConfig: Configuration) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package org.cosmicide.rewrite.startup

import android.content.Context
import android.os.Build
import android.os.StrictMode
import android.util.Log
import androidx.startup.Initializer
import org.cosmicide.rewrite.BuildConfig
import java.util.concurrent.Executors

class DebugInitializer : Initializer<Unit> {

override fun create(context: Context) {
if (BuildConfig.DEBUG) {
enableStrictMode()
}
}

override fun dependencies(): List<Class<out Initializer<*>>> = emptyList()

private fun enableStrictMode() {
StrictMode.setVmPolicy(
StrictMode.VmPolicy.Builder().apply {
detectLeakedRegistrationObjects()
detectActivityLeaks()
detectContentUriWithoutPermission()
detectFileUriExposure()
detectCleartextNetwork()
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
penaltyLog()
return@apply
}
permitNonSdkApiUsage()
penaltyListener(Executors.newSingleThreadExecutor()) { violation ->
Log.e("StrictMode", "VM violation", violation)
violation.printStackTrace()
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
detectIncorrectContextUse()
detectUnsafeIntentLaunch()
}
}.build()
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.cosmicide.rewrite.startup

import android.content.Context
import androidx.startup.Initializer

class MainInitializer : Initializer<Unit> {

override fun create(context: Context) {}

override fun dependencies(): List<Class<out Initializer<*>>> {
return listOf(
DebugInitializer::class.java,
PreferencesInitializer::class.java
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.cosmicide.rewrite.startup

import android.content.Context
import androidx.startup.Initializer
import org.cosmicide.rewrite.common.Prefs
import org.cosmicide.rewrite.util.FileUtil

class PreferencesInitializer : Initializer<Unit> {

override fun create(context: Context) {
FileUtil.init(context.getExternalFilesDir(null)!!)
Prefs.init(context.applicationContext)
}

override fun dependencies(): List<Class<out Initializer<*>>> = emptyList()
}

0 comments on commit 0a1b94c

Please sign in to comment.