From b3b7aef09a99eb10ce73a9a625654c69c74cf7bc Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sat, 9 Sep 2017 11:27:24 +0200 Subject: Android: Extract Sys to a different folder than the User folder --- .../org/dolphinemu/dolphinemu/NativeLibrary.java | 5 -- .../services/DirectoryInitializationService.java | 83 +++++++++++++++------- 2 files changed, 58 insertions(+), 30 deletions(-) (limited to 'Source/Android/app/src/main/java') diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java index b2d4ed8d39..a11a4ad154 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java @@ -302,11 +302,6 @@ public final class NativeLibrary */ public static native void LoadState(int slot); - /** - * Creates the initial folder structure in /sdcard/dolphin-emu/ - */ - public static native void CreateUserFolders(); - /** * Sets the current working user directory * If not set, it auto-detects a location diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/DirectoryInitializationService.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/DirectoryInitializationService.java index 8f4a8a6bca..f6362ff9cc 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/DirectoryInitializationService.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/DirectoryInitializationService.java @@ -59,7 +59,8 @@ public final class DirectoryInitializationService extends IntentService } else if (PermissionsHandler.hasWriteAccess(this)) { - initDolphinDirectories(); + initializeInternalStorage(); + initializeExternalStorage(); directoryState = DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED; sendBroadcastState(directoryState); } @@ -69,21 +70,47 @@ public final class DirectoryInitializationService extends IntentService } } - private void initDolphinDirectories() + private void initializeInternalStorage() { - String BaseDir = NativeLibrary.GetUserDirectory(); - String ConfigDir = BaseDir + File.separator + "Config"; - - // Copy assets if needed - NativeLibrary.CreateUserFolders(); - copyAssetFolder("GC", BaseDir + File.separator + "GC", false); - copyAssetFolder("Shaders", BaseDir + File.separator + "Shaders", false); - copyAssetFolder("Wii", BaseDir + File.separator + "Wii", false); - - // Always copy over the GCPad config in case of change or corruption. - // Not a user configurable file. - copyAsset("GCPadNew.ini", ConfigDir + File.separator + "GCPadNew.ini", true); - copyAsset("WiimoteNew.ini", ConfigDir + File.separator + "WiimoteNew.ini", false); + File sysDirectory = new File(getFilesDir(), "Sys"); + + // Delete the existing extracted Sys directory in case it's from a different version of Dolphin. + deleteDirectoryRecursively(sysDirectory); + + // Extract the Sys directory to app-local internal storage. + copyAssetFolder("Sys", sysDirectory, true); + + // Let the native code know where the Sys directory is. + SetSysDirectory(sysDirectory.getPath()); + } + + private void initializeExternalStorage() + { + // Create User directory structure and copy some NAND files from the extracted Sys directory. + CreateUserDirectories(); + + // GCPadNew.ini and WiimoteNew.ini must contain specific values in order for controller + // input to work as intended (they aren't user configurable), so we overwrite them just + // in case the user has tried to modify them manually. + // + // ...Except WiimoteNew.ini contains the user configurable settings for Wii Remote + // extensions in addition to all of its lines that aren't user configurable, so since we + // don't want to lose the selected extensions, we don't overwrite that file if it exists. + // + // TODO: Redo the Android controller system so that we don't have to extract these INIs. + String configDirectory = NativeLibrary.GetUserDirectory() + File.separator + "Config"; + copyAsset("GCPadNew.ini", new File(configDirectory, "GCPadNew.ini"), true); + copyAsset("WiimoteNew.ini", new File(configDirectory,"WiimoteNew.ini"), false); + } + + private static void deleteDirectoryRecursively(File file) + { + if (file.isDirectory()) + { + for (File child : file.listFiles()) + deleteDirectoryRecursively(child); + } + file.delete(); } public static boolean areDolphinDirectoriesReady() @@ -99,19 +126,16 @@ public final class DirectoryInitializationService extends IntentService LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent); } - private void copyAsset(String asset, String output, Boolean overwrite) + private void copyAsset(String asset, File output, Boolean overwrite) { Log.verbose("[DirectoryInitializationService] Copying File " + asset + " to " + output); - InputStream in; - OutputStream out; try { - File file = new File(output); - if (!file.exists() || overwrite) + if (!output.exists() || overwrite) { - in = getAssets().open(asset); - out = new FileOutputStream(output); + InputStream in = getAssets().open(asset); + OutputStream out = new FileOutputStream(output); copyFile(in, out); in.close(); out.close(); @@ -123,16 +147,22 @@ public final class DirectoryInitializationService extends IntentService } } - private void copyAssetFolder(String assetFolder, String outputFolder, Boolean overwrite) + private void copyAssetFolder(String assetFolder, File outputFolder, Boolean overwrite) { Log.verbose("[DirectoryInitializationService] Copying Folder " + assetFolder + " to " + outputFolder); try { + boolean createdFolder = false; for (String file : getAssets().list(assetFolder)) { - copyAssetFolder(assetFolder + File.separator + file, outputFolder + File.separator + file, overwrite); - copyAsset(assetFolder + File.separator + file, outputFolder + File.separator + file, overwrite); + if (!createdFolder) + { + outputFolder.mkdir(); + createdFolder = true; + } + copyAssetFolder(assetFolder + File.separator + file, new File(outputFolder, file), overwrite); + copyAsset(assetFolder + File.separator + file, new File(outputFolder, file), overwrite); } } catch (IOException e) @@ -151,4 +181,7 @@ public final class DirectoryInitializationService extends IntentService out.write(buffer, 0, read); } } + + private static native void CreateUserDirectories(); + private static native void SetSysDirectory(String path); } -- cgit v1.2.3 From 3262314435bb394d27aa3e1f490905e6868e4203 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sun, 10 Sep 2017 08:43:12 +0200 Subject: Android: Don't extract Sys if it already is extracted --- .../org/dolphinemu/dolphinemu/NativeLibrary.java | 2 ++ .../services/DirectoryInitializationService.java | 20 +++++++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) (limited to 'Source/Android/app/src/main/java') diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java index a11a4ad154..8d193e75ec 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java @@ -283,6 +283,8 @@ public final class NativeLibrary */ public static native String GetVersionString(); + public static native String GetGitRevision(); + /** * Saves a screen capture of the game */ diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/DirectoryInitializationService.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/DirectoryInitializationService.java index f6362ff9cc..7d41df25ac 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/DirectoryInitializationService.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/DirectoryInitializationService.java @@ -9,6 +9,8 @@ package org.dolphinemu.dolphinemu.services; import android.app.IntentService; import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; import android.support.v4.content.LocalBroadcastManager; import org.dolphinemu.dolphinemu.NativeLibrary; @@ -74,11 +76,19 @@ public final class DirectoryInitializationService extends IntentService { File sysDirectory = new File(getFilesDir(), "Sys"); - // Delete the existing extracted Sys directory in case it's from a different version of Dolphin. - deleteDirectoryRecursively(sysDirectory); - - // Extract the Sys directory to app-local internal storage. - copyAssetFolder("Sys", sysDirectory, true); + SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); + String revision = NativeLibrary.GetGitRevision(); + if (!preferences.getString("sysDirectoryVersion", "").equals(revision)) + { + // There is no extracted Sys directory, or there is a Sys directory from another + // version of Dolphin that might contain outdated files. Let's (re-)extract Sys. + deleteDirectoryRecursively(sysDirectory); + copyAssetFolder("Sys", sysDirectory, true); + + SharedPreferences.Editor editor = preferences.edit(); + editor.putString("sysDirectoryVersion", revision); + editor.apply(); + } // Let the native code know where the Sys directory is. SetSysDirectory(sysDirectory.getPath()); -- cgit v1.2.3 From 152f7fa35c0647f5203bf644959291bbaebd0f3c Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sun, 24 Dec 2017 16:44:43 +0100 Subject: Android: Fix race condition with writing files before setting User path --- .../dolphinemu/utils/StartupHandler.java | 40 ++++++++++------------ 1 file changed, 19 insertions(+), 21 deletions(-) (limited to 'Source/Android/app/src/main/java') diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/StartupHandler.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/StartupHandler.java index 398f569741..11cdf861c6 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/StartupHandler.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/StartupHandler.java @@ -13,33 +13,31 @@ public final class StartupHandler { public static boolean HandleInit(FragmentActivity parent) { - NativeLibrary.SetUserDirectory(""); // Auto-Detect + String user_dir = ""; + String start_file = ""; - if (PermissionsHandler.checkWritePermission(parent)) { - DirectoryInitializationService.startService(parent); + Bundle extras = parent.getIntent().getExtras(); + if (extras != null) + { + user_dir = extras.getString("UserDir"); + start_file = extras.getString("AutoStartFile"); } - Intent intent = parent.getIntent(); - Bundle extras = intent.getExtras(); + NativeLibrary.SetUserDirectory(user_dir); // Uses default path if user_dir equals "" - if (extras != null) + if (PermissionsHandler.checkWritePermission(parent)) + DirectoryInitializationService.startService(parent); + + if (!TextUtils.isEmpty(start_file)) { - String user_dir = extras.getString("UserDir"); - String start_file = extras.getString("AutoStartFile"); - - if (!TextUtils.isEmpty(user_dir)) - NativeLibrary.SetUserDirectory(user_dir); - - if (!TextUtils.isEmpty(start_file)) - { - // Start the emulation activity, send the ISO passed in and finish the main activity - Intent emulation_intent = new Intent(parent, EmulationActivity.class); - emulation_intent.putExtra("SelectedGame", start_file); - parent.startActivity(emulation_intent); - parent.finish(); - return false; - } + // Start the emulation activity, send the ISO passed in and finish the main activity + Intent emulation_intent = new Intent(parent, EmulationActivity.class); + emulation_intent.putExtra("SelectedGame", start_file); + parent.startActivity(emulation_intent); + parent.finish(); + return false; } + return false; } } -- cgit v1.2.3