diff --git a/src/main/cpp/smsbuffer.cpp b/src/main/cpp/smsbuffer.cpp index 1792ee8..edf9434 100644 --- a/src/main/cpp/smsbuffer.cpp +++ b/src/main/cpp/smsbuffer.cpp @@ -31,6 +31,7 @@ JNINativeMethod SmsBuffer::methods[] = DECL_JNIMETHOD(deleteNativeObject, "()V") DECL_JNIMETHOD(empty, "()Z") DECL_JNIMETHOD(asRawJsonString, "()Ljava/lang/String;") + DECL_JNIMETHOD(getLastMessageDate, "()J") DECL_JNIMETHOD(push, "(IIIJLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V") DECL_JNIMETHOD(print, "()V") @@ -69,6 +70,7 @@ void SmsBuffer::reset_buffer() m_buffer.clear(); m_buffer_empty = true; m_sms_count = 0; + m_last_message_date = 0; } void SmsBuffer::push(JNIEnv *env, jobject self, jint msg_id, jint mailbox_id, jint type, @@ -94,15 +96,19 @@ void SmsBuffer::_push(int msg_id, int mailbox_id, int type, 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_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) << "}"; + + if (date > m_last_message_date) { + m_last_message_date = date; + } m_sms_count++; } @@ -142,4 +148,15 @@ void SmsBuffer::as_raw_json_string(std::string &result) std::stringstream ss; ss << "{\"smsCount\": " << m_sms_count << ", \"smsDatas\": " << m_buffer.str() << "]}"; result = ss.str(); +} + +jlong SmsBuffer::getLastMessageDate(JNIEnv *env, jobject self) +{ + SMSBUFFER_CAST + return me->_get_last_message_date(); +} + +long long SmsBuffer::_get_last_message_date() const +{ + return m_last_message_date; } \ No newline at end of file diff --git a/src/main/cpp/smsbuffer.h b/src/main/cpp/smsbuffer.h index 1fd866c..1d8ef56 100644 --- a/src/main/cpp/smsbuffer.h +++ b/src/main/cpp/smsbuffer.h @@ -59,6 +59,13 @@ public: JNIEXPORT static jstring JNICALL asRawJsonString(JNIEnv *env, jobject self); void as_raw_json_string(std::string &result); + /* + * getLastMessageDate method + */ + + JNIEXPORT static jlong JNICALL getLastMessageDate(JNIEnv *env, jobject self); + long long _get_last_message_date() const; + DECL_JNICLASSATTRS private: @@ -66,6 +73,7 @@ private: std::stringstream m_buffer; uint32_t m_sms_count{0}; bool m_buffer_empty{true}; + long long m_last_message_date{0}; static bool gJava_inited; static jfieldID gJava_mHandle; 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 0e56003..ebfb8c8 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 @@ -47,13 +47,8 @@ import android.widget.Toast; 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; -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; import static fr.unix_experience.owncloud_sms.enums.PermissionID.REQUEST_MAX; @@ -210,21 +205,7 @@ public class MainActivity extends AppCompatActivity return; } - // Now fetch messages since last stored date - SmsBuffer smsBuffer = new SmsBuffer(); - new AndroidSmsFetcher(ctx).bufferMessagesSinceDate(smsBuffer, (long) 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; - } - - if (new OCSMSSharedPrefs(this).showSyncNotifications()) { - OCSMSNotificationUI.notify(ctx, ctx.getString(R.string.sync_title), - ctx.getString(R.string.sync_inprogress), OCSMSNotificationType.SYNC.ordinal()); - } - new SyncTask(getApplicationContext(), smsBuffer).execute(); + new SyncTask(getApplicationContext()).execute(); Log.v(MainActivity.TAG, "Finish syncAllMessages()"); } 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 60a6b9a..c1c546d 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 @@ -22,24 +22,72 @@ import android.accounts.AccountManager; import android.content.Context; import android.os.AsyncTask; import android.util.Log; +import android.widget.Toast; 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; +import fr.unix_experience.owncloud_sms.prefs.OCSMSSharedPrefs; public interface ASyncSMSSync { class SyncTask extends AsyncTask { - public SyncTask(Context context, SmsBuffer smsBuffer) { + public SyncTask(Context context) { _context = context; - _smsBuffer = smsBuffer; + _smsBuffer = null; + } + + public SyncTask(Context context, SmsBuffer buffer) { + _context = context; + _smsBuffer = buffer; } @Override protected Void doInBackground(Void... params) { Log.i(ASyncSMSSync.TAG, "Starting background sync"); + // If no smsBuffer given it's a full sync + if (_smsBuffer == null) { + doFullSync(); + } + else { + performSync(_smsBuffer); + } + + Log.i(ASyncSMSSync.TAG, "Stopping background sync"); + return null; + } + + private void doFullSync() { + OCSMSSharedPrefs prefs = new OCSMSSharedPrefs(_context); + long syncStartupDate = prefs.getLastMessageDate(); + + Log.i(ASyncSMSSync.TAG, "Current message date is " + syncStartupDate); + boolean shouldSync = true; + AndroidSmsFetcher fetcher = new AndroidSmsFetcher(_context); + while (shouldSync) { + SmsBuffer smsBuffer = new SmsBuffer(); + fetcher.bufferMessagesSinceDate(smsBuffer, syncStartupDate); + if (smsBuffer.empty()) { + Toast.makeText(_context, _context.getString(R.string.nothing_to_sync), Toast.LENGTH_SHORT).show(); + Log.i(ASyncSMSSync.TAG, "Finish syncAllMessages(): no more sms"); + smsBuffer.clear(); + shouldSync = false; + continue; + } + + if (prefs.showSyncNotifications()) { + OCSMSNotificationUI.notify(_context, _context.getString(R.string.sync_title), + _context.getString(R.string.sync_inprogress), OCSMSNotificationType.SYNC.ordinal()); + } + + syncStartupDate = smsBuffer.getLastMessageDate(); + performSync(smsBuffer); + } + } + + private void performSync(SmsBuffer smsBuffer) { // Get ownCloud SMS account list AccountManager _accountMgr = AccountManager.get(_context); Account[] myAccountList = _accountMgr.getAccountsByType(_context.getString(R.string.account_type)); @@ -48,25 +96,23 @@ public interface ASyncSMSSync { for (Account element : myAccountList) { try { OCSMSOwnCloudClient _client = new OCSMSOwnCloudClient(_context, element); - _client.doPushRequest(_smsBuffer); + _client.doPushRequest(smsBuffer); OCSMSNotificationUI.cancel(_context); } catch (IllegalStateException e) { // Fail to read account data OCSMSNotificationUI.notify(_context, _context.getString(R.string.fatal_error), e.getMessage(), OCSMSNotificationType.SYNC_FAILED.ordinal()); } catch (OCSyncException e) { Log.e(ASyncSMSSync.TAG, _context.getString(e.getErrorId())); - OCSMSNotificationUI.notify(_context, _context.getString(R.string.fatal_error), - e.getMessage(), OCSMSNotificationType.SYNC_FAILED.ordinal()); + OCSMSNotificationUI.notify(_context, _context.getString(R.string.fatal_error), + e.getMessage(), OCSMSNotificationType.SYNC_FAILED.ordinal()); } } - OCSMSNotificationUI.cancel(_context); - _smsBuffer.clear(); - Log.i(ASyncSMSSync.TAG, "Stopping background sync"); - return null; + OCSMSNotificationUI.cancel(_context); + smsBuffer.clear(); } - private final Context _context; private final SmsBuffer _smsBuffer; + private final Context _context; } 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 2e93ed1..2e55775 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 @@ -30,7 +30,6 @@ import fr.unix_experience.owncloud_sms.providers.SmsDataProvider; public class AndroidSmsFetcher { public AndroidSmsFetcher(Context ct) { - _lastMsgDate = (long) 0; _context = ct; _existingInboxMessages = null; @@ -174,11 +173,6 @@ public class AndroidSmsFetcher { entry.seen = (c.getInt(idx) > 0); break; case "date": - // Special case for date, we need to record last without searching - Long tmpDate = c.getLong(idx); - if (tmpDate > _lastMsgDate) { - _lastMsgDate = tmpDate; - } entry.date = c.getLong(idx); break; case "address": @@ -237,16 +231,10 @@ public class AndroidSmsFetcher { _existingDraftsMessages = draftMessages; } - Long getLastMessageDate() { - return _lastMsgDate; - } - private final Context _context; private JSONArray _existingInboxMessages; private JSONArray _existingSentMessages; private JSONArray _existingDraftsMessages; - private Long _lastMsgDate; - private static final String TAG = AndroidSmsFetcher.class.getSimpleName(); } 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 2fb7a4b..bbdc38e 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 @@ -148,9 +148,6 @@ public class OCSMSOwnCloudClient { } private void doPushRequestV1(SmsBuffer smsBuffer) throws OCSyncException { - // We need to save this date as a step for connectivity change - Long lastMsgDate = (long) 0; - if (smsBuffer == null) { doHttpRequest(_http.getAllSmsIds()); if (_jsonQueryBuffer == null) { @@ -159,8 +156,6 @@ public class OCSMSOwnCloudClient { // Create new JSONArray to get results smsBuffer = new SmsBuffer(); - // Get maximum message date present in smsList to keep a step when connectivity changes - lastMsgDate = collectMessages(smsBuffer).getLastMessageDate(); } if (smsBuffer.empty()) { @@ -193,9 +188,10 @@ public class OCSMSOwnCloudClient { } // Push was OK, we can save the lastMessageDate which was saved to server - (new OCSMSSharedPrefs(_context)).setLastMessageDate(lastMsgDate); + (new OCSMSSharedPrefs(_context)).setLastMessageDate(smsBuffer.getLastMessageDate()); Log.i(OCSMSOwnCloudClient.TAG, "SMS Push request said: status " + pushStatus + " - " + pushMessage); + Log.i(OCSMSOwnCloudClient.TAG, "LastMessageDate set to: " + smsBuffer.getLastMessageDate()); } private PostMethod createPushRequest(SmsBuffer smsBuffer) throws OCSyncException { 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 ebceffe..e52102d 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 @@ -45,6 +45,7 @@ public class SmsBuffer { public native boolean empty(); public native void print(); public native String asRawJsonString(); + public native long getLastMessageDate(); public void push(MailboxID mbid, SmsEntry smsEntry) { push(smsEntry.id, @@ -65,6 +66,4 @@ public class SmsBuffer { deleteNativeObject(); mHandle = 0; } - - } 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 7973161..628a00d 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 @@ -59,13 +59,13 @@ public class SmsObserver extends ContentObserver implements ASyncSMSSync { } AndroidSmsFetcher fetcher = new AndroidSmsFetcher(_context); - SmsBuffer smsList = fetcher.getLastMessage(MailboxID.ALL); + SmsBuffer smsBuffer = fetcher.getLastMessage(MailboxID.ALL); ConnectivityMonitor cMon = new ConnectivityMonitor(_context); // Synchronize if network is valid and there are SMS - if (cMon.isValid() && (smsList != null)) { - new SyncTask(_context, smsList).execute(); + if (cMon.isValid() && (smsBuffer != null)) { + new SyncTask(_context, smsBuffer).execute(); } } 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 92abd13..5ff733d 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 @@ -73,7 +73,7 @@ public class SmsDataProvider extends ContentProvider { public Cursor queryMessagesSinceDate(String mailBox, Long sinceDate) { return query(Uri.parse(mailBox), SmsDataProvider.messageFields, - "date > ?", new String[] { sinceDate.toString() }, null + "date > ?", new String[] { sinceDate.toString() }, "date ASC" ); }