Log and send native lib load error with HA crashes, fixed emoji scale with custom font size, removed all lib dependency in native code

This commit is contained in:
DrKLO 2014-06-15 12:03:43 +04:00
parent 68aeaeefc3
commit a87968cefc
10 changed files with 184 additions and 60 deletions

View file

@ -81,7 +81,7 @@ android {
defaultConfig { defaultConfig {
minSdkVersion 8 minSdkVersion 8
targetSdkVersion 19 targetSdkVersion 19
versionCode 256 versionCode 257
versionName "1.5.3" versionName "1.5.4"
} }
} }

View file

@ -3,11 +3,11 @@ LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS) include $(CLEAR_VARS)
LOCAL_PRELINK_MODULE := false LOCAL_PRELINK_MODULE := false
LOCAL_MODULE := tmessages LOCAL_MODULE := tmessages
LOCAL_CFLAGS := -w -std=gnu99 -O3 -DNULL=0 -DSOCKLEN_T=socklen_t -DLOCALE_NOT_USED -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 LOCAL_CFLAGS := -w -std=gnu99 -O3 -DNULL=0 -DSOCKLEN_T=socklen_t -DLOCALE_NOT_USED -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 -DLOG_DISABLED
LOCAL_CFLAGS += -Drestrict='' -D__EMX__ -DOPUS_BUILD -DFIXED_POINT -DUSE_ALLOCA -DHAVE_LRINT -DHAVE_LRINTF -fno-math-errno LOCAL_CFLAGS += -Drestrict='' -D__EMX__ -DOPUS_BUILD -DFIXED_POINT -DUSE_ALLOCA -DHAVE_LRINT -DHAVE_LRINTF -fno-math-errno
LOCAL_CFLAGS += -DANDROID_NDK -DDISABLE_IMPORTGL -fno-strict-aliasing -fprefetch-loop-arrays -DAVOID_TABLES -DANDROID_TILE_BASED_DECODE -DANDROID_ARMV6_IDCT LOCAL_CFLAGS += -DANDROID_NDK -DDISABLE_IMPORTGL -fno-strict-aliasing -fprefetch-loop-arrays -DAVOID_TABLES -DANDROID_TILE_BASED_DECODE -DANDROID_ARMV6_IDCT
LOCAL_CPPFLAGS := -DBSD=1 -ffast-math -O3 -funroll-loops LOCAL_CPPFLAGS := -DBSD=1 -ffast-math -O3 -funroll-loops
LOCAL_LDLIBS := -llog -lm #LOCAL_LDLIBS := -llog
LOCAL_SRC_FILES := \ LOCAL_SRC_FILES := \
./opus/src/opus.c \ ./opus/src/opus.c \

View file

@ -5,10 +5,17 @@
#include <jni.h> #include <jni.h>
#define LOG_TAG "tmessages_native" #define LOG_TAG "tmessages_native"
#ifndef LOG_DISABLED
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__) #define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)
#else
#define LOGI(...)
#define LOGD(...)
#define LOGE(...)
#define LOGV(...)
#endif
#ifndef max #ifndef max
#define max(x, y) ((x) > (y)) ? (x) : (y) #define max(x, y) ((x) > (y)) ? (x) : (y)

View file

@ -347,9 +347,14 @@ public class Emoji {
canvas.drawRect(getBounds(), placeholderPaint); canvas.drawRect(getBounds(), placeholderPaint);
return; return;
} }
int size = fullSize ? bigImgSize : drawImgSize; float scale = 1;
float scale = (float)size / (float)emojiFullSize; int offset = 0;
int offset = (getBounds().width() - size) / 2; if (fullSize) {
scale = (float) bigImgSize / (float) emojiFullSize;
offset = (getBounds().width() - bigImgSize) / 2;
} else {
scale = (float) getBounds().width() / (float) emojiFullSize;
}
canvas.save(); canvas.save();
canvas.scale(scale, scale); canvas.scale(scale, scale);
@ -461,12 +466,17 @@ public class Emoji {
public static class EmojiSpan extends ImageSpan { public static class EmojiSpan extends ImageSpan {
private Paint.FontMetricsInt fontMetrics = null; private Paint.FontMetricsInt fontMetrics = null;
private int size = Utilities.dp(20); int size = Utilities.dp(20);
public EmojiSpan(Drawable d, int verticalAlignment, int s, Paint.FontMetricsInt original) { public EmojiSpan(Drawable d, int verticalAlignment, int s, Paint.FontMetricsInt original) {
super(d, verticalAlignment); super(d, verticalAlignment);
fontMetrics = original; fontMetrics = original;
size = s; if (original != null) {
size = Math.abs(fontMetrics.descent) + Math.abs(fontMetrics.ascent);
if (size == 0) {
size = Utilities.dp(20);
}
}
} }
@Override @Override
@ -495,6 +505,9 @@ public class Emoji {
fm.top = fontMetrics.top; fm.top = fontMetrics.top;
fm.bottom = fontMetrics.bottom; fm.bottom = fontMetrics.bottom;
} }
if (getDrawable() != null) {
getDrawable().setBounds(0, 0, size, size);
}
return size; return size;
} }
} }

