package uk.org.smithfamily.mslogger; import java.io.File; import java.util.HashMap; import java.util.Map; import uk.org.smithfamily.mslogger.ecuDef.Megasquirt; import uk.org.smithfamily.mslogger.ecuDef.SettingGroup; import uk.org.smithfamily.mslogger.log.DebugLogManager; import android.bluetooth.BluetoothAdapter; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.os.Environment; import android.preference.PreferenceManager; import android.util.Log; /** * This class take care of the settings of the application. All these preferences can be found in the app in the "Preferences" section (bottom left menu icon) */ public enum ApplicationSettings implements SharedPreferences.OnSharedPreferenceChangeListener { INSTANCE; public static final String MISSING_VALUE = "f741d5b0-fbee-11e0-be50-0800200c9a66"; public static final String GENERAL_MESSAGE = "uk.org.smithfamily.mslogger.GENERAL_MESSAGE"; public static final String MESSAGE = "uk.org.smithfamily.mslogger.MESSAGE"; public static final String ECU_CHANGED = "uk.org.smithfamily.mslogger.ECU_CHANGED"; public static final String BT_CHANGED = "uk.org.smithfamily.mslogger.BT_CHANGED"; public static final String TAG = "uk.org.smithfamily.mslogger"; public static final String RPS_MESSAGE = "uk.org.smithfamily.mslogger.RPS_MESSAGE"; public static final String RPS = "uk.org.smithfamily.mslogger.RPS"; public static final String TOAST = "uk.org.smithfamily.mslogger.TOAST"; public static final String TOAST_MESSAGE = "uk.org.smithfamily.mslogger.TOAST_MESSAGE"; private Context context; private File dataDir; private int hertz; private SharedPreferences prefs; private Megasquirt ecuDefinition; private Boolean autoConnectOverride = null; private Map<String, Boolean> settings = new HashMap<String, Boolean>(); private BluetoothAdapter defaultAdapter; private boolean writable; private File dashDir; /** * Initialise all preferences Also load all ECU definitions currently supported * * @param context */ public void initialise(Context context) { this.context = context; PreferenceManager.setDefaultValues(context, R.xml.preferences, false); prefs = PreferenceManager.getDefaultSharedPreferences(context); prefs.registerOnSharedPreferenceChangeListener(this); String directoryName = prefs.getString("DataDir", context.getString(R.string.app_name)); dataDir = new File(Environment.getExternalStorageDirectory(), directoryName); boolean mkDirs = dataDir.mkdirs(); if (!mkDirs) { DebugLogManager.INSTANCE.log("Unable to create directory " + directoryName + " at " + Environment.getExternalStorageDirectory(), Log.ERROR); } dashDir = new File(dataDir, "dashboards"); mkDirs = dashDir.mkdirs(); if (!mkDirs) { DebugLogManager.INSTANCE.log("Unable to create directory " + directoryName + " at " + Environment.getExternalStorageDirectory(), Log.ERROR); } this.hertz = prefs.getInt(context.getString(R.string.hertz), 20); } /** * Get the data directory for the application */ public File getDataDir() { return dataDir; } public File getDashDir() { return dashDir; } /** * Get the context where the application settings are used */ public Context getContext() { return context; } /** * Get the hertz of the Android device */ public int getHertz() { return hertz; } /** * Get the current ECU definition */ public synchronized Megasquirt getEcuDefinition() { return ecuDefinition; } /** * Get the MAC address of the ECU Bluetooth device */ public synchronized String getECUBluetoothMac() { return prefs.getString("bluetooth_mac", MISSING_VALUE); } /** * @param Set * the MAC address of the current ECU Bluetooth device */ public synchronized void setECUBluetoothMac(String m) { Editor editor = prefs.edit(); editor.putString("bluetooth_mac", m); editor.commit(); Intent broadcast = new Intent(); broadcast.setAction(BT_CHANGED); context.sendBroadcast(broadcast); } /** * This method mimics the C style preprocessor of INI files * * @param name * Name of the settings to look for */ public boolean isSet(String name) { Boolean result = settings.get(name); if (result != null) { return result; } boolean val = false; synchronized(this) { for (SettingGroup g : ecuDefinition.getSettingGroups()) { String groupName = g.getName(); if (prefs.getString(groupName, MISSING_VALUE).equals(name)) { val = true; } } } //This probably needs to be retired in light of the above code. if (prefs.getString("temptype", MISSING_VALUE).equals(name) || prefs.getString("maptype", MISSING_VALUE).equals(name) || prefs.getString("egotype", MISSING_VALUE).equals(name)) { val = true; } if (prefs.getString(name, MISSING_VALUE).equalsIgnoreCase("true")) { val = true; } settings.put(name, val); return val; } /** * Triggered whenever the preference change to reset MAC address and settings * * @param sharedPreferences * @param key */ @Override public synchronized void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { settings = new HashMap<String, Boolean>(); } /** * If bluetooth device is not the default one, a bluetooth device has been selected */ public boolean btDeviceSelected() { return !MISSING_VALUE.equals(getECUBluetoothMac()); } /** * Return true if preference that automatically send email with datalog is enabled, false otherwise */ public boolean emailEnabled() { return prefs.getBoolean("autoemail_enabled", false); } /** * @return The current email to send datalog to */ public String getEmailDestination() { return prefs.getString("autoemail_target", ""); } /** * Return true if the preferences is enabled to automatically connect to the Megasquirt on startup */ public boolean autoConnectable() { boolean autoconnectpref = prefs.getBoolean("autoconnect", true); boolean btDeviceSelected = btDeviceSelected(); return (autoConnectOverride == null || autoConnectOverride == true) && btDeviceSelected && autoconnectpref; } /** * Get a specific application preference by name * * @param name * The name of the preference */ public String getPref(String name) { String value = prefs.getString(name, MISSING_VALUE); if (value.equals(MISSING_VALUE)) { value = null; } return value; } /** * Helper function to set or get a preference * * @param name * The name of the preference * @param def * The value of the preference * @return Return the current value in preference */ public String getOrSetPref(String name, String def) { String value = prefs.getString(name, MISSING_VALUE); if (value.equals(MISSING_VALUE)) { setPref(name, def); value = def; } return value; } /** * Helper function to save a string in preference * * @param name * @param value */ public void setPref(String name, String value) { Editor editor = prefs.edit(); editor.putString(name, value); editor.commit(); } /** * * @param gaugeName * @param title * @param var * @param def * @return */ public double getGaugeSetting(String gaugeName, String title, String var, double def) { return def; } /** * * @return */ public boolean isAutoConnectOverride() { return autoConnectOverride; } /** * * @param autoConnectOverride */ public void setAutoConnectOverride(Boolean autoConnectOverride) { this.autoConnectOverride = autoConnectOverride; } /** * * @return */ public boolean getAutoLogging() { return prefs.getBoolean("autolog", true); } /** * * @return */ public BluetoothAdapter getDefaultAdapter() { return defaultAdapter; } /** * * @param defaultAdapter */ public void setDefaultAdapter(BluetoothAdapter defaultAdapter) { this.defaultAdapter = defaultAdapter; } /** * * @param cardOK */ public void setWritable(boolean cardOK) { this.writable = cardOK; } /** * * */ public boolean isWritable() { return this.writable; } /** * * @param ecu */ public synchronized void setEcu(Megasquirt ecu) { ecuDefinition = ecu; Intent broadcast = new Intent(); broadcast.setAction(ApplicationSettings.ECU_CHANGED); context.sendBroadcast(broadcast); } /** * */ public void refreshFlags() { settings.clear(); } /** * Return true if Bluetooth work around is activated, false otherwise * * @return */ public boolean isBTWorkaround() { return prefs.getBoolean("workaround", false); } /** * Set the state for the Bluetooth work around * * @param state */ public void setBTWorkaround(boolean state) { Editor editor = prefs.edit(); editor.putBoolean("workaround", state); editor.commit(); DebugLogManager.INSTANCE.log("set BTWorkaround to " + state, Log.ASSERT); } /** * Return the logging level of the application Used for application debugging * * @return */ public int getLoggingLevel() { String value = prefs.getString("loglevel", null); return value == null ? 6 : Integer.valueOf(value); } /** * @return Datalog fields used in the datalog viewer */ public String[] getDatalogFields() { String datalogFields = prefs.getString("datalogfields", "Time\tRPM\tMAP\tAFR\tMAT\tCLT\tBatt\tIACstep"); return datalogFields.split("\t"); } /** * @param datalogFields * Datalog fields to be view in the datalog viewer */ public void setDatalogFields(String[] datalogFields) { String output = ""; if (datalogFields.length > 0) { StringBuilder sb = new StringBuilder(); sb.append(datalogFields[0]); for (int i = 1; i < datalogFields.length; i++) { sb.append("\t"); sb.append(datalogFields[i]); } output = sb.toString(); } setPref("datalogfields", output); } /** * Return true if preference that external/remote GPS device instead of the inbuilt GPS is enabled, false otherwise */ public boolean isExternalGPSEnabled() { return prefs.getBoolean("useexternal", false); } /** * Return true if preference to include device time for every log event is enabled, false otherwise */ public boolean isDeviceTimeEnabled() { return prefs.getBoolean("usedevicetime", true); } /** * Get the MAC address of the ECU Bluetooth device */ public synchronized String getExtGPSBluetoothMac() { return prefs.getString("gps_bluetooth_mac", MISSING_VALUE); } /** * @param Set * the MAC address of the current ExtGPS Bluetooth device */ public synchronized void setExtGPSBluetoothMac(String m) { Editor editor = prefs.edit(); editor.putString("gps_bluetooth_mac", m); editor.commit(); } /** * Get the ExtGPS active running state */ public synchronized boolean isExtGPSActive() { return prefs.getBoolean("externalgpsactive", false); } /** * @param Set * the ExtGPS active running state */ public synchronized void setExtGPSActive(boolean b) { Editor editor = prefs.edit(); editor.putBoolean("externalgpsactive", b); editor.commit(); } /** * @return The gauges orientation (Either Follow device orientation or force landscape or force portrait) */ public String getGaugesOrientation() { return prefs.getString("gaugesorientation", MISSING_VALUE); } }