mirror of
https://github.com/deltachat/deltachat-android.git
synced 2025-10-06 11:59:58 +02:00
get rid of open/close context
This commit is contained in:
parent
4782d18824
commit
d42eb1d920
4 changed files with 43 additions and 96 deletions
|
@ -173,14 +173,6 @@ static uint32_t* jintArray2uint32Pointer(JNIEnv* env, jintArray ja, int* ret_icn
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
typedef struct dc_jnicontext_t {
|
|
||||||
JavaVM* jvm; // JNIEnv cannot be shared between threads, so we share the JavaVM object
|
|
||||||
jclass cls;
|
|
||||||
jobject obj;
|
|
||||||
jmethodID methodId;
|
|
||||||
} dc_jnicontext_t;
|
|
||||||
|
|
||||||
|
|
||||||
static dc_context_t* get_dc_context(JNIEnv *env, jobject obj)
|
static dc_context_t* get_dc_context(JNIEnv *env, jobject obj)
|
||||||
{
|
{
|
||||||
static jfieldID fid = 0;
|
static jfieldID fid = 0;
|
||||||
|
@ -195,42 +187,12 @@ static dc_context_t* get_dc_context(JNIEnv *env, jobject obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uintptr_t s_context_callback_(dc_context_t* context, int event, uintptr_t data1, uintptr_t data2)
|
JNIEXPORT jlong Java_com_b44t_messenger_DcContext_createContextCPtr(JNIEnv *env, jobject obj, jstring osname, jstring dbfile)
|
||||||
{
|
{
|
||||||
jlong l;
|
|
||||||
JNIEnv* env;
|
|
||||||
dc_jnicontext_t* jnicontext = dc_get_userdata(context);
|
|
||||||
|
|
||||||
if (jnicontext==NULL || jnicontext->jvm==NULL || jnicontext->cls==NULL || jnicontext->obj==NULL || jnicontext->methodId==NULL) {
|
|
||||||
return 0; /* may happen on startup */
|
|
||||||
}
|
|
||||||
|
|
||||||
(*jnicontext->jvm)->GetEnv(jnicontext->jvm, (void**)&env, JNI_VERSION_1_6); // as this function may be called from _any_ thread, we cannot use a static pointer to JNIEnv
|
|
||||||
if (env==NULL) {
|
|
||||||
return 0; /* may happen on startup */
|
|
||||||
}
|
|
||||||
|
|
||||||
l = (*env)->CallLongMethod(env, jnicontext->obj, jnicontext->methodId, (jint)event, (jlong)data1, (jlong)data2);
|
|
||||||
return (uintptr_t)l;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
JNIEXPORT jlong Java_com_b44t_messenger_DcContext_createContextCPtr(JNIEnv *env, jobject obj, jstring osname)
|
|
||||||
{
|
|
||||||
jclass cls = (*env)->GetObjectClass(env, obj);
|
|
||||||
|
|
||||||
dc_jnicontext_t* jnicontext = calloc(1, sizeof(dc_jnicontext_t));
|
|
||||||
if (cls==NULL || jnicontext==NULL) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
(*env)->GetJavaVM(env, &jnicontext->jvm);
|
|
||||||
jnicontext->cls = (*env)->NewGlobalRef(env, cls);
|
|
||||||
jnicontext->obj = (*env)->NewGlobalRef(env, obj);
|
|
||||||
jnicontext->methodId = (*env)->GetMethodID(env, jnicontext->cls, "handleEvent","(IJJ)J" /*signature as "(param)ret" with I=int, J=long*/);
|
|
||||||
|
|
||||||
CHAR_REF(osname);
|
CHAR_REF(osname);
|
||||||
jlong contextCPtr = (jlong)dc_context_new(s_context_callback_, jnicontext, osnamePtr);
|
CHAR_REF(dbfile)
|
||||||
|
jlong contextCPtr = (jlong)dc_context_new(osnamePtr, dbfilePtr, NULL);
|
||||||
|
CHAR_UNREF(dbfile)
|
||||||
CHAR_UNREF(osname);
|
CHAR_UNREF(osname);
|
||||||
return contextCPtr;
|
return contextCPtr;
|
||||||
}
|
}
|
||||||
|
@ -244,21 +206,6 @@ JNIEXPORT void Java_com_b44t_messenger_DcContact_unrefContextCPtr(JNIEnv *env, j
|
||||||
|
|
||||||
/* DcContext - open/configure/connect/fetch */
|
/* DcContext - open/configure/connect/fetch */
|
||||||
|
|
||||||
JNIEXPORT jint Java_com_b44t_messenger_DcContext_open(JNIEnv *env, jobject obj, jstring dbfile)
|
|
||||||
{
|
|
||||||
CHAR_REF(dbfile);
|
|
||||||
jint ret = dc_open(get_dc_context(env, obj), dbfilePtr, NULL);
|
|
||||||
CHAR_UNREF(dbfile)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
JNIEXPORT void Java_com_b44t_messenger_DcContext_close(JNIEnv *env, jobject obj)
|
|
||||||
{
|
|
||||||
dc_close(get_dc_context(env, obj));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
JNIEXPORT void Java_com_b44t_messenger_DcContext_setStockTranslation(JNIEnv *env, jobject obj, jint stock_id, jstring translation)
|
JNIEXPORT void Java_com_b44t_messenger_DcContext_setStockTranslation(JNIEnv *env, jobject obj, jint stock_id, jstring translation)
|
||||||
{
|
{
|
||||||
CHAR_REF(translation);
|
CHAR_REF(translation);
|
||||||
|
@ -303,93 +250,79 @@ JNIEXPORT jint Java_com_b44t_messenger_DcContext_isConfigured(JNIEnv *env, jobje
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO-ASYNC: delete these functions, also in the java-part
|
||||||
JNIEXPORT void Java_com_b44t_messenger_DcContext_performImapJobs(JNIEnv *env, jobject obj)
|
JNIEXPORT void Java_com_b44t_messenger_DcContext_performImapJobs(JNIEnv *env, jobject obj)
|
||||||
{
|
{
|
||||||
dc_perform_imap_jobs(get_dc_context(env, obj));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
JNIEXPORT void Java_com_b44t_messenger_DcContext_performImapIdle(JNIEnv *env, jobject obj)
|
JNIEXPORT void Java_com_b44t_messenger_DcContext_performImapIdle(JNIEnv *env, jobject obj)
|
||||||
{
|
{
|
||||||
dc_perform_imap_idle(get_dc_context(env, obj));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
JNIEXPORT void Java_com_b44t_messenger_DcContext_performImapFetch(JNIEnv *env, jobject obj)
|
JNIEXPORT void Java_com_b44t_messenger_DcContext_performImapFetch(JNIEnv *env, jobject obj)
|
||||||
{
|
{
|
||||||
dc_perform_imap_fetch(get_dc_context(env, obj));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
JNIEXPORT void Java_com_b44t_messenger_DcContext_interruptImapIdle(JNIEnv *env, jobject obj)
|
JNIEXPORT void Java_com_b44t_messenger_DcContext_interruptImapIdle(JNIEnv *env, jobject obj)
|
||||||
{
|
{
|
||||||
dc_interrupt_imap_idle(get_dc_context(env, obj));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
JNIEXPORT void Java_com_b44t_messenger_DcContext_performSentboxJobs(JNIEnv *env, jobject obj)
|
JNIEXPORT void Java_com_b44t_messenger_DcContext_performSentboxJobs(JNIEnv *env, jobject obj)
|
||||||
{
|
{
|
||||||
dc_perform_sentbox_jobs(get_dc_context(env, obj));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
JNIEXPORT void Java_com_b44t_messenger_DcContext_performSentboxFetch(JNIEnv *env, jobject obj)
|
JNIEXPORT void Java_com_b44t_messenger_DcContext_performSentboxFetch(JNIEnv *env, jobject obj)
|
||||||
{
|
{
|
||||||
dc_perform_sentbox_fetch(get_dc_context(env, obj));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
JNIEXPORT void Java_com_b44t_messenger_DcContext_performSentboxIdle(JNIEnv *env, jobject obj)
|
JNIEXPORT void Java_com_b44t_messenger_DcContext_performSentboxIdle(JNIEnv *env, jobject obj)
|
||||||
{
|
{
|
||||||
dc_perform_sentbox_idle(get_dc_context(env, obj));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
JNIEXPORT void Java_com_b44t_messenger_DcContext_interruptSentboxIdle(JNIEnv *env, jobject obj)
|
JNIEXPORT void Java_com_b44t_messenger_DcContext_interruptSentboxIdle(JNIEnv *env, jobject obj)
|
||||||
{
|
{
|
||||||
dc_interrupt_sentbox_idle(get_dc_context(env, obj));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
JNIEXPORT void Java_com_b44t_messenger_DcContext_performMvboxJobs(JNIEnv *env, jobject obj)
|
JNIEXPORT void Java_com_b44t_messenger_DcContext_performMvboxJobs(JNIEnv *env, jobject obj)
|
||||||
{
|
{
|
||||||
dc_perform_mvbox_jobs(get_dc_context(env, obj));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
JNIEXPORT void Java_com_b44t_messenger_DcContext_performMvboxFetch(JNIEnv *env, jobject obj)
|
JNIEXPORT void Java_com_b44t_messenger_DcContext_performMvboxFetch(JNIEnv *env, jobject obj)
|
||||||
{
|
{
|
||||||
dc_perform_mvbox_fetch(get_dc_context(env, obj));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
JNIEXPORT void Java_com_b44t_messenger_DcContext_performMvboxIdle(JNIEnv *env, jobject obj)
|
JNIEXPORT void Java_com_b44t_messenger_DcContext_performMvboxIdle(JNIEnv *env, jobject obj)
|
||||||
{
|
{
|
||||||
dc_perform_mvbox_idle(get_dc_context(env, obj));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
JNIEXPORT void Java_com_b44t_messenger_DcContext_interruptMvboxIdle(JNIEnv *env, jobject obj)
|
JNIEXPORT void Java_com_b44t_messenger_DcContext_interruptMvboxIdle(JNIEnv *env, jobject obj)
|
||||||
{
|
{
|
||||||
dc_interrupt_mvbox_idle(get_dc_context(env, obj));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
JNIEXPORT void Java_com_b44t_messenger_DcContext_performSmtpJobs(JNIEnv *env, jobject obj)
|
JNIEXPORT void Java_com_b44t_messenger_DcContext_performSmtpJobs(JNIEnv *env, jobject obj)
|
||||||
{
|
{
|
||||||
dc_perform_smtp_jobs(get_dc_context(env, obj));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
JNIEXPORT void Java_com_b44t_messenger_DcContext_performSmtpIdle(JNIEnv *env, jobject obj)
|
JNIEXPORT void Java_com_b44t_messenger_DcContext_performSmtpIdle(JNIEnv *env, jobject obj)
|
||||||
{
|
{
|
||||||
dc_perform_smtp_idle(get_dc_context(env, obj));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
JNIEXPORT void Java_com_b44t_messenger_DcContext_interruptSmtpIdle(JNIEnv *env, jobject obj)
|
JNIEXPORT void Java_com_b44t_messenger_DcContext_interruptSmtpIdle(JNIEnv *env, jobject obj)
|
||||||
{
|
{
|
||||||
dc_interrupt_smtp_idle(get_dc_context(env, obj));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -72,20 +72,27 @@ public class DcContext {
|
||||||
public final static int DC_EMPTY_MVBOX = 0x01;
|
public final static int DC_EMPTY_MVBOX = 0x01;
|
||||||
public final static int DC_EMPTY_INBOX = 0x02;
|
public final static int DC_EMPTY_INBOX = 0x02;
|
||||||
|
|
||||||
public DcContext(String osName) {
|
public DcContext(String osName, String dbfile) {
|
||||||
handleEvent(0,0,0); // call handleEvent() to make sure it is not optimized away and JNI won't find it
|
contextCPtr = createContextCPtr(osName, dbfile);
|
||||||
contextCPtr = createContextCPtr(osName);
|
}
|
||||||
|
|
||||||
|
public boolean isOk() {
|
||||||
|
return contextCPtr != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void finalize() throws Throwable {
|
protected void finalize() throws Throwable {
|
||||||
super.finalize();
|
super.finalize();
|
||||||
unrefContextCPtr();
|
unref();
|
||||||
contextCPtr = 0;
|
}
|
||||||
|
|
||||||
|
public void unref() {
|
||||||
|
if (contextCPtr != 0) {
|
||||||
|
unrefContextCPtr();
|
||||||
|
contextCPtr = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public native int open (String dbfile);
|
|
||||||
public native void close ();
|
|
||||||
public native void setStockTranslation (int stockId, String translation);
|
public native void setStockTranslation (int stockId, String translation);
|
||||||
public native String getBlobdir ();
|
public native String getBlobdir ();
|
||||||
public native void configure ();
|
public native void configure ();
|
||||||
|
@ -189,11 +196,6 @@ public class DcContext {
|
||||||
*/
|
*/
|
||||||
public native boolean setLocation (float latitude, float longitude, float accuracy);
|
public native boolean setLocation (float latitude, float longitude, float accuracy);
|
||||||
|
|
||||||
// event handling - you should @Override this function in derived classes
|
|
||||||
public long handleEvent(int event, long data1, long data2) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// helper to get/return strings from/to handleEvent()
|
// helper to get/return strings from/to handleEvent()
|
||||||
public native static boolean data1IsString(int event);
|
public native static boolean data1IsString(int event);
|
||||||
public native static boolean data2IsString(int event);
|
public native static boolean data2IsString(int event);
|
||||||
|
@ -201,7 +203,7 @@ public class DcContext {
|
||||||
|
|
||||||
// working with raw c-data
|
// working with raw c-data
|
||||||
private long contextCPtr; // CAVE: the name is referenced in the JNI
|
private long contextCPtr; // CAVE: the name is referenced in the JNI
|
||||||
private native long createContextCPtr(String osName);
|
private native long createContextCPtr(String osName, String dbfile);
|
||||||
private native void unrefContextCPtr ();
|
private native void unrefContextCPtr ();
|
||||||
public native long createMsgCPtr (int viewtype);
|
public native long createMsgCPtr (int viewtype);
|
||||||
private native long getChatlistCPtr (int listflags, String query, int queryId);
|
private native long getChatlistCPtr (int listflags, String query, int queryId);
|
||||||
|
|
|
@ -65,8 +65,8 @@ public class AccountManager {
|
||||||
private @Nullable Account maybeGetAccount(File file) {
|
private @Nullable Account maybeGetAccount(File file) {
|
||||||
try {
|
try {
|
||||||
if (!file.isDirectory() && file.getName().endsWith(".db")) {
|
if (!file.isDirectory() && file.getName().endsWith(".db")) {
|
||||||
DcContext testContext = new DcContext(null);
|
DcContext testContext = new DcContext(null, file.getAbsolutePath());
|
||||||
if (testContext.open(file.getAbsolutePath()) != 0) {
|
if (testContext.isOk()) {
|
||||||
Account ret = new Account();
|
Account ret = new Account();
|
||||||
ret.dbName = file.getName();
|
ret.dbName = file.getName();
|
||||||
ret.displayname = testContext.getConfig("displayname");
|
ret.displayname = testContext.getConfig("displayname");
|
||||||
|
@ -99,7 +99,7 @@ public class AccountManager {
|
||||||
// getSelectedAccount()
|
// getSelectedAccount()
|
||||||
ApplicationContext appContext = (ApplicationContext)context.getApplicationContext();
|
ApplicationContext appContext = (ApplicationContext)context.getApplicationContext();
|
||||||
appContext.dcContext.stopThreads();
|
appContext.dcContext.stopThreads();
|
||||||
appContext.dcContext.close();
|
appContext.dcContext.unref();
|
||||||
appContext.dcContext = new ApplicationDcContext(context);
|
appContext.dcContext = new ApplicationDcContext(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,10 +243,10 @@ public class AccountManager {
|
||||||
if (deleteDbName!=null) {
|
if (deleteDbName!=null) {
|
||||||
// used to delete the previous account, however, as a resilience check, make sure,
|
// used to delete the previous account, however, as a resilience check, make sure,
|
||||||
// we do not delete already configured accounts (just in case sth. changes the flow of activities)
|
// we do not delete already configured accounts (just in case sth. changes the flow of activities)
|
||||||
DcContext testContext = new DcContext(null);
|
DcContext testContext = new DcContext(null, new File(activity.getFilesDir(), deleteDbName).getAbsolutePath());
|
||||||
if (testContext.open(new File(activity.getFilesDir(), deleteDbName).getAbsolutePath()) != 0) {
|
if (testContext.isOk()) {
|
||||||
if (testContext.isConfigured() == 0) {
|
if (testContext.isConfigured() == 0) {
|
||||||
testContext.close();
|
testContext.unref();
|
||||||
AccountManager.getInstance().deleteAccount(activity, deleteDbName);
|
AccountManager.getInstance().deleteAccount(activity, deleteDbName);
|
||||||
PreferenceManager.getDefaultSharedPreferences(activity)
|
PreferenceManager.getDefaultSharedPreferences(activity)
|
||||||
.edit().putString("prev_account_db_name", "").apply();
|
.edit().putString("prev_account_db_name", "").apply();
|
||||||
|
|
|
@ -56,12 +56,9 @@ public class ApplicationDcContext extends DcContext {
|
||||||
public NotificationCenter notificationCenter;
|
public NotificationCenter notificationCenter;
|
||||||
|
|
||||||
public ApplicationDcContext(Context context) {
|
public ApplicationDcContext(Context context) {
|
||||||
super("Android "+BuildConfig.VERSION_NAME);
|
super("Android "+BuildConfig.VERSION_NAME, AccountManager.getInstance().getSelectedAccount(context).getAbsolutePath());
|
||||||
this.context = context;
|
this.context = context;
|
||||||
|
|
||||||
File dbfile = AccountManager.getInstance().getSelectedAccount(context);
|
|
||||||
open(dbfile.getAbsolutePath());
|
|
||||||
|
|
||||||
// migration, can be removed after some versions (added 5/2020)
|
// migration, can be removed after some versions (added 5/2020)
|
||||||
// (this will convert only for one account, but that is fine, multi-account is experimental anyway)
|
// (this will convert only for one account, but that is fine, multi-account is experimental anyway)
|
||||||
try {
|
try {
|
||||||
|
@ -341,6 +338,10 @@ public class ApplicationDcContext extends DcContext {
|
||||||
public boolean run = true;
|
public boolean run = true;
|
||||||
|
|
||||||
public void startThreads(int flags) {
|
public void startThreads(int flags) {
|
||||||
|
|
||||||
|
// TODO-ASYNC: remove this function, handle the flags differently
|
||||||
|
|
||||||
|
/*
|
||||||
synchronized (threadsCritical) {
|
synchronized (threadsCritical) {
|
||||||
|
|
||||||
if (imapThread == null || !imapThread.isAlive()) {
|
if (imapThread == null || !imapThread.isAlive()) {
|
||||||
|
@ -432,9 +433,14 @@ public class ApplicationDcContext extends DcContext {
|
||||||
smtpThread.start();
|
smtpThread.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
public void waitForThreadsExecutedOnce() {
|
public void waitForThreadsExecutedOnce() {
|
||||||
|
|
||||||
|
// TODO-ASYNC
|
||||||
|
|
||||||
|
/*
|
||||||
while(true) {
|
while(true) {
|
||||||
synchronized (incLoopsCritical) {
|
synchronized (incLoopsCritical) {
|
||||||
if(inboxLoops>0 && mvboxLoops>0 && smtpLoops>0) {
|
if(inboxLoops>0 && mvboxLoops>0 && smtpLoops>0) {
|
||||||
|
@ -443,10 +449,15 @@ public class ApplicationDcContext extends DcContext {
|
||||||
}
|
}
|
||||||
Util.sleep(500);
|
Util.sleep(500);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stopThreads() {
|
public void stopThreads() {
|
||||||
notificationCenter.removeAllNotifiations();
|
notificationCenter.removeAllNotifiations();
|
||||||
|
|
||||||
|
// TODO-ASYNC
|
||||||
|
|
||||||
|
/*
|
||||||
run = false;
|
run = false;
|
||||||
synchronized (threadsCritical) {
|
synchronized (threadsCritical) {
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -470,6 +481,7 @@ public class ApplicationDcContext extends DcContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Log.i(TAG, "!!!!!!!!!!!! threads stopped");
|
Log.i(TAG, "!!!!!!!!!!!! threads stopped");
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -557,7 +569,7 @@ public class ApplicationDcContext extends DcContext {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// TODO-ASYNC: make this work again
|
||||||
public long handleEvent(final int event, long data1, long data2) {
|
public long handleEvent(final int event, long data1, long data2) {
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case DC_EVENT_INFO:
|
case DC_EVENT_INFO:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue