mirror of
https://github.com/nerzhul/ownCloud-SMS-App.git
synced 2025-06-05 23:16:27 +00:00
Replace C++ with Cmake with GoLang gomobile
* Add ncsmsgo.arr which is the GoLang gomobile part See: https://gitlab.com/nerzhul/ncsmsgo * Android-NDK is not needed anymore * Android app getVersion() now uses the Golang part * Use the next getLastHTTPStatus() call in getVersion() * Android app pushSms() now uses the Golang part * JNI SmsBuffer has been replaced with GoLang aar bindings -> This permits to remove some java code & increase performance * Prepare a insecure switch flag to the Golang client
This commit is contained in:
parent
5317dc4fd9
commit
d57810b5d8
10
.travis.yml
10
.travis.yml
@ -11,6 +11,9 @@ cache:
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
|
||||
before_install:
|
||||
- yes | sdkmanager "platforms;android-27"
|
||||
|
||||
android:
|
||||
components:
|
||||
- tools
|
||||
@ -23,10 +26,3 @@ android:
|
||||
- 'google-gdk-license-.+'
|
||||
- 'android-sdk-preview-license-.+'
|
||||
- 'android-.*'
|
||||
|
||||
before_install:
|
||||
- wget https://dl.google.com/android/repository/android-ndk-r16-linux-x86_64.zip > /dev/null
|
||||
- mkdir -p /usr/local/android-sdk/ndk-bundle
|
||||
- unzip android-ndk-r16-linux-x86_64.zip -d /usr/local/android-sdk/ndk-bundle > /dev/null
|
||||
- export ANDROID_NDK_HOME="/usr/local/android-sdk/ndk-bundle/android-ndk-r16"
|
||||
- rm -Rf "${ANDROID_HOME}/cmake"
|
@ -1,14 +0,0 @@
|
||||
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
|
||||
)
|
||||
|
||||
find_library(LOGGING_LIBRARY log)
|
||||
|
||||
add_library(nativesms SHARED ${SRC_FILES})
|
||||
|
||||
target_link_libraries(nativesms ${LOGGING_LIBRARY})
|
@ -2,6 +2,7 @@ buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
jcenter()
|
||||
google()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.0.1'
|
||||
@ -47,11 +48,6 @@ android {
|
||||
packagingOptions {
|
||||
exclude 'META-INF/LICENSE.txt'
|
||||
}
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
path 'CMakeLists.txt'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
@ -69,4 +65,5 @@ dependencies {
|
||||
compile 'in.srain.cube:ultra-ptr:1.0.11'
|
||||
compile 'com.github.dmytrodanylyk.android-process-button:library:1.0.4'
|
||||
compile 'com.android.support:support-v4:27.0.2'
|
||||
implementation project(':ncsmsgo')
|
||||
}
|
||||
|
2
ncsmsgo/build.gradle
Normal file
2
ncsmsgo/build.gradle
Normal file
@ -0,0 +1,2 @@
|
||||
configurations.maybeCreate("default")
|
||||
artifacts.add("default", file('ncsmsgo.aar'))
|
BIN
ncsmsgo/ncsmsgo.aar
Normal file
BIN
ncsmsgo/ncsmsgo.aar
Normal file
Binary file not shown.
25
ncsmsgo/ncsmsgo.iml
Normal file
25
ncsmsgo/ncsmsgo.iml
Normal file
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module external.linked.project.id=":ncsmsgo" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="android-gradle" name="Android-Gradle">
|
||||
<configuration>
|
||||
<option name="GRADLE_PROJECT_PATH" value=":ncsmsgo" />
|
||||
</configuration>
|
||||
</facet>
|
||||
<facet type="java-gradle" name="Java-Gradle">
|
||||
<configuration>
|
||||
<option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
|
||||
<option name="BUILDABLE" value="false" />
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
1
settings.gradle
Normal file
1
settings.gradle
Normal file
@ -0,0 +1 @@
|
||||
include ':ncsmsgo'
|
@ -1,56 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2017, Loic Blot <loic.blot@unix-experience.fr>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "httpclient.h"
|
||||
|
||||
const char *HTTPClient::classPathName = "fr/unix_experience/owncloud_sms/engine/OCHttpClient";
|
||||
|
||||
// See https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/types.html
|
||||
JNINativeMethod HTTPClient::methods[] =
|
||||
{
|
||||
DECL_JNIMETHOD(getAllSmsIdsCall, "()Ljava/lang/String;")
|
||||
DECL_JNIMETHOD(getLastMsgTimestamp, "()Ljava/lang/String;")
|
||||
DECL_JNIMETHOD(getPushRoute, "()Ljava/lang/String;")
|
||||
DECL_JNIMETHOD(getVersionCall, "()Ljava/lang/String;")
|
||||
};
|
||||
DECL_METHODSIZE(HTTPClient)
|
||||
|
||||
// APIv1 calls
|
||||
#define RCALL_GET_VERSION "/index.php/apps/ocsms/get/apiversion?format=json"
|
||||
#define RCALL_GET_ALL_SMS_IDS "/index.php/apps/ocsms/get/smsidlist?format=json"
|
||||
#define RCALL_GET_LAST_MSG_TIMESTAMP "/index.php/apps/ocsms/get/lastmsgtime?format=json"
|
||||
#define RCALL_PUSH_ROUTE "/index.php/apps/ocsms/push?format=json"
|
||||
|
||||
jstring HTTPClient::getVersionCall(JNIEnv *env, jobject)
|
||||
{
|
||||
return env->NewStringUTF(RCALL_GET_VERSION);
|
||||
}
|
||||
|
||||
jstring HTTPClient::getAllSmsIdsCall(JNIEnv *env, jobject)
|
||||
{
|
||||
return env->NewStringUTF(RCALL_GET_ALL_SMS_IDS);
|
||||
}
|
||||
|
||||
jstring HTTPClient::getLastMsgTimestamp(JNIEnv *env, jobject)
|
||||
{
|
||||
return env->NewStringUTF(RCALL_GET_LAST_MSG_TIMESTAMP);
|
||||
}
|
||||
|
||||
jstring HTTPClient::getPushRoute(JNIEnv *env, jobject)
|
||||
{
|
||||
return env->NewStringUTF(RCALL_PUSH_ROUTE);
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2017, Loic Blot <loic.blot@unix-experience.fr>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <jni.h>
|
||||
#include "macro_helpers.h"
|
||||
|
||||
class HTTPClient
|
||||
{
|
||||
public:
|
||||
JNIEXPORT static jstring JNICALL getVersionCall(JNIEnv *env, jobject);
|
||||
JNIEXPORT static jstring JNICALL getAllSmsIdsCall(JNIEnv *env, jobject);
|
||||
JNIEXPORT static jstring JNICALL getLastMsgTimestamp(JNIEnv *env, jobject);
|
||||
JNIEXPORT static jstring JNICALL getPushRoute(JNIEnv *env, jobject);
|
||||
|
||||
DECL_JNICLASSATTRS
|
||||
};
|
||||
|
||||
|
@ -1,73 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2017, Loic Blot <loic.blot@unix-experience.fr>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "json.h"
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
|
||||
namespace json {
|
||||
|
||||
std::string escape_string(const char *str)
|
||||
{
|
||||
if (!str) {
|
||||
return "";
|
||||
}
|
||||
|
||||
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<int>(*c);
|
||||
result += oss.str();
|
||||
} else {
|
||||
result += *c;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
result += "\"";
|
||||
return result;
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2017, Loic Blot <loic.blot@unix-experience.fr>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace json {
|
||||
|
||||
static inline bool is_control_character(char ch)
|
||||
{ return ch > 0 && ch <= 0x1F; }
|
||||
|
||||
std::string escape_string(const char *str);
|
||||
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2017, Loic Blot <loic.blot@unix-experience.fr>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define DECL_JNIMETHOD(name, type) \
|
||||
{#name, type, (void*) &name },
|
||||
|
||||
#define DECL_METHODSIZE(T) \
|
||||
int T::methods_size = sizeof(T::methods) / sizeof(T::methods[0]);
|
||||
|
||||
#define DECL_JNICLASSATTRS \
|
||||
static const char *classPathName; \
|
||||
static JNINativeMethod methods[]; \
|
||||
static int methods_size;
|
@ -1,76 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2014-2017, Loic Blot <loic.blot@unix-experience.fr>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <jni.h>
|
||||
#include <android/log.h>
|
||||
#include "httpclient.h"
|
||||
#include "smsbuffer.h"
|
||||
|
||||
#define LOG_TAG "nativesms.cpp"
|
||||
|
||||
/*
|
||||
* Register several native methods for one class.
|
||||
*/
|
||||
static int registerNativeMethods(JNIEnv* env, const char* className,
|
||||
JNINativeMethod* gMethods, int numMethods)
|
||||
{
|
||||
jclass clazz;
|
||||
clazz = env->FindClass(className);
|
||||
__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "Registering class '%s'", className);
|
||||
if (clazz == NULL) {
|
||||
__android_log_print(ANDROID_LOG_FATAL, LOG_TAG, "Native registration unable to find class %s", className);
|
||||
return JNI_FALSE;
|
||||
}
|
||||
if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "RegisterNatives failed for %s", className);
|
||||
return JNI_FALSE;
|
||||
}
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
static int registerNatives(JNIEnv* env)
|
||||
{
|
||||
if (!registerNativeMethods(env,
|
||||
HTTPClient::classPathName,
|
||||
HTTPClient::methods,
|
||||
HTTPClient::methods_size)) {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
if (!registerNativeMethods(env,
|
||||
SmsBuffer::classPathName,
|
||||
SmsBuffer::methods,
|
||||
SmsBuffer::methods_size)) {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
jint JNI_OnLoad(JavaVM* vm, void* reserved)
|
||||
{
|
||||
__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "NativeSMS library loading...");
|
||||
JNIEnv* env;
|
||||
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
registerNatives(env);
|
||||
|
||||
__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "NativeSMS library loaded.");
|
||||
return JNI_VERSION_1_6;
|
||||
}
|
@ -1,162 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2017, Loic Blot <loic.blot@unix-experience.fr>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <android/log.h>
|
||||
#include <cassert>
|
||||
#include <iomanip>
|
||||
#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, "()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")
|
||||
};
|
||||
DECL_METHODSIZE(SmsBuffer)
|
||||
|
||||
#define SMSBUFFER_CAST \
|
||||
if (!SmsBuffer::gJava_inited) { \
|
||||
SmsBuffer::gJava_inited = true; \
|
||||
SmsBuffer::gJava_mHandle = env->GetFieldID(env->GetObjectClass(self), "mHandle", "J"); \
|
||||
} \
|
||||
long ptr = env->GetLongField(self, SmsBuffer::gJava_mHandle); \
|
||||
SmsBuffer *me = reinterpret_cast<SmsBuffer *>(ptr); \
|
||||
if (!me) { \
|
||||
__android_log_print(ANDROID_LOG_FATAL, LOG_TAG, "It's not a SmsBuffer!"); \
|
||||
assert(false); \
|
||||
}
|
||||
|
||||
bool SmsBuffer::gJava_inited = false;
|
||||
jfieldID SmsBuffer::gJava_mHandle{};
|
||||
|
||||
jlong SmsBuffer::createNativeObject(JNIEnv *env, jobject self)
|
||||
{
|
||||
return reinterpret_cast<jlong>(new SmsBuffer());
|
||||
}
|
||||
|
||||
void SmsBuffer::deleteNativeObject(JNIEnv *env, jobject self)
|
||||
{
|
||||
SMSBUFFER_CAST
|
||||
__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "deleteNativeObject 0x%li", ptr);
|
||||
delete reinterpret_cast<SmsBuffer *>(ptr);
|
||||
}
|
||||
|
||||
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,
|
||||
jlong date, jstring address, jstring body, jstring read, jstring seen)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
void SmsBuffer::_push(int msg_id, int mailbox_id, int type,
|
||||
long 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)
|
||||
<< "}";
|
||||
|
||||
if (date > m_last_message_date) {
|
||||
m_last_message_date = date;
|
||||
}
|
||||
m_sms_count++;
|
||||
}
|
||||
|
||||
jboolean SmsBuffer::empty(JNIEnv *env, jobject self)
|
||||
{
|
||||
SMSBUFFER_CAST
|
||||
return (jboolean) (me->_empty() ? 1 : 0);
|
||||
}
|
||||
|
||||
bool SmsBuffer::_empty() const
|
||||
{
|
||||
return m_buffer_empty;
|
||||
}
|
||||
|
||||
void SmsBuffer::print(JNIEnv *env, jobject self)
|
||||
{
|
||||
SMSBUFFER_CAST
|
||||
me->_print();
|
||||
}
|
||||
|
||||
void SmsBuffer::_print()
|
||||
{
|
||||
__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "SmsBuffer content: '%s'",
|
||||
m_buffer.str().c_str());
|
||||
}
|
||||
|
||||
jstring SmsBuffer::asRawJsonString(JNIEnv *env, jobject self)
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2017, Loic Blot <loic.blot@unix-experience.fr>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <jni.h>
|
||||
#include <sstream>
|
||||
#include "macro_helpers.h"
|
||||
|
||||
class SmsBuffer
|
||||
{
|
||||
public:
|
||||
SmsBuffer() = default;
|
||||
~SmsBuffer() = default;
|
||||
|
||||
JNIEXPORT static jlong JNICALL createNativeObject(JNIEnv *env, jobject self);
|
||||
JNIEXPORT static void JNICALL deleteNativeObject(JNIEnv *env, jobject self);
|
||||
|
||||
/*
|
||||
* push method
|
||||
*/
|
||||
JNIEXPORT static void JNICALL push(JNIEnv *env, jobject self, 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 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);
|
||||
bool _empty() const;
|
||||
|
||||
/*
|
||||
* print method
|
||||
*/
|
||||
JNIEXPORT static void JNICALL print(JNIEnv *env, jobject self);
|
||||
void _print();
|
||||
|
||||
/*
|
||||
* asRawJsonString method
|
||||
*/
|
||||
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:
|
||||
void reset_buffer();
|
||||
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;
|
||||
};
|
@ -208,7 +208,7 @@ public class AppCompatListActivity extends AppCompatActivity {
|
||||
super.onContentChanged();
|
||||
|
||||
View emptyView = findViewById(R.id.empty);
|
||||
mList = (ListView)findViewById(R.id.list);
|
||||
mList = findViewById(R.id.list);
|
||||
if (mList == null) {
|
||||
throw new RuntimeException(
|
||||
"Your content must have a ListView whose id attribute is " +
|
||||
|
@ -44,8 +44,6 @@ import android.widget.TextView;
|
||||
|
||||
import com.dd.processbutton.iml.ActionProcessButton;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
@ -85,11 +83,11 @@ public class LoginActivity extends AppCompatActivity {
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
// Set up the login form.
|
||||
_protocolView = (Spinner) findViewById(R.id.oc_protocol);
|
||||
_serverView = (EditText) findViewById(R.id.oc_server);
|
||||
_loginView = (EditText) findViewById(R.id.oc_login);
|
||||
_protocolView = findViewById(R.id.oc_protocol);
|
||||
_serverView = findViewById(R.id.oc_server);
|
||||
_loginView = findViewById(R.id.oc_login);
|
||||
|
||||
_passwordView = (EditText) findViewById(R.id.oc_password);
|
||||
_passwordView = findViewById(R.id.oc_password);
|
||||
_passwordView
|
||||
.setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
||||
@Override
|
||||
@ -103,7 +101,7 @@ public class LoginActivity extends AppCompatActivity {
|
||||
}
|
||||
});
|
||||
|
||||
_signInButton = (ActionProcessButton) findViewById(R.id.oc_signin_button);
|
||||
_signInButton = findViewById(R.id.oc_signin_button);
|
||||
_signInButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
@ -270,8 +268,8 @@ public class LoginActivity extends AppCompatActivity {
|
||||
_returnCode = 0;
|
||||
OCHttpClient http = new OCHttpClient(getBaseContext(), _serverURL, _login, _password);
|
||||
try {
|
||||
Pair<Integer, JSONObject> response = http.getVersion();
|
||||
_returnCode = response.first;
|
||||
Pair<Integer, Integer> vPair = http.getVersion();
|
||||
_returnCode = vPair.first;
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.w(TAG, "Failed to getVersion, IllegalArgumentException occured: " + e.getMessage());
|
||||
_returnCode = 597;
|
||||
|
@ -76,7 +76,7 @@ public class MainActivity extends AppCompatActivity
|
||||
getSupportActionBar().setHomeButtonEnabled(true);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
|
||||
drawer = findViewById(R.id.drawer_layout);
|
||||
setupDrawer();
|
||||
drawer.openDrawer(GravityCompat.START);
|
||||
}
|
||||
@ -93,7 +93,7 @@ public class MainActivity extends AppCompatActivity
|
||||
toggle.syncState();
|
||||
toggle.setDrawerIndicatorEnabled(true);
|
||||
|
||||
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
|
||||
NavigationView navigationView = findViewById(R.id.nav_view);
|
||||
assert navigationView != null;
|
||||
navigationView.setNavigationItemSelectedListener(this);
|
||||
}
|
||||
|
@ -55,12 +55,12 @@ public class ContactListActivity extends AppCompatActivity implements ASyncConta
|
||||
mObjects = new ArrayList<>();
|
||||
setContentView(R.layout.restore_activity_contactlist);
|
||||
|
||||
mLayout = (SwipeRefreshLayout) findViewById(R.id.contactlist_swipe_container);
|
||||
mLayout = findViewById(R.id.contactlist_swipe_container);
|
||||
|
||||
mAdapter = new ContactListAdapter(getBaseContext(), mObjects);
|
||||
|
||||
mContactInfos = (LinearLayout) findViewById(R.id.contactinfos_layout);
|
||||
ListView contactPhoneListView = (ListView) findViewById(R.id.contact_phonelistView);
|
||||
mContactInfos = findViewById(R.id.contactinfos_layout);
|
||||
ListView contactPhoneListView = findViewById(R.id.contact_phonelistView);
|
||||
mContactPhoneListAdapter = new RecoveryPhoneNumberListViewAdapter(getBaseContext());
|
||||
assert contactPhoneListView != null;
|
||||
contactPhoneListView.setAdapter(mContactPhoneListAdapter);
|
||||
@ -72,7 +72,7 @@ public class ContactListActivity extends AppCompatActivity implements ASyncConta
|
||||
}
|
||||
|
||||
private void createAccountList() {
|
||||
final ProgressBar contactProgressBar = (ProgressBar) findViewById(R.id.contactlist_pgbar);
|
||||
final ProgressBar contactProgressBar = findViewById(R.id.contactlist_pgbar);
|
||||
assert contactProgressBar != null;
|
||||
|
||||
String accountName = getIntent().getExtras().getString("account");
|
||||
@ -112,7 +112,7 @@ public class ContactListActivity extends AppCompatActivity implements ASyncConta
|
||||
}
|
||||
|
||||
private void initSpinner() {
|
||||
final Spinner sp = (Spinner) findViewById(R.id.contact_spinner);
|
||||
final Spinner sp = findViewById(R.id.contact_spinner);
|
||||
assert sp != null;
|
||||
sp.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
|
@ -73,9 +73,9 @@ public class RestoreMessagesActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
initInterface();
|
||||
Button fix_button = (Button) findViewById(R.id.button_fix_permissions);
|
||||
final Button launch_restore = (Button) findViewById(R.id.button_launch_restore);
|
||||
final ProgressBar pb = (ProgressBar) findViewById(R.id.progressbar_restore);
|
||||
Button fix_button = findViewById(R.id.button_fix_permissions);
|
||||
final Button launch_restore = findViewById(R.id.button_launch_restore);
|
||||
final ProgressBar pb = findViewById(R.id.progressbar_restore);
|
||||
|
||||
final RestoreMessagesActivity me = this;
|
||||
fix_button.setOnClickListener(new View.OnClickListener() {
|
||||
@ -130,13 +130,13 @@ public class RestoreMessagesActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
private void initInterface() {
|
||||
TextView tv_error = (TextView) findViewById(R.id.tv_error_default_smsapp);
|
||||
TextView tv_error = findViewById(R.id.tv_error_default_smsapp);
|
||||
tv_error.setText(R.string.error_make_default_sms_app);
|
||||
findViewById(R.id.tv_restore_finished).setVisibility(View.INVISIBLE);
|
||||
findViewById(R.id.tv_progress_value).setVisibility(View.INVISIBLE);
|
||||
Button fix_button = (Button) findViewById(R.id.button_fix_permissions);
|
||||
Button launch_restore = (Button) findViewById(R.id.button_launch_restore);
|
||||
ProgressBar pb = (ProgressBar) findViewById(R.id.progressbar_restore);
|
||||
Button fix_button = findViewById(R.id.button_fix_permissions);
|
||||
Button launch_restore = findViewById(R.id.button_launch_restore);
|
||||
ProgressBar pb = findViewById(R.id.progressbar_restore);
|
||||
pb.setVisibility(View.INVISIBLE);
|
||||
|
||||
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.KITKAT) {
|
||||
@ -158,10 +158,10 @@ public class RestoreMessagesActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
private void errorNotification(int err) {
|
||||
TextView tv = (TextView) findViewById(R.id.tv_error_default_smsapp);
|
||||
Button fix_button = (Button) findViewById(R.id.button_fix_permissions);
|
||||
Button launch_restore = (Button) findViewById(R.id.button_launch_restore);
|
||||
ProgressBar pb = (ProgressBar) findViewById(R.id.progressbar_restore);
|
||||
TextView tv = findViewById(R.id.tv_error_default_smsapp);
|
||||
Button fix_button = findViewById(R.id.button_fix_permissions);
|
||||
Button launch_restore = findViewById(R.id.button_launch_restore);
|
||||
ProgressBar pb = findViewById(R.id.progressbar_restore);
|
||||
tv.setText(err);
|
||||
tv.setVisibility(View.VISIBLE);
|
||||
fix_button.setVisibility(View.INVISIBLE);
|
||||
@ -182,9 +182,9 @@ public class RestoreMessagesActivity extends AppCompatActivity {
|
||||
switch (requestCode) {
|
||||
case RestoreMessagesActivity.REQUEST_DEFAULT_SMSAPP:
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
TextView tv = (TextView) findViewById(R.id.tv_error_default_smsapp);
|
||||
Button fix_button = (Button) findViewById(R.id.button_fix_permissions);
|
||||
Button launch_restore = (Button) findViewById(R.id.button_launch_restore);
|
||||
TextView tv = findViewById(R.id.tv_error_default_smsapp);
|
||||
Button fix_button = findViewById(R.id.button_fix_permissions);
|
||||
Button launch_restore = findViewById(R.id.button_launch_restore);
|
||||
tv.setVisibility(View.INVISIBLE);
|
||||
fix_button.setVisibility(View.INVISIBLE);
|
||||
launch_restore.setVisibility(View.VISIBLE);
|
||||
@ -225,7 +225,7 @@ public class RestoreMessagesActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
public void onProgressUpdate(Integer value) {
|
||||
TextView tv_progress = (TextView) findViewById(R.id.tv_progress_value);
|
||||
TextView tv_progress = findViewById(R.id.tv_progress_value);
|
||||
if (tv_progress.getVisibility() == View.INVISIBLE) {
|
||||
tv_progress.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ public class AndroidAccountAdapter extends ArrayAdapter<Account> {
|
||||
final Account account = _accounts.get(position);
|
||||
|
||||
if (account != null) {
|
||||
TextView label = (TextView) v.findViewById(AndroidAccountAdapter._accountFieldId);
|
||||
TextView label = v.findViewById(AndroidAccountAdapter._accountFieldId);
|
||||
if (label != null) {
|
||||
label.setText(account.name + " >");
|
||||
v.setOnClickListener(new OnClickListener() {
|
||||
|
@ -39,7 +39,7 @@ public class ContactListAdapter extends ArrayAdapter<String> {
|
||||
String element = _objects.get(position);
|
||||
|
||||
if (element != null) {
|
||||
TextView label = (TextView) v.findViewById(ContactListAdapter._fieldId);
|
||||
TextView label = v.findViewById(ContactListAdapter._fieldId);
|
||||
if (label != null) {
|
||||
label.setText(element);
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ public class RecoveryPhoneNumberListViewAdapter extends ArrayAdapter<String> {
|
||||
v = inflater.inflate(RecoveryPhoneNumberListViewAdapter._itemLayout, null);
|
||||
}
|
||||
|
||||
TextView label = (TextView) v.findViewById(RecoveryPhoneNumberListViewAdapter._fieldId);
|
||||
TextView label = v.findViewById(RecoveryPhoneNumberListViewAdapter._fieldId);
|
||||
if (label != null) {
|
||||
final String l = getItem(position).toString();
|
||||
label.setText(getItem(position).toString());
|
||||
|
@ -32,9 +32,9 @@ 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;
|
||||
import ncsmsgo.SmsBuffer;
|
||||
|
||||
public class ConnectivityChanged extends BroadcastReceiver implements ASyncSMSSync {
|
||||
|
||||
|
@ -28,9 +28,9 @@ 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;
|
||||
import ncsmsgo.SmsBuffer;
|
||||
|
||||
public interface ASyncSMSSync {
|
||||
class SyncTask extends AsyncTask<Void, Void, Void> {
|
||||
|
@ -25,8 +25,8 @@ import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
|
||||
import fr.unix_experience.owncloud_sms.enums.MailboxID;
|
||||
import fr.unix_experience.owncloud_sms.jni.SmsBuffer;
|
||||
import fr.unix_experience.owncloud_sms.providers.SmsDataProvider;
|
||||
import ncsmsgo.SmsBuffer;
|
||||
|
||||
public class AndroidSmsFetcher {
|
||||
public AndroidSmsFetcher(Context ct) {
|
||||
@ -53,7 +53,14 @@ public class AndroidSmsFetcher {
|
||||
|
||||
// Mailbox ID is required by server
|
||||
entry.mailboxId = mbID.ordinal();
|
||||
smsBuffer.push(mbID, entry);
|
||||
smsBuffer.push(entry.id,
|
||||
mbID.ordinal(),
|
||||
entry.type,
|
||||
entry.date,
|
||||
entry.address,
|
||||
entry.body,
|
||||
entry.read ? "true" : "false",
|
||||
entry.seen ? "true" : "false");
|
||||
}
|
||||
while (c.moveToNext());
|
||||
}
|
||||
@ -114,7 +121,14 @@ public class AndroidSmsFetcher {
|
||||
* aren't indexed in the same mean
|
||||
*/
|
||||
entry.mailboxId = mboxId - 1;
|
||||
results.push(mbID, entry);
|
||||
results.push(entry.id,
|
||||
mbID.ordinal(),
|
||||
entry.type,
|
||||
entry.date,
|
||||
entry.address,
|
||||
entry.body,
|
||||
entry.read ? "true" : "false",
|
||||
entry.seen ? "true" : "false");
|
||||
|
||||
c.close();
|
||||
|
||||
|
@ -45,16 +45,12 @@ 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.providers.AndroidVersionProvider;
|
||||
import ncsmsgo.SmsBuffer;
|
||||
import ncsmsgo.SmsHTTPClient;
|
||||
import ncsmsgo.SmsPushResponse;
|
||||
|
||||
public class OCHttpClient {
|
||||
static {
|
||||
System.loadLibrary("nativesms");
|
||||
}
|
||||
|
||||
public static native String getAllSmsIdsCall();
|
||||
public static native String getLastMsgTimestamp();
|
||||
public static native String getPushRoute();
|
||||
public static native String getVersionCall();
|
||||
private SmsHTTPClient _smsHttpClient;
|
||||
|
||||
private static final String TAG = OCHttpClient.class.getCanonicalName();
|
||||
private static final String PARAM_PROTOCOL_VERSION = "http.protocol.version";
|
||||
@ -63,12 +59,6 @@ public class OCHttpClient {
|
||||
private final String _username;
|
||||
private final String _password;
|
||||
|
||||
// API v2 calls
|
||||
private static final String OC_V2_GET_PHONELIST = "/index.php/apps/ocsms/api/v2/phones/list?format=json";
|
||||
private static final String OC_V2_GET_MESSAGES ="/index.php/apps/ocsms/api/v2/messages/[START]/[LIMIT]?format=json";
|
||||
private static final String OC_V2_GET_MESSAGES_PHONE ="/index.php/apps/ocsms/api/v2/messages/[PHONENUMBER]/[START]/[LIMIT]?format=json";
|
||||
private static final String OC_V2_GET_MESSAGES_SENDQUEUE = "/index.php/apps/ocsms/api/v2/messages/sendqueue?format=json";
|
||||
|
||||
public OCHttpClient(Context context, URL serverURL, String accountName, String accountPassword) {
|
||||
// Create a trust manager that does not validate certificate chains
|
||||
TrustManager[] trustAllCerts = new TrustManager[]{
|
||||
@ -97,6 +87,11 @@ public class OCHttpClient {
|
||||
_username = accountName;
|
||||
_password = accountPassword;
|
||||
|
||||
_smsHttpClient = new SmsHTTPClient();
|
||||
// @TODO: at a point add a flag to permit insecure connections somewhere instead of trusting them
|
||||
_smsHttpClient.init(_url.toString(), new AndroidVersionProvider(context).getVersionCode(),
|
||||
_username, _password, false);
|
||||
|
||||
_userAgent = "nextcloud-phonesync (" + new AndroidVersionProvider(context).getVersionCode() + ")";
|
||||
}
|
||||
|
||||
@ -127,23 +122,46 @@ public class OCHttpClient {
|
||||
}
|
||||
|
||||
Pair<Integer, JSONObject> getAllSmsIds() throws OCSyncException {
|
||||
return get(OCHttpClient.getAllSmsIdsCall(), false);
|
||||
return get(_smsHttpClient.getAllSmsIdsCall(), false);
|
||||
}
|
||||
|
||||
public Pair<Integer, JSONObject> getVersion() throws OCSyncException {
|
||||
return get(OCHttpClient.getVersionCall(), true);
|
||||
// Perform the GoLang doVersionCall and handle return
|
||||
public Pair<Integer, Integer> getVersion() throws OCSyncException {
|
||||
Integer serverAPIVersion = (int) _smsHttpClient.doVersionCall();
|
||||
int httpStatus = (int) _smsHttpClient.getLastHTTPStatus();
|
||||
|
||||
// If last status is not 200, send the wrong status now
|
||||
if (httpStatus != 200) {
|
||||
return new Pair<>(httpStatus, 0);
|
||||
}
|
||||
|
||||
if (serverAPIVersion > 0) {
|
||||
return new Pair<>(200, serverAPIVersion);
|
||||
}
|
||||
else if (serverAPIVersion == 0) {
|
||||
// Return default version
|
||||
return new Pair<>(200, 1);
|
||||
}
|
||||
else if (serverAPIVersion == -1) {
|
||||
// This return code from API means I/O error
|
||||
throw new OCSyncException(R.string.err_sync_http_request_ioexception, OCSyncErrorType.IO);
|
||||
}
|
||||
else {
|
||||
throw new OCSyncException(R.string.err_sync_http_request_returncode_unhandled, OCSyncErrorType.SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
Pair<Integer, JSONObject> pushSms(String smsBuf) throws OCSyncException {
|
||||
return post(OCHttpClient.getPushRoute(), smsBuf);
|
||||
Pair<Integer, SmsPushResponse> pushSms(SmsBuffer smsBuf) throws OCSyncException {
|
||||
SmsPushResponse spr = _smsHttpClient.doPushCall(smsBuf);
|
||||
return new Pair<>((int) _smsHttpClient.getLastHTTPStatus(), spr);
|
||||
}
|
||||
|
||||
Pair<Integer, JSONObject> getPhoneList() throws OCSyncException {
|
||||
return get(OCHttpClient.OC_V2_GET_PHONELIST, true);
|
||||
return get(_smsHttpClient.getPhoneListCall(), true);
|
||||
}
|
||||
|
||||
Pair<Integer, JSONObject> getMessages(Long start, Integer limit) throws OCSyncException {
|
||||
return get(OCHttpClient.OC_V2_GET_MESSAGES
|
||||
return get(_smsHttpClient.getMessagesCall()
|
||||
.replace("[START]", start.toString())
|
||||
.replace("[LIMIT]", limit.toString()), false);
|
||||
}
|
||||
|
@ -33,8 +33,9 @@ import java.net.URL;
|
||||
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;
|
||||
import ncsmsgo.SmsBuffer;
|
||||
import ncsmsgo.SmsPushResponse;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class OCSMSOwnCloudClient {
|
||||
@ -56,6 +57,7 @@ public class OCSMSOwnCloudClient {
|
||||
_http = new OCHttpClient(context,
|
||||
serverURL, accountManager.getUserData(account, "ocLogin"),
|
||||
accountManager.getPassword(account));
|
||||
|
||||
_connectivityMonitor = new ConnectivityMonitor(_context);
|
||||
} catch (MalformedURLException e) {
|
||||
throw new IllegalStateException(context.getString(R.string.err_sync_account_unparsable));
|
||||
@ -63,21 +65,13 @@ public class OCSMSOwnCloudClient {
|
||||
}
|
||||
|
||||
public Integer getServerAPIVersion() throws OCSyncException {
|
||||
Pair<Integer, JSONObject> response = _http.getVersion();
|
||||
if (response.second == null) {
|
||||
// Return default version
|
||||
return 1;
|
||||
Pair<Integer, Integer> vPair = _http.getVersion();
|
||||
_serverAPIVersion = vPair.second;
|
||||
if (vPair.first == 200 && _serverAPIVersion > 0) {
|
||||
return _serverAPIVersion;
|
||||
}
|
||||
|
||||
try {
|
||||
_serverAPIVersion = response.second.getInt("version");
|
||||
}
|
||||
catch (JSONException e) {
|
||||
Log.e(OCSMSOwnCloudClient.TAG, "No version received from server, assuming version 1", e);
|
||||
_serverAPIVersion = 1;
|
||||
}
|
||||
|
||||
return _serverAPIVersion;
|
||||
return 0;
|
||||
}
|
||||
|
||||
JSONArray getServerPhoneNumbers() throws OCSyncException {
|
||||
@ -111,7 +105,7 @@ public class OCSMSOwnCloudClient {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create new JSONArray to get results
|
||||
// Create new SmsBuffer to get results
|
||||
smsBuffer = new SmsBuffer();
|
||||
}
|
||||
|
||||
@ -120,28 +114,18 @@ public class OCSMSOwnCloudClient {
|
||||
return;
|
||||
}
|
||||
|
||||
Pair<Integer, JSONObject> response = _http.pushSms(smsBuffer.asRawJsonString());
|
||||
Pair<Integer, SmsPushResponse> response = _http.pushSms(smsBuffer);
|
||||
|
||||
if (response.second == null) {
|
||||
Log.e(OCSMSOwnCloudClient.TAG,"Request failed. It doesn't return a valid JSON Object");
|
||||
Log.e(OCSMSOwnCloudClient.TAG,"Push request failed. GoLang response is empty.");
|
||||
throw new OCSyncException(R.string.err_sync_push_request, OCSyncErrorType.IO);
|
||||
}
|
||||
|
||||
Boolean pushStatus;
|
||||
String pushMessage;
|
||||
try {
|
||||
pushStatus = response.second.getBoolean("status");
|
||||
pushMessage = response.second.getString("msg");
|
||||
}
|
||||
catch (JSONException e) {
|
||||
Log.e(OCSMSOwnCloudClient.TAG, "Invalid datas received from server", e);
|
||||
throw new OCSyncException(R.string.err_sync_push_request_resp, OCSyncErrorType.PARSE);
|
||||
}
|
||||
|
||||
// Push was OK, we can save the lastMessageDate which was saved to server
|
||||
(new OCSMSSharedPrefs(_context)).setLastMessageDate(smsBuffer.getLastMessageDate());
|
||||
|
||||
Log.i(OCSMSOwnCloudClient.TAG, "SMS Push request said: status " + pushStatus + " - " + pushMessage);
|
||||
Log.i(OCSMSOwnCloudClient.TAG, "SMS Push request said: status " +
|
||||
response.second.getStatus() + " - " + response.second.getMessage());
|
||||
Log.i(OCSMSOwnCloudClient.TAG, "LastMessageDate set to: " + smsBuffer.getLastMessageDate());
|
||||
}
|
||||
|
||||
|
@ -1,69 +0,0 @@
|
||||
package fr.unix_experience.owncloud_sms.jni;
|
||||
|
||||
import fr.unix_experience.owncloud_sms.engine.SmsEntry;
|
||||
import fr.unix_experience.owncloud_sms.enums.MailboxID;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2014-2017, Loic Blot <loic.blot@unix-experience.fr>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
public class SmsBuffer {
|
||||
static {
|
||||
System.loadLibrary("nativesms");
|
||||
}
|
||||
|
||||
private long mHandle;
|
||||
|
||||
String TAG = SmsBuffer.class.getSimpleName();
|
||||
|
||||
public SmsBuffer() {
|
||||
mHandle = SmsBuffer.createNativeObject();
|
||||
}
|
||||
|
||||
protected void finalize() throws Throwable {
|
||||
clear();
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
private static native long createNativeObject();
|
||||
private native void deleteNativeObject();
|
||||
public native void push(int id, int mbid, int type, long date, String address,
|
||||
String body, String read, String seen);
|
||||
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,
|
||||
mbid.ordinal(),
|
||||
smsEntry.type,
|
||||
smsEntry.date,
|
||||
smsEntry.address,
|
||||
smsEntry.body,
|
||||
smsEntry.read ? "true" : "false",
|
||||
smsEntry.seen ? "true" : "false");
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
if (mHandle == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
deleteNativeObject();
|
||||
mHandle = 0;
|
||||
}
|
||||
}
|
@ -32,8 +32,8 @@ 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;
|
||||
import ncsmsgo.SmsBuffer;
|
||||
|
||||
public class SmsObserver extends ContentObserver implements ASyncSMSSync {
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user