diff --git a/Source/Android/app/src/main/AndroidManifest.xml b/Source/Android/app/src/main/AndroidManifest.xml index 5eae9e4445..d445f5d822 100644 --- a/Source/Android/app/src/main/AndroidManifest.xml +++ b/Source/Android/app/src/main/AndroidManifest.xml @@ -65,7 +65,7 @@ android:theme="@style/DolphinEmulationGamecube"/> - + { + if (directoryInitializationState == DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED) { + mEmulationState.run(); + } else if (directoryInitializationState == DirectoryInitializationState.EXTERNAL_STORAGE_PERMISSION_NEEDED) { + Toast.makeText(getContext(), R.string.write_permission_needed, Toast.LENGTH_SHORT) + .show(); + } + }); + + // Registers the DirectoryStateReceiver and its intent filters + LocalBroadcastManager.getInstance(getActivity()).registerReceiver( + directoryStateReceiver, + statusIntentFilter); + DirectoryInitializationService.startService(getActivity()); + } + public void toggleInputOverlayVisibility() { SharedPreferences.Editor editor = mPreferences.edit(); diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/AssetCopyService.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/AssetCopyService.java deleted file mode 100644 index d8c39459f6..0000000000 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/AssetCopyService.java +++ /dev/null @@ -1,112 +0,0 @@ -/** - * Copyright 2014 Dolphin Emulator Project - * Licensed under GPLv2+ - * Refer to the license.txt file included. - */ - -package org.dolphinemu.dolphinemu.services; - -import android.app.IntentService; -import android.content.Intent; -import android.content.SharedPreferences; -import android.preference.PreferenceManager; - -import org.dolphinemu.dolphinemu.NativeLibrary; -import org.dolphinemu.dolphinemu.utils.Log; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * A service that spawns its own thread in order to copy several binary and shader files - * from the Dolphin APK to the external file system. - */ -public final class AssetCopyService extends IntentService -{ - public AssetCopyService() - { - // Superclass constructor is called to name the thread on which this service executes. - super("AssetCopyService"); - } - - @Override - protected void onHandleIntent(Intent intent) - { - 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", true); - - // Record the fact that we've done this before, so we don't do it on every launch. - SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); - SharedPreferences.Editor editor = preferences.edit(); - - editor.putBoolean("assetsCopied", true); - editor.apply(); - } - - private void copyAsset(String asset, String output, Boolean overwrite) - { - Log.verbose("[AssetCopyService] Copying File " + asset + " to " + output); - InputStream in; - OutputStream out; - - try - { - File file = new File(output); - if(!file.exists() || overwrite) - { - in = getAssets().open(asset); - out = new FileOutputStream(output); - copyFile(in, out); - in.close(); - out.close(); - } - } - catch (IOException e) - { - Log.error("[AssetCopyService] Failed to copy asset file: " + asset + e.getMessage()); - } - } - - private void copyAssetFolder(String assetFolder, String outputFolder, Boolean overwrite) - { - Log.verbose("[AssetCopyService] Copying Folder " + assetFolder + " to " + outputFolder); - - try - { - 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); - } - } - catch (IOException e) - { - Log.error("[AssetCopyService] Failed to copy asset folder: " + assetFolder + e.getMessage()); - } - } - - private void copyFile(InputStream in, OutputStream out) throws IOException - { - byte[] buffer = new byte[1024]; - int read; - - while ((read = in.read(buffer)) != -1) - { - out.write(buffer, 0, read); - } - } -} 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 new file mode 100644 index 0000000000..acd1f9f821 --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/DirectoryInitializationService.java @@ -0,0 +1,154 @@ +/** + * Copyright 2014 Dolphin Emulator Project + * Licensed under GPLv2+ + * Refer to the license.txt file included. + */ + +package org.dolphinemu.dolphinemu.services; + +import android.app.IntentService; +import android.content.Context; +import android.content.Intent; +import android.support.v4.content.LocalBroadcastManager; + +import org.dolphinemu.dolphinemu.NativeLibrary; +import org.dolphinemu.dolphinemu.utils.Log; +import org.dolphinemu.dolphinemu.utils.PermissionsHandler; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * A service that spawns its own thread in order to copy several binary and shader files + * from the Dolphin APK to the external file system. + */ +public final class DirectoryInitializationService extends IntentService +{ + public static final String BROADCAST_ACTION = "org.dolphinemu.dolphinemu.BROADCAST"; + + public static final String EXTRA_STATE = "directoryState"; + private static DirectoryInitializationState directoryState = null; + + public enum DirectoryInitializationState + { + DOLPHIN_DIRECTORIES_INITIALIZED, + EXTERNAL_STORAGE_PERMISSION_NEEDED + } + + public DirectoryInitializationService() + { + // Superclass constructor is called to name the thread on which this service executes. + super("DirectoryInitializationService"); + } + + public static void startService(Context context) + { + Intent intent = new Intent(context, DirectoryInitializationService.class); + context.startService(intent); + } + + @Override + protected void onHandleIntent(Intent intent) + { + if (directoryState == DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED) + { + sendBroadcastState(DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED); + } + else if (PermissionsHandler.hasWriteAccess(this)) + { + initDolphinDirectories(); + directoryState = DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED; + sendBroadcastState(directoryState); + } + else + { + sendBroadcastState(DirectoryInitializationState.EXTERNAL_STORAGE_PERMISSION_NEEDED); + } + } + + private void initDolphinDirectories() + { + 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", true); + } + + public static boolean areDolphinDirectoriesReady() + { + return directoryState == DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED; + } + + private void sendBroadcastState(DirectoryInitializationState state) + { + Intent localIntent = + new Intent(BROADCAST_ACTION) + .putExtra(EXTRA_STATE, state); + LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent); + } + + private void copyAsset(String asset, String 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) + { + in = getAssets().open(asset); + out = new FileOutputStream(output); + copyFile(in, out); + in.close(); + out.close(); + } + } + catch (IOException e) + { + Log.error("[DirectoryInitializationService] Failed to copy asset file: " + asset + e.getMessage()); + } + } + + private void copyAssetFolder(String assetFolder, String outputFolder, Boolean overwrite) + { + Log.verbose("[DirectoryInitializationService] Copying Folder " + assetFolder + " to " + outputFolder); + + try + { + 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); + } + } + catch (IOException e) + { + Log.error("[DirectoryInitializationService] Failed to copy asset folder: " + assetFolder + e.getMessage()); + } + } + + private void copyFile(InputStream in, OutputStream out) throws IOException + { + byte[] buffer = new byte[1024]; + int read; + + while ((read = in.read(buffer)) != -1) + { + out.write(buffer, 0, read); + } + } +} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.java index 38c478480c..72a9477f00 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.java @@ -20,6 +20,7 @@ import org.dolphinemu.dolphinemu.R; import org.dolphinemu.dolphinemu.activities.AddDirectoryActivity; import org.dolphinemu.dolphinemu.adapters.PlatformPagerAdapter; import org.dolphinemu.dolphinemu.model.GameProvider; +import org.dolphinemu.dolphinemu.services.DirectoryInitializationService; import org.dolphinemu.dolphinemu.ui.platform.Platform; import org.dolphinemu.dolphinemu.ui.platform.PlatformGamesView; import org.dolphinemu.dolphinemu.ui.settings.SettingsActivity; @@ -154,7 +155,7 @@ public final class MainActivity extends AppCompatActivity implements MainView switch (requestCode) { case PermissionsHandler.REQUEST_CODE_WRITE_PERMISSION: if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { - StartupHandler.copyAssetsIfNeeded(this); + DirectoryInitializationService.startService(this); PlatformPagerAdapter platformPagerAdapter = new PlatformPagerAdapter( getSupportFragmentManager(), this); diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.java index 6e4dfa6063..cb72c34a3e 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.java @@ -28,6 +28,7 @@ import org.dolphinemu.dolphinemu.adapters.GameRowPresenter; import org.dolphinemu.dolphinemu.adapters.SettingsRowPresenter; import org.dolphinemu.dolphinemu.model.Game; import org.dolphinemu.dolphinemu.model.TvSettingsItem; +import org.dolphinemu.dolphinemu.services.DirectoryInitializationService; import org.dolphinemu.dolphinemu.ui.platform.Platform; import org.dolphinemu.dolphinemu.ui.settings.SettingsActivity; import org.dolphinemu.dolphinemu.utils.PermissionsHandler; @@ -157,7 +158,7 @@ public final class TvMainActivity extends FragmentActivity implements MainView switch (requestCode) { case PermissionsHandler.REQUEST_CODE_WRITE_PERMISSION: if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { - StartupHandler.copyAssetsIfNeeded(this); + DirectoryInitializationService.startService(this); loadGames(); } else { Toast.makeText(this, R.string.write_permission_needed, Toast.LENGTH_SHORT) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/settings/SettingsActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/settings/SettingsActivity.java index 43715cecba..cd942eb091 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/settings/SettingsActivity.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/settings/SettingsActivity.java @@ -1,9 +1,12 @@ package org.dolphinemu.dolphinemu.ui.settings; +import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.os.Bundle; import android.support.v4.app.FragmentTransaction; +import android.support.v4.content.LocalBroadcastManager; import android.support.v7.app.AppCompatActivity; import android.view.Menu; import android.view.MenuInflater; @@ -12,6 +15,8 @@ import android.widget.Toast; import org.dolphinemu.dolphinemu.R; import org.dolphinemu.dolphinemu.model.settings.SettingSection; +import org.dolphinemu.dolphinemu.services.DirectoryInitializationService; +import org.dolphinemu.dolphinemu.utils.DirectoryStateReceiver; import java.util.ArrayList; import java.util.HashMap; @@ -22,6 +27,8 @@ public final class SettingsActivity extends AppCompatActivity implements Setting private static final String FRAGMENT_TAG = "settings"; private SettingsActivityPresenter mPresenter = new SettingsActivityPresenter(this); + private ProgressDialog dialog; + public static void launch(Context context, String menuTag) { Intent settings = new Intent(context, SettingsActivity.class); @@ -65,6 +72,13 @@ public final class SettingsActivity extends AppCompatActivity implements Setting mPresenter.saveState(outState); } + @Override + protected void onStart() + { + super.onStart(); + mPresenter.onStart(); + } + /** * If this is called, the user has left the settings screen (potentially through the * home button) and will expect their changes to be persisted. So we kick off an @@ -106,6 +120,47 @@ public final class SettingsActivity extends AppCompatActivity implements Setting transaction.commit(); } + @Override + public void startDirectoryInitializationService(DirectoryStateReceiver receiver, IntentFilter filter) + { + LocalBroadcastManager.getInstance(this).registerReceiver( + receiver, + filter); + DirectoryInitializationService.startService(this); + } + + @Override + public void stopListeningToDirectoryInitializationService(DirectoryStateReceiver receiver) + { + LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver); + } + + @Override + public void showLoading() + { + if (dialog == null) + { + dialog = new ProgressDialog(this); + dialog.setMessage(getString(R.string.load_settings)); + dialog.setIndeterminate(true); + } + + dialog.show(); + } + + @Override + public void hideLoading() + { + dialog.dismiss(); + } + + @Override + public void showPermissionNeededHint() + { + Toast.makeText(this, R.string.write_permission_needed, Toast.LENGTH_SHORT) + .show(); + } + @Override public HashMap getSettings(int file) { diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/settings/SettingsActivityPresenter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/settings/SettingsActivityPresenter.java index 9e68c00d20..20cf5bcc78 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/settings/SettingsActivityPresenter.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/settings/SettingsActivityPresenter.java @@ -1,15 +1,20 @@ package org.dolphinemu.dolphinemu.ui.settings; +import android.content.IntentFilter; import android.os.Bundle; import org.dolphinemu.dolphinemu.R; import org.dolphinemu.dolphinemu.model.settings.SettingSection; +import org.dolphinemu.dolphinemu.services.DirectoryInitializationService; +import org.dolphinemu.dolphinemu.utils.DirectoryStateReceiver; import org.dolphinemu.dolphinemu.utils.Log; import org.dolphinemu.dolphinemu.utils.SettingsFile; import java.util.ArrayList; import java.util.HashMap; +import rx.functions.Action1; + public final class SettingsActivityPresenter { private static final String KEY_SHOULD_SAVE = "should_save"; @@ -22,6 +27,10 @@ public final class SettingsActivityPresenter private boolean mShouldSave; + private DirectoryStateReceiver directoryStateReceiver; + + private String menuTag; + public SettingsActivityPresenter(SettingsActivityView view) { mView = view; @@ -31,12 +40,10 @@ public final class SettingsActivityPresenter { if (savedInstanceState == null) { - mView.showSettingsFragment(menuTag, false); - mSettings.add(SettingsFile.SETTINGS_DOLPHIN, SettingsFile.readFile(SettingsFile.FILE_NAME_DOLPHIN, mView)); mSettings.add(SettingsFile.SETTINGS_GFX, SettingsFile.readFile(SettingsFile.FILE_NAME_GFX, mView)); mSettings.add(SettingsFile.SETTINGS_WIIMOTE, SettingsFile.readFile(SettingsFile.FILE_NAME_WIIMOTE, mView)); - mView.onSettingsFileLoaded(mSettings); + this.menuTag = menuTag; } else { @@ -44,6 +51,41 @@ public final class SettingsActivityPresenter } } + public void onStart() + { + prepareDolphinDirectoriesIfNeeded(); + } + + void loadSettingsUI() + { + mView.showSettingsFragment(menuTag, false); + mView.onSettingsFileLoaded(mSettings); + } + + private void prepareDolphinDirectoriesIfNeeded() + { + if (DirectoryInitializationService.areDolphinDirectoriesReady()) { + loadSettingsUI(); + } else { + mView.showLoading(); + IntentFilter statusIntentFilter = new IntentFilter( + DirectoryInitializationService.BROADCAST_ACTION); + + directoryStateReceiver = + new DirectoryStateReceiver(directoryInitializationState -> { + if (directoryInitializationState == DirectoryInitializationService.DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED) { + mView.hideLoading(); + loadSettingsUI(); + } else if (directoryInitializationState == DirectoryInitializationService.DirectoryInitializationState.EXTERNAL_STORAGE_PERMISSION_NEEDED) { + mView.showPermissionNeededHint(); + mView.hideLoading(); + } + }); + + mView.startDirectoryInitializationService(directoryStateReceiver, statusIntentFilter); + } + } + public void setSettings(ArrayList> settings) { mSettings = settings; @@ -56,6 +98,12 @@ public final class SettingsActivityPresenter public void onStop(boolean finishing) { + if (directoryStateReceiver != null) + { + mView.stopListeningToDirectoryInitializationService(directoryStateReceiver); + directoryStateReceiver = null; + } + if (mSettings != null && finishing && mShouldSave) { Log.debug("[SettingsActivity] Settings activity stopping. Saving settings to INI..."); diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/settings/SettingsActivityView.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/settings/SettingsActivityView.java index 8c5d6b9731..686338eaee 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/settings/SettingsActivityView.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/settings/SettingsActivityView.java @@ -1,6 +1,9 @@ package org.dolphinemu.dolphinemu.ui.settings; +import android.content.IntentFilter; + import org.dolphinemu.dolphinemu.model.settings.SettingSection; +import org.dolphinemu.dolphinemu.utils.DirectoryStateReceiver; import java.util.ArrayList; import java.util.HashMap; @@ -99,4 +102,34 @@ public interface SettingsActivityView * @param value New setting for the extension. */ void onExtensionSettingChanged(String key, int value); + + /** + * Show loading dialog while loading the settings + */ + void showLoading(); + + /** + * Hide the loading the dialog + */ + void hideLoading(); + + /** + * Show a hint to the user that the app needs write to external storage access + */ + void showPermissionNeededHint(); + + /** + * Start the DirectoryInitializationService and listen for the result. + * + * @param receiver the broadcast receiver for the DirectoryInitializationService + * @param filter the Intent broadcasts to be received. + */ + void startDirectoryInitializationService(DirectoryStateReceiver receiver, IntentFilter filter); + + /** + * Stop listening to the DirectoryInitializationService. + * + * @param receiver The broadcast receiver to unregister. + */ + void stopListeningToDirectoryInitializationService(DirectoryStateReceiver receiver); } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/DirectoryStateReceiver.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/DirectoryStateReceiver.java new file mode 100644 index 0000000000..ac00782366 --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/DirectoryStateReceiver.java @@ -0,0 +1,24 @@ +package org.dolphinemu.dolphinemu.utils; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +import org.dolphinemu.dolphinemu.services.DirectoryInitializationService; +import org.dolphinemu.dolphinemu.services.DirectoryInitializationService.DirectoryInitializationState; + +import rx.functions.Action1; + +public class DirectoryStateReceiver extends BroadcastReceiver { + Action1 callback; + public DirectoryStateReceiver(Action1 callback) { + this.callback = callback; + } + + @Override + public void onReceive(Context context, Intent intent) + { + DirectoryInitializationState state = (DirectoryInitializationState) intent.getSerializableExtra(DirectoryInitializationService.EXTRA_STATE); + callback.call(state); + } +} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/PermissionsHandler.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/PermissionsHandler.java index e569df112a..a38e33207a 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/PermissionsHandler.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/PermissionsHandler.java @@ -2,6 +2,7 @@ package org.dolphinemu.dolphinemu.utils; import android.annotation.TargetApi; import android.app.AlertDialog; +import android.content.Context; import android.content.DialogInterface; import android.content.pm.PackageManager; import android.os.Build; @@ -40,9 +41,9 @@ public class PermissionsHandler { return true; } - public static boolean hasWriteAccess(FragmentActivity activity) { + public static boolean hasWriteAccess(Context context) { if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - int hasWritePermission = ContextCompat.checkSelfPermission(activity, WRITE_EXTERNAL_STORAGE); + int hasWritePermission = ContextCompat.checkSelfPermission(context, WRITE_EXTERNAL_STORAGE); return hasWritePermission == PackageManager.PERMISSION_GRANTED; } 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 34cde9e59c..398f569741 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 @@ -1,15 +1,13 @@ package org.dolphinemu.dolphinemu.utils; import android.content.Intent; -import android.content.SharedPreferences; import android.os.Bundle; -import android.preference.PreferenceManager; import android.support.v4.app.FragmentActivity; import android.text.TextUtils; import org.dolphinemu.dolphinemu.NativeLibrary; import org.dolphinemu.dolphinemu.activities.EmulationActivity; -import org.dolphinemu.dolphinemu.services.AssetCopyService; +import org.dolphinemu.dolphinemu.services.DirectoryInitializationService; public final class StartupHandler { @@ -17,9 +15,8 @@ public final class StartupHandler { NativeLibrary.SetUserDirectory(""); // Auto-Detect - // Only perform these extensive copy operations once. if (PermissionsHandler.checkWritePermission(parent)) { - copyAssetsIfNeeded(parent); + DirectoryInitializationService.startService(parent); } Intent intent = parent.getIntent(); @@ -45,16 +42,4 @@ public final class StartupHandler } return false; } - - public static void copyAssetsIfNeeded(FragmentActivity parent) { - SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(parent); - boolean assetsCopied = preferences.getBoolean("assetsCopied", false); - - if (!assetsCopied) - { - // Copy assets into appropriate locations. - Intent copyAssets = new Intent(parent, AssetCopyService.class); - parent.startService(copyAssets); - } - } } diff --git a/Source/Android/app/src/main/res/values/strings.xml b/Source/Android/app/src/main/res/values/strings.xml index 9f51d02edd..d508c148e8 100644 --- a/Source/Android/app/src/main/res/values/strings.xml +++ b/Source/Android/app/src/main/res/values/strings.xml @@ -244,4 +244,6 @@ Controllers You need to allow write access to external storage for the emulator to work + + Loading Settings...