-
-
Notifications
You must be signed in to change notification settings - Fork 98
feat(imagefs): avoid extraction when changing container variant #484
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| package com.winlator.core; | ||
|
|
||
| public interface OnFileMergedListener { | ||
| void onFileMerged(long done, long filesCount); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,6 +6,8 @@ | |
| import android.content.res.AssetManager; | ||
| import android.util.Log; | ||
|
|
||
| import androidx.annotation.NonNull; | ||
|
|
||
| import app.gamenative.R; | ||
| import app.gamenative.enums.Marker; | ||
| import app.gamenative.service.SteamService; | ||
|
|
@@ -77,6 +79,7 @@ public static void installWineFromDownloads(final Context context) { | |
| for (String version : versions) { | ||
| File downloaded = new File(imageFs.getFilesDir(), version + ".txz"); | ||
| File outFile = new File(rootDir, "/opt/" + version); | ||
| if (outFile.exists()) continue; | ||
| outFile.mkdirs(); | ||
| TarCompressorUtils.extract( | ||
| TarCompressorUtils.Type.XZ, | ||
|
|
@@ -98,44 +101,7 @@ private static Future<Boolean> installFromAssetsFuture(final Context context, As | |
| // dialog.show(R.string.installing_system_files); | ||
| return Executors.newSingleThreadExecutor().submit(() -> { | ||
| clearRootDir(context, rootDir); | ||
| final byte compressionRatio = 22; | ||
| String imagefsFile = containerVariant.equals(Container.GLIBC) ? "imagefs_gamenative.txz" : "imagefs_bionic.txz"; | ||
| File downloaded = new File(imageFs.getFilesDir(), imagefsFile); | ||
|
|
||
| boolean success = false; | ||
|
|
||
| if (Arrays.asList(context.getAssets().list("")).contains(imagefsFile) == true){ | ||
| final long contentLength = (long) (FileUtils.getSize(assetManager, imagefsFile) * (100.0f / compressionRatio)); | ||
| AtomicLong totalSizeRef = new AtomicLong(); | ||
| Log.d("Extraction", "extracting " + imagefsFile); | ||
|
|
||
| success = TarCompressorUtils.extract(TarCompressorUtils.Type.XZ, assetManager, imagefsFile, rootDir, (file, size) -> { | ||
| if (size > 0) { | ||
| long totalSize = totalSizeRef.addAndGet(size); | ||
| if (onProgress != null) { | ||
| final int progress = (int) (((float) totalSize / contentLength) * 100); | ||
| onProgress.call(progress); | ||
| } | ||
| } | ||
| return file; | ||
| }); | ||
| } | ||
|
|
||
| else if (downloaded.exists()){ | ||
| final long contentLength = (long) (FileUtils.getSize(downloaded) * (100.0f / compressionRatio)); | ||
| AtomicLong totalSizeRef = new AtomicLong(); | ||
| Log.d("Extraction", "extracting " + imagefsFile); | ||
| success = TarCompressorUtils.extract(TarCompressorUtils.Type.XZ, downloaded, rootDir, (file, size) -> { | ||
| if (size > 0) { | ||
| long totalSize = totalSizeRef.addAndGet(size); | ||
| if (onProgress != null) { | ||
| final int progress = (int) (((float) totalSize / contentLength) * 100); | ||
| onProgress.call(progress); | ||
| } | ||
| } | ||
| return file; | ||
| }); | ||
| } | ||
| boolean success = extractImageFs(context, assetManager, containerVariant, onProgress, imageFs, rootDir); | ||
|
|
||
| if (success) { | ||
| Log.d("ImageFsInstaller", "Successfully installed system files"); | ||
|
|
@@ -158,6 +124,76 @@ else if (downloaded.exists()){ | |
| }); | ||
| } | ||
|
|
||
| private static void mergeImageFsFolder(Context context, String containerVariant, File rootDir, Callback<Integer> onProgress, Boolean isCleanInstall) throws IOException { | ||
| File variantDir = getVariantDir(context, containerVariant); | ||
| FileUtils.mergeDirectoryRecursively(variantDir, rootDir, (done, filesCount) -> { | ||
cubic-dev-ai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| if (onProgress == null) return; | ||
|
|
||
| int progress = (int) (((float) done / filesCount) * 100); | ||
| if (isCleanInstall) { | ||
| onProgress.call(progress / 2 + 50); | ||
| } else { | ||
| onProgress.call(progress); | ||
| } | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| }); | ||
| } | ||
|
|
||
| private static boolean extractImageFs(Context context, AssetManager assetManager, String containerVariant, Callback<Integer> onProgress, ImageFs imageFs, File rootDir) throws IOException { | ||
| final byte compressionRatio = 22; | ||
|
|
||
| String imagefsFile = containerVariant.equals(Container.GLIBC) ? "imagefs_gamenative.txz" : "imagefs_bionic.txz"; | ||
| File downloaded = new File(context.getFilesDir(), imagefsFile); | ||
|
|
||
| File variantDir = getVariantDir(context, containerVariant); | ||
| if (variantDir.exists()) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Cache reuse is based solely on Prompt for AI agents |
||
| mergeImageFsFolder(context, containerVariant, rootDir, onProgress, false); | ||
| return true; | ||
| } | ||
|
|
||
|
|
||
| boolean success = false; | ||
|
|
||
| if (Arrays.asList(context.getAssets().list("")).contains(imagefsFile) == true){ | ||
| final long contentLength = (long) (FileUtils.getSize(assetManager, imagefsFile) * (100.0f / compressionRatio)); | ||
| AtomicLong totalSizeRef = new AtomicLong(); | ||
| Log.d("Extraction", "extracting " + imagefsFile); | ||
|
|
||
| success = TarCompressorUtils.extract(TarCompressorUtils.Type.XZ, assetManager, imagefsFile, variantDir, (file, size) -> { | ||
| if (size > 0) { | ||
| long totalSize = totalSizeRef.addAndGet(size); | ||
| if (onProgress != null) { | ||
| final int progress = (int) (((float) totalSize / contentLength) * 100 / 2); | ||
| onProgress.call(progress); | ||
| } | ||
| } | ||
| return file; | ||
| }); | ||
| } | ||
|
|
||
| else if (downloaded.exists()){ | ||
| final long contentLength = (long) (FileUtils.getSize(downloaded) * (100.0f / compressionRatio)); | ||
| AtomicLong totalSizeRef = new AtomicLong(); | ||
| Log.d("Extraction", "extracting " + imagefsFile); | ||
| success = TarCompressorUtils.extract(TarCompressorUtils.Type.XZ, downloaded, variantDir, (file, size) -> { | ||
| if (size > 0) { | ||
| long totalSize = totalSizeRef.addAndGet(size); | ||
| if (onProgress != null) { | ||
| final int progress = (int) (((float) totalSize / contentLength) * 100 / 2); | ||
| onProgress.call(progress); | ||
| } | ||
| } | ||
| return file; | ||
| }); | ||
| } | ||
| mergeImageFsFolder(context, containerVariant, rootDir, onProgress, true); | ||
| return success; | ||
| } | ||
|
Comment on lines
+141
to
+190
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When neither the asset nor the downloaded file exists,
Consider guarding the merge call: 🐛 Proposed fix else if (downloaded.exists()){
// ... extraction logic ...
}
- mergeImageFsFolder(context, containerVariant, rootDir, onProgress, true);
- return success;
+
+ if (success) {
+ mergeImageFsFolder(context, containerVariant, rootDir, onProgress, true);
+ }
+ return success;
}Additionally, line 156 has a redundant - if (Arrays.asList(context.getAssets().list("")).contains(imagefsFile) == true){
+ if (Arrays.asList(context.getAssets().list("")).contains(imagefsFile)) {🤖 Prompt for AI Agents |
||
|
|
||
| @NonNull | ||
| private static File getVariantDir(Context context, String containerVariant) { | ||
| return new File(context.getFilesDir(), containerVariant.equals(Container.GLIBC) ? "glibc/imagefs" : "bionic/imagefs"); | ||
| } | ||
|
|
||
| private static void installGuestLibs(Context ctx) { | ||
| final String ASSET_TAR = "redirect.tzst"; // ➊ add this to assets/ | ||
| File imagefs = new File(ctx.getFilesDir(), "imagefs"); | ||
|
|
@@ -216,19 +252,6 @@ private static boolean isImportedWineProton(Context context, String fileName) { | |
| return false; | ||
| } | ||
|
|
||
| // Get bundled versions from resource arrays | ||
| String[] bionicWineEntries = context.getResources().getStringArray(R.array.bionic_wine_entries); | ||
| String[] glibcWineEntries = context.getResources().getStringArray(R.array.glibc_wine_entries); | ||
|
|
||
| // Check if it's a bundled version | ||
| for (String version : bionicWineEntries) { | ||
| if (lowerName.equals(version.toLowerCase())) return false; | ||
| } | ||
| for (String version : glibcWineEntries) { | ||
| if (lowerName.equals(version.toLowerCase())) return false; | ||
| } | ||
|
|
||
| // It's Wine/Proton but not bundled, so it's imported | ||
| return true; | ||
| } | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.