From 6be050c43d584343e1d74894cb1666d018f38cda Mon Sep 17 00:00:00 2001 From: Lode Hoste Date: Sat, 28 Mar 2015 14:28:23 +0100 Subject: [PATCH 1/3] Add log window (fixes #311). --- src/main/AndroidManifest.xml | 9 +- .../activities/LogActivity.java | 161 ++++++++++++++++++ .../activities/SettingsActivity.java | 5 +- src/main/res/layout/log_activity.xml | 24 +++ src/main/res/menu/log_list.xml | 17 ++ src/main/res/values/strings.xml | 25 +++ src/main/res/xml/app_settings.xml | 7 + 7 files changed, 246 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/nutomic/syncthingandroid/activities/LogActivity.java create mode 100644 src/main/res/layout/log_activity.xml create mode 100644 src/main/res/menu/log_list.xml diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index 63abb9f9..ade0cef9 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -25,7 +25,6 @@ android:launchMode="singleTop"> - @@ -44,6 +43,14 @@ android:name="android.support.PARENT_ACTIVITY" android:value=".activities.MainActivity" /> + + + diff --git a/src/main/java/com/nutomic/syncthingandroid/activities/LogActivity.java b/src/main/java/com/nutomic/syncthingandroid/activities/LogActivity.java new file mode 100644 index 00000000..ef7b3c0a --- /dev/null +++ b/src/main/java/com/nutomic/syncthingandroid/activities/LogActivity.java @@ -0,0 +1,161 @@ +package com.nutomic.syncthingandroid.activities; + +import android.content.Intent; +import android.os.AsyncTask; +import android.os.Bundle; +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.EditText; + +import android.support.v4.view.MenuItemCompat; +import android.widget.ScrollView; +import android.widget.TextView; + +import com.nutomic.syncthingandroid.R; + +import java.io.BufferedReader; +import java.io.DataOutputStream; +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.log_activity); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + 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); + + // Add the share button + MenuItem shareItem = menu.findItem(R.id.menu_share); + shareItem.setTitle(mSyncthingLog ? R.string.log_android_title : R.string.log_syncthing_title); + 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(new Runnable() { + @Override + public void run() { + mScrollView.scrollTo(0, mLog.getBottom()); + } + }); + } + + private void updateLog() { + if (mFetchLogTask != null) + mFetchLogTask.cancel(true); + mLog.setText("Retrieving logs..."); + mFetchLogTask = new AsyncTask() { + @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(); + } + + private String getLog(final boolean syncthingLog) { + Process process = null; + DataOutputStream pOut = null; + try { + ProcessBuilder pb; + if (syncthingLog) { + pb = new ProcessBuilder("/system/bin/logcat", "-t", "300", "-s", "SyncthingNativeCode"); + } else { + pb = new ProcessBuilder("/system/bin/logcat", "-t", "300", "'*'"); + } + pb.redirectErrorStream(true); + process = pb.start(); + BufferedReader bufferedReader = new BufferedReader( + new InputStreamReader(process.getInputStream()), 8192); + StringBuilder log = new StringBuilder(); + String line = ""; + while ((line = bufferedReader.readLine()) != null) { + log.append(line); + log.append(System.getProperty("line.separator")); + } + return log.toString(); + } catch (IOException e) { + Log.w(TAG, "Error reading Android log", e); + } finally { + try { + if (pOut != null) { + pOut.close(); + } + } catch (IOException e) { + Log.w(TAG, "Failed to close shell stream", e); + } + if (process != null) { + process.destroy(); + } + } + return ""; + } + +} diff --git a/src/main/java/com/nutomic/syncthingandroid/activities/SettingsActivity.java b/src/main/java/com/nutomic/syncthingandroid/activities/SettingsActivity.java index f922c8a8..c804a98f 100644 --- a/src/main/java/com/nutomic/syncthingandroid/activities/SettingsActivity.java +++ b/src/main/java/com/nutomic/syncthingandroid/activities/SettingsActivity.java @@ -43,7 +43,7 @@ public class SettingsActivity extends SyncthingActivity { if (savedInstanceState != null) { mFragment = fm.getFragment(savedInstanceState, savedInstanceState.getString("fragment_name")); - } else { + } else if (getIntent().getAction() != null) { switch (getIntent().getAction()) { case ACTION_APP_SETTINGS_FRAGMENT: setTitle(R.string.settings_title); @@ -65,6 +65,9 @@ public class SettingsActivity extends SyncthingActivity { throw new IllegalArgumentException( "You must provide the requested fragment type as an extra."); } + } else{ + setTitle(R.string.settings_title); + mFragment = new SettingsFragment(); } fm.beginTransaction() diff --git a/src/main/res/layout/log_activity.xml b/src/main/res/layout/log_activity.xml new file mode 100644 index 00000000..a355d0bb --- /dev/null +++ b/src/main/res/layout/log_activity.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + diff --git a/src/main/res/menu/log_list.xml b/src/main/res/menu/log_list.xml new file mode 100644 index 00000000..b7fa927e --- /dev/null +++ b/src/main/res/menu/log_list.xml @@ -0,0 +1,17 @@ + + + + + + + + + diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 597d83eb..719e611d 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -288,6 +288,12 @@ Please report any problems you encounter via Github. About + + Open Log + + + Open the Syncthing and Android log window + Report Issue @@ -323,6 +329,25 @@ Please report any problems you encounter via Github. Failed to create folder + + + + + Log + + + View Android Log + + + View Syncthing Log + + + Share Log + + + Share + + diff --git a/src/main/res/xml/app_settings.xml b/src/main/res/xml/app_settings.xml index af872291..57e2c4dd 100644 --- a/src/main/res/xml/app_settings.xml +++ b/src/main/res/xml/app_settings.xml @@ -126,6 +126,13 @@ + + + + From 0c13d8e106b71a554566fdd1fd0b669fd540acd2 Mon Sep 17 00:00:00 2001 From: Lode Hoste Date: Sun, 12 Apr 2015 22:55:06 +0200 Subject: [PATCH 2/3] Support opening LogActivity in debug package --- src/main/AndroidManifest.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index ade0cef9..37474c81 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -47,6 +47,10 @@ android:name=".activities.LogActivity" android:label="@string/log_title" android:parentActivityName=".activities.SettingsActivity"> + + + + From 1584754e322dd8ae09d8b1bf9585a5d9615084e9 Mon Sep 17 00:00:00 2001 From: Lode Hoste Date: Mon, 13 Apr 2015 22:13:44 +0200 Subject: [PATCH 3/3] Show GetTask progress in log Conflicts: src/main/java/com/nutomic/syncthingandroid/syncthing/GetTask.java --- .../activities/LogActivity.java | 17 ++++++++--------- .../activities/SettingsActivity.java | 2 +- .../syncthingandroid/syncthing/GetTask.java | 6 ++++-- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/nutomic/syncthingandroid/activities/LogActivity.java b/src/main/java/com/nutomic/syncthingandroid/activities/LogActivity.java index ef7b3c0a..12f2ae00 100644 --- a/src/main/java/com/nutomic/syncthingandroid/activities/LogActivity.java +++ b/src/main/java/com/nutomic/syncthingandroid/activities/LogActivity.java @@ -66,9 +66,11 @@ public class LogActivity extends SyncthingActivity { 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); - shareItem.setTitle(mSyncthingLog ? R.string.log_android_title : R.string.log_syncthing_title); ShareActionProvider actionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(shareItem); mShareIntent = new Intent(); mShareIntent.setAction(Intent.ACTION_SEND); @@ -120,9 +122,13 @@ public class LogActivity extends SyncthingActivity { }.execute(); } + /** + * Queries logcat to obtain a log. + * + * @param syncthingLog Filter on Syncthing's native messages. + */ private String getLog(final boolean syncthingLog) { Process process = null; - DataOutputStream pOut = null; try { ProcessBuilder pb; if (syncthingLog) { @@ -144,13 +150,6 @@ public class LogActivity extends SyncthingActivity { } catch (IOException e) { Log.w(TAG, "Error reading Android log", e); } finally { - try { - if (pOut != null) { - pOut.close(); - } - } catch (IOException e) { - Log.w(TAG, "Failed to close shell stream", e); - } if (process != null) { process.destroy(); } diff --git a/src/main/java/com/nutomic/syncthingandroid/activities/SettingsActivity.java b/src/main/java/com/nutomic/syncthingandroid/activities/SettingsActivity.java index c804a98f..722fcc73 100644 --- a/src/main/java/com/nutomic/syncthingandroid/activities/SettingsActivity.java +++ b/src/main/java/com/nutomic/syncthingandroid/activities/SettingsActivity.java @@ -65,7 +65,7 @@ public class SettingsActivity extends SyncthingActivity { throw new IllegalArgumentException( "You must provide the requested fragment type as an extra."); } - } else{ + } else { setTitle(R.string.settings_title); mFragment = new SettingsFragment(); } diff --git a/src/main/java/com/nutomic/syncthingandroid/syncthing/GetTask.java b/src/main/java/com/nutomic/syncthingandroid/syncthing/GetTask.java index 8695abd7..b456d630 100644 --- a/src/main/java/com/nutomic/syncthingandroid/syncthing/GetTask.java +++ b/src/main/java/com/nutomic/syncthingandroid/syncthing/GetTask.java @@ -83,8 +83,10 @@ public class GetTask extends AsyncTask { try { // Don't push the API too hard Thread.sleep(500 * i); - } catch (InterruptedException e) { } - Log.w(TAG, "Retrying GetTask Rest API call ("+i+")"); + } catch (InterruptedException e) { + Log.w(TAG, e); + } + Log.w(TAG, "Retrying GetTask Rest API call ("+(i+1)+"/10)"); } return null; }