feat: in-app test file generator for upload testing
adb-pushed files are invisible to the app due to scoped storage, so add a 'Create 120 MB test file' button in the Downloads tab that writes the file through the app's own uid (visible in its contribution set).
This commit is contained in:
@@ -19,7 +19,9 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.asSharedFlow
|
import kotlinx.coroutines.flow.asSharedFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import retrofit2.Retrofit
|
import retrofit2.Retrofit
|
||||||
import retrofit2.converter.kotlinx.serialization.asConverterFactory
|
import retrofit2.converter.kotlinx.serialization.asConverterFactory
|
||||||
import okhttp3.MediaType.Companion.toMediaType
|
import okhttp3.MediaType.Companion.toMediaType
|
||||||
@@ -257,6 +259,24 @@ class DashcamViewModel(application: Application) : AndroidViewModel(application)
|
|||||||
_downloadedFiles.value = files
|
_downloadedFiles.value = files
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun generateTestFile(sizeMb: Int = 120) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
val f = File(getDownloadDir(), "test-upload-${sizeMb}mb.mp4")
|
||||||
|
try {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
f.outputStream().use { out ->
|
||||||
|
val buf = ByteArray(1 shl 20) // 1MB
|
||||||
|
repeat(sizeMb) { out.write(buf) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scanDownloads()
|
||||||
|
_downloadEvents.emit("✓ Created test file: ${f.name} (${sizeMb} MB)")
|
||||||
|
} catch (e: Exception) {
|
||||||
|
_downloadEvents.emit("✗ Could not create test file: ${e.message}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun deleteDownloaded(file: DownloadedFile) {
|
fun deleteDownloaded(file: DownloadedFile) {
|
||||||
_deletingNames.value = _deletingNames.value + file.name
|
_deletingNames.value = _deletingNames.value + file.name
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ fun DownloadsScreen(
|
|||||||
onCancel: (ActiveDownload) -> Unit,
|
onCancel: (ActiveDownload) -> Unit,
|
||||||
onUpload: (DownloadedFile) -> Unit,
|
onUpload: (DownloadedFile) -> Unit,
|
||||||
onCancelUpload: (ActiveDownload) -> Unit,
|
onCancelUpload: (ActiveDownload) -> Unit,
|
||||||
|
onGenerateTestFile: () -> Unit,
|
||||||
onRefresh: () -> Unit,
|
onRefresh: () -> Unit,
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
@@ -83,6 +84,15 @@ fun DownloadsScreen(
|
|||||||
Text("Downloads", style = MaterialTheme.typography.titleLarge, color = MaterialTheme.colorScheme.primary)
|
Text("Downloads", style = MaterialTheme.typography.titleLarge, color = MaterialTheme.colorScheme.primary)
|
||||||
Spacer(Modifier.height(4.dp))
|
Spacer(Modifier.height(4.dp))
|
||||||
Text("${files.size} files · Movies/yaris-obd/", style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onSurfaceVariant)
|
Text("${files.size} files · Movies/yaris-obd/", style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onSurfaceVariant)
|
||||||
|
Spacer(Modifier.height(10.dp))
|
||||||
|
Button(
|
||||||
|
onClick = onGenerateTestFile,
|
||||||
|
modifier = Modifier.height(34.dp),
|
||||||
|
shape = RoundedCornerShape(8.dp),
|
||||||
|
contentPadding = PaddingValues(horizontal = 12.dp, vertical = 0.dp)
|
||||||
|
) {
|
||||||
|
Text("Create 120 MB test file", style = MaterialTheme.typography.bodySmall)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ fun YarisMainScreen(client: OkHttpClient) {
|
|||||||
onCancel = { dashcamVm.cancelDownload(it) },
|
onCancel = { dashcamVm.cancelDownload(it) },
|
||||||
onUpload = { dashcamVm.uploadFile(it) },
|
onUpload = { dashcamVm.uploadFile(it) },
|
||||||
onCancelUpload = { dashcamVm.cancelUpload(it) },
|
onCancelUpload = { dashcamVm.cancelUpload(it) },
|
||||||
|
onGenerateTestFile = { dashcamVm.generateTestFile() },
|
||||||
onRefresh = { dashcamVm.scanDownloads() },
|
onRefresh = { dashcamVm.scanDownloads() },
|
||||||
)
|
)
|
||||||
2 -> SettingsScreen(client = client)
|
2 -> SettingsScreen(client = client)
|
||||||
|
|||||||
Reference in New Issue
Block a user