(ctx, R.layout.line_list_item);
- try {
+ // Populate the adapter
+ File history = new File(ctx.getApplicationInfo().dataDir, "retroarch-history.txt");
+ try
+ {
BufferedReader br = new BufferedReader(new InputStreamReader(
new FileInputStream(history)));
- for (;;) {
+ for (;;)
+ {
String game = br.readLine();
String core = br.readLine();
String name = br.readLine();
@@ -55,30 +72,42 @@ public final class HistorySelection extends ListActivity {
adapter.add(new HistoryWrapper(game, core, name));
}
br.close();
- } catch (IOException ex) {
}
+ catch (IOException ignored)
+ {
+ }
+
+ // Set the adapter
+ rootView.setAdapter(adapter);
+ return rootView;
}
- @Override
- public void onListItemClick(ListView listView, View view, int position, long id) {
- final HistoryWrapper item = adapter.getItem(position);
- final String gamePath = item.getGamePath();
- final String corePath = item.getCorePath();
-
- MainMenuActivity.getInstance().setModule(corePath, item.getCoreName());
-
- String current_ime = Settings.Secure.getString(getContentResolver(),
- Settings.Secure.DEFAULT_INPUT_METHOD);
-
- UserPreferences.updateConfigFile(this);
-
- Toast.makeText(this, String.format(getString(R.string.loading_gamepath), gamePath), Toast.LENGTH_SHORT).show();
- Intent myIntent = new Intent(this, RetroActivity.class);
- myIntent.putExtra("ROM", gamePath);
- myIntent.putExtra("LIBRETRO", corePath);
- myIntent.putExtra("CONFIGFILE", UserPreferences.getDefaultConfigPath(this));
- myIntent.putExtra("IME", current_ime);
- startActivity(myIntent);
- finish();
- }
+ private final OnItemClickListener onItemClickListener = new OnItemClickListener()
+ {
+ @Override
+ public void onItemClick(AdapterView> listView, View view, int position, long id)
+ {
+ final HistoryWrapper item = adapter.getItem(position);
+ final String gamePath = item.getGamePath();
+ final String corePath = item.getCorePath();
+
+ // Set the core the selected game uses.
+ ((MainMenuActivity)getActivity()).setModule(corePath, item.getCoreName());
+
+ // Update the config accordingly.
+ UserPreferences.updateConfigFile(ctx);
+
+ // Launch the game.
+ String current_ime = Settings.Secure.getString(ctx.getContentResolver(),
+ Settings.Secure.DEFAULT_INPUT_METHOD);
+ Toast.makeText(ctx, String.format(getString(R.string.loading_gamepath), gamePath), Toast.LENGTH_SHORT).show();
+ Intent myIntent = new Intent(ctx, RetroActivity.class);
+ myIntent.putExtra("ROM", gamePath);
+ myIntent.putExtra("LIBRETRO", corePath);
+ myIntent.putExtra("CONFIGFILE", UserPreferences.getDefaultConfigPath(ctx));
+ myIntent.putExtra("IME", current_ime);
+ startActivity(myIntent);
+ dismiss();
+ }
+ };
}
diff --git a/android/phoenix/src/com/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/com/retroarch/browser/MainMenuActivity.java
deleted file mode 100644
index 24bb107ce3..0000000000
--- a/android/phoenix/src/com/retroarch/browser/MainMenuActivity.java
+++ /dev/null
@@ -1,409 +0,0 @@
-package com.retroarch.browser;
-
-import java.io.*;
-
-import com.retroarch.R;
-import com.retroarch.browser.preferences.util.UserPreferences;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.media.AudioManager;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.preference.PreferenceActivity;
-import android.provider.Settings;
-import android.util.Log;
-import android.widget.Toast;
-
-/**
- * {@link PreferenceActivity} subclass that provides all of the
- * functionality of the main menu screen.
- */
-public final class MainMenuActivity extends PreferenceActivity {
- private static MainMenuActivity instance = null;
- private static final int ACTIVITY_LOAD_ROM = 0;
- private static final int ACTIVITY_RETROARCH = 1;
- private static final String TAG = "MainMenu";
- private static String libretro_path;
- private static String libretro_name;
-
- private void showGPLWaiver() {
- AlertDialog.Builder alert = new AlertDialog.Builder(this)
- .setTitle(R.string.gpl_waiver)
- .setMessage(R.string.gpl_waiver_desc)
- .setPositiveButton("Keep", null)
- .setNegativeButton("Remove non-GPL cores",
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- final File[] libs = new File(getApplicationInfo().dataDir, "/cores").listFiles();
- for (final File lib : libs) {
- ModuleWrapper module = new ModuleWrapper(getApplicationContext(), lib);
-
- boolean gplv3 = module.getCoreLicense().equals("GPLv3");
- boolean gplv2 = module.getCoreLicense().equals("GPLv2");
-
- if (!gplv3 && !gplv2) {
- String libName = lib.getName();
- Log.i("GPL WAIVER", "Deleting non-GPL core" + libName + "...");
- lib.delete();
- }
- }
- }
- });
- alert.show();
- }
-
- @Override
- @SuppressWarnings("deprecation")
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- // Load the main menu XML.
- addPreferencesFromResource(R.xml.main_menu);
-
- // Cache an instance of this class (TODO: Bad practice, kill this somehow).
- instance = this;
-
- // Get libretro path and name.
- SharedPreferences prefs = UserPreferences.getPreferences(this);
- libretro_path = prefs.getString("libretro_path", getApplicationInfo().dataDir + "/cores");
- libretro_name = prefs.getString("libretro_name", getString(R.string.no_core));
-
- // Bind audio stream to hardware controls.
- setVolumeControlStream(AudioManager.STREAM_MUSIC);
-
- // Extract assets.
- extractAssets();
-
- if (!prefs.getBoolean("first_time_refreshrate_calculate", false)) {
- prefs.edit().putBoolean("first_time_refreshrate_calculate", true).commit();
-
- if (!detectDevice(false)) {
- AlertDialog.Builder alert = new AlertDialog.Builder(this)
- .setTitle(R.string.welcome_to_retroarch)
- .setMessage(R.string.welcome_to_retroarch_desc)
- .setPositiveButton("OK", null);
- alert.show();
- }
-
- showGPLWaiver();
- }
-
- Intent startedByIntent = getIntent();
- if (startedByIntent.getStringExtra("ROM") != null && startedByIntent.getStringExtra("LIBRETRO") != null) {
- if (savedInstanceState == null || !savedInstanceState.getBoolean("romexec"))
- loadRomExternal(startedByIntent.getStringExtra("ROM"),
- startedByIntent.getStringExtra("LIBRETRO"));
- else
- finish();
- }
- }
-
- public static MainMenuActivity getInstance() {
- return instance;
- }
-
- private int getVersionCode() {
- int version = 0;
- try {
- version = getPackageManager().getPackageInfo(getPackageName(), 0).versionCode;
- } catch (NameNotFoundException e) {
- }
-
- return version;
- }
-
- private boolean areAssetsExtracted() {
- int version = getVersionCode();
-
- try {
- String dataDir = getApplicationInfo().dataDir;
- File cacheVersion = new File(dataDir, ".cacheversion");
- if (cacheVersion.isFile() && cacheVersion.canRead() && cacheVersion.canWrite()) {
- DataInputStream cacheStream = new DataInputStream(
- new FileInputStream(cacheVersion));
-
- int currentCacheVersion = 0;
- try {
- currentCacheVersion = cacheStream.readInt();
- } catch (IOException e) {
- }
- cacheStream.close();
-
- if (currentCacheVersion == version) {
- Log.i("ASSETS", "Assets already extracted, skipping...");
- return true;
- }
- }
- } catch (IOException e) {
- Log.e(TAG, "Failed to extract assets to cache.");
- return false;
- }
-
- return false;
- }
-
- // Extract assets from native code. Doing it from Java side is apparently unbearably slow ...
- private void extractAssetsThread() {
- try {
- String dataDir = getApplicationInfo().dataDir;
-
- String apk = getApplicationInfo().sourceDir;
- Log.i(TAG, "Extracting RetroArch assets from: " + apk + " ...");
- boolean success = NativeInterface.extractArchiveTo(apk, "assets", dataDir);
- if (!success) {
- throw new IOException("Failed to extract assets ...");
- }
- Log.i(TAG, "Extracted assets ...");
-
- File cacheVersion = new File(dataDir, ".cacheversion");
- DataOutputStream outputCacheVersion = new DataOutputStream(
- new FileOutputStream(cacheVersion, false));
- outputCacheVersion.writeInt(getVersionCode());
- outputCacheVersion.close();
- } catch (IOException e) {
- Log.e(TAG, "Failed to extract assets to cache.");
- }
- }
-
- private void extractAssets() {
- if (areAssetsExtracted())
- return;
-
- final Dialog dialog = new Dialog(this);
- final Handler handler = new Handler();
- dialog.setContentView(R.layout.assets);
- dialog.setCancelable(false);
- dialog.setTitle("Asset extraction");
-
- // Java is fun :)
- Thread assetsThread = new Thread(new Runnable() {
- public void run() {
- extractAssetsThread();
- handler.post(new Runnable() {
- public void run() {
- dialog.dismiss();
- }
- });
- }
- });
- assetsThread.start();
-
- dialog.show();
- }
-
- public void setModule(String core_path, String core_name) {
- UserPreferences.updateConfigFile(this);
-
- libretro_path = core_path;
- libretro_name = core_name;
-
- SharedPreferences prefs = UserPreferences.getPreferences(this);
- SharedPreferences.Editor edit = prefs.edit();
- edit.putString("libretro_path", libretro_path);
- edit.putString("libretro_name", libretro_name);
- edit.commit();
-
- // Set the title section to contain the name of the selected core.
- setCoreTitle(libretro_name);
-
- }
-
- public void setCoreTitle(String core_name) {
- setTitle("RetroArch : " + core_name);
- }
-
- private boolean detectDevice(boolean show_dialog) {
- boolean retval = false;
-
- final Context ctx = this;
- final boolean mentionPlayStore = !Build.MODEL.equals("OUYA Console");
- final String message = (mentionPlayStore ? getString(R.string.detect_device_msg_general) : getString(R.string.detect_device_msg_ouya));
-
- Log.i("Device MODEL", Build.MODEL);
- if (Build.MODEL.equals("SHIELD")) {
- AlertDialog.Builder alert = new AlertDialog.Builder(this)
- .setTitle(R.string.nvidia_shield_detected)
- .setMessage(message)
- .setPositiveButton(R.string.ok,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- SharedPreferences prefs = UserPreferences.getPreferences(MainMenuActivity.this);
- SharedPreferences.Editor edit = prefs.edit();
- edit.putString("video_refresh_rate", Double.toString(60.00d));
- edit.putBoolean("input_overlay_enable", false);
- edit.putBoolean("input_autodetect_enable", true);
- edit.putString("audio_latency", "64");
- edit.putBoolean("audio_latency_auto", true);
- edit.commit();
- UserPreferences.updateConfigFile(ctx);
- }
- });
- alert.show();
- retval = true;
- } else if (Build.MODEL.equals("GAMEMID_BT")) {
- AlertDialog.Builder alert = new AlertDialog.Builder(this)
- .setTitle(R.string.game_mid_detected)
- .setMessage(message)
- .setPositiveButton(R.string.ok,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- SharedPreferences prefs = UserPreferences.getPreferences(MainMenuActivity.this);
- SharedPreferences.Editor edit = prefs.edit();
- edit.putBoolean("input_overlay_enable", false);
- edit.putBoolean("input_autodetect_enable", true);
- edit.putString("audio_latency", "160");
- edit.putBoolean("audio_latency_auto", false);
- edit.commit();
- UserPreferences.updateConfigFile(ctx);
- }
- });
- alert.show();
- retval = true;
- } else if (Build.MODEL.equals("OUYA Console")) {
- AlertDialog.Builder alert = new AlertDialog.Builder(this)
- .setTitle(R.string.ouya_detected)
- .setMessage(message)
- .setPositiveButton(R.string.ok,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- SharedPreferences prefs = UserPreferences.getPreferences(MainMenuActivity.this);
- SharedPreferences.Editor edit = prefs.edit();
- edit.putBoolean("input_overlay_enable", false);
- edit.putBoolean("input_autodetect_enable", true);
- edit.putString("audio_latency", "64");
- edit.putBoolean("audio_latency_auto", true);
- edit.commit();
- UserPreferences.updateConfigFile(ctx);
- }
- });
- alert.show();
- retval = true;
- } else if (Build.MODEL.equals("R800x")) {
- AlertDialog.Builder alert = new AlertDialog.Builder(this)
- .setTitle(R.string.xperia_play_detected)
- .setMessage(message)
- .setPositiveButton(R.string.ok,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- SharedPreferences prefs = UserPreferences.getPreferences(MainMenuActivity.this);
- SharedPreferences.Editor edit = prefs.edit();
- edit.putBoolean("video_threaded", false);
- edit.putBoolean("input_overlay_enable", false);
- edit.putBoolean("input_autodetect_enable", true);
- edit.putString("video_refresh_rate", Double.toString(59.19132938771038));
- edit.putString("audio_latency", "128");
- edit.putBoolean("audio_latency_auto", false);
- edit.commit();
- UserPreferences.updateConfigFile(ctx);
- }
- });
- alert.show();
- retval = true;
- } else if (Build.ID.equals("JSS15J")) {
- AlertDialog.Builder alert = new AlertDialog.Builder(this)
- .setTitle(R.string.nexus_7_2013_detected)
- .setMessage(message)
- .setPositiveButton(R.string.ok,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- SharedPreferences prefs = UserPreferences.getPreferences(MainMenuActivity.this);
- SharedPreferences.Editor edit = prefs.edit();
- edit.putString("video_refresh_rate", Double.toString(59.65));
- edit.putString("audio_latency", "64");
- edit.putBoolean("audio_latency_auto", false);
- edit.commit();
- UserPreferences.updateConfigFile(ctx);
- }
- });
- alert.show();
- retval = true;
- }
-
- if (show_dialog) {
- Toast.makeText(this, R.string.no_optimal_settings, Toast.LENGTH_SHORT).show();
- }
-
- return retval;
- }
-
- @Override
- public void startActivity(Intent intent) {
- if (intent.getComponent().getClassName()
- .equals("com.retroarch.browser.diractivities.ROMActivity")) {
- if (!new File(libretro_path).isDirectory()) {
- super.startActivityForResult(intent, ACTIVITY_LOAD_ROM);
- } else {
- Toast.makeText(this, R.string.load_a_core_first, Toast.LENGTH_SHORT).show();
- }
- } else {
- super.startActivity(intent);
- }
- }
-
- @Override
- protected void onActivityResult(int reqCode, int resCode, Intent data) {
- switch (reqCode) {
- case ACTIVITY_LOAD_ROM: {
- if (data.getStringExtra("PATH") != null) {
- UserPreferences.updateConfigFile(this);
- String current_ime = Settings.Secure.getString(getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
- Toast.makeText(this,String.format(getString(R.string.loading_data), data.getStringExtra("PATH")), Toast.LENGTH_SHORT).show();
- Intent myIntent = new Intent(this, RetroActivity.class);
- myIntent.putExtra("ROM", data.getStringExtra("PATH"));
- myIntent.putExtra("LIBRETRO", libretro_path);
- myIntent.putExtra("CONFIGFILE", UserPreferences.getDefaultConfigPath(this));
- myIntent.putExtra("IME", current_ime);
- startActivityForResult(myIntent, ACTIVITY_RETROARCH);
- }
- break;
- }
-
- case ACTIVITY_RETROARCH: {
- Log.i(TAG, "RetroArch finished running.");
- UserPreferences.readbackConfigFile(this);
- break;
- }
- }
- }
-
- @Override
- protected void onSaveInstanceState(Bundle data) {
- super.onSaveInstanceState(data);
- data.putCharSequence("title", getTitle());
- data.putBoolean("romexec", true);
- }
-
- @Override
- protected void onRestoreInstanceState(Bundle state) {
- super.onRestoreInstanceState(state);
-
- if (state != null) {
- setTitle(state.getCharSequence("title"));
- }
- }
-
- private void loadRomExternal(String rom, String core) {
- UserPreferences.updateConfigFile(this);
- String current_ime = Settings.Secure.getString(getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
- Toast.makeText(this, String.format(getString(R.string.loading_data), rom), Toast.LENGTH_SHORT).show();
- Intent myIntent = new Intent(this, RetroActivity.class);
- myIntent.putExtra("ROM", rom);
- myIntent.putExtra("LIBRETRO", core);
- myIntent.putExtra("CONFIGFILE", UserPreferences.getDefaultConfigPath(this));
- myIntent.putExtra("IME", current_ime);
- startActivity(myIntent);
- }
-}
\ No newline at end of file
diff --git a/android/phoenix/src/com/retroarch/browser/RetroActivity.java b/android/phoenix/src/com/retroarch/browser/RetroActivity.java
index d4771de5d1..d70950a7ec 100644
--- a/android/phoenix/src/com/retroarch/browser/RetroActivity.java
+++ b/android/phoenix/src/com/retroarch/browser/RetroActivity.java
@@ -1,20 +1,24 @@
package com.retroarch.browser;
+import com.retroarch.browser.preferences.util.UserPreferences;
+
import android.app.NativeActivity;
-import android.os.Bundle;
-
-public final class RetroActivity extends NativeActivity {
+public final class RetroActivity extends NativeActivity
+{
@Override
- public void onCreate(Bundle savedInstance) {
- super.onCreate(savedInstance);
+ public void onDestroy()
+ {
+ UserPreferences.readbackConfigFile(this);
}
@Override
- public void onLowMemory() {
+ public void onLowMemory()
+ {
}
@Override
- public void onTrimMemory(int level) {
+ public void onTrimMemory(int level)
+ {
}
}
diff --git a/android/phoenix/src/com/retroarch/browser/RetroTVMode.java b/android/phoenix/src/com/retroarch/browser/RetroTVMode.java
index 889b18e003..c351617551 100644
--- a/android/phoenix/src/com/retroarch/browser/RetroTVMode.java
+++ b/android/phoenix/src/com/retroarch/browser/RetroTVMode.java
@@ -6,51 +6,36 @@ import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.provider.Settings;
-import android.util.Log;
/**
* The {@link Activity} derivative responsible for displaying the TV Mode feature.
*/
-public final class RetroTVMode extends Activity {
- private static final String TAG = "RetroTVMode";
- private static final int ACTIVITY_RETROARCH = 1;
-
+public final class RetroTVMode extends Activity
+{
// Need to do this wonky logic as we have to keep this activity alive until
// RetroArch is done running.
// Have to readback config right after RetroArch has run to avoid potential
// broken config state.
@Override
- public void onCreate(Bundle savedInstanceState) {
+ public void onCreate(Bundle savedInstanceState)
+ {
super.onCreate(savedInstanceState);
- if (savedInstanceState == null
- || !savedInstanceState.getBoolean("started", false)) {
+ if (savedInstanceState == null || !savedInstanceState.getBoolean("started", false))
+ {
UserPreferences.updateConfigFile(this);
Intent myIntent = new Intent(this, RetroActivity.class);
- String current_ime = Settings.Secure.getString(
- getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
- myIntent.putExtra("CONFIGFILE",
- UserPreferences.getDefaultConfigPath(this));
+ String current_ime = Settings.Secure.getString(getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
+ myIntent.putExtra("CONFIGFILE", UserPreferences.getDefaultConfigPath(this));
myIntent.putExtra("IME", current_ime);
- startActivityForResult(myIntent, ACTIVITY_RETROARCH);
+ startActivity(myIntent);
}
}
@Override
- protected void onActivityResult(int reqCode, int resCode, Intent data) {
- switch (reqCode) {
- case ACTIVITY_RETROARCH: {
- Log.i(TAG, "RetroArch finished running.");
- UserPreferences.readbackConfigFile(this);
- finish();
- break;
- }
- }
- }
-
- @Override
- protected void onSaveInstanceState(Bundle savedInstanceState) {
+ protected void onSaveInstanceState(Bundle savedInstanceState)
+ {
savedInstanceState.putBoolean("started", true);
}
}
diff --git a/android/phoenix/src/com/retroarch/browser/diractivities/DirectoryActivity.java b/android/phoenix/src/com/retroarch/browser/diractivities/DirectoryActivity.java
deleted file mode 100644
index 5dc1e8b65a..0000000000
--- a/android/phoenix/src/com/retroarch/browser/diractivities/DirectoryActivity.java
+++ /dev/null
@@ -1,271 +0,0 @@
-package com.retroarch.browser.diractivities;
-
-import com.retroarch.R;
-import com.retroarch.browser.FileWrapper;
-import com.retroarch.browser.IconAdapter;
-import com.retroarch.browser.preferences.util.UserPreferences;
-
-import java.util.*;
-import java.io.*;
-
-import android.content.*;
-import android.app.*;
-import android.media.AudioManager;
-import android.os.*;
-import android.widget.*;
-import android.view.*;
-
-/**
- * {@link ListActivity} subclass that provides a file-browser
- * like UI for browsing for specific files.
- *
- * This file browser also allows for custom filtering
- * depending on the type of class that inherits it.
- *
- * This file browser also uses an implementation of a
- * backstack for remembering previously browsed folders
- * within this DirectoryActivity.
- */
-public class DirectoryActivity extends ListActivity {
- private IconAdapter adapter;
- private File listedDirectory;
-
- public static class BackStackItem implements Parcelable {
- private final String path;
- private final boolean parentIsBack;
-
- public BackStackItem(String path, boolean parentIsBack) {
- this.path = path;
- this.parentIsBack = parentIsBack;
- }
-
- private BackStackItem(Parcel in) {
- this.path = in.readString();
- this.parentIsBack = in.readInt() != 0;
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel out, int flags) {
- out.writeString(path);
- out.writeInt(parentIsBack ? 1 : 0);
- }
-
- public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
- public BackStackItem createFromParcel(Parcel in) {
- return new BackStackItem(in);
- }
-
- public BackStackItem[] newArray(int size) {
- return new BackStackItem[size];
- }
- };
-
- }
-
- private ArrayList backStack;
-
- protected String startDirectory;
- protected String pathSettingKey;
-
- protected void setStartDirectory(String path) {
- startDirectory = path;
- }
-
- protected void setPathSettingKey(String key) {
- pathSettingKey = key;
- }
-
- private boolean isDirectoryTarget;
- protected void setIsDirectoryTarget(boolean enable) {
- isDirectoryTarget = enable;
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.line_list);
-
- // Setup the list
- adapter = new IconAdapter(this, R.layout.line_list_item);
- setListAdapter(adapter);
-
- // Load Directory
- if (savedInstanceState != null) {
- backStack = savedInstanceState.getParcelableArrayList("BACKSTACK");
- }
-
- if (backStack == null || backStack.isEmpty()) {
- backStack = new ArrayList();
- String startPath = (startDirectory == null || startDirectory.isEmpty()) ? Environment
- .getExternalStorageDirectory().getPath() : startDirectory;
- backStack.add(new BackStackItem(startPath, false));
- }
-
- wrapFiles();
- this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
- }
-
- @Override
- protected void onSaveInstanceState(Bundle aState) {
- super.onSaveInstanceState(aState);
- aState.putParcelableArrayList("BACKSTACK", backStack);
- }
-
- private void finishWithPath(String path) {
- if (pathSettingKey != null && !pathSettingKey.isEmpty()) {
- SharedPreferences settings = UserPreferences.getPreferences(this);
- SharedPreferences.Editor editor = settings.edit();
- editor.putString(pathSettingKey, path);
- editor.commit();
- }
-
- Intent intent = new Intent();
- intent.putExtra("PATH", path);
- setResult(RESULT_OK, intent);
- finish();
- }
-
- @Override
- public void onListItemClick(ListView listView, View aView, int position, long id) {
- final FileWrapper item = adapter.getItem(position);
-
- if (item.isParentItem() && backStack.get(backStack.size() - 1).parentIsBack) {
- backStack.remove(backStack.size() - 1);
- wrapFiles();
- return;
- } else if (item.isDirSelectItem()) {
- finishWithPath(listedDirectory.getAbsolutePath());
- return;
- }
-
- final File selected = item.isParentItem() ? listedDirectory.getParentFile() : item.getFile();
-
- if (selected.isDirectory()) {
- backStack.add(new BackStackItem(selected.getAbsolutePath(),
- !item.isParentItem()));
- wrapFiles();
- } else {
- String filePath = selected.getAbsolutePath();
- finishWithPath(filePath);
- }
- }
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_BACK) {
- if (backStack.size() > 1) {
- backStack.remove(backStack.size() - 1);
- wrapFiles();
- } else {
- Intent intent = new Intent();
- setResult(RESULT_CANCELED, intent);
- finish();
- }
- return true;
- }
-
- return super.onKeyDown(keyCode, event);
- }
-
- private ArrayList allowedExt;
- private ArrayList disallowedExt;
-
- private boolean filterPath(String path) {
- if (disallowedExt != null) {
- for (String ext : disallowedExt)
- if (path.endsWith(ext))
- return false;
- }
-
- if (allowedExt != null) {
- for (String ext : allowedExt)
- if (path.endsWith(ext))
- return true;
-
- return false;
- }
-
- return true;
- }
-
- /**
- * Allows specifying an allowed file extension.
- *
- * Any files that contain this file extension will be shown
- * within the DirectoryActivity file browser. Those that don't
- * contain this extension will not be shows.
- *
- * It is possible to specify more than one allowed extension by
- * simply calling this method with a different file extension specified.
- *
- * @param ext The file extension to allow being shown in this DirectoryActivity.
- */
- protected void addAllowedExt(String ext) {
- if (allowedExt == null)
- allowedExt = new ArrayList();
-
- allowedExt.add(ext);
- }
-
- /**
- * Allows specifying a disallowed file extension.
- *
- * Any files that contain this file extension will not be shown
- * within the DirectoryActivity file browser.
- *
- * It is possible to specify more than one disallowed extension by
- * simply calling this method with a different file extension specified.
- *
- * @param ext The file extension to hide from being shown in this DirectoryActivity.
- */
- protected void addDisallowedExt(String ext) {
- if (disallowedExt == null)
- disallowedExt = new ArrayList();
-
- disallowedExt.add(ext);
- }
-
- private void wrapFiles() {
- listedDirectory = new File(backStack.get(backStack.size() - 1).path);
-
- if (!listedDirectory.isDirectory()) {
- throw new IllegalArgumentException("Directory is not valid.");
- }
-
- adapter.clear();
- setTitle(listedDirectory.getAbsolutePath());
-
- if (isDirectoryTarget)
- adapter.add(new FileWrapper(null, FileWrapper.DIRSELECT, true));
-
- if (listedDirectory.getParentFile() != null)
- adapter.add(new FileWrapper(null, FileWrapper.PARENT, true));
-
- // Copy new items
- final File[] files = listedDirectory.listFiles();
- if (files != null) {
- for (File file : files) {
- String path = file.getName();
-
- boolean allowFile = file.isDirectory() || (filterPath(path) && !isDirectoryTarget);
-
- if (allowFile)
- adapter.add(new FileWrapper(file, FileWrapper.FILE, true));
- }
- }
-
- // Sort items
- adapter.sort(new Comparator() {
- @Override
- public int compare(FileWrapper left, FileWrapper right) {
- return left.compareTo(right);
- };
- });
-
- // Update
- adapter.notifyDataSetChanged();
- }
-}
diff --git a/android/phoenix/src/com/retroarch/browser/diractivities/OverlayActivity.java b/android/phoenix/src/com/retroarch/browser/diractivities/OverlayActivity.java
deleted file mode 100644
index fcee83a51b..0000000000
--- a/android/phoenix/src/com/retroarch/browser/diractivities/OverlayActivity.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.retroarch.browser.diractivities;
-
-import java.io.File;
-
-import android.os.Bundle;
-
-/**
- * {@link DirectoryActivity} subclass used for the sole
- * purpose of navigating the Android filesystem for input overlays.
- * @author Lioncash-yay
- *
- */
-public final class OverlayActivity extends DirectoryActivity {
- @Override
- public void onCreate(Bundle savedInstanceState) {
- File overlayDir = new File(getApplicationInfo().dataDir, "overlays");
- if (overlayDir.exists())
- super.setStartDirectory(overlayDir.getAbsolutePath());
-
- super.addAllowedExt(".cfg");
- super.setPathSettingKey("input_overlay");
- super.onCreate(savedInstanceState);
- }
-}
diff --git a/android/phoenix/src/com/retroarch/browser/diractivities/ROMActivity.java b/android/phoenix/src/com/retroarch/browser/diractivities/ROMActivity.java
deleted file mode 100644
index 82c0b474ce..0000000000
--- a/android/phoenix/src/com/retroarch/browser/diractivities/ROMActivity.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.retroarch.browser.diractivities;
-
-import java.io.File;
-
-import com.retroarch.browser.preferences.util.UserPreferences;
-
-import android.content.SharedPreferences;
-import android.os.Bundle;
-
-/**
- * {@link DirectoryActivity} subclass used for the sole
- * purpose of navigating the Android filesystem for selecting
- * a ROM file to execute during emulation.
- */
-public final class ROMActivity extends DirectoryActivity {
- @Override
- public void onCreate(Bundle savedInstanceState) {
-
- SharedPreferences prefs = UserPreferences.getPreferences(this);
- String startPath = prefs.getString("rgui_browser_directory", "");
- if (!startPath.isEmpty() && new File(startPath).exists())
- super.setStartDirectory(startPath);
-
- super.addDisallowedExt(".state");
- super.addDisallowedExt(".srm");
- super.addDisallowedExt(".state.auto");
- super.addDisallowedExt(".rtc");
- super.onCreate(savedInstanceState);
- }
-}
diff --git a/android/phoenix/src/com/retroarch/browser/diractivities/ROMDirActivity.java b/android/phoenix/src/com/retroarch/browser/diractivities/ROMDirActivity.java
deleted file mode 100644
index dcdb7efe70..0000000000
--- a/android/phoenix/src/com/retroarch/browser/diractivities/ROMDirActivity.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.retroarch.browser.diractivities;
-
-import android.os.Bundle;
-
-/**
- * {@link DirectoryActivity} subclass used for the sole
- * purpose of navigating the Android filesystem to select
- * a custom ROM directory.
- */
-public final class ROMDirActivity extends DirectoryActivity {
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.setPathSettingKey("rgui_browser_directory");
- super.setIsDirectoryTarget(true);
- super.onCreate(savedInstanceState);
- }
-}
diff --git a/android/phoenix/src/com/retroarch/browser/diractivities/SRMDirActivity.java b/android/phoenix/src/com/retroarch/browser/diractivities/SRMDirActivity.java
deleted file mode 100644
index 1234a1c160..0000000000
--- a/android/phoenix/src/com/retroarch/browser/diractivities/SRMDirActivity.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.retroarch.browser.diractivities;
-
-import android.os.Bundle;
-
-/**
- * {@link DirectoryActivity} subclass used for the sole
- * purpose of navigating the Android filesystem for selecting
- * a custom save file directory.
- */
-public final class SRMDirActivity extends DirectoryActivity {
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.setPathSettingKey("savefile_directory");
- super.setIsDirectoryTarget(true);
- super.onCreate(savedInstanceState);
- }
-}
diff --git a/android/phoenix/src/com/retroarch/browser/diractivities/ShaderActivity.java b/android/phoenix/src/com/retroarch/browser/diractivities/ShaderActivity.java
deleted file mode 100644
index c8250e4e26..0000000000
--- a/android/phoenix/src/com/retroarch/browser/diractivities/ShaderActivity.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.retroarch.browser.diractivities;
-
-import java.io.File;
-
-import android.os.Bundle;
-
-/**
- * {@link DirectoryActivity} subclass used for the sole
- * purpose of navigating the Android filesystem for selecting
- * a shader to use during emulation.
- */
-public final class ShaderActivity extends DirectoryActivity {
- @Override
- public void onCreate(Bundle savedInstanceState) {
- File shaderDir = new File(getApplicationInfo().dataDir, "shaders_glsl");
- if (shaderDir.exists())
- super.setStartDirectory(shaderDir.getAbsolutePath());
-
- super.addAllowedExt(".glsl");
- super.setPathSettingKey("video_shader");
- super.onCreate(savedInstanceState);
- }
-}
diff --git a/android/phoenix/src/com/retroarch/browser/diractivities/StateDirActivity.java b/android/phoenix/src/com/retroarch/browser/diractivities/StateDirActivity.java
deleted file mode 100644
index ae8ee5735d..0000000000
--- a/android/phoenix/src/com/retroarch/browser/diractivities/StateDirActivity.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.retroarch.browser.diractivities;
-
-import android.os.Bundle;
-
-/**
- * {@link DirectoryActivity} subclass used for the sole
- * purpose of navigating the Android filesystem to select
- * a custom save state directory.
- */
-public final class StateDirActivity extends DirectoryActivity {
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.setPathSettingKey("savestate_directory");
- super.setIsDirectoryTarget(true);
- super.onCreate(savedInstanceState);
- }
-}
diff --git a/android/phoenix/src/com/retroarch/browser/diractivities/SystemDirActivity.java b/android/phoenix/src/com/retroarch/browser/diractivities/SystemDirActivity.java
deleted file mode 100644
index dde21536cc..0000000000
--- a/android/phoenix/src/com/retroarch/browser/diractivities/SystemDirActivity.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.retroarch.browser.diractivities;
-
-import android.os.Bundle;
-
-/**
- * {@link DirectoryActivity} subclass used for the sole
- * purpose of navigating the Android filesystem for selecting
- * a custom 'System' directory that the cores will look in for
- * required files, such as BIOS files and other miscellaneous
- * system-required files.
- */
-public final class SystemDirActivity extends DirectoryActivity {
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.setPathSettingKey("system_directory");
- super.setIsDirectoryTarget(true);
- super.onCreate(savedInstanceState);
- }
-}
diff --git a/android/phoenix/src/com/retroarch/browser/dirfragment/DirectoryFragment.java b/android/phoenix/src/com/retroarch/browser/dirfragment/DirectoryFragment.java
new file mode 100644
index 0000000000..45edc54202
--- /dev/null
+++ b/android/phoenix/src/com/retroarch/browser/dirfragment/DirectoryFragment.java
@@ -0,0 +1,371 @@
+package com.retroarch.browser.dirfragment;
+
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.os.Environment;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.support.v4.app.DialogFragment;
+import android.support.v4.app.ListFragment;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ListView;
+
+import com.retroarch.R;
+import com.retroarch.browser.FileWrapper;
+import com.retroarch.browser.IconAdapter;
+import com.retroarch.browser.preferences.util.UserPreferences;
+
+import java.util.*;
+import java.io.*;
+
+
+/**
+ * {@link ListFragment} subclass that provides a file-browser
+ * like UI for browsing for specific files.
+ *
+ * This file browser also allows for custom filtering
+ * depending on the type of class that inherits it.
+ *
+ * This file browser also uses an implementation of a
+ * backstack for remembering previously browsed folders
+ * within this DirectoryFragment.
+ *
+ * To instantiate a new instance of this class
+ * you must use the {@code newInstance} method.
+ */
+public final class DirectoryFragment extends DialogFragment
+{
+ private IconAdapter adapter;
+ private File listedDirectory;
+
+ public static final class BackStackItem implements Parcelable
+ {
+ private final String path;
+ private final boolean parentIsBack;
+
+ public BackStackItem(String path, boolean parentIsBack)
+ {
+ this.path = path;
+ this.parentIsBack = parentIsBack;
+ }
+
+ private BackStackItem(Parcel in)
+ {
+ this.path = in.readString();
+ this.parentIsBack = in.readInt() != 0;
+ }
+
+ public int describeContents()
+ {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags)
+ {
+ out.writeString(path);
+ out.writeInt(parentIsBack ? 1 : 0);
+ }
+
+ public static final Parcelable.Creator CREATOR = new Parcelable.Creator()
+ {
+ public BackStackItem createFromParcel(Parcel in)
+ {
+ return new BackStackItem(in);
+ }
+
+ public BackStackItem[] newArray(int size)
+ {
+ return new BackStackItem[size];
+ }
+ };
+ }
+
+ /**
+ * Listener interface for executing ROMs or performing
+ * other things upon the DirectoryFragment instance closing.
+ */
+ public interface OnDirectoryFragmentClosedListener
+ {
+ /**
+ * Performs some arbitrary action after the
+ * {@link DirectoryFragment} closes.
+ *
+ * @param path The path to the file chosen within the {@link DirectoryFragment}
+ */
+ void onDirectoryFragmentClosed(String path);
+ }
+
+
+ private ArrayList backStack;
+
+ private String startDirectory;
+ private String pathSettingKey;
+
+ public void setStartDirectory(String path)
+ {
+ startDirectory = path;
+ }
+
+ public void setPathSettingKey(String key)
+ {
+ pathSettingKey = key;
+ }
+
+ private boolean isDirectoryTarget;
+ public void setIsDirectoryTarget(boolean enable)
+ {
+ isDirectoryTarget = enable;
+ }
+
+ private OnDirectoryFragmentClosedListener onClosedListener;
+ public void setOnDirectoryFragmentClosedListener(OnDirectoryFragmentClosedListener onClosedListener)
+ {
+ this.onClosedListener = onClosedListener;
+ }
+
+ /**
+ * Retrieves a new instance of a DirectoryFragment
+ * with a title specified by the given resource ID.
+ *
+ * @param titleResId String resource ID for the title
+ * of this DirectoryFragment.
+ *
+ * @return A new instance of a DirectoryFragment.
+ */
+ public static DirectoryFragment newInstance(int titleResId)
+ {
+ final DirectoryFragment dFrag = new DirectoryFragment();
+ final Bundle bundle = new Bundle();
+ bundle.putInt("titleResId", titleResId);
+ dFrag.setArguments(bundle);
+
+ return dFrag;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
+ {
+ ListView rootView = (ListView) inflater.inflate(R.layout.line_list, container, false);
+ rootView.setOnItemClickListener(onItemClickListener);
+
+ // Set the dialog title.
+ getDialog().setTitle(getArguments().getInt("titleResId"));
+
+ // Setup the list
+ adapter = new IconAdapter(getActivity(), R.layout.line_list_item);
+ rootView.setAdapter(adapter);
+
+ // Load Directory
+ if (savedInstanceState != null)
+ {
+ backStack = savedInstanceState.getParcelableArrayList("BACKSTACK");
+ }
+
+ if (backStack == null || backStack.isEmpty())
+ {
+ backStack = new ArrayList();
+ String startPath = (startDirectory == null || startDirectory.isEmpty()) ? Environment
+ .getExternalStorageDirectory().getPath() : startDirectory;
+ backStack.add(new BackStackItem(startPath, false));
+ }
+
+ wrapFiles();
+ return rootView;
+ }
+
+ private final OnItemClickListener onItemClickListener = new OnItemClickListener()
+ {
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id)
+ {
+ final FileWrapper item = adapter.getItem(position);
+
+ if (item.isParentItem() && backStack.get(backStack.size() - 1).parentIsBack)
+ {
+ backStack.remove(backStack.size() - 1);
+ wrapFiles();
+ return;
+ }
+ else if (item.isDirSelectItem())
+ {
+ finishWithPath(listedDirectory.getAbsolutePath());
+ return;
+ }
+
+ final File selected = item.isParentItem() ? listedDirectory.getParentFile() : item.getFile();
+
+ if (selected.isDirectory())
+ {
+ backStack.add(new BackStackItem(selected.getAbsolutePath(), !item.isParentItem()));
+ wrapFiles();
+ }
+ else
+ {
+ String filePath = selected.getAbsolutePath();
+ finishWithPath(filePath);
+ }
+ }
+ };
+
+ @Override
+ public void onSaveInstanceState(Bundle outState)
+ {
+ super.onSaveInstanceState(outState);
+
+ outState.putParcelableArrayList("BACKSTACK", backStack);
+ }
+
+ private void finishWithPath(String path)
+ {
+ if (pathSettingKey != null && !pathSettingKey.isEmpty())
+ {
+ SharedPreferences settings = UserPreferences.getPreferences(getActivity());
+ SharedPreferences.Editor editor = settings.edit();
+ editor.putString(pathSettingKey, path);
+ editor.commit();
+ }
+
+ if (onClosedListener != null)
+ {
+ onClosedListener.onDirectoryFragmentClosed(path);
+ }
+
+ dismiss();
+ }
+
+ // TODO: Hook this up to a callable interface (if backstack is desirable).
+ public boolean onKeyDown(int keyCode, KeyEvent event)
+ {
+ if (keyCode == KeyEvent.KEYCODE_BACK)
+ {
+ if (backStack.size() > 1)
+ {
+ backStack.remove(backStack.size() - 1);
+ wrapFiles();
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ private ArrayList allowedExt;
+ private ArrayList disallowedExt;
+
+ private boolean filterPath(String path)
+ {
+ if (disallowedExt != null)
+ {
+ for (String ext : disallowedExt)
+ {
+ if (path.endsWith(ext))
+ return false;
+ }
+ }
+
+ if (allowedExt != null)
+ {
+ for (String ext : allowedExt)
+ {
+ if (path.endsWith(ext))
+ return true;
+ }
+
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Allows specifying an allowed file extension.
+ *
+ * Any files that contain this file extension will be shown
+ * within the DirectoryFragment file browser. Those that don't
+ * contain this extension will not be shows.
+ *
+ * It is possible to specify more than one allowed extension by
+ * simply calling this method with a different file extension specified.
+ *
+ * @param ext The file extension(s) to allow being shown in this DirectoryFragment.
+ */
+ public void addAllowedExts(String... exts)
+ {
+ if (allowedExt == null)
+ allowedExt = new ArrayList();
+
+ allowedExt.addAll(Arrays.asList(exts));
+ }
+
+ /**
+ * Allows specifying a disallowed file extension.
+ *
+ * Any files that contain this file extension will not be shown
+ * within the DirectoryFragment file browser.
+ *
+ * It is possible to specify more than one disallowed extension by
+ * simply calling this method with a different file extension specified.
+ *
+ * @param exts The file extension(s) to hide from being shown in this DirectoryFragment.
+ */
+ public void addDisallowedExts(String... exts)
+ {
+ if (disallowedExt == null)
+ disallowedExt = new ArrayList();
+
+ disallowedExt.addAll(Arrays.asList(exts));
+ }
+
+ private void wrapFiles()
+ {
+ listedDirectory = new File(backStack.get(backStack.size() - 1).path);
+
+ if (!listedDirectory.isDirectory())
+ {
+ throw new IllegalArgumentException("Directory is not valid.");
+ }
+
+ adapter.clear();
+
+ if (isDirectoryTarget)
+ adapter.add(new FileWrapper(null, FileWrapper.DIRSELECT, true));
+
+ if (listedDirectory.getParentFile() != null)
+ adapter.add(new FileWrapper(null, FileWrapper.PARENT, true));
+
+ // Copy new items
+ final File[] files = listedDirectory.listFiles();
+ if (files != null)
+ {
+ for (File file : files)
+ {
+ String path = file.getName();
+
+ boolean allowFile = file.isDirectory() || (filterPath(path) && !isDirectoryTarget);
+ if (allowFile)
+ {
+ adapter.add(new FileWrapper(file, FileWrapper.FILE, true));
+ }
+ }
+ }
+
+ // Sort items
+ adapter.sort(new Comparator()
+ {
+ @Override
+ public int compare(FileWrapper left, FileWrapper right)
+ {
+ return left.compareTo(right);
+ };
+ });
+
+ // Update
+ adapter.notifyDataSetChanged();
+ }
+}
diff --git a/android/phoenix/src/com/retroarch/browser/mainmenu/MainMenuActivity.java b/android/phoenix/src/com/retroarch/browser/mainmenu/MainMenuActivity.java
new file mode 100644
index 0000000000..f9dd0e9115
--- /dev/null
+++ b/android/phoenix/src/com/retroarch/browser/mainmenu/MainMenuActivity.java
@@ -0,0 +1,74 @@
+package com.retroarch.browser.mainmenu;
+
+import com.retroarch.R;
+import com.retroarch.browser.preferences.util.UserPreferences;
+
+import android.content.SharedPreferences;
+import android.media.AudioManager;
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentTransaction;
+
+/**
+ * {@link PreferenceActivity} subclass that provides all of the
+ * functionality of the main menu screen.
+ */
+public final class MainMenuActivity extends FragmentActivity
+{
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+
+ // Load the main menu layout
+ setContentView(R.layout.mainmenu_activity_layout);
+ if (savedInstanceState == null)
+ {
+ final MainMenuFragment mmf = new MainMenuFragment();
+ final FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
+
+ // Add the base main menu fragment to the content view.
+ ft.replace(R.id.content_frame, mmf);
+ ft.commit();
+ }
+
+ // Bind audio stream to hardware controls.
+ setVolumeControlStream(AudioManager.STREAM_MUSIC);
+ }
+
+ public void setModule(String core_path, String core_name)
+ {
+ UserPreferences.updateConfigFile(this);
+
+ SharedPreferences prefs = UserPreferences.getPreferences(this);
+ SharedPreferences.Editor edit = prefs.edit();
+ edit.putString("libretro_path", core_path);
+ edit.putString("libretro_name", core_name);
+ edit.commit();
+
+ // Set the title section to contain the name of the selected core.
+ setCoreTitle(core_name);
+ }
+
+ public void setCoreTitle(String core_name)
+ {
+ setTitle("RetroArch : " + core_name);
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle data)
+ {
+ super.onSaveInstanceState(data);
+
+ data.putCharSequence("title", getTitle());
+ }
+
+ @Override
+ protected void onRestoreInstanceState(Bundle savedInstanceState)
+ {
+ super.onRestoreInstanceState(savedInstanceState);
+
+ setTitle(savedInstanceState.getCharSequence("title"));
+ }
+}
\ No newline at end of file
diff --git a/android/phoenix/src/com/retroarch/browser/mainmenu/MainMenuFragment.java b/android/phoenix/src/com/retroarch/browser/mainmenu/MainMenuFragment.java
new file mode 100644
index 0000000000..e6df9996c9
--- /dev/null
+++ b/android/phoenix/src/com/retroarch/browser/mainmenu/MainMenuFragment.java
@@ -0,0 +1,416 @@
+package com.retroarch.browser.mainmenu;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceClickListener;
+import android.preference.PreferenceManager;
+import android.provider.Settings;
+import android.util.Log;
+import android.widget.Toast;
+
+import com.retroarch.R;
+import com.retroarch.browser.CoreSelection;
+import com.retroarch.browser.HistorySelection;
+import com.retroarch.browser.ModuleWrapper;
+import com.retroarch.browser.NativeInterface;
+import com.retroarch.browser.RetroActivity;
+import com.retroarch.browser.dirfragment.DirectoryFragment;
+import com.retroarch.browser.dirfragment.DirectoryFragment.OnDirectoryFragmentClosedListener;
+import com.retroarch.browser.preferences.fragments.util.PreferenceListFragment;
+import com.retroarch.browser.preferences.util.UserPreferences;
+
+/**
+ * Represents the fragment that handles the layout of the main menu.
+ */
+public final class MainMenuFragment extends PreferenceListFragment implements OnPreferenceClickListener, OnDirectoryFragmentClosedListener
+{
+ private static final String TAG = "MainMenuFragment";
+
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+
+ // Add the layout through the XML.
+ addPreferencesFromResource(R.xml.main_menu);
+
+ // Set the listeners for the menu items
+ findPreference("loadCorePref").setOnPreferenceClickListener(this);
+ findPreference("loadRomPref").setOnPreferenceClickListener(this);
+ findPreference("loadRomHistoryPref").setOnPreferenceClickListener(this);
+
+ // Extract assets.
+ extractAssets();
+
+ final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
+ if (!prefs.getBoolean("first_time_refreshrate_calculate", false))
+ {
+ prefs.edit().putBoolean("first_time_refreshrate_calculate", true).commit();
+
+ if (!detectDevice(false))
+ {
+ AlertDialog.Builder alert = new AlertDialog.Builder(getActivity())
+ .setTitle(R.string.welcome_to_retroarch)
+ .setMessage(R.string.welcome_to_retroarch_desc)
+ .setPositiveButton(R.string.ok, null);
+ alert.show();
+ }
+
+ showGPLWaiver();
+ }
+ }
+
+ private void showGPLWaiver()
+ {
+ AlertDialog.Builder alert = new AlertDialog.Builder(getActivity())
+ .setTitle(R.string.gpl_waiver)
+ .setMessage(R.string.gpl_waiver_desc)
+ .setPositiveButton(R.string.keep_cores, null)
+ .setNegativeButton(R.string.remove_cores, new DialogInterface.OnClickListener()
+ {
+ @Override
+ public void onClick(DialogInterface dialog, int which)
+ {
+ final File[] libs = new File(getActivity().getApplicationInfo().dataDir, "/cores").listFiles();
+ for (final File lib : libs)
+ {
+ ModuleWrapper module = new ModuleWrapper(getActivity().getApplicationContext(), lib);
+
+ boolean gplv3 = module.getCoreLicense().equals("GPLv3");
+ boolean gplv2 = module.getCoreLicense().equals("GPLv2");
+
+ if (!gplv3 && !gplv2)
+ {
+ String libName = lib.getName();
+ Log.i("GPL WAIVER", "Deleting non-GPL core" + libName + "...");
+ lib.delete();
+ }
+ }
+ }
+ });
+ alert.show();
+ }
+
+ private void extractAssets()
+ {
+ if (areAssetsExtracted())
+ return;
+
+ final Dialog dialog = new Dialog(getActivity());
+ final Handler handler = new Handler();
+ dialog.setContentView(R.layout.assets);
+ dialog.setCancelable(false);
+ dialog.setTitle(R.string.asset_extraction);
+
+ // Java is fun :)
+ Thread assetsThread = new Thread(new Runnable()
+ {
+ public void run()
+ {
+ extractAssetsThread();
+ handler.post(new Runnable()
+ {
+ public void run()
+ {
+ dialog.dismiss();
+ }
+ });
+ }
+ });
+ assetsThread.start();
+
+ dialog.show();
+ }
+
+ // Extract assets from native code. Doing it from Java side is apparently unbearably slow ...
+ private void extractAssetsThread()
+ {
+ try
+ {
+ final String dataDir = getActivity().getApplicationInfo().dataDir;
+ final String apk = getActivity().getApplicationInfo().sourceDir;
+
+ Log.i(TAG, "Extracting RetroArch assets from: " + apk + " ...");
+ boolean success = NativeInterface.extractArchiveTo(apk, "assets", dataDir);
+ if (!success) {
+ throw new IOException("Failed to extract assets ...");
+ }
+ Log.i(TAG, "Extracted assets ...");
+
+ File cacheVersion = new File(dataDir, ".cacheversion");
+ DataOutputStream outputCacheVersion = new DataOutputStream(new FileOutputStream(cacheVersion, false));
+ outputCacheVersion.writeInt(getVersionCode());
+ outputCacheVersion.close();
+ }
+ catch (IOException e)
+ {
+ Log.e(TAG, "Failed to extract assets to cache.");
+ }
+ }
+
+ private boolean areAssetsExtracted()
+ {
+ int version = getVersionCode();
+
+ try
+ {
+ String dataDir = getActivity().getApplicationInfo().dataDir;
+ File cacheVersion = new File(dataDir, ".cacheversion");
+ if (cacheVersion.isFile() && cacheVersion.canRead() && cacheVersion.canWrite())
+ {
+ DataInputStream cacheStream = new DataInputStream(new FileInputStream(cacheVersion));
+ int currentCacheVersion = 0;
+ try
+ {
+ currentCacheVersion = cacheStream.readInt();
+ cacheStream.close();
+ }
+ catch (IOException ignored)
+ {
+ }
+
+ if (currentCacheVersion == version)
+ {
+ Log.i("ASSETS", "Assets already extracted, skipping...");
+ return true;
+ }
+ }
+ }
+ catch (IOException e)
+ {
+ Log.e(TAG, "Failed to extract assets to cache.");
+ return false;
+ }
+
+ return false;
+ }
+
+ private int getVersionCode()
+ {
+ int version = 0;
+ try
+ {
+ final Context ctx = getActivity();
+ version = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(), 0).versionCode;
+ }
+ catch (NameNotFoundException ignored)
+ {
+ }
+
+ return version;
+ }
+
+ private boolean detectDevice(boolean show_dialog)
+ {
+ boolean retval = false;
+
+ final Context ctx = getActivity();
+ final boolean mentionPlayStore = !Build.MODEL.equals("OUYA Console");
+ final String message = (mentionPlayStore ? getString(R.string.detect_device_msg_general) : getString(R.string.detect_device_msg_ouya));
+
+ Log.i("Device MODEL", Build.MODEL);
+ if (Build.MODEL.equals("SHIELD"))
+ {
+ AlertDialog.Builder alert = new AlertDialog.Builder(ctx);
+ alert.setTitle(R.string.nvidia_shield_detected);
+ alert.setMessage(message);
+ alert.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener()
+ {
+ @Override
+ public void onClick(DialogInterface dialog, int which)
+ {
+ SharedPreferences prefs = UserPreferences.getPreferences(ctx);
+ SharedPreferences.Editor edit = prefs.edit();
+ edit.putString("video_refresh_rate", Double.toString(60.00d));
+ edit.putBoolean("input_overlay_enable", false);
+ edit.putBoolean("input_autodetect_enable", true);
+ edit.putString("audio_latency", "64");
+ edit.putBoolean("audio_latency_auto", true);
+ edit.commit();
+ UserPreferences.updateConfigFile(ctx);
+ }
+ });
+ alert.show();
+ retval = true;
+ }
+ else if (Build.MODEL.equals("GAMEMID_BT"))
+ {
+ AlertDialog.Builder alert = new AlertDialog.Builder(ctx);
+ alert.setTitle(R.string.game_mid_detected);
+ alert.setMessage(message);
+ alert.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener()
+ {
+ @Override
+ public void onClick(DialogInterface dialog, int which)
+ {
+ SharedPreferences prefs = UserPreferences.getPreferences(ctx);
+ SharedPreferences.Editor edit = prefs.edit();
+ edit.putBoolean("input_overlay_enable", false);
+ edit.putBoolean("input_autodetect_enable", true);
+ edit.putString("audio_latency", "160");
+ edit.putBoolean("audio_latency_auto", false);
+ edit.commit();
+ UserPreferences.updateConfigFile(ctx);
+ }
+ });
+ alert.show();
+ retval = true;
+ }
+ else if (Build.MODEL.equals("OUYA Console"))
+ {
+ AlertDialog.Builder alert = new AlertDialog.Builder(ctx);
+ alert.setTitle(R.string.ouya_detected);
+ alert.setMessage(message);
+ alert.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener()
+ {
+ @Override
+ public void onClick(DialogInterface dialog, int which)
+ {
+ SharedPreferences prefs = UserPreferences.getPreferences(ctx);
+ SharedPreferences.Editor edit = prefs.edit();
+ edit.putBoolean("input_overlay_enable", false);
+ edit.putBoolean("input_autodetect_enable", true);
+ edit.putString("audio_latency", "64");
+ edit.putBoolean("audio_latency_auto", true);
+ edit.commit();
+ UserPreferences.updateConfigFile(ctx);
+ }
+ });
+ alert.show();
+ retval = true;
+ }
+ else if (Build.MODEL.equals("R800x"))
+ {
+ AlertDialog.Builder alert = new AlertDialog.Builder(ctx);
+ alert.setTitle(R.string.xperia_play_detected);
+ alert.setMessage(message);
+ alert.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener()
+ {
+ @Override
+ public void onClick(DialogInterface dialog, int which)
+ {
+ SharedPreferences prefs = UserPreferences.getPreferences(ctx);
+ SharedPreferences.Editor edit = prefs.edit();
+ edit.putBoolean("video_threaded", false);
+ edit.putBoolean("input_overlay_enable", false);
+ edit.putBoolean("input_autodetect_enable", true);
+ edit.putString("video_refresh_rate", Double.toString(59.19132938771038));
+ edit.putString("audio_latency", "128");
+ edit.putBoolean("audio_latency_auto", false);
+ edit.commit();
+ UserPreferences.updateConfigFile(ctx);
+ }
+ });
+ alert.show();
+ retval = true;
+ }
+ else if (Build.ID.equals("JSS15J"))
+ {
+ AlertDialog.Builder alert = new AlertDialog.Builder(ctx);
+ alert.setTitle(R.string.nexus_7_2013_detected);
+ alert.setMessage(message);
+ alert.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener()
+ {
+ @Override
+ public void onClick(DialogInterface dialog, int which)
+ {
+ SharedPreferences prefs = UserPreferences.getPreferences(ctx);
+ SharedPreferences.Editor edit = prefs.edit();
+ edit.putString("video_refresh_rate", Double.toString(59.65));
+ edit.putString("audio_latency", "64");
+ edit.putBoolean("audio_latency_auto", false);
+ edit.commit();
+ UserPreferences.updateConfigFile(ctx);
+ }
+ });
+ alert.show();
+ retval = true;
+ }
+
+ if (show_dialog)
+ {
+ Toast.makeText(ctx, R.string.no_optimal_settings, Toast.LENGTH_SHORT).show();
+ }
+
+ return retval;
+ }
+
+ @Override
+ public boolean onPreferenceClick(Preference preference)
+ {
+ final String prefKey = preference.getKey();
+
+ // Load Core Preference
+ if (prefKey.equals("loadCorePref"))
+ {
+ final CoreSelection coreSelection = new CoreSelection();
+ coreSelection.show(getFragmentManager(), "core_selection");
+ }
+ // Load ROM Preference
+ else if (prefKey.equals("loadRomPref"))
+ {
+ final Context ctx = getActivity();
+ final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
+ final String libretro_path = prefs.getString("libretro_path", ctx.getApplicationInfo().dataDir + "/cores");
+
+ if (!new File(libretro_path).isDirectory())
+ {
+ final DirectoryFragment romBrowser = DirectoryFragment.newInstance(R.string.load_game);
+ romBrowser.addDisallowedExts(".state", ".srm", ".state.auto", ".rtc");
+ romBrowser.setOnDirectoryFragmentClosedListener(this);
+
+ final String startPath = prefs.getString("rgui_browser_directory", "");
+ if (!startPath.isEmpty() && new File(startPath).exists())
+ romBrowser.setStartDirectory(startPath);
+
+ romBrowser.show(getFragmentManager(), "romBrowser");
+ }
+ else
+ {
+ Toast.makeText(ctx, R.string.load_a_core_first, Toast.LENGTH_SHORT).show();
+ }
+ }
+ // Load ROM (History) Preference
+ else if (prefKey.equals("loadRomHistoryPref"))
+ {
+ final HistorySelection historySelection = new HistorySelection();
+ historySelection.show(getFragmentManager(), "history_selection");
+ }
+
+ return true;
+ }
+
+ @Override
+ public void onDirectoryFragmentClosed(String path)
+ {
+ final Context ctx = getActivity();
+ final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
+ final String libretro_path = prefs.getString("libretro_path", "");
+
+ UserPreferences.updateConfigFile(ctx);
+ String current_ime = Settings.Secure.getString(ctx.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
+ Toast.makeText(ctx, String.format(getString(R.string.loading_data), path), Toast.LENGTH_SHORT).show();
+ Intent myIntent = new Intent(ctx, RetroActivity.class);
+ myIntent.putExtra("ROM", path);
+ myIntent.putExtra("LIBRETRO", libretro_path);
+ myIntent.putExtra("CONFIGFILE", UserPreferences.getDefaultConfigPath(ctx));
+ myIntent.putExtra("IME", current_ime);
+ startActivity(myIntent);
+ }
+}
diff --git a/android/phoenix/src/com/retroarch/browser/preferences/fragments/PreferenceActivity.java b/android/phoenix/src/com/retroarch/browser/preferences/PreferenceActivity.java
similarity index 91%
rename from android/phoenix/src/com/retroarch/browser/preferences/fragments/PreferenceActivity.java
rename to android/phoenix/src/com/retroarch/browser/preferences/PreferenceActivity.java
index 6de3a3a0bc..798b4ef51f 100644
--- a/android/phoenix/src/com/retroarch/browser/preferences/fragments/PreferenceActivity.java
+++ b/android/phoenix/src/com/retroarch/browser/preferences/PreferenceActivity.java
@@ -1,4 +1,4 @@
-package com.retroarch.browser.preferences.fragments;
+package com.retroarch.browser.preferences;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
@@ -15,6 +15,11 @@ import android.support.v7.app.ActionBar.TabListener;
import android.support.v7.app.ActionBarActivity;
import com.retroarch.R;
+import com.retroarch.browser.preferences.fragments.AudioPreferenceFragment;
+import com.retroarch.browser.preferences.fragments.GeneralPreferenceFragment;
+import com.retroarch.browser.preferences.fragments.InputPreferenceFragment;
+import com.retroarch.browser.preferences.fragments.PathPreferenceFragment;
+import com.retroarch.browser.preferences.fragments.VideoPreferenceFragment;
import com.retroarch.browser.preferences.fragments.util.PreferenceListFragment;
import com.retroarch.browser.preferences.util.UserPreferences;
diff --git a/android/phoenix/src/com/retroarch/browser/preferences/fragments/InputPreferenceFragment.java b/android/phoenix/src/com/retroarch/browser/preferences/fragments/InputPreferenceFragment.java
index 6cf34f316b..71dd41ea31 100644
--- a/android/phoenix/src/com/retroarch/browser/preferences/fragments/InputPreferenceFragment.java
+++ b/android/phoenix/src/com/retroarch/browser/preferences/fragments/InputPreferenceFragment.java
@@ -1,6 +1,9 @@
package com.retroarch.browser.preferences.fragments;
+import java.io.File;
+
import com.retroarch.R;
+import com.retroarch.browser.dirfragment.DirectoryFragment;
import com.retroarch.browser.preferences.fragments.util.PreferenceListFragment;
import android.app.AlertDialog;
@@ -14,47 +17,59 @@ import android.view.inputmethod.InputMethodManager;
/**
* A {@link PreferenceListFragment} responsible for handling the input preferences.
*/
-public final class InputPreferenceFragment extends PreferenceListFragment
+public final class InputPreferenceFragment extends PreferenceListFragment implements OnPreferenceClickListener
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
-
+
// Add input preferences from the XML.
addPreferencesFromResource(R.xml.input_preferences);
- // Set Input Method preference
- final Preference setImePref = findPreference("set_ime_pref");
- setImePref.setOnPreferenceClickListener(new OnPreferenceClickListener()
- {
- @Override
- public boolean onPreferenceClick(Preference preference)
- {
- // Show an IME picker so the user can change their set IME.
- InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
- imm.showInputMethodPicker();
- return true;
- }
- });
+ // Set preference listeners
+ findPreference("set_ime_pref").setOnPreferenceClickListener(this);
+ findPreference("report_ime_pref").setOnPreferenceClickListener(this);
+ findPreference("inputOverlayDirPref").setOnPreferenceClickListener(this);
+ }
- // Report IME preference
- final Preference reportImePref = findPreference("report_ime_pref");
- reportImePref.setOnPreferenceClickListener(new OnPreferenceClickListener()
+ @Override
+ public boolean onPreferenceClick(Preference preference)
+ {
+ final String prefKey = preference.getKey();
+
+ // Set Input Method preference
+ if (prefKey.equals("set_ime_pref"))
{
- @Override
- public boolean onPreferenceClick(Preference preference)
- {
- final String currentIme = Settings.Secure.getString(getActivity().getContentResolver(),
- Settings.Secure.DEFAULT_INPUT_METHOD);
-
- AlertDialog.Builder reportImeDialog = new AlertDialog.Builder(getActivity());
- reportImeDialog.setTitle(R.string.current_ime);
- reportImeDialog.setMessage(currentIme);
- reportImeDialog.setNegativeButton(R.string.close, null);
- reportImeDialog.show();
- return true;
- }
- });
+ // Show an IME picker so the user can change their set IME.
+ InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
+ imm.showInputMethodPicker();
+ }
+ // Report IME preference
+ else if (prefKey.equals("report_ime_pref"))
+ {
+ final String currentIme = Settings.Secure.getString(getActivity().getContentResolver(),
+ Settings.Secure.DEFAULT_INPUT_METHOD);
+
+ AlertDialog.Builder reportImeDialog = new AlertDialog.Builder(getActivity());
+ reportImeDialog.setTitle(R.string.current_ime);
+ reportImeDialog.setMessage(currentIme);
+ reportImeDialog.setNegativeButton(R.string.close, null);
+ reportImeDialog.show();
+ }
+ // Input Overlay selection
+ else if (prefKey.equals("inputOverlayDirPref"))
+ {
+ final DirectoryFragment overlayBrowser = DirectoryFragment.newInstance(R.string.input_overlay_select);
+ File overlayDir = new File(getActivity().getApplicationInfo().dataDir, "overlays");
+ if (overlayDir.exists())
+ overlayBrowser.setStartDirectory(overlayDir.getAbsolutePath());
+
+ overlayBrowser.addAllowedExts(".cfg");
+ overlayBrowser.setPathSettingKey("input_overlay");
+ overlayBrowser.show(getFragmentManager(), "overlayBrowser");
+ }
+
+ return true;
}
}
diff --git a/android/phoenix/src/com/retroarch/browser/preferences/fragments/PathPreferenceFragment.java b/android/phoenix/src/com/retroarch/browser/preferences/fragments/PathPreferenceFragment.java
index 359d489c33..174935e4a1 100644
--- a/android/phoenix/src/com/retroarch/browser/preferences/fragments/PathPreferenceFragment.java
+++ b/android/phoenix/src/com/retroarch/browser/preferences/fragments/PathPreferenceFragment.java
@@ -1,14 +1,17 @@
package com.retroarch.browser.preferences.fragments;
import com.retroarch.R;
+import com.retroarch.browser.dirfragment.DirectoryFragment;
import com.retroarch.browser.preferences.fragments.util.PreferenceListFragment;
import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceClickListener;
/**
* A {@link PreferenceListFragment} that handles the path preferences.
*/
-public final class PathPreferenceFragment extends PreferenceListFragment
+public final class PathPreferenceFragment extends PreferenceListFragment implements OnPreferenceClickListener
{
@Override
public void onCreate(Bundle savedInstanceState)
@@ -17,5 +20,52 @@ public final class PathPreferenceFragment extends PreferenceListFragment
// Add path preferences from the XML.
addPreferencesFromResource(R.xml.path_preferences);
+
+ // Set preference click listeners
+ findPreference("romDirPref").setOnPreferenceClickListener(this);
+ findPreference("srmDirPref").setOnPreferenceClickListener(this);
+ findPreference("saveStateDirPref").setOnPreferenceClickListener(this);
+ findPreference("systemDirPref").setOnPreferenceClickListener(this);
+ }
+
+ @Override
+ public boolean onPreferenceClick(Preference preference)
+ {
+ final String prefKey = preference.getKey();
+
+ // Custom ROM directory
+ if (prefKey.equals("romDirPref"))
+ {
+ final DirectoryFragment romDirBrowser = DirectoryFragment.newInstance(R.string.rom_directory_select);
+ romDirBrowser.setPathSettingKey("rgui_browser_directory");
+ romDirBrowser.setIsDirectoryTarget(true);
+ romDirBrowser.show(getFragmentManager(), "romDirBrowser");
+ }
+ // Custom savefile directory
+ else if (prefKey.equals("srmDirPref"))
+ {
+ final DirectoryFragment srmDirBrowser = DirectoryFragment.newInstance(R.string.savefile_directory_select);
+ srmDirBrowser.setPathSettingKey("savefile_directory");
+ srmDirBrowser.setIsDirectoryTarget(true);
+ srmDirBrowser.show(getFragmentManager(), "srmDirBrowser");
+ }
+ // Custom save state directory
+ else if (prefKey.equals("saveStateDirPref"))
+ {
+ final DirectoryFragment saveStateDirBrowser = DirectoryFragment.newInstance(R.string.save_state_directory_select);
+ saveStateDirBrowser.setPathSettingKey("savestate_directory");
+ saveStateDirBrowser.setIsDirectoryTarget(true);
+ saveStateDirBrowser.show(getFragmentManager(), "saveStateDirBrowser");
+ }
+ // Custom system directory
+ else if (prefKey.equals("systemDirPref"))
+ {
+ final DirectoryFragment systemDirBrowser = DirectoryFragment.newInstance(R.string.system_directory_select);
+ systemDirBrowser.setPathSettingKey("system_directory");
+ systemDirBrowser.setIsDirectoryTarget(true);
+ systemDirBrowser.show(getFragmentManager(), "systemDirBrowser");
+ }
+
+ return true;
}
}
diff --git a/android/phoenix/src/com/retroarch/browser/preferences/fragments/VideoPreferenceFragment.java b/android/phoenix/src/com/retroarch/browser/preferences/fragments/VideoPreferenceFragment.java
index 8afe7d5bfd..3ab2a4ac65 100644
--- a/android/phoenix/src/com/retroarch/browser/preferences/fragments/VideoPreferenceFragment.java
+++ b/android/phoenix/src/com/retroarch/browser/preferences/fragments/VideoPreferenceFragment.java
@@ -1,6 +1,9 @@
package com.retroarch.browser.preferences.fragments;
+import java.io.File;
+
import com.retroarch.R;
+import com.retroarch.browser.dirfragment.DirectoryFragment;
import com.retroarch.browser.preferences.fragments.util.PreferenceListFragment;
import android.content.SharedPreferences;
@@ -15,7 +18,7 @@ import android.widget.Toast;
/**
* A {@link PreferenceListFragment} responsible for handling the video preferences.
*/
-public final class VideoPreferenceFragment extends PreferenceListFragment
+public final class VideoPreferenceFragment extends PreferenceListFragment implements OnPreferenceClickListener
{
@Override
public void onCreate(Bundle savedInstanceState)
@@ -25,25 +28,44 @@ public final class VideoPreferenceFragment extends PreferenceListFragment
// Add preferences from the resources
addPreferencesFromResource(R.xml.video_preferences);
+ // Set preference click listeners
+ findPreference("set_os_reported_ref_rate_pref").setOnPreferenceClickListener(this);
+ findPreference("glsl_shader_pref").setOnPreferenceClickListener(this);
+ }
+
+ @Override
+ public boolean onPreferenceClick(Preference preference)
+ {
+ final String prefKey = preference.getKey();
+
// Set OS-reported refresh rate preference.
- final Preference osReportedRatePref = findPreference("set_os_reported_ref_rate_pref");
- osReportedRatePref.setOnPreferenceClickListener(new OnPreferenceClickListener()
+ if (prefKey.equals("set_os_reported_ref_rate_pref"))
{
- @Override
- public boolean onPreferenceClick(Preference preference)
- {
- final WindowManager wm = getActivity().getWindowManager();
- final Display display = wm.getDefaultDisplay();
- final double rate = display.getRefreshRate();
+ final WindowManager wm = getActivity().getWindowManager();
+ final Display display = wm.getDefaultDisplay();
+ final double rate = display.getRefreshRate();
- final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
- final SharedPreferences.Editor edit = prefs.edit();
- edit.putString("video_refresh_rate", Double.toString(rate));
- edit.commit();
+ final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
+ final SharedPreferences.Editor edit = prefs.edit();
+ edit.putString("video_refresh_rate", Double.toString(rate));
+ edit.commit();
- Toast.makeText(getActivity(), String.format(getString(R.string.using_os_reported_refresh_rate), rate), Toast.LENGTH_LONG).show();
- return true;
- }
- });
+ Toast.makeText(getActivity(), String.format(getString(R.string.using_os_reported_refresh_rate), rate), Toast.LENGTH_LONG).show();
+ }
+ // GLSL shader selection
+ else if (prefKey.equals("glsl_shader_pref"))
+ {
+ final DirectoryFragment shaderBrowser = DirectoryFragment.newInstance(R.string.glsl_shader_select);
+
+ File shaderDir = new File(getActivity().getApplicationInfo().dataDir, "shaders_glsl");
+ if (shaderDir.exists())
+ shaderBrowser.setStartDirectory(shaderDir.getAbsolutePath());
+
+ shaderBrowser.addAllowedExts(".glsl");
+ shaderBrowser.setPathSettingKey("video_shader");
+ shaderBrowser.show(getFragmentManager(), "shaderBrowser");
+ }
+
+ return true;
}
}
diff --git a/android/phoenix/src/com/retroarch/browser/preferences/fragments/util/PreferenceListFragment.java b/android/phoenix/src/com/retroarch/browser/preferences/fragments/util/PreferenceListFragment.java
index e6a80c0165..bf7ee61e09 100644
--- a/android/phoenix/src/com/retroarch/browser/preferences/fragments/util/PreferenceListFragment.java
+++ b/android/phoenix/src/com/retroarch/browser/preferences/fragments/util/PreferenceListFragment.java
@@ -1,28 +1,43 @@
-package com.retroarch.browser.preferences.fragments.util;
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
+package com.retroarch.browser.preferences.fragments.util;
import com.retroarch.R;
-import android.app.Activity;
-import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.Preference;
+import android.preference.PreferenceGroup;
import android.preference.PreferenceManager;
import android.preference.PreferenceScreen;
-import android.support.v4.app.ListFragment;
+import android.support.v4.app.Fragment;
+import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.View.OnKeyListener;
import android.view.ViewGroup;
import android.widget.ListView;
-public class PreferenceListFragment extends ListFragment
+public abstract class PreferenceListFragment extends Fragment implements PreferenceManagerCompat.OnPreferenceTreeClickListener
{
- private static final String PREFERENCES_TAG = "android:preferences";
+ private static final String PREFERENCES_TAG = "android:preferences";
+
private PreferenceManager mPreferenceManager;
private ListView mList;
private boolean mHavePrefs;
@@ -34,7 +49,7 @@ public class PreferenceListFragment extends ListFragment
private static final int FIRST_REQUEST_CODE = 100;
private static final int MSG_BIND_PREFERENCES = 1;
- private final Handler mHandler = new Handler()
+ private Handler mHandler = new Handler()
{
@Override
public void handleMessage(Message msg)
@@ -48,35 +63,42 @@ public class PreferenceListFragment extends ListFragment
}
};
- private final Runnable mRequestFocus = new Runnable()
+ final private Runnable mRequestFocus = new Runnable()
{
- @Override
public void run()
{
mList.focusableViewAvailable(mList);
}
};
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle b)
+ /**
+ * Interface that PreferenceFragment's containing activity should
+ * implement to be able to process preference items that wish to
+ * switch to a new fragment.
+ */
+ public interface OnPreferenceStartFragmentCallback
{
- View view = inflater.inflate(R.layout.preference_list_content, container, false);
- view.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
-
- return view;
+ /**
+ * Called when the user has clicked on a Preference that has
+ * a fragment class name associated with it. The implementation
+ * to should instantiate and switch to an instance of the given
+ * fragment.
+ */
+ boolean onPreferenceStartFragment(PreferenceListFragment caller, Preference pref);
}
@Override
- public void onDestroyView()
+ public void onCreate(Bundle paramBundle)
{
- super.onDestroyView();
+ super.onCreate(paramBundle);
+ mPreferenceManager = PreferenceManagerCompat.newInstance(getActivity(), FIRST_REQUEST_CODE);
+ PreferenceManagerCompat.setFragment(mPreferenceManager, this);
+ }
- // Kill the list
- mList = null;
-
- // Remove callbacks and messages.
- mHandler.removeCallbacks(mRequestFocus);
- mHandler.removeMessages(MSG_BIND_PREFERENCES);
+ @Override
+ public View onCreateView(LayoutInflater paramLayoutInflater, ViewGroup paramViewGroup, Bundle paramBundle)
+ {
+ return paramLayoutInflater.inflate(R.layout.preference_list_fragment, paramViewGroup, false);
}
@Override
@@ -84,12 +106,10 @@ public class PreferenceListFragment extends ListFragment
{
super.onActivityCreated(savedInstanceState);
- if (mHavePrefs)
- {
- bindPreferences();
+ if (mHavePrefs) {
+ bindPreferences();
}
- // Done initializing.
mInitDone = true;
if (savedInstanceState != null)
@@ -107,47 +127,34 @@ public class PreferenceListFragment extends ListFragment
}
@Override
- public void onCreate(Bundle savedInstanceState)
+ public void onStart()
{
- super.onCreate(savedInstanceState);
-
- mPreferenceManager = onCreatePreferenceManager();
-
- postBindPreferences();
+ super.onStart();
+ PreferenceManagerCompat.setOnPreferenceTreeClickListener(mPreferenceManager, this);
}
@Override
public void onStop()
{
super.onStop();
+ PreferenceManagerCompat.dispatchActivityStop(mPreferenceManager);
+ PreferenceManagerCompat.setOnPreferenceTreeClickListener(mPreferenceManager, null);
+ }
- try
- {
- Method m = PreferenceManager.class.getDeclaredMethod("dispatchActivityStop");
- m.setAccessible(true);
- m.invoke(mPreferenceManager);
- }
- catch(Exception e)
- {
- e.printStackTrace();
- }
+ @Override
+ public void onDestroyView()
+ {
+ mList = null;
+ mHandler.removeCallbacks(mRequestFocus);
+ mHandler.removeMessages(MSG_BIND_PREFERENCES);
+ super.onDestroyView();
}
@Override
public void onDestroy()
{
super.onDestroy();
-
- try
- {
- Method m = PreferenceManager.class.getDeclaredMethod("dispatchActivityDestroy");
- m.setAccessible(true);
- m.invoke(mPreferenceManager);
- }
- catch(Exception e)
- {
- e.printStackTrace();
- }
+ PreferenceManagerCompat.dispatchActivityDestroy(mPreferenceManager);
}
@Override
@@ -169,69 +176,12 @@ public class PreferenceListFragment extends ListFragment
{
super.onActivityResult(requestCode, resultCode, data);
- try
- {
- Method m = PreferenceManager.class.getDeclaredMethod("dispatchActivityResult", int.class, int.class, Intent.class);
- m.setAccessible(true);
- m.invoke(mPreferenceManager, requestCode, resultCode, data);
- }
- catch(Exception e)
- {
- e.printStackTrace();
- }
+ PreferenceManagerCompat.dispatchActivityResult(mPreferenceManager, requestCode, resultCode, data);
}
/**
- * Posts a message to bind the preferences to the list view.
- *
- * Binding late is preferred as any custom preference types created in
- * {@link #onCreate(Bundle)} are able to have their views recycled.
- */
- private void postBindPreferences()
- {
- if (mHandler.hasMessages(MSG_BIND_PREFERENCES))
- {
- return;
- }
-
- mHandler.obtainMessage(MSG_BIND_PREFERENCES).sendToTarget();
- }
-
- private void bindPreferences()
- {
- final PreferenceScreen preferenceScreen = getPreferenceScreen();
- if (preferenceScreen != null)
- {
- preferenceScreen.bind(getListView());
- }
- }
-
- /**
- * Creates the {@link PreferenceManager}.
- *
- * @return The {@link PreferenceManager} used by this fragment.
- */
- private PreferenceManager onCreatePreferenceManager()
- {
- try
- {
- Constructor c = PreferenceManager.class.getDeclaredConstructor(Activity.class, int.class);
- c.setAccessible(true);
-
- PreferenceManager preferenceManager = c.newInstance(getActivity(), FIRST_REQUEST_CODE);
- return preferenceManager;
- }
- catch(Exception e)
- {
- e.printStackTrace();
- return null;
- }
- }
-
- /**
- * Gets the {@link PreferenceManager} used by this fragment.
- *
- * @return The {@link PreferenceManager} used by this fragment.
+ * Returns the {@link PreferenceManager} used by this fragment.
+ * @return The {@link PreferenceManager}.
*/
public PreferenceManager getPreferenceManager()
{
@@ -240,90 +190,75 @@ public class PreferenceListFragment extends ListFragment
/**
* Sets the root of the preference hierarchy that this fragment is showing.
- *
+ *
* @param preferenceScreen The root {@link PreferenceScreen} of the preference hierarchy.
*/
public void setPreferenceScreen(PreferenceScreen preferenceScreen)
{
- try
+ if (PreferenceManagerCompat.setPreferences(mPreferenceManager, preferenceScreen) && preferenceScreen != null)
{
- Method m = PreferenceManager.class.getDeclaredMethod("setPreferences", PreferenceScreen.class);
- m.setAccessible(true);
- boolean result = (Boolean) m.invoke(mPreferenceManager, preferenceScreen);
- if (result && preferenceScreen != null)
+ mHavePrefs = true;
+ if (mInitDone)
{
- mHavePrefs = true;
- if (mInitDone)
- {
- postBindPreferences();
- }
+ postBindPreferences();
}
}
- catch(Exception e)
- {
- e.printStackTrace();
- }
}
/**
* Gets the root of the preference hierarchy that this fragment is showing.
- *
+ *
* @return The {@link PreferenceScreen} that is the root of the preference
* hierarchy.
*/
public PreferenceScreen getPreferenceScreen()
{
- try
- {
- Method m = PreferenceManager.class.getDeclaredMethod("getPreferenceScreen");
- m.setAccessible(true);
- return (PreferenceScreen) m.invoke(mPreferenceManager);
- }
- catch(Exception e)
- {
- e.printStackTrace();
- return null;
- }
+ return PreferenceManagerCompat.getPreferenceScreen(mPreferenceManager);
}
/**
* Adds preferences from activities that match the given {@link Intent}.
- *
+ *
* @param intent The {@link Intent} to query activities.
*/
public void addPreferencesFromIntent(Intent intent)
{
- throw new UnsupportedOperationException("addPreferencesFromIntent not implemented yet.");
+ requirePreferenceManager();
+
+ setPreferenceScreen(PreferenceManagerCompat.inflateFromIntent(mPreferenceManager, intent, getPreferenceScreen()));
}
/**
* Inflates the given XML resource and adds the preference hierarchy to the current
* preference hierarchy.
- *
+ *
* @param preferencesResId The XML resource ID to inflate.
*/
public void addPreferencesFromResource(int preferencesResId)
{
- try
+ requirePreferenceManager();
+
+ setPreferenceScreen(PreferenceManagerCompat.inflateFromResource(mPreferenceManager, getActivity(),
+ preferencesResId, getPreferenceScreen()));
+ }
+
+ public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference)
+ {
+ //if (preference.getFragment() != null &&
+ if (getActivity() instanceof OnPreferenceStartFragmentCallback)
{
- Method m = PreferenceManager.class.getDeclaredMethod("inflateFromResource", Context.class, int.class, PreferenceScreen.class);
- m.setAccessible(true);
- PreferenceScreen prefScreen = (PreferenceScreen) m.invoke(mPreferenceManager, getActivity(), preferencesResId, getPreferenceScreen());
- setPreferenceScreen(prefScreen);
- }
- catch(Exception e)
- {
- e.printStackTrace();
+ return ((OnPreferenceStartFragmentCallback)getActivity()).onPreferenceStartFragment(
+ this, preference);
}
+
+ return false;
}
/**
* Finds a {@link Preference} based on its key.
*
* @param key The key of the preference to retrieve.
- *
* @return The {@link Preference} with the key, or null.
- *
* @see PreferenceGroup#findPreference(CharSequence)
*/
public Preference findPreference(CharSequence key)
@@ -336,6 +271,29 @@ public class PreferenceListFragment extends ListFragment
return mPreferenceManager.findPreference(key);
}
+ private void requirePreferenceManager()
+ {
+ if (mPreferenceManager == null)
+ {
+ throw new RuntimeException("This should be called after super.onCreate.");
+ }
+ }
+
+ private void postBindPreferences()
+ {
+ if (mHandler.hasMessages(MSG_BIND_PREFERENCES)) return;
+ mHandler.obtainMessage(MSG_BIND_PREFERENCES).sendToTarget();
+ }
+
+ private void bindPreferences()
+ {
+ final PreferenceScreen preferenceScreen = getPreferenceScreen();
+ if (preferenceScreen != null)
+ {
+ preferenceScreen.bind(getListView());
+ }
+ }
+
public ListView getListView()
{
ensureList();
@@ -349,24 +307,45 @@ public class PreferenceListFragment extends ListFragment
return;
}
- final View root = getView();
+ View root = getView();
if (root == null)
{
throw new IllegalStateException("Content view not yet created");
}
- final View rawListView = root.findViewById(android.R.id.list);
+ View rawListView = root.findViewById(android.R.id.list);
if (!(rawListView instanceof ListView))
{
- throw new RuntimeException("Content has view with id attribute 'android.R.id.list' that is not a ListView class");
+ throw new RuntimeException(
+ "Content has view with id attribute 'android.R.id.list' that is not a ListView class");
}
mList = (ListView)rawListView;
if (mList == null)
{
- throw new RuntimeException("Your content must have a ListView whose id attribute is 'android.R.id.list'");
+ throw new RuntimeException(
+ "Your content must have a ListView whose id attribute is 'android.R.id.list'");
}
-
+ mList.setOnKeyListener(mListOnKeyListener);
mHandler.post(mRequestFocus);
}
+
+ private OnKeyListener mListOnKeyListener = new OnKeyListener()
+ {
+ @Override
+ public boolean onKey(View v, int keyCode, KeyEvent event)
+ {
+ Object selectedItem = mList.getSelectedItem();
+ if (selectedItem instanceof Preference)
+ {
+ @SuppressWarnings("unused")
+ View selectedView = mList.getSelectedView();
+ //return ((Preference)selectedItem).onKey(
+ // selectedView, keyCode, event);
+ return false;
+ }
+
+ return false;
+ }
+ };
}
\ No newline at end of file
diff --git a/android/phoenix/src/com/retroarch/browser/preferences/fragments/util/PreferenceManagerCompat.java b/android/phoenix/src/com/retroarch/browser/preferences/fragments/util/PreferenceManagerCompat.java
new file mode 100644
index 0000000000..db18870618
--- /dev/null
+++ b/android/phoenix/src/com/retroarch/browser/preferences/fragments/util/PreferenceManagerCompat.java
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.retroarch.browser.preferences.fragments.util;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.preference.Preference;
+import android.preference.PreferenceManager;
+import android.preference.PreferenceScreen;
+import android.util.Log;
+
+class PreferenceManagerCompat
+{
+ private static final String TAG = PreferenceManagerCompat.class.getSimpleName();
+
+ /**
+ * Interface definition for a callback to be invoked when a
+ * {@link Preference} in the hierarchy rooted at this {@link PreferenceScreen} is
+ * clicked.
+ */
+ interface OnPreferenceTreeClickListener
+ {
+ /**
+ * Called when a preference in the tree rooted at this
+ * {@link PreferenceScreen} has been clicked.
+ *
+ * @param preferenceScreen The {@link PreferenceScreen} that the
+ * preference is located in.
+ * @param preference The preference that was clicked.
+ * @return Whether the click was handled.
+ */
+ boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference);
+ }
+
+ static PreferenceManager newInstance(Activity activity, int firstRequestCode)
+ {
+ try
+ {
+ Constructor c = PreferenceManager.class.getDeclaredConstructor(Activity.class, int.class);
+ c.setAccessible(true);
+ return c.newInstance(activity, firstRequestCode);
+ }
+ catch (Exception e)
+ {
+ Log.w(TAG, "Couldn't call constructor PreferenceManager by reflection", e);
+ }
+ return null;
+ }
+
+ /**
+ * Sets the owning preference fragment
+ */
+ static void setFragment(PreferenceManager manager, PreferenceListFragment fragment)
+ {
+ // stub
+ }
+
+ /**
+ * Sets the callback to be invoked when a {@link Preference} in the
+ * hierarchy rooted at this {@link PreferenceManager} is clicked.
+ *
+ * @param listener The callback to be invoked.
+ */
+ static void setOnPreferenceTreeClickListener(PreferenceManager manager, final OnPreferenceTreeClickListener listener)
+ {
+ try
+ {
+ Field onPreferenceTreeClickListener = PreferenceManager.class.getDeclaredField("mOnPreferenceTreeClickListener");
+ onPreferenceTreeClickListener.setAccessible(true);
+ if (listener != null)
+ {
+ Object proxy = Proxy.newProxyInstance(onPreferenceTreeClickListener.getType().getClassLoader(), new Class[] { onPreferenceTreeClickListener.getType() }, new InvocationHandler()
+ {
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args)
+ {
+ if (method.getName().equals("onPreferenceTreeClick"))
+ {
+ return Boolean.valueOf(listener.onPreferenceTreeClick((PreferenceScreen) args[0], (Preference) args[1]));
+ }
+ else
+ {
+ return null;
+ }
+ }
+ });
+ onPreferenceTreeClickListener.set(manager, proxy);
+ }
+ else
+ {
+ onPreferenceTreeClickListener.set(manager, null);
+ }
+ }
+ catch (Exception e)
+ {
+ Log.w(TAG, "Couldn't set PreferenceManager.mOnPreferenceTreeClickListener by reflection", e);
+ }
+ }
+
+ /**
+ * Inflates a preference hierarchy from the preference hierarchies of
+ * {@link Activity Activities} that match the given {@link Intent}. An
+ * {@link Activity} defines its preference hierarchy with meta-data using
+ * the {@link #METADATA_KEY_PREFERENCES} key.
+ *
+ * If a preference hierarchy is given, the new preference hierarchies will
+ * be merged in.
+ *
+ * @param queryIntent The intent to match activities.
+ * @param rootPreferences Optional existing hierarchy to merge the new
+ * hierarchies into.
+ * @return The root hierarchy (if one was not provided, the new hierarchy's
+ * root).
+ */
+ static PreferenceScreen inflateFromIntent(PreferenceManager manager, Intent intent, PreferenceScreen screen)
+ {
+ try
+ {
+ Method m = PreferenceManager.class.getDeclaredMethod("inflateFromIntent", Intent.class, PreferenceScreen.class);
+ m.setAccessible(true);
+ PreferenceScreen prefScreen = (PreferenceScreen) m.invoke(manager, intent, screen);
+ return prefScreen;
+ }
+ catch (Exception e)
+ {
+ Log.w(TAG, "Couldn't call PreferenceManager.inflateFromIntent by reflection", e);
+ }
+ return null;
+ }
+
+ /**
+ * Inflates a preference hierarchy from XML. If a preference hierarchy is
+ * given, the new preference hierarchies will be merged in.
+ *
+ * @param context The context of the resource.
+ * @param resId The resource ID of the XML to inflate.
+ * @param rootPreferences Optional existing hierarchy to merge the new
+ * hierarchies into.
+ * @return The root hierarchy (if one was not provided, the new hierarchy's
+ * root).
+ * @hide
+ */
+ static PreferenceScreen inflateFromResource(PreferenceManager manager, Activity activity, int resId, PreferenceScreen screen)
+ {
+ try
+ {
+ Method m = PreferenceManager.class.getDeclaredMethod("inflateFromResource", Context.class, int.class, PreferenceScreen.class);
+ m.setAccessible(true);
+ PreferenceScreen prefScreen = (PreferenceScreen) m.invoke(manager, activity, resId, screen);
+ return prefScreen;
+ }
+ catch (Exception e)
+ {
+ Log.w(TAG, "Couldn't call PreferenceManager.inflateFromResource by reflection", e);
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the root of the preference hierarchy managed by this class.
+ *
+ * @return The {@link PreferenceScreen} object that is at the root of the hierarchy.
+ */
+ static PreferenceScreen getPreferenceScreen(PreferenceManager manager)
+ {
+ try
+ {
+ Method m = PreferenceManager.class.getDeclaredMethod("getPreferenceScreen");
+ m.setAccessible(true);
+ return (PreferenceScreen) m.invoke(manager);
+ }
+ catch (Exception e)
+ {
+ Log.w(TAG, "Couldn't call PreferenceManager.getPreferenceScreen by reflection", e);
+ }
+
+ return null;
+ }
+
+ /**
+ * Called by the {@link PreferenceManager} to dispatch a subactivity result.
+ */
+ static void dispatchActivityResult(PreferenceManager manager, int requestCode, int resultCode, Intent data)
+ {
+ try
+ {
+ Method m = PreferenceManager.class.getDeclaredMethod("dispatchActivityResult", int.class, int.class, Intent.class);
+ m.setAccessible(true);
+ m.invoke(manager, requestCode, resultCode, data);
+ }
+ catch (Exception e)
+ {
+ Log.w(TAG, "Couldn't call PreferenceManager.dispatchActivityResult by reflection", e);
+ }
+ }
+
+ /**
+ * Called by the {@link PreferenceManager} to dispatch the activity stop
+ * event.
+ */
+ static void dispatchActivityStop(PreferenceManager manager)
+ {
+ try
+ {
+ Method m = PreferenceManager.class.getDeclaredMethod("dispatchActivityStop");
+ m.setAccessible(true);
+ m.invoke(manager);
+ }
+ catch (Exception e)
+ {
+ Log.w(TAG, "Couldn't call PreferenceManager.dispatchActivityStop by reflection", e);
+ }
+ }
+
+ /**
+ * Called by the {@link PreferenceManager} to dispatch the activity destroy
+ * event.
+ */
+ static void dispatchActivityDestroy(PreferenceManager manager)
+ {
+ try
+ {
+ Method m = PreferenceManager.class.getDeclaredMethod("dispatchActivityDestroy");
+ m.setAccessible(true);
+ m.invoke(manager);
+ }
+ catch (Exception e)
+ {
+ Log.w(TAG, "Couldn't call PreferenceManager.dispatchActivityDestroy by reflection", e);
+ }
+ }
+
+ /**
+ * Sets the root of the preference hierarchy.
+ *
+ * @param preferenceScreen The root {@link PreferenceScreen} of the preference hierarchy.
+ * @return Whether the {@link PreferenceScreen} given is different than the previous.
+ */
+ static boolean setPreferences(PreferenceManager manager, PreferenceScreen screen)
+ {
+ try
+ {
+ Method m = PreferenceManager.class.getDeclaredMethod("setPreferences", PreferenceScreen.class);
+ m.setAccessible(true);
+ return ((Boolean) m.invoke(manager, screen));
+ }
+ catch (Exception e)
+ {
+ Log.w(TAG, "Couldn't call PreferenceManager.setPreferences by reflection", e);
+ }
+ return false;
+ }
+}
\ No newline at end of file