123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318 |
- package com.xugame.gameconsole.preferences;
- import android.annotation.TargetApi;
- import android.content.Context;
- import android.content.SharedPreferences;
- import android.content.pm.PackageManager;
- import android.media.AudioManager;
- import android.media.AudioTrack;
- import android.os.Build;
- import android.preference.PreferenceManager;
- import android.util.Log;
- import com.xugame.gameconsole.util.DebugUtil;
- import java.io.File;
- import java.io.IOException;
- public class UserPreferences {
- // Logging tag.
- private static final String TAG = "UserPreferences";
- // Disallow explicit instantiation.
- private UserPreferences()
- {
- }
- /**
- * Retrieves the path to the default location of the libretro config.
- *
- * @param ctx the current {@link Context}
- *
- * @return the path to the default location of the libretro config.
- */
- public static String getDefaultConfigPath(Context ctx)
- {
- // Internal/External storage dirs.
- final String internal = ctx.getFilesDir().getAbsolutePath();
- String external = null;
- // Get the App's external storage folder
- final String state = android.os.Environment.getExternalStorageState();
- if (android.os.Environment.MEDIA_MOUNTED.equals(state)) {
- File extsd = ctx.getExternalFilesDir(null);
- external = extsd.getAbsolutePath();
- }
- // Native library directory and data directory for this front-end.
- final String dataDir = ctx.getApplicationInfo().dataDir;
- final String coreDir = dataDir + "/cores/";
- // Get libretro name and path
- final SharedPreferences prefs = getPreferences(ctx);
- final String libretro_path = prefs.getString("libretro_path", coreDir);
- // Check if global config is being used. Return true upon failure.
- final boolean globalConfigEnabled = prefs.getBoolean("global_config_enable", true);
- String append_path;
- // If we aren't using the global config.
- if (!globalConfigEnabled && !libretro_path.equals(coreDir))
- {
- String sanitized_name = sanitizeLibretroPath(libretro_path);
- append_path = File.separator + sanitized_name + ".cfg";
- }
- else // Using global config.
- {
- append_path = File.separator + "retroarch.cfg";
- }
- if (external != null)
- {
- String confPath = external + append_path;
- if (new File(confPath).exists())
- return confPath;
- }
- else if (internal != null)
- {
- String confPath = internal + append_path;
- if (new File(confPath).exists())
- return confPath;
- }
- else
- {
- String confPath = "/mnt/extsd" + append_path;
- if (new File(confPath).exists())
- return confPath;
- }
- // Config file does not exist. Create empty one.
- // emergency fallback
- String new_path = "/mnt/sd" + append_path;
- if (external != null)
- new_path = external + append_path;
- else if (internal != null)
- new_path = internal + append_path;
- else if (dataDir != null)
- new_path = dataDir + append_path;
- try {
- new File(new_path).createNewFile();
- }
- catch (IOException e)
- {
- Log.e(TAG, "Failed to create config file to: " + new_path);
- }
- return new_path;
- }
- /**
- * Updates the libretro configuration file
- * with new values if settings have changed.
- *
- * @param ctx the current {@link Context}.
- */
- public static void updateConfigFile(Context ctx)
- {
- String path = getDefaultConfigPath(ctx);
- ConfigFile config = new ConfigFile(path);
- Log.i(TAG, "Writing config to: " + path);
- final String dataDir = ctx.getApplicationInfo().dataDir;
- final String coreDir = dataDir + "/cores/";
- final SharedPreferences prefs = getPreferences(ctx);
- config.setString("libretro_directory", coreDir);
- int samplingRate = getOptimalSamplingRate(ctx);
- if (samplingRate != -1) {
- config.setInt("audio_out_rate", samplingRate);
- }
- try
- {
- int version = ctx.getPackageManager().
- getPackageInfo(ctx.getPackageName(), 0).versionCode;
- final String dst_path = dataDir;
- final String dst_path_subdir = "assets";
- Log.i(TAG, "dst dir is: " + dst_path);
- Log.i(TAG, "dst subdir is: " + dst_path_subdir);
- config.setString("bundle_assets_src_path", ctx.getApplicationInfo().sourceDir);
- DebugUtil.i(TAG,"source="+ctx.getApplicationInfo().sourceDir);
- DebugUtil.i(TAG,"versionCode="+version);
- config.setString("bundle_assets_dst_path", dst_path);
- config.setString("bundle_assets_dst_path_subdir", dst_path_subdir);
- config.setInt("bundle_assets_extract_version_current", version);
- }
- catch (PackageManager.NameNotFoundException ignored)
- {
- }
- // Refactor this entire mess and make this usable for per-core config
- if (Build.VERSION.SDK_INT >= 17 && prefs.getBoolean("audio_latency_auto", true))
- {
- int bufferSize = getLowLatencyBufferSize(ctx);
- if (bufferSize != -1) {
- config.setInt("audio_block_frames", bufferSize);
- }
- }
- try
- {
- config.write(path);
- }
- catch (IOException e)
- {
- Log.e(TAG, "Failed to save config file to: " + path);
- }
- }
- private static void readbackString(ConfigFile cfg, SharedPreferences.Editor edit, String key)
- {
- if (cfg.keyExists(key))
- edit.putString(key, cfg.getString(key));
- else
- edit.remove(key);
- }
- private static void readbackBool(ConfigFile cfg, SharedPreferences.Editor edit, String key)
- {
- if (cfg.keyExists(key))
- edit.putBoolean(key, cfg.getBoolean(key));
- else
- edit.remove(key);
- }
- private static void readbackDouble(ConfigFile cfg, SharedPreferences.Editor edit, String key)
- {
- if (cfg.keyExists(key))
- edit.putFloat(key, (float)cfg.getDouble(key));
- else
- edit.remove(key);
- }
- /*
- private static void readbackFloat(ConfigFile cfg, SharedPreferences.Editor edit, String key)
- {
- if (cfg.keyExists(key))
- edit.putFloat(key, cfg.getFloat(key));
- else
- edit.remove(key);
- }
- */
- /**
- private static void readbackInt(ConfigFile cfg, SharedPreferences.Editor edit, String key)
- {
- if (cfg.keyExists(key))
- edit.putInt(key, cfg.getInt(key));
- else
- edit.remove(key);
- }
- */
- /**
- * Sanitizes a libretro core path.
- *
- * @param path The path to the libretro core.
- *
- * @return the sanitized libretro path.
- */
- private static String sanitizeLibretroPath(String path)
- {
- String sanitized_name = path.substring(
- path.lastIndexOf('/') + 1,
- path.lastIndexOf('.'));
- sanitized_name = sanitized_name.replace("neon", "");
- sanitized_name = sanitized_name.replace("libretro_", "");
- return sanitized_name;
- }
- /**
- * Gets a {@link SharedPreferences} instance containing current settings.
- *
- * @param ctx the current {@link Context}.
- *
- * @return A SharedPreference instance containing current settings.
- */
- public static SharedPreferences getPreferences(Context ctx)
- {
- return PreferenceManager.getDefaultSharedPreferences(ctx);
- }
- /**
- * Gets the optimal sampling rate for low-latency audio playback.
- *
- * @param ctx the current {@link Context}.
- *
- * @return the optimal sampling rate for low-latency audio playback in Hz.
- */
- @TargetApi(17)
- private static int getLowLatencyOptimalSamplingRate(Context ctx)
- {
- AudioManager manager = (AudioManager) ctx.getSystemService(Context.AUDIO_SERVICE);
- String value = manager.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE);
- if(value == null || value.isEmpty()) {
- return -1;
- }
- return Integer.parseInt(value);
- }
- /**
- * Gets the optimal buffer size for low-latency audio playback.
- *
- * @param ctx the current {@link Context}.
- *
- * @return the optimal output buffer size in decimal PCM frames.
- */
- @TargetApi(17)
- private static int getLowLatencyBufferSize(Context ctx)
- {
- AudioManager manager = (AudioManager) ctx.getSystemService(Context.AUDIO_SERVICE);
- String value = manager.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER);
- if(value == null || value.isEmpty()) {
- return -1;
- }
- int buffersize = Integer.parseInt(value);
- Log.i(TAG, "Queried ideal buffer size (frames): " + buffersize);
- return buffersize;
- }
- /**
- * Gets the optimal audio sampling rate.
- * <p>
- * On Android 4.2+ devices this will retrieve the optimal low-latency sampling rate,
- * since Android 4.2 adds support for low latency audio in general.
- * <p>
- * On other devices, it simply returns the regular optimal sampling rate
- * as returned by the hardware.
- *
- * @param ctx The current {@link Context}.
- *
- * @return the optimal audio sampling rate in Hz.
- */
- private static int getOptimalSamplingRate(Context ctx)
- {
- int ret;
- if (Build.VERSION.SDK_INT >= 17)
- ret = getLowLatencyOptimalSamplingRate(ctx);
- else
- ret = AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_MUSIC);
- Log.i(TAG, "Using sampling rate: " + ret + " Hz");
- return ret;
- }
- }
|