From 509ebe9aaf956a4f408c7596d105735f54c7b382 Mon Sep 17 00:00:00 2001 From: "B. Petersen" Date: Sun, 19 Aug 2018 00:47:58 +0200 Subject: [PATCH] handle log events, http-get event --- jni/dc_wrapper.c | 4 +- src/com/b44t/messenger/DcContext.java | 6 +- .../securesms/ApplicationContext.java | 3 +- .../securesms/ApplicationDcContext.java | 79 +++++++++++++++- .../securesms/ForegroundDetector.java | 89 +++++++++++++++++++ 5 files changed, 174 insertions(+), 7 deletions(-) create mode 100644 src/org/thoughtcrime/securesms/ForegroundDetector.java diff --git a/jni/dc_wrapper.c b/jni/dc_wrapper.c index 9e9693461..0bc2dd6a4 100644 --- a/jni/dc_wrapper.c +++ b/jni/dc_wrapper.c @@ -1244,7 +1244,7 @@ JNIEXPORT void Java_com_b44t_messenger_DcLot_DcLotUnref(JNIEnv *env, jclass cls, ******************************************************************************/ -JNIEXPORT jstring Java_com_b44t_messenger_DcContext_CPtr2String(JNIEnv *env, jclass cls, jlong hStr) +JNIEXPORT jstring Java_com_b44t_messenger_DcContext_dataToString(JNIEnv *env, jclass cls, jlong hStr) { /* the callback may return a long that represents a pointer to a C-String; this function creates a Java-string from such values. */ if( hStr == 0 ) { @@ -1255,7 +1255,7 @@ JNIEXPORT jstring Java_com_b44t_messenger_DcContext_CPtr2String(JNIEnv *env, jcl } -JNIEXPORT jlong Java_com_b44t_messenger_DcContext_String2CPtr(JNIEnv *env, jclass cls, jstring str) +JNIEXPORT jlong Java_com_b44t_messenger_DcContext_stringToData(JNIEnv *env, jclass cls, jstring str) { char* hStr = NULL; if( str ) { diff --git a/src/com/b44t/messenger/DcContext.java b/src/com/b44t/messenger/DcContext.java index 02a3557c5..cb064d14a 100644 --- a/src/com/b44t/messenger/DcContext.java +++ b/src/com/b44t/messenger/DcContext.java @@ -146,6 +146,10 @@ public class DcContext { return 0; } + // helper to get/return strings from/to handleEvent() + public native static String dataToString(long hString); + public native static long stringToData(String str); + // working with raw c-data private long m_hContext = 0; // must not be renamed as referenced by JNI private native long DcContextNew(String osName); @@ -153,6 +157,4 @@ public class DcContext { private native static long DcContextGetChat(long hContext, int chat_id); private native static long DcContextGetMsg(long hMailbox, int id); private native static long DcContextGetContact(long hContext, int id); - public native static String CPtr2String(long hString); - public native static long String2CPtr(String str); } diff --git a/src/org/thoughtcrime/securesms/ApplicationContext.java b/src/org/thoughtcrime/securesms/ApplicationContext.java index 55720471d..3936dd5ed 100644 --- a/src/org/thoughtcrime/securesms/ApplicationContext.java +++ b/src/org/thoughtcrime/securesms/ApplicationContext.java @@ -93,8 +93,7 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc super.onCreate(); System.loadLibrary("native-utils"); - dcContext = new ApplicationDcContext(); - dcContext.open("foo"); + dcContext = new ApplicationDcContext(this); initializeRandomNumberFix(); initializeLogging(); diff --git a/src/org/thoughtcrime/securesms/ApplicationDcContext.java b/src/org/thoughtcrime/securesms/ApplicationDcContext.java index 438bb9844..4026e7257 100644 --- a/src/org/thoughtcrime/securesms/ApplicationDcContext.java +++ b/src/org/thoughtcrime/securesms/ApplicationDcContext.java @@ -16,16 +16,93 @@ */ package org.thoughtcrime.securesms; +import android.content.Context; +import android.util.Log; +import android.widget.Toast; + import com.b44t.messenger.DcContext; +import org.thoughtcrime.securesms.util.Util; + +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; + public class ApplicationDcContext extends DcContext { - public ApplicationDcContext() { + public static final Object lastErrorLock = new Object(); + public static int lastErrorCode = 0; + public static String lastErrorString = ""; + public static boolean showNextErrorAsToast = true; + public Context context; + + public ApplicationDcContext(Context context) { super("Android"); + this.context = context; + new ForegroundDetector(ApplicationContext.getInstance(context)); } @Override public long handleEvent(final int event, final long data1, final long data2) { + switch(event) { + case DC_EVENT_INFO: + Log.i("DeltaChat", dataToString(data2)); + break; + + case DC_EVENT_WARNING: + Log.w("DeltaChat", dataToString(data2)); + break; + + case DC_EVENT_ERROR: + Log.e("DeltaChat", dataToString(data2)); + synchronized (lastErrorLock) { + lastErrorCode = (int)data1; + lastErrorString = dataToString(data2); + } + Util.runOnMain(new Runnable() { + @Override + public void run() { + synchronized (lastErrorLock) { + if (showNextErrorAsToast) { + if (ForegroundDetector.getInstance().isForeground()) { + Toast.makeText(context, lastErrorString, Toast.LENGTH_LONG).show(); + } + } + showNextErrorAsToast = true; + } + } + }); + break; + + case DC_EVENT_HTTP_GET: + String httpContent = null; + try { + URL url = new URL(dataToString(data1)); + HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); + try { + urlConnection.setConnectTimeout(10*1000); + InputStream inputStream = new BufferedInputStream(urlConnection.getInputStream()); + + BufferedReader r = new BufferedReader(new InputStreamReader(inputStream)); + + StringBuilder total = new StringBuilder(); + String line; + while ((line = r.readLine()) != null) { + total.append(line).append('\n'); + } + httpContent = total.toString(); + } finally { + urlConnection.disconnect(); + } + } + catch(Exception e) { + e.printStackTrace(); + } + return stringToData(httpContent); + } return 0; } } diff --git a/src/org/thoughtcrime/securesms/ForegroundDetector.java b/src/org/thoughtcrime/securesms/ForegroundDetector.java new file mode 100644 index 000000000..8775566ae --- /dev/null +++ b/src/org/thoughtcrime/securesms/ForegroundDetector.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2018 Delta Chat contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.thoughtcrime.securesms; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.app.Application; +import android.os.Bundle; + + +@SuppressLint("NewApi") +public class ForegroundDetector implements Application.ActivityLifecycleCallbacks { + + private int refs = 0; + private static ForegroundDetector Instance = null; + + public static ForegroundDetector getInstance() { + return Instance; + } + + public ForegroundDetector(Application application) { + Instance = this; + application.registerActivityLifecycleCallbacks(this); + } + + public boolean isForeground() { + return refs > 0; + } + + public boolean isBackground() { + return refs == 0; + } + + @Override + public void onActivityStarted(Activity activity) { + refs++; + + //applicationContext.stopService(new Intent(applicationContext, KeepAliveService.class)); + //ApplicationLoader.startThreads(); // we call this without checking getPermanentPush() to have a simple guarantee that push is always active when the app is in foregroud (startIdleThread makes sure the thread is not started twice) + } + + + @Override + public void onActivityStopped(Activity activity) { + if( refs <= 0 ) { + return; + } + + refs--; + if (refs == 0) { + //ApplicationLoader.afterForgroundWakeLock.acquire(60*1000); + } + } + + @Override + public void onActivityCreated(Activity activity, Bundle savedInstanceState) { + } + + @Override + public void onActivityResumed(Activity activity) { + } + + @Override + public void onActivityPaused(Activity activity) { + // pause/resume will also be called when the app is partially covered by a dialog + } + + @Override + public void onActivitySaveInstanceState(Activity activity, Bundle outState) { + } + + @Override + public void onActivityDestroyed(Activity activity) { + } +}