fragments = fm.getFragments();
- if (fragments != null && fragments.size() > 0)
- {
- for (Fragment fragment : fragments)
- {
- if (fragment.getChildFragmentManager().getBackStackEntryCount() > 0)
- {
- if (fragment.getChildFragmentManager().popBackStackImmediate())
- {
- return true;
- }
- else
- {
- return returnBackStackImmediate(fragment.getChildFragmentManager());
- }
- }
- }
- }
-
- return false;
- }
-
- // Callback function used to update the installed cores list
- @Override
- public void onCoreDownloaded()
- {
- InstalledCoresManagerFragment icmf = (InstalledCoresManagerFragment) getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.coreviewer_viewPager + ":" + 0);
- if (icmf != null)
- {
- InstalledCoresFragment icf = (InstalledCoresFragment) icmf.getChildFragmentManager().findFragmentByTag("InstalledCoresList");
- if (icf != null)
- icf.updateInstalledCoresList();
- }
- }
-
- // Adapter for the core manager ViewPager.
- private final class ViewPagerAdapter extends FragmentPagerAdapter
- {
- private final String[] pageTitles = {
- getString(R.string.installed_cores),
- getString(R.string.downloadable_cores)
- };
-
- /**
- * Constructor
- *
- * @param fm The {@link FragmentManager} for this adapter.
- */
- public ViewPagerAdapter(FragmentManager fm)
- {
- super(fm);
- }
-
- @Override
- public Fragment getItem(int position)
- {
- switch (position)
- {
- case 0:
- return new InstalledCoresManagerFragment();
-
- case 1:
- return new DownloadableCoresFragment();
-
- default: // Should never happen.
- return null;
- }
- }
-
- @Override
- public int getCount()
- {
- return 2;
- }
-
- @Override
- public CharSequence getPageTitle(int position)
- {
- return pageTitles[position];
- }
- }
-}
diff --git a/android/phoenix/src/com/retroarch/browser/coremanager/fragments/DownloadableCore.java b/android/phoenix/src/com/retroarch/browser/coremanager/fragments/DownloadableCore.java
deleted file mode 100644
index 9e55b96ccb..0000000000
--- a/android/phoenix/src/com/retroarch/browser/coremanager/fragments/DownloadableCore.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package com.retroarch.browser.coremanager.fragments;
-
-/**
- * Represents a core that can be downloaded.
- */
-final class DownloadableCore
-{
- private final String coreName;
- private final String coreURL;
- private final String shortURL;
-
- /**
- * Constructor
- *
- * @param coreName Name of the core.
- * @param coreURL URL to this core.
- */
- public DownloadableCore(String coreName, String coreURL)
- {
- this.coreName = coreName;
- this.coreURL = coreURL;
- this.shortURL = coreURL.substring(coreURL.lastIndexOf('/') + 1);
- }
-
- /**
- * Gets the name of this core.
- *
- * @return The name of this core.
- */
- public String getCoreName()
- {
- return coreName;
- }
-
- /**
- * Gets the URL to download this core.
- *
- * @return The URL to download this core.
- */
- public String getCoreURL()
- {
- return coreURL;
- }
-
- /**
- * Gets the short URL name of this core.
- *
- * e.g. Consider the url: www.somesite/somecore.zip.
- * This would return "somecore.zip"
- *
- * @return the short URL name of this core.
- */
- public String getShortURLName()
- {
- return shortURL;
- }
-}
diff --git a/android/phoenix/src/com/retroarch/browser/coremanager/fragments/DownloadableCoresAdapter.java b/android/phoenix/src/com/retroarch/browser/coremanager/fragments/DownloadableCoresAdapter.java
deleted file mode 100644
index 63e63f5158..0000000000
--- a/android/phoenix/src/com/retroarch/browser/coremanager/fragments/DownloadableCoresAdapter.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package com.retroarch.browser.coremanager.fragments;
-
-import android.content.Context;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import android.widget.TextView;
-
-/**
- * {@link ArrayAdapter} that handles the display of downloadable cores.
- */
-final class DownloadableCoresAdapter extends ArrayAdapter
-{
- private final int layoutId;
-
- /**
- * Constructor
- *
- * @param context The current {@link Context}.
- * @param layoutID The resource ID for a layout file containing a layout to use when instantiating views
- */
- public DownloadableCoresAdapter(Context context, int layoutId)
- {
- super(context, layoutId);
-
- this.layoutId = layoutId;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent)
- {
- if (convertView == null)
- {
- final LayoutInflater li = LayoutInflater.from(getContext());
- convertView = li.inflate(layoutId, parent, false);
- }
-
- final DownloadableCore core = getItem(position);
- if (core != null)
- {
- TextView title = (TextView) convertView.findViewById(android.R.id.text1);
- TextView subtitle = (TextView) convertView.findViewById(android.R.id.text2);
-
- if (title != null)
- title.setText(core.getCoreName());
-
- if (subtitle != null)
- subtitle.setText(core.getCoreURL());
- }
-
- return convertView;
- }
-}
\ No newline at end of file
diff --git a/android/phoenix/src/com/retroarch/browser/coremanager/fragments/DownloadableCoresFragment.java b/android/phoenix/src/com/retroarch/browser/coremanager/fragments/DownloadableCoresFragment.java
deleted file mode 100644
index b815de6ac5..0000000000
--- a/android/phoenix/src/com/retroarch/browser/coremanager/fragments/DownloadableCoresFragment.java
+++ /dev/null
@@ -1,449 +0,0 @@
-package com.retroarch.browser.coremanager.fragments;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-
-import org.jsoup.Connection;
-import org.jsoup.Jsoup;
-import org.jsoup.nodes.Element;
-import org.jsoup.select.Elements;
-
-import android.app.AlertDialog;
-import android.app.ProgressDialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Build;
-import android.os.Bundle;
-import android.support.v4.app.ListFragment;
-import android.util.Log;
-import android.view.ContextMenu;
-import android.view.ContextMenu.ContextMenuInfo;
-import android.view.LayoutInflater;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView.AdapterContextMenuInfo;
-import android.widget.ListView;
-import android.widget.Toast;
-
-import com.retroarch.R;
-
-/**
- * {@link ListFragment} that is responsible for showing
- * cores that are able to be downloaded or are not installed.
- */
-public final class DownloadableCoresFragment extends ListFragment
-{
- // List of TODOs.
- // - Eventually make the core downloader capable of directory-based browsing from the base URL.
- // - Allow for 'repository'-like core downloading.
- // - Clean this up a little better. It can likely be way more organized.
- // - Don't re-download the info files on orientation changes.
- // - Use a loading wheel when core retrieval is being done. User may think something went wrong otherwise.
- // - Check the info directory for an info file before downloading it. Can save bandwidth this way (and list load times would be faster).
- // - Should probably display a dialog or a toast message when the Internet connection process fails.
-
- /**
- * Dictates what actions will occur when a core download completes.
- *
- * Acts like a callback so that communication between fragments is possible.
- */
- public interface OnCoreDownloadedListener
- {
- /** The action that will occur when a core is successfully downloaded. */
- void onCoreDownloaded();
- }
-
- private static final String BUILDBOT_BASE_URL = "http://buildbot.libretro.com";
- private static final String BUILDBOT_CORE_URL_ARM = BUILDBOT_BASE_URL + "/nightly/android/latest/armeabi-v7a/";
- private static final String BUILDBOT_CORE_URL_X86 = BUILDBOT_BASE_URL + "/nightly/android/latest/x86/";
- private static final String BUILDBOT_INFO_URL = BUILDBOT_BASE_URL + "/assets/info/";
-
- private OnCoreDownloadedListener coreDownloadedListener = null;
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
- {
- super.onCreateView(inflater, container, savedInstanceState);
- final ListView coreList = (ListView) inflater.inflate(R.layout.coremanager_listview, container, false);
- registerForContextMenu(coreList);
-
- final DownloadableCoresAdapter adapter = new DownloadableCoresAdapter(getActivity(), android.R.layout.simple_list_item_2);
- adapter.setNotifyOnChange(true);
- coreList.setAdapter(adapter);
-
- coreDownloadedListener = (OnCoreDownloadedListener) getActivity();
-
- new PopulateCoresListOperation(adapter).execute();
-
- return coreList;
- }
-
- @Override
- public void onListItemClick(final ListView lv, final View v, final int position, final long id)
- {
- super.onListItemClick(lv, v, position, id);
- final DownloadableCore core = (DownloadableCore) lv.getItemAtPosition(position);
-
- // Prompt the user for confirmation on downloading the core.
- AlertDialog.Builder notification = new AlertDialog.Builder(getActivity());
- notification.setMessage(String.format(getString(R.string.download_core_confirm_msg), core.getCoreName()));
- notification.setTitle(R.string.download_core_confirm_title);
- notification.setNegativeButton(R.string.no, null);
- notification.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which)
- {
- // Begin downloading the core.
- new DownloadCoreOperation(getActivity(), core.getCoreName()).execute(core.getCoreURL(), core.getShortURLName());
- }
- });
- notification.show();
- }
-
- @Override
- public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)
- {
- super.onCreateContextMenu(menu, v, menuInfo);
-
- menu.setHeaderTitle(R.string.downloadable_cores_ctx_title);
-
- MenuInflater inflater = getActivity().getMenuInflater();
- inflater.inflate(R.menu.downloadable_cores_context_menu, menu);
- }
-
- @Override
- public boolean onContextItemSelected(MenuItem item)
- {
- final AdapterContextMenuInfo info = (AdapterContextMenuInfo)item.getMenuInfo();
-
- switch (item.getItemId())
- {
- case R.id.go_to_wiki_ctx_item:
- {
- String coreUrlPart = ((DownloadableCore)getListView().getItemAtPosition(info.position)).getCoreName().replace(" ", "_");
- Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://wiki.libretro.com/index.php?title=" + coreUrlPart));
- startActivity(browserIntent);
- return true;
- }
-
- default:
- return super.onContextItemSelected(item);
- }
- }
-
- // Async event responsible for populating the Downloadable Cores list.
- private static final class PopulateCoresListOperation extends AsyncTask>
- {
- // Acts as an object reference to an adapter in a list view.
- private DownloadableCoresAdapter adapter;
-
- /**
- * Constructor
- *
- * @param adapter The adapter to asynchronously update.
- */
- public PopulateCoresListOperation(DownloadableCoresAdapter adapter)
- {
- this.adapter = adapter;
- }
-
- @Override
- protected ArrayList doInBackground(Void... params)
- {
- try
- {
- final Connection core_connection = Build.CPU_ABI.startsWith("arm") ? Jsoup.connect(BUILDBOT_CORE_URL_ARM)
- : Jsoup.connect(BUILDBOT_CORE_URL_X86);
- final Elements coreElements = core_connection.get().body().getElementsByClass("fb-n").select("a");
-
- final ArrayList downloadableCores = new ArrayList();
-
- // NOTE: Start from 1 to skip the ".." (parent directory element)
- // Set this to zero if directory-based browsing becomes a thing.
- for (int i = 1; i < coreElements.size(); i++)
- {
- Element coreElement = coreElements.get(i);
-
- final String coreURL = BUILDBOT_BASE_URL + coreElement.attr("href");
- final String coreName = coreURL.substring(coreURL.lastIndexOf("/") + 1);
- final String infoURL = BUILDBOT_INFO_URL + coreName.replace(".so.zip", ".info");
-
- downloadableCores.add(new DownloadableCore(getCoreName(infoURL), coreURL));
- }
-
- return downloadableCores;
- }
- catch (IOException e)
- {
- Log.e("PopulateCoresListOperation", e.toString());
-
- // Make a dummy entry to notify an error.
- return new ArrayList();
- }
- }
-
- @Override
- protected void onPostExecute(ArrayList result)
- {
- super.onPostExecute(result);
-
- if (result.isEmpty())
- {
- Toast.makeText(adapter.getContext(), R.string.download_core_list_error, Toast.LENGTH_SHORT).show();
- }
- else
- {
- for (int i = 0; i < result.size(); i++)
- {
- adapter.add(result.get(i));
- }
- }
- }
-
- // Literally downloads the info file, writes it, and parses it for the corename key/value pair.
- // AKA an argument for having a manifest file on the server.
- //
- // This makes list loading take way longer than it should.
- //
- // One way this can be improved is by checking the info directory for
- // existing info files that match the core. Eliminating the download retrieval.
- private String getCoreName(String urlPath)
- {
- String name = "";
-
- try
- {
- final URL url = new URL(urlPath);
- final BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
- final StringBuilder sb = new StringBuilder();
-
- String str = "";
- while ((str = br.readLine()) != null)
- sb.append(str + "\n");
- br.close();
-
- // Write the info file.
- File outputPath = new File(adapter.getContext().getApplicationInfo().dataDir + "/info/", urlPath.substring(urlPath.lastIndexOf('/') + 1));
- BufferedWriter bw = new BufferedWriter(new FileWriter(outputPath));
- bw.append(sb);
- bw.close();
-
- // Now read the core name
- String[] lines = sb.toString().split("\n");
- for (int i = 0; i < lines.length; i++)
- {
- if (lines[i].contains("corename"))
- {
- // Gross
- name = lines[i].split("=")[1].trim().replace("\"", "");
- break;
- }
- }
- }
- catch (FileNotFoundException fnfe)
- {
- // Can't find the info file. Name it the same thing as the package.
- final int start = urlPath.lastIndexOf('/') + 1;
- final int end = urlPath.lastIndexOf('.');
- if (end == -1)
- name = urlPath.substring(start);
- else
- name = urlPath.substring(start, end);
- }
- catch (IOException ioe)
- {
- name = "Report this: " + ioe.getMessage();
- }
-
- return name;
- }
- }
-
- // Executed when the user confirms a core download.
- private final class DownloadCoreOperation extends AsyncTask
- {
- private final ProgressDialog dlg;
- private final Context ctx;
- private final String coreName;
-
- /**
- * Constructor
- *
- * @param ctx The current {@link Context}.
- * @param coreName The name of the core being downloaded.
- */
- public DownloadCoreOperation(Context ctx, String coreName)
- {
- this.dlg = new ProgressDialog(ctx);
- this.ctx = ctx;
- this.coreName = coreName;
- }
-
- @Override
- protected void onPreExecute()
- {
- super.onPreExecute();
-
- dlg.setMessage(String.format(ctx.getString(R.string.downloading_msg), coreName));
- dlg.setCancelable(false);
- dlg.setCanceledOnTouchOutside(false);
- dlg.setIndeterminate(false);
- dlg.setMax(100);
- dlg.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
- dlg.show();
- }
-
- @Override
- protected Void doInBackground(String... params)
- {
- InputStream input = null;
- OutputStream output = null;
- HttpURLConnection connection = null;
- try
- {
- URL url = new URL(params[0]);
- connection = (HttpURLConnection) url.openConnection();
- connection.connect();
-
- if (connection.getResponseCode() != HttpURLConnection.HTTP_OK)
- {
- Log.i("DownloadCoreOperation", "HTTP response code not OK. Response code: " + connection.getResponseCode());
- return null;
- }
-
- // Set up the streams
- final int fileLen = connection.getContentLength();
- final File zipPath = new File(ctx.getApplicationInfo().dataDir + "/cores/", params[1]);
- input = new BufferedInputStream(connection.getInputStream(), 8192);
- output = new FileOutputStream(zipPath);
-
- // Download and write to storage.
- long totalDownloaded = 0;
- byte[] buffer = new byte[4096];
- int countBytes = 0;
- while ((countBytes = input.read(buffer)) != -1)
- {
- totalDownloaded += countBytes;
- if (fileLen > 0)
- publishProgress((int) (totalDownloaded * 100 / fileLen));
-
- output.write(buffer, 0, countBytes);
- }
-
- unzipCore(zipPath);
- }
- catch (IOException ignored)
- {
- // Can't really do anything to recover.
- }
- finally
- {
- try
- {
- if (output != null)
- output.close();
-
- if (input != null)
- input.close();
- }
- catch (IOException ignored)
- {
- }
-
- if (connection != null)
- connection.disconnect();
- }
-
- return null;
- }
-
- @Override
- protected void onProgressUpdate(Integer... progress)
- {
- super.onProgressUpdate(progress);
-
- dlg.setProgress(progress[0]);
- }
-
- @Override
- protected void onPostExecute(Void result)
- {
- super.onPostExecute(result);
-
- if (dlg.isShowing())
- dlg.dismiss();
-
- // Invoke callback to update the installed cores list.
- coreDownloadedListener.onCoreDownloaded();
- }
- }
-
- // Java 6 ladies and gentlemen.
- private static void unzipCore(File zipFile)
- {
- ZipInputStream zis = null;
-
- try
- {
- zis = new ZipInputStream(new FileInputStream(zipFile));
- ZipEntry entry = zis.getNextEntry();
-
- while (entry != null)
- {
- File file = new File(zipFile.getParent(), entry.getName());
-
- FileOutputStream fos = new FileOutputStream(file);
- int len = 0;
- byte[] buffer = new byte[4096];
- while ((len = zis.read(buffer)) != -1)
- {
- fos.write(buffer, 0, len);
- }
- fos.close();
-
- entry = zis.getNextEntry();
- }
- }
- catch (IOException ignored)
- {
- // Can't do anything.
- }
- finally
- {
- try
- {
- if (zis != null)
- {
- zis.closeEntry();
- zis.close();
- }
- }
- catch (IOException ignored)
- {
- // Can't do anything
- }
-
- zipFile.delete();
- }
- }
-}
diff --git a/android/phoenix/src/com/retroarch/browser/coremanager/fragments/InstalledCoreInfoFragment.java b/android/phoenix/src/com/retroarch/browser/coremanager/fragments/InstalledCoreInfoFragment.java
deleted file mode 100644
index 4e7b1e1a0b..0000000000
--- a/android/phoenix/src/com/retroarch/browser/coremanager/fragments/InstalledCoreInfoFragment.java
+++ /dev/null
@@ -1,121 +0,0 @@
-package com.retroarch.browser.coremanager.fragments;
-
-import java.io.File;
-
-import com.retroarch.R;
-import com.retroarch.browser.ModuleWrapper;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.support.v4.app.ListFragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import android.widget.ListView;
-import android.widget.TextView;
-
-/**
- * Fragment that displays information about a selected core.
- */
-public final class InstalledCoreInfoFragment extends ListFragment
-{
- /**
- * Creates a new instance of a InstalledCoreInfoFragment.
- *
- * @param core The wrapped core to represent.
- *
- * @return a new instance of a InstalledCoreInfoFragment.
- */
- public static InstalledCoreInfoFragment newInstance(ModuleWrapper core)
- {
- InstalledCoreInfoFragment cif = new InstalledCoreInfoFragment();
-
- // Set the core path as an argument.
- // This will allow us to re-retrieve information if the Fragment
- // is destroyed upon state changes
- Bundle args = new Bundle();
- args.putString("core_path", core.getUnderlyingFile().getPath());
- cif.setArguments(args);
-
- return cif;
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
- {
- // Inflate the view.
- ListView infoView = (ListView) inflater.inflate(R.layout.coremanager_listview, container, false);
-
- // Get the appropriate info providers.
- final Bundle args = getArguments();
- final ModuleWrapper core = new ModuleWrapper(getActivity(), new File(args.getString("core_path")));
-
- // Initialize the core info.
- CoreInfoAdapter adapter = new CoreInfoAdapter(getActivity(), android.R.layout.simple_list_item_2);
- adapter.add(new InstalledCoreInfoItem(getString(R.string.core_info_displayNameTitle), core.getDisplayName()));
- adapter.add(new InstalledCoreInfoItem(getString(R.string.core_info_internalNameTitle), core.getInternalName()));
- adapter.add(new InstalledCoreInfoItem(getString(R.string.core_info_systemNameTitle), core.getEmulatedSystemName()));
- adapter.add(new InstalledCoreInfoItem(getString(R.string.core_info_manufacturer), core.getManufacturer()));
- adapter.add(new InstalledCoreInfoItem(getString(R.string.core_info_author), core.getAuthors()));
- adapter.add(new InstalledCoreInfoItem(getString(R.string.core_info_licenseTitle), core.getCoreLicense()));
- adapter.add(new InstalledCoreInfoItem(getString(R.string.core_info_permissions), core.getPermissions()));
-
- // Set the list adapter.
- infoView.setAdapter(adapter);
-
- return infoView;
- }
-
- /**
- * Adapter backing this InstalledCoreInfoFragment
- */
- private final class CoreInfoAdapter extends ArrayAdapter
- {
- private final Context context;
- private final int resourceId;
-
- /**
- * Constructor
- *
- * @param context The current {@link Context}.
- * @param resourceId The resource ID for a layout file containing a layout to use when instantiating views.
- */
- public CoreInfoAdapter(Context context, int resourceId)
- {
- super(context, resourceId);
-
- this.context = context;
- this.resourceId = resourceId;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent)
- {
- if (convertView == null)
- {
- LayoutInflater vi = LayoutInflater.from(context);
- convertView = vi.inflate(resourceId, parent, false);
- }
-
- final InstalledCoreInfoItem item = getItem(position);
- if (item != null)
- {
- final TextView title = (TextView) convertView.findViewById(android.R.id.text1);
- final TextView subtitle = (TextView) convertView.findViewById(android.R.id.text2);
-
- if (title != null)
- {
- title.setText(item.getTitle());
- }
-
- if (subtitle != null)
- {
- subtitle.setText(item.getSubtitle());
- }
- }
-
- return convertView;
- }
- }
-}
diff --git a/android/phoenix/src/com/retroarch/browser/coremanager/fragments/InstalledCoreInfoItem.java b/android/phoenix/src/com/retroarch/browser/coremanager/fragments/InstalledCoreInfoItem.java
deleted file mode 100644
index 6b6d4ae0d8..0000000000
--- a/android/phoenix/src/com/retroarch/browser/coremanager/fragments/InstalledCoreInfoItem.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package com.retroarch.browser.coremanager.fragments;
-
-import java.util.List;
-
-import android.text.TextUtils;
-
-/**
- * Represents a single list item within the InstalledCoreInfoFragment.
- */
-public final class InstalledCoreInfoItem
-{
- private final String title;
- private final String subtitle;
-
- /**
- * Constructor
- *
- * @param title Title of the item within the core info list.
- * @param subtitle Subtitle of the item within the core info list.
- */
- public InstalledCoreInfoItem(String title, String subtitle)
- {
- this.title = title;
- this.subtitle = subtitle;
- }
-
- /**
- * Constructor.
- *
- * Allows for creating a subtitle out of multiple strings.
- *
- * @param title Title of the item within the core info list.
- * @param subtitle List of strings to add to the subtitle section of this item.
- */
- public InstalledCoreInfoItem(String title, List subtitle)
- {
- this.title = title;
- this.subtitle = TextUtils.join(", ", subtitle);
- }
-
- /**
- * Gets the title of this InstalledCoreInfoItem.
- *
- * @return the title of this InstalledCoreInfoItem.
- */
- public String getTitle()
- {
- return title;
- }
-
- /**
- * Gets the subtitle of this InstalledCoreInfoItem.
- *
- * @return the subtitle of this InstalledCoreInfoItem.
- */
- public String getSubtitle()
- {
- return subtitle;
- }
-}
diff --git a/android/phoenix/src/com/retroarch/browser/coremanager/fragments/InstalledCoresFragment.java b/android/phoenix/src/com/retroarch/browser/coremanager/fragments/InstalledCoresFragment.java
deleted file mode 100644
index 449298f78c..0000000000
--- a/android/phoenix/src/com/retroarch/browser/coremanager/fragments/InstalledCoresFragment.java
+++ /dev/null
@@ -1,248 +0,0 @@
-package com.retroarch.browser.coremanager.fragments;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import com.retroarch.R;
-import com.retroarch.browser.ModuleWrapper;
-import com.retroarch.browser.preferences.util.UserPreferences;
-
-import android.app.AlertDialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnClickListener;
-import android.os.Bundle;
-import android.support.v4.app.ListFragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemLongClickListener;
-import android.widget.ArrayAdapter;
-import android.widget.ListView;
-import android.widget.TextView;
-import android.widget.Toast;
-
-/**
- * {@link ListFragment} that displays all of the currently installed cores
- *
- * In terms of layout, this is the fragment that is placed on the
- * left side of the screen within the core manager
- */
-public final class InstalledCoresFragment extends ListFragment
-{
- // Callback for the interface.
- private OnCoreItemClickedListener callback;
-
- // Adapter backing this ListFragment.
- private InstalledCoresAdapter adapter;
-
- /**
- * Interface that a parent fragment must implement
- * in order to display the core info view.
- */
- interface OnCoreItemClickedListener
- {
- /**
- * The action to perform when a core is selected within the list view.
- *
- * @param position The position of the item in the list.
- * @param core A reference to the actual {@link ModuleWrapper}
- * represented by that list item.
- */
- void onCoreItemClicked(int position, ModuleWrapper core);
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState)
- {
- super.onActivityCreated(savedInstanceState);
-
- adapter = new InstalledCoresAdapter(getActivity(), android.R.layout.simple_list_item_2, getInstalledCoresList());
- setListAdapter(adapter);
-
- // Get the callback. (implemented within InstalledCoresManagerFragment).
- callback = (OnCoreItemClickedListener) getParentFragment();
- }
-
- @Override
- public void onViewCreated(View view, Bundle savedInstanceState)
- {
- super.onViewCreated(view, savedInstanceState);
-
- getListView().setOnItemLongClickListener(itemLongClickListener);
- }
-
- @Override
- public void onListItemClick(ListView l, View v, int position, long id)
- {
- callback.onCoreItemClicked(position, adapter.getItem(position));
-
- // Set the item as checked so it highlights in the two-fragment view.
- getListView().setItemChecked(position, true);
- }
-
- /**
- * Refreshes the list of installed cores.
- */
- public void updateInstalledCoresList()
- {
- adapter.clear();
- for (int i = 0; i < getInstalledCoresList().size(); i++)
- {
- adapter.add(getInstalledCoresList().get(i));
- }
- adapter.notifyDataSetChanged();
- }
-
- private List getInstalledCoresList()
- {
- // The list of items that will be added to the adapter backing this ListFragment.
- final List items = new ArrayList();
-
- // Check if the device supports NEON.
- final String cpuInfo = UserPreferences.readCPUInfo();
- final boolean supportsNeon = cpuInfo.contains("neon");
-
- // Populate the list
- final File[] libs = new File(getActivity().getApplicationInfo().dataDir, "/cores").listFiles();
- if (libs != null)
- {
- for (File lib : libs)
- {
- String libName = lib.getName();
-
- // Never append a NEON lib if we don't have NEON.
- if (libName.contains("neon") && !supportsNeon)
- continue;
-
- // If we have a NEON version with NEON capable CPU,
- // never append a non-NEON version.
- if (supportsNeon && !libName.contains("neon"))
- {
- boolean hasNeonVersion = false;
- for (File lib_ : libs)
- {
- String otherName = lib_.getName();
- String baseName = libName.replace(".so", "");
-
- if (otherName.contains("neon") && otherName.startsWith(baseName))
- {
- hasNeonVersion = true;
- break;
- }
- }
-
- if (hasNeonVersion)
- continue;
- }
-
- // Add it to the list.
- items.add(new ModuleWrapper(getActivity(), lib));
- }
- }
-
- // Sort the list alphabetically
- Collections.sort(items);
- return items;
- }
-
- // This will be the handler for long clicks on individual list items in this ListFragment.
- private final OnItemLongClickListener itemLongClickListener = new OnItemLongClickListener()
- {
- @Override
- public boolean onItemLongClick(AdapterView> parent, View view, int position, long id)
- {
- // Begin building the AlertDialog
- final ModuleWrapper item = adapter.getItem(position);
- final AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());
- alert.setTitle(R.string.uninstall_core);
- alert.setMessage(String.format(getString(R.string.uninstall_core_message), item.getText()));
- alert.setNegativeButton(R.string.no, null);
- alert.setPositiveButton(R.string.yes, new OnClickListener()
- {
- @Override
- public void onClick(DialogInterface dialog, int which)
- {
- // Attempt to uninstall the core item.
- if (item.getUnderlyingFile().delete())
- {
- Toast.makeText(getActivity(), String.format(getString(R.string.uninstall_success), item.getText()), Toast.LENGTH_LONG).show();
- adapter.remove(item);
- adapter.notifyDataSetChanged();
- }
- else // Failed to uninstall.
- {
- Toast.makeText(getActivity(), String.format(getString(R.string.uninstall_failure), item.getText()), Toast.LENGTH_LONG).show();
- }
- }
- });
- alert.show();
-
- return true;
- }
- };
-
- /**
- * The {@link ArrayAdapter} that backs this InstalledCoresFragment.
- */
- private final class InstalledCoresAdapter extends ArrayAdapter
- {
- private final Context context;
- private final int resourceId;
- private final List items;
-
- /**
- * Constructor
- *
- * @param context The current {@link Context}.
- * @param resourceId The resource ID for a layout file containing a layout to use when instantiating views.
- * @param items The list of items to represent in this adapter.
- */
- public InstalledCoresAdapter(Context context, int resourceId, List items)
- {
- super(context, resourceId, items);
-
- this.context = context;
- this.resourceId = resourceId;
- this.items = items;
- }
-
- @Override
- public ModuleWrapper getItem(int i)
- {
- return items.get(i);
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent)
- {
- if (convertView == null)
- {
- LayoutInflater vi = LayoutInflater.from(context);
- convertView = vi.inflate(resourceId, parent, false);
- }
-
- final ModuleWrapper item = items.get(position);
- if (item != null)
- {
- TextView title = (TextView) convertView.findViewById(android.R.id.text1);
- TextView subtitle = (TextView) convertView.findViewById(android.R.id.text2);
-
- if (title != null)
- {
- title.setText(item.getText());
- }
-
- if (subtitle != null)
- {
- subtitle.setText(item.getSubText());
- }
- }
-
- return convertView;
- }
- }
-}
diff --git a/android/phoenix/src/com/retroarch/browser/coremanager/fragments/InstalledCoresManagerFragment.java b/android/phoenix/src/com/retroarch/browser/coremanager/fragments/InstalledCoresManagerFragment.java
deleted file mode 100644
index 1178710130..0000000000
--- a/android/phoenix/src/com/retroarch/browser/coremanager/fragments/InstalledCoresManagerFragment.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package com.retroarch.browser.coremanager.fragments;
-
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentTransaction;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.retroarch.R;
-import com.retroarch.browser.ModuleWrapper;
-
-/**
- * Underlying {@link Fragment} that manages layout functionality
- * for the two fragments that rest inside of this one.
- */
-public class InstalledCoresManagerFragment extends Fragment implements InstalledCoresFragment.OnCoreItemClickedListener
-{
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
- {
- View v = inflater.inflate(R.layout.coremanager_installed_cores_base, container, false);
-
- final Fragment installedCores = new InstalledCoresFragment();
- final FragmentTransaction ft = getChildFragmentManager().beginTransaction();
- ft.replace(R.id.installed_cores_fragment_container1, installedCores, "InstalledCoresList");
- ft.commit();
-
- return v;
- }
-
- @Override
- public void onCoreItemClicked(int position, ModuleWrapper core)
- {
- // If this view does not exist, it means the screen
- // is not considered 'large' and thus, we use the single fragment layout.
- if (getView().findViewById(R.id.installed_cores_fragment_container2) == null)
- {
- InstalledCoreInfoFragment cif = InstalledCoreInfoFragment.newInstance(core);
- FragmentTransaction ft = getChildFragmentManager().beginTransaction();
- ft.replace(R.id.installed_cores_fragment_container1, cif);
- ft.addToBackStack(null);
- ft.commit();
- }
- else // Large screen
- {
- InstalledCoreInfoFragment cif = InstalledCoreInfoFragment.newInstance(core);
- FragmentTransaction ft = getChildFragmentManager().beginTransaction();
- ft.replace(R.id.installed_cores_fragment_container2, cif);
- ft.commit();
- }
- }
-}
diff --git a/android/phoenix/src/com/retroarch/browser/mainmenu/MainMenuFragment.java b/android/phoenix/src/com/retroarch/browser/mainmenu/MainMenuFragment.java
index b0f910ebaf..cc69775a24 100644
--- a/android/phoenix/src/com/retroarch/browser/mainmenu/MainMenuFragment.java
+++ b/android/phoenix/src/com/retroarch/browser/mainmenu/MainMenuFragment.java
@@ -25,7 +25,6 @@ import android.widget.Toast;
import com.retroarch.R;
import com.retroarch.browser.CoreSelection;
-import com.retroarch.browser.HistorySelection;
import com.retroarch.browser.NativeInterface;
import com.retroarch.browser.dirfragment.DetectCoreDirectoryFragment;
import com.retroarch.browser.dirfragment.DirectoryFragment;
@@ -68,7 +67,6 @@ public final class MainMenuFragment extends PreferenceListFragment implements On
findPreference("loadCorePref").setOnPreferenceClickListener(this);
findPreference("loadContentAutoPref").setOnPreferenceClickListener(this);
findPreference("loadContentPref").setOnPreferenceClickListener(this);
- findPreference("loadContentHistoryPref").setOnPreferenceClickListener(this);
findPreference("quitRetroArch").setOnPreferenceClickListener(this);
// Extract assets.
@@ -259,11 +257,6 @@ public final class MainMenuFragment extends PreferenceListFragment implements On
contentBrowser.show(getFragmentManager(), "contentBrowser");
}
- // Load Content (History) Preference
- else if (prefKey.equals("loadContentHistoryPref"))
- {
- HistorySelection.newInstance().show(getFragmentManager(), "history_selection");
- }
// Quit RetroArch preference
else if (prefKey.equals("quitRetroArch"))
{
diff --git a/android/phoenix/src/com/retroarch/browser/preferences/util/KeyBindPreference.java b/android/phoenix/src/com/retroarch/browser/preferences/util/KeyBindPreference.java
deleted file mode 100644
index d35454b3b8..0000000000
--- a/android/phoenix/src/com/retroarch/browser/preferences/util/KeyBindPreference.java
+++ /dev/null
@@ -1,139 +0,0 @@
-package com.retroarch.browser.preferences.util;
-
-import android.content.Context;
-import android.preference.DialogPreference;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.AdapterView;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.ListView;
-
-import com.retroarch.R;
-
-final class KeyBindEditText extends EditText
-{
- private KeyBindPreference pref;
-
- public KeyBindEditText(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public void setBoundPreference(KeyBindPreference pref)
- {
- this.pref = pref;
- }
-
- @Override
- public boolean onKeyPreIme(int keyCode, KeyEvent event)
- {
- return pref.onKey(null, event.getKeyCode(), event);
- }
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event)
- {
- return pref.onKey(null, event.getKeyCode(), event);
- }
-}
-
-final class KeyBindPreference extends DialogPreference implements View.OnKeyListener, AdapterView.OnItemClickListener, LayoutInflater.Factory {
- private int key_bind_code;
- private boolean grabKeyCode = false;
- private KeyBindEditText keyText;
- private String[] key_labels;
- private final int DEFAULT_KEYCODE = 0;
- private final Context context;
-
- public KeyBindPreference(Context context, AttributeSet attrs) {
- super(context, attrs);
-
- this.context = context;
- this.key_labels = getContext().getResources().getStringArray(R.array.key_bind_values);
- }
-
- private void setKey(int keyCode, boolean force)
- {
- if (grabKeyCode || force)
- {
- grabKeyCode = false;
- key_bind_code = keyCode;
- keyText.setText(String.format(context.getString(R.string.current_binding), key_labels[key_bind_code]));
- }
- }
-
- @Override
- protected View onCreateDialogView()
- {
- LayoutInflater inflater = LayoutInflater.from(context).cloneInContext(getContext());
- inflater.setFactory(this);
- View view = inflater.inflate(R.layout.key_bind_dialog, null);
- keyText = (KeyBindEditText) view.findViewById(R.id.key_bind_value);
- keyText.setBoundPreference(this);
- view.setOnKeyListener(this);
- ((ListView) view.findViewById(R.id.key_bind_list)).setOnItemClickListener(this);
- ((Button) view.findViewById(R.id.key_bind_clear)).setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- setKey(0, true);
- }
- });
- ((Button) view.findViewById(R.id.key_bind_detect)).setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- grabKeyCode = true;
- keyText.setText(R.string.press_key_to_use);
- keyText.requestFocus();
- }
- });
- InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
- imm.hideSoftInputFromWindow(keyText.getWindowToken(), 0);
- setKey(getPersistedInt(DEFAULT_KEYCODE), true);
- return view;
- }
-
- @Override
- protected void onDialogClosed(boolean positiveResult) {
- super.onDialogClosed(positiveResult);
-
- if (positiveResult) {
- persistInt(key_bind_code);
- notifyChanged();
- }
- }
-
- @Override
- public boolean onKey(View v, int keyCode, KeyEvent event) {
- if (grabKeyCode && event.getAction() == KeyEvent.ACTION_DOWN && keyCode != 0 && keyCode < key_labels.length)
- {
- setKey(keyCode, false);
- return true;
- }
- return false;
- }
-
- @Override
- public void onItemClick(AdapterView> parent, View view, int position, long id) {
- setKey((int)id, true);
- }
-
- @Override
- public CharSequence getSummary() {
- int code = getPersistedInt(DEFAULT_KEYCODE);
- if (code >= key_labels.length)
- return "";
- else
- return key_labels[code];
- }
-
- @Override
- public View onCreateView(String name, Context context, AttributeSet attrs) {
- Log.i("RetroArch", "view name: " + name);
- if (name.equals("EditText"))
- return new KeyBindEditText(context, attrs);
- else
- return null;
- }
-}
\ No newline at end of file
diff --git a/configuration.c b/configuration.c
index 25cb43fc34..4d9ecd1c00 100644
--- a/configuration.c
+++ b/configuration.c
@@ -630,6 +630,7 @@ static void config_set_defaults(void)
settings->network.buildbot_auto_extract_archive = true;
settings->input.overlay_enable = true;
+ settings->input.overlay_enable_autopreferred = true;
settings->input.overlay_opacity = 0.7f;
settings->input.overlay_scale = 1.0f;
settings->input.autodetect_enable = input_autodetect_enable;
@@ -1544,6 +1545,7 @@ static bool config_load_file(const char *path, bool set_defaults)
config_get_path(conf, "input_overlay", settings->input.overlay, sizeof(settings->input.overlay));
CONFIG_GET_BOOL_BASE(conf, settings, input.overlay_enable, "input_overlay_enable");
+ CONFIG_GET_BOOL_BASE(conf, settings, input.overlay_enable_autopreferred, "input_overlay_enable_autopreferred");
CONFIG_GET_FLOAT_BASE(conf, settings, input.overlay_opacity, "input_overlay_opacity");
CONFIG_GET_FLOAT_BASE(conf, settings, input.overlay_scale, "input_overlay_scale");
@@ -2548,6 +2550,7 @@ bool config_save_file(const char *path)
*global->overlay_dir ? global->overlay_dir : "default");
config_set_path(conf, "input_overlay", settings->input.overlay);
config_set_bool(conf, "input_overlay_enable", settings->input.overlay_enable);
+ config_set_bool(conf, "input_overlay_enable_autopreferred", settings->input.overlay_enable_autopreferred);
config_set_float(conf, "input_overlay_opacity",
settings->input.overlay_opacity);
config_set_float(conf, "input_overlay_scale",
diff --git a/configuration.h b/configuration.h
index 24409aae58..84d355fc4b 100644
--- a/configuration.h
+++ b/configuration.h
@@ -229,6 +229,7 @@ typedef struct settings
unsigned turbo_duty_cycle;
bool overlay_enable;
+ bool overlay_enable_autopreferred;
char overlay[PATH_MAX_LENGTH];
float overlay_opacity;
float overlay_scale;
diff --git a/menu/intl/menu_hash_us.c b/menu/intl/menu_hash_us.c
index c1fd1dfaf7..d587c73e3a 100644
--- a/menu/intl/menu_hash_us.c
+++ b/menu/intl/menu_hash_us.c
@@ -26,6 +26,8 @@ static const char *menu_hash_to_str_us_label(uint32_t hash)
{
switch (hash)
{
+ case MENU_LABEL_OVERLAY_AUTOLOAD_PREFERRED:
+ return "overlay_autoload_preferred";
case MENU_LABEL_INFORMATION_LIST:
return "information_list";
case MENU_LABEL_USE_BUILTIN_PLAYER:
@@ -594,6 +596,8 @@ const char *menu_hash_to_str_us(uint32_t hash)
switch (hash)
{
+ case MENU_LABEL_OVERLAY_AUTOLOAD_PREFERRED:
+ return "Auto-load preferred overlay";
case MENU_LABEL_VALUE_INFORMATION_LIST:
return "Information";
case MENU_LABEL_VALUE_USE_BUILTIN_PLAYER:
diff --git a/menu/menu_hash.h b/menu/menu_hash.h
index d376b61f70..8b077b7d6e 100644
--- a/menu/menu_hash.h
+++ b/menu/menu_hash.h
@@ -952,6 +952,9 @@ extern "C" {
#define MENU_LABEL_USE_BUILTIN_IMAGE_VIEWER 0x5203b5bbU
#define MENU_LABEL_VALUE_USE_BUILTIN_IMAGE_VIEWER 0x1ab45d3eU
+#define MENU_LABEL_OVERLAY_AUTOLOAD_PREFERRED 0xc9298cbdU
+#define MENU_LABEL_VALUE_OVERLAY_AUTOLOAD_PREFERRED 0x0e27e33fU
+
const char *menu_hash_to_str_de(uint32_t hash);
int menu_hash_get_help_de(uint32_t hash, char *s, size_t len);
diff --git a/menu/menu_setting.c b/menu/menu_setting.c
index d20becab11..2c2c2f4155 100644
--- a/menu/menu_setting.c
+++ b/menu/menu_setting.c
@@ -4485,6 +4485,20 @@ static bool setting_append_list_overlay_options(
general_read_handler);
(*list)[list_info->index - 1].change_handler = overlay_enable_toggle_change_handler;
+ CONFIG_BOOL(
+ settings->input.overlay_enable,
+ menu_hash_to_str(MENU_LABEL_OVERLAY_AUTOLOAD_PREFERRED),
+ menu_hash_to_str(MENU_LABEL_VALUE_OVERLAY_AUTOLOAD_PREFERRED),
+ true,
+ menu_hash_to_str(MENU_VALUE_OFF),
+ menu_hash_to_str(MENU_VALUE_ON),
+ group_info.name,
+ subgroup_info.name,
+ parent_group,
+ general_write_handler,
+ general_read_handler);
+ (*list)[list_info->index - 1].change_handler = overlay_enable_toggle_change_handler;
+
CONFIG_BOOL(
settings->osk.enable,
menu_hash_to_str(MENU_LABEL_INPUT_OSK_OVERLAY_ENABLE),