summaryrefslogtreecommitdiff
path: root/Source/Android/app/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Android/app/src/main/java')
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/AddDirectoryActivity.java8
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/MainActivity.java173
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/SettingsActivity.java7
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/TvMainActivity.java146
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.java4
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.java176
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainPresenter.java95
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainView.java47
8 files changed, 394 insertions, 262 deletions
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/AddDirectoryActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/AddDirectoryActivity.java
index f9308fc80e..09e833d1ad 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/AddDirectoryActivity.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/AddDirectoryActivity.java
@@ -1,5 +1,6 @@
package org.dolphinemu.dolphinemu.activities;
+import android.app.Activity;
import android.content.AsyncQueryHandler;
import android.content.ContentValues;
import android.content.Intent;
@@ -19,6 +20,7 @@ import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.adapters.FileAdapter;
import org.dolphinemu.dolphinemu.model.GameDatabase;
import org.dolphinemu.dolphinemu.model.GameProvider;
+import org.dolphinemu.dolphinemu.ui.main.MainPresenter;
/**
* An Activity that shows a list of files and folders, allowing the user to tell the app which folder(s)
@@ -131,4 +133,10 @@ public class AddDirectoryActivity extends AppCompatActivity implements FileAdapt
{
mToolbar.setSubtitle(path);
}
+
+ public static void launch(Activity activity)
+ {
+ Intent fileChooser = new Intent(activity, AddDirectoryActivity.class);
+ activity.startActivityForResult(fileChooser, MainPresenter.REQUEST_ADD_DIRECTORY);
+ }
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/MainActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/MainActivity.java
deleted file mode 100644
index 5dc3bbd983..0000000000
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/MainActivity.java
+++ /dev/null
@@ -1,173 +0,0 @@
-package org.dolphinemu.dolphinemu.activities;
-
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.database.Cursor;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.support.annotation.Nullable;
-import android.support.design.widget.FloatingActionButton;
-import android.support.design.widget.TabLayout;
-import android.support.v4.view.ViewPager;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.Toolbar;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-
-import org.dolphinemu.dolphinemu.NativeLibrary;
-import org.dolphinemu.dolphinemu.R;
-import org.dolphinemu.dolphinemu.adapters.PlatformPagerAdapter;
-import org.dolphinemu.dolphinemu.fragments.PlatformGamesFragment;
-import org.dolphinemu.dolphinemu.model.Game;
-import org.dolphinemu.dolphinemu.model.GameDatabase;
-import org.dolphinemu.dolphinemu.model.GameProvider;
-import org.dolphinemu.dolphinemu.services.AssetCopyService;
-import org.dolphinemu.dolphinemu.utils.StartupHandler;
-
-/**
- * The main Activity of the Lollipop style UI. Manages several PlatformGamesFragments, which
- * individually display a grid of available games for each Fragment, in a tabbed layout.
- */
-public final class MainActivity extends AppCompatActivity
-{
- public static final int REQUEST_ADD_DIRECTORY = 1;
- public static final int REQUEST_EMULATE_GAME = 2;
-
- private ViewPager mViewPager;
- private PlatformPagerAdapter mPlatformPagerAdapter;
-
- @Override
- protected void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- // Set up the Toolbar.
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar_main);
- setSupportActionBar(toolbar);
-
- // TODO Rather than calling into native code, this should use the commented line below.
- // String versionName = BuildConfig.VERSION_NAME;
- String versionName = NativeLibrary.GetVersionString();
- toolbar.setSubtitle(versionName);
-
- // Set up the Tab bar.
- mViewPager = (ViewPager) findViewById(R.id.pager_platforms);
-
- mPlatformPagerAdapter = new PlatformPagerAdapter(getFragmentManager(), this);
- mViewPager.setAdapter(mPlatformPagerAdapter);
-
- TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs_platforms);
- tabLayout.setupWithViewPager(mViewPager);
-
- // Set up the FAB.
- FloatingActionButton buttonAddDirectory = (FloatingActionButton) findViewById(R.id.button_add_directory);
- buttonAddDirectory.setOnClickListener(new View.OnClickListener()
- {
- @Override
- public void onClick(View view)
- {
- Intent fileChooser = new Intent(MainActivity.this, AddDirectoryActivity.class);
-
- // The second argument to this method is read below in onActivityResult().
- startActivityForResult(fileChooser, REQUEST_ADD_DIRECTORY);
- }
- });
-
- // Stuff in this block only happens when this activity is newly created (i.e. not a rotation)
- if (savedInstanceState == null)
- StartupHandler.HandleInit(this);
- }
-
- /**
- * Callback from AddDirectoryActivity. Applies any changes necessary to the GameGridActivity.
- *
- * @param requestCode An int describing whether the Activity that is returning did so successfully.
- * @param resultCode An int describing what Activity is giving us this callback.
- * @param result The information the returning Activity is providing us.
- */
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent result)
- {
- switch (requestCode)
- {
- case REQUEST_ADD_DIRECTORY:
- // If the user picked a file, as opposed to just backing out.
- if (resultCode == RESULT_OK)
- {
- // Sanity check to make sure the Activity that just returned was the AddDirectoryActivity;
- // other activities might use this callback in the future (don't forget to change Javadoc!)
- if (requestCode == REQUEST_ADD_DIRECTORY)
- {
- refreshFragment();
- }
- }
- break;
-
- case REQUEST_EMULATE_GAME:
- // Invalidate Picasso image so that the new screenshot is animated in.
- PlatformGamesFragment fragment = getPlatformFragment(mViewPager.getCurrentItem());
-
- if (fragment != null)
- {
- fragment.refreshScreenshotAtPosition(resultCode);
- }
- break;
- }
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu)
- {
- MenuInflater inflater = getMenuInflater();
- inflater.inflate(R.menu.menu_game_grid, menu);
- return true;
- }
-
- /**
- * Called by the framework whenever any actionbar/toolbar icon is clicked.
- *
- * @param item The icon that was clicked on.
- * @return True if the event was handled, false to bubble it up to the OS.
- */
- @Override
- public boolean onOptionsItemSelected(MenuItem item)
- {
- switch (item.getItemId())
- {
- case R.id.menu_settings:
- // Launch the Settings Actvity.
- Intent settings = new Intent(this, SettingsActivity.class);
- startActivity(settings);
- return true;
-
- case R.id.menu_refresh:
- getContentResolver().insert(GameProvider.URI_REFRESH, null);
- refreshFragment();
-
- return true;
- }
-
- return false;
- }
-
- public void refreshFragment()
- {
- PlatformGamesFragment fragment = getPlatformFragment(mViewPager.getCurrentItem());
- if (fragment != null)
- {
- fragment.refresh();
- }
- }
-
- @Nullable
- public PlatformGamesFragment getPlatformFragment(int platform)
- {
- String fragmentTag = "android:switcher:" + mViewPager.getId() + ":" + platform;
-
- return (PlatformGamesFragment) getFragmentManager().findFragmentByTag(fragmentTag);
- }
-}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/SettingsActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/SettingsActivity.java
index a595cdeb0f..c6ce27acfe 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/SettingsActivity.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/SettingsActivity.java
@@ -1,6 +1,7 @@
package org.dolphinemu.dolphinemu.activities;
+import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
@@ -38,4 +39,10 @@ public final class SettingsActivity extends AppCompatActivity
Intent settingsSaver = new Intent(this, SettingsSaveService.class);
startService(settingsSaver);
}
+
+ public static void launch(Context context)
+ {
+ Intent settings = new Intent(context, SettingsActivity.class);
+ context.startActivity(settings);
+ }
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/TvMainActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/TvMainActivity.java
index a01e080549..6d580eaafb 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/TvMainActivity.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/TvMainActivity.java
@@ -4,10 +4,8 @@ import android.app.Activity;
import android.app.ActivityOptions;
import android.app.FragmentManager;
import android.content.Intent;
-import android.content.SharedPreferences;
import android.database.Cursor;
import android.os.Bundle;
-import android.preference.PreferenceManager;
import android.support.v17.leanback.app.BrowseFragment;
import android.support.v17.leanback.database.CursorMapper;
import android.support.v17.leanback.widget.ArrayObjectAdapter;
@@ -19,23 +17,22 @@ import android.support.v17.leanback.widget.OnItemViewClickedListener;
import android.support.v17.leanback.widget.Presenter;
import android.support.v17.leanback.widget.Row;
import android.support.v17.leanback.widget.RowPresenter;
-import android.widget.Toast;
-import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.adapters.GameRowPresenter;
import org.dolphinemu.dolphinemu.adapters.SettingsRowPresenter;
import org.dolphinemu.dolphinemu.model.Game;
-import org.dolphinemu.dolphinemu.model.GameDatabase;
-import org.dolphinemu.dolphinemu.model.GameProvider;
import org.dolphinemu.dolphinemu.model.TvSettingsItem;
-import org.dolphinemu.dolphinemu.services.AssetCopyService;
+import org.dolphinemu.dolphinemu.ui.main.MainPresenter;
+import org.dolphinemu.dolphinemu.ui.main.MainView;
import org.dolphinemu.dolphinemu.utils.StartupHandler;
import org.dolphinemu.dolphinemu.viewholders.TvGameViewHolder;
-public final class TvMainActivity extends Activity
+public final class TvMainActivity extends Activity implements MainView
{
- protected BrowseFragment mBrowseFragment;
+ private MainPresenter mPresenter = new MainPresenter(this);
+
+ private BrowseFragment mBrowseFragment;
private ArrayObjectAdapter mRowsAdapter;
@@ -58,6 +55,8 @@ public final class TvMainActivity extends Activity
buildRowsAdapter();
+ mPresenter.onCreate();
+
mBrowseFragment.setOnItemViewClickedListener(
new OnItemViewClickedListener()
{
@@ -68,34 +67,7 @@ public final class TvMainActivity extends Activity
if (item instanceof TvSettingsItem)
{
TvSettingsItem settingsItem = (TvSettingsItem) item;
-
- switch (settingsItem.getItemId())
- {
- case R.id.menu_refresh:
- getContentResolver().insert(GameProvider.URI_REFRESH, null);
-
- // TODO Let the Activity know the data is refreshed in some other, better way.
- recreate();
- break;
-
- case R.id.menu_settings:
- // Launch the Settings Actvity.
- Intent settings = new Intent(TvMainActivity.this, SettingsActivity.class);
- startActivity(settings);
- break;
-
- case R.id.button_add_directory:
- Intent fileChooser = new Intent(TvMainActivity.this, AddDirectoryActivity.class);
-
- // The second argument to this method is read below in onActivityResult().
- startActivityForResult(fileChooser, MainActivity.REQUEST_ADD_DIRECTORY);
-
- break;
-
- default:
- Toast.makeText(TvMainActivity.this, "Unimplemented menu option.", Toast.LENGTH_SHORT).show();
- break;
- }
+ mPresenter.handleOptionSelection(settingsItem.getItemId());
}
else
{
@@ -123,6 +95,52 @@ public final class TvMainActivity extends Activity
}
/**
+ * MainView
+ */
+
+ @Override
+ public void setVersionString(String version)
+ {
+ // No-op
+ }
+
+ @Override
+ public void refresh()
+ {
+ recreate();
+ }
+
+ @Override
+ public void refreshFragmentScreenshot(int fragmentPosition)
+ {
+ // No-op (For now)
+ }
+
+ @Override
+ public void launchSettingsActivity()
+ {
+ SettingsActivity.launch(this);
+ }
+
+ @Override
+ public void launchFileListActivity()
+ {
+ AddDirectoryActivity.launch(this);
+ }
+
+ @Override
+ public void showGames(int platformIndex, Cursor games)
+ {
+ ListRow row = buildGamesRow(platformIndex, games);
+
+ // Add row to the adapter only if it is not empty.
+ if (row != null)
+ {
+ mRowsAdapter.add(row);
+ }
+ }
+
+ /**
* Callback from AddDirectoryActivity. Applies any changes necessary to the GameGridActivity.
*
* @param requestCode An int describing whether the Activity that is returning did so successfully.
@@ -132,22 +150,7 @@ public final class TvMainActivity extends Activity
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent result)
{
- switch (requestCode)
- {
- case MainActivity.REQUEST_ADD_DIRECTORY:
- // If the user picked a file, as opposed to just backing out.
- if (resultCode == RESULT_OK)
- {
- // Sanity check to make sure the Activity that just returned was the AddDirectoryActivity;
- // other activities might use this callback in the future (don't forget to change Javadoc!)
- if (requestCode == MainActivity.REQUEST_ADD_DIRECTORY)
- {
- // TODO Let the Activity know the data is refreshed in some other, better way.
- recreate();
- }
- }
- break;
- }
+ mPresenter.handleActivityResult(requestCode, resultCode);
}
private void buildRowsAdapter()
@@ -157,50 +160,19 @@ public final class TvMainActivity extends Activity
// For each platform
for (int platformIndex = 0; platformIndex <= Game.PLATFORM_ALL; ++platformIndex)
{
- ListRow row = buildGamesRow(platformIndex);
-
- // Add row to the adapter only if it is not empty.
- if (row != null)
- {
- mRowsAdapter.add(row);
- }
+ mPresenter.loadGames(platformIndex);
}
- ListRow settingsRow = buildSettingsRow();
- mRowsAdapter.add(settingsRow);
+ mRowsAdapter.add(buildSettingsRow());
mBrowseFragment.setAdapter(mRowsAdapter);
}
- private ListRow buildGamesRow(int platform)
+ private ListRow buildGamesRow(int platform, Cursor games)
{
// Create an adapter for this row.
CursorObjectAdapter row = new CursorObjectAdapter(new GameRowPresenter());
- Cursor games;
- if (platform == Game.PLATFORM_ALL)
- {
- // Get all games.
- games = getContentResolver().query(
- GameProvider.URI_GAME, // URI of table to query
- null, // Return all columns
- null, // Return all games
- null, // Return all games
- GameDatabase.KEY_GAME_TITLE + " asc" // Sort by game name, ascending order
- );
- }
- else
- {
- // Get games for this particular platform.
- games = getContentResolver().query(
- GameProvider.URI_GAME, // URI of table to query
- null, // Return all columns
- GameDatabase.KEY_GAME_PLATFORM + " = ?", // Select by platform
- new String[]{Integer.toString(platform)}, // Platform id
- GameDatabase.KEY_GAME_TITLE + " asc" // Sort by game name, ascending order
- );
- }
-
// If cursor is empty, don't return a Row.
if (!games.moveToFirst())
{
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.java
index e74bd6f96d..205447e054 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.java
@@ -17,9 +17,9 @@ import com.squareup.picasso.Picasso;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.activities.EmulationActivity;
-import org.dolphinemu.dolphinemu.activities.MainActivity;
import org.dolphinemu.dolphinemu.dialogs.GameDetailsDialog;
import org.dolphinemu.dolphinemu.model.GameDatabase;
+import org.dolphinemu.dolphinemu.ui.main.MainPresenter;
import org.dolphinemu.dolphinemu.viewholders.GameViewHolder;
/**
@@ -231,7 +231,7 @@ public final class GameAdapter extends RecyclerView.Adapter<GameViewHolder> impl
"image_game_screenshot");
((Activity) view.getContext()).startActivityForResult(intent,
- MainActivity.REQUEST_EMULATE_GAME,
+ MainPresenter.REQUEST_EMULATE_GAME,
options.toBundle());
}
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
new file mode 100644
index 0000000000..372edd3249
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.java
@@ -0,0 +1,176 @@
+package org.dolphinemu.dolphinemu.ui.main;
+
+import android.content.Intent;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.design.widget.FloatingActionButton;
+import android.support.design.widget.TabLayout;
+import android.support.v4.view.ViewPager;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.Toolbar;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+
+import org.dolphinemu.dolphinemu.R;
+import org.dolphinemu.dolphinemu.activities.AddDirectoryActivity;
+import org.dolphinemu.dolphinemu.activities.SettingsActivity;
+import org.dolphinemu.dolphinemu.adapters.PlatformPagerAdapter;
+import org.dolphinemu.dolphinemu.fragments.PlatformGamesFragment;
+import org.dolphinemu.dolphinemu.model.GameProvider;
+import org.dolphinemu.dolphinemu.utils.StartupHandler;
+
+/**
+ * The main Activity of the Lollipop style UI. Manages several PlatformGamesFragments, which
+ * individually display a grid of available games for each Fragment, in a tabbed layout.
+ */
+public final class MainActivity extends AppCompatActivity implements MainView
+{
+ private ViewPager mViewPager;
+ private Toolbar mToolbar;
+ private TabLayout mTabLayout;
+ private FloatingActionButton mFab;
+
+ private MainPresenter mPresenter = new MainPresenter(this);
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ findViews();
+
+ setSupportActionBar(mToolbar);
+
+ PlatformPagerAdapter platformPagerAdapter = new PlatformPagerAdapter(getFragmentManager(), this);
+
+ mViewPager.setAdapter(platformPagerAdapter);
+ mTabLayout.setupWithViewPager(mViewPager);
+
+ // Set up the FAB.
+ mFab.setOnClickListener(new View.OnClickListener()
+ {
+ @Override
+ public void onClick(View view)
+ {
+ mPresenter.onFabClick();
+ }
+ });
+
+ mPresenter.onCreate();
+
+ // Stuff in this block only happens when this activity is newly created (i.e. not a rotation)
+ // TODO Split some of this stuff into Application.onCreate()
+ if (savedInstanceState == null)
+ StartupHandler.HandleInit(this);
+ }
+
+ // TODO: Replace with a ButterKnife injection.
+ private void findViews()
+ {
+ mToolbar = (Toolbar) findViewById(R.id.toolbar_main);
+ mViewPager = (ViewPager) findViewById(R.id.pager_platforms);
+ mTabLayout = (TabLayout) findViewById(R.id.tabs_platforms);
+ mFab = (FloatingActionButton) findViewById(R.id.button_add_directory);
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu)
+ {
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.menu_game_grid, menu);
+ return true;
+ }
+
+ /**
+ * MainView
+ */
+
+ @Override
+ public void setVersionString(String version)
+ {
+ mToolbar.setSubtitle(version);
+ }
+
+ @Override
+ public void refresh()
+ {
+ getContentResolver().insert(GameProvider.URI_REFRESH, null);
+ refreshFragment();
+ }
+
+ @Override
+ public void refreshFragmentScreenshot(int fragmentPosition)
+ {
+ // Invalidate Picasso image so that the new screenshot is animated in.
+ PlatformGamesFragment fragment = getPlatformFragment(mViewPager.getCurrentItem());
+
+ if (fragment != null)
+ {
+ fragment.refreshScreenshotAtPosition(fragmentPosition);
+ }
+ }
+
+ @Override
+ public void launchSettingsActivity()
+ {
+ SettingsActivity.launch(this);
+ }
+
+ @Override
+ public void launchFileListActivity()
+ {
+ AddDirectoryActivity.launch(this);
+ }
+
+ @Override
+ public void showGames(int platformIndex, Cursor games)
+ {
+ // no-op. Handled by PlatformGamesFragment.
+ }
+
+ /**
+ * Callback from AddDirectoryActivity. Applies any changes necessary to the GameGridActivity.
+ *
+ * @param requestCode An int describing whether the Activity that is returning did so successfully.
+ * @param resultCode An int describing what Activity is giving us this callback.
+ * @param result The information the returning Activity is providing us.
+ */
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent result)
+ {
+ mPresenter.handleActivityResult(requestCode, resultCode);
+ }
+
+ /**
+ * Called by the framework whenever any actionbar/toolbar icon is clicked.
+ *
+ * @param item The icon that was clicked on.
+ * @return True if the event was handled, false to bubble it up to the OS.
+ */
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item)
+ {
+ return mPresenter.handleOptionSelection(item.getItemId());
+ }
+
+ private void refreshFragment()
+ {
+ PlatformGamesFragment fragment = getPlatformFragment(mViewPager.getCurrentItem());
+ if (fragment != null)
+ {
+ fragment.refresh();
+ }
+ }
+
+ @Nullable
+ private PlatformGamesFragment getPlatformFragment(int platform)
+ {
+ String fragmentTag = "android:switcher:" + mViewPager.getId() + ":" + platform;
+
+ return (PlatformGamesFragment) getFragmentManager().findFragmentByTag(fragmentTag);
+ }
+}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainPresenter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainPresenter.java
new file mode 100644
index 0000000000..97b7a39f25
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainPresenter.java
@@ -0,0 +1,95 @@
+package org.dolphinemu.dolphinemu.ui.main;
+
+
+import android.database.Cursor;
+
+import org.dolphinemu.dolphinemu.DolphinApplication;
+import org.dolphinemu.dolphinemu.NativeLibrary;
+import org.dolphinemu.dolphinemu.R;
+import org.dolphinemu.dolphinemu.model.GameDatabase;
+
+import rx.android.schedulers.AndroidSchedulers;
+import rx.functions.Action1;
+import rx.schedulers.Schedulers;
+
+public final class MainPresenter
+{
+ public static final int REQUEST_ADD_DIRECTORY = 1;
+ public static final int REQUEST_EMULATE_GAME = 2;
+
+ private final MainView mView;
+
+ public MainPresenter(MainView view)
+ {
+ mView = view;
+ }
+
+ public void onCreate()
+ {
+ // TODO Rather than calling into native code, this should use the commented line below.
+ // String versionName = BuildConfig.VERSION_NAME;
+ String versionName = NativeLibrary.GetVersionString();
+ mView.setVersionString(versionName);
+ }
+
+ public void onFabClick()
+ {
+ mView.launchFileListActivity();
+ }
+
+ public boolean handleOptionSelection(int itemId)
+ {
+ switch (itemId)
+ {
+ case R.id.menu_settings:
+ mView.launchSettingsActivity();
+ return true;
+
+ case R.id.menu_refresh:
+ mView.refresh();
+ return true;
+
+ case R.id.button_add_directory:
+ mView.launchFileListActivity();
+ return true;
+ }
+
+ return false;
+ }
+
+ public void handleActivityResult(int requestCode, int resultCode)
+ {
+ switch (requestCode)
+ {
+ case REQUEST_ADD_DIRECTORY:
+ // If the user picked a file, as opposed to just backing out.
+ if (resultCode == MainActivity.RESULT_OK)
+ {
+ mView.refresh();
+ }
+ break;
+
+ case REQUEST_EMULATE_GAME:
+ mView.refreshFragmentScreenshot(resultCode);
+ break;
+ }
+ }
+
+ public void loadGames(final int platformIndex)
+ {
+ GameDatabase databaseHelper = DolphinApplication.databaseHelper;
+
+ databaseHelper.getGamesForPlatform(platformIndex)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(new Action1<Cursor>()
+ {
+ @Override
+ public void call(Cursor games)
+ {
+ mView.showGames(platformIndex, games);
+ }
+ }
+ );
+ }
+}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainView.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainView.java
new file mode 100644
index 0000000000..1d286bebf3
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainView.java
@@ -0,0 +1,47 @@
+package org.dolphinemu.dolphinemu.ui.main;
+
+
+import android.database.Cursor;
+
+/**
+ * Abstraction for the screen that shows on application launch.
+ * Implementations will differ primarily to target touch-screen
+ * or non-touch screen devices.
+ */
+public interface MainView
+{
+ /**
+ * Pass the view the native library's version string. Displaying
+ * it is optional.
+ *
+ * @param version A string pulled from native code.
+ */
+ void setVersionString(String version);
+
+ /**
+ * Tell the view to refresh its contents.
+ */
+ void refresh();
+
+ /**
+ * Tell the view to tell the currently displayed {@link android.support.v4.app.Fragment}
+ * to refresh the screenshot at the given position in its list of games.
+ *
+ * @param fragmentPosition An index corresponding to the list or grid of games.
+ */
+ void refreshFragmentScreenshot(int fragmentPosition);
+
+
+ void launchSettingsActivity();
+
+ void launchFileListActivity();
+
+ /**
+ * To be called when an asynchronous database read completes. Passes the
+ * result, in this case a {@link Cursor} to the view.
+ *
+ * @param platformIndex Which platform contains these games.
+ * @param games A Cursor containing the games read from the database.
+ */
+ void showGames(int platformIndex, Cursor games);
+}