Compare commits

..

1 Commits

Author SHA1 Message Date
Producdevity
0818e2ed64 feat: show state of already installed driver 2025-12-08 01:08:04 +01:00
4 changed files with 62 additions and 15 deletions

View File

@@ -143,8 +143,21 @@ class ReleaseAdapter(
binding.containerDownloads.removeAllViews()
release.artifacts.forEach { artifact ->
val alreadyInstalled = try {
// Prefer fast check via ViewModel list; fallback to helper if needed
driverViewModel.driverData.any {
File(it.first).name.equals(artifact.name, ignoreCase = true)
} || GpuDriverHelper.isDriverZipInstalledByName(artifact.name)
} catch (_: Exception) {
false
}
val button = MaterialButton(binding.root.context).apply {
text = artifact.name
text = if (alreadyInstalled) {
context.getString(R.string.installed_label, artifact.name)
} else {
artifact.name
}
setTextAppearance(
com.google.android.material.R.style.TextAppearance_Material3_LabelLarge
)
@@ -154,7 +167,7 @@ class ReleaseAdapter(
com.google.android.material.R.color.m3_button_background_color_selector
)
)
setIconResource(R.drawable.ic_import)
setIconResource(if (alreadyInstalled) R.drawable.ic_check else R.drawable.ic_import)
iconTint = ColorStateList.valueOf(
MaterialColors.getColor(
this,
@@ -167,7 +180,22 @@ class ReleaseAdapter(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
isEnabled = !alreadyInstalled
setOnClickListener {
// Double-check just before starting (race-proof)
if (GpuDriverHelper.isDriverZipInstalledByName(artifact.name)) {
Toast.makeText(
context,
context.getString(R.string.driver_already_installed),
Toast.LENGTH_SHORT
).show()
// Update UI to reflect installed state
this.isEnabled = false
this.text = context.getString(R.string.installed_label, artifact.name)
this.setIconResource(R.drawable.ic_check)
return@setOnClickListener
}
val dialogBinding =
DialogProgressBinding.inflate(LayoutInflater.from(context))
dialogBinding.progressBar.isIndeterminate = true
@@ -233,6 +261,10 @@ class ReleaseAdapter(
driverViewModel.onDriverAdded(Pair(driverPath, driverData))
progressDialog.dismiss()
// Update button to installed state
this@apply.isEnabled = false
this@apply.text = context.getString(R.string.installed_label, artifact.name)
this@apply.setIconResource(R.drawable.ic_check)
Toast.makeText(
context,
context.getString(

View File

@@ -238,4 +238,18 @@ object GpuDriverHelper {
driverStorageDirectory.mkdirs()
}
}
/**
* Checks if a driver zip with the given filename is already present and valid in the
* internal driver storage directory. Validation requires a readable meta.json with a name.
*/
fun isDriverZipInstalledByName(fileName: String): Boolean {
// Normalize separators in case upstream sent a path
val baseName = fileName.substringAfterLast('/')
.substringAfterLast('\\')
val candidate = File("$driverStoragePath$baseName")
if (!candidate.exists() || candidate.length() == 0L) return false
val metadata = getMetadataFromZip(candidate)
return metadata.name != null
}
}

View File

@@ -1166,8 +1166,11 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeEmptyUserDirectory(JNIEnv*
void Java_org_yuzu_yuzu_1emu_NativeLibrary_playTimeManagerInit(JNIEnv* env, jobject obj) {
// for some reason the full user directory isnt initialized in Android, so we need to create it
const auto play_time_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::PlayTimeDir);
if (!Common::FS::IsDir(play_time_dir) && !Common::FS::CreateDir(play_time_dir))
LOG_WARNING(Frontend, "Failed to create play time directory");
if (!Common::FS::IsDir(play_time_dir)) {
if (!Common::FS::CreateDir(play_time_dir)) {
LOG_WARNING(Frontend, "Failed to create play time directory");
}
}
play_time_manager = std::make_unique<PlayTime::PlayTimeManager>();
}
@@ -1180,16 +1183,13 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_playTimeManagerStart(JNIEnv* env, job
}
void Java_org_yuzu_yuzu_1emu_NativeLibrary_playTimeManagerStop(JNIEnv* env, jobject obj) {
if (play_time_manager)
play_time_manager->Stop();
play_time_manager->Stop();
}
jlong Java_org_yuzu_yuzu_1emu_NativeLibrary_playTimeManagerGetPlayTime(JNIEnv* env, jobject obj, jstring jprogramId) {
if (play_time_manager) {
u64 program_id = EmulationSession::GetProgramId(env, jprogramId);
return play_time_manager->GetPlayTime(program_id);
}
return 0UL;
jlong Java_org_yuzu_yuzu_1emu_NativeLibrary_playTimeManagerGetPlayTime(JNIEnv* env, jobject obj,
jstring jprogramId) {
u64 program_id = EmulationSession::GetProgramId(env, jprogramId);
return play_time_manager->GetPlayTime(program_id);
}
jlong Java_org_yuzu_yuzu_1emu_NativeLibrary_playTimeManagerGetCurrentTitleId(JNIEnv* env,
@@ -1199,17 +1199,17 @@ jlong Java_org_yuzu_yuzu_1emu_NativeLibrary_playTimeManagerGetCurrentTitleId(JNI
void Java_org_yuzu_yuzu_1emu_NativeLibrary_playTimeManagerResetProgramPlayTime(JNIEnv* env, jobject obj,
jstring jprogramId) {
u64 program_id = EmulationSession::GetProgramId(env, jprogramId);
if (play_time_manager) {
u64 program_id = EmulationSession::GetProgramId(env, jprogramId);
play_time_manager->ResetProgramPlayTime(program_id);
}
}
void Java_org_yuzu_yuzu_1emu_NativeLibrary_playTimeManagerSetPlayTime(JNIEnv* env, jobject obj,
jstring jprogramId, jlong playTimeSeconds) {
u64 program_id = EmulationSession::GetProgramId(env, jprogramId);
if (play_time_manager) {
u64 program_id = EmulationSession::GetProgramId(env, jprogramId);
play_time_manager->SetPlayTime(program_id, u64(playTimeSeconds));
play_time_manager->SetPlayTime(program_id, static_cast<u64>(playTimeSeconds));
}
}

View File

@@ -661,6 +661,7 @@
<string name="select_gpu_driver_default">Default</string>
<string name="select_gpu_driver_error">Invalid driver selected</string>
<string name="driver_already_installed">Driver already installed</string>
<string name="installed_label">%1$s (Installed)</string>
<string name="system_gpu_driver">System GPU driver</string>
<string name="installing_driver">Installing driver…</string>