From dd1ccc6259059b20608a103f0962b0f46cbae971 Mon Sep 17 00:00:00 2001 From: Matthew Nelson Date: Sat, 2 Mar 2024 07:43:32 -0500 Subject: [PATCH] Fix SysTempDir for Android API 15 and below --- .../test/android/SysTempDirAndroidTest.kt | 32 +++++++++++++ .../kmp/file/internal/-JvmPlatform.kt | 46 +++++++++++++++++-- 2 files changed, 74 insertions(+), 4 deletions(-) create mode 100644 library/file-test-android/src/androidInstrumentedTest/kotlin/io/matthewnelson/kmp/file/test/android/SysTempDirAndroidTest.kt diff --git a/library/file-test-android/src/androidInstrumentedTest/kotlin/io/matthewnelson/kmp/file/test/android/SysTempDirAndroidTest.kt b/library/file-test-android/src/androidInstrumentedTest/kotlin/io/matthewnelson/kmp/file/test/android/SysTempDirAndroidTest.kt new file mode 100644 index 0000000..e8a20f5 --- /dev/null +++ b/library/file-test-android/src/androidInstrumentedTest/kotlin/io/matthewnelson/kmp/file/test/android/SysTempDirAndroidTest.kt @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2024 Matthew Nelson + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +package io.matthewnelson.kmp.file.test.android + +import android.app.Application +import androidx.test.core.app.ApplicationProvider +import io.matthewnelson.kmp.file.SysTempDir +import kotlin.test.Test +import kotlin.test.assertEquals + +class SysTempDirAndroidTest { + + private val ctx = ApplicationProvider.getApplicationContext() + + @Test + fun givenAndroidRuntime_whenSysTempDir_thenIsSameAsCacheDir() { + assertEquals(ctx.cacheDir, SysTempDir) + } +} diff --git a/library/file/src/jvmMain/kotlin/io/matthewnelson/kmp/file/internal/-JvmPlatform.kt b/library/file/src/jvmMain/kotlin/io/matthewnelson/kmp/file/internal/-JvmPlatform.kt index 72bf32e..f4bded4 100644 --- a/library/file/src/jvmMain/kotlin/io/matthewnelson/kmp/file/internal/-JvmPlatform.kt +++ b/library/file/src/jvmMain/kotlin/io/matthewnelson/kmp/file/internal/-JvmPlatform.kt @@ -15,9 +15,11 @@ **/ package io.matthewnelson.kmp.file.internal +import io.matthewnelson.kmp.file.ANDROID import io.matthewnelson.kmp.file.IOException import io.matthewnelson.kmp.file.toFile import java.io.File +import kotlin.io.resolve import kotlin.io.readText as _readText import kotlin.io.readBytes as _readBytes import kotlin.io.resolve as _resolve @@ -27,10 +29,46 @@ import kotlin.io.writeText as _writeText @Suppress("NOTHING_TO_INLINE") internal actual inline fun platformDirSeparator(): Char = File.separatorChar -@Suppress("NOTHING_TO_INLINE") -internal actual inline fun platformTempDirectory(): File = System - .getProperty("java.io.tmpdir") - .toFile() +@Suppress("NOTHING_TO_INLINE", "SdCardPath") +internal actual inline fun platformTempDirectory(): File { + val jTemp = System + .getProperty("java.io.tmpdir") + .toFile() + + return ANDROID.SDK_INT?.let { sdk -> + if (sdk > 15) return@let null + + // java.io.tmpdir=/sdcard + if ( + !jTemp.path.startsWith("/data") + || jTemp.path.startsWith("/sdcard") + ) { + // dexmaker.dexcache=/data/data/com.example.app/app_dxmaker_cache + val parent = System.getProperty("dexmaker.dexcache") + ?.toFile() + ?.parentFile + ?: return@let null + + try { + if (!parent.exists()) return@let null + } catch (_: Throwable) { + return@let null + } + + val cacheDir = parent.resolve("cache") + + try { + if (!cacheDir.exists() && !cacheDir.mkdirs()) return@let null + } catch (_: Throwable) { + return@let null + } + + cacheDir + } else { + null + } + } ?: jTemp +} internal actual val IsWindows: Boolean = System.getProperty("os.name") ?.ifBlank { null }