package com.nutomic.syncthingandroid.activities;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.widget.ShareActionProvider;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.ScrollView;
import android.widget.TextView;
import com.nutomic.syncthingandroid.R;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* Shows the log information from Syncthing.
*/
public class LogActivity extends SyncthingActivity {
private final static String TAG = "LogActivity";
private TextView mLog;
private boolean mSyncthingLog = true;
private AsyncTask mFetchLogTask;
private ScrollView mScrollView;
private Intent mShareIntent;
/**
* Initialize Log.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_log);
if (savedInstanceState != null) {
mSyncthingLog = savedInstanceState.getBoolean("syncthingLog");
invalidateOptionsMenu();
}
mLog = (TextView) findViewById(R.id.log);
mScrollView = (ScrollView) findViewById(R.id.scroller);
updateLog();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean("syncthingLog", mSyncthingLog);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.log_list, menu);
MenuItem switchLog = menu.findItem(R.id.switch_logs);
switchLog.setTitle(mSyncthingLog ? R.string.log_android_title : R.string.log_syncthing_title);
// Add the share button
MenuItem shareItem = menu.findItem(R.id.menu_share);
ShareActionProvider actionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(shareItem);
mShareIntent = new Intent();
mShareIntent.setAction(Intent.ACTION_SEND);
mShareIntent.setType("text/plain");
mShareIntent.putExtra(android.content.Intent.EXTRA_TEXT, mLog.getText());
actionProvider.setShareIntent(mShareIntent);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.switch_logs:
mSyncthingLog = !mSyncthingLog;
item.setTitle(mSyncthingLog ? R.string.log_android_title : R.string.log_syncthing_title);
updateLog();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void scrollToBottom() {
mScrollView.post(() -> mScrollView.scrollTo(0, mLog.getBottom()));
}
private void updateLog() {
if (mFetchLogTask != null)
mFetchLogTask.cancel(true);
mLog.setText(R.string.retrieving_logs);
mFetchLogTask = new AsyncTask<Void, Void, String>() {
@Override
protected String doInBackground(Void... params) {
return getLog(mSyncthingLog);
}
@Override
protected void onPostExecute(String log) {
mLog.setText(log);
if (mShareIntent != null)
mShareIntent.putExtra(android.content.Intent.EXTRA_TEXT, log);
scrollToBottom();
}
}.execute();
}
/**
* Queries logcat to obtain a log.
*
* @param syncthingLog Filter on Syncthing's native messages.
*/
private String getLog(final boolean syncthingLog) {
Process process = null;
try {
ProcessBuilder pb;
if (syncthingLog) {
pb = new ProcessBuilder("/system/bin/logcat", "-t", "300", "-v", "raw", "-s", "SyncthingNativeCode");
} else {
pb = new ProcessBuilder("/system/bin/logcat", "-t", "300", "-v", "time", "'*'");
}
pb.redirectErrorStream(true);
process = pb.start();
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream(), "UTF-8"), 8192);
StringBuilder log = new StringBuilder();
String line;
String sep = System.getProperty("line.separator");
while ((line = bufferedReader.readLine()) != null) {
log.append(line);
log.append(sep);
}
return log.toString();
} catch (IOException e) {
Log.w(TAG, "Error reading Android log", e);
} finally {
if (process != null) {
process.destroy();
}
}
return "";
}
}