Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ android {
// https://developer.android.com/ndk/downloads
ndkVersion = "22.1.7171670"

lint {
disable += setOf("ExtraTranslation", "ExpiredTargetSdkVersion")
}

signingConfigs {
create("pluvia") {
if (keystoreProperties != null) {
Expand Down Expand Up @@ -115,18 +119,18 @@ android {
signingConfig = signingConfigs.getByName("debug")
}
release {
isMinifyEnabled = true
isShrinkResources = true
isMinifyEnabled = false
isShrinkResources = false
signingConfig = signingConfigs.getByName("debug")
}
create("release-signed") {
isMinifyEnabled = true
isShrinkResources = true
isMinifyEnabled = false
isShrinkResources = false
signingConfig = signingConfigs.getByName("pluvia")
}
create("release-gold") {
isMinifyEnabled = true
isShrinkResources = true
isMinifyEnabled = false
isShrinkResources = false
signingConfig = signingConfigs.getByName("pluvia")
Comment on lines 121 to 134

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid disabling minify/shrink on all release variants by default.

Applying this to every release-like build type increases artifact size and weakens release hardening. Gate it behind an explicit OSS/dev flag instead.

Suggested fix pattern
+val ossFastBuild = (project.findProperty("ossFastBuild") as String?)?.toBoolean() == true
 ...
         release {
-            isMinifyEnabled = false
-            isShrinkResources = false
+            isMinifyEnabled = !ossFastBuild
+            isShrinkResources = !ossFastBuild
         }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/build.gradle.kts` around lines 121 - 134, The release build types
('release', 'release-signed', 'release-gold') currently disable minification and
resource shrinking by default; change this so minify/shrink remain enabled for
real releases and only get disabled when an explicit Gradle flag/property is set
(e.g., project property like "skipReleaseMinify" or a gradle.properties key).
Update the blocks that set isMinifyEnabled and isShrinkResources to read that
property (default false meaning do not skip minify) and only set them to false
when the property is explicitly true; keep the existing signingConfig
assignments (signingConfigs.getByName("debug") / "pluvia") unchanged. Ensure the
flag is documented in the repo's README or gradle.properties so CI/oss/dev
builds can opt out without affecting normal release hardening.

applicationIdSuffix = ".gold"
buildConfigField("boolean", "GOLD", "true")
Expand Down Expand Up @@ -219,7 +223,7 @@ dependencies {
implementation("androidx.browser:browser:1.8.0")

// JavaSteam
val localBuild = false // Change to 'true' needed when building JavaSteam manually
val localBuild = true // Change to 'true' needed when building JavaSteam manually

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Accidentally committed local build configuration: localBuild is hardcoded to true, forcing dependency resolution from local relative JAR paths that won't exist on CI or other machines

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At app/build.gradle.kts, line 226:

<comment>Accidentally committed local build configuration: `localBuild` is hardcoded to `true`, forcing dependency resolution from local relative JAR paths that won't exist on CI or other machines</comment>

<file context>
@@ -219,7 +223,7 @@ dependencies {
 
     // JavaSteam
-    val localBuild = false // Change to 'true' needed when building JavaSteam manually
+    val localBuild = true // Change to 'true' needed when building JavaSteam manually
     if (localBuild) {
         implementation(files("../../JavaSteam/build/libs/javasteam-1.8.0.1-18-SNAPSHOT.jar"))
</file context>
Suggested change
val localBuild = true // Change to 'true' needed when building JavaSteam manually
- val localBuild = true // Change to 'true' needed when building JavaSteam manually
+ val localBuild = false // Change to 'true' needed when building JavaSteam manually

if (localBuild) {
implementation(files("../../JavaSteam/build/libs/javasteam-1.8.0.1-18-SNAPSHOT.jar"))
implementation(files("../../JavaSteam/javasteam-depotdownloader/build/libs/javasteam-depotdownloader-1.8.0.1-18-SNAPSHOT.jar"))
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"id":3,"name":"Virtual Gamepad","cursorSpeed":1,"elements":[{"type":"D_PAD","shape":"CIRCLE","bindings":["GAMEPAD_DPAD_UP","GAMEPAD_DPAD_RIGHT","GAMEPAD_DPAD_DOWN","GAMEPAD_DPAD_LEFT"],"scale":0.85,"x":0.10784313827753067,"y":0.4,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"CIRCLE","bindings":["GAMEPAD_BUTTON_X","NONE","NONE","NONE"],"scale":1,"x":0.8133170008659363,"y":0.4,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"CIRCLE","bindings":["GAMEPAD_BUTTON_Y","NONE","NONE","NONE"],"scale":1,"x":0.8721405267715454,"y":0.2666666746,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"CIRCLE","bindings":["GAMEPAD_BUTTON_A","NONE","NONE","NONE"],"scale":1,"x":0.8721405267715454,"y":0.5333333254,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"CIRCLE","bindings":["GAMEPAD_BUTTON_B","NONE","NONE","NONE"],"scale":1,"x":0.9309640526771545,"y":0.4,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"RECT","bindings":["GAMEPAD_BUTTON_R2","NONE","NONE","NONE"],"scale":2,"x":0.93,"y":0.07,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"RECT","bindings":["GAMEPAD_BUTTON_R1","NONE","NONE","NONE"],"scale":1,"x":0.97,"y":0.2222222388,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"RECT","bindings":["GAMEPAD_BUTTON_L1","NONE","NONE","NONE"],"scale":1,"x":0.03,"y":0.2222222388,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"RECT","bindings":["GAMEPAD_BUTTON_L2","NONE","NONE","NONE"],"scale":2,"x":0.07,"y":0.07,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"ROUND_RECT","bindings":["GAMEPAD_BUTTON_START","NONE","NONE","NONE"],"scale":0.85,"x":0.538807213306427,"y":0.9111111164093018,"toggleSwitch":false,"text":"","iconId":15},{"type":"BUTTON","shape":"ROUND_RECT","bindings":["GAMEPAD_BUTTON_SELECT","NONE","NONE","NONE"],"scale":0.85,"x":0.46078431606292725,"y":0.9111111164093018,"toggleSwitch":false,"text":"","iconId":16},{"type":"STICK","shape":"CIRCLE","bindings":["GAMEPAD_LEFT_THUMB_UP","GAMEPAD_LEFT_THUMB_RIGHT","GAMEPAD_LEFT_THUMB_DOWN","GAMEPAD_LEFT_THUMB_LEFT"],"scale":1,"x":0.21568627655506134,"y":0.7333333492279053,"toggleSwitch":false,"text":"","iconId":0},{"type":"STICK","shape":"CIRCLE","bindings":["GAMEPAD_RIGHT_THUMB_UP","GAMEPAD_RIGHT_THUMB_RIGHT","GAMEPAD_RIGHT_THUMB_DOWN","GAMEPAD_RIGHT_THUMB_LEFT"],"scale":1,"x":0.7843137383460999,"y":0.7333333492279053,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"CIRCLE","bindings":["GAMEPAD_BUTTON_L3","NONE","NONE","NONE"],"scale":0.85,"x":0.05,"y":0.7333333492279053,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"CIRCLE","bindings":["GAMEPAD_BUTTON_R3","NONE","NONE","NONE"],"scale":0.85,"x":0.95,"y":0.7333333492279053,"toggleSwitch":false,"text":"","iconId":0}]}
{"id":3,"name":"Virtual Gamepad","cursorSpeed":1,"elements":[{"type":"D_PAD","shape":"CIRCLE","bindings":["GAMEPAD_DPAD_UP","GAMEPAD_DPAD_RIGHT","GAMEPAD_DPAD_DOWN","GAMEPAD_DPAD_LEFT"],"scale":0.85,"x":0.10784313827753067,"y":0.4,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"CIRCLE","bindings":["GAMEPAD_BUTTON_X","GAMEPAD_BUTTON_X","NONE","NONE"],"scale":1,"x":0.8133170008659363,"y":0.4,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"CIRCLE","bindings":["GAMEPAD_BUTTON_Y","GAMEPAD_BUTTON_Y","NONE","NONE"],"scale":1,"x":0.8721405267715454,"y":0.2666666746,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"CIRCLE","bindings":["GAMEPAD_BUTTON_A","GAMEPAD_BUTTON_A","NONE","NONE"],"scale":1,"x":0.8721405267715454,"y":0.5333333254,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"CIRCLE","bindings":["GAMEPAD_BUTTON_B","GAMEPAD_BUTTON_B","NONE","NONE"],"scale":1,"x":0.9309640526771545,"y":0.4,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"RECT","bindings":["GAMEPAD_BUTTON_R2","GAMEPAD_BUTTON_R2","NONE","NONE"],"scale":2,"x":0.93,"y":0.07,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"RECT","bindings":["GAMEPAD_BUTTON_R1","GAMEPAD_BUTTON_R1","NONE","NONE"],"scale":1,"x":0.97,"y":0.2222222388,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"RECT","bindings":["GAMEPAD_BUTTON_L1","GAMEPAD_BUTTON_L1","NONE","NONE"],"scale":1,"x":0.03,"y":0.2222222388,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"RECT","bindings":["GAMEPAD_BUTTON_L2","GAMEPAD_BUTTON_L2","NONE","NONE"],"scale":2,"x":0.07,"y":0.07,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"ROUND_RECT","bindings":["GAMEPAD_BUTTON_START","GAMEPAD_BUTTON_START","NONE","NONE"],"scale":0.85,"x":0.538807213306427,"y":0.9111111164093018,"toggleSwitch":false,"text":"","iconId":15},{"type":"BUTTON","shape":"ROUND_RECT","bindings":["GAMEPAD_BUTTON_SELECT","GAMEPAD_BUTTON_SELECT","NONE","NONE"],"scale":0.85,"x":0.46078431606292725,"y":0.9111111164093018,"toggleSwitch":false,"text":"","iconId":16},{"type":"STICK","shape":"CIRCLE","bindings":["GAMEPAD_LEFT_THUMB_UP","GAMEPAD_LEFT_THUMB_RIGHT","GAMEPAD_LEFT_THUMB_DOWN","GAMEPAD_LEFT_THUMB_LEFT"],"scale":1,"x":0.21568627655506134,"y":0.7333333492279053,"toggleSwitch":false,"text":"","iconId":0},{"type":"STICK","shape":"CIRCLE","bindings":["GAMEPAD_RIGHT_THUMB_UP","GAMEPAD_RIGHT_THUMB_RIGHT","GAMEPAD_RIGHT_THUMB_DOWN","GAMEPAD_RIGHT_THUMB_LEFT"],"scale":1,"x":0.7843137383460999,"y":0.7333333492279053,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"CIRCLE","bindings":["GAMEPAD_BUTTON_L3","GAMEPAD_BUTTON_L3","NONE","NONE"],"scale":0.85,"x":0.05,"y":0.7333333492279053,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"CIRCLE","bindings":["GAMEPAD_BUTTON_R3","GAMEPAD_BUTTON_R3","NONE","NONE"],"scale":0.85,"x":0.95,"y":0.7333333492279053,"toggleSwitch":false,"text":"","iconId":0}]}
14 changes: 14 additions & 0 deletions app/src/main/java/app/gamenative/data/DownloadInfo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ data class DownloadInfo(
private var hasEmaSpeed: Boolean = false
private var isActive: Boolean = true
private val statusMessage = MutableStateFlow<String?>(null)
private val downloadLog = MutableStateFlow<List<String>>(emptyList())
private val postInstallSyncing = MutableStateFlow(false)

fun cancel() {
Expand Down Expand Up @@ -142,6 +143,19 @@ data class DownloadInfo(

fun getStatusMessageFlow(): StateFlow<String?> = statusMessage

fun appendLog(message: String) {
val timestamp = java.text.SimpleDateFormat("HH:mm:ss", java.util.Locale.getDefault()).format(java.util.Date())
downloadLog.value = downloadLog.value + "[$timestamp] $message"
// Keep last 500 entries to avoid memory issues
if (downloadLog.value.size > 500) {
downloadLog.value = downloadLog.value.takeLast(500)
}
// Also update the single status message for backward compatibility
statusMessage.value = message
}

fun getDownloadLogFlow(): StateFlow<List<String>> = downloadLog

fun setPostInstallSyncing(syncing: Boolean) {
postInstallSyncing.value = syncing
}
Expand Down
48 changes: 40 additions & 8 deletions app/src/main/java/app/gamenative/service/SteamService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import app.gamenative.enums.SaveLocation
import app.gamenative.enums.SyncResult
import app.gamenative.events.AndroidEvent
import app.gamenative.events.SteamEvent
import app.gamenative.utils.DownloadLogger
import app.gamenative.utils.CaseInsensitiveFileSystem
import app.gamenative.utils.ContainerUtils
import app.gamenative.utils.FileUtils
Expand Down Expand Up @@ -116,8 +117,6 @@ import `in`.dragonbra.javasteam.types.FileData
import `in`.dragonbra.javasteam.types.KeyValue
import `in`.dragonbra.javasteam.types.PublishedFileID
import `in`.dragonbra.javasteam.types.SteamID
import `in`.dragonbra.javasteam.util.log.LogListener
import `in`.dragonbra.javasteam.util.log.LogManager
import java.io.Closeable
import java.io.File
import java.io.IOException
Expand Down Expand Up @@ -184,7 +183,7 @@ import java.nio.ByteOrder
class SteamService : Service(), IChallengeUrlChanged {

// To view log messages in android logcat properly
private val logger = object : LogListener {
private val logger = object : `in`.dragonbra.javasteam.util.log.LogListener {
override fun onLog(clazz: Class<*>, message: String?, throwable: Throwable?) {
val logMessage = message ?: "No message given"
Timber.i(throwable, "[${clazz.simpleName}] -> $logMessage")
Expand Down Expand Up @@ -1768,6 +1767,35 @@ class SteamService : Service(), IChallengeUrlChanged {
Timber.i("maxDownloads: $maxDownloads")
Timber.i("maxDecompress: $maxDecompress")

// Register a log listener to capture JavaSteam internal logs
val logListenerActive = java.util.concurrent.atomic.AtomicBoolean(true)
val logListener = object : `in`.dragonbra.javasteam.util.log.LogListener {
override fun onLog(clazz: Class<*>, message: String?, throwable: Throwable?) {
if (!logListenerActive.get()) return
val prefix = clazz.simpleName
message?.let { DownloadLogger.append(appId, "[$prefix] $it") }
throwable?.let { DownloadLogger.append(appId, "[$prefix] ${it.message ?: it.javaClass.simpleName}") }
}
override fun onError(clazz: Class<*>, message: String?, throwable: Throwable?) {
if (!logListenerActive.get()) return
val prefix = clazz.simpleName
message?.let { DownloadLogger.append(appId, "[$prefix] ERROR: $it") }
throwable?.let { DownloadLogger.append(appId, "[$prefix] ERROR: ${it.message ?: it.javaClass.simpleName}") }
}
}

// Clear previous download log BEFORE registering listener (avoid race)
DownloadLogger.clear(appId)

`in`.dragonbra.javasteam.util.log.LogManager.addListener(logListener)

// Guaranteed cleanup: remove listener when the download coroutine completes
val downloadCleanup = {
logListenerActive.set(false)
`in`.dragonbra.javasteam.util.log.LogManager.removeListener(logListener)
}
coroutineContext[Job]?.invokeOnCompletion { downloadCleanup() }
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
Comment on lines +1770 to +1797

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Per-game log capture is still wired to a process-global log stream.

At Line 1790, this listener subscribes to LogManager, so it will receive all JavaSteam log events, not just the DepotDownloader started by this coroutine. Since downloadJobs allows multiple active downloads, concurrent downloads will append the same global log stream into different DownloadLogger files, which breaks the new “per-game” viewer semantics.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/main/java/app/gamenative/service/SteamService.kt` around lines 1770 -
1797, The listener currently added via LogManager.addListener (LogListener
implemented in the block using logListenerActive and methods onLog/onError) will
receive all JavaSteam events; restrict it so it only appends messages for the
current download before calling DownloadLogger.append. Modify the onLog and
onError implementations to filter events (e.g., check clazz.simpleName or
clazz.packageName and/or inspect message content for the current appId/depot id
or a DepotDownloader-specific marker) and return early for unrelated events,
keeping the existing downloadCleanup (removeListener and logListenerActive)
behavior unchanged; ensure the check uses the same appId/depot identifier
available in this coroutine so concurrent downloads do not mix logs.


// Create DepotDownloader instance
val depotDownloader = DepotDownloader(
instance!!.steamClient!!,
Expand Down Expand Up @@ -2144,30 +2172,34 @@ class SteamService : Service(), IChallengeUrlChanged {

override fun onDownloadStarted(item: DownloadItem) {
Timber.i("Item ${item.appId} download started")
DownloadLogger.append(downloadInfo.gameId, "Download started for app ${item.appId}")
}

override fun onDownloadCompleted(item: DownloadItem) {
Timber.i("Item ${item.appId} download completed")
DownloadLogger.append(downloadInfo.gameId, "Download completed")
DownloadLogger.flush(downloadInfo.gameId)
}

override fun onDownloadFailed(item: DownloadItem, error: Throwable) {
Timber.e(error, "Item ${item.appId} failed to download")
DownloadLogger.append(downloadInfo.gameId, "FAILED: ${error.message ?: error.javaClass.simpleName}")
DownloadLogger.flush(downloadInfo.gameId)
Comment on lines 2178 to +2187

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Keep item identity in the completion/failure log lines.

Line 2175 includes item.appId, but Lines 2180 and 2186 drop it. For base-game + DLC downloads, the viewer will show indistinguishable Download completed / FAILED entries.

✏️ Proposed fix
 override fun onDownloadCompleted(item: DownloadItem) {
     Timber.i("Item ${item.appId} download completed")
-    DownloadLogger.append(downloadInfo.gameId, "Download completed")
+    DownloadLogger.append(downloadInfo.gameId, "Download completed for app ${item.appId}")
     DownloadLogger.flush(downloadInfo.gameId)
 }

 override fun onDownloadFailed(item: DownloadItem, error: Throwable) {
     Timber.e(error, "Item ${item.appId} failed to download")
-    DownloadLogger.append(downloadInfo.gameId, "FAILED: ${error.message ?: error.javaClass.simpleName}")
+    DownloadLogger.append(
+        downloadInfo.gameId,
+        "FAILED for app ${item.appId}: ${error.message ?: error.javaClass.simpleName}",
+    )
     DownloadLogger.flush(downloadInfo.gameId)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
override fun onDownloadCompleted(item: DownloadItem) {
Timber.i("Item ${item.appId} download completed")
DownloadLogger.append(downloadInfo.gameId, "Download completed")
DownloadLogger.flush(downloadInfo.gameId)
}
override fun onDownloadFailed(item: DownloadItem, error: Throwable) {
Timber.e(error, "Item ${item.appId} failed to download")
DownloadLogger.append(downloadInfo.gameId, "FAILED: ${error.message ?: error.javaClass.simpleName}")
DownloadLogger.flush(downloadInfo.gameId)
override fun onDownloadCompleted(item: DownloadItem) {
Timber.i("Item ${item.appId} download completed")
DownloadLogger.append(downloadInfo.gameId, "Download completed for app ${item.appId}")
DownloadLogger.flush(downloadInfo.gameId)
}
override fun onDownloadFailed(item: DownloadItem, error: Throwable) {
Timber.e(error, "Item ${item.appId} failed to download")
DownloadLogger.append(
downloadInfo.gameId,
"FAILED for app ${item.appId}: ${error.message ?: error.javaClass.simpleName}",
)
DownloadLogger.flush(downloadInfo.gameId)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/main/java/app/gamenative/service/SteamService.kt` around lines 2178 -
2187, The completion/failure log messages lose the specific item identity;
update the onDownloadCompleted and onDownloadFailed handlers so
DownloadLogger.append (and then flush) include the item identifier (e.g.
item.appId or item.id) in the message text rather than only using
downloadInfo.gameId; modify the messages in onDownloadCompleted and
onDownloadFailed so they read something like "Item <item.appId> - Download
completed" and "Item <item.appId> - FAILED: <error...>" when calling
DownloadLogger.append before DownloadLogger.flush to keep base-game vs DLC
entries distinguishable.

downloadInfo.failedToDownload()

// Remove the downloading app info
// Remove the downloading app info from DB
runBlocking {
instance?.downloadingAppInfoDao?.deleteApp(downloadInfo.gameId)
}

removeDownloadJob(downloadInfo.gameId)
instance?.let { service ->
SnackbarManager.show(service.getString(R.string.download_failed_try_again))
}
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

override fun onStatusUpdate(message: String) {
Timber.d("Download status: $message")
downloadInfo.updateStatusMessage(message)
DownloadLogger.append(downloadInfo.gameId, message)
Comment on lines 2200 to +2202

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Writers of status text:"
rg -n --glob '*.kt' --glob '*.java' '\bupdateStatusMessage\s*\('

echo
echo "Readers of status text:"
rg -n --glob '*.kt' --glob '*.java' '\bstatusMessage\b|\bgetStatusMessage\s*\('

Repository: utkarshdalal/GameNative

Length of output: 15484


The removal of updateStatusMessage(message) from the onStatusUpdate handler breaks live download status display.

The UI actively reads statusMessage via DownloadsViewModel (line 289: info.getStatusMessageFlow().value) and renders it in DownloadsScreen (line 737). Writing only to DownloadLogger will not update the download status displayed to the user during Steam downloads. The updateStatusMessage() calls at lines 2129 and 2151 only handle post-install sync, not the active download phase.

Restore the downloadInfo.updateStatusMessage(message) call in the onStatusUpdate handler (line 2201) alongside the DownloadLogger write to maintain live UI updates.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/main/java/app/gamenative/service/SteamService.kt` around lines 2200 -
2202, The onStatusUpdate handler currently only logs to
DownloadLogger.append(downloadInfo.gameId, message) which prevents the UI from
seeing live updates; restore a call to downloadInfo.updateStatusMessage(message)
inside the same onStatusUpdate override so the DownloadsViewModel (via
info.getStatusMessageFlow()) continues to receive and display the live download
status while also writing to DownloadLogger.

}

override fun onChunkCompleted(
Expand Down Expand Up @@ -3277,7 +3309,7 @@ class SteamService : Service(), IChallengeUrlChanged {
connectivityManager.registerNetworkCallback(networkRequest, networkCallback)

// To view log messages in android logcat properly
LogManager.addListener(logger)
`in`.dragonbra.javasteam.util.log.LogManager.addListener(logger)
}

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Expand Down Expand Up @@ -3477,7 +3509,7 @@ class SteamService : Service(), IChallengeUrlChanged {
PluviaApp.events.off<AndroidEvent.EndProcess, Unit>(onEndProcess)
PluviaApp.events.clearAllListenersOf<SteamEvent<Any>>()

LogManager.removeListener(logger)
`in`.dragonbra.javasteam.util.log.LogManager.removeListener(logger)
}

private fun reconnect() {
Expand Down
Loading