From c567cc3b926a41554e1730dc7200a678df5c12e6 Mon Sep 17 00:00:00 2001 From: agnostic-apollo Date: Sat, 5 Feb 2022 07:19:36 +0500 Subject: [PATCH] Fixed: Fix app crash if failed to start TermuxService while in background due to android bg restrictions The crash happens due to android 8.0 background restrictions if TermuxActivity is not in foreground/whitelist and attempts to start TermuxService. With this commit, the app will not crash but will just exit with a toast message. https://developer.android.com/about/versions/oreo/background#services https://cs.android.com/android/platform/superproject/+/android-12.0.0_r4:frameworks/base/services/core/java/com/android/server/am/ActiveServices.java;l=722 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.termux/com.termux.app.TermuxActivity}: java.lang.IllegalStateException: Not allowed to start service Intent { cmp=com.termux/.app.TermuxService }: app is in background uid UidRecord{533ae62 u0a187 TPSL idle procs:1 seq(0,0,0)} at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2947) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3082) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1832) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:201) at android.app.ActivityThread.main(ActivityThread.java:6821) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873) Caused by: java.lang.IllegalStateException: Not allowed to start service Intent { cmp=com.termux/.app.TermuxService }: app is in background uid UidRecord{533ae62 u0a187 TPSL idle procs:1 seq(0,0,0)} at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1587) at android.app.ContextImpl.startService(ContextImpl.java:1542) at android.content.ContextWrapper.startService(ContextWrapper.java:674) at com.termux.app.TermuxActivity.onCreate(TermuxActivity.java:242) at android.app.Activity.performCreate(Activity.java:7224) at android.app.Activity.performCreate(Activity.java:7213) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1272) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2927) ... 11 more Closes #2552 --- .../java/com/termux/app/TermuxActivity.java | 24 +++++++++++++------ app/src/main/res/values/strings.xml | 2 ++ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/termux/app/TermuxActivity.java b/app/src/main/java/com/termux/app/TermuxActivity.java index b802d824..9a245324 100644 --- a/app/src/main/java/com/termux/app/TermuxActivity.java +++ b/app/src/main/java/com/termux/app/TermuxActivity.java @@ -248,14 +248,24 @@ public final class TermuxActivity extends AppCompatActivity implements ServiceCo registerForContextMenu(mTerminalView); - // Start the {@link TermuxService} and make it run regardless of who is bound to it - Intent serviceIntent = new Intent(this, TermuxService.class); - startService(serviceIntent); + try { + // Start the {@link TermuxService} and make it run regardless of who is bound to it + Intent serviceIntent = new Intent(this, TermuxService.class); + startService(serviceIntent); - // Attempt to bind to the service, this will call the {@link #onServiceConnected(ComponentName, IBinder)} - // callback if it succeeds. - if (!bindService(serviceIntent, this, 0)) - throw new RuntimeException("bindService() failed"); + // Attempt to bind to the service, this will call the {@link #onServiceConnected(ComponentName, IBinder)} + // callback if it succeeds. + if (!bindService(serviceIntent, this, 0)) + throw new RuntimeException("bindService() failed"); + } catch (Exception e) { + Logger.logStackTraceWithMessage(LOG_TAG,"TermuxActivity failed to start TermuxService", e); + Logger.showToast(this, + getString(e.getMessage() != null && e.getMessage().contains("app is in background") ? + R.string.error_termux_service_start_failed_bg : R.string.error_termux_service_start_failed_general), + true); + mIsInvalidState = true; + return; + } // Send the {@link TermuxConstants#BROADCAST_TERMUX_OPENED} broadcast to notify apps that Termux // app has been opened. diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d5335bf0..5f23f4bb 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -118,6 +118,8 @@ %1$s requires `allow-external-apps` property to be set to `true` in `%2$s` file. + Failed to start TermuxService. Check logcat for exception message. + Failed to start TermuxService while app is in background due to android bg restrictions.