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.
This commit is contained in:
parent
bad119c55a
commit
ae10e8c458
|
@ -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();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue