Android: Run Directory Initialization as a thread instead of service

Two reasons for this change. First, it appears that some android launchers do some sort of call into
the application when long pressing the app icon, which in turn calls the DirectoryInit service. This
was ok to do prior to Oreo but will cause crashes with the new restrictions on services running
in the background. Which leads to the second reason that DirectoryInit doesn't need to be a service
at all since these actions are required for dolphin to function and shouldn't be a scheduled action.
So we instead just kick this off in a new thread and send the broadcast when done.
This commit is contained in:
zackhow 2018-09-14 00:46:30 -04:00
parent 5f0d825f40
commit 1311f84706
17 changed files with 90 additions and 99 deletions

View file

@ -84,7 +84,7 @@
</intent-filter>
</activity>
<service android:name=".services.DirectoryInitializationService"/>
<service android:name=".utils.DirectoryInitialization"/>
<service android:name=".services.GameFileCacheService"/>
<service
android:name=".services.SyncChannelJobService"

View file

@ -3,7 +3,7 @@ package org.dolphinemu.dolphinemu;
import android.app.Application;
import android.content.Context;
import org.dolphinemu.dolphinemu.services.DirectoryInitializationService;
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization;
import org.dolphinemu.dolphinemu.utils.PermissionsHandler;
import org.dolphinemu.dolphinemu.utils.VolleyUtil;
@ -20,7 +20,7 @@ public class DolphinApplication extends Application
System.loadLibrary("main");
if (PermissionsHandler.hasWriteAccess(getApplicationContext()))
DirectoryInitializationService.startService(getApplicationContext());
DirectoryInitialization.start(getApplicationContext());
}
public static Context getAppContext()

View file

@ -11,7 +11,7 @@ import android.widget.Toast;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.model.GameFile;
import org.dolphinemu.dolphinemu.services.DirectoryInitializationService;
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization;
import org.dolphinemu.dolphinemu.services.GameFileCacheService;
import org.dolphinemu.dolphinemu.ui.main.TvMainActivity;
import org.dolphinemu.dolphinemu.utils.AppLinkHelper;
@ -64,24 +64,24 @@ public class AppLinkActivity extends FragmentActivity
private void initResources()
{
IntentFilter statusIntentFilter = new IntentFilter(
DirectoryInitializationService.BROADCAST_ACTION);
DirectoryInitialization.BROADCAST_ACTION);
directoryStateReceiver =
new DirectoryStateReceiver(directoryInitializationState ->
{
if (directoryInitializationState ==
DirectoryInitializationService.DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED)
DirectoryInitialization.DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED)
{
play(playAction);
}
else if (directoryInitializationState ==
DirectoryInitializationService.DirectoryInitializationState.EXTERNAL_STORAGE_PERMISSION_NEEDED)
DirectoryInitialization.DirectoryInitializationState.EXTERNAL_STORAGE_PERMISSION_NEEDED)
{
Toast.makeText(this, R.string.write_permission_needed, Toast.LENGTH_SHORT)
.show();
}
else if (directoryInitializationState ==
DirectoryInitializationService.DirectoryInitializationState.CANT_FIND_EXTERNAL_STORAGE)
DirectoryInitialization.DirectoryInitializationState.CANT_FIND_EXTERNAL_STORAGE)
{
Toast.makeText(this, R.string.external_storage_not_mounted, Toast.LENGTH_SHORT)
.show();
@ -92,7 +92,7 @@ public class AppLinkActivity extends FragmentActivity
LocalBroadcastManager.getInstance(this).registerReceiver(
directoryStateReceiver,
statusIntentFilter);
DirectoryInitializationService.startService(this);
DirectoryInitialization.start(this);
GameFileCacheService.startLoad(this);
}

View file

