/*
* 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.service;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import org.apache.commons.lang3.StringUtils;
import org.opensilk.common.core.mortar.DaggerService;
import org.opensilk.common.core.util.BundleHelper;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import javax.inject.Inject;
/**
* Created by drew on 10/13/15.
*/
public class ServiceSettingsProvider extends ContentProvider {
@Inject ServiceSettingsDB mDB;
private final ReentrantReadWriteLock mLock = new ReentrantReadWriteLock(true);
@Override
public boolean onCreate() {
ServiceComponent cmp = DaggerService.getDaggerComponent(getContext());
cmp.inject(this);
return true;
}
@Nullable
@Override
public Bundle call(String method, String arg, Bundle extras) {
if (StringUtils.equals("get_settings", method)) {
if (arg == null) arg = "_NONE_";
switch (arg) {
case ServiceSettings.ENABLED:
case ServiceSettings.INITIALISED:
case ServiceSettings.ONLY_CHARGING:
case ServiceSettings.ONLY_WIFI: {
Cursor c = null;
try {
c = getIntSetting(arg);
if (c != null && c.moveToNext()) {
return BundleHelper.b().putInt(c.getInt(0)).get();
} else {
return extras;
}
} finally {
if (c != null) c.close();
}
}
case ServiceSettings.RUN_WHEN:
case ServiceSettings.RANGE_START:
case ServiceSettings.RANGE_END:
case ServiceSettings.WIFI_NETWORKS: {
Cursor c = null;
try {
c = getTextSetting(arg);
if (c != null && c.moveToNext()) {
return BundleHelper.b().putString(c.getString(0)).get();
} else {
return extras;
}
} finally {
if (c != null) c.close();
}
}
default:
return null;
}
} else if (StringUtils.equals("put_settings", method)) {
if (arg == null) arg = "_NONE_";
switch (arg) {
case ServiceSettings.ENABLED:
case ServiceSettings.INITIALISED:
case ServiceSettings.ONLY_CHARGING:
case ServiceSettings.ONLY_WIFI: {
long id = putIntSetting(arg, BundleHelper.getInt(extras));
return BundleHelper.b().putString(id > 0 ? "ok" : "err").get();
}
case ServiceSettings.RUN_WHEN:
case ServiceSettings.RANGE_START:
case ServiceSettings.RANGE_END:
case ServiceSettings.WIFI_NETWORKS: {
long id = putTextSetting(arg, BundleHelper.getString(extras));
return BundleHelper.b().putString(id > 0 ? "ok" : "err").get();
}
default:
return null;
}
} else {
return null;
}
}
private static final String[] intCols = new String[] {
ServiceSettingsDB.SCHEMA.INT_VAL
};
private static final String[] textCols = new String[] {
ServiceSettingsDB.SCHEMA.TEXT_VAL
};
private static final String sel = ServiceSettingsDB.SCHEMA.KEY + "=?";
private Cursor getTextSetting(String key) {
ReentrantReadWriteLock.ReadLock lock = mLock.readLock();
try {
lock.lock();
return mDB.getReadableDatabase().query(
ServiceSettingsDB.SCHEMA.TABLE,
textCols, sel, new String[]{key}, null, null, null);
} finally {
lock.unlock();
}
}
private Cursor getIntSetting(String key) {
ReentrantReadWriteLock.ReadLock lock = mLock.readLock();
try {
lock.lock();
return mDB.getReadableDatabase().query(
ServiceSettingsDB.SCHEMA.TABLE,
intCols, sel, new String[]{key}, null, null, null);
} finally {
lock.unlock();
}
}
private long putTextSetting(String key, String val) {
ReentrantReadWriteLock.WriteLock lock = mLock.writeLock();
try {
lock.lock();
ContentValues cv = new ContentValues(2);
cv.put(ServiceSettingsDB.SCHEMA.KEY, key);
cv.put(ServiceSettingsDB.SCHEMA.TEXT_VAL, val);
return mDB.getWritableDatabase().insertWithOnConflict(
ServiceSettingsDB.SCHEMA.TABLE,
null, cv, SQLiteDatabase.CONFLICT_REPLACE);
} finally {
lock.unlock();
}
}
private long putIntSetting(String key, int val) {
ReentrantReadWriteLock.WriteLock lock = mLock.writeLock();
try {
lock.lock();
ContentValues cv = new ContentValues(2);
cv.put(ServiceSettingsDB.SCHEMA.KEY, key);
cv.put(ServiceSettingsDB.SCHEMA.INT_VAL, val);
return mDB.getWritableDatabase().insertWithOnConflict(
ServiceSettingsDB.SCHEMA.TABLE,
null, cv, SQLiteDatabase.CONFLICT_REPLACE);
} finally {
lock.unlock();
}
}
@Nullable
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
throw new UnsupportedOperationException();
}
@Nullable
@Override
public String getType(Uri uri) {
return null;
}
@Nullable
@Override
public Uri insert(Uri uri, ContentValues values) {
throw new UnsupportedOperationException();
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
throw new UnsupportedOperationException();
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
throw new UnsupportedOperationException();
}
}