From 01b3a65a05730a1608237230ccdd44c67cd62de8 Mon Sep 17 00:00:00 2001 From: Greg Alexander Date: Sun, 22 Sep 2019 15:49:48 -0400 Subject: [PATCH] make all startService calls go through SimpleSSHDService.do_startService() so they can be forced through startForegroundService or what-have-you. --- NOTES | 37 ++++++++++++++++++- .../org/galexander/sshd/BootReceiver.java | 4 +- .../java/org/galexander/sshd/SimpleSSHD.java | 8 +--- .../galexander/sshd/SimpleSSHDService.java | 12 ++++-- .../org/galexander/sshd/StartReceiver.java | 3 +- .../org/galexander/sshd/StopReceiver.java | 4 +- 6 files changed, 51 insertions(+), 17 deletions(-) diff --git a/NOTES b/NOTES index 6917af4..52e1c02 100644 --- a/NOTES +++ b/NOTES @@ -1067,7 +1067,42 @@ and I'm not gonna be doing new updates to version 19 anyways, so, whatever. -XXX - see if crash in startService continues with version 23 +September 22, 2019. + +The crash on startService() in onResume() has already been verified to +occur also at version 23, so I have to track that down. I found this, +which is likely to be the underlying problem: + + https://stackoverflow.com/questions/52013545/android-9-0-not-allowed-to-start-service-app-is-in-background-after-onresume + +It looks like the user opens the app with start-on-open, it works, and +then they let the phone fall asleep with SimpleSSHD on top, and some sort +of shuffle kills the service, and then they wake the phone up, and then +it tries to resume SimpleSSHD, which tries to re-start the service, which +fails because the phone hasn't finished waking up yet so even the top +activity isn't active yet, even though it's already in +SimpleSSHD.onResume(). Apparently acknowledged as a bug in Android 9. + +I tried to synthesize this sequence on the emulator with x86 pie, and I +had no luck. I was able to get the service to die (by broadcasting STOP) +while the emulator was "asleep", but then it woke up it didn't cause any +trouble. I suspect it takes a few coincidences to reliably trigger. + +Anyways, so what I'm doing is I'm having the startService() calls in +SimpleSSHD go through the SimpleSSHDService.do_startService() wrapper, so +that they become startForegroundService() calls as appropriate. This may +solve the problem on its own, if the user happens to have selected +foreground. But then I can also make this common path smarter... + +On another note, I stumbled onto something that says Android 9 limits +implicit broadcasts (no explicit destination), and considers a broadcast +to be implicit even if it does have an explicit destination if there is +an "action string." !!! Not sure if that's something I can play with, +but putting it on the list. + + +XXX - make do_startService() implement the hack to check if it's really foreground +XXX - figure out how to make the google play store know it's android TV compatible XXX - figure out how to force a refresh on eink devices (onyx boox) when the password is displayed (Roman) XXX - Tasker on Android 9 can't trigger the new START/STOP intents? (Kumaran) XXX - test file renaming in /storage/emulated/0/download on Quiche for Ben Reaves diff --git a/app/src/main/java/org/galexander/sshd/BootReceiver.java b/app/src/main/java/org/galexander/sshd/BootReceiver.java index 221cc17..9d18263 100644 --- a/app/src/main/java/org/galexander/sshd/BootReceiver.java +++ b/app/src/main/java/org/galexander/sshd/BootReceiver.java @@ -8,8 +8,8 @@ public class BootReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { Prefs.init(context); if (Prefs.get_onboot()) { - SimpleSSHDService.my_startService(context, - new Intent(context, SimpleSSHDService.class)); + SimpleSSHDService.do_startService(context, + /*stop=*/false); } } } diff --git a/app/src/main/java/org/galexander/sshd/SimpleSSHD.java b/app/src/main/java/org/galexander/sshd/SimpleSSHD.java index 51508bd..a35ec5a 100644 --- a/app/src/main/java/org/galexander/sshd/SimpleSSHD.java +++ b/app/src/main/java/org/galexander/sshd/SimpleSSHD.java @@ -60,7 +60,7 @@ public class SimpleSSHD extends Activity ip_view.setText(get_ip(true)); if (Prefs.get_onopen() && !SimpleSSHDService.is_started()) { - startService(new Intent(this, SimpleSSHDService.class)); + SimpleSSHDService.do_startService(this, /*stop=*/false); } } @@ -172,11 +172,7 @@ public class SimpleSSHD extends Activity public void startstop_clicked(View v) { boolean already_started = SimpleSSHDService.is_started(); - Intent i = new Intent(this, SimpleSSHDService.class); - if (already_started) { - i.putExtra("stop", true); - } - startService(i); + SimpleSSHDService.do_startService(this, already_started); if (already_started && Prefs.get_onopen()) { finish(); } diff --git a/app/src/main/java/org/galexander/sshd/SimpleSSHDService.java b/app/src/main/java/org/galexander/sshd/SimpleSSHDService.java index 5de7f2e..9a6bb64 100644 --- a/app/src/main/java/org/galexander/sshd/SimpleSSHDService.java +++ b/app/src/main/java/org/galexander/sshd/SimpleSSHDService.java @@ -1,5 +1,6 @@ package org.galexander.sshd; +import android.app.Activity; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; @@ -212,12 +213,17 @@ public class SimpleSSHDService extends Service { System.loadLibrary("simplesshd-jni"); } - public static void my_startService(Context ctx, Intent i) { + public static void do_startService(Context ctx, boolean stop) { + Intent i = new Intent(ctx, SimpleSSHDService.class); + if (stop) { + i.putExtra("stop", true); + } Prefs.init(ctx); - if (Build.VERSION.SDK_INT >= - Build.VERSION_CODES.O) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Prefs.get_foreground()) { ctx.startForegroundService(i); + } else if (ctx instanceof Activity) { + ctx.startService(i); } else { Toast.makeText(ctx, "SimpleSSHD cannot start in background since Oreo (enable Settings -> Foreground Service).", diff --git a/app/src/main/java/org/galexander/sshd/StartReceiver.java b/app/src/main/java/org/galexander/sshd/StartReceiver.java index cfa4673..27cbdc8 100644 --- a/app/src/main/java/org/galexander/sshd/StartReceiver.java +++ b/app/src/main/java/org/galexander/sshd/StartReceiver.java @@ -6,7 +6,6 @@ import android.content.Context; public class StartReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { - SimpleSSHDService.my_startService(context, - new Intent(context, SimpleSSHDService.class)); + SimpleSSHDService.do_startService(context, /*stop=*/false); } } diff --git a/app/src/main/java/org/galexander/sshd/StopReceiver.java b/app/src/main/java/org/galexander/sshd/StopReceiver.java index 5438340..2eedd98 100644 --- a/app/src/main/java/org/galexander/sshd/StopReceiver.java +++ b/app/src/main/java/org/galexander/sshd/StopReceiver.java @@ -6,8 +6,6 @@ import android.content.Context; public class StopReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { - SimpleSSHDService.my_startService(context, - new Intent(context, SimpleSSHDService.class) - .putExtra("stop", true)); + SimpleSSHDService.do_startService(context, /*stop=*/true); } }