From efc093a5c03dd4c0045bf3d524a795141fa2bcee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Fdez?= Date: Mon, 7 Jun 2021 01:31:29 +0200 Subject: [PATCH] bump to API30 --- .gitignore | 3 +- Makefile | 2 +- app/build.gradle | 17 +- app/src/debug/res/mipmap-anydpi-v26/icon.xml | 2 +- app/src/main/AndroidManifest.xml | 16 +- .../main/java/org/koreader/launcher/Assets.kt | 20 ++ .../koreader/launcher/CrashReportActivity.kt | 16 +- .../org/koreader/launcher/EPDTestActivity.kt | 60 +++--- .../java/org/koreader/launcher/Timeout.kt | 25 +-- .../launcher/extensions/FileExtensions.kt | 23 +++ app/src/main/res/layout/crash_report.xml | 28 +-- app/src/main/res/layout/epd_test.xml | 191 +++++++----------- app/src/main/res/mipmap-anydpi-v26/icon.xml | 2 +- app/src/main/res/values/colors.xml | 5 + app/src/main/res/values/dimens.xml | 6 + app/src/main/res/values/strings.xml | 26 +-- app/src/main/res/values/styles.xml | 2 - build.gradle | 2 +- gradle/wrapper/gradle-wrapper.jar | Bin 54329 -> 59203 bytes gradle/wrapper/gradle-wrapper.properties | 5 +- gradlew | 57 ++++-- 21 files changed, 270 insertions(+), 238 deletions(-) create mode 100644 app/src/main/res/values/colors.xml create mode 100644 app/src/main/res/values/dimens.xml diff --git a/.gitignore b/.gitignore index 9d2d5441a..eb71dab09 100644 --- a/.gitignore +++ b/.gitignore @@ -8,11 +8,10 @@ project.properties *.iml bin +libs build app/.* app/build assets/libs assets/module jni/luajit/build -tests/einkTest/build -tests/einkTest/src/org/koreader/test/eink/*EPDController.java diff --git a/Makefile b/Makefile index 55bc86d9e..e518f777d 100644 --- a/Makefile +++ b/Makefile @@ -120,7 +120,7 @@ example: update clean build-luajit find app/build/outputs/apk/ -type f -name '*.apk' -exec mv -v {} bin/ \; lint: - ./gradlew $(LINT_TASK)Release + ./gradlew -PndkCustomPath=$(ANDROID_NDK_FULLPATH) $(LINT_TASK)Release clean: @echo "Cleaning binaries, assets and LuaJIT build" diff --git a/app/build.gradle b/app/build.gradle index 1dc829f8b..d57267da2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -23,9 +23,14 @@ android { sourceSets { main { assets.srcDirs = [ '../assets' ] + jniLibs.srcDirs = [ '../libs' ] } } + dependenciesInfo { + includeInApk = false + } + externalNativeBuild { ndkBuild { path file('../jni/Android.mk') @@ -83,11 +88,19 @@ android { compileOptions { coreLibraryDesugaringEnabled true - kotlinOptions.freeCompilerArgs += ['-module-name', projectName.toLowerCase()] } packagingOptions { - exclude 'META-INF/*.version' + exclude '/kotlin/**.kotlin_builtins' + exclude '/kotlin/**.kotlin_metadata' + exclude '/META-INF/**.kotlin_module' + exclude '/META-INF/**.version' + } + + lintOptions { + xmlReport false + htmlReport false + disable 'QueryAllPackagesPermission' } applicationVariants.all { variant -> diff --git a/app/src/debug/res/mipmap-anydpi-v26/icon.xml b/app/src/debug/res/mipmap-anydpi-v26/icon.xml index f81c67bdb..999ffb5f2 100644 --- a/app/src/debug/res/mipmap-anydpi-v26/icon.xml +++ b/app/src/debug/res/mipmap-anydpi-v26/icon.xml @@ -1,5 +1,5 @@ - + diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d7d7d5ac7..aa364df2e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -12,15 +12,17 @@ - - + + - + - --> + android:supportsRtl="true" + android:extractNativeLibs="true" > diff --git a/app/src/main/java/org/koreader/launcher/Assets.kt b/app/src/main/java/org/koreader/launcher/Assets.kt index 7f20af02d..773f60a65 100644 --- a/app/src/main/java/org/koreader/launcher/Assets.kt +++ b/app/src/main/java/org/koreader/launcher/Assets.kt @@ -9,6 +9,7 @@ import android.view.Gravity import android.view.ViewGroup import android.widget.ProgressBar import androidx.core.content.ContextCompat +import org.koreader.launcher.extensions.symlink import java.io.* class Assets { @@ -80,6 +81,25 @@ class Assets { return false } } + (assetName == "module/map.txt") -> { + /* Symlink binaries stored as shared libraries */ + val nativeLibsDir = activity.applicationInfo.nativeLibraryDir + activity.assets.open(assetName).bufferedReader().use { text -> + Log.v(tag, "Reading symlinks map from $assetName") + text.forEachLine { line -> + try { + val array = line.split(" ").toTypedArray() + if (array.size == 2) { + val link = "$filesDir/${array[0]}" + val file = "$nativeLibsDir/${array[1]}" + File(file).symlink(link) + } + } catch (e: Exception) { + e.printStackTrace() + } + } + } + } else -> { /* Copy all regular files in assets store */ Log.v(tag, "Extracting $assetName") diff --git a/app/src/main/java/org/koreader/launcher/CrashReportActivity.kt b/app/src/main/java/org/koreader/launcher/CrashReportActivity.kt index ec55683b9..ecadbba07 100644 --- a/app/src/main/java/org/koreader/launcher/CrashReportActivity.kt +++ b/app/src/main/java/org/koreader/launcher/CrashReportActivity.kt @@ -1,6 +1,7 @@ package org.koreader.launcher import android.content.Intent +import android.view.View import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import org.koreader.launcher.databinding.CrashReportBinding @@ -13,25 +14,28 @@ class CrashReportActivity : AppCompatActivity() { intent?.extras?.let { bundle -> binding = CrashReportBinding.inflate(layoutInflater) setContentView(binding.root) - + val log = StringBuilder().append(bundle.get("logs").toString()) + binding.logs.text = log.toString() binding.title.text = bundle.get("title").toString() binding.reason.text = bundle.get("reason").toString() - binding.logs.text = bundle.get("logs").toString() - + if (binding.reason.text.equals("")) { + binding.reason.visibility = View.GONE + } binding.shareReport.setOnClickListener { val intent: Intent = Intent().apply { action = Intent.ACTION_SEND - putExtra(Intent.EXTRA_TEXT, binding.logs.text.toString()) type = "text/plain" + putExtra(Intent.EXTRA_TEXT, log.toString()) } startActivity(Intent.createChooser(intent, - resources.getString(R.string.crash_report_share_button))) + resources.getString(R.string.common_share_rationale))) } } ?: noCrashReportAttachedError() } private fun noCrashReportAttachedError() { - Toast.makeText(this, "No crash report", Toast.LENGTH_LONG).show() + Toast.makeText(this, + resources.getString(R.string.no_crash_attached), Toast.LENGTH_LONG).show() finish() } } diff --git a/app/src/main/java/org/koreader/launcher/EPDTestActivity.kt b/app/src/main/java/org/koreader/launcher/EPDTestActivity.kt index f01194e90..f7a79b434 100644 --- a/app/src/main/java/org/koreader/launcher/EPDTestActivity.kt +++ b/app/src/main/java/org/koreader/launcher/EPDTestActivity.kt @@ -10,10 +10,9 @@ import org.koreader.launcher.device.epd.freescale.NTXEPDController import org.koreader.launcher.device.epd.qualcomm.QualcommEPDController import org.koreader.launcher.device.epd.rockchip.RK30xxEPDController import org.koreader.launcher.device.epd.rockchip.RK33xxEPDController -import java.util.Locale /* A test activity for EPD routines. It can be called from lua using the android.einkTest() function - If the device in question doesn't play nice with the main NativeActivity it can be called from + If the device in question doesn't play nice with the main Activity it can be called from commandline using `adb shell am start -n org.koreader.launcher/.EPDTestActivity` */ class EPDTestActivity : AppCompatActivity() { @@ -43,14 +42,6 @@ class EPDTestActivity : AppCompatActivity() { binding.info.append("Platform: $it\n") } - binding.rk30xxButton.setOnClickListener { - runEinkTest(TEST_RK30XX) - } - - binding.rk33xxButton.setOnClickListener { - runEinkTest(TEST_RK33XX) - } - binding.ntxNewButton.setOnClickListener { runEinkTest(TEST_NTX) } @@ -59,6 +50,14 @@ class EPDTestActivity : AppCompatActivity() { runEinkTest(TEST_QUALCOMM) } + binding.rk30xxButton.setOnClickListener { + runEinkTest(TEST_RK30XX) + } + + binding.rk33xxButton.setOnClickListener { + runEinkTest(TEST_RK33XX) + } + binding.shareButton.setOnClickListener { val intent: Intent = Intent().apply { action = Intent.ACTION_SEND @@ -66,54 +65,49 @@ class EPDTestActivity : AppCompatActivity() { type = "text/plain" } startActivity(Intent.createChooser(intent, - resources.getString(R.string.epd_test_share_button))) + resources.getString(R.string.common_share_rationale))) } } @Suppress("DEPRECATION") private fun runEinkTest(test: Int) { var success = false - binding.info.append(String.format(Locale.US, "run test #%d -> ", test)) try { val v = window.decorView.findViewById(android.R.id.content) when (test) { - TEST_RK30XX -> { - binding.info.append("rk30xx: ") - if (RK30xxEPDController.requestEpdMode(v, "EPD_FULL", true)) - success = true - } - - TEST_RK33XX -> { - binding.info.append("rk33xx: ") - if (RK33xxEPDController.requestEpdMode("EPD_FULL")) - success = true - } - TEST_NTX, TEST_QUALCOMM -> { - // get screen width and height val display = windowManager.defaultDisplay val size = Point() display.getSize(size) - val width = size.x - val height = size.y - if (test == TEST_NTX) { - binding.info.append("tolino: ") - if (NTXEPDController.requestEpdMode(v, 34, 50, 0, 0, width, height)) + binding.info.append("run test for tolino: ") + if (NTXEPDController.requestEpdMode(v, 34, 50, 0, 0, size.x, size.y)) success = true } else if (test == TEST_QUALCOMM) { - binding.info.append("qualcomm: ") - if (QualcommEPDController.requestEpdMode(v, 98, 50, 0, 0, width, height)) + binding.info.append("run test for qualcomm: ") + if (QualcommEPDController.requestEpdMode(v, 98, 50, 0, 0, size.x, size.y)) success = true } } + + TEST_RK30XX -> { + binding.info.append("run test for rk30xx: ") + if (RK30xxEPDController.requestEpdMode(v, "EPD_FULL", true)) + success = true + } + + TEST_RK33XX -> { + binding.info.append("run test for rk33xx: ") + if (RK33xxEPDController.requestEpdMode("EPD_FULL")) + success = true + } } } catch (e: Exception) { e.printStackTrace() } finally { if (success) - binding.info.append("pass\n") + binding.info.append("ok\n") else binding.info.append("fail\n") } diff --git a/app/src/main/java/org/koreader/launcher/Timeout.kt b/app/src/main/java/org/koreader/launcher/Timeout.kt index c7760522b..3b465961c 100644 --- a/app/src/main/java/org/koreader/launcher/Timeout.kt +++ b/app/src/main/java/org/koreader/launcher/Timeout.kt @@ -7,13 +7,14 @@ import android.view.WindowManager import java.util.* class Timeout { + private val tag = this::class.java.simpleName + private var appTimeout: Int = 0 private var systemTimeout: Int = 0 private var alwaysOn: Boolean = false private var customTimeout: Boolean = false companion object { - private const val TAG = "TimeoutHelper" private const val SCREEN_ON_ENABLED = -1 private const val SCREEN_ON_DISABLED = 0 private const val TIMEOUT_MIN = 2 * 60 * 1000 @@ -33,7 +34,7 @@ class Timeout { Settings.System.getInt(activity.applicationContext.contentResolver, Settings.System.SCREEN_OFF_TIMEOUT) } catch (e: Exception) { - Log.w(TAG, e.toString()) + Log.w(tag, e.toString()) 0 } } @@ -45,7 +46,7 @@ class Timeout { customTimeout = true appTimeout = safeTimeout(ms) val mins = toMin(appTimeout) - Log.v(TAG, "applying activity custom timeout: $mins minutes") + Log.v(tag, "applying activity custom timeout: $mins minutes") setSystemScreenOffTimeout(activity, appTimeout) setScreenOn(activity, false) } @@ -79,30 +80,30 @@ class Timeout { val logMsg = if (resumed) "onResume" else "onPause" if (resumed) { systemTimeout = getSystemScreenOffTimeout(activity) - Log.v(TAG, String.format(Locale.US, + Log.v(tag, String.format(Locale.US, "%s: updating system timeout: %s", logMsg, toMin(systemTimeout))) } if (resumed && customTimeout) { if (appTimeout > 0) { - Log.v(TAG, String.format(Locale.US, + Log.v(tag, String.format(Locale.US, "%s: applying custom timeout: %s", logMsg, toMin(appTimeout))) val safe = safeTimeout(appTimeout) setSystemScreenOffTimeout(activity, safe) } else { - Log.w(TAG, "$logMsg: custom timeout is 0, ignoring") + Log.w(tag, "$logMsg: custom timeout is 0, ignoring") } } else if (!resumed && customTimeout) { if (systemTimeout > 0) { - Log.v(TAG, String.format(Locale.US, + Log.v(tag, String.format(Locale.US, "applying system timeout: %s", toMin(systemTimeout))) setSystemScreenOffTimeout(activity, systemTimeout) } else { - Log.w(TAG, "$logMsg: system timeout is 0, ignoring") + Log.w(tag, "$logMsg: system timeout is 0, ignoring") } } else { - Log.v(TAG, logMsg) + Log.v(tag, logMsg) } } @@ -116,12 +117,12 @@ class Timeout { private fun setScreenOn(activity: Activity, enable: Boolean) { if (enable != alwaysOn) { - Log.v(TAG, "screen on: switching to $enable") + Log.v(tag, "screen on: switching to $enable") alwaysOn = enable val flag = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON val action = if (enable) "add" else "clear" activity.runOnUiThread { - Log.v(TAG, "$action FLAG_KEEP_SCREEN_ON") + Log.v(tag, "$action FLAG_KEEP_SCREEN_ON") if (enable) activity.window.addFlags(flag) else activity.window.clearFlags(flag) } } @@ -133,7 +134,7 @@ class Timeout { Settings.System.putInt(activity.applicationContext.contentResolver, Settings.System.SCREEN_OFF_TIMEOUT, timeout) } catch (e: Exception) { - Log.w(TAG, "$e") + Log.w(tag, "$e") } } diff --git a/app/src/main/java/org/koreader/launcher/extensions/FileExtensions.kt b/app/src/main/java/org/koreader/launcher/extensions/FileExtensions.kt index f169ff93d..be649b011 100644 --- a/app/src/main/java/org/koreader/launcher/extensions/FileExtensions.kt +++ b/app/src/main/java/org/koreader/launcher/extensions/FileExtensions.kt @@ -1,11 +1,34 @@ package org.koreader.launcher.extensions +import android.os.Build +import android.system.Os import org.apache.commons.compress.archivers.tar.TarArchiveInputStream import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream import org.apache.commons.compress.compressors.lzma.LZMACompressorInputStream import java.io.* +fun File.symlink(link: String): Boolean { + if (!this.exists()) return false + try { + File(link).delete() + } catch (e: IOException) {} + try { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + Os.symlink(this.absolutePath, link) + return true + } + val os = Class.forName("libcore.io.Libcore").getDeclaredField("os") + os.isAccessible = true + os.get(null).javaClass.getMethod("symlink", String::class.java, + String::class.java).invoke(os, this.absolutePath, link) + return true + } catch (e: Exception) { + e.printStackTrace() + return false + } +} + fun File.uncompress(extract_to: String, deleteIfOk: Boolean = false): Boolean { val success = try { uncompress(this.absolutePath, extract_to) diff --git a/app/src/main/res/layout/crash_report.xml b/app/src/main/res/layout/crash_report.xml index 42b79b235..bf270169c 100644 --- a/app/src/main/res/layout/crash_report.xml +++ b/app/src/main/res/layout/crash_report.xml @@ -4,35 +4,30 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > - - + android:textSize="@dimen/bomb" + android:gravity="top|center_horizontal"/> + android:layout_weight="1"> + android:gravity="start" + android:fontFamily="monospace" + android:layout_marginTop="8sp" + android:layout_marginBottom="8sp" + android:layout_marginLeft="4sp" + android:layout_marginStart="4sp" + android:layout_marginRight="4sp" + android:layout_marginEnd="4sp" /> + android:text="@string/common_share_button" /> diff --git a/app/src/main/res/layout/epd_test.xml b/app/src/main/res/layout/epd_test.xml index 3d18b9f04..216649429 100644 --- a/app/src/main/res/layout/epd_test.xml +++ b/app/src/main/res/layout/epd_test.xml @@ -1,136 +1,87 @@ - - - + - - - - - - - -