summaryrefslogtreecommitdiff
path: root/vdrmanager/src/de/bjusystems
diff options
context:
space:
mode:
authorlado <herrlado@gmail.com>2013-03-22 01:04:38 +0100
committerlado <herrlado@gmail.com>2013-03-22 01:04:38 +0100
commit66a971c14691514230ff0a1f1a19a29c194c74ee (patch)
treefc4dd2074672dead53149fb4badaba7b799097a8 /vdrmanager/src/de/bjusystems
parent21d97e639e711c0f261a9590866452360bc70def (diff)
downloadvdr-manager-66a971c14691514230ff0a1f1a19a29c194c74ee.tar.gz
vdr-manager-66a971c14691514230ff0a1f1a19a29c194c74ee.tar.bz2
SharedPreferences refactored
Diffstat (limited to 'vdrmanager/src/de/bjusystems')
-rw-r--r--vdrmanager/src/de/bjusystems/vdrmanager/QueuedWork.java101
-rw-r--r--vdrmanager/src/de/bjusystems/vdrmanager/VdrSharedPreferencesImpl.java527
-rw-r--r--vdrmanager/src/de/bjusystems/vdrmanager/data/FetchEditTextPreference.java2
-rw-r--r--vdrmanager/src/de/bjusystems/vdrmanager/data/Vdr.java179
-rw-r--r--vdrmanager/src/de/bjusystems/vdrmanager/data/VdrSharedPreferences.java1
-rw-r--r--vdrmanager/src/de/bjusystems/vdrmanager/gui/VdrPreferencesActivity.java24
6 files changed, 734 insertions, 100 deletions
diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/QueuedWork.java b/vdrmanager/src/de/bjusystems/vdrmanager/QueuedWork.java
new file mode 100644
index 0000000..09bb15b
--- /dev/null
+++ b/vdrmanager/src/de/bjusystems/vdrmanager/QueuedWork.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package de.bjusystems.vdrmanager;
+
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * Internal utility class to keep track of process-global work that's
+ * outstanding and hasn't been finished yet.
+ *
+ * This was created for writing SharedPreference edits out
+ * asynchronously so we'd have a mechanism to wait for the writes in
+ * Activity.onPause and similar places, but we may use this mechanism
+ * for other things in the future.
+ *
+ *
+ */
+public class QueuedWork {
+
+ // The set of Runnables that will finish or wait on any async
+ // activities started by the application.
+ private static final ConcurrentLinkedQueue<Runnable> sPendingWorkFinishers =
+ new ConcurrentLinkedQueue<Runnable>();
+
+ private static ExecutorService sSingleThreadExecutor = null; // lazy, guarded by class
+
+ /**
+ * Returns a single-thread Executor shared by the entire process,
+ * creating it if necessary.
+ */
+ public static ExecutorService singleThreadExecutor() {
+ synchronized (QueuedWork.class) {
+ if (sSingleThreadExecutor == null) {
+ // TODO: can we give this single thread a thread name?
+ sSingleThreadExecutor = Executors.newSingleThreadExecutor();
+ }
+ return sSingleThreadExecutor;
+ }
+ }
+
+ /**
+ * Add a runnable to finish (or wait for) a deferred operation
+ * started in this context earlier. Typically finished by e.g.
+ * an Activity#onPause. Used by SharedPreferences$Editor#startCommit().
+ *
+ * Note that this doesn't actually start it running. This is just
+ * a scratch set for callers doing async work to keep updated with
+ * what's in-flight. In the common case, caller code
+ * (e.g. SharedPreferences) will pretty quickly call remove()
+ * after an add(). The only time these Runnables are run is from
+ * waitToFinish(), below.
+ */
+ public static void add(Runnable finisher) {
+ sPendingWorkFinishers.add(finisher);
+ }
+
+ public static void remove(Runnable finisher) {
+ sPendingWorkFinishers.remove(finisher);
+ }
+
+ /**
+ * Finishes or waits for async operations to complete.
+ * (e.g. SharedPreferences$Editor#startCommit writes)
+ *
+ * Is called from the Activity base class's onPause(), after
+ * BroadcastReceiver's onReceive, after Service command handling,
+ * etc. (so async work is never lost)
+ */
+ public static void waitToFinish() {
+ Runnable toFinish;
+ while ((toFinish = sPendingWorkFinishers.poll()) != null) {
+ toFinish.run();
+ }
+ }
+
+ /**
+ * Returns true if there is pending work to be done. Note that the
+ * result is out of data as soon as you receive it, so be careful how you
+ * use it.
+ */
+ public static boolean hasPendingWork() {
+ return !sPendingWorkFinishers.isEmpty();
+ }
+
+}
diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/VdrSharedPreferencesImpl.java b/vdrmanager/src/de/bjusystems/vdrmanager/VdrSharedPreferencesImpl.java
new file mode 100644
index 0000000..0eac4fb
--- /dev/null
+++ b/vdrmanager/src/de/bjusystems/vdrmanager/VdrSharedPreferencesImpl.java
@@ -0,0 +1,527 @@
+/*
+ * Copyrigsht (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package de.bjusystems.vdrmanager;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.WeakHashMap;
+import java.util.concurrent.CountDownLatch;
+
+import android.content.SharedPreferences;
+import android.os.Looper;
+
+import com.j256.ormlite.dao.RuntimeExceptionDao;
+
+import de.bjusystems.vdrmanager.data.Vdr;
+
+public class VdrSharedPreferencesImpl implements SharedPreferences {
+
+ private static final String TAG = "SharedPreferencesImpl";
+
+ private static final boolean DEBUG = false;
+
+ // Lock ordering rules:
+ // - acquire SharedPreferencesImpl.this before EditorImpl.this
+ // - acquire mWritingToDiskLock before EditorImpl.this
+
+ Vdr mVdr;
+
+
+ public Vdr getVdr(){
+ return mVdr;
+ }
+
+ RuntimeExceptionDao<Vdr, Integer> dao;
+
+ private Map<String, Object> mMap; // guarded by 'this'
+ private int mDiskWritesInFlight = 0; // guarded by 'this'
+ private boolean mLoaded = false; // guarded by 'this'
+
+ private final Object mWritingToDiskLock = new Object();
+ private static final Object mContent = new Object();
+ private final WeakHashMap<OnSharedPreferenceChangeListener, Object> mListeners = new WeakHashMap<OnSharedPreferenceChangeListener, Object>();
+
+ public VdrSharedPreferencesImpl(Vdr vdr, RuntimeExceptionDao<Vdr, Integer> dao) {
+ mVdr = vdr;
+ this.dao = dao;
+ mLoaded = false;
+ mMap = null;
+ startLoadFromDisk();
+ }
+
+ private void startLoadFromDisk() {
+ synchronized (this) {
+ mLoaded = false;
+ }
+ new Thread("SharedPreferencesImpl-load") {
+ public void run() {
+ synchronized (VdrSharedPreferencesImpl.this) {
+ loadFromDiskLocked();
+ }
+ }
+ }.start();
+ }
+
+ private void loadFromDiskLocked() {
+ if (mLoaded) {
+ return;
+ }
+
+ Map map = mVdr.toMap();
+ //StructStat stat = null;
+ //try {
+ //stat = Libcore.os.stat(mFile.getPath());
+ //if (mFile.canRead()) {
+ //BufferedInputStream str = null;
+ //try {
+ //str = new BufferedInputStream(new FileInputStream(mFile),
+ // 16 * 1024);
+ //map = XmlUtils.readMapXml(str);
+ //} catch (XmlPullParserException e) {
+// Log.w(TAG, "getSharedPreferences", e);
+ // } catch (FileNotFoundException e) {
+ // Log.w(TAG, "getSharedPreferences", e);
+ // } catch (IOException e) {
+ // Log.w(TAG, "getSharedPreferences", e);
+ //} finally {
+ //IoUtils.closeQuietly(str);
+ //}
+ //}
+ //} catch (ErrnoException e) {
+ //}
+ mLoaded = true;
+ if (map != null) {
+ mMap = map;
+ } else {
+ mMap = new HashMap<String, Object>();
+ }
+ notifyAll();
+ }
+
+
+
+ public void registerOnSharedPreferenceChangeListener(
+ OnSharedPreferenceChangeListener listener) {
+ synchronized (this) {
+ mListeners.put(listener, mContent);
+ }
+ }
+
+ public void unregisterOnSharedPreferenceChangeListener(
+ OnSharedPreferenceChangeListener listener) {
+ synchronized (this) {
+ mListeners.remove(listener);
+ }
+ }
+
+ private void awaitLoadedLocked() {
+ // if (!mLoaded) {
+ // // Raise an explicit StrictMode onReadFromDisk for this
+ // // thread, since the real read will be in a different
+ // // thread and otherwise ignored by StrictMode.
+ // BlockGuard.getThreadPolicy().onReadFromDisk();
+ // }
+ while (!mLoaded) {
+ try {
+ wait();
+ } catch (InterruptedException unused) {
+ }
+ }
+ }
+
+ public Map<String, ?> getAll() {
+ synchronized (this) {
+ awaitLoadedLocked();
+ // noinspection unchecked
+ return new HashMap<String, Object>(mMap);
+ }
+ }
+
+ public String getString(String key, String defValue) {
+ synchronized (this) {
+ awaitLoadedLocked();
+ String v = String.valueOf(mMap.get(key));
+ return v != null ? v : defValue;
+ }
+ }
+
+ public Set<String> getStringSet(String key, Set<String> defValues) {
+ synchronized (this) {
+ awaitLoadedLocked();
+ Set<String> v = (Set<String>) mMap.get(key);
+ return v != null ? v : defValues;
+ }
+ }
+
+ public int getInt(String key, int defValue) {
+ synchronized (this) {
+ awaitLoadedLocked();
+ Integer v = (Integer) mMap.get(key);
+ return v != null ? v : defValue;
+ }
+ }
+
+ public long getLong(String key, long defValue) {
+ synchronized (this) {
+ awaitLoadedLocked();
+ Long v = (Long) mMap.get(key);
+ return v != null ? v : defValue;
+ }
+ }
+
+ public float getFloat(String key, float defValue) {
+ synchronized (this) {
+ awaitLoadedLocked();
+ Float v = (Float) mMap.get(key);
+ return v != null ? v : defValue;
+ }
+ }
+
+ public boolean getBoolean(String key, boolean defValue) {
+ synchronized (this) {
+ awaitLoadedLocked();
+ Boolean v = (Boolean) mMap.get(key);
+ return v != null ? v : defValue;
+ }
+ }
+
+ public boolean contains(String key) {
+ synchronized (this) {
+ awaitLoadedLocked();
+ return mMap.containsKey(key);
+ }
+ }
+
+ public Editor edit() {
+ // TODO: remove the need to call awaitLoadedLocked() when
+ // requesting an editor. will require some work on the
+ // Editor, but then we should be able to do:
+ //
+ // context.getSharedPreferences(..).edit().putString(..).apply()
+ //
+ // ... all without blocking.
+ synchronized (this) {
+ awaitLoadedLocked();
+ }
+
+ return new EditorImpl();
+ }
+
+ // Return value from EditorImpl#commitToMemory()
+ private static class MemoryCommitResult {
+ public boolean changesMade; // any keys different?
+ public List<String> keysModified; // may be null
+ public Set<OnSharedPreferenceChangeListener> listeners; // may be null
+ public Map<String, Object> mapToWriteToDisk;
+ public final CountDownLatch writtenToDiskLatch = new CountDownLatch(1);
+ public volatile boolean writeToDiskResult = false;
+
+ public void setDiskWriteResult(boolean result) {
+ writeToDiskResult = result;
+ writtenToDiskLatch.countDown();
+ }
+ }
+
+ public final class EditorImpl implements Editor {
+
+ private final Map<String, Object> mModified = new HashMap<String, Object>();
+
+ private boolean mClear = false;
+
+ public Editor putString(String key, String value) {
+ synchronized (this) {
+ mModified.put(key, value);
+ return this;
+ }
+ }
+
+ public Editor putStringSet(String key, Set<String> values) {
+ synchronized (this) {
+ mModified.put(key, (values == null) ? null
+ : new HashSet<String>(values));
+ return this;
+ }
+ }
+
+ public Editor putInt(String key, int value) {
+ synchronized (this) {
+ mModified.put(key, value);
+ return this;
+ }
+ }
+
+ public Editor putLong(String key, long value) {
+ synchronized (this) {
+ mModified.put(key, value);
+ return this;
+ }
+ }
+
+ public Editor putFloat(String key, float value) {
+ synchronized (this) {
+ mModified.put(key, value);
+ return this;
+ }
+ }
+
+ public Editor putBoolean(String key, boolean value) {
+ synchronized (this) {
+ mModified.put(key, value);
+ return this;
+ }
+ }
+
+ public Editor remove(String key) {
+ synchronized (this) {
+ mModified.put(key, this);
+ return this;
+ }
+ }
+
+ public Editor clear() {
+ synchronized (this) {
+ mClear = true;
+ return this;
+ }
+ }
+
+ public void apply() {
+ final MemoryCommitResult mcr = commitToMemory();
+ final Runnable awaitCommit = new Runnable() {
+ public void run() {
+ try {
+ mcr.writtenToDiskLatch.await();
+ } catch (InterruptedException ignored) {
+ }
+ }
+ };
+
+ QueuedWork.add(awaitCommit);
+
+ Runnable postWriteRunnable = new Runnable() {
+ public void run() {
+ awaitCommit.run();
+ QueuedWork.remove(awaitCommit);
+ }
+ };
+
+ VdrSharedPreferencesImpl.this.enqueueDiskWrite(mcr, postWriteRunnable);
+
+ // Okay to notify the listeners before it's hit disk
+ // because the listeners should always get the same
+ // SharedPreferences instance back, which has the
+ // changes reflected in memory.
+ notifyListeners(mcr);
+ }
+
+ // Returns true if any changes were made
+ private MemoryCommitResult commitToMemory() {
+ MemoryCommitResult mcr = new MemoryCommitResult();
+ synchronized (VdrSharedPreferencesImpl.this) {
+ // We optimistically don't make a deep copy until
+ // a memory commit comes in when we're already
+ // writing to disk.
+ if (mDiskWritesInFlight > 0) {
+ // We can't modify our mMap as a currently
+ // in-flight write owns it. Clone it before
+ // modifying it.
+ // noinspection unchecked
+ mMap = new HashMap<String, Object>(mMap);
+ }
+ mcr.mapToWriteToDisk = mMap;
+ mDiskWritesInFlight++;
+
+ boolean hasListeners = mListeners.size() > 0;
+ if (hasListeners) {
+ mcr.keysModified = new ArrayList<String>();
+ mcr.listeners = new HashSet<OnSharedPreferenceChangeListener>(
+ mListeners.keySet());
+ }
+
+ synchronized (this) {
+ if (mClear) {
+ if (!mMap.isEmpty()) {
+ mcr.changesMade = true;
+ mMap.clear();
+ }
+ mClear = false;
+ }
+
+ for (Map.Entry<String, Object> e : mModified.entrySet()) {
+ String k = e.getKey();
+ Object v = e.getValue();
+ if (v == this) { // magic value for a removal mutation
+ if (!mMap.containsKey(k)) {
+ continue;
+ }
+ mMap.remove(k);
+ } else {
+ boolean isSame = false;
+ if (mMap.containsKey(k)) {
+ Object existingValue = mMap.get(k);
+ if (existingValue != null
+ && existingValue.equals(v)) {
+ continue;
+ }
+ }
+ mMap.put(k, v);
+ }
+
+ mcr.changesMade = true;
+ if (hasListeners) {
+ mcr.keysModified.add(k);
+ }
+ }
+
+ mModified.clear();
+ }
+ }
+ return mcr;
+ }
+
+ public boolean commit() {
+ MemoryCommitResult mcr = commitToMemory();
+ VdrSharedPreferencesImpl.this.enqueueDiskWrite(mcr, null /*
+ * sync write on
+ * this thread
+ * okay
+ */);
+ try {
+ mcr.writtenToDiskLatch.await();
+ } catch (InterruptedException e) {
+ return false;
+ }
+ notifyListeners(mcr);
+ return mcr.writeToDiskResult;
+ }
+
+ private void notifyListeners(final MemoryCommitResult mcr) {
+ if (mcr.listeners == null || mcr.keysModified == null
+ || mcr.keysModified.size() == 0) {
+ return;
+ }
+ //if (Looper.myLooper() == Looper.getMainLooper()) {
+ for (int i = mcr.keysModified.size() - 1; i >= 0; i--) {
+ final String key = mcr.keysModified.get(i);
+ for (OnSharedPreferenceChangeListener listener : mcr.listeners) {
+ if (listener != null) {
+ listener.onSharedPreferenceChanged(
+ VdrSharedPreferencesImpl.this, key);
+ }
+ }
+ }
+ //} else {
+ // Run this function on the main thread.
+ // VdrManagerApp.sMainThreadHandler.post(new Runnable() {
+ // public void run() {
+ // notifyListeners(mcr);
+ // }
+ // });
+ //}
+ }
+ }
+
+ /**
+ * Enqueue an already-committed-to-memory result to be written to disk.
+ *
+ * They will be written to disk one-at-a-time in the order that they're
+ * enqueued.
+ *
+ * @param postWriteRunnable
+ * if non-null, we're being called from apply() and this is the
+ * runnable to run after the write proceeds. if null (from a
+ * regular commit()), then we're allowed to do this disk write on
+ * the main thread (which in addition to reducing allocations and
+ * creating a background thread, this has the advantage that we
+ * catch them in userdebug StrictMode reports to convert them
+ * where possible to apply() ...)
+ */
+ private void enqueueDiskWrite(final MemoryCommitResult mcr,
+ final Runnable postWriteRunnable) {
+ final Runnable writeToDiskRunnable = new Runnable() {
+ public void run() {
+ synchronized (mWritingToDiskLock) {
+ writeToFile(mcr);
+ }
+ synchronized (VdrSharedPreferencesImpl.this) {
+ mDiskWritesInFlight--;
+ }
+ if (postWriteRunnable != null) {
+ postWriteRunnable.run();
+ }
+ }
+ };
+
+ final boolean isFromSyncCommit = (postWriteRunnable == null);
+
+ // Typical #commit() path with fewer allocations, doing a write on
+ // the current thread.
+ if (isFromSyncCommit) {
+ boolean wasEmpty = false;
+ synchronized (VdrSharedPreferencesImpl.this) {
+ wasEmpty = mDiskWritesInFlight == 1;
+ }
+ if (wasEmpty) {
+ writeToDiskRunnable.run();
+ return;
+ }
+ }
+
+ QueuedWork.singleThreadExecutor().execute(writeToDiskRunnable);
+ }
+
+ // Note: must hold mWritingToDiskLock
+ private void writeToFile(MemoryCommitResult mcr) {
+ // Rename the current file so it may be used as a backup during the next
+ // read
+
+ // Attempt to write the file, delete the backup and return true as
+ // atomically as
+ // possible. If any exception occurs, delete the new file; next time we
+ // will restore
+ // from the backup.
+ // FileOutputStream str = createFileOutputStream(mFile);
+ // if (str == null) {
+ // mcr.setDiskWriteResult(false);
+ // return;
+ // }
+ //
+ // XmlUtils.writeMapXml(mcr.mapToWriteToDisk, str);
+ mVdr.set(mcr.mapToWriteToDisk);
+ dao.createOrUpdate(mVdr);
+ // FileUtils.sync(str);
+ // str.close();
+ // ContextImpl.setFilePermissionsFromMode(mFile.getPath(), mMode, 0);
+ // try {
+ // final StructStat stat = Libcore.os.stat(mFile.getPath());
+ // synchronized (this) {
+ // mStatTimestamp = stat.st_mtime;
+ // mStatSize = stat.st_size;
+ // }
+ // } catch (ErrnoException e) {
+ // // Do nothing
+ // }
+ // Writing was successful, delete the backup file if there is one.
+ mcr.setDiskWriteResult(true);
+ return;
+
+ }
+}
diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/data/FetchEditTextPreference.java b/vdrmanager/src/de/bjusystems/vdrmanager/data/FetchEditTextPreference.java
index 5e4022e..17a93b7 100644
--- a/vdrmanager/src/de/bjusystems/vdrmanager/data/FetchEditTextPreference.java
+++ b/vdrmanager/src/de/bjusystems/vdrmanager/data/FetchEditTextPreference.java
@@ -2,13 +2,13 @@ package de.bjusystems.vdrmanager.data;
import android.content.Context;
import android.content.DialogInterface;
+import android.content.SharedPreferences.Editor;
import android.preference.DialogPreference;
import android.util.AttributeSet;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageButton;
import de.bjusystems.vdrmanager.R;
-import de.bjusystems.vdrmanager.data.VdrSharedPreferences.Editor;
public class FetchEditTextPreference extends DialogPreference{
diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/data/Vdr.java b/vdrmanager/src/de/bjusystems/vdrmanager/data/Vdr.java
index b34c5bd..761a11e 100644
--- a/vdrmanager/src/de/bjusystems/vdrmanager/data/Vdr.java
+++ b/vdrmanager/src/de/bjusystems/vdrmanager/data/Vdr.java
@@ -17,7 +17,7 @@ public class Vdr {
private Integer id;
@DatabaseField(columnName = "name")
- private String name = "-";
+ private String name = "VDR";
/**
* Use secure channel
@@ -27,15 +27,15 @@ public class Vdr {
/** SVDRP host name or ip */
@DatabaseField
- private String host = "0.0.0.0";
+ private String host = "0.0.0.0";
/** SVDRP port */
@DatabaseField
- private int port = 6420;
+ private Integer port = 6420;
/** Password */
@DatabaseField
- private String password;
+ private String password = "";
/** should channels be filtered? */
@DatabaseField
@@ -51,15 +51,15 @@ public class Vdr {
/** URL of the wakeup script */
@DatabaseField
- private String wakeupUrl;
+ private String wakeupUrl = "";
/** User for wakeup */
@DatabaseField
- private String wakeupUser;
+ private String wakeupUser = "";
/** Password for wakeup */
@DatabaseField
- private String wakeupPassword;
+ private String wakeupPassword = "";
/**
* vdr mac for wol
@@ -67,7 +67,7 @@ public class Vdr {
* @since 0.2
*/
@DatabaseField
- private String mac;
+ private String mac = "";
/**
* which wakeup method to use
@@ -84,7 +84,7 @@ public class Vdr {
/** Intervall for alive test */
@DatabaseField
- private int aliveCheckInterval;
+ private Integer aliveCheckInterval;
/** Buffer before event */
@DatabaseField
@@ -104,7 +104,7 @@ public class Vdr {
/** user defined epg search times */
@DatabaseField
- private String epgSearchTimes;
+ private String epgSearchTimes = "";
/**
* Which port to use for streaming
@@ -140,7 +140,7 @@ public class Vdr {
* Remux command
*/
@DatabaseField
- private String remuxCommand = "EXT";
+ private String remuxCommand = "EXT";
/**
* Remux command Parameter
@@ -170,10 +170,10 @@ public class Vdr {
private int timeout = 60;
@DatabaseField
- private String streamingUsername;
+ private String streamingUsername = "";
@DatabaseField
- private String streamingPassword;
+ private String streamingPassword = "";
@DatabaseField
private int livePort = 8008;
@@ -184,8 +184,7 @@ public class Vdr {
@DatabaseField
private boolean enableRecStreaming = false;
-
- @DatabaseField(columnName="stz")
+ @DatabaseField(columnName = "stz")
private String serverTimeZone = "Europe/Berlin";
public String getServerTimeZone() {
@@ -489,10 +488,14 @@ public class Vdr {
}
private static <T> T get(Map<String, Object> map, String key, Object def) {
- if(map.containsKey(key)){
+ if (map.containsKey(key)) {
return (T) map.get(key);
}
- return (T)def;
+ return (T) def;
+ }
+
+ private static Integer getInteger(Map<String, Object> map, String key) {
+ return getInteger(map, key, 0);
}
private static Integer getInteger(Map<String, Object> map, String key,
@@ -505,21 +508,26 @@ public class Vdr {
if (obj instanceof Integer) {
return (Integer) obj;
}
- return Integer.valueOf(String.valueOf(obj));
- }
- private static Integer getInteger(Map<String, Object> map, String key) {
- if (map.containsKey(key) == false) {
- return Integer.valueOf(0);
- }
-
- Object obj = get(map, key);
- if (obj instanceof Integer) {
- return (Integer) obj;
+ try {
+ return Integer.valueOf(String.valueOf(obj));
+ } catch (NumberFormatException nfe) {
+ return def;
}
- return Integer.valueOf(String.valueOf(obj));
}
+ // private static Integer getInteger(Map<String, Object> map, String key) {
+ // if (map.containsKey(key) == false) {
+ // return Integer.valueOf(0);
+ // }
+
+ // Object obj = get(map, key);
+ // if (obj instanceof Integer) {
+ // return (Integer) obj;
+ // }
+ // return Integer.valueOf(String.valueOf(obj));
+ // }
+
private static Boolean getBoolean(Map<String, Object> map, String key) {
return getBoolean(map, key, false);
}
@@ -580,58 +588,9 @@ public class Vdr {
}
public void set(Map<String, Object> map) {
- name = get(map, "vdr_name", name);
- host = get(map, "vdr_host", host);
- port = getInteger(map, "vdr_port", port);
- password = get(map, "vdr_password", password);
- secure = getBoolean(map, "vdr_secure", secure);
-
- filterChannels = getBoolean(map, "limit_channels", filterChannels);
- channelFilter = get(map, "last_channel", channelFilter);
-
- wakeupEnabled = getBoolean(map, "key_wakeup_enabled", wakeupEnabled);
- wakeupUrl = get(map, "key_wakeup_url", wakeupUrl);
- wakeupUser = get(map, "key_wakeup_user", wakeupUser);
- wakeupPassword = get(map, "key_wakeup_password", wakeupPassword);
- wakeupMethod = get(map, "key_wakeup_method", wakeupMethod);
- wolCustomBroadcast = get(map, "key_wol_custom_broadcast",
- wolCustomBroadcast);
- mac = get(map, "key_wakeup_wol_mac", mac);
-
- connectionTimeout = getInteger(map, "key_conntimeout_key",
- connectionTimeout);
- readTimeout = getInteger(map, "key_vdr_readtimeout", readTimeout);
- timeout = getInteger(map, "key_vdr_timeout", timeout);
-
- timerPreMargin = getInteger(map, "timer_pre_start_buffer",
- timerPreMargin);
- timerPostMargin = getInteger(map, "timer_post_end_buffer",
- timerPostMargin);
- timerDefaultPriority = getInteger(map, "timer_default_priority",
- timerDefaultPriority);
- timerDefaultLifetime = getInteger(map, "timer_default_lifetime",
- timerDefaultLifetime);
-
- streamPort = getInteger(map, "streamingport", streamPort);
- streamingPassword = get(map, "key_streaming_password",
- streamingPassword);
- streamingUsername = get(map, "key_streaming_username",
- streamingUsername);
- encoding = get(map, "key_vdr_encoding", encoding);
- streamFormat = get(map, "livetv_streamformat", streamFormat);
- remuxCommand = get(map, "remux_command", remuxCommand);
- remuxParameter = get(map, "remux_parameter", remuxParameter);
- enableRemux = getBoolean(map, "remux_enable", enableRemux);
-
- enableRecStreaming = getBoolean(map, "key_rec_stream_enable",
- enableRecStreaming);
- livePort = getInteger(map, "key_live_port", livePort);
- recStreamMethod = get(map, "key_recstream_method", recStreamMethod);
-
- }
-
- public void init(Map<String, Object> map) {
- name = get(map, "vdr_name", name);
+ init(map);
+/*
+ name = get(map, "vdr_name");
host = get(map, "vdr_host");
port = getInteger(map, "vdr_port");
password = get(map, "vdr_password");
@@ -641,19 +600,20 @@ public class Vdr {
channelFilter = get(map, "last_channel");
wakeupEnabled = getBoolean(map, "key_wakeup_enabled");
- wakeupUrl = get(map, "key_wakeup_url", "0.0.0.0");
- wakeupUser = get(map, "key_wakeup_user", "");
- wakeupPassword = get(map, "key_wakeup_password", "");
- wakeupMethod = get(map, "key_wakeup_method", "wol");
- wolCustomBroadcast = get(map, "key_wol_custom_broadcast", "");
- mac = get(map, "key_wakeup_wol_mac", "");
+ wakeupUrl = get(map, "key_wakeup_url");
+ wakeupUser = get(map, "key_wakeup_user");
+ wakeupPassword = get(map, "key_wakeup_password");
+ wakeupMethod = get(map, "key_wakeup_method");
+ wolCustomBroadcast = get(map, "key_wol_custom_broadcast");
+ mac = get(map, "key_wakeup_wol_mac");
connectionTimeout = getInteger(map, "key_conntimeout_key");
readTimeout = getInteger(map, "key_vdr_readtimeout");
timeout = getInteger(map, "key_vdr_timeout");
- timerPreMargin = getInteger(map, "timer_pre_start_buffer", 5);
- timerPostMargin = getInteger(map, "timer_post_end_buffer", 30);
+ timerPreMargin = getInteger(map, "timer_pre_start_buffer"
+ );
+ timerPostMargin = getInteger(map, "timer_post_end_buffer");
timerDefaultPriority = getInteger(map, "timer_default_priority");
timerDefaultLifetime = getInteger(map, "timer_default_lifetime");
@@ -669,8 +629,49 @@ public class Vdr {
enableRecStreaming = getBoolean(map, "key_rec_stream_enable");
livePort = getInteger(map, "key_live_port");
recStreamMethod = get(map, "key_recstream_method");
- serverTimeZone = get(map, "key_imezone", TimeZone.getDefault());
+ */
+ }
+ public void init(Map<String, Object> map) {
+ name = get(map, "vdr_name", "VDR");
+ host = get(map, "vdr_host", "0.0.0.0");
+ port = getInteger(map, "vdr_port", 6420);
+ password = get(map, "vdr_password", "");
+ secure = getBoolean(map, "vdr_secure");
+
+ filterChannels = getBoolean(map, "limit_channels", true);
+ channelFilter = get(map, "last_channel", "");
+
+ wakeupEnabled = getBoolean(map, "key_wakeup_enabled", false);
+ wakeupUrl = get(map, "key_wakeup_url", "");
+ wakeupUser = get(map, "key_wakeup_user", "");
+ wakeupPassword = get(map, "key_wakeup_password", "");
+ wakeupMethod = get(map, "key_wakeup_method", "wol");
+ wolCustomBroadcast = get(map, "key_wol_custom_broadcast", "");
+ mac = get(map, "key_wakeup_wol_mac", "");
+
+ connectionTimeout = getInteger(map, "key_conntimeout_key", 10);
+ readTimeout = getInteger(map, "key_vdr_readtimeout", 10);
+ timeout = getInteger(map, "key_vdr_timeout", 60);
+
+ timerPreMargin = getInteger(map, "timer_pre_start_buffer", 5);
+ timerPostMargin = getInteger(map, "timer_post_end_buffer", 30);
+ timerDefaultPriority = getInteger(map, "timer_default_priority", 50);
+ timerDefaultLifetime = getInteger(map, "timer_default_lifetime",99);
+
+ streamPort = getInteger(map, "streamingport", 3000);
+ streamingPassword = get(map, "key_streaming_password", "");
+ streamingUsername = get(map, "key_streaming_username", "");
+ encoding = get(map, "key_vdr_encoding", "utf-8");
+ streamFormat = get(map, "livetv_streamformat", "TS");
+ remuxCommand = get(map, "remux_command", "EXT");
+ remuxParameter = get(map, "remux_parameter", "");
+ enableRemux = getBoolean(map, "remux_enable");
+
+ enableRecStreaming = getBoolean(map, "key_rec_stream_enable");
+ livePort = getInteger(map, "key_live_port", 8008);
+ recStreamMethod = get(map, "key_recstream_method", "vdr-live");
+ serverTimeZone = get(map, "key_imezone", TimeZone.getDefault().getID());
}
}
diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/data/VdrSharedPreferences.java b/vdrmanager/src/de/bjusystems/vdrmanager/data/VdrSharedPreferences.java
index 8839fa0..bb0ad77 100644
--- a/vdrmanager/src/de/bjusystems/vdrmanager/data/VdrSharedPreferences.java
+++ b/vdrmanager/src/de/bjusystems/vdrmanager/data/VdrSharedPreferences.java
@@ -12,6 +12,7 @@ import android.content.SharedPreferences;
import com.j256.ormlite.dao.Dao.CreateOrUpdateStatus;
import com.j256.ormlite.dao.RuntimeExceptionDao;
+@Deprecated
public class VdrSharedPreferences implements SharedPreferences {
private static final String EMPTY_STRING = "";
diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/VdrPreferencesActivity.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/VdrPreferencesActivity.java
index 35798d2..6f9d47d 100644
--- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/VdrPreferencesActivity.java
+++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/VdrPreferencesActivity.java
@@ -25,12 +25,12 @@ import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.view.View;
import de.bjusystems.vdrmanager.R;
+import de.bjusystems.vdrmanager.VdrSharedPreferencesImpl;
import de.bjusystems.vdrmanager.ZonePicker;
import de.bjusystems.vdrmanager.app.Intents;
import de.bjusystems.vdrmanager.data.FetchEditTextPreference;
import de.bjusystems.vdrmanager.data.Preferences;
import de.bjusystems.vdrmanager.data.Vdr;
-import de.bjusystems.vdrmanager.data.VdrSharedPreferences;
import de.bjusystems.vdrmanager.data.db.DBAccess;
import de.bjusystems.vdrmanager.tasks.VoidAsyncTask;
@@ -41,7 +41,7 @@ public class VdrPreferencesActivity extends BasePreferencesActivity implements
Vdr vdr;
- VdrSharedPreferences pref;
+ VdrSharedPreferencesImpl pref;
int id = -1;
@@ -68,11 +68,16 @@ public class VdrPreferencesActivity extends BasePreferencesActivity implements
super.updateSummary(ep);
}
+
+ private boolean isNew = false;
+
+ private boolean hasChanged = false;
+
private void initVDRInstance() {
id = getIntent().getIntExtra(Intents.VDR_ID, -1);
if (id == -1) {// new vdr
vdr = new Vdr();
-
+ isNew = true;
} else {// edit
Vdr v = DBAccess.get(this).getVdrDAO().queryForId(id);
if (v != null) {
@@ -80,9 +85,10 @@ public class VdrPreferencesActivity extends BasePreferencesActivity implements
} else {
vdr = new Vdr();
id = -1;
+ isNew = true;
}
}
- pref.setInstance(vdr);
+ pref = new VdrSharedPreferencesImpl(vdr, DBAccess.get(this).getVdrDAO());
}
public static String ARP_CACHE = "/proc/net/arp";
@@ -149,10 +155,6 @@ public class VdrPreferencesActivity extends BasePreferencesActivity implements
super.onCreate(savedInstanceState);
- pref = new VdrSharedPreferences();
-
- pref.dao = DBAccess.get(this).getVdrDAO();
-
initVDRInstance();
this.addPreferencesFromResource(R.xml.vdr_prefs);
@@ -317,6 +319,7 @@ public class VdrPreferencesActivity extends BasePreferencesActivity implements
}
public void onSharedPreferenceChanged(SharedPreferences arg0, String key) {
+ hasChanged = true;
updateChildPreferences();
Preference p = findPreference(key);
updateSummary(p);
@@ -437,8 +440,9 @@ public class VdrPreferencesActivity extends BasePreferencesActivity implements
finish();
return;
}
- if (pref.commits < 2) {// user has not changed anything
- DBAccess.get(this).getVdrDAO().delete(pref.getInstance());
+ if(isNew == true && hasChanged == false) {
+ //if (pref.commits < 2) {// user has not changed anything
+ DBAccess.get(this).getVdrDAO().delete(pref.getVdr());
finish();
return;
}