<NME> PlatformSqliteHelper.java
<BEF> package com.platform.sqlite;

/**
 * BreadWallet
 * <p/>
 * Created by Mihail Gutan on <mihail@breadwallet.com> 11/8/16.
 * Copyright (c) 2016 breadwallet LLC
 * <p/>
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * <p/>
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * <p/>
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

import com.breadwallet.tools.util.BRConstants;

public class PlatformSqliteHelper extends SQLiteOpenHelper {
    private static final String TAG = PlatformSqliteHelper.class.getName();

    private static PlatformSqliteHelper instance;

    public static final String DATABASE_NAME = "platform.db";
    private static final int DATABASE_VERSION = 3;

    public static synchronized PlatformSqliteHelper getInstance(Context context) {

        // Use the application context, which will ensure that you
        // don't accidentally leak an Activity's context.
        // See this article for more information: http://bit.ly/6LRzfx
        if (instance == null) {
            instance = new PlatformSqliteHelper(context.getApplicationContext());
        }
        return instance;
    }

    /**
     * KV Store table
     */

    public static final String KV_STORE_TABLE_NAME = "kvStoreTable";
    public static final String KV_VERSION = "version";
    public static final String KV_REMOTE_VERSION = "remote_version";
        public static final String KV_KEY = "key";
    public static final String KV_VALUE = "value";
    public static final String KV_TIME = "thetime";
    public static final String KV_DELETED = "deleted";

    private static final String KV_DATABASE_CREATE = String.format("CREATE TABLE IF NOT EXISTS %s(" +
            "   %s         INTEGER  NOT NULL, " +
            "   %s  INTEGER  NOT NULL DEFAULT 0, " +
            "   %s             TEXT    NOT NULL, " +
            "   %s           BLOB    NOT NULL, " +
            "   %s         INTEGER  NOT NULL, " + // server unix timestamp in MS
            "   %s         INTEGER    NOT NULL, " +
            "   PRIMARY KEY (%s, %s) " +
            ");", KV_STORE_TABLE_NAME, KV_VERSION, KV_REMOTE_VERSION, KV_KEY, KV_VALUE, KV_TIME, KV_DELETED, KV_KEY, KV_VERSION);

    private PlatformSqliteHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        setWriteAheadLoggingEnabled(BRConstants.WRITE_AHEAD_LOGGING);
    }

    @Override
    public void onCreate(SQLiteDatabase database) {
        Log.d(TAG, "onCreate: " + KV_DATABASE_CREATE);
        database.execSQL(KV_DATABASE_CREATE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        Log.e(TAG, "Upgrading database from version " + oldVersion + " to "
                + newVersion + ", which will destroy all old data");
        db.execSQL("DROP TABLE IF EXISTS " + KV_STORE_TABLE_NAME);
        //recreate the dbs
        onCreate(db);
    }
}

<MSG> Merge branch 'pablobu/DROID-1066-p1' into 'develop'

DROID-1066: Refactor ReplicatedKVStore to follow the team's coding standards and add Javadocs to KVStoreAdaptor.

Closes DROID-1066

