diff --git a/terminal-emulator/src/main/java/com/termux/terminal/Logger.java b/terminal-emulator/src/main/java/com/termux/terminal/Logger.java new file mode 100644 index 00000000..d4d502e0 --- /dev/null +++ b/terminal-emulator/src/main/java/com/termux/terminal/Logger.java @@ -0,0 +1,80 @@ +package com.termux.terminal; + +import android.util.Log; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; + +public class Logger { + + public static void logError(TerminalSessionClient client, String logTag, String message) { + if (client != null) + client.logError(logTag, message); + else + Log.e(logTag, message); + } + + public static void logWarn(TerminalSessionClient client, String logTag, String message) { + if (client != null) + client.logWarn(logTag, message); + else + Log.w(logTag, message); + } + + public static void logInfo(TerminalSessionClient client, String logTag, String message) { + if (client != null) + client.logInfo(logTag, message); + else + Log.i(logTag, message); + } + + public static void logDebug(TerminalSessionClient client, String logTag, String message) { + if (client != null) + client.logDebug(logTag, message); + else + Log.d(logTag, message); + } + + public static void logVerbose(TerminalSessionClient client, String logTag, String message) { + if (client != null) + client.logVerbose(logTag, message); + else + Log.v(logTag, message); + } + + public static void logStackTraceWithMessage(TerminalSessionClient client, String tag, String message, Throwable throwable) { + logError(client, tag, getMessageAndStackTraceString(message, throwable)); + } + + public static String getMessageAndStackTraceString(String message, Throwable throwable) { + if (message == null && throwable == null) + return null; + else if (message != null && throwable != null) + return message + ":\n" + getStackTraceString(throwable); + else if (throwable == null) + return message; + else + return getStackTraceString(throwable); + } + + public static String getStackTraceString(Throwable throwable) { + if (throwable == null) return null; + + String stackTraceString = null; + + try { + StringWriter errors = new StringWriter(); + PrintWriter pw = new PrintWriter(errors); + throwable.printStackTrace(pw); + pw.close(); + stackTraceString = errors.toString(); + errors.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + return stackTraceString; + } + +} diff --git a/terminal-emulator/src/main/java/com/termux/terminal/TerminalEmulator.java b/terminal-emulator/src/main/java/com/termux/terminal/TerminalEmulator.java index 471c5df5..d37eab8d 100644 --- a/terminal-emulator/src/main/java/com/termux/terminal/TerminalEmulator.java +++ b/terminal-emulator/src/main/java/com/termux/terminal/TerminalEmulator.java @@ -824,7 +824,7 @@ public final class TerminalEmulator { if (internalBit != -1) { value = isDecsetInternalBitSet(internalBit) ? 1 : 2; // 1=set, 2=reset. } else { - mClient.logError(LOG_TAG, "Got DECRQM for unrecognized private DEC mode=" + mode); + Logger.logError(mClient, LOG_TAG, "Got DECRQM for unrecognized private DEC mode=" + mode); value = 0; // 0=not recognized, 3=permanently set, 4=permanently reset } } @@ -961,7 +961,7 @@ public final class TerminalEmulator { case "&8": // Undo key - ignore. break; default: - mClient.logWarn(LOG_TAG, "Unhandled termcap/terminfo name: '" + trans + "'"); + Logger.logWarn(mClient, LOG_TAG, "Unhandled termcap/terminfo name: '" + trans + "'"); } // Respond with invalid request: mSession.write("\033P0+r" + part + "\033\\"); @@ -973,12 +973,12 @@ public final class TerminalEmulator { mSession.write("\033P1+r" + part + "=" + hexEncoded + "\033\\"); } } else { - mClient.logError(LOG_TAG, "Invalid device termcap/terminfo name of odd length: " + part); + Logger.logError(mClient, LOG_TAG, "Invalid device termcap/terminfo name of odd length: " + part); } } } else { if (LOG_ESCAPE_SEQUENCES) - mClient.logError(LOG_TAG, "Unrecognized device control string: " + dcs); + Logger.logError(mClient, LOG_TAG, "Unrecognized device control string: " + dcs); } finishSequence(); } @@ -1068,7 +1068,7 @@ public final class TerminalEmulator { int externalBit = mArgs[i]; int internalBit = mapDecSetBitToInternalBit(externalBit); if (internalBit == -1) { - mClient.logWarn(LOG_TAG, "Ignoring request to save/recall decset bit=" + externalBit); + Logger.logWarn(mClient, LOG_TAG, "Ignoring request to save/recall decset bit=" + externalBit); } else { if (b == 's') { mSavedDecSetFlags |= internalBit; @@ -1258,7 +1258,7 @@ public final class TerminalEmulator { // (1) enables this feature for keys except for those with well-known behavior, e.g., Tab, Backarrow and // some special control character cases, e.g., Control-Space to make a NUL. // (2) enables this feature for keys including the exceptions listed. - mClient.logError(LOG_TAG, "(ignored) CSI > MODIFY RESOURCE: " + getArg0(-1) + " to " + getArg1(-1)); + Logger.logError(mClient, LOG_TAG, "(ignored) CSI > MODIFY RESOURCE: " + getArg0(-1) + " to " + getArg1(-1)); break; default: parseArg(b); @@ -1805,7 +1805,7 @@ public final class TerminalEmulator { int firstArg = mArgs[i + 1]; if (firstArg == 2) { if (i + 4 > mArgIndex) { - mClient.logWarn(LOG_TAG, "Too few CSI" + code + ";2 RGB arguments"); + Logger.logWarn(mClient, LOG_TAG, "Too few CSI" + code + ";2 RGB arguments"); } else { int red = mArgs[i + 2], green = mArgs[i + 3], blue = mArgs[i + 4]; if (red < 0 || green < 0 || blue < 0 || red > 255 || green > 255 || blue > 255) { @@ -1830,7 +1830,7 @@ public final class TerminalEmulator { mBackColor = color; } } else { - if (LOG_ESCAPE_SEQUENCES) mClient.logWarn(LOG_TAG, "Invalid color index: " + color); + if (LOG_ESCAPE_SEQUENCES) Logger.logWarn(mClient, LOG_TAG, "Invalid color index: " + color); } } else { finishSequenceAndLogError("Invalid ISO-8613-3 SGR first argument: " + firstArg); @@ -1847,7 +1847,7 @@ public final class TerminalEmulator { mBackColor = code - 100 + 8; } else { if (LOG_ESCAPE_SEQUENCES) - mClient.logWarn(LOG_TAG, String.format("SGR unknown code %d", code)); + Logger.logWarn(mClient, LOG_TAG, String.format("SGR unknown code %d", code)); } } } @@ -1981,7 +1981,7 @@ public final class TerminalEmulator { String clipboardText = new String(Base64.decode(textParameter.substring(startIndex), 0), StandardCharsets.UTF_8); mSession.onCopyTextToClipboard(clipboardText); } catch (Exception e) { - mClient.logError(LOG_TAG, "OSC Manipulate selection, invalid string '" + textParameter + ""); + Logger.logError(mClient, LOG_TAG, "OSC Manipulate selection, invalid string '" + textParameter + ""); } break; case 104: @@ -2177,7 +2177,7 @@ public final class TerminalEmulator { } private void finishSequenceAndLogError(String error) { - if (LOG_ESCAPE_SEQUENCES) mClient.logWarn(LOG_TAG, error); + if (LOG_ESCAPE_SEQUENCES) Logger.logWarn(mClient, LOG_TAG, error); finishSequence(); } diff --git a/terminal-emulator/src/main/java/com/termux/terminal/TerminalSession.java b/terminal-emulator/src/main/java/com/termux/terminal/TerminalSession.java index 47ea8533..b06f0dea 100644 --- a/terminal-emulator/src/main/java/com/termux/terminal/TerminalSession.java +++ b/terminal-emulator/src/main/java/com/termux/terminal/TerminalSession.java @@ -236,7 +236,7 @@ public final class TerminalSession extends TerminalOutput { try { Os.kill(mShellPid, OsConstants.SIGKILL); } catch (ErrnoException e) { - mClient.logWarn(LOG_TAG, "Failed sending SIGKILL: " + e.getMessage()); + Logger.logWarn(mClient, LOG_TAG, "Failed sending SIGKILL: " + e.getMessage()); } } } @@ -308,7 +308,7 @@ public final class TerminalSession extends TerminalOutput { return outputPath; } } catch (IOException | SecurityException e) { - mClient.logStackTraceWithMessage(LOG_TAG, "Error getting current directory", e); + Logger.logStackTraceWithMessage(mClient, LOG_TAG, "Error getting current directory", e); } return null; } @@ -326,7 +326,7 @@ public final class TerminalSession extends TerminalOutput { descriptorField.setAccessible(true); descriptorField.set(result, fileDescriptor); } catch (NoSuchFieldException | IllegalAccessException | IllegalArgumentException e) { - client.logStackTraceWithMessage(LOG_TAG, "Error accessing FileDescriptor#descriptor private field", e); + Logger.logStackTraceWithMessage(client, LOG_TAG, "Error accessing FileDescriptor#descriptor private field", e); System.exit(1); } return result;