From 5e6a1fc28e8043d3ce3ae644e73f023160baf0a3 Mon Sep 17 00:00:00 2001 From: Loic Blot Date: Wed, 23 Aug 2017 00:28:34 +0200 Subject: [PATCH] SmsBuffer is now working, replace json objects with the SmsBuffer on sync --- CMakeLists.txt | 1 + src/main/cpp/json.cpp | 68 +++++++++ src/main/cpp/json.h | 29 ++++ src/main/cpp/smsbuffer.cpp | 130 ++++++++++++------ src/main/cpp/smsbuffer.h | 31 ++++- .../owncloud_sms/activities/MainActivity.java | 11 +- .../ConnectivityChanged.java | 11 +- .../owncloud_sms/engine/ASyncSMSSync.java | 11 +- .../engine/AndroidSmsFetcher.java | 48 ++++--- .../engine/OCSMSOwnCloudClient.java | 58 ++------ .../owncloud_sms/jni/SmsBuffer.java | 32 ++++- .../owncloud_sms/observers/SmsObserver.java | 5 +- .../providers/SmsDataProvider.java | 20 +-- 13 files changed, 313 insertions(+), 142 deletions(-) create mode 100644 src/main/cpp/json.cpp create mode 100644 src/main/cpp/json.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 0250097..259717d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.5.0) set (SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/main/cpp/httpclient.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/main/cpp/json.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/main/cpp/nativesms.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/main/cpp/smsbuffer.cpp ) diff --git a/src/main/cpp/json.cpp b/src/main/cpp/json.cpp new file mode 100644 index 0000000..16e0a7d --- /dev/null +++ b/src/main/cpp/json.cpp @@ -0,0 +1,68 @@ +/** + * Copyright (c) 2017, Loic Blot + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include "json.h" +#include +#include + +namespace json { + +std::string escape_string(const char *str) +{ + std::string result; + // Create a sufficient buffer to escape all chars + result.reserve(strlen(str) * 2 + 3); + result += "\""; + for (const char *c = str; *c != 0; ++c) { + switch (*c) { + case '\"': + result += "\\\""; + break; + case '\\': + result += "\\\\"; + break; + case '\b': + result += "\\b"; + break; + case '\t': + result += "\\t"; + break; + case '\n': + result += "\\n"; + break; + case '\f': + result += "\\f"; + break; + case '\r': + result += "\\r"; + break; + default: + if (is_control_character(*c)) { + std::stringstream oss; + oss << "\\u" << std::hex << std::uppercase << std::setfill('0') + << std::setw(4) << static_cast(*c); + result += oss.str(); + } else { + result += *c; + } + break; + } + } + result += "\""; + return result; +} +} \ No newline at end of file diff --git a/src/main/cpp/json.h b/src/main/cpp/json.h new file mode 100644 index 0000000..f05b87c --- /dev/null +++ b/src/main/cpp/json.h @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2017, Loic Blot + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include + +namespace json { + +static inline bool is_control_character(char ch) +{ return ch > 0 && ch <= 0x1F; } + +std::string escape_string(const char *str); + +} \ No newline at end of file diff --git a/src/main/cpp/smsbuffer.cpp b/src/main/cpp/smsbuffer.cpp index 431906c..3f6fb1e 100644 --- a/src/main/cpp/smsbuffer.cpp +++ b/src/main/cpp/smsbuffer.cpp @@ -16,79 +16,121 @@ */ #include +#include +#include #include "smsbuffer.h" +#include "json.h" #define LOG_TAG "SmsBuffer" const char *SmsBuffer::classPathName = "fr/unix_experience/owncloud_sms/jni/SmsBuffer"; // See https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/types.html JNINativeMethod SmsBuffer::methods[] = -{ - DECL_JNIMETHOD(createNativeObject, "()J") - DECL_JNIMETHOD(deleteNativeObject, "(J)V") - DECL_JNIMETHOD(push, "(JI)V") - DECL_JNIMETHOD(print, "(J)V") -}; + { + DECL_JNIMETHOD(createNativeObject, "()J") + DECL_JNIMETHOD(deleteNativeObject, "(J)V") + DECL_JNIMETHOD(empty, "(J)Z") + DECL_JNIMETHOD(asRawJsonString, "(J)Ljava/lang/String;") + DECL_JNIMETHOD(push, + "(JIIIJLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V") + DECL_JNIMETHOD(print, "(J)V") + }; DECL_METHODSIZE(SmsBuffer) +#define SMSBUFFER_CAST \ + SmsBuffer *me = reinterpret_cast(ptr); \ + if (!me) { \ + __android_log_print(ANDROID_LOG_FATAL, LOG_TAG, "It's not a SmsBuffer!"); \ + assert(false); \ + } + jlong SmsBuffer::createNativeObject(JNIEnv *env, jobject self) { - return reinterpret_cast(new SmsBuffer()); + return reinterpret_cast(new SmsBuffer()); } void SmsBuffer::deleteNativeObject(JNIEnv *env, jobject self, jlong ptr) { - __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "deleteSmsBuffer"); - delete reinterpret_cast(ptr); -} - -SmsBuffer::SmsBuffer() -{ + __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "deleteSmsBuffer"); + delete reinterpret_cast(ptr); } void SmsBuffer::reset_buffer() { - m_buffer.clear(); - m_buffer_empty = true; -} -void SmsBuffer::push(JNIEnv *env, jobject self, jlong ptr, jint mailbox_id) -{ - SmsBuffer *me = reinterpret_cast(ptr); - if (!me) { - __android_log_print(ANDROID_LOG_FATAL, LOG_TAG, "It's not a SmsBuffer!"); - return; - } - - me->_push(mailbox_id); + m_buffer.clear(); + m_buffer_empty = true; + m_sms_count = 0; } -void SmsBuffer::_push(int mailbox_id) +void SmsBuffer::push(JNIEnv *env, jobject self, jlong ptr, jint msg_id, jint mailbox_id, jint type, + jlong date, jstring address, jstring body, jstring read, jstring seen) { - // If buffer is not empty, we are joining messages - if (!m_buffer_empty) { - m_buffer << ","; - } - // Else, we are starting array - else { - m_buffer << "["; - m_buffer_empty = true; - } + SMSBUFFER_CAST + me->_push(msg_id, mailbox_id, type, date, env->GetStringUTFChars(address, NULL), + env->GetStringUTFChars(body, NULL), env->GetStringUTFChars(read, NULL), + env->GetStringUTFChars(seen, NULL)); +} - m_buffer << "{\"mbox\": " << mailbox_id << "}"; +void SmsBuffer::_push(int msg_id, int mailbox_id, int type, + long date, const char *address, const char *body, const char *read, + const char *seen) +{ + // If buffer is not empty, we are joining messages + if (!m_buffer_empty) { + m_buffer << ","; + } + // Else, we are starting array + else { + m_buffer << "["; + m_buffer_empty = false; + } + + m_buffer << "{\"_id\": " << msg_id << ", " + << "\"mbox\": " << mailbox_id << ", " + << "\"type\": " << type << ", " + << "\"date\": " << date << ", " + << "\"body\": " << json::escape_string(body) << ", " + << "\"address\": " << json::escape_string(address) << ", " + << "\"read\": " << json::escape_string(read) << ", " + << "\"seen\": " << json::escape_string(seen) + << "}"; + m_sms_count++; +} + +jboolean SmsBuffer::empty(JNIEnv *env, jobject self, jlong ptr) +{ + SMSBUFFER_CAST + return (jboolean) (me->_empty() ? 1 : 0); +} + +bool SmsBuffer::_empty() const +{ + return m_buffer_empty; } void SmsBuffer::print(JNIEnv *env, jobject self, jlong ptr) { - SmsBuffer *me = reinterpret_cast(ptr); - if (!me) { - __android_log_print(ANDROID_LOG_FATAL, LOG_TAG, "It's not a SmsBuffer!"); - return; - } - - me->_print(); + SMSBUFFER_CAST + me->_print(); } void SmsBuffer::_print() { - __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "SmsBuffer content: '%s'", m_buffer.str().c_str()); + __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "SmsBuffer content: '%s'", + m_buffer.str().c_str()); +} + +jstring SmsBuffer::asRawJsonString(JNIEnv *env, jobject self, jlong ptr) +{ + SMSBUFFER_CAST + std::string result; + me->as_raw_json_string(result); + return env->NewStringUTF(result.c_str()); +} + +void SmsBuffer::as_raw_json_string(std::string &result) +{ + std::stringstream ss; + ss << "{\"smsCount\": " << m_sms_count << ", \"smsDatas\": " << m_buffer.str() << "]}"; + result = ss.str(); } \ No newline at end of file diff --git a/src/main/cpp/smsbuffer.h b/src/main/cpp/smsbuffer.h index 9f0a61f..8e36082 100644 --- a/src/main/cpp/smsbuffer.h +++ b/src/main/cpp/smsbuffer.h @@ -24,21 +24,46 @@ class SmsBuffer { public: - SmsBuffer(); + SmsBuffer() = default; + ~SmsBuffer() = default; JNIEXPORT static jlong JNICALL createNativeObject(JNIEnv *env, jobject self); JNIEXPORT static void JNICALL deleteNativeObject(JNIEnv *env, jobject self, jlong ptr); - JNIEXPORT static void JNICALL push(JNIEnv *env, jobject self, jlong ptr, jint mailbox_id); - void _push(int mailbox_id); + /* + * push method + */ + JNIEXPORT static void JNICALL push(JNIEnv *env, jobject self, jlong ptr, jint msg_id, + jint mailbox_id, jint type, jlong date, jstring address, + jstring body, jstring read, jstring seen); + void _push(int msg_id, int mailbox_id, int type, + long date, const char *address, const char *body, const char *read, + const char *seen); + /* + * empty method + */ + + JNIEXPORT static jboolean JNICALL empty(JNIEnv *env, jobject self, jlong ptr); + bool _empty() const; + + /* + * print method + */ JNIEXPORT static void JNICALL print(JNIEnv *env, jobject self, jlong ptr); void _print(); + /* + * asRawJsonString method + */ + JNIEXPORT static jstring JNICALL asRawJsonString(JNIEnv *env, jobject self, jlong ptr); + void as_raw_json_string(std::string &result); + DECL_JNICLASSATTRS private: void reset_buffer(); std::stringstream m_buffer; + uint32_t m_sms_count{0}; bool m_buffer_empty{true}; }; \ No newline at end of file diff --git a/src/main/java/fr/unix_experience/owncloud_sms/activities/MainActivity.java b/src/main/java/fr/unix_experience/owncloud_sms/activities/MainActivity.java index 8141143..0e56003 100644 --- a/src/main/java/fr/unix_experience/owncloud_sms/activities/MainActivity.java +++ b/src/main/java/fr/unix_experience/owncloud_sms/activities/MainActivity.java @@ -44,8 +44,6 @@ import android.view.MenuItem; import android.view.Window; import android.widget.Toast; -import org.json.JSONArray; - import fr.unix_experience.owncloud_sms.R; import fr.unix_experience.owncloud_sms.activities.remote_account.AccountListActivity; import fr.unix_experience.owncloud_sms.engine.ASyncSMSSync.SyncTask; @@ -53,6 +51,7 @@ import fr.unix_experience.owncloud_sms.engine.AndroidSmsFetcher; import fr.unix_experience.owncloud_sms.engine.ConnectivityMonitor; import fr.unix_experience.owncloud_sms.enums.OCSMSNotificationType; import fr.unix_experience.owncloud_sms.enums.PermissionID; +import fr.unix_experience.owncloud_sms.jni.SmsBuffer; import fr.unix_experience.owncloud_sms.notifications.OCSMSNotificationUI; import fr.unix_experience.owncloud_sms.prefs.OCSMSSharedPrefs; import fr.unix_experience.owncloud_sms.prefs.PermissionChecker; @@ -212,10 +211,10 @@ public class MainActivity extends AppCompatActivity } // Now fetch messages since last stored date - JSONArray smsList = new JSONArray(); - new AndroidSmsFetcher(ctx).bufferMessagesSinceDate(smsList, (long) 0); + SmsBuffer smsBuffer = new SmsBuffer(); + new AndroidSmsFetcher(ctx).bufferMessagesSinceDate(smsBuffer, (long) 0); - if (smsList.length() == 0) { + if (smsBuffer.empty()) { Toast.makeText(ctx, ctx.getString(R.string.nothing_to_sync), Toast.LENGTH_SHORT).show(); Log.v(MainActivity.TAG, "Finish syncAllMessages(): no sms"); return; @@ -225,7 +224,7 @@ public class MainActivity extends AppCompatActivity OCSMSNotificationUI.notify(ctx, ctx.getString(R.string.sync_title), ctx.getString(R.string.sync_inprogress), OCSMSNotificationType.SYNC.ordinal()); } - new SyncTask(getApplicationContext(), smsList).execute(); + new SyncTask(getApplicationContext(), smsBuffer).execute(); Log.v(MainActivity.TAG, "Finish syncAllMessages()"); } diff --git a/src/main/java/fr/unix_experience/owncloud_sms/broadcast_receivers/ConnectivityChanged.java b/src/main/java/fr/unix_experience/owncloud_sms/broadcast_receivers/ConnectivityChanged.java index 2a9a703..c5f96ee 100644 --- a/src/main/java/fr/unix_experience/owncloud_sms/broadcast_receivers/ConnectivityChanged.java +++ b/src/main/java/fr/unix_experience/owncloud_sms/broadcast_receivers/ConnectivityChanged.java @@ -25,8 +25,6 @@ import android.content.Context; import android.content.Intent; import android.util.Log; -import org.json.JSONArray; - import java.util.concurrent.atomic.AtomicReference; import fr.unix_experience.owncloud_sms.R; @@ -34,6 +32,7 @@ import fr.unix_experience.owncloud_sms.engine.ASyncSMSSync; import fr.unix_experience.owncloud_sms.engine.AndroidSmsFetcher; import fr.unix_experience.owncloud_sms.engine.ConnectivityMonitor; import fr.unix_experience.owncloud_sms.enums.PermissionID; +import fr.unix_experience.owncloud_sms.jni.SmsBuffer; import fr.unix_experience.owncloud_sms.prefs.OCSMSSharedPrefs; import fr.unix_experience.owncloud_sms.prefs.PermissionChecker; @@ -82,14 +81,14 @@ public class ConnectivityChanged extends BroadcastReceiver implements ASyncSMSSy Log.i(ConnectivityChanged.TAG,"Synced Last:" + lastMessageSynced); // Now fetch messages since last stored date - JSONArray smsList = new JSONArray(); - new AndroidSmsFetcher(context).bufferMessagesSinceDate(smsList, lastMessageSynced); + SmsBuffer smsBuffer = new SmsBuffer(); + new AndroidSmsFetcher(context).bufferMessagesSinceDate(smsBuffer, lastMessageSynced); AtomicReference cMon = new AtomicReference<>(new ConnectivityMonitor(context)); // Synchronize if network is valid and there are SMS - if (cMon.get().isValid() && (smsList.length() > 0)) { - new SyncTask(context, smsList).execute(); + if (cMon.get().isValid() && !smsBuffer.empty()) { + new SyncTask(context, smsBuffer).execute(); } } diff --git a/src/main/java/fr/unix_experience/owncloud_sms/engine/ASyncSMSSync.java b/src/main/java/fr/unix_experience/owncloud_sms/engine/ASyncSMSSync.java index a23011b..75caaef 100644 --- a/src/main/java/fr/unix_experience/owncloud_sms/engine/ASyncSMSSync.java +++ b/src/main/java/fr/unix_experience/owncloud_sms/engine/ASyncSMSSync.java @@ -23,18 +23,17 @@ import android.content.Context; import android.os.AsyncTask; import android.util.Log; -import org.json.JSONArray; - import fr.unix_experience.owncloud_sms.R; import fr.unix_experience.owncloud_sms.enums.OCSMSNotificationType; import fr.unix_experience.owncloud_sms.exceptions.OCSyncException; +import fr.unix_experience.owncloud_sms.jni.SmsBuffer; import fr.unix_experience.owncloud_sms.notifications.OCSMSNotificationUI; public interface ASyncSMSSync { class SyncTask extends AsyncTask { - public SyncTask(Context context, JSONArray smsList) { + public SyncTask(Context context, SmsBuffer smsBuffer) { _context = context; - _smsList = smsList; + _smsBuffer = smsBuffer; } @Override @@ -49,7 +48,7 @@ public interface ASyncSMSSync { for (Account element : myAccountList) { try { OCSMSOwnCloudClient _client = new OCSMSOwnCloudClient(_context, element); - _client.doPushRequest(_smsList); + _client.doPushRequest(_smsBuffer); OCSMSNotificationUI.cancel(_context); } catch (IllegalStateException e) { // Fail to read account data OCSMSNotificationUI.notify(_context, _context.getString(R.string.fatal_error), @@ -66,7 +65,7 @@ public interface ASyncSMSSync { } private final Context _context; - private final JSONArray _smsList; + private final SmsBuffer _smsBuffer; } String TAG = ASyncSMSSync.class.getSimpleName(); diff --git a/src/main/java/fr/unix_experience/owncloud_sms/engine/AndroidSmsFetcher.java b/src/main/java/fr/unix_experience/owncloud_sms/engine/AndroidSmsFetcher.java index 35532f5..1ea40fd 100644 --- a/src/main/java/fr/unix_experience/owncloud_sms/engine/AndroidSmsFetcher.java +++ b/src/main/java/fr/unix_experience/owncloud_sms/engine/AndroidSmsFetcher.java @@ -39,13 +39,13 @@ public class AndroidSmsFetcher { _existingDraftsMessages = null; } - void fetchAllMessages(JSONArray result) { + void fetchAllMessages(SmsBuffer result) { bufferMailboxMessages(result, MailboxID.INBOX); bufferMailboxMessages(result, MailboxID.SENT); bufferMailboxMessages(result, MailboxID.DRAFTS); } - private void readMailBox(Cursor c, JSONArray result, MailboxID mbID) { + private void readMailBox(Cursor c, SmsBuffer smsBuffer, MailboxID mbID) { do { JSONObject entry = new JSONObject(); @@ -56,10 +56,15 @@ public class AndroidSmsFetcher { // Mailbox ID is required by server entry.put("mbox", mbID.ordinal()); - result.put(entry); - SmsBuffer buf = new SmsBuffer(); - buf.push(mbID.ordinal()); - buf.print(); + + smsBuffer.push(entry.getInt("_id"), + mbID.ordinal(), + entry.getInt("type"), + entry.getLong("date"), + entry.getString("address"), + entry.getString("body"), + entry.getString("read"), + entry.getString("seen")); } catch (JSONException e) { Log.e(AndroidSmsFetcher.TAG, "JSON Exception when reading SMS Mailbox", e); @@ -68,7 +73,7 @@ public class AndroidSmsFetcher { while (c.moveToNext()); } - private void bufferMailboxMessages(JSONArray result, MailboxID mbID) { + private void bufferMailboxMessages(SmsBuffer smsBuffer, MailboxID mbID) { if ((_context == null)) { return; } @@ -88,14 +93,14 @@ public class AndroidSmsFetcher { } // Reading mailbox - readMailBox(c, result, mbID); + readMailBox(c, smsBuffer, mbID); Log.i(AndroidSmsFetcher.TAG, c.getCount() + " messages read from " + mbID.getURI()); c.close(); } // Used by Content Observer - public JSONArray getLastMessage(MailboxID mbID) { + public SmsBuffer getLastMessage(MailboxID mbID) { if ((_context == null)) { return null; } @@ -107,8 +112,8 @@ public class AndroidSmsFetcher { } // We create a list of strings to store results - JSONArray results = new JSONArray(); JSONObject entry = new JSONObject(); + SmsBuffer results = new SmsBuffer(); try { Integer mboxId = -1; @@ -126,7 +131,14 @@ public class AndroidSmsFetcher { */ entry.put("mbox", (mboxId - 1)); - results.put(entry); + results.push(entry.getInt("_id"), + mbID.ordinal(), + entry.getInt("type"), + entry.getLong("date"), + entry.getString("address"), + entry.getString("body"), + entry.getString("read"), + entry.getString("seen")); } catch (JSONException e) { Log.e(AndroidSmsFetcher.TAG, "JSON Exception when reading SMS Mailbox", e); } @@ -137,14 +149,14 @@ public class AndroidSmsFetcher { } // Used by ConnectivityChanged Event - public void bufferMessagesSinceDate(JSONArray result, Long sinceDate) { - bufferMessagesSinceDate(result, MailboxID.INBOX, sinceDate); - bufferMessagesSinceDate(result, MailboxID.SENT, sinceDate); - bufferMessagesSinceDate(result, MailboxID.DRAFTS, sinceDate); + public void bufferMessagesSinceDate(SmsBuffer smsBuffer, Long sinceDate) { + bufferMessagesSinceDate(smsBuffer, MailboxID.INBOX, sinceDate); + bufferMessagesSinceDate(smsBuffer, MailboxID.SENT, sinceDate); + bufferMessagesSinceDate(smsBuffer, MailboxID.DRAFTS, sinceDate); } // Used by ConnectivityChanged Event - private void bufferMessagesSinceDate(JSONArray result, MailboxID mbID, Long sinceDate) { + private void bufferMessagesSinceDate(SmsBuffer smsBuffer, MailboxID mbID, Long sinceDate) { Log.i(AndroidSmsFetcher.TAG, "bufferMessagesSinceDate for " + mbID.toString() + " sinceDate " + sinceDate.toString()); if ((_context == null)) { return; @@ -159,7 +171,7 @@ public class AndroidSmsFetcher { } // Read Mailbox - readMailBox(c, result, mbID); + readMailBox(c, smsBuffer, mbID); Log.i(AndroidSmsFetcher.TAG, c.getCount() + " messages read from " + mbID.getURI()); c.close(); @@ -191,7 +203,7 @@ public class AndroidSmsFetcher { if (tmpDate > _lastMsgDate) { _lastMsgDate = tmpDate; } - entry.put(colName, c.getString(idx)); + entry.put(colName, c.getLong(idx)); break; default: entry.put(colName, c.getString(idx)); diff --git a/src/main/java/fr/unix_experience/owncloud_sms/engine/OCSMSOwnCloudClient.java b/src/main/java/fr/unix_experience/owncloud_sms/engine/OCSMSOwnCloudClient.java index 374d1d9..62d5d65 100644 --- a/src/main/java/fr/unix_experience/owncloud_sms/engine/OCSMSOwnCloudClient.java +++ b/src/main/java/fr/unix_experience/owncloud_sms/engine/OCSMSOwnCloudClient.java @@ -38,6 +38,7 @@ import java.net.ConnectException; import fr.unix_experience.owncloud_sms.R; import fr.unix_experience.owncloud_sms.enums.OCSyncErrorType; import fr.unix_experience.owncloud_sms.exceptions.OCSyncException; +import fr.unix_experience.owncloud_sms.jni.SmsBuffer; import fr.unix_experience.owncloud_sms.prefs.OCSMSSharedPrefs; @SuppressWarnings("deprecation") @@ -94,17 +95,17 @@ public class OCSMSOwnCloudClient { } } - public void doPushRequest(JSONArray smsList) throws OCSyncException { + public void doPushRequest(SmsBuffer smsBuffer) throws OCSyncException { /* * If we need other API push, set it here */ switch (_serverAPIVersion) { case 1: - default: doPushRequestV1(smsList); break; + default: doPushRequestV1(smsBuffer); break; } } - private AndroidSmsFetcher collectMessages(JSONArray smsList) throws OCSyncException { + private AndroidSmsFetcher collectMessages(SmsBuffer smsBuffer) throws OCSyncException { JSONObject smsBoxes = new JSONObject(); JSONArray inboxSmsList = null, sentSmsList = null, draftsSmsList = null; try { @@ -141,33 +142,33 @@ public class OCSMSOwnCloudClient { fetcher.setExistingSentMessages(sentSmsList); fetcher.setExistingDraftsMessages(draftsSmsList); - fetcher.fetchAllMessages(smsList); + fetcher.fetchAllMessages(smsBuffer); return fetcher; } - private void doPushRequestV1(JSONArray smsList) throws OCSyncException { + private void doPushRequestV1(SmsBuffer smsBuffer) throws OCSyncException { // We need to save this date as a step for connectivity change Long lastMsgDate = (long) 0; - if (smsList == null) { + if (smsBuffer == null) { doHttpRequest(_http.getAllSmsIds()); if (_jsonQueryBuffer == null) { return; } // Create new JSONArray to get results - smsList = new JSONArray(); + smsBuffer = new SmsBuffer(); // Get maximum message date present in smsList to keep a step when connectivity changes - lastMsgDate = collectMessages(smsList).getLastMessageDate(); + lastMsgDate = collectMessages(smsBuffer).getLastMessageDate(); } - if (smsList.length() == 0) { + if (smsBuffer.empty()) { Log.i(OCSMSOwnCloudClient.TAG, "No new SMS to sync, sync done"); return; } - PostMethod post = createPushRequest(smsList); + PostMethod post = createPushRequest(smsBuffer); if (post == null) { Log.e(OCSMSOwnCloudClient.TAG,"Push request for POST is null"); throw new OCSyncException(R.string.err_sync_craft_http_request, OCSyncErrorType.IO); @@ -196,44 +197,15 @@ public class OCSMSOwnCloudClient { Log.i(OCSMSOwnCloudClient.TAG, "SMS Push request said: status " + pushStatus + " - " + pushMessage); } - private PostMethod createPushRequest(JSONArray smsList) throws OCSyncException { - JSONObject obj = createPushJSONObject(smsList); - if (obj == null) { - return null; - } - - StringRequestEntity ent = createJSONRequestEntity(obj); - if (ent == null) { - return null; - } - - return _http.pushSms(ent); + private PostMethod createPushRequest(SmsBuffer smsBuffer) throws OCSyncException { + return _http.pushSms(createJSONRequestEntity(smsBuffer)); } - private JSONObject createPushJSONObject(JSONArray smsList) throws OCSyncException { - if (smsList == null) { - Log.e(OCSMSOwnCloudClient.TAG,"NULL SMS List"); - throw new OCSyncException(R.string.err_sync_create_json_null_smslist, OCSyncErrorType.IO); - } - - JSONObject reqJSON = new JSONObject(); - - try { - reqJSON.put("smsDatas", smsList); - reqJSON.put("smsCount", smsList.length()); - } catch (JSONException e) { - Log.e(OCSMSOwnCloudClient.TAG,"JSON Exception when creating JSON request object"); - throw new OCSyncException(R.string.err_sync_create_json_put_smslist, OCSyncErrorType.PARSE); - } - - return reqJSON; - } - - private StringRequestEntity createJSONRequestEntity(JSONObject obj) throws OCSyncException { + private StringRequestEntity createJSONRequestEntity(SmsBuffer smsBuffer) throws OCSyncException { StringRequestEntity requestEntity; try { requestEntity = new StringRequestEntity( - obj.toString(), + smsBuffer.asRawJsonString(), "application/json", "UTF-8"); diff --git a/src/main/java/fr/unix_experience/owncloud_sms/jni/SmsBuffer.java b/src/main/java/fr/unix_experience/owncloud_sms/jni/SmsBuffer.java index 86a00ec..65452ae 100644 --- a/src/main/java/fr/unix_experience/owncloud_sms/jni/SmsBuffer.java +++ b/src/main/java/fr/unix_experience/owncloud_sms/jni/SmsBuffer.java @@ -37,13 +37,39 @@ public class SmsBuffer { private static native long createNativeObject(); private static native void deleteNativeObject(long handle); - public static native void push(long handle, int mbid); - public void push(int mbid) { - SmsBuffer.push(mHandle, mbid); + /* + JNI: push method + */ + public static native void push(long handle, int id, int mbid, int type, long date, + String address, String body, String read, String seen); + + public void push(int id, int mbid, int type, long date, String address, String body, + String read, String seen) { + SmsBuffer.push(mHandle, id, mbid, type, date, address, body, read, seen); } + /* + JNI: Eepty method + */ + public static native boolean empty(long handle); + + public boolean empty() { + return SmsBuffer.empty(mHandle); + } + + /* + JNI: print method + */ public static native void print(long handle); public void print() { SmsBuffer.print(mHandle); } + + /* + JNI: asRawJsonString method + */ + public static native String asRawJsonString(long handle); + public String asRawJsonString() { + return SmsBuffer.asRawJsonString(mHandle); + } } diff --git a/src/main/java/fr/unix_experience/owncloud_sms/observers/SmsObserver.java b/src/main/java/fr/unix_experience/owncloud_sms/observers/SmsObserver.java index 4dc1619..7973161 100644 --- a/src/main/java/fr/unix_experience/owncloud_sms/observers/SmsObserver.java +++ b/src/main/java/fr/unix_experience/owncloud_sms/observers/SmsObserver.java @@ -25,8 +25,6 @@ import android.database.ContentObserver; import android.os.Handler; import android.util.Log; -import org.json.JSONArray; - import fr.unix_experience.owncloud_sms.R; import fr.unix_experience.owncloud_sms.engine.ASyncSMSSync; import fr.unix_experience.owncloud_sms.engine.AndroidSmsFetcher; @@ -34,6 +32,7 @@ import fr.unix_experience.owncloud_sms.engine.ConnectivityMonitor; import fr.unix_experience.owncloud_sms.engine.OCSMSOwnCloudClient; import fr.unix_experience.owncloud_sms.enums.MailboxID; import fr.unix_experience.owncloud_sms.enums.PermissionID; +import fr.unix_experience.owncloud_sms.jni.SmsBuffer; import fr.unix_experience.owncloud_sms.prefs.PermissionChecker; public class SmsObserver extends ContentObserver implements ASyncSMSSync { @@ -60,7 +59,7 @@ public class SmsObserver extends ContentObserver implements ASyncSMSSync { } AndroidSmsFetcher fetcher = new AndroidSmsFetcher(_context); - JSONArray smsList = fetcher.getLastMessage(MailboxID.ALL); + SmsBuffer smsList = fetcher.getLastMessage(MailboxID.ALL); ConnectivityMonitor cMon = new ConnectivityMonitor(_context); diff --git a/src/main/java/fr/unix_experience/owncloud_sms/providers/SmsDataProvider.java b/src/main/java/fr/unix_experience/owncloud_sms/providers/SmsDataProvider.java index dffd6b2..92abd13 100644 --- a/src/main/java/fr/unix_experience/owncloud_sms/providers/SmsDataProvider.java +++ b/src/main/java/fr/unix_experience/owncloud_sms/providers/SmsDataProvider.java @@ -29,15 +29,15 @@ import fr.unix_experience.owncloud_sms.enums.MailboxID; import fr.unix_experience.owncloud_sms.prefs.OCSMSSharedPrefs; public class SmsDataProvider extends ContentProvider { - static String messageFields[] = { - "read", - "date", - "address", - "seen", - "body", - "_id", - "type", - //"length(address)" // For debug purposes + static String[] messageFields = { + "read", + "date", + "address", + "seen", + "body", + "_id", + "type", + //"length(address)" // For debug purposes }; // WARNING: mandatory @@ -54,7 +54,7 @@ public class SmsDataProvider extends ContentProvider { public Cursor query(String mailBox) { return query(Uri.parse(mailBox), - new String[] { "read", "date", "address", "seen", "body", "_id", "type", }, + SmsDataProvider.messageFields, null, null, null ); }