See merge request breadwallet/breadwallet-android!471
<DFF> @@ -58,7 +58,7 @@ public class PlatformSqliteHelper extends SQLiteOpenHelper {
     public static final String KV_STORE_TABLE_NAME = "kvStoreTable";
     public static final String KV_VERSION = "version";
     public static final String KV_REMOTE_VERSION = "remote_version";
-        public static final String KV_KEY = "key";
+    public static final String KV_KEY = "key";
     public static final String KV_VALUE = "value";
     public static final String KV_TIME = "thetime";
     public static final String KV_DELETED = "deleted";

{'commit': 'diff --git a/app/src/main/java/com/platform/interfaces/KVStoreAdaptor.java b/app/src/main/java/com/platform/interfaces/KVStoreAdaptor.java\nindex e111e3bd7..617286f32 100644\n--- a/app/src/main/java/com/platform/interfaces/KVStoreAdaptor.java\n+++ b/app/src/main/java/com/platform/interfaces/KVStoreAdaptor.java\n@@ -1,9 +1,3 @@\n-package com.platform.interfaces;\n-\n-import com.platform.kvstore.CompletionObject;\n-\n-import static android.R.attr.value;\n-\n /**\n  * BreadWallet\n  * <p/>\n@@ -28,16 +22,57 @@ import static android.R.attr.value;\n  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n  * THE SOFTWARE.\n  */\n+package com.platform.interfaces;\n+\n+import com.platform.kvstore.CompletionObject;\n+\n+/**\n+ * Interface for the available operations with server\'s KV store.\n+ */\n public interface KVStoreAdaptor {\n \n-    public CompletionObject ver(String key);\n+    /**\n+     * Return the most recent version of the key in the server.\n+     *\n+     * @param key\n+     * @return\n+     */\n+    CompletionObject ver(String key);\n \n-    public CompletionObject put(String key, byte[] value, long version);\n+    /**\n+     * Save a value under a key. If it\'s a new key, then pass 0 as the If-None-Match header, otherwise you must\n+     * pass the current version in the database (which may be retrieved with KVStoreAdaptor.get).\n+     *\n+     * @param key     Existing key or 0 if it\'s a new key.\n+     * @param value   Value to be stored.\n+     * @param version Current version in the database.\n+     * @return\n+     */\n+    CompletionObject put(String key, byte[] value, long version);\n \n-    public CompletionObject del(String key, long version);\n+    /**\n+     * Mark a key as deleted in the KV store.\n+     *\n+     * @param key     The key to save the data under\n+     * @param version Version of the key.\n+     * @return\n+     */\n+    CompletionObject del(String key, long version);\n \n-    public CompletionObject get(String key, long version);\n+    /**\n+     * Retrieve a value from a key. If the given version is older than the server\'s version conflict will be returned.\n+     *\n+     * @param key     The key to retrieve from the KV store\n+     * @param version Current version in the database.\n+     * @return\n+     */\n+    CompletionObject get(String key, long version);\n \n-    public CompletionObject keys();\n+    /**\n+     * Retrieve all the keys from the server belonging to the current user.\n+     *\n+     * @return\n+     */\n+    CompletionObject keys();\n \n }\ndiff --git a/app/src/main/java/com/platform/kvstore/ReplicatedKVStore.java b/app/src/main/java/com/platform/kvstore/ReplicatedKVStore.java\nindex 87cd3c694..dd25c7869 100644\n--- a/app/src/main/java/com/platform/kvstore/ReplicatedKVStore.java\n+++ b/app/src/main/java/com/platform/kvstore/ReplicatedKVStore.java\n@@ -55,24 +55,10 @@ import static com.platform.sqlite.PlatformSqliteHelper.KV_STORE_TABLE_NAME;\n public class ReplicatedKVStore implements ApplicationLifecycleObserver.ApplicationLifecycleListener {\n     private static final String TAG = ReplicatedKVStore.class.getName();\n \n-    //    private AtomicInteger mOpenCounter = new AtomicInteger();\n-    private SQLiteDatabase mDatabase;\n-\n     private static final String KEY_REGEX = "^[^_][\\\\w-]{1,255}$";\n-\n-    public final boolean encrypted = true;\n-    public final boolean encryptedReplication = true;\n-    //    private Lock dbLock = new ReentrantLock();\n-    public boolean syncImmediately = false;\n-    private boolean syncRunning = false;\n-    private KVStoreAdaptor remoteKvStore;\n-    private static Context mContext;\n-    private static byte[] tempAuthKey;\n-    // Database fields\n-//    private SQLiteDatabase readDb;\n-//    private SQLiteDatabase writeDb;\n-    private final PlatformSqliteHelper dbHelper;\n-    private final String[] allColumns = {\n+    private static final boolean ENCRYPTED = true;\n+    private static final boolean ENCRYPTED_REPLICATION = true;\n+    private static final String[] ALL_COLUMNS = {\n             PlatformSqliteHelper.KV_VERSION,\n             PlatformSqliteHelper.KV_REMOTE_VERSION,\n             PlatformSqliteHelper.KV_KEY,\n@@ -81,6 +67,15 @@ public class ReplicatedKVStore implements ApplicationLifecycleObserver.Applicati\n             PlatformSqliteHelper.KV_DELETED\n     };\n \n+    private static byte[] mTempAuthKey;\n+    private Context mContext;\n+    private SQLiteDatabase mDatabase;\n+    private boolean mSyncImmediately = false;\n+    private boolean mSyncRunning = false;\n+    private KVStoreAdaptor mRemoteKvStore;\n+    private final PlatformSqliteHelper mDbHelper;\n+\n+\n     private static ReplicatedKVStore instance;\n \n     public static ReplicatedKVStore getInstance(Context context, KVStoreAdaptor remoteKvStore) {\n@@ -93,27 +88,27 @@ public class ReplicatedKVStore implements ApplicationLifecycleObserver.Applicati\n     private ReplicatedKVStore(Context context, KVStoreAdaptor remoteKvStore) {\n //        if (ActivityUTILS.isMainThread()) throw new NetworkOnMainThreadException();\n         mContext = context;\n-        this.remoteKvStore = remoteKvStore;\n-        dbHelper = PlatformSqliteHelper.getInstance(context);\n+        this.mRemoteKvStore = remoteKvStore;\n+        mDbHelper = PlatformSqliteHelper.getInstance(context);\n     }\n \n-    public SQLiteDatabase getWritable() {\n+    private SQLiteDatabase getWritable() {\n //        if (mOpenCounter.incrementAndGet() == 1) {\n         // Opening new database\n //        if (ActivityUTILS.isMainThread()) throw new NetworkOnMainThreadException();\n         if (mDatabase == null || !mDatabase.isOpen())\n-            mDatabase = dbHelper.getWritableDatabase();\n-        dbHelper.setWriteAheadLoggingEnabled(BRConstants.WRITE_AHEAD_LOGGING);\n+            mDatabase = mDbHelper.getWritableDatabase();\n+        mDbHelper.setWriteAheadLoggingEnabled(BRConstants.WRITE_AHEAD_LOGGING);\n //        }\n //        Log.d(TAG, "getWritable open counter: " + String.valueOf(mOpenCounter.get()));\n         return mDatabase;\n     }\n \n-    public SQLiteDatabase getReadable() {\n+    private SQLiteDatabase getReadable() {\n         return getWritable();\n     }\n \n-    public void closeDB() {\n+    private void closeDB() {\n //        mDatabase.close();\n //        if (mOpenCounter.decrementAndGet() == 0) {\n         // Closing database\n@@ -124,7 +119,7 @@ public class ReplicatedKVStore implements ApplicationLifecycleObserver.Applicati\n     }\n \n     /**\n-     * Set the value of a key locally in the database. If syncImmediately is true (the default) then immediately\n+     * Set the value of a key locally in the database. If mSyncImmediately is true (the default) then immediately\n      * after successfully saving locally, replicate to server. The `localVer` key must be the same as is currently\n      * stored in the database. To create a new key, pass `0` as `localVer`\n      */\n@@ -134,8 +129,9 @@ public class ReplicatedKVStore implements ApplicationLifecycleObserver.Applicati\n     }\n \n     public void set(List<KVItem> kvs) {\n-        for (KVItem kv : kvs)\n+        for (KVItem kv : kvs) {\n             set(kv);\n+        }\n     }\n \n     public CompletionObject set(KVItem kv) {\n@@ -148,8 +144,8 @@ public class ReplicatedKVStore implements ApplicationLifecycleObserver.Applicati\n                 } catch (Exception e) {\n                     e.printStackTrace();\n                 }\n-                if (syncImmediately && obj.err == null) {\n-                    if (!syncRunning) {\n+                if (mSyncImmediately && obj.err == null) {\n+                    if (!mSyncRunning) {\n                         syncKey(kv.key, 0, 0, null);\n                         Log.e(TAG, "set: key synced: " + kv.key);\n                     }\n@@ -168,7 +164,7 @@ public class ReplicatedKVStore implements ApplicationLifecycleObserver.Applicati\n         }\n     }\n \n-    private synchronized CompletionObject _set(KVItem kv) throws Exception {\n+    private synchronized CompletionObject _set(KVItem kv) {\n         Log.d(TAG, "_set: " + kv.key);\n         long localVer = kv.version;\n         long newVer = 0;\n@@ -181,7 +177,7 @@ public class ReplicatedKVStore implements ApplicationLifecycleObserver.Applicati\n             return new CompletionObject(CompletionObject.RemoteKVStoreError.conflict);\n         }\n         newVer = curVer + 1;\n-        byte[] encryptionData = encrypted ? encrypt(kv.value, mContext) : kv.value;\n+        byte[] encryptionData = ENCRYPTED ? encrypt(kv.value, mContext) : kv.value;\n         SQLiteDatabase db = getWritable();\n         try {\n             db.beginTransaction();\n@@ -240,7 +236,7 @@ public class ReplicatedKVStore implements ApplicationLifecycleObserver.Applicati\n //                    curVer = version;\n                 //if we have a version, check if it\'s correct\n                 cursor = db.query(KV_STORE_TABLE_NAME,\n-                        allColumns, "key = ? AND version = ?", new String[]{key, String.valueOf(version)},\n+                        ALL_COLUMNS, "key = ? AND version = ?", new String[]{key, String.valueOf(version)},\n                         null, null, "version DESC", "1");\n                 if (cursor.moveToNext())\n                     curVer = cursor.getLong(0);\n@@ -254,14 +250,14 @@ public class ReplicatedKVStore implements ApplicationLifecycleObserver.Applicati\n             }\n             if (cursor != null) cursor.close();\n             cursor = db.query(KV_STORE_TABLE_NAME,\n-                    allColumns, "key = ? AND version = ?", new String[]{key, String.valueOf(curVer)},\n+                    ALL_COLUMNS, "key = ? AND version = ?", new String[]{key, String.valueOf(curVer)},\n                     null, null, "version DESC", "1");\n             if (cursor.moveToNext()) {\n                 kv = cursorToKv(cursor);\n             }\n             if (kv != null) {\n                 byte[] val = kv.value;\n-                kv.value = encrypted ? decrypt(val, mContext) : val;\n+                kv.value = ENCRYPTED ? decrypt(val, mContext) : val;\n                 if (val != null && Utils.isNullOrEmpty(kv.value)) {\n                     //decrypting failed\n                     Log.e(TAG, "get: Decrypting failed for key: " + key + ", deleting the kv");\n@@ -283,7 +279,6 @@ public class ReplicatedKVStore implements ApplicationLifecycleObserver.Applicati\n     /**\n      * Gets the local version of the provided key, or 0 if it doesn\'t exist\n      */\n-\n     public CompletionObject localVersion(String key) {\n         if (isKeyValid(key)) {\n             return _localVersion(key);\n@@ -308,8 +303,9 @@ public class ReplicatedKVStore implements ApplicationLifecycleObserver.Applicati\n         } catch (Exception e) {\n             e.printStackTrace();\n         } finally {\n-            if (cursor != null)\n+            if (cursor != null) {\n                 cursor.close();\n+            }\n //            closeDB();\n         }\n         return new CompletionObject(version, time, null);\n@@ -374,7 +370,7 @@ public class ReplicatedKVStore implements ApplicationLifecycleObserver.Applicati\n                 KVItem kvItem = cursorToKv(cursor);\n                 if (kvItem != null) {\n                     byte[] val = kvItem.value;\n-                    kvItem.value = encrypted ? decrypt(val, mContext) : val;\n+                    kvItem.value = ENCRYPTED ? decrypt(val, mContext) : val;\n                     kvs.add(kvItem);\n                 }\n             }\n@@ -437,13 +433,15 @@ public class ReplicatedKVStore implements ApplicationLifecycleObserver.Applicati\n     /**\n      * Sync an individual key. Normally this is only called internally and you should call syncAllKeys\n      */\n-    public void syncKey(final String key, final long remoteVersion, final long remoteTime, final CompletionObject.RemoteKVStoreError err) {\n-        if (syncRunning) return;\n-        syncRunning = true;\n+    private void syncKey(final String key, final long remoteVersion, final long remoteTime, final CompletionObject.RemoteKVStoreError err) {\n+        if (mSyncRunning) {\n+            return;\n+        }\n+        mSyncRunning = true;\n \n         try {\n             if (remoteVersion == 0 || remoteTime == 0) {\n-                final CompletionObject completionObject = remoteKvStore.ver(key);\n+                final CompletionObject completionObject = mRemoteKvStore.ver(key);\n                 Log.e(TAG, String.format("syncKey: completionObject: version: %d, value: %s, err: %s, time: %d",\n                         completionObject.version, Arrays.toString(completionObject.value), completionObject.err, completionObject.time));\n                 _syncKey(key, completionObject.version, completionObject.time, completionObject.err);\n@@ -461,7 +459,7 @@ public class ReplicatedKVStore implements ApplicationLifecycleObserver.Applicati\n         } catch (Exception ex) {\n             ex.printStackTrace();\n         } finally {\n-            syncRunning = false;\n+            mSyncRunning = false;\n         }\n     }\n \n@@ -479,14 +477,16 @@ public class ReplicatedKVStore implements ApplicationLifecycleObserver.Applicati\n         // 2. along with the remote version will come the last-modified date of the remote object\n         // 3. if their last-modified date is newer than ours, overwrite ours\n         // 4. if their last-modified date is older than ours, overwrite theirs\n-        if (!syncRunning) throw new IllegalArgumentException("how did we get here?");\n+        if (!mSyncRunning) {\n+            throw new IllegalArgumentException("how did we get here?");\n+        }\n \n         // one optimization is we keep the remote version on the most recent local version, if they match,\n         // there is nothing to do\n \n         long recorderRemoteVersion = remoteVersion(key);\n         if (err != CompletionObject.RemoteKVStoreError.notFound && remoteVersion > 0 && recorderRemoteVersion == remoteVersion) {\n-//            Log.e(TAG, "_syncKey: " + String.format("Remote version of key: %s is the same as the one we have", key));\n+            Log.d(TAG, "_syncKey: Remote version of key: " + key + " is the same as the one we have");\n             return true;\n         }\n \n@@ -499,7 +499,7 @@ public class ReplicatedKVStore implements ApplicationLifecycleObserver.Applicati\n \n         if (completionObject.err == null) {\n             locVal = localKv.value;\n-            localKv.value = encryptedReplication ? encrypt(locVal, mContext) : locVal;\n+            localKv.value = ENCRYPTED_REPLICATION ? encrypt(locVal, mContext) : locVal;\n         }\n \n         if (err == null || err == CompletionObject.RemoteKVStoreError.notFound || err == CompletionObject.RemoteKVStoreError.tombstone) {\n@@ -509,21 +509,20 @@ public class ReplicatedKVStore implements ApplicationLifecycleObserver.Applicati\n                 Log.i(TAG, String.format("Local key %s was deleted, and so was the remote key", key));\n                 return setRemoteVersion(key, localKv.version, localKv.remoteVersion).err == null;\n             }\n-            if (localKv.time >= remoteTime) {// local is newer (or a tiebreaker)\n+            if (localKv.time >= remoteTime) { // local is newer (or a tiebreaker)\n                 if (localKv.deleted > 0) {\n                     Log.i(TAG, String.format("Local key %s was deleted, removing remotely...", key));\n-                    CompletionObject obj = remoteKvStore.del(key, remoteVersion);\n+                    CompletionObject obj = mRemoteKvStore.del(key, remoteVersion);\n                     if (obj.err == CompletionObject.RemoteKVStoreError.notFound) {\n                         Log.i(TAG, String.format("Local key %s was already missing on the server. Ignoring", key));\n                         return true;\n                     }\n                     if (obj.err != null) {\n-                        Log.e(TAG, String.format("Error deleting remote version for key %s, error: %s", key, err));\n+                        Log.e(TAG, String.format("Error deleting remote version for key %s, error: %s", key, obj.err));\n                         return false;\n                     }\n \n-                    boolean success = setRemoteVersion(key, localKv.version, obj.version).err == null;\n-                    if (!success) return false;\n+                    return setRemoteVersion(key, localKv.version, obj.version).err == null;\n                 } else {\n                     Log.i(TAG, String.format("Local key %s is newer, updating remotely...", key));\n                     // if the remote version is zero it means it doesnt yet exist on the server. set the remote version\n@@ -534,16 +533,16 @@ public class ReplicatedKVStore implements ApplicationLifecycleObserver.Applicati\n                         Log.e(TAG, "_syncKey: encrypting value before sending to remote failed");\n                         return false;\n                     }\n-                    CompletionObject obj = remoteKvStore.put(key, val, useRemoteVer);\n+                    CompletionObject obj = mRemoteKvStore.put(key, val, useRemoteVer);\n \n                     if (obj.err != null) {\n-                        Log.e(TAG, String.format("Error updating remote version for key %s, error: %s", key, err));\n+                        Log.e(TAG, String.format("Error updating remote version for key %s, error: %s", key, obj.err));\n                         return false;\n                     }\n \n                     boolean success = setRemoteVersion(key, localKv.version, obj.version).err == null;\n                     Log.i(TAG, String.format("Local key %s updated on server", key));\n-                    if (!success) return false;\n+                    return success;\n                 }\n             } else {\n                 // local is out-of-date\n@@ -558,16 +557,17 @@ public class ReplicatedKVStore implements ApplicationLifecycleObserver.Applicati\n                     }\n                     if (obj.version != 0) {\n                         boolean success = setRemoteVersion(key, obj.version, remoteVersion).err == null;\n-                        if (!success) return false;\n-                        Log.i(TAG, String.format("Remote key %s was removed locally", key));\n-\n+                        if (success) {\n+                            Log.i(TAG, String.format("Remote key %s was removed locally", key));\n+                        }\n+                        return success;\n                     }\n                 } else {\n                     Log.i(TAG, String.format("Remote key %s is newer, fetching...", key));\n-                    CompletionObject remoteGet = remoteKvStore.get(key, remoteVersion);\n+                    CompletionObject remoteGet = mRemoteKvStore.get(key, remoteVersion);\n \n                     if (remoteGet.err != null) {\n-                        Log.e(TAG, String.format("Error fetching the remote value for key %s, error: %s", key, err));\n+                        Log.e(TAG, String.format("Error fetching the remote value for key %s, error: %s", key, remoteGet.err));\n                         return false;\n                     }\n \n@@ -576,7 +576,7 @@ public class ReplicatedKVStore implements ApplicationLifecycleObserver.Applicati\n                         Log.e(TAG, "_syncKey: key: " + key + " ,from the remote, is empty");\n                         return false;\n                     }\n-                    byte[] decryptedValue = encryptedReplication ? decrypt(val, mContext) : val;\n+                    byte[] decryptedValue = ENCRYPTED_REPLICATION ? decrypt(val, mContext) : val;\n                     if (Utils.isNullOrEmpty(decryptedValue)) {\n                         Log.e(TAG, "_syncKey: failed to decrypt the value from remote for key: " + key);\n                         return false;\n@@ -589,8 +589,7 @@ public class ReplicatedKVStore implements ApplicationLifecycleObserver.Applicati\n                         e.printStackTrace();\n                     }\n                     if (setObj.err == null) {\n-                        boolean success = setRemoteVersion(key, setObj.version, remoteGet.version).err == null;\n-                        if (!success) return false;\n+                        return setRemoteVersion(key, setObj.version, remoteGet.version).err == null;\n                     }\n                 }\n             }\n@@ -611,18 +610,18 @@ public class ReplicatedKVStore implements ApplicationLifecycleObserver.Applicati\n         // 2. for kvs that we don\'t have, add em\n         // 3. for kvs that we do have, sync em\n         // 4. for kvs that they don\'t have that we do, upload em\n-        if (syncRunning) {\n+        if (mSyncRunning) {\n             Log.e(TAG, "syncAllKeys: already syncing");\n             return false;\n         }\n-        syncRunning = true;\n+        mSyncRunning = true;\n         long startTime = System.currentTimeMillis();\n \n         try {\n-            CompletionObject obj = remoteKvStore.keys();\n+            CompletionObject obj = mRemoteKvStore.keys();\n             if (obj.err != null) {\n                 Log.e(TAG, String.format("Error fetching remote key data: %s", obj.err));\n-                syncRunning = false;\n+                mSyncRunning = false;\n                 return false;\n             }\n             List<KVItem> localKvs = getRawKVs();\n@@ -648,15 +647,16 @@ public class ReplicatedKVStore implements ApplicationLifecycleObserver.Applicati\n         } catch (Exception ex) {\n             ex.printStackTrace();\n         } finally {\n-            syncRunning = false;\n+            mSyncRunning = false;\n         }\n         return false;\n     }\n \n     private List<String> getKeysFromKVEntity(List<KVItem> entities) {\n         List<String> keys = new ArrayList<>();\n-        for (KVItem kv : entities)\n+        for (KVItem kv : entities) {\n             keys.add(kv.key);\n+        }\n         return keys;\n     }\n \n@@ -705,8 +705,9 @@ public class ReplicatedKVStore implements ApplicationLifecycleObserver.Applicati\n      * Record the remote version for the object in a new version of the local key\n      */\n     public synchronized CompletionObject setRemoteVersion(String key, long localVer, long remoteVer) {\n-        if (localVer < 1)\n+        if (localVer < 1) {\n             return new CompletionObject(CompletionObject.RemoteKVStoreError.conflict); // setRemoteVersion can\'t be used for creates\n+        }\n         if (isKeyValid(key)) {\n \n             Cursor c = null;\n@@ -724,13 +725,14 @@ public class ReplicatedKVStore implements ApplicationLifecycleObserver.Applicati\n                 }\n \n                 newVer = curVer + 1;\n-                c = db.query(true, KV_STORE_TABLE_NAME, allColumns, PlatformSqliteHelper.KV_KEY + "=? and " + PlatformSqliteHelper.KV_VERSION + "=?", new String[]{key, String.valueOf(curVer)}, null, null, "version DESC", "1");\n+                c = db.query(true, KV_STORE_TABLE_NAME, ALL_COLUMNS, PlatformSqliteHelper.KV_KEY + "=? and " + PlatformSqliteHelper.KV_VERSION + "=?", new String[]{key, String.valueOf(curVer)}, null, null, "version DESC", "1");\n                 KVItem tmp = null;\n                 if (c.moveToNext()) {\n                     tmp = cursorToKv(c);\n                 }\n-                if (tmp == null)\n+                if (tmp == null) {\n                     return new CompletionObject(CompletionObject.RemoteKVStoreError.notFound);\n+                }\n                 c.close();\n \n                 ContentValues values = new ContentValues();\n@@ -741,16 +743,18 @@ public class ReplicatedKVStore implements ApplicationLifecycleObserver.Applicati\n                 values.put(PlatformSqliteHelper.KV_TIME, time);\n                 values.put(PlatformSqliteHelper.KV_DELETED, tmp.deleted);\n                 long id = db.insert(KV_STORE_TABLE_NAME, null, values);\n-                if (id == -1)\n+                if (id == -1) {\n                     return new CompletionObject(CompletionObject.RemoteKVStoreError.unknown);\n-\n+                }\n                 db.setTransactionSuccessful();\n                 return new CompletionObject(newVer, time, null);\n             } catch (Exception e) {\n-                e.printStackTrace();\n+                Log.e(TAG, "setRemoteVersion: Failed", e);\n             } finally {\n                 db.endTransaction();\n-                if (c != null) c.close();\n+                if (c != null) {\n+                    c.close();\n+                }\n                 closeDB();\n             }\n         } else {\n@@ -760,7 +764,7 @@ public class ReplicatedKVStore implements ApplicationLifecycleObserver.Applicati\n     }\n \n     /**\n-     * Mark a key as removed locally. If syncImmediately is true (the defualt) then immediately mark the key\n+     * Mark a key as removed locally. If mSyncImmediately is true (the defualt) then immediately mark the key\n      * as removed on the server as well. `localVer` must match the most recent version in the local database.\n      */\n     public CompletionObject delete(String key, long localVersion) {\n@@ -775,8 +779,8 @@ public class ReplicatedKVStore implements ApplicationLifecycleObserver.Applicati\n                 } catch (Exception e) {\n                     e.printStackTrace();\n                 }\n-                if (syncImmediately && obj.err == null) {\n-                    if (!syncRunning) {\n+                if (mSyncImmediately && obj.err == null) {\n+                    if (!mSyncRunning) {\n                         syncKey(key, 0, 0, null);\n                         Log.e(TAG, "set: key synced: " + key);\n                     }\n@@ -789,7 +793,7 @@ public class ReplicatedKVStore implements ApplicationLifecycleObserver.Applicati\n         return new CompletionObject(CompletionObject.RemoteKVStoreError.unknown);\n     }\n \n-    private synchronized CompletionObject _delete(String key, long localVersion) throws Exception {\n+    private synchronized CompletionObject _delete(String key, long localVersion) {\n         if (localVersion == 0)\n             return new CompletionObject(CompletionObject.RemoteKVStoreError.notFound);\n         long newVer = 0;\n@@ -848,12 +852,12 @@ public class ReplicatedKVStore implements ApplicationLifecycleObserver.Applicati\n             Log.e(TAG, "encrypt: app is null");\n             return null;\n         }\n-        if (tempAuthKey == null) cacheKeyIfNeeded(app);\n-        if (Utils.isNullOrEmpty(tempAuthKey)) {\n-            Log.e(TAG, "encrypt: authKey is empty: " + (tempAuthKey == null ? null : tempAuthKey.length));\n+        if (mTempAuthKey == null) cacheKeyIfNeeded(app);\n+        if (Utils.isNullOrEmpty(mTempAuthKey)) {\n+            Log.e(TAG, "encrypt: authKey is empty: " + (mTempAuthKey == null ? null : mTempAuthKey.length));\n             return null;\n         }\n-        BRCoreKey key = new BRCoreKey(tempAuthKey);\n+        BRCoreKey key = new BRCoreKey(mTempAuthKey);\n         byte[] nonce = CryptoHelper.generateRandomNonce();\n         if (Utils.isNullOrEmpty(nonce) || nonce.length != 12) {\n             Log.e(TAG, "encrypt: nonce is invalid: " + (nonce == null ? null : nonce.length));\n@@ -881,17 +885,17 @@ public class ReplicatedKVStore implements ApplicationLifecycleObserver.Applicati\n         }\n         if (app == null) app = BreadApp.getBreadContext();\n         if (app == null) return null;\n-        if (tempAuthKey == null)\n+        if (mTempAuthKey == null)\n             cacheKeyIfNeeded(app);\n-        BRCoreKey key = new BRCoreKey(tempAuthKey);\n+        BRCoreKey key = new BRCoreKey(mTempAuthKey);\n         //12 bytes is the nonce\n         return key.decryptNative(Arrays.copyOfRange(data, 12, data.length), Arrays.copyOfRange(data, 0, 12));\n     }\n \n     private static void cacheKeyIfNeeded(Context context) {\n-        if (Utils.isNullOrEmpty(tempAuthKey)) {\n-            tempAuthKey = BRKeyStore.getAuthKey(context);\n-            if (tempAuthKey == null) Log.e(TAG, "cacheKeyIfNeeded: FAILED, still null!");\n+        if (Utils.isNullOrEmpty(mTempAuthKey)) {\n+            mTempAuthKey = BRKeyStore.getAuthKey(context);\n+            if (mTempAuthKey == null) Log.e(TAG, "cacheKeyIfNeeded: FAILED, still null!");\n             ApplicationLifecycleObserver.addApplicationLifecycleListener(instance);\n         }\n     }\n@@ -915,7 +919,7 @@ public class ReplicatedKVStore implements ApplicationLifecycleObserver.Applicati\n     public void onLifeCycle(Lifecycle.Event event) {\n         switch (event) {\n             case ON_STOP:\n-                tempAuthKey = null;\n+                mTempAuthKey = null;\n                 break;\n         }\n     }\ndiff --git a/app/src/main/java/com/platform/sqlite/PlatformSqliteHelper.java b/app/src/main/java/com/platform/sqlite/PlatformSqliteHelper.java\nindex dec8e2bd1..1fc46efae 100644\n--- a/app/src/main/java/com/platform/sqlite/PlatformSqliteHelper.java\n+++ b/app/src/main/java/com/platform/sqlite/PlatformSqliteHelper.java\n@@ -58,7 +58,7 @@ public class PlatformSqliteHelper extends SQLiteOpenHelper {\n     public static final String KV_STORE_TABLE_NAME = "kvStoreTable";\n     public static final String KV_VERSION = "version";\n     public static final String KV_REMOTE_VERSION = "remote_version";\n-        public static final String KV_KEY = "key";\n+    public static final String KV_KEY = "key";\n     public static final String KV_VALUE = "value";\n     public static final String KV_TIME = "thetime";\n     public static final String KV_DELETED = "deleted";\ndiff --git a/app/src/main/java/com/platform/tools/KVStoreManager.java b/app/src/main/java/com/platform/tools/KVStoreManager.java\nindex f6f334928..9d9da88ef 100644\n--- a/app/src/main/java/com/platform/tools/KVStoreManager.java\n+++ b/app/src/main/java/com/platform/tools/KVStoreManager.java\n@@ -483,7 +483,7 @@ public class KVStoreManager {\n         return mds;\n     }\n \n-    public static TxMetaData valueToMetaData(byte[] value) {\n+    private static TxMetaData valueToMetaData(byte[] value) {\n         TxMetaData result = new TxMetaData();\n         JSONObject json;\n         if (value == null) {\n', 'commit_subject': "Merge branch 'pablobu/DROID-1066-p1' into 'develop'", 'repo_name': 'breadwallet/breadwallet-android', 'committer': {'name': 'Shivangi Gandhi', 'email': 'dcc651c4fad3399209a3e29807f8d03e5338cb66@gmail.com', 'time_sec': '1550690127', 'tz_offset': '0', 'date': {'seconds': '1550690127'}}, 'commit_tree': 'dbb2faaa47832fd3c3bf8f7f8c29a9a053b21949', 'commit_message': "Merge branch 'pablobu/DROID-1066-p1' into 'develop'\n\nDROID-1066: Refactor ReplicatedKVStore to follow the team's coding standards and add Javadocs to KVStoreAdaptor.\n\nCloses DROID-1066\n\nSee merge request breadwallet/breadwallet-android!471", 'language_name': 'Kotlin', 'license': 'mit', 'hunks': '@@ -58,7 +58,7 @@ public class PlatformSqliteHelper extends SQLiteOpenHelper {\n     public static final String KV_STORE_TABLE_NAME = "kvStoreTable";\n     public static final String KV_VERSION = "version";\n     public static final String KV_REMOTE_VERSION = "remote_version";\n-        public static final String KV_KEY = "key";\n+    public static final String KV_KEY = "key";\n     public static final String KV_VALUE = "value";\n     public static final String KV_TIME = "thetime";\n     public static final String KV_DELETED = "deleted";\n', 'addition_count': 1, 'deletion_count': 1, 'src_file': 'a/app/src/main/java/com/platform/sqlite/PlatformSqliteHelper.java', 'tgt_file': 'b/app/src/main/java/com/platform/sqlite/PlatformSqliteHelper.java', 'file_extension': '.java', 'before_file': 'package com.platform.sqlite;\n\n/**\n * BreadWallet\n * <p/>\n * Created by Mihail Gutan on <mihail@breadwallet.com> 11/8/16.\n * Copyright (c) 2016 breadwallet LLC\n * <p/>\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the "Software"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * <p/>\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * <p/>\n * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nimport android.content.Context;\nimport android.database.sqlite.SQLiteDatabase;\nimport android.database.sqlite.SQLiteOpenHelper;\nimport android.util.Log;\n\nimport com.breadwallet.tools.util.BRConstants;\n\npublic class PlatformSqliteHelper extends SQLiteOpenHelper {\n    private static final String TAG = PlatformSqliteHelper.class.getName();\n\n    private static PlatformSqliteHelper instance;\n\n    public static final String DATABASE_NAME = "platform.db";\n    private static final int DATABASE_VERSION = 3;\n\n    public static synchronized PlatformSqliteHelper getInstance(Context context) {\n\n        // Use the application context, which will ensure that you\n        // don\'t accidentally leak an Activity\'s context.\n        // See this article for more information: http://bit.ly/6LRzfx\n        if (instance == null) {\n            instance = new PlatformSqliteHelper(context.getApplicationContext());\n        }\n        return instance;\n    }\n\n    /**\n     * KV Store table\n     */\n\n    public static final String KV_STORE_TABLE_NAME = "kvStoreTable";\n    public static final String KV_VERSION = "version";\n    public static final String KV_REMOTE_VERSION = "remote_version";\n        public static final String KV_KEY = "key";\n    public static final String KV_VALUE = "value";\n    public static final String KV_TIME = "thetime";\n    public static final String KV_DELETED = "deleted";\n\n    private static final String KV_DATABASE_CREATE = String.format("CREATE TABLE IF NOT EXISTS %s(" +\n            "   %s         INTEGER  NOT NULL, " +\n            "   %s  INTEGER  NOT NULL DEFAULT 0, " +\n            "   %s             TEXT    NOT NULL, " +\n            "   %s           BLOB    NOT NULL, " +\n            "   %s         INTEGER  NOT NULL, " + // server unix timestamp in MS\n            "   %s         INTEGER    NOT NULL, " +\n            "   PRIMARY KEY (%s, %s) " +\n            ");", KV_STORE_TABLE_NAME, KV_VERSION, KV_REMOTE_VERSION, KV_KEY, KV_VALUE, KV_TIME, KV_DELETED, KV_KEY, KV_VERSION);\n\n    private PlatformSqliteHelper(Context context) {\n        super(context, DATABASE_NAME, null, DATABASE_VERSION);\n        setWriteAheadLoggingEnabled(BRConstants.WRITE_AHEAD_LOGGING);\n    }\n\n    @Override\n    public void onCreate(SQLiteDatabase database) {\n        Log.d(TAG, "onCreate: " + KV_DATABASE_CREATE);\n        database.execSQL(KV_DATABASE_CREATE);\n    }\n\n    @Override\n    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {\n        Log.e(TAG, "Upgrading database from version " + oldVersion + " to "\n                + newVersion + ", which will destroy all old data");\n        db.execSQL("DROP TABLE IF EXISTS " + KV_STORE_TABLE_NAME);\n        //recreate the dbs\n        onCreate(db);\n    }\n}\n', 'message': "Merge branch 'pablobu/DROID-1066-p1' into 'develop'\n\nDROID-1066: Refactor ReplicatedKVStore to follow the team's coding standards and add Javadocs to KVStoreAdaptor.\n\nCloses DROID-1066\n\nSee merge request breadwallet/breadwallet-android!471", 'author_name': 'Shivangi Gandhi', 'lang': 'java'}