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 424cc82
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 44 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
79 changes: 35 additions & 44 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 @@ -25,22 +24,23 @@ import io.github.rosemoe.sora.langs.textmate.registry.ThemeRegistry
import io.github.rosemoe.sora.langs.textmate.registry.model.ThemeModel
import io.github.rosemoe.sora.langs.textmate.registry.provider.AssetsFileResolver
import org.cosmicide.rewrite.common.Analytics
import org.cosmicide.rewrite.common.Prefs
import org.cosmicide.rewrite.fragment.PluginsFragment
import org.cosmicide.rewrite.plugin.api.Hook
import org.cosmicide.rewrite.plugin.api.HookManager
import org.cosmicide.rewrite.plugin.api.PluginLoader
import org.cosmicide.rewrite.util.CommonUtils
import org.cosmicide.rewrite.util.FileUtil
import org.eclipse.tm4e.core.registry.IThemeSource
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 +62,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 @@ -156,18 +126,42 @@ class App : Application() {
}

fun extractAsset(assetName: String, targetFile: File) {
targetFile.exists().ifTrue { return }
try {
assets.open(assetName).use { inputStream ->
targetFile.outputStream().use { outputStream ->
inputStream.copyTo(outputStream)
if (targetFile.exists() && assetNeedsUpdate(assetName, targetFile)) {
targetFile.delete()
}

if (!targetFile.exists()) {
try {
assets.open(assetName).use { inputStream ->
targetFile.outputStream().use { outputStream ->
inputStream.copyTo(outputStream)
}
}
} catch (e: FileNotFoundException) {
Log.e("App", "Failed to extract asset: $assetName", e)
}
} catch (e: FileNotFoundException) {
Log.e("App", "Failed to extract asset: $assetName", e)
}
}

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 +180,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 +216,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.FileUtil
import org.cosmicide.rewrite.common.Prefs

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 424cc82

Please sign in to comment.