mirror of
https://github.com/fankes/termux-app.git
synced 2025-09-06 02:35:19 +08:00
Added: Add support for ACTION_NOTIFY_APP_CRASH
in receiver registered by TermuxActivity
to notify users of plugin app crashes
Once plugins integrate changes for `TermuxCrashUtils.onPostLogCrash()`, they will send the `ACTION_NOTIFY_APP_CRASH` broadcast when an uncaught exception is caught by `CrashHandler`. If `TermuxActivity` is in foreground, then it will receive the broadcast and notify user of the crash by reading it from the crash log file without the user having to restart termux app to be notified.
This commit is contained in:
@@ -907,8 +907,9 @@ public final class TermuxActivity extends AppCompatActivity implements ServiceCo
|
|||||||
|
|
||||||
private void registerTermuxActivityBroadcastReceiver() {
|
private void registerTermuxActivityBroadcastReceiver() {
|
||||||
IntentFilter intentFilter = new IntentFilter();
|
IntentFilter intentFilter = new IntentFilter();
|
||||||
intentFilter.addAction(TERMUX_ACTIVITY.ACTION_REQUEST_PERMISSIONS);
|
intentFilter.addAction(TERMUX_ACTIVITY.ACTION_NOTIFY_APP_CRASH);
|
||||||
intentFilter.addAction(TERMUX_ACTIVITY.ACTION_RELOAD_STYLE);
|
intentFilter.addAction(TERMUX_ACTIVITY.ACTION_RELOAD_STYLE);
|
||||||
|
intentFilter.addAction(TERMUX_ACTIVITY.ACTION_REQUEST_PERMISSIONS);
|
||||||
|
|
||||||
registerReceiver(mTermuxActivityBroadcastReceiver, intentFilter);
|
registerReceiver(mTermuxActivityBroadcastReceiver, intentFilter);
|
||||||
}
|
}
|
||||||
@@ -936,14 +937,18 @@ public final class TermuxActivity extends AppCompatActivity implements ServiceCo
|
|||||||
fixTermuxActivityBroadcastReceieverIntent(intent);
|
fixTermuxActivityBroadcastReceieverIntent(intent);
|
||||||
|
|
||||||
switch (intent.getAction()) {
|
switch (intent.getAction()) {
|
||||||
case TERMUX_ACTIVITY.ACTION_REQUEST_PERMISSIONS:
|
case TERMUX_ACTIVITY.ACTION_NOTIFY_APP_CRASH:
|
||||||
Logger.logDebug(LOG_TAG, "Received intent to request storage permissions");
|
Logger.logDebug(LOG_TAG, "Received intent to notify app crash");
|
||||||
requestStoragePermission(false);
|
TermuxCrashUtils.notifyAppCrashFromCrashLogFile(context, LOG_TAG);
|
||||||
return;
|
return;
|
||||||
case TERMUX_ACTIVITY.ACTION_RELOAD_STYLE:
|
case TERMUX_ACTIVITY.ACTION_RELOAD_STYLE:
|
||||||
Logger.logDebug(LOG_TAG, "Received intent to reload styling");
|
Logger.logDebug(LOG_TAG, "Received intent to reload styling");
|
||||||
reloadActivityStyling(intent.getBooleanExtra(TERMUX_ACTIVITY.EXTRA_RECREATE_ACTIVITY, true));
|
reloadActivityStyling(intent.getBooleanExtra(TERMUX_ACTIVITY.EXTRA_RECREATE_ACTIVITY, true));
|
||||||
return;
|
return;
|
||||||
|
case TERMUX_ACTIVITY.ACTION_REQUEST_PERMISSIONS:
|
||||||
|
Logger.logDebug(LOG_TAG, "Received intent to request storage permissions");
|
||||||
|
requestStoragePermission(false);
|
||||||
|
return;
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -8,7 +8,7 @@ import java.util.Formatter;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Version: v0.37.0
|
* Version: v0.38.0
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
* Changelog
|
* Changelog
|
||||||
@@ -223,6 +223,9 @@ import java.util.List;
|
|||||||
*
|
*
|
||||||
* - 0.37.0 (2022-03-15)
|
* - 0.37.0 (2022-03-15)
|
||||||
* - Added `TERMUX_API_APT_*`.
|
* - Added `TERMUX_API_APT_*`.
|
||||||
|
*
|
||||||
|
* - 0.38.0 (2022-03-16)
|
||||||
|
* - Added `TERMUX_APP.TERMUX_ACTIVITY.ACTION_NOTIFY_APP_CRASH`.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -874,8 +877,9 @@ public final class TermuxConstants {
|
|||||||
public static final String EXTRA_FAILSAFE_SESSION = TermuxConstants.TERMUX_PACKAGE_NAME + ".app.failsafe_session"; // Default: "com.termux.app.failsafe_session"
|
public static final String EXTRA_FAILSAFE_SESSION = TermuxConstants.TERMUX_PACKAGE_NAME + ".app.failsafe_session"; // Default: "com.termux.app.failsafe_session"
|
||||||
|
|
||||||
|
|
||||||
/** Intent action to make termux request storage permissions */
|
/** Intent action to make termux app notify user that a crash happened. */
|
||||||
public static final String ACTION_REQUEST_PERMISSIONS = TermuxConstants.TERMUX_PACKAGE_NAME + ".app.request_storage_permissions"; // Default: "com.termux.app.request_storage_permissions"
|
public static final String ACTION_NOTIFY_APP_CRASH = TermuxConstants.TERMUX_PACKAGE_NAME + ".app.notify_app_crash"; // Default: "com.termux.app.notify_app_crash"
|
||||||
|
|
||||||
|
|
||||||
/** Intent action to make termux reload its termux session styling */
|
/** Intent action to make termux reload its termux session styling */
|
||||||
public static final String ACTION_RELOAD_STYLE = TermuxConstants.TERMUX_PACKAGE_NAME + ".app.reload_style"; // Default: "com.termux.app.reload_style"
|
public static final String ACTION_RELOAD_STYLE = TermuxConstants.TERMUX_PACKAGE_NAME + ".app.reload_style"; // Default: "com.termux.app.reload_style"
|
||||||
@@ -886,6 +890,9 @@ public final class TermuxConstants {
|
|||||||
/** Intent {@code boolean} extra for whether to recreate activity for the TERMUX_ACTIVITY.ACTION_RELOAD_STYLE intent. */
|
/** Intent {@code boolean} extra for whether to recreate activity for the TERMUX_ACTIVITY.ACTION_RELOAD_STYLE intent. */
|
||||||
public static final String EXTRA_RECREATE_ACTIVITY = TERMUX_APP.TERMUX_ACTIVITY_NAME + ".EXTRA_RECREATE_ACTIVITY"; // Default: "com.termux.app.TermuxActivity.EXTRA_RECREATE_ACTIVITY"
|
public static final String EXTRA_RECREATE_ACTIVITY = TERMUX_APP.TERMUX_ACTIVITY_NAME + ".EXTRA_RECREATE_ACTIVITY"; // Default: "com.termux.app.TermuxActivity.EXTRA_RECREATE_ACTIVITY"
|
||||||
|
|
||||||
|
|
||||||
|
/** Intent action to make termux request storage permissions */
|
||||||
|
public static final String ACTION_REQUEST_PERMISSIONS = TermuxConstants.TERMUX_PACKAGE_NAME + ".app.request_storage_permissions"; // Default: "com.termux.app.request_storage_permissions"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -34,12 +34,70 @@ import java.nio.charset.Charset;
|
|||||||
|
|
||||||
public class TermuxCrashUtils implements CrashHandler.CrashHandlerClient {
|
public class TermuxCrashUtils implements CrashHandler.CrashHandlerClient {
|
||||||
|
|
||||||
|
public enum TYPE {
|
||||||
|
UNCAUGHT_EXCEPTION,
|
||||||
|
CAUGHT_EXCEPTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final TYPE mType;
|
||||||
|
|
||||||
|
private static final String LOG_TAG = "TermuxCrashUtils";
|
||||||
|
|
||||||
|
TermuxCrashUtils(TYPE type) {
|
||||||
|
mType = type;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set default uncaught crash handler of current thread to {@link CrashHandler} for Termux app
|
* Set default uncaught crash handler of current thread to {@link CrashHandler} for Termux app
|
||||||
* and its plugin to log crashes at {@link TermuxConstants#TERMUX_CRASH_LOG_FILE_PATH}.
|
* and its plugin to log crashes at {@link TermuxConstants#TERMUX_CRASH_LOG_FILE_PATH}.
|
||||||
*/
|
*/
|
||||||
public static void setCrashHandler(@NonNull final Context context) {
|
public static void setCrashHandler(@NonNull final Context context) {
|
||||||
CrashHandler.setCrashHandler(context, new TermuxCrashUtils());
|
CrashHandler.setCrashHandler(context, new TermuxCrashUtils(TYPE.UNCAUGHT_EXCEPTION));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log a crash to {@link TermuxConstants#TERMUX_CRASH_LOG_FILE_PATH} and notify termux app
|
||||||
|
* by sending it the {@link TERMUX_APP.TERMUX_ACTIVITY#ACTION_NOTIFY_APP_CRASH} broadcast.
|
||||||
|
*
|
||||||
|
* @param context The {@link Context} for operations.
|
||||||
|
* @param throwable The {@link Throwable} thrown for the crash.
|
||||||
|
*/
|
||||||
|
public static void logCrash(@NonNull final Context context, final Throwable throwable) {
|
||||||
|
if (throwable == null) return;
|
||||||
|
CrashHandler.logCrash(context, new TermuxCrashUtils(TYPE.CAUGHT_EXCEPTION), Thread.currentThread(), throwable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPreLogCrash(Context context, Thread thread, Throwable throwable) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPostLogCrash(final Context currentPackageContext, Thread thread, Throwable throwable) {
|
||||||
|
if (currentPackageContext == null) return;
|
||||||
|
String currentPackageName = currentPackageContext.getPackageName();
|
||||||
|
|
||||||
|
// Do not notify if is a non-termux app
|
||||||
|
final Context context = TermuxUtils.getTermuxPackageContext(currentPackageContext);
|
||||||
|
if (context == null) {
|
||||||
|
Logger.logWarn(LOG_TAG, "Ignoring call to onPostLogCrash() since failed to get \"" + TermuxConstants.TERMUX_PACKAGE_NAME + "\" package context from \"" + currentPackageName + "\" context");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If an uncaught exception, then do not notify since the termux app itself would be crashing
|
||||||
|
if (TYPE.UNCAUGHT_EXCEPTION.equals(mType) && TermuxConstants.TERMUX_PACKAGE_NAME.equals(currentPackageName))
|
||||||
|
return;
|
||||||
|
|
||||||
|
String message = TERMUX_APP.TERMUX_ACTIVITY_NAME + " that \"" + currentPackageName + "\" app crashed";
|
||||||
|
|
||||||
|
try {
|
||||||
|
Logger.logInfo(LOG_TAG, "Sending broadcast to notify " + message);
|
||||||
|
Intent intent = new Intent(TERMUX_APP.TERMUX_ACTIVITY.ACTION_NOTIFY_APP_CRASH);
|
||||||
|
intent.setPackage(TermuxConstants.TERMUX_PACKAGE_NAME);
|
||||||
|
context.sendBroadcast(intent);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Logger.logStackTraceWithMessage(LOG_TAG,"Failed to notify " + message, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
|
Reference in New Issue
Block a user