Skip to content

Commit

Permalink
Merge pull request #37 from amank22/spx_db_location
Browse files Browse the repository at this point in the history
Db location from user home
  • Loading branch information
amank22 authored Jan 12, 2022
2 parents eeac013 + cc2f599 commit 5689b48
Show file tree
Hide file tree
Showing 13 changed files with 177 additions and 39 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ on:
- 'docs/**'
- '.github/config/labels.yml'

pull_request:
branches:
- main
pull_request:
branches:
- main

workflow_dispatch:
repository_dispatch:
Expand Down
2 changes: 2 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ dependencies {
implementation("org.jetbrains.kotlin:kotlin-reflect:1.6.10")

implementation("io.sentry:sentry-log4j2:5.5.2")
// https://mvnrepository.com/artifact/net.harawata/appdirs
implementation("net.harawata:appdirs:1.2.1")

r8("com.android.tools:r8:3.0.73")
}
Expand Down
4 changes: 2 additions & 2 deletions detekt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,8 @@ complexity:
thresholdInInterfaces: 11
thresholdInObjects: 11
thresholdInEnums: 11
ignoreDeprecated: false
ignorePrivate: false
ignoreDeprecated: true
ignorePrivate: true
ignoreOverridden: false

coroutines:
Expand Down
3 changes: 3 additions & 0 deletions src/main/kotlin/app/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,8 @@ package app
import androidx.compose.ui.window.application

fun main() = application(false) {
val environment = System.getenv("SKIKO_RENDER_API")
val property = System.getProperty("skiko.renderApi")
println("env: $environment render: $property")
appWindow()
}
4 changes: 1 addition & 3 deletions src/main/kotlin/app/MainWindow.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package app