View file

@ -16,6 +16,7 @@ import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
@ -30,6 +31,49 @@ public class NativeLoader {
private static volatile boolean nativeLoaded = false; private static volatile boolean nativeLoaded = false;
public static void cleanNativeLog(Context context) {
try {
File sdCard = context.getFilesDir();
if (sdCard == null) {
return;
}
File file = new File(sdCard, "nativeer.log");
if (file == null || !file.exists()) {
return;
}
file.delete();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void writeNativeError(Context context, String info, Throwable throwable) {
try {
File sdCard = context.getFilesDir();
if (sdCard == null) {
return;
}
File file = new File(sdCard, "nativeer.log");
if (file == null) {
return;
}
FileOutputStream stream = new FileOutputStream(file);
OutputStreamWriter streamWriter = new OutputStreamWriter(stream);
streamWriter.write("info" + "\n");
streamWriter.write(throwable + "\n");
StackTraceElement[] stack = throwable.getStackTrace();
for (StackTraceElement el : stack) {
streamWriter.write(el + "\n");
}
streamWriter.flush();
streamWriter.close();
stream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private static File getNativeLibraryDir(Context context) { private static File getNativeLibraryDir(Context context) {
File f = null; File f = null;
if (context != null) { if (context != null) {
@ -48,6 +92,55 @@ public class NativeLoader {
return null; return null;
} }
private static boolean loadFromZip(Context context, File destLocalFile, String folder) {
ZipFile zipFile = null;
InputStream stream = null;
try {
zipFile = new ZipFile(context.getApplicationInfo().sourceDir);
ZipEntry entry = zipFile.getEntry("lib/" + folder + "/libtmessages.so");
if (entry == null) {
throw new Exception("Unable to find file in apk:" + "lib/" + folder + "/libtmessages.so");
}
stream = zipFile.getInputStream(entry);
OutputStream out = new FileOutputStream(destLocalFile);
byte[] buf = new byte[4096];
int len;
while ((len = stream.read(buf)) > 0) {
Thread.yield();
out.write(buf, 0, len);
}
out.close();
try {
System.load(destLocalFile.getAbsolutePath());
nativeLoaded = true;
} catch (Error e) {
FileLog.e("tmessages", e);
writeNativeError(context, "after zip", e);
}
return true;
} catch (Exception e) {
FileLog.e("tmessages", e);
writeNativeError(context, "zip", e);
} finally {
if (stream != null) {
try {
stream.close();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
if (zipFile != null) {
try {
zipFile.close();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
}
return false;
}
public static synchronized void initNativeLibs(Context context) { public static synchronized void initNativeLibs(Context context) {
if (nativeLoaded) { if (nativeLoaded) {
@ -55,6 +148,8 @@ public class NativeLoader {
} }
try { try {
cleanNativeLog(context);
String folder = null; String folder = null;
long libSize = 0; long libSize = 0;
long libSize2 = 0; long libSize2 = 0;
@ -82,6 +177,7 @@ public class NativeLoader {
} }
} catch (Exception e) { } catch (Exception e) {
FileLog.e("tmessages", e); FileLog.e("tmessages", e);
writeNativeError(context, "arch", e);
folder = "armeabi"; folder = "armeabi";
libSize = sizes[0]; libSize = sizes[0];
libSize2 = sizes[1]; libSize2 = sizes[1];
@ -98,6 +194,7 @@ public class NativeLoader {
return; return;
} catch (Error e) { } catch (Error e) {
FileLog.e("tmessages", e); FileLog.e("tmessages", e);
writeNativeError(context, "normal", e);
} }
} }
} }
@ -112,6 +209,7 @@ public class NativeLoader {
return; return;
} catch (Error e) { } catch (Error e) {
FileLog.e("tmessages", e); FileLog.e("tmessages", e);
writeNativeError(context, "local", e);
} }
} else { } else {
destLocalFile.delete(); destLocalFile.delete();
@ -120,58 +218,20 @@ public class NativeLoader {
FileLog.e("tmessages", "Library not found, arch = " + folder); FileLog.e("tmessages", "Library not found, arch = " + folder);
ZipFile zipFile = null; if (!loadFromZip(context, destLocalFile, folder) && folder.equals("armeabi-v7a")) {
InputStream stream = null; folder = "armeabi";
try { loadFromZip(context, destLocalFile, folder);
zipFile = new ZipFile(context.getApplicationInfo().sourceDir);
ZipEntry entry = zipFile.getEntry("lib/" + folder + "/libtmessages.so");
if (entry == null) {
throw new Exception("Unable to find file in apk:" + "lib/" + folder + "/libtmessages.so");
}
stream = zipFile.getInputStream(entry);
OutputStream out = new FileOutputStream(destLocalFile);
byte[] buf = new byte[4096];
int len;
while ((len = stream.read(buf)) > 0) {
Thread.yield();
out.write(buf, 0, len);
}
out.close();
try {
System.load(destLocalFile.getAbsolutePath());
nativeLoaded = true;
} catch (Error e) {
FileLog.e("tmessages", e);
}
return;
} catch (Exception e) {
FileLog.e("tmessages", e);
} finally {
if (stream != null) {
try {
stream.close();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
if (zipFile != null) {
try {
zipFile.close();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
} }
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
writeNativeError(context, "", e);
} }
try { try {
System.loadLibrary("tmessages"); System.loadLibrary("tmessages");
nativeLoaded = true; nativeLoaded = true;
} catch (Error e) { } catch (Error e) {
writeNativeError(context, "last chance", e);
FileLog.e("tmessages", e); FileLog.e("tmessages", e);
} }
} }

View file

@ -34,10 +34,12 @@ import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import net.hockeyapp.android.CrashManager; import net.hockeyapp.android.CrashManager;
import net.hockeyapp.android.CrashManagerListener;
import net.hockeyapp.android.UpdateManager; import net.hockeyapp.android.UpdateManager;
import org.telegram.ui.ApplicationLoader; import org.telegram.ui.ApplicationLoader;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
@ -45,6 +47,7 @@ import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream; import java.io.OutputStream;
import java.math.BigInteger; import java.math.BigInteger;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
@ -986,7 +989,47 @@ public class Utilities {
} }
public static void checkForCrashes(Activity context) { public static void checkForCrashes(Activity context) {
CrashManager.register(context, BuildVars.HOCKEY_APP_HASH); CrashManager.register(context, BuildVars.HOCKEY_APP_HASH, new CrashManagerListener() {
@Override
public boolean includeDeviceData() {
return true;
}
@Override
public String getDescription() {
String description = "";
try {
File sdCard = ApplicationLoader.applicationContext.getFilesDir();
if (sdCard == null) {
return description;
}
File file = new File(sdCard, "nativeer.log");
if (file == null || !file.exists()) {
return description;
}
FileInputStream inputStream = new FileInputStream(file);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder log = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
log.append(line);
log.append("\n");
}
bufferedReader.close();
inputStream.close();
description = log.toString();
NativeLoader.cleanNativeLog(ApplicationLoader.applicationContext);
} catch (Exception e) {
e.printStackTrace();
}
return description;
}
});
} }
public static void checkForUpdates(Activity context) { public static void checkForUpdates(Activity context) {

View file

@ -20,7 +20,6 @@ import android.content.SharedPreferences;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Handler; import android.os.Handler;
@ -295,6 +294,7 @@ public class ApplicationLoader extends Application {
UserConfig.pushString = regid; UserConfig.pushString = regid;
UserConfig.registeredForPush = !isNew; UserConfig.registeredForPush = !isNew;
UserConfig.saveConfig(false); UserConfig.saveConfig(false);
if (UserConfig.getClientUserId() != 0) {
Utilities.RunOnUIThread(new Runnable() { Utilities.RunOnUIThread(new Runnable() {
@Override @Override
public void run() { public void run() {
@ -302,6 +302,7 @@ public class ApplicationLoader extends Application {
} }
}); });
} }
}
}); });
} }