aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rwxr-xr-xbuild-android/build.sh5
-rw-r--r--build-android/jni/Android.mk9
-rw-r--r--src/core/basetypes/MCData.cpp35
-rw-r--r--src/core/basetypes/MCLog.cpp12
-rw-r--r--src/core/basetypes/MCMainThreadAndroid.cpp136
-rw-r--r--src/core/basetypes/MCMainThreadAndroid.h17
-rw-r--r--src/core/basetypes/MCOperationQueue.cpp8
-rw-r--r--src/core/basetypes/MCString.cpp4
-rw-r--r--src/core/basetypes/com_libmailcore_MainThreadUtils.h37
-rw-r--r--src/core/security/MCCertificateUtils.cpp24
-rw-r--r--tests/test-all.cpp8
11 files changed, 282 insertions, 13 deletions
diff --git a/build-android/build.sh b/build-android/build.sh
index c2e14c32..bb41aba3 100755
--- a/build-android/build.sh
+++ b/build-android/build.sh
@@ -5,6 +5,7 @@ ANDROID_PLATFORM=android-21
archs="armeabi armeabi-v7a x86 x86_64"
package_name=mailcore2-android
ctemplate_build_version=1
+cyrus_sasl_build_version=1
icu4c_build_version=1
libetpan_build_version=1
libxml2_build_version=1
@@ -44,7 +45,8 @@ function build {
LIBXML2_PATH=$current_dir/third-party/libxml2-android-1 \
UCHARDET_PATH=$current_dir/third-party/uchardet-android-1 \
TIDY_HTML5_PATH=$current_dir/third-party/tidy-html5-android-1 \
- OPENSSL_PATH=$current_dir/third-party/openssl-android-1
+ OPENSSL_PATH=$current_dir/third-party/openssl-android-1 \
+ CYRUS_SASL_PATH=$current_dir/third-party/cyrus-sasl-android-1
mkdir -p "$current_dir/$package_name-$build_version/libs/$TARGET_ARCH_ABI"
cp "$current_dir/libs/$TARGET_ARCH_ABI/libMailCore.so" "$current_dir/$package_name-$build_version/libs/$TARGET_ARCH_ABI"
@@ -70,6 +72,7 @@ download_dep "libxml2-android" $libxml2_build_version
download_dep "uchardet-android" $uchardet_build_version
download_dep "tidy-html5-android" $tidy_html5_build_version
download_dep "openssl-android" $openssl_build_version
+download_dep "cyrus-sasl-android" $cyrus_sasl_build_version
# Start building.
for arch in $archs ; do
diff --git a/build-android/jni/Android.mk b/build-android/jni/Android.mk
index 7f3b4aa0..d3eddf13 100644
--- a/build-android/jni/Android.mk
+++ b/build-android/jni/Android.mk
@@ -102,6 +102,11 @@ LOCAL_SRC_FILES := $(CTEMPLATE_PATH)/libs/$(TARGET_ARCH_ABI)/libctemplate.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
+LOCAL_MODULE := sasl2
+LOCAL_SRC_FILES := $(CYRUS_SASL_PATH)/libs/$(TARGET_ARCH_ABI)/libsasl2.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
LOCAL_MODULE := MailCore
LOCAL_C_INCLUDES := $(includes)
LOCAL_SRC_FILES := $(core_src_files) $(abstract_src_files) $(imap_src_files) $(nntp_src_files) \
@@ -110,7 +115,7 @@ LOCAL_SRC_FILES := $(core_src_files) $(abstract_src_files) $(imap_src_files) $(n
$(async_imap_src_files) $(async_nntp_src_files) $(async_pop_src_files) $(async_smtp_src_files)
LOCAL_CPPFLAGS := -frtti
LOCAL_CFLAGS := -DNOCRYPT
-LOCAL_LDLIBS := -lz \
+LOCAL_LDLIBS := -lz -llog \
-lc++_shared -L$(ANDROID_NDK)/sources/cxx-stl/llvm-libc++/libs/$(TARGET_ARCH_ABI)
-LOCAL_STATIC_LIBRARIES := etpan ssl crypto icu4c xml2 uchardet tidy ctemplate
+LOCAL_STATIC_LIBRARIES := etpan sasl2 ssl crypto icu4c xml2 uchardet tidy ctemplate
include $(BUILD_SHARED_LIBRARY)
diff --git a/src/core/basetypes/MCData.cpp b/src/core/basetypes/MCData.cpp
index 3a042e46..d1feac48 100644
--- a/src/core/basetypes/MCData.cpp
+++ b/src/core/basetypes/MCData.cpp
@@ -809,7 +809,7 @@ static int lepIConv(const char * tocode, const char * fromcode,
goto err;
}
- out_size = length * 6;
+ out_size = * result_len;
old_out_size = out_size;
p_result = result;
@@ -861,6 +861,9 @@ static int lepCFConv(const char * tocode, const char * fromcode,
unsigned int len;
len = (unsigned int) CFDataGetLength(resultData);
+ if (len > * result_len) {
+ len = (unsigned int) * result_len;
+ }
CFDataGetBytes(resultData, CFRangeMake(0, len), (UInt8 *) result);
* result_len = len;
result[len] = 0;
@@ -894,6 +897,34 @@ static int lepMixedConv(const char * tocode, const char * fromcode,
}
#endif
+#if defined(__ANDROID__) || defined(ANDROID)
+
+static int lepMixedConv(const char * tocode, const char * fromcode,
+ const char * str, size_t length,
+ char * result, size_t * result_len)
+{
+ Data * data = Data::dataWithBytes(str, length);
+ String * ustr = data->stringWithCharset(fromcode);
+ if (ustr == NULL) {
+ return MAIL_CHARCONV_ERROR_CONV;
+ }
+ data = ustr->dataUsingEncoding(tocode);
+ if (data == NULL) {
+ return MAIL_CHARCONV_ERROR_CONV;
+ }
+ size_t len = data->length();
+ if (len > * result_len) {
+ len = * result_len;
+ }
+ memcpy(result, data->bytes(), len);
+ result[len] = 0;
+ * result_len = len;
+
+ return MAIL_CHARCONV_NO_ERROR;
+}
+
+#endif
+
static void * createObject()
{
return new Data();
@@ -902,7 +933,7 @@ static void * createObject()
INITIALIZE(Data)
{
Object::registerObjectConstructor("mailcore::Data", &createObject);
-#if __APPLE__
+#if __APPLE__ || defined(__ANDROID__) || defined(ANDROID)
extended_charconv = lepMixedConv;
#endif
}
diff --git a/src/core/basetypes/MCLog.cpp b/src/core/basetypes/MCLog.cpp
index ceb1b93c..952229ec 100644
--- a/src/core/basetypes/MCLog.cpp
+++ b/src/core/basetypes/MCLog.cpp
@@ -16,6 +16,10 @@
#include <execinfo.h>
#endif
+#if defined(ANDROID) || defined(__ANDROID__)
+#include <android/log.h>
+#endif
+
static pid_t sPid = -1;
int MCLogEnabled = 0;
@@ -61,7 +65,11 @@ static void logInternalv(FILE * file,
struct timeval tv;
struct tm tm_value;
pthread_t thread_id = pthread_self();
-
+
+#if defined(ANDROID) || defined(__ANDROID__)
+ __android_log_vprint(ANDROID_LOG_INFO, filename, format, argp);
+#else
+
gettimeofday(&tv, NULL);
time_t timevalue_sec = tv.tv_sec;
localtime_r(&timevalue_sec, &tm_value);
@@ -103,5 +111,5 @@ static void logInternalv(FILE * file,
#endif
// TODO: other platforms implemented needed.
}
-
+#endif
}
diff --git a/src/core/basetypes/MCMainThreadAndroid.cpp b/src/core/basetypes/MCMainThreadAndroid.cpp
new file mode 100644
index 00000000..425558ca
--- /dev/null
+++ b/src/core/basetypes/MCMainThreadAndroid.cpp
@@ -0,0 +1,136 @@
+//
+// MCMainThreadAndroid.cpp
+// mailcore2
+//
+// Created by Hoa Dinh on 11/11/14.
+// Copyright (c) 2014 MailCore. All rights reserved.
+//
+
+#include "MCMainThread.h"
+#include "MCMainThreadAndroid.h"
+#include "com_libmailcore_MainThreadUtils.h"
+
+#include <libetpan/libetpan.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+#include "MCDefines.h"
+#include "MCAssert.h"
+#include "MCLog.h"
+#include "MCAutoreleasePool.h"
+
+#include "test-all.h"
+
+using namespace mailcore;
+
+struct main_thread_call_data {
+ void (* function)(void *);
+ void * context;
+ struct mailsem * sem;
+};
+
+static jobject s_mainThreadUtils = NULL;
+static jclass s_mainThreadUtilsClass = NULL;
+static JavaVM * s_jvm = NULL;
+static jint s_version = 0;
+
+void mailcore::androidSetupThread(void)
+{
+ JNIEnv * env = NULL;
+ s_jvm->AttachCurrentThread(&env, NULL);
+}
+
+void mailcore::androidUnsetupThread()
+{
+ s_jvm->DetachCurrentThread();
+}
+
+JNIEXPORT void JNICALL Java_com_libmailcore_MainThreadUtils_setupNative(JNIEnv * env, jobject object)
+{
+ AutoreleasePool * pool = new AutoreleasePool();
+
+ env->GetJavaVM(&s_jvm);
+ s_version = env->GetVersion();
+ s_mainThreadUtils = reinterpret_cast<jobject>(env->NewGlobalRef(object));
+ jclass localClass = env->FindClass("com/libmailcore/MainThreadUtils");
+ s_mainThreadUtilsClass = reinterpret_cast<jclass>(env->NewGlobalRef(localClass));
+ MCAssert(s_mainThreadUtilsClass != NULL);
+
+ pool->release();
+}
+
+JNIEXPORT void JNICALL Java_com_libmailcore_MainThreadUtils_runIdentifier(JNIEnv * env, jobject object, jlong identifier)
+{
+ AutoreleasePool * pool = new AutoreleasePool();
+ struct main_thread_call_data * data = (struct main_thread_call_data *) identifier;
+ data->function(data->context);
+ free(data);
+ pool->release();
+}
+
+JNIEXPORT void JNICALL Java_com_libmailcore_MainThreadUtils_runIdentifierAndNotify(JNIEnv * env, jobject object, jlong identifier)
+{
+ AutoreleasePool * pool = new AutoreleasePool();
+ struct main_thread_call_data * data = (struct main_thread_call_data *) identifier;
+ data->function(data->context);
+ mailsem_up(data->sem);
+ pool->release();
+}
+
+void mailcore::callOnMainThread(void (* function)(void *), void * context)
+{
+ struct main_thread_call_data * data = (struct main_thread_call_data *) malloc(sizeof(* data));
+ data->function = function;
+ data->context = context;
+ data->sem = NULL;
+
+ JNIEnv * env = NULL;
+ s_jvm->GetEnv((void **)&env, s_version);
+ jmethodID mid = env->GetMethodID(s_mainThreadUtilsClass, "runOnMainThread", "(J)V");
+ MCAssert(mid != NULL);
+ env->CallVoidMethod(s_mainThreadUtils, mid, (jlong) data);
+}
+
+void mailcore::callOnMainThreadAndWait(void (* function)(void *), void * context)
+{
+ struct main_thread_call_data * data = (struct main_thread_call_data *) malloc(sizeof(* data));
+ data->function = function;
+ data->context = context;
+ data->sem = mailsem_new();
+
+ JNIEnv * env = NULL;
+ s_jvm->GetEnv((void **)&env, s_version);
+ jmethodID mid = env->GetMethodID(s_mainThreadUtilsClass, "runOnMainThreadAndWait", "(J)V");
+ MCAssert(mid != NULL);
+ env->CallVoidMethod(s_mainThreadUtils, mid, (jlong) data);
+
+ // Wait.
+ mailsem_down(data->sem);
+
+ mailsem_free(data->sem);
+ free(data);
+}
+
+void * mailcore::callAfterDelay(void (* function)(void *), void * context, double time)
+{
+ struct main_thread_call_data * data = (struct main_thread_call_data *) malloc(sizeof(* data));
+ data->function = function;
+ data->context = context;
+ data->sem = NULL;
+
+ JNIEnv * env = NULL;
+ s_jvm->GetEnv((void **)&env, s_version);
+ jmethodID mid = env->GetMethodID(s_mainThreadUtilsClass, "runAfterDelay", "(JI)V");
+ MCAssert(mid != NULL);
+ env->CallVoidMethod(s_mainThreadUtils, mid, (jlong) data, (jint) (time * 1000));
+ return data;
+}
+
+void mailcore::cancelDelayedCall(void * delayedCall)
+{
+ JNIEnv * env = NULL;
+ s_jvm->GetEnv((void **)&env, s_version);
+ jmethodID mid = env->GetMethodID(s_mainThreadUtilsClass, "cancelDelayedRun", "(J)V");
+ MCAssert(mid != NULL);
+ env->CallVoidMethod(s_mainThreadUtils, mid, (jlong) delayedCall);
+}
diff --git a/src/core/basetypes/MCMainThreadAndroid.h b/src/core/basetypes/MCMainThreadAndroid.h
new file mode 100644
index 00000000..8dfa1078
--- /dev/null
+++ b/src/core/basetypes/MCMainThreadAndroid.h
@@ -0,0 +1,17 @@
+#ifndef MAILCORE_MCMAINTHREADANDROID_H
+
+#define MAILCORE_MCMAINTHREADANDROID_H
+
+#if defined(__ANDROID) || defined(ANDROID)
+
+#ifdef __cplusplus
+
+namespace mailcore {
+ extern void androidSetupThread(void);
+ extern void androidUnsetupThread(void);
+}
+#endif
+
+#endif
+
+#endif
diff --git a/src/core/basetypes/MCOperationQueue.cpp b/src/core/basetypes/MCOperationQueue.cpp
index 7783a978..b9e8d779 100644
--- a/src/core/basetypes/MCOperationQueue.cpp
+++ b/src/core/basetypes/MCOperationQueue.cpp
@@ -10,6 +10,7 @@
#include "MCArray.h"
#include "MCLog.h"
#include "MCAutoreleasePool.h"
+#include "MCMainThreadAndroid.h"
using namespace mailcore;
@@ -72,6 +73,10 @@ void OperationQueue::runOperationsOnThread(OperationQueue * queue)
void OperationQueue::runOperations()
{
+#if defined(__ANDROID) || defined(ANDROID)
+ androidSetupThread();
+#endif
+
MCLog("start thread");
mailsem_up(mStartSem);
@@ -142,6 +147,9 @@ void OperationQueue::runOperations()
pool->release();
}
MCLog("cleanup thread %p", this);
+#if defined(__ANDROID) || defined(ANDROID)
+ androidUnsetupThread();
+#endif
}
void OperationQueue::performOnCallbackThread(Operation * op, Method method, void * context, bool waitUntilDone)
diff --git a/src/core/basetypes/MCString.cpp b/src/core/basetypes/MCString.cpp
index 90d7b227..d1115c40 100644
--- a/src/core/basetypes/MCString.cpp
+++ b/src/core/basetypes/MCString.cpp
@@ -1388,7 +1388,7 @@ String * String::extractedSubjectAndKeepBracket(bool keepBracket)
String * String::uuidString()
{
- char buffer[38];
+ char buffer[40];
FILE * f = fopen("/proc/sys/kernel/random/uuid", "r");
if (f == NULL) {
return NULL;
@@ -1397,7 +1397,7 @@ String * String::uuidString()
fclose(f);
return NULL;
}
- buffer[38] = 0;
+ buffer[36] = 0;
fclose(f);
return String::stringWithUTF8Characters(buffer);
}
diff --git a/src/core/basetypes/com_libmailcore_MainThreadUtils.h b/src/core/basetypes/com_libmailcore_MainThreadUtils.h
new file mode 100644
index 00000000..327d9910
--- /dev/null
+++ b/src/core/basetypes/com_libmailcore_MainThreadUtils.h
@@ -0,0 +1,37 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class com_libmailcore_MainThreadUtils */
+
+#ifndef _Included_com_libmailcore_MainThreadUtils
+#define _Included_com_libmailcore_MainThreadUtils
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_libmailcore_MainThreadUtils
+ * Method: setupNative
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_libmailcore_MainThreadUtils_setupNative
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_libmailcore_MainThreadUtils
+ * Method: runIdentifier
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_libmailcore_MainThreadUtils_runIdentifier
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_libmailcore_MainThreadUtils
+ * Method: runIdentifierAndNotify
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_libmailcore_MainThreadUtils_runIdentifierAndNotify
+ (JNIEnv *, jobject, jlong);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/core/security/MCCertificateUtils.cpp b/src/core/security/MCCertificateUtils.cpp
index f2345e90..2130714b 100644
--- a/src/core/security/MCCertificateUtils.cpp
+++ b/src/core/security/MCCertificateUtils.cpp
@@ -19,6 +19,8 @@
#include <openssl/err.h>
#endif
+#include <dirent.h>
+
#include "MCLog.h"
bool mailcore::checkCertificate(mailstream * stream, String * hostname)
@@ -97,6 +99,9 @@ err:
X509_STORE * store = NULL;
X509_STORE_CTX * storectx = NULL;
STACK_OF(X509) * certificates = NULL;
+ DIR * dir = NULL;
+ struct dirent * ent = NULL;
+ FILE * f = NULL;
int status;
carray * cCerts = mailstream_get_certificate_chain(stream);
@@ -127,6 +132,25 @@ err:
previousCert = nextCert;
}
CertCloseStore(systemStore, 0);
+#elif defined(ANDROID) || defined(__ANDROID__)
+ dir = opendir("/system/etc/security/cacerts");
+ while (ent = readdir(dir)) {
+ if (ent->d_name[0] == '.') {
+ continue;
+ }
+ char filename[1024];
+ snprintf(filename, sizeof(filename), "/system/etc/security/cacerts/%s", ent->d_name);
+ f = fopen(filename, "rb");
+ if (f != NULL) {
+ X509 * cert = PEM_read_X509(f, NULL, NULL, NULL);
+ if (cert != NULL) {
+ X509_STORE_add_cert(store, cert);
+ X509_free(cert);
+ }
+ fclose(f);
+ }
+ }
+ closedir(dir);
#endif
status = X509_STORE_set_default_paths(store);
diff --git a/tests/test-all.cpp b/tests/test-all.cpp
index 3372811d..9b506792 100644
--- a/tests/test-all.cpp
+++ b/tests/test-all.cpp
@@ -12,7 +12,7 @@
#if __APPLE__
#include <CoreFoundation/CoreFoundation.h>
#endif
-#if __linux__
+#if __linux__ && !defined(ANDROID) && !defined(__ANDROID__)
#include <glib.h>
#endif
#ifdef _MSC_VER
@@ -22,7 +22,7 @@
static mailcore::String * password = NULL;
static mailcore::String * displayName = NULL;
static mailcore::String * email = NULL;
-#if __linux
+#if __linux__ && !defined(ANDROID) && !defined(__ANDROID__)
static GMainLoop * s_main_loop = NULL;
#endif
@@ -42,7 +42,7 @@ static void mainLoop(void)
{
#if __APPLE__
CFRunLoopRun();
-#elif __linux__
+#elif __linux__ && !defined(ANDROID) && !defined(__ANDROID__)
g_main_loop_run(s_main_loop);
#elif defined(_MSC_VER)
win32MainLoop();
@@ -360,7 +360,7 @@ void testAll()
password = MCSTR("MyP4ssw0rd");
displayName = MCSTR("My Email");
-#if __linux__
+#if __linux__ && !defined(ANDROID) && !defined(__ANDROID__)
s_main_loop = g_main_loop_new (NULL, FALSE);
#endif