import androidx.compose.runtime.Composable
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.ApplicationScope
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.WindowPlacement
Expand Down Expand Up @@ -30,7 +28,7 @@ fun ApplicationScope.appWindow() {
}
Thread.setDefaultUncaughtExceptionHandler(CustomExceptionHandler())
SentryHelper.init()
val windowState = rememberWindowState(WindowPlacement.Floating, size = DpSize(1440.dp, 1024.dp))
val windowState = rememberWindowState(WindowPlacement.Maximized)
Window(onCloseRequest = onCloseRequest, title = CustomTheme.strings.appName, state = windowState) {
App()
}
Expand Down
12 changes: 7 additions & 5 deletions src/main/kotlin/inputs/adb/ddmlib/AdbHelper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,17 @@ object AdbHelper {
private const val PACKAGES_COMMAND = "pm list packages -3 -e"
// list of lines with format : package:com.ea.games.r3_row

private const val ADB_TIMEOUT = 10L

fun init() {
val options = AdbInitOptions.builder().setClientSupportEnabled(true).build()
AndroidDebugBridge.init(options)
AndroidDebugBridge.addDeviceChangeListener(Devices())
val adbPath = adbPath()
bridge = if (!adbPath.isNullOrBlank()) {
AndroidDebugBridge.createBridge(adbPath, false, 10, TimeUnit.SECONDS)
AndroidDebugBridge.createBridge(adbPath, false, ADB_TIMEOUT, TimeUnit.SECONDS)
} else {
AndroidDebugBridge.createBridge(10, TimeUnit.SECONDS)
AndroidDebugBridge.createBridge(ADB_TIMEOUT, TimeUnit.SECONDS)
}
AndroidDebugBridge.addDebugBridgeChangeListener {
bridge = it
Expand Down Expand Up @@ -112,18 +114,18 @@ object AdbHelper {
suspend fun getPackages(device: IDevice, onValue: (packages: List<String>) -> Unit) = withContext(Dispatchers.IO) {
device.executeShellCommand(
PACKAGES_COMMAND, PackagesReceiver(onValue),
10, TimeUnit.SECONDS
ADB_TIMEOUT, TimeUnit.SECONDS
)
}

private fun IDevice.emptyShellCommand(command: String) {
executeShellCommand(
command,
EmptyReceiver, 10, TimeUnit.SECONDS
EmptyReceiver, ADB_TIMEOUT, TimeUnit.SECONDS
)
}

private fun adbPath(): String? {
fun adbPath(): String? {
val androidEnvHome: File? = try {
System.getenv("ANDROID_HOME") ?: System.getenv("ANDROID_SDK_ROOT")
} catch (e: SecurityException) {
Expand Down
37 changes: 18 additions & 19 deletions src/main/kotlin/storage/Db.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package storage

import models.LogItem
import models.SessionInfo
import org.mapdb.DBMaker
import org.mapdb.HTreeMap
import org.mapdb.Serializer
import storage.serializer.ObjectSerializer
Expand All @@ -11,20 +10,20 @@ object Db {

private const val PREFIX = "Session-"

private val db by lazy {
DBMaker.fileDB("sessions.db").fileMmapEnableIfSupported().checksumHeaderBypass().make()
private val diskDb by lazy {
StorageHelper.createDiskDb()
}

private var session: HTreeMap<String, LogItem>? = null
private var sessionId: String? = null
private val LOCK = Any()

val configs by lazy {
db.hashMap("configs", Serializer.STRING, Serializer.STRING).createOrOpen()
diskDb.hashMap("configs", Serializer.STRING, Serializer.STRING).createOrOpen()
}

private val sessionInfoMap by lazy {
db.hashMap("sessionInfo", Serializer.STRING, ObjectSerializer<SessionInfo>()).createOrOpen()
diskDb.hashMap("sessionInfo", Serializer.STRING, ObjectSerializer<SessionInfo>()).createOrOpen()
}

init {
Expand All @@ -37,14 +36,14 @@ object Db {
return sessionInfoMap[sessionId]
}

fun getAllSessions() = db.getAllNames().filter { it.startsWith(PREFIX) }.sortedBy { getSessionNumber(it) }
fun getAllSessions() = diskDb.getAllNames().filter { it.startsWith(PREFIX) }.sortedBy { getSessionNumber(it) }

fun getLastSessionNumber(): Int {
private fun getLastSessionNumber(): Int {
val lastSessionId = getAllSessions().lastOrNull() ?: sessionIdFromNumber(0)
return getSessionNumber(lastSessionId)
}

fun getPreviousSessionNumber(): Int {
private fun getPreviousSessionNumber(): Int {
val lastDbSessionId = configs["lastSessionId"]
val lastSessionId = if (lastDbSessionId.isNullOrBlank() || !lastDbSessionId.startsWith(PREFIX)) {
getAllSessions().lastOrNull() ?: sessionIdFromNumber(0)
Expand All @@ -54,11 +53,11 @@ object Db {
return getSessionNumber(lastSessionId)
}

fun getSessionNumber(sessionId: String) = sessionId.split("-").lastOrNull()?.toIntOrNull() ?: 0
private fun getSessionNumber(sessionId: String) = sessionId.split("-").lastOrNull()?.toIntOrNull() ?: 0

fun areNoSessionsCreated() = getAllSessions().isEmpty()
private fun areNoSessionsCreated() = getAllSessions().isEmpty()

fun isThisTheOnlySession(sessionId: String): Boolean {
private fun isThisTheOnlySession(sessionId: String): Boolean {
val sessions = getAllSessions()
if (sessions.size != 1) return false
return sessions.first() == sessionId
Expand All @@ -78,12 +77,12 @@ object Db {
} else if (sessionId == sessionId()) {
changeSession(null)
}
val oldSession = db.hashMap(sessionId, Serializer.STRING, ObjectSerializer<LogItem>())
val oldSession = diskDb.hashMap(sessionId, Serializer.STRING, ObjectSerializer<LogItem>())
.open()
oldSession.clear()
sessionInfoMap.remove(sessionId)
val recIds = arrayListOf<Long>()
db.nameCatalogParamsFor(sessionId).forEach { (t, u) ->
diskDb.nameCatalogParamsFor(sessionId).forEach { (t, u) ->
if (t.endsWith("rootRecids")) {
u.split(",").forEach { value ->
val recId = value.trim().toLongOrNull()
Expand All @@ -93,15 +92,15 @@ object Db {
}
}
recIds.forEach {
db.getStore().delete(it, Serializer.STRING)
diskDb.getStore().delete(it, Serializer.STRING)
}
val newCatalog = db.nameCatalogLoad()
val newCatalog = diskDb.nameCatalogLoad()
val keys = newCatalog.keys.filter { it.startsWith(sessionId) }
keys.forEach {
newCatalog.remove(it)
}
db.nameCatalogSave(newCatalog)
db.commit()
diskDb.nameCatalogSave(newCatalog)
diskDb.commit()
}

fun changeSession(sessionId: String?) {
Expand All @@ -123,7 +122,7 @@ object Db {
}
if (sessionNumber < 1) throw Exception("Session number must be greater than 1")
val sessionId = sessionIdFromNumber(sessionNumber)
val session = db
val session = diskDb
.hashMap(sessionId, Serializer.STRING, ObjectSerializer<LogItem>())
.createOrOpen()
this.sessionId = sessionId
Expand All @@ -143,6 +142,6 @@ object Db {
}

fun close() {
db.close()
diskDb.close()
}
}
61 changes: 61 additions & 0 deletions src/main/kotlin/storage/StorageHelper.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package storage

import com.voxfinite.logvue.APP_NAME
import net.harawata.appdirs.AppDirsFactory
import org.mapdb.DB
import org.mapdb.DBException
import org.mapdb.DBMaker
import utils.DbCreationException
import utils.reportException
import java.io.File
import java.io.IOException
import java.nio.file.FileSystems
import java.nio.file.Files
import java.nio.file.attribute.PosixFilePermissions


object StorageHelper {

internal fun createDiskDb(): DB {
val dbFile = getDbFile()
return try {
DBMaker.fileDB(dbFile).fileMmapEnableIfSupported().checksumHeaderBypass().make()
} catch (e: DBException.VolumeIOError) {
DbCreationException("Mmap enabled db could not be created", e).reportException()
try {
DBMaker.fileDB(dbFile).fileChannelEnable().checksumHeaderBypass().make()
} catch (ee: DBException.VolumeIOError) {
DbCreationException("file channel enabled db could not be created", ee).reportException()
DBMaker.fileDB(dbFile).checksumHeaderBypass().make()
}
}
}

@Throws(IOException::class)
private fun getDbFile(): File {
val appDirs = AppDirsFactory.getInstance()
val dataDir = appDirs.getUserDataDir(APP_NAME, null, APP_NAME)
val folder = File(dataDir)
if (!folder.exists() || !folder.isDirectory) {
if (folder.exists()) {
folder.delete()
}
try {
val isPosix = FileSystems.getDefault().supportedFileAttributeViews().contains("posix")
if (isPosix) {
val posixAttribute = PosixFilePermissions.asFileAttribute(
PosixFilePermissions.fromString("rwxr-x---")
)
Files.createDirectories(folder.toPath(), posixAttribute)
} else {
Files.createDirectories(folder.toPath())
}
} catch (e: IOException) {
throw IOException("Cannot create app folder at path ${folder.canonicalPath}", e)
}
}
val dbName = "sessions.db"
return File(dataDir, dbName)
}

}
1 change: 1 addition & 0 deletions src/main/kotlin/utils/CustomExceptionHandler.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ class CustomExceptionHandler : Thread.UncaughtExceptionHandler {
override fun uncaughtException(t: Thread?, e: Throwable?) {
e?.printStackTrace()
setCrashed()
throw e ?: Exception("Unknown exception")
}

companion object {
Expand Down
8 changes: 8 additions & 0 deletions src/main/kotlin/utils/DbCreationException.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package utils

class DbCreationException : Exception {
constructor() : super()
constructor(message: String) : super(message)
constructor(message: String, cause: Throwable) : super(message, cause)
constructor(cause: Throwable) : super(cause)
}
8 changes: 1 addition & 7 deletions src/main/kotlin/utils/Helpers.kt
Original file line number Diff line number Diff line change
Expand Up @@ -276,16 +276,10 @@ object Helpers {
return takeValue
}

fun isWindows(): Boolean {
val os = System.getProperty("os.name").lowercase(Locale.getDefault())
// windows
return os.indexOf("win") >= 0
}

fun openFileExplorer(path: Path) {
try {
val pathString = path.absolutePathString()
val command = if (isWindows()) {
val command = if (SystemTools.getOS() == OsWindows) {
"Explorer.exe $pathString"
} else {
"open $pathString"
Expand Down
48 changes: 48 additions & 0 deletions src/main/kotlin/utils/Renderer.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package utils

import org.jetbrains.skiko.GraphicsApi
import org.jetbrains.skiko.OS
import org.jetbrains.skiko.hostOs

object Renderer {

// private const val RENDER_API_KEY = "skiko.renderApi"

// fun setRender() {
// when(SystemTools.getOS()) {
// OsWindows, OsLinux -> {
// System.setProperty(RENDER_API_KEY, "OPENGL")
// }
// OsMac -> {
//
// }
// }
// }

internal fun parseRenderApi(text: String?): GraphicsApi {
return when (text) {
"SOFTWARE_COMPAT" -> GraphicsApi.SOFTWARE_COMPAT
"SOFTWARE_FAST", "DIRECT_SOFTWARE", "SOFTWARE" -> GraphicsApi.SOFTWARE_FAST
"OPENGL" -> GraphicsApi.OPENGL
"DIRECT3D" -> {
if (hostOs == OS.Windows) GraphicsApi.DIRECT3D
else throw UnsupportedOperationException("$hostOs does not support DirectX rendering API.")
}
"METAL" -> {
if (hostOs == OS.MacOS) GraphicsApi.METAL
else throw UnsupportedOperationException("$hostOs does not support Metal rendering API.")
}
else -> bestRenderApiForCurrentOS()
}
}

private fun bestRenderApiForCurrentOS(): GraphicsApi {
return when (hostOs) {
OS.MacOS -> GraphicsApi.METAL
OS.Linux -> GraphicsApi.OPENGL
OS.Windows -> GraphicsApi.DIRECT3D
OS.JS, OS.Ios -> TODO("commonize me")
}
}

}
22 changes: 22 additions & 0 deletions src/main/kotlin/utils/SystemTools.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package utils

import java.util.*

object SystemTools {

fun getOS(): OS {
val os = System.getProperty("os.name").lowercase(Locale.getDefault())
return when {
os.contains("window") -> OsWindows
os.contains("nix") || os.contains("nux") || os.contains("aix") -> OsLinux
os.contains("os x") || os.contains("mac") -> OsMac
else -> throw UnsupportedOperationException("Operating system $os is not supported")
}
}

}

sealed interface OS
object OsWindows : OS
object OsLinux : OS
object OsMac : OS

0 comments on commit 5689b48

Please sign in to comment.