aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2012-08-10 10:05:38 +0200
committerTobias Brunner <tobias@strongswan.org>2012-08-13 11:22:21 +0200
commitae10e8c458cd87b5bbcf1e40e1ce430335c9bb65 (patch)
tree7526c4d64a853e493bcd57a5d9fba9781330cef3 /src
parentbad119c55a9e64c4fff96a009f89645fd94c59e7 (diff)
downloadstrongswan-ae10e8c458cd87b5bbcf1e40e1ce430335c9bb65.tar.bz2
strongswan-ae10e8c458cd87b5bbcf1e40e1ce430335c9bb65.tar.xz
Watch for changes to the log file so we can reopen it
If the log fragment is shown while the daemon starts (which is not the case at the moment, but maybe later on tablets) the file reader would not notice that the file got truncated. The same applies if the file is deleted directly on the file system e.g. with adb shell.
Diffstat (limited to 'src')
-rw-r--r--src/frontends/android/src/org/strongswan/android/ui/LogFragment.java91
1 files changed, 86 insertions, 5 deletions
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();
+ }
+ });
+ }
+ }
}