@ -15,7 +15,7 @@ import org.dolphinemu.dolphinemu.activities.EmulationActivity;
import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag;
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsActivity;
import org.dolphinemu.dolphinemu.model.GameFile;
import org.dolphinemu.dolphinemu.services.DirectoryInitializationService;
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization;
import org.dolphinemu.dolphinemu.utils.PicassoUtils;
import org.dolphinemu.dolphinemu.viewholders.GameViewHolder;
@ -166,7 +166,7 @@ public final class GameAdapter extends RecyclerView.Adapter<GameViewHolder> impl
break;
case 2:
String path =
DirectoryInitializationService.getUserDirectory() + "/GameSettings/" +
DirectoryInitialization.getUserDirectory() + "/GameSettings/" +
gameId + ".ini";
File gameSettingsFile = new File(path);
if (gameSettingsFile.exists())

View file

@ -17,7 +17,7 @@ import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag;
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsActivity;
import org.dolphinemu.dolphinemu.model.GameFile;
import org.dolphinemu.dolphinemu.services.DirectoryInitializationService;
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization;
import org.dolphinemu.dolphinemu.ui.platform.Platform;
import org.dolphinemu.dolphinemu.utils.PicassoUtils;
import org.dolphinemu.dolphinemu.viewholders.TvGameViewHolder;
@ -113,7 +113,7 @@ public final class GameRowPresenter extends Presenter
SettingsActivity.launch(activity, MenuTag.GRAPHICS, gameId);
break;
case 2:
String path = DirectoryInitializationService.getUserDirectory() +
String path = DirectoryInitialization.getUserDirectory() +
"/GameSettings/" + gameId + ".ini";
File gameSettingsFile = new File(path);
if (gameSettingsFile.exists())

View file

@ -15,7 +15,7 @@ import android.view.MenuItem;
import android.widget.Toast;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.services.DirectoryInitializationService;
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization;
import org.dolphinemu.dolphinemu.utils.DirectoryStateReceiver;
public final class SettingsActivity extends AppCompatActivity implements SettingsActivityView
@ -142,7 +142,7 @@ public final class SettingsActivity extends AppCompatActivity implements Setting
LocalBroadcastManager.getInstance(this).registerReceiver(
receiver,
filter);
DirectoryInitializationService.startService(this);
DirectoryInitialization.start(this);
}
@Override

View file

