com.csipsimple.utils.PreferencesWrapper.java Source code

Java tutorial

Introduction

Here is the source code for com.csipsimple.utils.PreferencesWrapper.java

Source

/**
 * 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;
    }

}