diff --git a/app/src/main/java/com/nutomic/syncthingandroid/activities/LogActivity.java b/app/src/main/java/com/nutomic/syncthingandroid/activities/LogActivity.java index 2288bf11..1e82a0e5 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/activities/LogActivity.java +++ b/app/src/main/java/com/nutomic/syncthingandroid/activities/LogActivity.java @@ -13,6 +13,7 @@ import android.widget.ScrollView; import android.widget.TextView; import com.nutomic.syncthingandroid.R; +import com.nutomic.syncthingandroid.util.Util; import java.io.BufferedReader; import java.io.IOException; @@ -26,8 +27,12 @@ public class LogActivity extends SyncthingActivity { private final static String TAG = "LogActivity"; + /** + * Show Android Log by default. + */ + private boolean mSyncthingLog = false; + private TextView mLog; - private boolean mSyncthingLog = true; private AsyncTask mFetchLogTask = null; private ScrollView mScrollView; private Intent mShareIntent; @@ -40,7 +45,7 @@ public class LogActivity extends SyncthingActivity { super.onCreate(savedInstanceState); setContentView(R.layout.activity_log); - setTitle(R.string.syncthing_log_title); + setTitle(R.string.android_log_title); if (savedInstanceState != null) { mSyncthingLog = savedInstanceState.getBoolean("syncthingLog"); @@ -143,34 +148,12 @@ public class LogActivity extends SyncthingActivity { * @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", "time", "-s", "SyncthingNativeCode"); - } else { - pb = new ProcessBuilder("/system/bin/logcat", "-t", "300", "-v", "time", "*:i ps:s art:s"); - } - 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(); - } + if (syncthingLog) { + String output = Util.runShellCommandGetOutput("/system/bin/logcat -t 300 -v time -s SyncthingNativeCode", false); + return output.replaceAll("SyncthingNativeCode", ""); + } else { + return Util.runShellCommandGetOutput("/system/bin/logcat -t 300 -v time *:i ps:s art:s", false); } - return ""; } } diff --git a/app/src/main/java/com/nutomic/syncthingandroid/service/SyncthingRunnable.java b/app/src/main/java/com/nutomic/syncthingandroid/service/SyncthingRunnable.java index 16297e37..f9b38eb9 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/service/SyncthingRunnable.java +++ b/app/src/main/java/com/nutomic/syncthingandroid/service/SyncthingRunnable.java @@ -85,6 +85,7 @@ public class SyncthingRunnable implements Runnable { public SyncthingRunnable(Context context, Command command) { ((SyncthingApp) context.getApplicationContext()).component().inject(this); mContext = context; + // Example: mSyncthingBinary="/data/app/com.github.catfriend1.syncthingandroid.debug-8HsN-IsVtZXc8GrE5-Hepw==/lib/x86/libsyncthing.so" mSyncthingBinary = Constants.getSyncthingBinary(mContext); mLogFile = Constants.getLogFile(mContext); @@ -131,12 +132,11 @@ public class SyncthingRunnable implements Runnable { trimLogFile(); // Make sure Syncthing is executable - try { - ProcessBuilder pb = new ProcessBuilder("chmod", "500", mSyncthingBinary.getPath()); - Process p = pb.start(); - p.waitFor(); - } catch (IOException | InterruptedException e) { - Log.w(TAG, "Failed to chmod Syncthing", e); + exitCode = Util.runShellCommand("chmod 500 " + mSyncthingBinary.getPath(), false); + if (exitCode == 1) { + LogV("chmod SyncthingNative exited with code 1 [permission denied]. This is expected on Android 5+."); + } else if (exitCode > 1) { + Log.w(TAG, "chmod SyncthingNative failed with exit code " + Integer.toString(exitCode)); } /** diff --git a/app/src/main/java/com/nutomic/syncthingandroid/util/Util.java b/app/src/main/java/com/nutomic/syncthingandroid/util/Util.java index 5c9e583a..366a2834 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/util/Util.java +++ b/app/src/main/java/com/nutomic/syncthingandroid/util/Util.java @@ -33,7 +33,7 @@ import eu.chainfire.libsuperuser.Shell; public class Util { - private static final String TAG = "SyncthingUtil"; + private static final String TAG = "Util"; private Util() { } @@ -181,6 +181,7 @@ public class Util { */ public static int runShellCommand(String cmd, Boolean useRoot) { // Assume "failure" exit code if an error is caught. + // Note: redirectErrorStream(true); System.getProperty("line.separator"); int exitCode = 255; Process shellProc = null; DataOutputStream shellOut = null; @@ -193,6 +194,20 @@ public class Util { bufferedWriter.flush(); shellOut.close(); shellOut = null; + BufferedReader bufferedReader = null; + try { + bufferedReader = new BufferedReader(new InputStreamReader(shellProc.getInputStream(), Charsets.UTF_8)); + String line; + while ((line = bufferedReader.readLine()) != null) { + Log.v(TAG, "runShellCommand: " + line); + } + } catch (IOException e) { + Log.w(TAG, "runShellCommand: Failed to read output", e); + } finally { + if (bufferedReader != null) { + bufferedReader.close(); + } + } exitCode = shellProc.waitFor(); } catch (IOException | InterruptedException e) { Log.w(TAG, "runShellCommand: Exception", e); @@ -212,6 +227,7 @@ public class Util { } public static String runShellCommandGetOutput(String cmd, Boolean useRoot) { + // Note: redirectErrorStream(true); System.getProperty("line.separator"); int exitCode = 255; String capturedStdOut = ""; Process shellProc = null; @@ -236,8 +252,9 @@ public class Util { } catch (IOException e) { Log.w(TAG, "runShellCommandGetOutput: Failed to read output", e); } finally { - if (bufferedReader != null) + if (bufferedReader != null) { bufferedReader.close(); + } } exitCode = shellProc.waitFor(); Log.i(TAG, "runShellCommandGetOutput: Exited with code " + exitCode);