diff --git a/src/frontends/android/src/org/strongswan/android/ui/LogFragment.java b/src/frontends/android/src/org/strongswan/android/ui/LogFragment.java index 23cd2aa46..8740e0c46 100644 --- a/src/frontends/android/src/org/strongswan/android/ui/LogFragment.java +++ b/src/frontends/android/src/org/strongswan/android/ui/LogFragment.java @@ -26,6 +26,7 @@ import org.strongswan.android.logic.CharonVpnService; import android.app.Fragment; import android.os.Bundle; +import android.os.FileObserver; import android.os.Handler; import android.view.LayoutInflater; import android.view.View; @@ -41,6 +42,7 @@ public class LogFragment extends Fragment implements Runnable private BufferedReader mReader; private Thread mThread; private volatile boolean mRunning; + private FileObserver mDirectoryObserver; @Override public void onCreate(Bundle savedInstanceState) @@ -50,6 +52,8 @@ public class LogFragment extends Fragment implements Runnable mLogFilePath = getActivity().getFilesDir() + File.separator + CharonVpnService.LOG_FILE; /* use a handler to update the log view */ mLogHandler = new Handler(); + + mDirectoryObserver = new LogDirectoryObserver(getActivity().getFilesDir().getAbsolutePath()); } @Override @@ -65,7 +69,23 @@ public class LogFragment extends Fragment implements Runnable public void onStart() { super.onStart(); - mLogView.setText(""); + startLogReader(); + mDirectoryObserver.startWatching(); + } + + @Override + public void onStop() + { + super.onStop(); + mDirectoryObserver.stopWatching(); + stopLogReader(); + } + + /** + * Start reading from the log file + */ + private void startLogReader() + { try { mReader = new BufferedReader(new FileReader(mLogFilePath)); @@ -74,15 +94,18 @@ public class LogFragment extends Fragment implements Runnable { mReader = new BufferedReader(new StringReader("")); } + + mLogView.setText(""); mRunning = true; mThread = new Thread(this); mThread.start(); } - @Override - public void onStop() + /** + * Stop reading from the log file + */ + private void stopLogReader() { - super.onStop(); try { mRunning = false; @@ -97,6 +120,7 @@ public class LogFragment extends Fragment implements Runnable /** * Write the given log line to the TextView. We strip the prefix off to save * some space (it is not that helpful for regular users anyway). + * * @param line log line to log */ public void logLine(final String line) @@ -126,7 +150,7 @@ public class LogFragment extends Fragment implements Runnable while (mRunning) { try - { + { /* this works as long as the file is not truncated */ String line = mReader.readLine(); if (line == null) { /* wait until there is more to log */ @@ -143,4 +167,61 @@ public class LogFragment extends Fragment implements Runnable } } } + + /** + * FileObserver that checks for changes regarding the log file. Since charon + * truncates it (for which there is no explicit event) we check for any modification + * to the file, keep track of the file size and reopen it if it got smaller. + */ + private class LogDirectoryObserver extends FileObserver + { + private final File mFile; + private long mSize; + + public LogDirectoryObserver(String path) + { + super(path, FileObserver.CREATE | FileObserver.MODIFY | FileObserver.DELETE); + mFile = new File(mLogFilePath); + mSize = mFile.length(); + } + + @Override + public void onEvent(int event, String path) + { + if (path == null || !path.equals(CharonVpnService.LOG_FILE)) + { + return; + } + switch (event) + { /* even though we only subscribed for these we check them, + * as strange events are sometimes received */ + case FileObserver.CREATE: + case FileObserver.DELETE: + restartLogReader(); + break; + case FileObserver.MODIFY: + /* if the size got smaller reopen the log file, as it was probably truncated */ + long size = mFile.length(); + if (size < mSize) + { + restartLogReader(); + } + mSize = size; + break; + } + } + + private void restartLogReader() + { + /* we are called from a separate thread, so we use the handler */ + mLogHandler.post(new Runnable() { + @Override + public void run() + { + stopLogReader(); + startLogReader(); + } + }); + } + } }