From db04d330c7945b3fc24efaab2bba31b5e1f1f0f4 Mon Sep 17 00:00:00 2001 From: Aaron Culliney Date: Sat, 22 Oct 2016 11:06:27 -0700 Subject: [PATCH] Expose save-state file in /sdcard/apple2ix --- .../org/deadc0de/apple2ix/Apple2MainMenu.java | 11 +++- .../deadc0de/apple2ix/Apple2Preferences.java | 4 +- .../org/deadc0de/apple2ix/Apple2Utils.java | 50 ++++++++++++++++++- 3 files changed, 61 insertions(+), 4 deletions(-) diff --git a/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2MainMenu.java b/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2MainMenu.java index 90857be8..6403aafd 100644 --- a/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2MainMenu.java +++ b/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2MainMenu.java @@ -39,7 +39,7 @@ import java.util.concurrent.atomic.AtomicBoolean; public class Apple2MainMenu { - private final static String SAVE_FILE = "emulator.state"; + public final static String SAVE_FILE = "emulator.state"; private final static String TAG = "Apple2MainMenu"; private Apple2Activity mActivity = null; @@ -299,7 +299,14 @@ public class Apple2MainMenu { public void maybeSaveRestore() { mActivity.pauseEmulation(); - final String quickSavePath = Apple2Utils.getDataDir(mActivity) + File.separator + SAVE_FILE; + final String quickSavePath; + final File extStorage = Apple2Utils.getExternalStorageDirectory(mActivity); + + if (extStorage != null) { + quickSavePath = extStorage + File.separator + SAVE_FILE; + } else { + quickSavePath = Apple2Utils.getDataDir(mActivity) + File.separator + SAVE_FILE; + } final AtomicBoolean selectionAlreadyHandled = new AtomicBoolean(false); diff --git a/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2Preferences.java b/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2Preferences.java index 84548836..4bd0ab95 100644 --- a/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2Preferences.java +++ b/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2Preferences.java @@ -174,8 +174,10 @@ public class Apple2Preferences { Log.v(TAG, "Triggering migration to Apple2ix version : " + BuildConfig.VERSION_NAME); setJSONPref(PREF_DOMAIN_INTERFACE, PREF_EMULATOR_VERSION, BuildConfig.VERSION_CODE); + + Apple2Utils.migrate(activity); if (BuildConfig.VERSION_CODE >= 17) { - // FIXME TODO : remove this after shipping 1.1.7+ + // FIXME TODO : remove this after most/all app users are on 18+ boolean keypadPreset = false; Apple2AbstractMenu.IMenuEnum menuEnum = null; diff --git a/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2Utils.java b/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2Utils.java index 8e664fd8..7dc20e33 100644 --- a/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2Utils.java +++ b/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2Utils.java @@ -19,11 +19,13 @@ import android.util.Log; import android.view.View; import android.widget.ProgressBar; +import org.deadc0de.apple2ix.basic.BuildConfig; import org.deadc0de.apple2ix.basic.R; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; +import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; @@ -100,6 +102,52 @@ public class Apple2Utils { return attempts < maxAttempts; } + public static void migrate(Apple2Activity activity) { + do { + if (BuildConfig.VERSION_CODE >= 18) { + + // Migrate emulator.state file from internal path to external storage to allow user manipulation + // TODO FIXME : Remove this migration code when all/most users are on version >= 18 + + final File extStorage = Apple2Utils.getExternalStorageDirectory(activity); + if (extStorage == null) { + break; + } + + final String srcPath = getDataDir(activity) + File.separator + Apple2MainMenu.SAVE_FILE; + final File srcFile = new File(srcPath); + if (!srcFile.exists()) { + break; + } + + final String dstPath = extStorage + File.separator + Apple2MainMenu.SAVE_FILE; + + final int maxAttempts = 5; + int attempts = 0; + do { + try { + FileInputStream is = new FileInputStream(srcFile); + FileOutputStream os = new FileOutputStream(dstPath); + copyFile(is, os); + break; + } catch (InterruptedIOException e) { + // EINTR, EAGAIN ... + } catch (IOException e) { + Log.d(TAG, "OOPS exception attempting to copy emulator.state file : " + e); + } + + try { + Thread.sleep(100, 0); + } catch (InterruptedException ie) { + // ... + } + ++attempts; + } while (attempts < maxAttempts); + + srcFile.delete(); + } + } while (false); + } public static File getExternalStorageDirectory(Apple2Activity activity) { @@ -140,7 +188,7 @@ public class Apple2Utils { return sRealExternalFilesDir; } - // HACK NOTE 2015/02/22 : Apparently native code cannot easily access stuff in the APK ... so copy various resources + // HACK NOTE 2015/02/22 : Apparently native code cannot easily access stuff in the APK ... so copy various resources // out of the APK and into the /data/data/... for ease of access. Because this is FOSS software we don't care about // security or DRM for these assets =) public static String getDataDir(Apple2Activity activity) {