mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-03 19:42:45 +01:00
Android: Optional AfterDirectoryInitializationRunner failure message
This centralizes the code for showing the write_permission_needed and external_storage_not_mounted toasts.
This commit is contained in:
parent
db067104ed
commit
2959e76f4a
@ -11,15 +11,13 @@ import androidx.fragment.app.FragmentActivity;
|
|||||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import org.dolphinemu.dolphinemu.R;
|
|
||||||
import org.dolphinemu.dolphinemu.model.GameFile;
|
import org.dolphinemu.dolphinemu.model.GameFile;
|
||||||
|
import org.dolphinemu.dolphinemu.utils.AfterDirectoryInitializationRunner;
|
||||||
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization;
|
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization;
|
||||||
import org.dolphinemu.dolphinemu.services.GameFileCacheService;
|
import org.dolphinemu.dolphinemu.services.GameFileCacheService;
|
||||||
import org.dolphinemu.dolphinemu.ui.main.TvMainActivity;
|
import org.dolphinemu.dolphinemu.ui.main.TvMainActivity;
|
||||||
import org.dolphinemu.dolphinemu.utils.AppLinkHelper;
|
import org.dolphinemu.dolphinemu.utils.AppLinkHelper;
|
||||||
import org.dolphinemu.dolphinemu.utils.DirectoryStateReceiver;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Linker between leanback homescreen and app
|
* Linker between leanback homescreen and app
|
||||||
@ -29,7 +27,7 @@ public class AppLinkActivity extends FragmentActivity
|
|||||||
private static final String TAG = "AppLinkActivity";
|
private static final String TAG = "AppLinkActivity";
|
||||||
|
|
||||||
private AppLinkHelper.PlayAction playAction;
|
private AppLinkHelper.PlayAction playAction;
|
||||||
private DirectoryStateReceiver directoryStateReceiver;
|
private AfterDirectoryInitializationRunner mAfterDirectoryInitializationRunner;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState)
|
protected void onCreate(Bundle savedInstanceState)
|
||||||
@ -67,34 +65,12 @@ public class AppLinkActivity extends FragmentActivity
|
|||||||
*/
|
*/
|
||||||
private void initResources()
|
private void initResources()
|
||||||
{
|
{
|
||||||
IntentFilter directoryStateIntentFilter = new IntentFilter(
|
mAfterDirectoryInitializationRunner = new AfterDirectoryInitializationRunner();
|
||||||
DirectoryInitialization.BROADCAST_ACTION);
|
mAfterDirectoryInitializationRunner.run(this, true, () -> tryPlay(playAction));
|
||||||
|
|
||||||
IntentFilter gameFileCacheIntentFilter = new IntentFilter(
|
IntentFilter gameFileCacheIntentFilter = new IntentFilter(
|
||||||
GameFileCacheService.BROADCAST_ACTION);
|
GameFileCacheService.BROADCAST_ACTION);
|
||||||
|
|
||||||
directoryStateReceiver =
|
|
||||||
new DirectoryStateReceiver(directoryInitializationState ->
|
|
||||||
{
|
|
||||||
if (directoryInitializationState ==
|
|
||||||
DirectoryInitialization.DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED)
|
|
||||||
{
|
|
||||||
tryPlay(playAction);
|
|
||||||
}
|
|
||||||
else if (directoryInitializationState ==
|
|
||||||
DirectoryInitialization.DirectoryInitializationState.EXTERNAL_STORAGE_PERMISSION_NEEDED)
|
|
||||||
{
|
|
||||||
Toast.makeText(this, R.string.write_permission_needed, Toast.LENGTH_SHORT)
|
|
||||||
.show();
|
|
||||||
}
|
|
||||||
else if (directoryInitializationState ==
|
|
||||||
DirectoryInitialization.DirectoryInitializationState.CANT_FIND_EXTERNAL_STORAGE)
|
|
||||||
{
|
|
||||||
Toast.makeText(this, R.string.external_storage_not_mounted, Toast.LENGTH_SHORT)
|
|
||||||
.show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
BroadcastReceiver gameFileCacheReceiver = new BroadcastReceiver()
|
BroadcastReceiver gameFileCacheReceiver = new BroadcastReceiver()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
@ -108,7 +84,6 @@ public class AppLinkActivity extends FragmentActivity
|
|||||||
};
|
};
|
||||||
|
|
||||||
LocalBroadcastManager broadcastManager = LocalBroadcastManager.getInstance(this);
|
LocalBroadcastManager broadcastManager = LocalBroadcastManager.getInstance(this);
|
||||||
broadcastManager.registerReceiver(directoryStateReceiver, directoryStateIntentFilter);
|
|
||||||
broadcastManager.registerReceiver(gameFileCacheReceiver, gameFileCacheIntentFilter);
|
broadcastManager.registerReceiver(gameFileCacheReceiver, gameFileCacheIntentFilter);
|
||||||
|
|
||||||
DirectoryInitialization.start(this);
|
DirectoryInitialization.start(this);
|
||||||
@ -160,10 +135,10 @@ public class AppLinkActivity extends FragmentActivity
|
|||||||
|
|
||||||
private void startGame(GameFile game)
|
private void startGame(GameFile game)
|
||||||
{
|
{
|
||||||
if (directoryStateReceiver != null)
|
if (mAfterDirectoryInitializationRunner != null)
|
||||||
{
|
{
|
||||||
LocalBroadcastManager.getInstance(this).unregisterReceiver(directoryStateReceiver);
|
mAfterDirectoryInitializationRunner.cancel();
|
||||||
directoryStateReceiver = null;
|
mAfterDirectoryInitializationRunner = null;
|
||||||
}
|
}
|
||||||
EmulationActivity.launch(this, game);
|
EmulationActivity.launch(this, game);
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ package org.dolphinemu.dolphinemu.features.settings.ui;
|
|||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
|
||||||
@ -11,7 +10,6 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.fragment.app.FragmentTransaction;
|
import androidx.fragment.app.FragmentTransaction;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
@ -22,8 +20,6 @@ import android.widget.Toast;
|
|||||||
import org.dolphinemu.dolphinemu.R;
|
import org.dolphinemu.dolphinemu.R;
|
||||||
import org.dolphinemu.dolphinemu.ui.main.MainActivity;
|
import org.dolphinemu.dolphinemu.ui.main.MainActivity;
|
||||||
import org.dolphinemu.dolphinemu.ui.main.TvMainActivity;
|
import org.dolphinemu.dolphinemu.ui.main.TvMainActivity;
|
||||||
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization;
|
|
||||||
import org.dolphinemu.dolphinemu.utils.DirectoryStateReceiver;
|
|
||||||
import org.dolphinemu.dolphinemu.utils.FileBrowserHelper;
|
import org.dolphinemu.dolphinemu.utils.FileBrowserHelper;
|
||||||
import org.dolphinemu.dolphinemu.utils.TvUtil;
|
import org.dolphinemu.dolphinemu.utils.TvUtil;
|
||||||
|
|
||||||
@ -150,22 +146,6 @@ public final class SettingsActivity extends AppCompatActivity implements Setting
|
|||||||
return duration != 0 && transition != 0;
|
return duration != 0 && transition != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void startDirectoryInitializationService(DirectoryStateReceiver receiver,
|
|
||||||
IntentFilter filter)
|
|
||||||
{
|
|
||||||
LocalBroadcastManager.getInstance(this).registerReceiver(
|
|
||||||
receiver,
|
|
||||||
filter);
|
|
||||||
DirectoryInitialization.start(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void stopListeningToDirectoryInitializationService(DirectoryStateReceiver receiver)
|
|
||||||
{
|
|
||||||
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent result)
|
protected void onActivityResult(int requestCode, int resultCode, Intent result)
|
||||||
{
|
{
|
||||||
@ -212,20 +192,6 @@ public final class SettingsActivity extends AppCompatActivity implements Setting
|
|||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void showPermissionNeededHint()
|
|
||||||
{
|
|
||||||
Toast.makeText(this, R.string.write_permission_needed, Toast.LENGTH_SHORT)
|
|
||||||
.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void showExternalStorageNotMountedHint()
|
|
||||||
{
|
|
||||||
Toast.makeText(this, R.string.external_storage_not_mounted, Toast.LENGTH_SHORT)
|
|
||||||
.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void showGameIniJunkDeletionQuestion()
|
public void showGameIniJunkDeletionQuestion()
|
||||||
{
|
{
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
package org.dolphinemu.dolphinemu.features.settings.ui;
|
package org.dolphinemu.dolphinemu.features.settings.ui;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.IntentFilter;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import org.dolphinemu.dolphinemu.R;
|
import org.dolphinemu.dolphinemu.R;
|
||||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
|
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
|
||||||
|
import org.dolphinemu.dolphinemu.utils.AfterDirectoryInitializationRunner;
|
||||||
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization;
|
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.Log;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -25,7 +23,7 @@ public final class SettingsActivityPresenter
|
|||||||
|
|
||||||
private boolean mShouldSave;
|
private boolean mShouldSave;
|
||||||
|
|
||||||
private DirectoryStateReceiver directoryStateReceiver;
|
private AfterDirectoryInitializationRunner mAfterDirectoryInitializationRunner;
|
||||||
|
|
||||||
private MenuTag menuTag;
|
private MenuTag menuTag;
|
||||||
private String gameId;
|
private String gameId;
|
||||||
@ -85,33 +83,10 @@ public final class SettingsActivityPresenter
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
mView.showLoading();
|
mView.showLoading();
|
||||||
IntentFilter statusIntentFilter = new IntentFilter(
|
|
||||||
DirectoryInitialization.BROADCAST_ACTION);
|
|
||||||
|
|
||||||
directoryStateReceiver =
|
mAfterDirectoryInitializationRunner = new AfterDirectoryInitializationRunner();
|
||||||
new DirectoryStateReceiver(directoryInitializationState ->
|
mAfterDirectoryInitializationRunner.setFinishedCallback(mView::hideLoading);
|
||||||
{
|
mAfterDirectoryInitializationRunner.run(context, true, this::loadSettingsUI);
|
||||||
if (directoryInitializationState ==
|
|
||||||
DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED)
|
|
||||||
{
|
|
||||||
mView.hideLoading();
|
|
||||||
loadSettingsUI();
|
|
||||||
}
|
|
||||||
else if (directoryInitializationState ==
|
|
||||||
DirectoryInitializationState.EXTERNAL_STORAGE_PERMISSION_NEEDED)
|
|
||||||
{
|
|
||||||
mView.showPermissionNeededHint();
|
|
||||||
mView.hideLoading();
|
|
||||||
}
|
|
||||||
else if (directoryInitializationState ==
|
|
||||||
DirectoryInitializationState.CANT_FIND_EXTERNAL_STORAGE)
|
|
||||||
{
|
|
||||||
mView.showExternalStorageNotMountedHint();
|
|
||||||
mView.hideLoading();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mView.startDirectoryInitializationService(directoryStateReceiver, statusIntentFilter);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,10 +103,10 @@ public final class SettingsActivityPresenter
|
|||||||
|
|
||||||
public void onStop(boolean finishing)
|
public void onStop(boolean finishing)
|
||||||
{
|
{
|
||||||
if (directoryStateReceiver != null)
|
if (mAfterDirectoryInitializationRunner != null)
|
||||||
{
|
{
|
||||||
mView.stopListeningToDirectoryInitializationService(directoryStateReceiver);
|
mAfterDirectoryInitializationRunner.cancel();
|
||||||
directoryStateReceiver = null;
|
mAfterDirectoryInitializationRunner = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mSettings != null && finishing && mShouldSave)
|
if (mSettings != null && finishing && mShouldSave)
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
package org.dolphinemu.dolphinemu.features.settings.ui;
|
package org.dolphinemu.dolphinemu.features.settings.ui;
|
||||||
|
|
||||||
import android.content.IntentFilter;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
|
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
|
||||||
import org.dolphinemu.dolphinemu.utils.DirectoryStateReceiver;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstraction for the Activity that manages SettingsFragments.
|
* Abstraction for the Activity that manages SettingsFragments.
|
||||||
@ -97,33 +95,8 @@ public interface SettingsActivityView
|
|||||||
*/
|
*/
|
||||||
void hideLoading();
|
void hideLoading();
|
||||||
|
|
||||||
/**
|
|
||||||
* Show a hint to the user that the app needs write to external storage access
|
|
||||||
*/
|
|
||||||
void showPermissionNeededHint();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show a hint to the user that the app needs the external storage to be mounted
|
|
||||||
*/
|
|
||||||
void showExternalStorageNotMountedHint();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tell the user that there is junk in the game INI and ask if they want to delete the whole file.
|
* Tell the user that there is junk in the game INI and ask if they want to delete the whole file.
|
||||||
*/
|
*/
|
||||||
void showGameIniJunkDeletionQuestion();
|
void showGameIniJunkDeletionQuestion();
|
||||||
|
|
||||||
/**
|
|
||||||
* Start the DirectoryInitialization and listen for the result.
|
|
||||||
*
|
|
||||||
* @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 DirectoryInitialization.
|
|
||||||
*
|
|
||||||
* @param receiver The broadcast receiver to unregister.
|
|
||||||
*/
|
|
||||||
void stopListeningToDirectoryInitializationService(DirectoryStateReceiver receiver);
|
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
package org.dolphinemu.dolphinemu.fragments;
|
package org.dolphinemu.dolphinemu.fragments;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.IntentFilter;
|
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
|
||||||
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
@ -17,15 +15,12 @@ import android.view.SurfaceView;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import org.dolphinemu.dolphinemu.NativeLibrary;
|
import org.dolphinemu.dolphinemu.NativeLibrary;
|
||||||
import org.dolphinemu.dolphinemu.R;
|
import org.dolphinemu.dolphinemu.R;
|
||||||
import org.dolphinemu.dolphinemu.activities.EmulationActivity;
|
import org.dolphinemu.dolphinemu.activities.EmulationActivity;
|
||||||
import org.dolphinemu.dolphinemu.overlay.InputOverlay;
|
import org.dolphinemu.dolphinemu.overlay.InputOverlay;
|
||||||
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization;
|
import org.dolphinemu.dolphinemu.utils.AfterDirectoryInitializationRunner;
|
||||||
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization.DirectoryInitializationState;
|
|
||||||
import org.dolphinemu.dolphinemu.utils.DirectoryStateReceiver;
|
|
||||||
import org.dolphinemu.dolphinemu.utils.Log;
|
import org.dolphinemu.dolphinemu.utils.Log;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -40,7 +35,7 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
|
|||||||
|
|
||||||
private EmulationState mEmulationState;
|
private EmulationState mEmulationState;
|
||||||
|
|
||||||
private DirectoryStateReceiver directoryStateReceiver;
|
private AfterDirectoryInitializationRunner mAfterDirectoryInitializationRunner;
|
||||||
|
|
||||||
private EmulationActivity activity;
|
private EmulationActivity activity;
|
||||||
|
|
||||||
@ -115,23 +110,19 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
|
|||||||
public void onResume()
|
public void onResume()
|
||||||
{
|
{
|
||||||
super.onResume();
|
super.onResume();
|
||||||
if (DirectoryInitialization.areDolphinDirectoriesReady())
|
|
||||||
{
|
mAfterDirectoryInitializationRunner = new AfterDirectoryInitializationRunner();
|
||||||
mEmulationState.run(activity.isActivityRecreated());
|
mAfterDirectoryInitializationRunner.run(requireContext(), true,
|
||||||
}
|
() -> mEmulationState.run(activity.isActivityRecreated()));
|
||||||
else
|
|
||||||
{
|
|
||||||
setupDolphinDirectoriesThenStartEmulation();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPause()
|
public void onPause()
|
||||||
{
|
{
|
||||||
if (directoryStateReceiver != null)
|
if (mAfterDirectoryInitializationRunner != null)
|
||||||
{
|
{
|
||||||
LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(directoryStateReceiver);
|
mAfterDirectoryInitializationRunner.cancel();
|
||||||
directoryStateReceiver = null;
|
mAfterDirectoryInitializationRunner = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mEmulationState.isRunning())
|
if (mEmulationState.isRunning())
|
||||||
@ -146,41 +137,6 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
|
|||||||
super.onDetach();
|
super.onDetach();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupDolphinDirectoriesThenStartEmulation()
|
|
||||||
{
|
|
||||||
IntentFilter statusIntentFilter = new IntentFilter(
|
|
||||||
DirectoryInitialization.BROADCAST_ACTION);
|
|
||||||
|
|
||||||
directoryStateReceiver =
|
|
||||||
new DirectoryStateReceiver(directoryInitializationState ->
|
|
||||||
{
|
|
||||||
if (directoryInitializationState ==
|
|
||||||
DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED)
|
|
||||||
{
|
|
||||||
mEmulationState.run(activity.isActivityRecreated());
|
|
||||||
}
|
|
||||||
else if (directoryInitializationState ==
|
|
||||||
DirectoryInitializationState.EXTERNAL_STORAGE_PERMISSION_NEEDED)
|
|
||||||
{
|
|
||||||
Toast.makeText(getContext(), R.string.write_permission_needed, Toast.LENGTH_SHORT)
|
|
||||||
.show();
|
|
||||||
}
|
|
||||||
else if (directoryInitializationState ==
|
|
||||||
DirectoryInitializationState.CANT_FIND_EXTERNAL_STORAGE)
|
|
||||||
{
|
|
||||||
Toast.makeText(getContext(), R.string.external_storage_not_mounted,
|
|
||||||
Toast.LENGTH_SHORT)
|
|
||||||
.show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Registers the DirectoryStateReceiver and its intent filters
|
|
||||||
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(
|
|
||||||
directoryStateReceiver,
|
|
||||||
statusIntentFilter);
|
|
||||||
DirectoryInitialization.start(getActivity());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void toggleInputOverlayVisibility()
|
public void toggleInputOverlayVisibility()
|
||||||
{
|
{
|
||||||
SharedPreferences.Editor editor = mPreferences.edit();
|
SharedPreferences.Editor editor = mPreferences.edit();
|
||||||
|
@ -109,7 +109,7 @@ public final class GameFileCacheService extends IntentService
|
|||||||
*/
|
*/
|
||||||
public static void startLoad(Context context)
|
public static void startLoad(Context context)
|
||||||
{
|
{
|
||||||
new AfterDirectoryInitializationRunner().run(context,
|
new AfterDirectoryInitializationRunner().run(context, false,
|
||||||
() -> startService(context, ACTION_LOAD));
|
() -> startService(context, ACTION_LOAD));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +120,7 @@ public final class GameFileCacheService extends IntentService
|
|||||||
*/
|
*/
|
||||||
public static void startRescan(Context context)
|
public static void startRescan(Context context)
|
||||||
{
|
{
|
||||||
new AfterDirectoryInitializationRunner().run(context,
|
new AfterDirectoryInitializationRunner().run(context, false,
|
||||||
() -> startService(context, ACTION_RESCAN));
|
() -> startService(context, ACTION_RESCAN));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ public final class MainActivity extends AppCompatActivity implements MainView
|
|||||||
if (PermissionsHandler.hasWriteAccess(this))
|
if (PermissionsHandler.hasWriteAccess(this))
|
||||||
{
|
{
|
||||||
new AfterDirectoryInitializationRunner()
|
new AfterDirectoryInitializationRunner()
|
||||||
.run(this, this::setPlatformTabsAndStartGameFileCacheService);
|
.run(this, false, this::setPlatformTabsAndStartGameFileCacheService);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,7 +213,7 @@ public final class MainActivity extends AppCompatActivity implements MainView
|
|||||||
{
|
{
|
||||||
DirectoryInitialization.start(this);
|
DirectoryInitialization.start(this);
|
||||||
new AfterDirectoryInitializationRunner()
|
new AfterDirectoryInitializationRunner()
|
||||||
.run(this, this::setPlatformTabsAndStartGameFileCacheService);
|
.run(this, false, this::setPlatformTabsAndStartGameFileCacheService);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2,12 +2,38 @@ package org.dolphinemu.dolphinemu.utils;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||||
|
|
||||||
|
import org.dolphinemu.dolphinemu.R;
|
||||||
|
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization.DirectoryInitializationState;
|
||||||
|
|
||||||
public class AfterDirectoryInitializationRunner
|
public class AfterDirectoryInitializationRunner
|
||||||
{
|
{
|
||||||
private DirectoryStateReceiver directoryStateReceiver;
|
private DirectoryStateReceiver mDirectoryStateReceiver;
|
||||||
|
private LocalBroadcastManager mLocalBroadcastManager;
|
||||||
|
|
||||||
|
private Runnable mUnregisterCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a Runnable which will be called when:
|
||||||
|
*
|
||||||
|
* 1. The Runnable supplied to {@link #run} is just about to run, or
|
||||||
|
* 2. {@link #run} was called with abortOnFailure == true and there is a failure
|
||||||
|
*/
|
||||||
|
public void setFinishedCallback(Runnable runnable)
|
||||||
|
{
|
||||||
|
mUnregisterCallback = runnable;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runFinishedCallback()
|
||||||
|
{
|
||||||
|
if (mUnregisterCallback != null)
|
||||||
|
{
|
||||||
|
mUnregisterCallback.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes a Runnable after directory initialization has finished.
|
* Executes a Runnable after directory initialization has finished.
|
||||||
@ -19,33 +45,84 @@ public class AfterDirectoryInitializationRunner
|
|||||||
* in case directory initialization doesn't finish successfully.
|
* in case directory initialization doesn't finish successfully.
|
||||||
*
|
*
|
||||||
* Calling this function multiple times per object is not supported.
|
* Calling this function multiple times per object is not supported.
|
||||||
|
*
|
||||||
|
* If abortOnFailure is true and the user has not granted the required
|
||||||
|
* permission or the external storage was not found, a message will be
|
||||||
|
* shown to the user and the Runnable will not run. If it is false, the
|
||||||
|
* attempt to run the Runnable will never be aborted, and the Runnable
|
||||||
|
* is guaranteed to run if directory initialization ever finishes.
|
||||||
*/
|
*/
|
||||||
public void run(Context context, Runnable runnable)
|
public void run(Context context, boolean abortOnFailure, Runnable runnable)
|
||||||
{
|
{
|
||||||
if (!DirectoryInitialization.areDolphinDirectoriesReady())
|
if (DirectoryInitialization.areDolphinDirectoriesReady())
|
||||||
{
|
{
|
||||||
// Wait for directories to get initialized
|
runFinishedCallback();
|
||||||
IntentFilter statusIntentFilter = new IntentFilter(
|
runnable.run();
|
||||||
DirectoryInitialization.BROADCAST_ACTION);
|
}
|
||||||
|
else if (abortOnFailure &&
|
||||||
directoryStateReceiver = new DirectoryStateReceiver(directoryInitializationState ->
|
showErrorMessage(context, DirectoryInitialization.getDolphinDirectoriesState(context)))
|
||||||
{
|
{
|
||||||
if (directoryInitializationState ==
|
runFinishedCallback();
|
||||||
DirectoryInitialization.DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED)
|
|
||||||
{
|
|
||||||
LocalBroadcastManager.getInstance(context).unregisterReceiver(directoryStateReceiver);
|
|
||||||
directoryStateReceiver = null;
|
|
||||||
runnable.run();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// Registers the DirectoryStateReceiver and its intent filters
|
|
||||||
LocalBroadcastManager.getInstance(context).registerReceiver(
|
|
||||||
directoryStateReceiver,
|
|
||||||
statusIntentFilter);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
runnable.run();
|
runAfterInitialization(context, abortOnFailure, runnable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runAfterInitialization(Context context, boolean abortOnFailure, Runnable runnable)
|
||||||
|
{
|
||||||
|
mDirectoryStateReceiver = new DirectoryStateReceiver(state ->
|
||||||
|
{
|
||||||
|
boolean done = state == DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED;
|
||||||
|
|
||||||
|
if (!done && abortOnFailure)
|
||||||
|
{
|
||||||
|
done = showErrorMessage(context, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (done)
|
||||||
|
{
|
||||||
|
cancel();
|
||||||
|
runFinishedCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state == DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED)
|
||||||
|
{
|
||||||
|
runnable.run();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mLocalBroadcastManager = LocalBroadcastManager.getInstance(context);
|
||||||
|
|
||||||
|
IntentFilter statusIntentFilter = new IntentFilter(DirectoryInitialization.BROADCAST_ACTION);
|
||||||
|
mLocalBroadcastManager.registerReceiver(mDirectoryStateReceiver, statusIntentFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cancel()
|
||||||
|
{
|
||||||
|
if (mDirectoryStateReceiver != null)
|
||||||
|
{
|
||||||
|
mLocalBroadcastManager.unregisterReceiver(mDirectoryStateReceiver);
|
||||||
|
mDirectoryStateReceiver = null;
|
||||||
|
mLocalBroadcastManager = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean showErrorMessage(Context context, DirectoryInitializationState state)
|
||||||
|
{
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case EXTERNAL_STORAGE_PERMISSION_NEEDED:
|
||||||
|
Toast.makeText(context, R.string.write_permission_needed, Toast.LENGTH_SHORT).show();
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case CANT_FIND_EXTERNAL_STORAGE:
|
||||||
|
Toast.makeText(context, R.string.external_storage_not_mounted, Toast.LENGTH_SHORT).show();
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ public class Analytics
|
|||||||
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
|
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
if (!preferences.getBoolean(analyticsAsked, false))
|
if (!preferences.getBoolean(analyticsAsked, false))
|
||||||
{
|
{
|
||||||
new AfterDirectoryInitializationRunner().run(context,
|
new AfterDirectoryInitializationRunner().run(context, false,
|
||||||
() -> showMessage(context, preferences));
|
() -> showMessage(context, preferences));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,13 +37,15 @@ public final class DirectoryInitialization
|
|||||||
|
|
||||||
public static final String EXTRA_STATE = "directoryState";
|
public static final String EXTRA_STATE = "directoryState";
|
||||||
private static final int WiimoteNewVersion = 5; // Last changed in PR 8907
|
private static final int WiimoteNewVersion = 5; // Last changed in PR 8907
|
||||||
private static volatile DirectoryInitializationState directoryState = null;
|
private static volatile DirectoryInitializationState directoryState =
|
||||||
|
DirectoryInitializationState.NOT_YET_INITIALIZED;
|
||||||
private static String userPath;
|
private static String userPath;
|
||||||
private static String internalPath;
|
private static String internalPath;
|
||||||
private static AtomicBoolean isDolphinDirectoryInitializationRunning = new AtomicBoolean(false);
|
private static AtomicBoolean isDolphinDirectoryInitializationRunning = new AtomicBoolean(false);
|
||||||
|
|
||||||
public enum DirectoryInitializationState
|
public enum DirectoryInitializationState
|
||||||
{
|
{
|
||||||
|
NOT_YET_INITIALIZED,
|
||||||
DOLPHIN_DIRECTORIES_INITIALIZED,
|
DOLPHIN_DIRECTORIES_INITIALIZED,
|
||||||
EXTERNAL_STORAGE_PERMISSION_NEEDED,
|
EXTERNAL_STORAGE_PERMISSION_NEEDED,
|
||||||
CANT_FIND_EXTERNAL_STORAGE
|
CANT_FIND_EXTERNAL_STORAGE
|
||||||
@ -199,9 +201,22 @@ public final class DirectoryInitialization
|
|||||||
return directoryState == DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED;
|
return directoryState == DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static DirectoryInitializationState getDolphinDirectoriesState(Context context)
|
||||||
|
{
|
||||||
|
if (directoryState == DirectoryInitializationState.NOT_YET_INITIALIZED &&
|
||||||
|
!PermissionsHandler.hasWriteAccess(context))
|
||||||
|
{
|
||||||
|
return DirectoryInitializationState.EXTERNAL_STORAGE_PERMISSION_NEEDED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return directoryState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static String getUserDirectory()
|
public static String getUserDirectory()
|
||||||
{
|
{
|
||||||
if (directoryState == null)
|
if (directoryState == DirectoryInitializationState.NOT_YET_INITIALIZED)
|
||||||
{
|
{
|
||||||
throw new IllegalStateException("DirectoryInitialization has to run at least once!");
|
throw new IllegalStateException("DirectoryInitialization has to run at least once!");
|
||||||
}
|
}
|
||||||
@ -216,7 +231,7 @@ public final class DirectoryInitialization
|
|||||||
|
|
||||||
public static String getDolphinInternalDirectory()
|
public static String getDolphinInternalDirectory()
|
||||||
{
|
{
|
||||||
if (directoryState == null)
|
if (directoryState == DirectoryInitializationState.NOT_YET_INITIALIZED)
|
||||||
{
|
{
|
||||||
throw new IllegalStateException("DirectoryInitialization has to run at least once!");
|
throw new IllegalStateException("DirectoryInitialization has to run at least once!");
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ public final class StartupHandler
|
|||||||
long lastOpen = preferences.getLong(LAST_CLOSED, 0);
|
long lastOpen = preferences.getLong(LAST_CLOSED, 0);
|
||||||
if (currentTime > (lastOpen + SESSION_TIMEOUT))
|
if (currentTime > (lastOpen + SESSION_TIMEOUT))
|
||||||
{
|
{
|
||||||
new AfterDirectoryInitializationRunner().run(context,
|
new AfterDirectoryInitializationRunner().run(context, false,
|
||||||
NativeLibrary::ReportStartToAnalytics);
|
NativeLibrary::ReportStartToAnalytics);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user