/* * Copyright (c) 2015 OpenSilk Productions LLC * * This program 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. * * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. */ package syncthing.android.settings; import android.content.ContentValues; import android.content.Context; import android.content.SharedPreferences; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.preference.PreferenceManager; import android.support.annotation.Nullable; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import org.apache.commons.lang3.StringUtils; import org.opensilk.common.core.app.PreferencesWrapper; import org.opensilk.common.core.dagger2.ForApplication; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.inject.Inject; import javax.inject.Singleton; import syncthing.api.Credentials; /** * Created by drew on 3/8/15. */ @Singleton public class AppSettings extends PreferencesWrapper { public static final String KEEP_SCREEN_ON = "keep_screen_on"; final Gson gson; final Context appContext; final SharedPreferences prefs; final CredentialsDB db; @Inject public AppSettings( Gson gson, @ForApplication Context appContext, CredentialsDB db ) { this.gson = gson; this.appContext = appContext; prefs = PreferenceManager.getDefaultSharedPreferences(appContext); this.db = db; migrateToDb(); } @Override public SharedPreferences getPrefs() { return prefs; } static final String[] credentialCols = new String[] { CredentialsDB.SCHEMA._ID, CredentialsDB.SCHEMA.ALIAS, CredentialsDB.SCHEMA.DEVICE_ID, CredentialsDB.SCHEMA.URL, CredentialsDB.SCHEMA.API_KEY, CredentialsDB.SCHEMA.CERT, }; static final String[] idCols = new String[] { CredentialsDB.SCHEMA._ID, }; static final String credentialsDeviceIdSel = CredentialsDB.SCHEMA.DEVICE_ID + "=?"; static final String credentialsDefaultSel = CredentialsDB.SCHEMA.DEFAULT + "=?"; static final String idSel = CredentialsDB.SCHEMA._ID + "=?"; public Set<Credentials> getSavedCredentials() { return new HashSet<>(getSavedCredentialsSorted()); } public List<Credentials> getSavedCredentialsSorted() { Cursor c = null; try { c = db.getReadableDatabase().query(CredentialsDB.SCHEMA.TABLE, credentialCols, null, null, CredentialsDB.SCHEMA.ALIAS, null, null); List<Credentials> credentials = new ArrayList<>(); if (c != null && c.moveToFirst()) { do { credentials.add(new Credentials(c.getString(1), c.getString(2), c.getString(3), c.getString(4), c.getString(5))); } while (c.moveToNext()); } return credentials; } finally { if (c != null) c.close(); } } public @Nullable Credentials getSavedCredentials(String deviceId) { Cursor c = null; try { c = db.getReadableDatabase().query(CredentialsDB.SCHEMA.TABLE, credentialCols, credentialsDeviceIdSel, new String[]{deviceId}, null, null, null); if (c != null && c.moveToFirst()) { return new Credentials(c.getString(1), c.getString(2), c.getString(3), c.getString(4), c.getString(5)); } else { return null; } } finally { if (c != null) c.close(); } } public void saveCredentials(Credentials creds) { SQLiteDatabase _db = db.getWritableDatabase(); Cursor c = null; try { ContentValues cv = new ContentValues(); cv.put(CredentialsDB.SCHEMA.ALIAS, creds.alias); cv.put(CredentialsDB.SCHEMA.URL, creds.url); cv.put(CredentialsDB.SCHEMA.API_KEY, creds.apiKey); cv.put(CredentialsDB.SCHEMA.CERT, creds.caCert); String[] sel = new String[]{creds.id}; _db.beginTransaction(); c = _db.query(CredentialsDB.SCHEMA.TABLE, idCols, credentialsDeviceIdSel, sel, null, null, null); if (c != null && c.getCount() > 0) { _db.update(CredentialsDB.SCHEMA.TABLE, cv, credentialsDeviceIdSel, sel); } else { cv.put(CredentialsDB.SCHEMA.DEVICE_ID, creds.id); _db.insert(CredentialsDB.SCHEMA.TABLE, null, cv); } _db.setTransactionSuccessful(); } finally { _db.endTransaction(); if (c != null) c.close(); } } public void removeCredentials(Credentials creds) { SQLiteDatabase _db = db.getWritableDatabase(); Cursor c = null; try { _db.beginTransaction(); _db.delete(CredentialsDB.SCHEMA.TABLE, credentialsDeviceIdSel, new String[]{creds.id}); c = _db.query(CredentialsDB.SCHEMA.TABLE, idCols, credentialsDefaultSel, null, null, null, null); if (c != null && c.getCount() == 0) { c.close(); //no default set a new one c = _db.query(CredentialsDB.SCHEMA.TABLE, idCols, null, null, null, null, null); if (c != null && c.moveToFirst()) { ContentValues cv = new ContentValues(); cv.put(CredentialsDB.SCHEMA.DEFAULT, 1); _db.update(CredentialsDB.SCHEMA.TABLE, cv, idSel, new String[]{c.getString(0)}); } } _db.setTransactionSuccessful(); } finally { _db.endTransaction(); if (c != null) c.close(); } } public @Nullable Credentials getDefaultCredentials() { Cursor c = null; try { c = db.getReadableDatabase().query(CredentialsDB.SCHEMA.TABLE, credentialCols, credentialsDefaultSel, new String[]{"1"}, null, null, null); if (c != null && c.moveToFirst()) { return new Credentials(c.getString(1), c.getString(2), c.getString(3), c.getString(4), c.getString(5)); } } finally { if (c != null) c.close(); } return null; } public void setDefaultCredentials(Credentials creds) { SQLiteDatabase _db = db.getWritableDatabase(); try { _db.beginTransaction(); ContentValues cv = new ContentValues(); cv.put(CredentialsDB.SCHEMA.DEFAULT, 0); //first unset default for everyone _db.update(CredentialsDB.SCHEMA.TABLE, cv, null, null); cv.put(CredentialsDB.SCHEMA.DEFAULT, 1); String[] sel = new String[]{creds.id}; //set default for specified device _db.update(CredentialsDB.SCHEMA.TABLE, cv, credentialsDeviceIdSel, sel); _db.setTransactionSuccessful(); } finally { _db.endTransaction(); } } public boolean keepScreenOn() { return getBoolean(KEEP_SCREEN_ON, false); } @SuppressWarnings("unchecked") private void migrateToDb() { if (getPrefs().contains("TRANSIENT_saved_credentials")) { String str = getPrefs().getString("TRANSIENT_saved_credentials", null); if (!StringUtils.isEmpty(str)) { Set<Credentials> credentialses = (Set<Credentials>)gson.fromJson(str, new TypeToken<Set<Credentials>>(){}.getType()); for (Credentials c : credentialses) { saveCredentials(c); } } getPrefs().edit().remove("TRANSIENT_saved_credentials").commit(); } if (getPrefs().contains("TRANSIENT_default_credentials")) { String str = getPrefs().getString("TRANSIENT_default_credentials", null); Credentials def = gson.fromJson(str, Credentials.class); if (def != null) { setDefaultCredentials(def); } getPrefs().edit().remove("TRANSIENT_default_credentials").commit(); } } }