]> git.ipfire.org Git - thirdparty/strongswan.git/blame - src/frontends/android/app/src/main/java/org/strongswan/android/ui/LogFragment.java
android: Migrate to the Gradle build system
[thirdparty/strongswan.git] / src / frontends / android / app / src / main / java / org / strongswan / android / ui / LogFragment.java
CommitLineData
f9a162a2
TB
1/*
2 * Copyright (C) 2012 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16package org.strongswan.android.ui;
17
18import java.io.BufferedReader;
19import java.io.File;
20import java.io.FileNotFoundException;
21import java.io.FileReader;
22import java.io.StringReader;
23
24import org.strongswan.android.R;
25import org.strongswan.android.logic.CharonVpnService;
26
27import android.app.Fragment;
28import android.os.Bundle;
ae10e8c4 29import android.os.FileObserver;
f9a162a2
TB
30import android.os.Handler;
31import android.view.LayoutInflater;
32import android.view.View;
33import android.view.ViewGroup;
34import android.widget.TextView;
35
36public class LogFragment extends Fragment implements Runnable
37{
38 private String mLogFilePath;
39 private Handler mLogHandler;
40 private TextView mLogView;
41 private LogScrollView mScrollView;
42 private BufferedReader mReader;
43 private Thread mThread;
44 private volatile boolean mRunning;
ae10e8c4 45 private FileObserver mDirectoryObserver;
f9a162a2
TB
46
47 @Override
48 public void onCreate(Bundle savedInstanceState)
49 {
50 super.onCreate(savedInstanceState);
51
52 mLogFilePath = getActivity().getFilesDir() + File.separator + CharonVpnService.LOG_FILE;
53 /* use a handler to update the log view */
54 mLogHandler = new Handler();
ae10e8c4
TB
55
56 mDirectoryObserver = new LogDirectoryObserver(getActivity().getFilesDir().getAbsolutePath());
f9a162a2
TB
57 }
58
59 @Override
60 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
61 {
62 View view = inflater.inflate(R.layout.log_fragment, null);
63 mLogView = (TextView)view.findViewById(R.id.log_view);
64 mScrollView = (LogScrollView)view.findViewById(R.id.scroll_view);
65 return view;
66 }
67
68 @Override
69 public void onStart()
70 {
71 super.onStart();
ae10e8c4
TB
72 startLogReader();
73 mDirectoryObserver.startWatching();
74 }
75
76 @Override
77 public void onStop()
78 {
79 super.onStop();
80 mDirectoryObserver.stopWatching();
81 stopLogReader();
82 }
83
84 /**
85 * Start reading from the log file
86 */
87 private void startLogReader()
88 {
f9a162a2
TB
89 try
90 {
91 mReader = new BufferedReader(new FileReader(mLogFilePath));
92 }
93 catch (FileNotFoundException e)
94 {
95 mReader = new BufferedReader(new StringReader(""));
96 }
ae10e8c4
TB
97
98 mLogView.setText("");
f9a162a2
TB
99 mRunning = true;
100 mThread = new Thread(this);
101 mThread.start();
102 }
103
ae10e8c4
TB
104 /**
105 * Stop reading from the log file
106 */
107 private void stopLogReader()
f9a162a2 108 {
f9a162a2
TB
109 try
110 {
111 mRunning = false;
112 mThread.interrupt();
113 mThread.join();
114 }
115 catch (InterruptedException e)
116 {
117 }
118 }
119
120 /**
121 * Write the given log line to the TextView. We strip the prefix off to save
122 * some space (it is not that helpful for regular users anyway).
ae10e8c4 123 *
f9a162a2
TB
124 * @param line log line to log
125 */
126 public void logLine(final String line)
127 {
128 mLogHandler.post(new Runnable() {
129 @Override
130 public void run()
131 {
132 /* strip off prefix (month=3, day=2, time=8, thread=2, spaces=3) */
133 mLogView.append((line.length() > 18 ? line.substring(18) : line) + '\n');
134 /* calling autoScroll() directly does not work, probably because content
135 * is not yet updated, so we post this to be done later */
136 mScrollView.post(new Runnable() {
137 @Override
138 public void run()
139 {
140 mScrollView.autoScroll();
141 }
142 });
143 }
144 });
145 }
146
147 @Override
148 public void run()
149 {
150 while (mRunning)
151 {
152 try
ae10e8c4 153 { /* this works as long as the file is not truncated */
f9a162a2
TB
154 String line = mReader.readLine();
155 if (line == null)
156 { /* wait until there is more to log */
157 Thread.sleep(1000);
158 }
159 else
160 {
161 logLine(line);
162 }
163 }
164 catch (Exception e)
165 {
166 break;
167 }
168 }
169 }
ae10e8c4
TB
170
171 /**
172 * FileObserver that checks for changes regarding the log file. Since charon
173 * truncates it (for which there is no explicit event) we check for any modification
174 * to the file, keep track of the file size and reopen it if it got smaller.
175 */
176 private class LogDirectoryObserver extends FileObserver
177 {
178 private final File mFile;
179 private long mSize;
180
181 public LogDirectoryObserver(String path)
182 {
183 super(path, FileObserver.CREATE | FileObserver.MODIFY | FileObserver.DELETE);
184 mFile = new File(mLogFilePath);
185 mSize = mFile.length();
186 }
187
188 @Override
189 public void onEvent(int event, String path)
190 {
191 if (path == null || !path.equals(CharonVpnService.LOG_FILE))
192 {
193 return;
194 }
195 switch (event)
196 { /* even though we only subscribed for these we check them,
197 * as strange events are sometimes received */
198 case FileObserver.CREATE:
199 case FileObserver.DELETE:
200 restartLogReader();
201 break;
202 case FileObserver.MODIFY:
203 /* if the size got smaller reopen the log file, as it was probably truncated */
204 long size = mFile.length();
205 if (size < mSize)
206 {
207 restartLogReader();
208 }
209 mSize = size;
210 break;
211 }
212 }
213
214 private void restartLogReader()
215 {
216 /* we are called from a separate thread, so we use the handler */
217 mLogHandler.post(new Runnable() {
218 @Override
219 public void run()
220 {
221 stopLogReader();
222 startLogReader();
223 }
224 });
225 }
226 }
f9a162a2 227}