@ -6,8 +6,8 @@ import android.text.TextUtils;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
import org.dolphinemu.dolphinemu.services.DirectoryInitializationService;
import org.dolphinemu.dolphinemu.services.DirectoryInitializationService.DirectoryInitializationState;
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization;
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization.DirectoryInitializationState;
import org.dolphinemu.dolphinemu.utils.DirectoryStateReceiver;
import org.dolphinemu.dolphinemu.utils.Log;
@ -71,7 +71,7 @@ public final class SettingsActivityPresenter
private void prepareDolphinDirectoriesIfNeeded()
{
if (DirectoryInitializationService.areDolphinDirectoriesReady())
if (DirectoryInitialization.areDolphinDirectoriesReady())
{
loadSettingsUI();
}
@ -79,7 +79,7 @@ public final class SettingsActivityPresenter
{
mView.showLoading();
IntentFilter statusIntentFilter = new IntentFilter(
DirectoryInitializationService.BROADCAST_ACTION);
DirectoryInitialization.BROADCAST_ACTION);
directoryStateReceiver =
new DirectoryStateReceiver(directoryInitializationState ->

View file

@ -120,15 +120,15 @@ public interface SettingsActivityView
void showExternalStorageNotMountedHint();
/**
* Start the DirectoryInitializationService and listen for the result.
* Start the DirectoryInitialization and listen for the result.
*
* @param receiver the broadcast receiver for the DirectoryInitializationService
* @param receiver the broadcast receiver for the DirectoryInitialization
* @param filter the Intent broadcasts to be received.
*/
void startDirectoryInitializationService(DirectoryStateReceiver receiver, IntentFilter filter);
/**
* Stop listening to the DirectoryInitializationService.
* Stop listening to the DirectoryInitialization.
*
* @param receiver The broadcast receiver to unregister.
*/

View file

@ -20,7 +20,7 @@ import org.dolphinemu.dolphinemu.features.settings.model.view.SliderSetting;
import org.dolphinemu.dolphinemu.features.settings.model.view.StringSingleChoiceSetting;
import org.dolphinemu.dolphinemu.features.settings.model.view.SubmenuSetting;
import org.dolphinemu.dolphinemu.features.settings.utils.SettingsFile;
import org.dolphinemu.dolphinemu.services.DirectoryInitializationService;
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization;
import org.dolphinemu.dolphinemu.utils.EGLHelper;
import org.dolphinemu.dolphinemu.utils.Log;
@ -473,7 +473,7 @@ public final class SettingsFragmentPresenter
try
{
String shadersPath =
DirectoryInitializationService.getDolphinInternalDirectory() + "/Shaders";
DirectoryInitialization.getDolphinInternalDirectory() + "/Shaders";
if (!TextUtils.isEmpty(subDir))
{
shadersPath += "/" + subDir;

View file

@ -11,7 +11,7 @@ import org.dolphinemu.dolphinemu.features.settings.model.SettingSection;
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
import org.dolphinemu.dolphinemu.features.settings.model.StringSetting;
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsActivityView;
import org.dolphinemu.dolphinemu.services.DirectoryInitializationService;
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization;
import org.dolphinemu.dolphinemu.utils.BiMap;
import org.dolphinemu.dolphinemu.utils.Log;
@ -462,7 +462,7 @@ public final class SettingsFile
private static File getSettingsFile(String fileName)
{
return new File(
DirectoryInitializationService.getUserDirectory() + "/Config/" + fileName + ".ini");
DirectoryInitialization.getUserDirectory() + "/Config/" + fileName + ".ini");
}
private static File getGenericGameSettingsForAllRegions(String gameId)
@ -470,21 +470,21 @@ public final class SettingsFile
// Use the first 3 chars from the gameId to load the generic game settings for all regions
gameId = gameId.substring(0, 3);
return new File(
DirectoryInitializationService.getDolphinInternalDirectory() + "/GameSettings/" +
DirectoryInitialization.getDolphinInternalDirectory() + "/GameSettings/" +
gameId + ".ini");
}
private static File getGenericGameSettingsFile(String gameId)
{
return new File(
DirectoryInitializationService.getDolphinInternalDirectory() + "/GameSettings/" +
DirectoryInitialization.getDolphinInternalDirectory() + "/GameSettings/" +
gameId + ".ini");
}
private static File getCustomGameSettingsFile(String gameId)
{
return new File(
DirectoryInitializationService.getUserDirectory() + "/GameSettings/" + gameId + ".ini");
DirectoryInitialization.getUserDirectory() + "/GameSettings/" + gameId + ".ini");
}
private static SettingSection sectionFromLine(String line, boolean isCustomGame)

View file

@ -20,8 +20,8 @@ import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.activities.EmulationActivity;
import org.dolphinemu.dolphinemu.overlay.InputOverlay;
import org.dolphinemu.dolphinemu.services.DirectoryInitializationService;
import org.dolphinemu.dolphinemu.services.DirectoryInitializationService.DirectoryInitializationState;
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization;
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization.DirectoryInitializationState;
import org.dolphinemu.dolphinemu.utils.DirectoryStateReceiver;
import org.dolphinemu.dolphinemu.utils.Log;
import org.dolphinemu.dolphinemu.utils.StartupHandler;
@ -127,7 +127,7 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
public void onResume()
{
super.onResume();
if (DirectoryInitializationService.areDolphinDirectoriesReady())
if (DirectoryInitialization.areDolphinDirectoriesReady())
{
mEmulationState.run(activity.isActivityRecreated());
}
@ -160,7 +160,7 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
private void setupDolphinDirectoriesThenStartEmulation()
{
IntentFilter statusIntentFilter = new IntentFilter(
DirectoryInitializationService.BROADCAST_ACTION);
DirectoryInitialization.BROADCAST_ACTION);
directoryStateReceiver =
new DirectoryStateReceiver(directoryInitializationState ->
@ -189,7 +189,7 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(
directoryStateReceiver,
statusIntentFilter);
DirectoryInitializationService.startService(getActivity());
DirectoryInitialization.start(getActivity());
}
public void toggleInputOverlayVisibility()

View file

@ -19,7 +19,7 @@ import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.adapters.PlatformPagerAdapter;
import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag;
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsActivity;
import org.dolphinemu.dolphinemu.services.DirectoryInitializationService;
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization;
import org.dolphinemu.dolphinemu.services.GameFileCacheService;
import org.dolphinemu.dolphinemu.ui.platform.Platform;
import org.dolphinemu.dolphinemu.ui.platform.PlatformGamesView;
@ -188,7 +188,7 @@ public final class MainActivity extends AppCompatActivity implements MainView
case PermissionsHandler.REQUEST_CODE_WRITE_PERMISSION:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
DirectoryInitializationService.startService(this);
DirectoryInitialization.start(this);
PlatformPagerAdapter platformPagerAdapter = new PlatformPagerAdapter(
getSupportFragmentManager(), this);
mViewPager.setAdapter(platformPagerAdapter);

View file

@ -22,7 +22,7 @@ import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag;
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsActivity;
import org.dolphinemu.dolphinemu.model.GameFile;
import org.dolphinemu.dolphinemu.model.TvSettingsItem;
import org.dolphinemu.dolphinemu.services.DirectoryInitializationService;
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization;
import org.dolphinemu.dolphinemu.services.GameFileCacheService;
import org.dolphinemu.dolphinemu.ui.platform.Platform;
import org.dolphinemu.dolphinemu.utils.FileBrowserHelper;
@ -158,7 +158,7 @@ public final class TvMainActivity extends FragmentActivity implements MainView
// Kicks off the program services to update all channels
TvUtil.updateAllChannels(getApplicationContext());
recreate();
buildRowsAdapter();
}
/**
@ -195,7 +195,7 @@ public final class TvMainActivity extends FragmentActivity implements MainView
case PermissionsHandler.REQUEST_CODE_WRITE_PERMISSION:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
DirectoryInitializationService.startService(this);
DirectoryInitialization.start(this);
GameFileCacheService.startLoad(this);
}
else

View file

@ -15,7 +15,6 @@ import org.dolphinemu.dolphinemu.DolphinApplication;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
import org.dolphinemu.dolphinemu.features.settings.utils.SettingsFile;
import org.dolphinemu.dolphinemu.services.DirectoryInitializationService;
public class Analytics
{
@ -36,16 +35,16 @@ public class Analytics
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
if (!preferences.getBoolean(analyticsAsked, false))
{
if (!DirectoryInitializationService.areDolphinDirectoriesReady())
if (!DirectoryInitialization.areDolphinDirectoriesReady())
{
// Wait for directories to get initialized
IntentFilter statusIntentFilter = new IntentFilter(
DirectoryInitializationService.BROADCAST_ACTION);
DirectoryInitialization.BROADCAST_ACTION);
directoryStateReceiver = new DirectoryStateReceiver(directoryInitializationState ->
{
if (directoryInitializationState ==
DirectoryInitializationService.DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED)
DirectoryInitialization.DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED)
{
LocalBroadcastManager.getInstance(context).unregisterReceiver(directoryStateReceiver);
directoryStateReceiver = null;

View file

@ -4,9 +4,8 @@
* Refer to the license.txt file included.
*/
package org.dolphinemu.dolphinemu.services;
package org.dolphinemu.dolphinemu.utils;
import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
@ -15,8 +14,6 @@ import android.preference.PreferenceManager;
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;
@ -30,7 +27,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
* 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 final class DirectoryInitialization
{
public static final String BROADCAST_ACTION =
"org.dolphinemu.dolphinemu.DIRECTORY_INITIALIZATION";
@ -48,31 +45,26 @@ public final class DirectoryInitializationService extends IntentService
CANT_FIND_EXTERNAL_STORAGE
}
public DirectoryInitializationService()
public static void start(Context context)
{
// Superclass constructor is called to name the thread on which this service executes.
super("DirectoryInitializationService");
// Can take a few seconds to run, so don't block UI thread.
//noinspection TrivialFunctionalExpressionUsage
((Runnable) () -> init(context)).run();
}
public static void startService(Context context)
private static void init(Context context)
{
Intent intent = new Intent(context, DirectoryInitializationService.class);
context.startService(intent);
}
@Override
protected void onHandleIntent(Intent intent)
{
isDolphinDirectoryInitializationRunning.set(true);
if (!isDolphinDirectoryInitializationRunning.compareAndSet(false, true))
return;
if (directoryState != DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED)
{
if (PermissionsHandler.hasWriteAccess(this))
if (PermissionsHandler.hasWriteAccess(context))
{
if (setDolphinUserDirectory())
{
initializeInternalStorage();
initializeExternalStorage();
initializeInternalStorage(context);
initializeExternalStorage(context);
directoryState = DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED;
}
@ -88,10 +80,10 @@ public final class DirectoryInitializationService extends IntentService
}
isDolphinDirectoryInitializationRunning.set(false);
sendBroadcastState(directoryState);
sendBroadcastState(directoryState, context);
}
private boolean setDolphinUserDirectory()
private static boolean setDolphinUserDirectory()
{
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()))
{
@ -99,7 +91,7 @@ public final class DirectoryInitializationService extends IntentService
if (externalPath != null)
{
userPath = externalPath.getAbsolutePath() + "/dolphin-emu";
Log.debug("[DirectoryInitializationService] User Dir: " + userPath);
Log.debug("[DirectoryInitialization] User Dir: " + userPath);
NativeLibrary.SetUserDirectory(userPath);
return true;
}
@ -109,19 +101,19 @@ public final class DirectoryInitializationService extends IntentService
return false;
}
private void initializeInternalStorage()
private static void initializeInternalStorage(Context context)
{
File sysDirectory = new File(getFilesDir(), "Sys");
File sysDirectory = new File(context.getFilesDir(), "Sys");
internalPath = sysDirectory.getAbsolutePath();
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
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);
copyAssetFolder("Sys", sysDirectory, true, context);
SharedPreferences.Editor editor = preferences.edit();
editor.putString("sysDirectoryVersion", revision);
@ -132,7 +124,7 @@ public final class DirectoryInitializationService extends IntentService
SetSysDirectory(sysDirectory.getPath());
}
private void initializeExternalStorage()
private static void initializeExternalStorage(Context context)
{
// Create User directory structure and copy some NAND files from the extracted Sys directory.
CreateUserDirectories();
@ -147,8 +139,8 @@ public final class DirectoryInitializationService extends IntentService
//
// 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);
copyAsset("GCPadNew.ini", new File(configDirectory, "GCPadNew.ini"), true, context);
copyAsset("WiimoteNew.ini", new File(configDirectory, "WiimoteNew.ini"), false, context);
}
private static void deleteDirectoryRecursively(File file)
@ -170,12 +162,12 @@ public final class DirectoryInitializationService extends IntentService
{
if (directoryState == null)
{
throw new IllegalStateException("DirectoryInitializationService has to run at least once!");
throw new IllegalStateException("DirectoryInitialization has to run at least once!");
}
else if (isDolphinDirectoryInitializationRunning.get())
{
throw new IllegalStateException(
"DirectoryInitializationService has to finish running first!");
"DirectoryInitialization has to finish running first!");
}
return userPath;
@ -185,34 +177,34 @@ public final class DirectoryInitializationService extends IntentService
{
if (directoryState == null)
{
throw new IllegalStateException("DirectoryInitializationService has to run at least once!");
throw new IllegalStateException("DirectoryInitialization has to run at least once!");
}
else if (isDolphinDirectoryInitializationRunning.get())
{
throw new IllegalStateException(
"DirectoryInitializationService has to finish running first!");
"DirectoryInitialization has to finish running first!");
}
return internalPath;
}
private void sendBroadcastState(DirectoryInitializationState state)
private static void sendBroadcastState(DirectoryInitializationState state, Context context)
{
Intent localIntent =
new Intent(BROADCAST_ACTION)
.putExtra(EXTRA_STATE, state);
LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent);
LocalBroadcastManager.getInstance(context).sendBroadcast(localIntent);
}
private void copyAsset(String asset, File output, Boolean overwrite)
private static void copyAsset(String asset, File output, Boolean overwrite, Context context)
{
Log.verbose("[DirectoryInitializationService] Copying File " + asset + " to " + output);
Log.verbose("[DirectoryInitialization] Copying File " + asset + " to " + output);
try
{
if (!output.exists() || overwrite)
{
InputStream in = getAssets().open(asset);
InputStream in = context.getAssets().open(asset);
OutputStream out = new FileOutputStream(output);
copyFile(in, out);
in.close();
@ -221,20 +213,21 @@ public final class DirectoryInitializationService extends IntentService
}
catch (IOException e)
{
Log.error("[DirectoryInitializationService] Failed to copy asset file: " + asset +
Log.error("[DirectoryInitialization] Failed to copy asset file: " + asset +
e.getMessage());
}
}
private void copyAssetFolder(String assetFolder, File outputFolder, Boolean overwrite)
private static void copyAssetFolder(String assetFolder, File outputFolder, Boolean overwrite,
Context context)
{
Log.verbose("[DirectoryInitializationService] Copying Folder " + assetFolder + " to " +
Log.verbose("[DirectoryInitialization] Copying Folder " + assetFolder + " to " +
outputFolder);
try
{
boolean createdFolder = false;
for (String file : getAssets().list(assetFolder))
for (String file : context.getAssets().list(assetFolder))
{
if (!createdFolder)
{
@ -242,18 +235,19 @@ public final class DirectoryInitializationService extends IntentService
createdFolder = true;
}
copyAssetFolder(assetFolder + File.separator + file, new File(outputFolder, file),
overwrite);
copyAsset(assetFolder + File.separator + file, new File(outputFolder, file), overwrite);
overwrite, context);
copyAsset(assetFolder + File.separator + file, new File(outputFolder, file), overwrite,
context);
}
}
catch (IOException e)
{
Log.error("[DirectoryInitializationService] Failed to copy asset folder: " + assetFolder +
Log.error("[DirectoryInitialization] Failed to copy asset folder: " + assetFolder +
e.getMessage());
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException
private static void copyFile(InputStream in, OutputStream out) throws IOException
{
byte[] buffer = new byte[1024];
int read;

View file

@ -4,8 +4,7 @@ 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 org.dolphinemu.dolphinemu.utils.DirectoryInitialization.DirectoryInitializationState;
import rx.functions.Action1;
@ -22,7 +21,7 @@ public class DirectoryStateReceiver extends BroadcastReceiver
public void onReceive(Context context, Intent intent)
{
DirectoryInitializationState state = (DirectoryInitializationState) intent
.getSerializableExtra(DirectoryInitializationService.EXTRA_STATE);
.getSerializableExtra(DirectoryInitialization.EXTRA_STATE);
callback.call(state);
}
}

View file

@ -246,8 +246,8 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_LoadStateAs(
jobject obj,
jstring path);
JNIEXPORT void JNICALL
Java_org_dolphinemu_dolphinemu_services_DirectoryInitializationService_CreateUserDirectories(
JNIEnv* env, jobject obj);
Java_org_dolphinemu_dolphinemu_utils_DirectoryInitialization_CreateUserDirectories(JNIEnv* env,
jobject obj);
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetUserDirectory(
JNIEnv* env, jobject obj, jstring jDirectory);
JNIEXPORT jstring JNICALL
@ -457,8 +457,7 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_LoadStateAs(
State::LoadAs(GetJString(env, path));
}
JNIEXPORT void JNICALL
Java_org_dolphinemu_dolphinemu_services_DirectoryInitializationService_SetSysDirectory(
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_utils_DirectoryInitialization_SetSysDirectory(
JNIEnv* env, jobject obj, jstring jPath)
{
const std::string path = GetJString(env, jPath);
@ -466,8 +465,8 @@ Java_org_dolphinemu_dolphinemu_services_DirectoryInitializationService_SetSysDir
}
JNIEXPORT void JNICALL
Java_org_dolphinemu_dolphinemu_services_DirectoryInitializationService_CreateUserDirectories(
JNIEnv* env, jobject obj)
Java_org_dolphinemu_dolphinemu_utils_DirectoryInitialization_CreateUserDirectories(JNIEnv* env,
jobject obj)
{
UICommon::CreateDirectories();
}