summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArne Schwabe <arne@rfc2549.org>2016-04-25 11:23:42 +0300
committerArne Schwabe <arne@rfc2549.org>2016-04-25 11:23:42 +0300
commit32478332830697ef36a6bc6bcc0ef3b914a86e6d (patch)
tree2184d8902a3a68d653cd5df6535c5019a34ad4d5
parent4d8c036c367ad861a3d53a3a8c60074b9ad2d923 (diff)
Implement custom marschal/unmarschal for LogItem, hopefully this will fix the problems.
-rw-r--r--main/src/main/java/de/blinkt/openvpn/core/LogFileHandler.java25
-rw-r--r--main/src/main/java/de/blinkt/openvpn/core/LogItem.java375
-rw-r--r--main/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java4
-rw-r--r--main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java228
-rw-r--r--main/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java3
-rw-r--r--main/src/test/java/de/blinkt/openvpn/core/TestLogFileHandler.java54
6 files changed, 437 insertions, 252 deletions
diff --git a/main/src/main/java/de/blinkt/openvpn/core/LogFileHandler.java b/main/src/main/java/de/blinkt/openvpn/core/LogFileHandler.java
index dfa6c5fa..7bb9d134 100644
--- a/main/src/main/java/de/blinkt/openvpn/core/LogFileHandler.java
+++ b/main/src/main/java/de/blinkt/openvpn/core/LogFileHandler.java
@@ -8,7 +8,6 @@ package de.blinkt.openvpn.core;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
-import android.os.Parcel;
import java.io.BufferedInputStream;
import java.io.File;
@@ -18,6 +17,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.Locale;
@@ -50,14 +50,14 @@ class LogFileHandler extends Handler {
throw new RuntimeException("mLogFile not null");
readLogCache((File) msg.obj);
openLogFile((File) msg.obj);
- } else if (msg.what == LOG_MESSAGE && msg.obj instanceof VpnStatus.LogItem) {
+ } else if (msg.what == LOG_MESSAGE && msg.obj instanceof LogItem) {
// Ignore log messages if not yet initialized
if (mLogFile == null)
return;
- writeLogItemToDisk((VpnStatus.LogItem) msg.obj);
+ writeLogItemToDisk((LogItem) msg.obj);
} else if (msg.what == TRIM_LOG_FILE) {
trimLogFile();
- for (VpnStatus.LogItem li : VpnStatus.getlogbuffer())
+ for (LogItem li : VpnStatus.getlogbuffer())
writeLogItemToDisk(li);
} else if (msg.what == FLUSH_TO_DISK) {
flushToDisk();
@@ -84,15 +84,13 @@ class LogFileHandler extends Handler {
}
}
- private void writeLogItemToDisk(VpnStatus.LogItem li) throws IOException {
- Parcel p = Parcel.obtain();
- li.writeToParcel(p, 0);
+ private void writeLogItemToDisk(LogItem li) throws IOException {
+
// We do not really care if the log cache breaks between Android upgrades,
// write binary format to disc
- byte[] liBytes = p.marshall();
+ byte[] liBytes = li.getMarschaledBytes();
writeEscapedBytes(liBytes);
- p.recycle();
}
public void writeEscapedBytes(byte[] bytes) throws IOException {
@@ -211,11 +209,9 @@ class LogFileHandler extends Handler {
}
- protected void restoreLogItem(byte[] buf, int len) {
- Parcel p = Parcel.obtain();
- p.unmarshall(buf, 0, len);
- p.setDataPosition(0);
- VpnStatus.LogItem li = VpnStatus.LogItem.CREATOR.createFromParcel(p);
+ protected void restoreLogItem(byte[] buf, int len) throws UnsupportedEncodingException {
+
+ LogItem li = new LogItem(buf, len);
if (li.verify()) {
VpnStatus.newLogItem(li, true);
} else {
@@ -223,7 +219,6 @@ class LogFileHandler extends Handler {
"Could not read log item from file: %d: %s",
len, bytesToHex(buf, Math.max(len, 80))));
}
- p.recycle();
}
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
diff --git a/main/src/main/java/de/blinkt/openvpn/core/LogItem.java b/main/src/main/java/de/blinkt/openvpn/core/LogItem.java
new file mode 100644
index 00000000..57bc3e1e
--- /dev/null
+++ b/main/src/main/java/de/blinkt/openvpn/core/LogItem.java
@@ -0,0 +1,375 @@
+/*
+ * Copyright (c) 2012-2016 Arne Schwabe
+ * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt
+ */
+
+package de.blinkt.openvpn.core;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.Signature;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.FormatFlagsConversionMismatchException;
+import java.util.Locale;
+import java.util.UnknownFormatConversionException;
+
+import de.blinkt.openvpn.R;
+
+/**
+ * Created by arne on 24.04.16.
+ */
+public class LogItem implements Parcelable {
+ private Object[] mArgs = null;
+ private String mMessage = null;
+ private int mRessourceId;
+ // Default log priority
+ VpnStatus.LogLevel mLevel = VpnStatus.LogLevel.INFO;
+ private long logtime = System.currentTimeMillis();
+ private int mVerbosityLevel = -1;
+
+ private LogItem(int ressourceId, Object[] args) {
+ mRessourceId = ressourceId;
+ mArgs = args;
+ }
+
+ public LogItem(VpnStatus.LogLevel level, int verblevel, String message) {
+ mMessage = message;
+ mLevel = level;
+ mVerbosityLevel = verblevel;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeArray(mArgs);
+ dest.writeString(mMessage);
+ dest.writeInt(mRessourceId);
+ dest.writeInt(mLevel.getInt());
+ dest.writeInt(mVerbosityLevel);
+
+ dest.writeLong(logtime);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof LogItem))
+ return obj.equals(this);
+ LogItem other = (LogItem) obj;
+
+ return Arrays.equals(mArgs, other.mArgs) &&
+ ((other.mMessage == null && mMessage == other.mMessage) ||
+ mMessage.equals(other.mMessage)) &&
+ mRessourceId == other.mRessourceId &&
+ ((mLevel == null && other.mLevel == mLevel) ||
+ other.mLevel.equals(mLevel)) &&
+ mVerbosityLevel == other.mVerbosityLevel &&
+ logtime == other.logtime;
+
+
+ }
+
+ public byte[] getMarschaledBytes() throws UnsupportedEncodingException {
+ ByteBuffer bb = ByteBuffer.allocate(16384);
+
+
+ bb.put((byte) 0x0); //version
+ bb.putLong(logtime); //8
+ bb.putInt(mVerbosityLevel); //4
+ bb.putInt(mLevel.getInt());
+ bb.putInt(mRessourceId);
+ if (mMessage == null || mMessage.length() == 0) {
+ bb.putInt(0);
+ } else {
+ marschalString(mMessage, bb);
+ }
+ if (mArgs == null || mArgs.length == 0) {
+ bb.putInt(0);
+ } else {
+ bb.putInt(mArgs.length);
+ for (Object o : mArgs) {
+ if (o instanceof String) {
+ bb.putChar('s');
+ marschalString((String) o, bb);
+ } else if (o instanceof Integer) {
+ bb.putChar('i');
+ bb.putInt((Integer) o);
+ } else if (o instanceof Float) {
+ bb.putChar('f');
+ bb.putFloat((Float) o);
+ } else if (o instanceof Double) {
+ bb.putChar('d');
+ bb.putDouble((Double) o);
+ } else if (o instanceof Long) {
+ bb.putChar('l');
+ bb.putLong((Long) o);
+ } else if (o == null) {
+ bb.putChar('0');
+ } else {
+ VpnStatus.logDebug("Unknown object for LogItem marschaling " + o);
+ bb.putChar('s');
+ marschalString(o.toString(), bb);
+ }
+
+ }
+ }
+
+ int pos = bb.position();
+ bb.rewind();
+ return Arrays.copyOf(bb.array(), pos);
+
+ }
+
+ public LogItem(byte[] in, int length) throws UnsupportedEncodingException {
+ ByteBuffer bb = ByteBuffer.wrap(in, 0, length);
+ bb.get(); // ignore version
+ logtime = bb.getLong();
+ mVerbosityLevel = bb.getInt();
+ mLevel = VpnStatus.LogLevel.getEnumByValue(bb.getInt());
+ mRessourceId = bb.getInt();
+ int len = bb.getInt();
+ if (len == 0) {
+ mMessage = null;
+ } else {
+ byte[] utf8bytes = new byte[len];
+ bb.get(utf8bytes);
+ mMessage = new String(utf8bytes, "UTF-8");
+ }
+ int numArgs = bb.getInt();
+ if (numArgs > 30) {
+ throw new IndexOutOfBoundsException("Too many arguments for Logitem to unmarschal");
+ }
+ if (numArgs == 0) {
+ mArgs = null;
+ } else {
+ mArgs = new Object[numArgs];
+ for (int i = 0; i < numArgs; i++) {
+ char type = bb.getChar();
+ switch (type) {
+ case 's':
+ mArgs[i] = unmarschalString(bb);
+ break;
+ case 'i':
+ mArgs[i] = bb.getInt();
+ break;
+ case 'd':
+ mArgs[i] = bb.getDouble();
+ break;
+ case 'f':
+ mArgs[i] = bb.getFloat();
+ break;
+ case 'l':
+ mArgs[i] = bb.getLong();
+ break;
+ case '0':
+ mArgs[i] = null;
+ break;
+ default:
+ throw new UnsupportedEncodingException("Unknown format type: " + type);
+ }
+ }
+ }
+ if (bb.hasRemaining())
+ throw new UnsupportedEncodingException(bb.remaining() + " bytes left after unmarshaling everything");
+ }
+
+ private void marschalString(String str, ByteBuffer bb) throws UnsupportedEncodingException {
+ byte[] utf8bytes = str.getBytes("UTF-8");
+ bb.putInt(utf8bytes.length);
+ bb.put(utf8bytes);
+ }
+
+ private String unmarschalString(ByteBuffer bb) throws UnsupportedEncodingException {
+ int len = bb.getInt();
+ byte[] utf8bytes = new byte[len];
+ bb.get(utf8bytes);
+ return new String(utf8bytes, "UTF-8");
+ }
+
+
+ public LogItem(Parcel in) {
+ mArgs = in.readArray(Object.class.getClassLoader());
+ mMessage = in.readString();
+ mRessourceId = in.readInt();
+ mLevel = VpnStatus.LogLevel.getEnumByValue(in.readInt());
+ mVerbosityLevel = in.readInt();
+ logtime = in.readLong();
+ }
+
+ public static final Creator<LogItem> CREATOR
+ = new Creator<LogItem>() {
+ public LogItem createFromParcel(Parcel in) {
+ return new LogItem(in);
+ }
+
+ public LogItem[] newArray(int size) {
+ return new LogItem[size];
+ }
+ };
+
+ public LogItem(VpnStatus.LogLevel loglevel, int ressourceId, Object... args) {
+ mRessourceId = ressourceId;
+ mArgs = args;
+ mLevel = loglevel;
+ }
+
+
+ public LogItem(VpnStatus.LogLevel loglevel, String msg) {
+ mLevel = loglevel;
+ mMessage = msg;
+ }
+
+
+ public LogItem(VpnStatus.LogLevel loglevel, int ressourceId) {
+ mRessourceId = ressourceId;
+ mLevel = loglevel;
+ }
+
+ public String getString(Context c) {
+ try {
+ if (mMessage != null) {
+ return mMessage;
+ } else {
+ if (c != null) {
+ if (mRessourceId == R.string.mobile_info)
+ return getMobileInfoString(c);
+ if (mArgs == null)
+ return c.getString(mRessourceId);
+ else
+ return c.getString(mRessourceId, mArgs);
+ } else {
+ String str = String.format(Locale.ENGLISH, "Log (no context) resid %d", mRessourceId);
+ if (mArgs != null)
+ str += join("|", mArgs);
+
+ return str;
+ }
+ }
+ } catch (UnknownFormatConversionException e) {
+ if (c != null)
+ throw new UnknownFormatConversionException(e.getLocalizedMessage() + getString(null));
+ else
+ throw e;
+ } catch (java.util.FormatFlagsConversionMismatchException e) {
+ if (c != null)
+ throw new FormatFlagsConversionMismatchException(e.getLocalizedMessage() + getString(null), e.getConversion());
+ else
+ throw e;
+ }
+
+ }
+
+
+ // TextUtils.join will cause not macked exeception in tests ....
+ public static String join(CharSequence delimiter, Object[] tokens) {
+ StringBuilder sb = new StringBuilder();
+ boolean firstTime = true;
+ for (Object token : tokens) {
+ if (firstTime) {
+ firstTime = false;
+ } else {
+ sb.append(delimiter);
+ }
+ sb.append(token);
+ }
+ return sb.toString();
+ }
+
+
+ public VpnStatus.LogLevel getLogLevel() {
+ return mLevel;
+ }
+
+
+ @Override
+ public String toString() {
+ return getString(null);
+ }
+
+ // The lint is wrong here
+ @SuppressLint("StringFormatMatches")
+ private String getMobileInfoString(Context c) {
+ c.getPackageManager();
+ String apksign = "error getting package signature";
+
+ String version = "error getting version";
+ try {
+ @SuppressLint("PackageManagerGetSignatures")
+ Signature raw = c.getPackageManager().getPackageInfo(c.getPackageName(), PackageManager.GET_SIGNATURES).signatures[0];
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ X509Certificate cert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(raw.toByteArray()));
+ MessageDigest md = MessageDigest.getInstance("SHA-1");
+ byte[] der = cert.getEncoded();
+ md.update(der);
+ byte[] digest = md.digest();
+
+ if (Arrays.equals(digest, VpnStatus.officalkey))
+ apksign = c.getString(R.string.official_build);
+ else if (Arrays.equals(digest, VpnStatus.officaldebugkey))
+ apksign = c.getString(R.string.debug_build);
+ else if (Arrays.equals(digest, VpnStatus.amazonkey))
+ apksign = "amazon version";
+ else if (Arrays.equals(digest, VpnStatus.fdroidkey))
+ apksign = "F-Droid built and signed version";
+ else
+ apksign = c.getString(R.string.built_by, cert.getSubjectX500Principal().getName());
+
+ PackageInfo packageinfo = c.getPackageManager().getPackageInfo(c.getPackageName(), 0);
+ version = packageinfo.versionName;
+
+ } catch (PackageManager.NameNotFoundException | CertificateException |
+ NoSuchAlgorithmException ignored) {
+ }
+
+ Object[] argsext = Arrays.copyOf(mArgs, mArgs.length);
+ argsext[argsext.length - 1] = apksign;
+ argsext[argsext.length - 2] = version;
+
+ return c.getString(R.string.mobile_info, argsext);
+
+ }
+
+ public long getLogtime() {
+ return logtime;
+ }
+
+
+ public int getVerbosityLevel() {
+ if (mVerbosityLevel == -1) {
+ // Hack:
+ // For message not from OpenVPN, report the status level as log level
+ return mLevel.getInt();
+ }
+ return mVerbosityLevel;
+ }
+
+ public boolean verify() {
+ if (mLevel == null)
+ return false;
+
+ if (mMessage == null && mRessourceId == 0)
+ return false;
+
+ return true;
+ }
+}
diff --git a/main/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java b/main/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java
index 7fd43906..4f743a19 100644
--- a/main/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java
+++ b/main/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java
@@ -25,9 +25,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import de.blinkt.openvpn.R;
-import de.blinkt.openvpn.VpnProfile;
import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus;
-import de.blinkt.openvpn.core.VpnStatus.LogItem;
public class OpenVPNThread implements Runnable {
private static final String DUMP_PATH_STRING = "Dump path: ";
@@ -69,7 +67,7 @@ public class OpenVPNThread implements Runnable {
try {
Log.i(TAG, "Starting openvpn");
startOpenVPNThreadArgs(mArgv, mProcessEnv);
- Log.i(TAG, "OpenVPN process exited");
+ Log.i(TAG, "OpenVPN process exited");
} catch (Exception e) {
VpnStatus.logException("Starting OpenVPN Thread", e);
Log.e(TAG, "OpenVPNThread Got " + e.toString());
diff --git a/main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java b/main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java
index 92ab5900..d23f0013 100644
--- a/main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java
+++ b/main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java
@@ -5,39 +5,18 @@
package de.blinkt.openvpn.core;
-import android.annotation.SuppressLint;
import android.content.Context;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.Signature;
import android.os.Build;
import android.os.HandlerThread;
import android.os.Message;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-import android.util.Log;
-import java.io.ByteArrayInputStream;
-import java.io.DataOutputStream;
import java.io.File;
-import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-import java.util.FormatFlagsConversionMismatchException;
import java.util.LinkedList;
import java.util.Locale;
-import java.util.UnknownFormatConversionException;
import java.util.Vector;
-import de.blinkt.openvpn.BuildConfig;
import de.blinkt.openvpn.R;
public class VpnStatus {
@@ -206,205 +185,6 @@ public class VpnStatus {
}
- public static class LogItem implements Parcelable {
- private Object[] mArgs = null;
- private String mMessage = null;
- private int mRessourceId;
- // Default log priority
- LogLevel mLevel = LogLevel.INFO;
- private long logtime = System.currentTimeMillis();
- private int mVerbosityLevel = -1;
-
- private LogItem(int ressourceId, Object[] args) {
- mRessourceId = ressourceId;
- mArgs = args;
- }
-
- public LogItem(LogLevel level, int verblevel, String message) {
- mMessage = message;
- mLevel = level;
- mVerbosityLevel = verblevel;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeArray(mArgs);
- dest.writeString(mMessage);
- dest.writeInt(mRessourceId);
- dest.writeInt(mLevel.getInt());
- dest.writeInt(mVerbosityLevel);
-
- dest.writeLong(logtime);
- }
-
- public LogItem(Parcel in) {
- mArgs = in.readArray(Object.class.getClassLoader());
- mMessage = in.readString();
- mRessourceId = in.readInt();
- mLevel = LogLevel.getEnumByValue(in.readInt());
- mVerbosityLevel = in.readInt();
- logtime = in.readLong();
- }
-
- public static final Parcelable.Creator<LogItem> CREATOR
- = new Parcelable.Creator<LogItem>() {
- public LogItem createFromParcel(Parcel in) {
- return new LogItem(in);
- }
-
- public LogItem[] newArray(int size) {
- return new LogItem[size];
- }
- };
-
- public LogItem(LogLevel loglevel, int ressourceId, Object... args) {
- mRessourceId = ressourceId;
- mArgs = args;
- mLevel = loglevel;
- }
-
-
- public LogItem(LogLevel loglevel, String msg) {
- mLevel = loglevel;
- mMessage = msg;
- }
-
-
- public LogItem(LogLevel loglevel, int ressourceId) {
- mRessourceId = ressourceId;
- mLevel = loglevel;
- }
-
- public String getString(Context c) {
- try {
- if (mMessage != null) {
- return mMessage;
- } else {
- if (c != null) {
- if (mRessourceId == R.string.mobile_info)
- return getMobileInfoString(c);
- if (mArgs == null)
- return c.getString(mRessourceId);
- else
- return c.getString(mRessourceId, mArgs);
- } else {
- String str = String.format(Locale.ENGLISH, "Log (no context) resid %d", mRessourceId);
- if (mArgs != null)
- str += join("|", mArgs);
-
- return str;
- }
- }
- } catch (UnknownFormatConversionException e) {
- if (c != null)
- throw new UnknownFormatConversionException(e.getLocalizedMessage() + getString(null));
- else
- throw e;
- } catch (java.util.FormatFlagsConversionMismatchException e) {
- if (c != null)
- throw new FormatFlagsConversionMismatchException(e.getLocalizedMessage() + getString(null), e.getConversion());
- else
- throw e;
- }
-
- }
-
-
- // TextUtils.join will cause not macked exeception in tests ....
- public static String join(CharSequence delimiter, Object[] tokens) {
- StringBuilder sb = new StringBuilder();
- boolean firstTime = true;
- for (Object token: tokens) {
- if (firstTime) {
- firstTime = false;
- } else {
- sb.append(delimiter);
- }
- sb.append(token);
- }
- return sb.toString();
- }
-
-
-
- public LogLevel getLogLevel() {
- return mLevel;
- }
-
- // The lint is wrong here
- @SuppressLint("StringFormatMatches")
- private String getMobileInfoString(Context c) {
- c.getPackageManager();
- String apksign = "error getting package signature";
-
- String version = "error getting version";
- try {
- @SuppressLint("PackageManagerGetSignatures")
- Signature raw = c.getPackageManager().getPackageInfo(c.getPackageName(), PackageManager.GET_SIGNATURES).signatures[0];
- CertificateFactory cf = CertificateFactory.getInstance("X.509");
- X509Certificate cert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(raw.toByteArray()));
- MessageDigest md = MessageDigest.getInstance("SHA-1");
- byte[] der = cert.getEncoded();
- md.update(der);
- byte[] digest = md.digest();
-
- if (Arrays.equals(digest, officalkey))
- apksign = c.getString(R.string.official_build);
- else if (Arrays.equals(digest, officaldebugkey))
- apksign = c.getString(R.string.debug_build);
- else if (Arrays.equals(digest, amazonkey))
- apksign = "amazon version";
- else if (Arrays.equals(digest, fdroidkey))
- apksign = "F-Droid built and signed version";
- else
- apksign = c.getString(R.string.built_by, cert.getSubjectX500Principal().getName());
-
- PackageInfo packageinfo = c.getPackageManager().getPackageInfo(c.getPackageName(), 0);
- version = packageinfo.versionName;
-
- } catch (NameNotFoundException | CertificateException |
- NoSuchAlgorithmException ignored) {
- }
-
- Object[] argsext = Arrays.copyOf(mArgs, mArgs.length);
- argsext[argsext.length - 1] = apksign;
- argsext[argsext.length - 2] = version;
-
- return c.getString(R.string.mobile_info, argsext);
-
- }
-
- public long getLogtime() {
- return logtime;
- }
-
-
- public int getVerbosityLevel() {
- if (mVerbosityLevel == -1) {
- // Hack:
- // For message not from OpenVPN, report the status level as log level
- return mLevel.getInt();
- }
- return mVerbosityLevel;
- }
-
- public boolean verify() {
- if (mLevel == null)
- return false;
-
- if (mMessage == null && mRessourceId == 0)
- return false;
-
- return true;
- }
- }
-
public interface LogListener {
void newLog(LogItem logItem);
}
@@ -425,7 +205,7 @@ public class VpnStatus {
public synchronized static void clearLog() {
logbuffer.clear();
logInformation();
- if (mLogFileHandler!=null)
+ if (mLogFileHandler != null)
mLogFileHandler.sendEmptyMessage(LogFileHandler.TRIM_LOG_FILE);
}
@@ -438,7 +218,7 @@ public class VpnStatus {
}
logInfo(R.string.mobile_info, Build.MODEL, Build.BOARD, Build.BRAND, Build.VERSION.SDK_INT,
- nativeAPI , Build.VERSION.RELEASE, Build.ID, Build.FINGERPRINT, "", "");
+ nativeAPI, Build.VERSION.RELEASE, Build.ID, Build.FINGERPRINT, "", "");
}
public synchronized static void addLogListener(LogListener ll) {
@@ -607,7 +387,7 @@ public class VpnStatus {
logbuffer.addFirst(logItem);
} else {
logbuffer.addLast(logItem);
- if (mLogFileHandler!=null) {
+ if (mLogFileHandler != null) {
Message m = mLogFileHandler.obtainMessage(LogFileHandler.LOG_MESSAGE, logItem);
mLogFileHandler.sendMessage(m);
}
@@ -616,7 +396,7 @@ public class VpnStatus {
if (logbuffer.size() > MAXLOGENTRIES + MAXLOGENTRIES / 2) {
while (logbuffer.size() > MAXLOGENTRIES)
logbuffer.removeFirst();
- if (mLogFileHandler!=null)
+ if (mLogFileHandler != null)
mLogFileHandler.sendMessage(mLogFileHandler.obtainMessage(LogFileHandler.TRIM_LOG_FILE));
}
diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java b/main/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java
index a620beb4..d3381bcb 100644
--- a/main/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java
+++ b/main/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java
@@ -22,7 +22,6 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
-import android.preference.Preference;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.text.SpannableString;
@@ -63,7 +62,7 @@ import de.blinkt.openvpn.core.OpenVPNService;
import de.blinkt.openvpn.core.ProfileManager;
import de.blinkt.openvpn.core.VpnStatus;
import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus;
-import de.blinkt.openvpn.core.VpnStatus.LogItem;
+import de.blinkt.openvpn.core.LogItem;
import de.blinkt.openvpn.core.VpnStatus.LogListener;
import de.blinkt.openvpn.core.VpnStatus.StateListener;
diff --git a/main/src/test/java/de/blinkt/openvpn/core/TestLogFileHandler.java b/main/src/test/java/de/blinkt/openvpn/core/TestLogFileHandler.java
index f86dbcdc..c35df598 100644
--- a/main/src/test/java/de/blinkt/openvpn/core/TestLogFileHandler.java
+++ b/main/src/test/java/de/blinkt/openvpn/core/TestLogFileHandler.java
@@ -1,9 +1,6 @@
package de.blinkt.openvpn.core;
import android.annotation.SuppressLint;
-import android.os.Looper;
-import android.os.Message;
-import android.util.Log;
import junit.framework.Assert;
@@ -15,19 +12,18 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.io.StringBufferInputStream;
+import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class TestLogFileHandler {
- byte[] testUnescaped = new byte[] {0x00, 0x55, -27, 0x00, 0x56, 0x10, -128, 0x55, 0x54};
- byte[] expectedEscaped = new byte[] {0x55, 0x00, 0x00, 0x00, 0x09, 0x00, 0x56, 0x00, -27, 0x00, 0x56, 0x01, 0x10, -128, 0x56, 0x00, 0x54};
+ byte[] testUnescaped = new byte[]{0x00, 0x55, -27, 0x00, 0x56, 0x10, -128, 0x55, 0x54};
+ byte[] expectedEscaped = new byte[]{0x55, 0x00, 0x00, 0x00, 0x09, 0x00, 0x56, 0x00, -27, 0x00, 0x56, 0x01, 0x10, -128, 0x56, 0x00, 0x54};
private TestingLogFileHandler lfh;
@Before
- public void setup()
- {
+ public void setup() {
lfh = new TestingLogFileHandler();
}
@@ -55,6 +51,46 @@ public class TestLogFileHandler {
}
+ @Test
+ public void testMarschal() throws UnsupportedEncodingException {
+ LogItem li = new LogItem(VpnStatus.LogLevel.DEBUG, 72, "foobar");
+ LogItem li2 = marschalAndBack(li);
+ testEquals(li, li2);
+ Assert.assertEquals(li, li2);
+ }
+
+ @Test
+ public void testMarschalArgs() throws UnsupportedEncodingException {
+ LogItem li = new LogItem(VpnStatus.LogLevel.DEBUG, 72, 772, "sinnloser Text", 7723, 723.2f, 7.2);
+ LogItem li2 = marschalAndBack(li);
+ testEquals(li, li2);
+ Assert.assertEquals(li, li2);
+ }
+
+ @Test
+ public void testMarschalString() throws UnsupportedEncodingException {
+ LogItem li = new LogItem(VpnStatus.LogLevel.DEBUG, "Nutzlose Nachricht");
+ LogItem li2 = marschalAndBack(li);
+ testEquals(li, li2);
+ Assert.assertEquals(li, li2);
+ }
+
+
+ private void testEquals(LogItem li, LogItem li2) {
+ Assert.assertEquals(li.getLogLevel(), li2.getLogLevel());
+ Assert.assertEquals(li.getLogtime(), li2.getLogtime());
+ Assert.assertEquals(li.getVerbosityLevel(), li2.getVerbosityLevel());
+ Assert.assertEquals(li.toString(), li2.toString());
+
+ }
+
+ private LogItem marschalAndBack(LogItem li) throws UnsupportedEncodingException {
+ byte[] bytes = li.getMarschaledBytes();
+
+ return new LogItem(bytes, bytes.length);
+ }
+
+
@SuppressLint("HandlerLeak")
static class TestingLogFileHandler extends LogFileHandler {
@@ -78,4 +114,6 @@ public class TestLogFileHandler {
mRestoredByteArray = Arrays.copyOf(buf, len);
}
}
+
+
} \ No newline at end of file