Java tutorial
/** * Copyright (C) 2010 Regis Montoya (aka r3gis - www.r3gis.fr) * This file is part of CSipSimple. * * CSipSimple is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * CSipSimple is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with CSipSimple. If not, see <http://www.gnu.org/licenses/>. */ package com.csipsimple.utils; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.regex.Pattern; import org.json.JSONException; import org.json.JSONObject; import android.content.ContentResolver; import android.content.Context; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.os.Environment; import android.preference.PreferenceManager; import android.provider.Settings; import android.text.TextUtils; import com.csipsimple.api.SipConfigManager; import com.csipsimple.ui.SipHome; public class PreferencesWrapper { //Internal use public static final String HAS_BEEN_QUIT = "has_been_quit"; public static final String IS_ADVANCED_USER = "is_advanced_user"; public static final String HAS_ALREADY_SETUP = "has_already_setup"; public static final String HAS_ALREADY_SETUP_SERVICE = "has_already_setup_service"; private static final String THIS_FILE = "PreferencesWrapper"; private SharedPreferences prefs; private ContentResolver resolver; private Context context; public final static HashMap<String, String> STRING_PREFS = new HashMap<String, String>() { private static final long serialVersionUID = 1L; { put(SipConfigManager.USER_AGENT, CustomDistribution.getUserAgent()); put(SipConfigManager.LOG_LEVEL, "1"); put(SipConfigManager.USE_SRTP, "0"); put(SipConfigManager.USE_ZRTP, "1"); /* 1 is no zrtp */ put(SipConfigManager.UDP_TRANSPORT_PORT, "0"); put(SipConfigManager.TCP_TRANSPORT_PORT, "0"); put(SipConfigManager.TLS_TRANSPORT_PORT, "0"); put(SipConfigManager.KEEP_ALIVE_INTERVAL_WIFI, "80"); put(SipConfigManager.KEEP_ALIVE_INTERVAL_MOBILE, "40"); put(SipConfigManager.RTP_PORT, "4000"); put(SipConfigManager.OVERRIDE_NAMESERVER, ""); put(SipConfigManager.TIMER_MIN_SE, "90"); put(SipConfigManager.TIMER_SESS_EXPIRES, "1800"); put(SipConfigManager.SND_AUTO_CLOSE_TIME, "1"); put(SipConfigManager.ECHO_CANCELLATION_TAIL, "200"); put(SipConfigManager.ECHO_MODE, "3"); /* WEBRTC */ put(SipConfigManager.SND_MEDIA_QUALITY, "4"); put(SipConfigManager.SND_CLOCK_RATE, "16000"); put(SipConfigManager.SND_PTIME, "20"); put(SipConfigManager.BITS_PER_SAMPLE, "16"); put(SipConfigManager.SIP_AUDIO_MODE, "0"); put(SipConfigManager.MICRO_SOURCE, "1"); //put(SipConfigManager.THREAD_COUNT, "0"); put(SipConfigManager.HEADSET_ACTION, "0"); put(SipConfigManager.STUN_SERVER, "stun.counterpath.com"); put(SipConfigManager.TURN_SERVER, ""); put(SipConfigManager.TURN_USERNAME, ""); put(SipConfigManager.TURN_PASSWORD, ""); put(SipConfigManager.TLS_SERVER_NAME, ""); put(SipConfigManager.CA_LIST_FILE, ""); put(SipConfigManager.CERT_FILE, ""); put(SipConfigManager.PRIVKEY_FILE, ""); put(SipConfigManager.TLS_PASSWORD, ""); put(SipConfigManager.TLS_METHOD, "0"); put(SipConfigManager.DSCP_VAL, "26"); put(SipConfigManager.DTMF_MODE, "0"); put(SipConfigManager.GSM_INTEGRATION_TYPE, "0"); put(SipConfigManager.DIAL_PRESS_TONE_MODE, "0"); put(SipConfigManager.DIAL_PRESS_VIBRATE_MODE, "0"); put(SipConfigManager.DEFAULT_CALLER_ID, ""); put(SipConfigManager.THEME, ""); put(SipConfigManager.RINGTONE, ""); } }; private final static HashMap<String, Boolean> BOOLEAN_PREFS = new HashMap<String, Boolean>() { private static final long serialVersionUID = 1L; { //Network put(SipConfigManager.LOCK_WIFI, true); put(SipConfigManager.LOCK_WIFI_PERFS, false); put(SipConfigManager.ENABLE_TCP, true); put(SipConfigManager.ENABLE_UDP, true); put(SipConfigManager.ENABLE_TLS, false); put(SipConfigManager.USE_IPV6, false); put(SipConfigManager.ENABLE_DNS_SRV, false); put(SipConfigManager.ENABLE_ICE, false); put(SipConfigManager.ENABLE_TURN, false); put(SipConfigManager.ENABLE_STUN, false); put(SipConfigManager.ENABLE_QOS, false); put(SipConfigManager.USE_COMPACT_FORM, false); put("use_wifi_in", true); put("use_wifi_out", true); put("use_other_in", true); put("use_other_out", true); put("use_3g_in", false); put("use_3g_out", false); put("use_gprs_in", false); put("use_gprs_out", false); put("use_edge_in", false); put("use_edge_out", false); put(SipConfigManager.FORCE_NO_UPDATE, true); //Media put(SipConfigManager.ECHO_CANCELLATION, true); put(SipConfigManager.ENABLE_VAD, false); put(SipConfigManager.USE_SOFT_VOLUME, false); put(SipConfigManager.USE_ROUTING_API, false); put(SipConfigManager.USE_MODE_API, false); put(SipConfigManager.HAS_IO_QUEUE, false); put(SipConfigManager.SET_AUDIO_GENERATE_TONE, false); put(SipConfigManager.USE_SGS_CALL_HACK, false); put(SipConfigManager.USE_WEBRTC_HACK, false); put(SipConfigManager.DO_FOCUS_AUDIO, true); put(SipConfigManager.INTEGRATE_WITH_NATIVE_MUSIC, true); //UI put(SipConfigManager.PREVENT_SCREEN_ROTATION, true); put(SipConfigManager.KEEP_AWAKE_IN_CALL, false); put(SipConfigManager.INVERT_PROXIMITY_SENSOR, false); put(SipConfigManager.ICON_IN_STATUS_BAR, true); put(SipConfigManager.USE_PARTIAL_WAKE_LOCK, false); put(SipConfigManager.ICON_IN_STATUS_BAR_NBR, false); put(SipConfigManager.INTEGRATE_WITH_CALLLOGS, true); put(SipConfigManager.INTEGRATE_WITH_DIALER, true); put(HAS_BEEN_QUIT, false); put(HAS_ALREADY_SETUP_SERVICE, false); //Calls put(SipConfigManager.AUTO_RECORD_CALLS, false); put(SipConfigManager.SUPPORT_MULTIPLE_CALLS, false); //Secure put(SipConfigManager.TLS_VERIFY_SERVER, false); put(SipConfigManager.TLS_VERIFY_CLIENT, false); } }; private final static HashMap<String, Float> FLOAT_PREFS = new HashMap<String, Float>() { private static final long serialVersionUID = 1L; { put(SipConfigManager.SND_MIC_LEVEL, (float) 1.0); put(SipConfigManager.SND_SPEAKER_LEVEL, (float) 1.0); put(SipConfigManager.SND_BT_MIC_LEVEL, (float) 1.0); put(SipConfigManager.SND_BT_SPEAKER_LEVEL, (float) 1.0); put(SipConfigManager.SND_STREAM_LEVEL, (float) 8.0); } }; public PreferencesWrapper(Context aContext) { context = aContext; prefs = PreferenceManager.getDefaultSharedPreferences(aContext); resolver = aContext.getContentResolver(); } //Public setters /** * Set a preference string value * @param key the preference key to set * @param value the value for this key */ public void setPreferenceStringValue(String key, String value) { //TODO : authorized values Editor editor = prefs.edit(); editor.putString(key, value); editor.commit(); } /** * Set a preference boolean value * @param key the preference key to set * @param value the value for this key */ public void setPreferenceBooleanValue(String key, boolean value) { Editor editor = prefs.edit(); editor.putBoolean(key, value); editor.commit(); } /** * Set a preference float value * @param key the preference key to set * @param value the value for this key */ public void setPreferenceFloatValue(String key, float value) { Editor editor = prefs.edit(); editor.putFloat(key, value); editor.commit(); Log.d(THIS_FILE, "Changed value of " + key + " : " + value); } //Private static getters // For string private static String gPrefStringValue(SharedPreferences aPrefs, String key) { if (STRING_PREFS.containsKey(key)) { return aPrefs.getString(key, STRING_PREFS.get(key)); } return aPrefs.getString(key, (String) null); } // For boolean private static Boolean gPrefBooleanValue(SharedPreferences aPrefs, String key) { if (BOOLEAN_PREFS.containsKey(key)) { return aPrefs.getBoolean(key, BOOLEAN_PREFS.get(key)); } return aPrefs.getBoolean(key, (Boolean) null); } // For float private static Float gPrefFloatValue(SharedPreferences aPrefs, String key) { if (FLOAT_PREFS.containsKey(key)) { return aPrefs.getFloat(key, FLOAT_PREFS.get(key)); } return aPrefs.getFloat(key, (Float) null); } public static Class<?> gPrefClass(String key) { if (STRING_PREFS.containsKey(key)) { return String.class; } else if (BOOLEAN_PREFS.containsKey(key)) { return Boolean.class; } else if (FLOAT_PREFS.containsKey(key)) { return Float.class; } return null; } /** * Get string preference value * @param key the key preference to retrieve * @return the value */ public String getPreferenceStringValue(String key) { return gPrefStringValue(prefs, key); } /** * Get boolean preference value * @param key the key preference to retrieve * @return the value */ public Boolean getPreferenceBooleanValue(String key) { return gPrefBooleanValue(prefs, key); } /** * Get float preference value * @param key the key preference to retrieve * @return the value */ public Float getPreferenceFloatValue(String key) { return gPrefFloatValue(prefs, key); } /** * Get integer preference value * @param key the key preference to retrieve * @return the value */ public int getPreferenceIntegerValue(String key) { try { return Integer.parseInt(getPreferenceStringValue(key)); } catch (NumberFormatException e) { Log.e(THIS_FILE, "Invalid " + key + " format : expect a int"); } return Integer.parseInt(STRING_PREFS.get(key)); } /** * Set all values to default */ public void resetAllDefaultValues() { for (String key : STRING_PREFS.keySet()) { setPreferenceStringValue(key, STRING_PREFS.get(key)); } for (String key : BOOLEAN_PREFS.keySet()) { setPreferenceBooleanValue(key, BOOLEAN_PREFS.get(key)); } for (String key : FLOAT_PREFS.keySet()) { setPreferenceFloatValue(key, FLOAT_PREFS.get(key)); } Compatibility.setFirstRunParameters(this); setPreferenceBooleanValue(PreferencesProviderWrapper.HAS_ALREADY_SETUP_SERVICE, true); } public JSONObject serializeSipSettings() { JSONObject jsonSipSettings = new JSONObject(); for (String key : STRING_PREFS.keySet()) { try { jsonSipSettings.put(key, getPreferenceStringValue(key)); } catch (JSONException e) { Log.e(THIS_FILE, "Not able to add preference " + key); } } for (String key : BOOLEAN_PREFS.keySet()) { try { jsonSipSettings.put(key, getPreferenceBooleanValue(key)); } catch (JSONException e) { Log.e(THIS_FILE, "Not able to add preference " + key); } } for (String key : FLOAT_PREFS.keySet()) { try { jsonSipSettings.put(key, getPreferenceFloatValue(key).doubleValue()); } catch (JSONException e) { Log.e(THIS_FILE, "Not able to add preference " + key); } } // And get latest known version so that restore will be able to apply necessary patches int lastSeenVersion = prefs.getInt(SipHome.LAST_KNOWN_VERSION_PREF, 0); try { jsonSipSettings.put(SipHome.LAST_KNOWN_VERSION_PREF, lastSeenVersion); } catch (JSONException e) { Log.e(THIS_FILE, "Not able to add last known version pref"); } return jsonSipSettings; } public void restoreSipSettings(JSONObject jsonSipSettings) { for (String key : STRING_PREFS.keySet()) { try { String val = jsonSipSettings.getString(key); if (val != null) { setPreferenceStringValue(key, val); } } catch (JSONException e) { Log.e(THIS_FILE, "Not able to get preference " + key); } } for (String key : BOOLEAN_PREFS.keySet()) { try { Boolean val = jsonSipSettings.getBoolean(key); if (val != null) { setPreferenceBooleanValue(key, val); } } catch (JSONException e) { Log.e(THIS_FILE, "Not able to get preference " + key); } } for (String key : FLOAT_PREFS.keySet()) { try { Double val = jsonSipSettings.getDouble(key); if (val != null) { setPreferenceFloatValue(key, val.floatValue()); } } catch (JSONException e) { Log.e(THIS_FILE, "Not able to get preference " + key); } getPreferenceFloatValue(key); } // And get latest known version so that restore will be able to apply necessary patches try { Integer lastSeenVersion = jsonSipSettings.getInt(SipHome.LAST_KNOWN_VERSION_PREF); if (lastSeenVersion != null) { Editor editor = prefs.edit(); editor.putInt(SipHome.LAST_KNOWN_VERSION_PREF, lastSeenVersion); editor.commit(); } } catch (JSONException e) { Log.e(THIS_FILE, "Not able to add last known version pref"); } } public SharedPreferences getDirectPrefs() { return prefs; } public ArrayList<String> getAllIncomingNetworks() { ArrayList<String> incomingNetworks = new ArrayList<String>(); String[] availableNetworks = { "3g", "edge", "gprs", "wifi", "other" }; for (String network : availableNetworks) { if (getPreferenceBooleanValue("use_" + network + "_in")) { incomingNetworks.add(network); } } return incomingNetworks; } public void disableAllForIncoming() { String[] availableNetworks = { "3g", "edge", "gprs", "wifi", "other" }; for (String network : availableNetworks) { setPreferenceBooleanValue("use_" + network + "_in", false); } } private boolean hasStunServer(String string) { String[] servers = getPreferenceStringValue(SipConfigManager.STUN_SERVER).split(","); for (String server : servers) { if (server.equalsIgnoreCase(string)) { return true; } } return false; } public void addStunServer(String server) { if (!hasStunServer(server)) { String oldStuns = getPreferenceStringValue(SipConfigManager.STUN_SERVER); Log.d(THIS_FILE, "Old stun > " + oldStuns + " vs " + STRING_PREFS.get(SipConfigManager.STUN_SERVER)); if (oldStuns.equalsIgnoreCase(STRING_PREFS.get(SipConfigManager.STUN_SERVER))) { oldStuns = ""; } else { oldStuns += ","; } setPreferenceStringValue(SipConfigManager.STUN_SERVER, oldStuns + server); } } // Codec public short getCodecPriority(String codecName, String type, String defaultValue) { String key = SipConfigManager.getCodecKey(codecName, type); if (key != null) { return (short) Integer.parseInt(prefs.getString(key, defaultValue)); } return (short) Integer.parseInt(defaultValue); } public void setCodecPriority(String codecName, String type, String newValue) { String key = SipConfigManager.getCodecKey(codecName, type); if (key != null) { setPreferenceStringValue(key, newValue); } //TODO : else raise error } // ---- // UI related // ---- public boolean getDialPressTone() { int mode = getPreferenceIntegerValue(SipConfigManager.DIAL_PRESS_TONE_MODE); switch (mode) { case 0: return Settings.System.getInt(resolver, Settings.System.DTMF_TONE_WHEN_DIALING, 1) == 1; case 1: return true; case 2: return false; default: break; } return false; } public boolean getDialPressVibrate() { int mode = getPreferenceIntegerValue(SipConfigManager.DIAL_PRESS_VIBRATE_MODE); switch (mode) { case 0: return Settings.System.getInt(resolver, Settings.System.HAPTIC_FEEDBACK_ENABLED, 1) == 1; case 1: return true; case 2: return false; default: break; } return false; } public boolean startIsDigit() { return !prefs.getBoolean("start_with_text_dialer", false); } public boolean getUseAlternateUnlocker() { return prefs.getBoolean("use_alternate_unlocker", false); } public boolean invertProximitySensor() { return getPreferenceBooleanValue(SipConfigManager.INVERT_PROXIMITY_SENSOR); } public int getLogLevel() { int prefsValue = getPreferenceIntegerValue(SipConfigManager.LOG_LEVEL); if (prefsValue <= 6 && prefsValue >= 1) { return prefsValue; } return 1; } public final static int GSM_TYPE_AUTO = 0; public final static int GSM_TYPE_FORCE = 1; public final static int GSM_TYPE_PREVENT = 2; public int getGsmIntegrationType() { int prefsValue = 1; String gsmType = getPreferenceStringValue(SipConfigManager.GSM_INTEGRATION_TYPE); try { prefsValue = Integer.parseInt(gsmType); } catch (NumberFormatException e) { Log.e(THIS_FILE, "Gsm type " + gsmType + " not well formated"); } return prefsValue; } /** * Check wether setup has already been done * @return */ public boolean hasAlreadySetup() { return prefs.getBoolean(HAS_ALREADY_SETUP, false); } private static String CONFIG_FOLDER = "configs"; private static String RECORDS_FOLDER = "records"; private static String LOGS_FOLDER = "logs"; private static String ZRTP_FOLDER = "zrtp"; private static File getStorageFolder() { File root = Environment.getExternalStorageDirectory(); if (root.canWrite()) { File dir = new File(root.getAbsolutePath() + File.separator + "CSipSimple"); if (!dir.exists()) { dir.mkdirs(); Log.d(THIS_FILE, "Create directory " + dir.getAbsolutePath()); } return dir; } return null; } private static File getSubFolder(String subFolder) { File root = getStorageFolder(); if (root != null) { File dir = new File(root.getAbsoluteFile() + File.separator + subFolder); dir.mkdirs(); return dir; } return null; } public static File getConfigFolder() { return getSubFolder(CONFIG_FOLDER); } public static File getRecordsFolder() { return getSubFolder(RECORDS_FOLDER); } public static File getLogsFolder() { return getSubFolder(LOGS_FOLDER); } public static File getZrtpFolder() { return getSubFolder(ZRTP_FOLDER); } public static void cleanLogsFiles() { File logsFolder = getLogsFolder(); if (logsFolder != null) { File[] files = logsFolder.listFiles(); for (File file : files) { if (file.isFile()) { file.delete(); } } } } public boolean isAdvancedUser() { return prefs.getBoolean(IS_ADVANCED_USER, false); } public void toogleExpertMode() { setPreferenceBooleanValue(IS_ADVANCED_USER, !isAdvancedUser()); } public void setQuit(boolean quit) { setPreferenceBooleanValue(HAS_BEEN_QUIT, quit); } // Codec list management -- only internal use set at each start of the sip stack public static final String CODECS_SEPARATOR = "|"; public static final String CODECS_LIST = "codecs_list"; public static final String BACKUP_PREFIX = "backup_"; public static final String LIB_CAP_TLS = "cap_tls"; public static final String LIB_CAP_SRTP = "cap_srtp"; public String[] getCodecList() { return TextUtils.split(prefs.getString(CODECS_LIST, ""), Pattern.quote(CODECS_SEPARATOR)); } public boolean getLibCapability(String cap) { return prefs.getBoolean(BACKUP_PREFIX + cap, false); } public Context getContext() { return context; } }