Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android 14 requires a foreground service type for startForeground #24

Open
KieronQuinn opened this issue Oct 8, 2023 · 67 comments
Open

Comments

@KieronQuinn
Copy link

As of Android 14, all foreground services need a type.

Currently, when targeting 14, you get this exception when running a plugin:

E  FATAL EXCEPTION: main
E  Process: com.kieronquinn.app.smartspacer.plugin.tasker, PID: 10215
E  android.app.MissingForegroundServiceTypeException: Starting FGS without a type  callerApp=ProcessRecord{faa457f 10215:com.kieronquinn.app.smartspacer.plugin.tasker/u0a567} targetSDK=34
E      at android.app.MissingForegroundServiceTypeException$1.createFromParcel(MissingForegroundServiceTypeException.java:53)
E      at android.app.MissingForegroundServiceTypeException$1.createFromParcel(MissingForegroundServiceTypeException.java:49)
E      at android.os.Parcel.readParcelableInternal(Parcel.java:4870)
E      at android.os.Parcel.readParcelable(Parcel.java:4852)
E      at android.os.Parcel.createExceptionOrNull(Parcel.java:3052)
E      at android.os.Parcel.createException(Parcel.java:3041)
E      at android.os.Parcel.readException(Parcel.java:3024)
E      at android.os.Parcel.readException(Parcel.java:2966)
E      at android.app.IActivityManager$Stub$Proxy.setServiceForeground(IActivityManager.java:6761)
E      at android.app.Service.startForeground(Service.java:775)
E      at com.joaomgcd.taskerpluginlibrary.runner.TaskerPluginRunner$Companion.startForegroundIfNeeded(TaskerPluginRunner.kt:77)
E      at com.joaomgcd.taskerpluginlibrary.runner.TaskerPluginRunner$Companion.startForegroundIfNeeded$default(TaskerPluginRunner.kt:73)
E      at com.joaomgcd.taskerpluginlibrary.runner.IntentServiceParallel.startForegroundIfNeeded(IntentServiceParallel.kt:25)
E      at com.joaomgcd.taskerpluginlibrary.action.IntentServiceAction.onHandleIntent(ActionReceivers.kt:24)
E      at com.joaomgcd.taskerpluginlibrary.runner.IntentServiceParallel.onStart$lambda-3(IntentServiceParallel.kt:66)
E      at com.joaomgcd.taskerpluginlibrary.runner.IntentServiceParallel.$r8$lambda$f5iZS9-kgufLZQgCE7KMiNChUM8(Unknown Source:0)
E      at com.joaomgcd.taskerpluginlibrary.runner.IntentServiceParallel$$ExternalSyntheticLambda2.run(Unknown Source:4)
E      at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:487)
E      at java.util.concurrent.FutureTask.run(FutureTask.java:264)
E      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
E      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
E      at java.lang.Thread.run(Thread.java:1012)

Note that the services declared in the manifest must also have this type, I suggest maybe the special use one might be best. Unsure how this would be taken in Play review though.

@joaomgcd
Copy link
Owner

joaomgcd commented Oct 9, 2023

Thank you for the heads up. Fixed in 0.4.9!

I did set it to android:foregroundServiceType="specialUse". Let's see if Google has any issues with that!

@joaomgcd joaomgcd closed this as completed Oct 9, 2023
@Tolriq
Copy link

Tolriq commented Oct 16, 2023

@joaomgcd See https://developer.android.com/about/versions/14/changes/fgs-types-required#special-use we are supposed to also add the property and this will all go through a google form very soon :(

If this road is chosen then the value should be well defined and we should already prepare a talk to convince Google, this will be a nightmare as each and every time :(

@KieronQuinn
Copy link
Author

You can override the service declaration in your manifest with your own description and the manifest merger will merge it. The important thing in this fix was the code.

@Tolriq
Copy link

Tolriq commented Oct 16, 2023

I perfectly know that, but you missed the important part: Google Form to publish in Play Store in a couple of months or less depending on their decisions.

If all apps puts random things there it will be harder to have a common ground discussion with Google so that they accept the permission and not reject your app and you'll be wondering what to do in that case.

The specialUse case is for certain one that will be under the form and will be the harder to get validated by the dumb support team.

@KieronQuinn
Copy link
Author

I don't read it as that. I read it as it's a freeform field to put your use for it, like how it is in the various forms on the Play Console. I think having a shared one would actually be detrimental as they'd view it as either spam or potentially malicious if everyone submitted the same generic "This is for Tasker" reason.

@Tolriq
Copy link

Tolriq commented Oct 16, 2023

The use is the same for everyone as it's the same library and the same service name.

I suppose you never had to deal with Google support for permission forms and the joy it is. At 99,99% the answer will be rejected, we can not confirm that this is a core feature of your application. The reviewer barely speak English and everything needs to be very simple sentences. Try to explain this is to allow automation from another app named tasker.

@KieronQuinn
Copy link
Author

I regularly deal with Google's policy team, in fact I spent much of last week arguing with them to turn on a VPN because they indeed do not read what is in front of them. This was for an app with 1.2 million users and was blocking an important update - they are useless.

However, I reiterate, I do not think sending the same message from multiple apps to them is a very good idea. Their ideas of "spam" are very rudimentary, and I'm pretty confident this would fall under them. The use is not the same for everyone, plugins do not all do the same thing. For example, the plugin at the root of this thread is for allowing Tasker to update and modify components of my app to effect what is displayed in a widget - it's not just "Allows Tasker to work with my app". They are more likely to approve an app-specific description than one they've seen before from another app.

@Tolriq
Copy link

Tolriq commented Oct 16, 2023

Well I'll let you discover then when they tell you that you do not need a foreground service for that.

Tasker is foreground if it binds to our service for your need you do not need to go foreground.

To update widget they will tell you work manager that is made for this. The concept of other app calling your app won't matter. That's why yes it matters to explain why tasker needs to start a foreground service to communicate with our app even if in most case it actually don't.

@KieronQuinn
Copy link
Author

You've essentially just proven my point. If I were to use a generic message, they would indeed ask why I need a foreground service to update a widget. That is why it should be custom, so you can provide a explanation of why it is needed. Just saying "oh it works with this app called Tasker" would most likely just be rejected, whereas a detailed message about what the Tasker integration provides and why a separate service is needed would be far, far better.

Anyway, since we're never going to reach an agreement on this, how about as a compromise there could be a generic reason in the library, with a strong emphasis of overriding it with your own. If you want to run the risk of using a generic message, that's on you. But when in a year they blanket ban every app with the generic message because it's deemed "spam" or because one of them was doing something deemed malicious and therefore they're all connected, don't say you weren't warned.

@Tolriq
Copy link

Tolriq commented Oct 16, 2023

I'll remove the plugin and tell user to call my API instead.

And the explanation will be on the form that you fill not in the 20 char you'll use there.
So yes having all tasker services using the same explanation that you justify in the form will. It's easier to keep the service name via R8 to ensure Google is aware than having each and every user explaining that no we do not need foreground but Takser current API requires ven if in fact it does not

Future will tell but 12 years on Play Store touching with many perm form we already know it will be a shit show. They want the end of foreground services.

@KieronQuinn
Copy link
Author

The developer page specifically asks for the explanation to be in the manifest, and asks you to provide enough information in it alone - putting a brief explanation in here and expecting them to read the form will probably not go well

image

I agree the service name will stay the same - it will have to - but the use case does not need to.

And yes, they are doing everything they can to kill off foreground services. The Play Store is minefield to submit to nowadays, which is why I no longer submit personal projects due to the risk of their stupid "association" bans impacting my work, because one test phone was on the same IP once or something ridiculous like that. It's bad enough having to communicate with the policy team for large apps, let alone small ones.

@Tolriq
Copy link

Tolriq commented Oct 16, 2023

Again there is no need for the service to be foreground for 99% of the cases. So either we can have a default communication or most people will be rejected. Tasker is foreground if it binds to our service we are foreground too.

So the actual real solution is to fix the API to not require foreground when not needed, not hoping that everyone will be able to pass a dumb review system handled by monkeys. This will be frustration for the whole Tasker eco system with no benefits.

@joaomgcd
Copy link
Owner

Sorry for the late Response.

@Tolriq foreground services are required if the actions done in the service take more than 5 seconds to complete.

Unfortunately you can't really control how much time your service will take because sometimes users' devices are slow and will take a long time to perform even trivial operations.

Because of this I thought it would be appropriate to make foreground services a requirement?

What do you think?

Also, ( also for @KieronQuinn ) just thinking here: since not all plugins require actions or conditions (a plugin could only have an action or a condition and not both) I shouldn't declare the services at all in the plugin library's manifest, right? Because if I do, plugin developers will have to justify services that they don't even use. Am I thinking correctly?

@Tolriq
Copy link

Tolriq commented Oct 18, 2023

@joaomgcd I don't know Tasker internals but since tasker is foreground it can just bind to the service and do not have any limitation in times. The 5 second limit for a service is the time to go foreground if you call startforeground else it ANR. But this is another story since you can bind and not call startForeground at all. (https://developer.android.com/guide/components/foreground-services#background-start-restriction-exemptions)

For the other question, yes if there's things that does not require the foreground services at all clients should not be forced to deal with the stupid Google review team.

One way could be to split the library in 2 parts so that it's clear what requires it (if it really requires) and what does not.

But really the question is are the services really needing the foreground here? I'm pretty sure we can solve this without foreground at all.

@joaomgcd
Copy link
Owner

Hhmm, switching to binding services from what we have now is kind of a big refactor. 😅 I would also have to do plenty of tests with it because I don't have much experience with binding services myself...

Thanks for the suggestion. I'll look into it.

@Tolriq
Copy link

Tolriq commented Oct 18, 2023

You are not forced to go full bind and aidl :) You can just cheat the system.

You bind to the service without anything special or calls to the service (just a service connection to manage) and you keep doing what you do without calling startForeground, just a normal start.

The only question would be if OEMs have broken implementations that does not propagate the foreground state, but we already have to deal with OEMs that do not respect foreground at all so in the end it would not change a lot.

@joaomgcd
Copy link
Owner

I see what you mean. Ok, let me try that and see how it works. Thanks!

@joaomgcd
Copy link
Owner

So, first shot at this.

If you could try building the plugin library from source (get the latest version) and then make hasToRunServicesInForeground always return false and then try using this version of Tasker and see if it correctly runs your actions with the bound service but without putting it in the foreground...

Can you try that? 😅 Thanks in advance!

@Tolriq
Copy link

Tolriq commented Oct 18, 2023

I can try tomorrow but I'm not an advanced Tasker user. So not sure I'll be able to test all. A part of the plugin export state I don't even know how to properly use it on Tasker :p

@joaomgcd
Copy link
Owner

It's really just a matter of adding a Yatse plugin action in a task and running it and see if it runs correctly :) If nothing crashes and it runs as expected (after you did the change to the code I mentioned above), then it means that Tasker is running the plugin correctly without asking it to be in the foreground.

Let me know if you have any questions!

@Tolriq
Copy link

Tolriq commented Oct 19, 2023

@joaomgcd So tested with the hasToRunServicesInForeground to false and removing the FGS type from manifest to be sure and it does not crash and the simple commands like playpause works properly.

Not sure this counts as a full test, but this works in Android 14 :)

@joaomgcd
Copy link
Owner

Sounds good :) And your app is already targeting Android 14, correct?

@Tolriq
Copy link

Tolriq commented Oct 19, 2023

Yes and it crashed before I added the fgs types.

@joaomgcd
Copy link
Owner

Cool! Ok, I'll try a release with this change then. Thanks for testing!

@Tolriq
Copy link

Tolriq commented Oct 19, 2023

It will probably require some coordination between the lib and tasker to ensure no issue.

If the library is updated to remove the fgs type we need to check that tasker is up to date or find a way to warn the users to update tasker.

@joaomgcd
Copy link
Owner

joaomgcd commented Oct 19, 2023

Yep.

  • The current Play Store version of Tasker will always start plugins in the foreground
  • My update will only call services in the foreground if the <meta-data android:name="canBind"> tag is not present in the plugin service manifest declaration
  • If the <meta-data> tag is present, Tasker will bind instead of calling in the foreground and will signal the plugin that it did that, so that the plugin doesn't try to start its service in the foreground either

The problem is that the current public version of Tasker doesn't have this check yet, so I'll have to hurry and update it as soon as possible 😅

@Tolriq
Copy link

Tolriq commented Oct 19, 2023

What I meant is if I update Yatse with a new lib that have the tag and no more FGS type.
But the user on his phone still have an older tasker version. Then tasker won't bind and if it does call startForeground then we'll have ANRs or crash on A14 no? Hence this case to handle.

@joaomgcd
Copy link
Owner

If

  • user has updated Yatse with new Tasker lib
  • user has old Tasker

Tasker will always call plugin service in the foreground and plugin will always call startForeground in its service.

Oh, but you're right, the service does need to retain the FGS type tag :/, because it would crash if it runs with an old Tasker version.

But if the FGS tag is retained we end up where we started with the Play Store issues :/

Hmm... do you see any solution for this?

@Tolriq
Copy link

Tolriq commented Oct 19, 2023

If tasker always startforeground calls and it's not the plugin doing something then there's not much.

Only solution is to add a way to check tasker version in the library, keep the FGS type for now until Google add the form.

And during the intermediary time the apps can check if tasker is uptodate or not in the calls and tell the user that he should update.

Not perfect but well.

@Tolriq
Copy link

Tolriq commented Oct 27, 2023

Lol no problem we still have time, but in all case for tasker showing them a video of another app would be problematic anyway :)

@Tolriq
Copy link

Tolriq commented Nov 7, 2023

So the dead line is now official it's 7th December to be approved or no more updates allowed :(

Have you made progress with Google and that other permission?

@joaomgcd
Copy link
Owner

joaomgcd commented Nov 8, 2023

I'm working on the release now. The problem is that I now need to update the app on all tracks without the permission, so I can't widely test the new version that doesn't have the permission. I'm hoping to do a public release next week though!

It's so weird how they demand that you update all release tracks at once without the permission and don't even allow you to beta test it :(

@Tolriq
Copy link

Tolriq commented Nov 8, 2023

One of the many Google mysteries :(
That and who they employ for the AA and Wear reviews.

But I'm sure we'll face the same issue with tasker plugins won't be able to test a release without the perm in beta without getting the form first. So absurd.

@joaomgcd
Copy link
Owner

Ok, I've sent the app for review now in Production. Hope they approve it soon.

@Tolriq
Copy link

Tolriq commented Dec 1, 2023

@joaomgcd any luck with the publishing? Deadline is short now.

@Tolriq
Copy link

Tolriq commented Dec 2, 2023

Just saw your post on reddit :( So sorry, Google is really a pain those days this is incredible :(

@KieronQuinn did you attempt the form with the custom permission did they validate it?

@KieronQuinn
Copy link
Author

Just saw your post on reddit :( So sorry, Google is really a pain those days this is incredible :(

@KieronQuinn did you attempt the form with the custom permission did they validate it?

I don't publish on Google Play, for this very reason.

@joaomgcd
Copy link
Owner

joaomgcd commented Dec 4, 2023

Yeah, sorry, they keep making stuff up and I can't really understand why.

Now they're saying I'm sending SMS and Contact data to http://myserver.com/ ....

And worst of all, they're taking a really long time to get back to me about it after I asked for proof. Sorry! :(

@Tolriq
Copy link

Tolriq commented Dec 4, 2023

Don't be sorry this is not your fault if Google is becoming more and more hostile to indie devs :(

We just need to adapt with the little info we have.

@Tolriq
Copy link

Tolriq commented Dec 5, 2023

@joaomgcd don't know why can't post the patch file on reddit.

You probably forget to change something.

Here's the Yatse patch that pleased them .

 Wear/build.gradle.kts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Wear/build.gradle.kts b/Wear/build.gradle.kts
index 89baa7021..fdf8efd60 100644
--- a/Wear/build.gradle.kts
+++ b/Wear/build.gradle.kts
@@ -217,6 +217,7 @@ dependencies {
     implementation(libs.playservices.wearable)
     implementation(libs.androidx.wear)
     implementation(libs.androidx.activity.ktx)
+    implementation(libs.androidx.core.splashscreen)
     implementation(libs.androidx.compose.activity)
     implementation(libs.androidx.fragment.ktx)
     implementation(libs.coroutines.android)
 Wear/src/main/AndroidManifest.xml | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/Wear/src/main/AndroidManifest.xml b/Wear/src/main/AndroidManifest.xml
index 6e9733f6d..936276a90 100644
--- a/Wear/src/main/AndroidManifest.xml
+++ b/Wear/src/main/AndroidManifest.xml
@@ -11,7 +11,7 @@
         android:allowBackup="false"
         android:icon="@mipmap/ic_launcher"
         android:label="${applicationLabel}"
-        android:theme="@android:style/Theme.DeviceDefault"
+        android:theme="@style/Theme.App.Starting"
         tools:ignore="GoogleAppIndexingWarning">
 
         <uses-library
@@ -21,7 +21,8 @@
         <activity
             android:name=".ui.MainActivity"
             android:exported="true"
-            android:launchMode="singleTop">
+            android:launchMode="singleTop"
+            android:taskAffinity="">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
 
@@ -44,8 +45,10 @@
 
         <activity
             android:name=".ui.VoiceHandlerActivity"
+            android:excludeFromRecents="true"
             android:exported="true"
-            android:launchMode="singleTop" />
+            android:launchMode="singleTop"
+            android:noHistory="true" />
 
         <meta-data
             android:name="com.google.android.gms.version"
 .../main/java/org/leetzone/android/yatsewidgetfree/ui/MainActivity.kt   | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Wear/src/main/java/org/leetzone/android/yatsewidgetfree/ui/MainActivity.kt b/Wear/src/main/java/org/leetzone/android/yatsewidgetfree/ui/MainActivity.kt
index 02959b730..d23a62ff4 100644
--- a/Wear/src/main/java/org/leetzone/android/yatsewidgetfree/ui/MainActivity.kt
+++ b/Wear/src/main/java/org/leetzone/android/yatsewidgetfree/ui/MainActivity.kt
@@ -7,6 +7,7 @@ import androidx.activity.viewModels
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.setValue
+import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
 import androidx.fragment.app.FragmentActivity
 import androidx.wear.ambient.AmbientModeSupport
 import com.google.android.gms.wearable.CapabilityClient
@@ -41,6 +42,7 @@ class MainActivity : FragmentActivity(), AmbientModeSupport.AmbientCallbackProvi
     }
 
     override fun onCreate(savedInstanceState: Bundle?) {
+        installSplashScreen()
         super.onCreate(savedInstanceState)
         AmbientModeSupport.attach(this)
         runCatching {
 Wear/src/main/res/drawable/splash_screen.xml | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/Wear/src/main/res/drawable/splash_screen.xml b/Wear/src/main/res/drawable/splash_screen.xml
new file mode 100644
index 000000000..f73db93e0
--- /dev/null
+++ b/Wear/src/main/res/drawable/splash_screen.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item
+        android:width="@dimen/splash_screen_icon_size"
+        android:height="@dimen/splash_screen_icon_size"
+        android:drawable="@mipmap/ic_launcher"
+        android:gravity="center" />
+</layer-list>
\ No newline at end of file
 Wear/src/main/res/values/dimens.xml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Wear/src/main/res/values/dimens.xml b/Wear/src/main/res/values/dimens.xml
new file mode 100644
index 000000000..aeb08d638
--- /dev/null
+++ b/Wear/src/main/res/values/dimens.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <!-- Round app icon can take all of default space -->
+    <dimen name="splash_screen_icon_size">48dp</dimen>
+</resources>
\ No newline at end of file
 Wear/src/main/res/values/styles.xml | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/Wear/src/main/res/values/styles.xml b/Wear/src/main/res/values/styles.xml
new file mode 100644
index 000000000..eb46f38cc
--- /dev/null
+++ b/Wear/src/main/res/values/styles.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <style name="Theme.App" parent="@android:style/Theme.DeviceDefault" />
+
+    <style name="Theme.App.Starting" parent="Theme.SplashScreen">
+        <!-- Set the splash screen background to black -->
+        <item name="windowSplashScreenBackground">@android:color/black</item>
+        <!-- Use windowSplashScreenAnimatedIcon to add a drawable or an animated
+             drawable. -->
+        <item name="windowSplashScreenAnimatedIcon">@drawable/ic_yatse_default</item>
+        <!-- Set the theme of the Activity that follows your splash screen. -->
+        <item name="postSplashScreenTheme">@style/Theme.App</item>
+    </style>
+</resources>
\ No newline at end of file

@joaomgcd
Copy link
Owner

joaomgcd commented Dec 5, 2023

Thank you very much! I actually did all of that :/

They actually got back to me now again and added a small piece of information: Note that the production APK of your app must be compliant with our policy.

So, that means that, once again, I have to publish the updates I wanted to test directly to production... 🤷‍♂️

It seems like they are losing the grasp on what beta testing means... I've published it to production now, so lets see if they accept it this time. Maybe the whole problem was that they were looking at the production version all along...

@Tolriq
Copy link

Tolriq commented Dec 5, 2023

The joy of Wear / Android Auto review teams ....
Worse and worse and nothing we can do about it.

@Tolriq
Copy link

Tolriq commented Jan 10, 2024

So now that Tasker is in prod I tried to go in prod too and they reject my DATA_SYNC permission saying me that I enter the wrong data without any details ...
I hate those morons.

Anyway glad, you finally managed to publish :)

@joaomgcd
Copy link
Owner

Oh yeah, sorry that I forgot to mention it!

And, what?? Why have the types if apps can't even use it :/ Geez...

@Tolriq
Copy link

Tolriq commented Jan 10, 2024

Yes it will be fun, good news is that it seems they give some time, after the appeal the update passed on "probation"

Your update has been approved with issues. The update will be published on Google Play, but these issues must be fixed and resubmitted as soon as possible. More information can be found in Policy status.

I seriously want to quit at this point too much pain :(

@Tolriq
Copy link

Tolriq commented Jan 10, 2024

BTW You should probably update the library now to no more embed the perm and stuff by default.

@joaomgcd
Copy link
Owner

Oh no, I just realized that I need to do this change for the conditions service as well! 😨 Oops!

Well, at least you can still update your app to use the <meta-data android:name="canBind"> tag for the action service and override the .IntentServiceCondition service so it doesn't use the foregroundServiceType, right?

I'll try making the same change to the Condition Service too. Sorry for the hassle.

@Tolriq
Copy link

Tolriq commented Jan 12, 2024

Hum I went to prod with last library version and override all the perms / FGS part.

No complain so far so I guess it kinda works.

Can't push more updates now they really want me to fix that form and i'm waiting for details about why clicking a by download button is not an user initiated action for them .....

@Tolriq
Copy link

Tolriq commented Sep 18, 2024

@joaomgcd seems you never updated the condition service and it crashes for some users without the FGS type.

java.lang.IllegalArgumentException: foregroundServiceType 0x40000000 is not a subset of foregroundServiceType attribute 0x00000000 in service element of manifest file
	at android.os.Parcel.createExceptionOrNull(Parcel.java:3187)
	at android.os.Parcel.createException(Parcel.java:3167)
	at android.os.Parcel.readException(Parcel.java:3150)
	at android.os.Parcel.readException(Parcel.java:3092)
	at android.app.IActivityManager$Stub$Proxy.setServiceForeground(IActivityManager.java:6960)
	at android.app.Service.startForeground(Service.java:863)
	at com.joaomgcd.taskerpluginlibrary.runner.TaskerPluginRunner$Companion.startForegroundIfNeeded(TaskerPluginRunner.kt:86)
	at com.joaomgcd.taskerpluginlibrary.runner.TaskerPluginRunner$Companion.startForegroundIfNeeded$default(TaskerPluginRunner.kt:79)
	at com.joaomgcd.taskerpluginlibrary.runner.IntentServiceParallel.startForegroundIfNeeded(IntentServiceParallel.kt:27)
	at com.joaomgcd.taskerpluginlibrary.runner.IntentServiceParallel.startForegroundIfNeeded$default(IntentServiceParallel.kt:27)
	at com.joaomgcd.taskerpluginlibrary.condition.IntentServiceCondition.onHandleIntent(ConditionReceivers.kt:38)
	at com.joaomgcd.taskerpluginlibrary.runner.IntentServiceParallel.onStart$lambda$3(IntentServiceParallel.kt:71)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:487)
	at java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
	at java.lang.Thread.run(Thread.java:1012)
Caused by: android.os.RemoteException: Remote stack trace:
	at com.android.server.am.ActiveServices.setServiceForegroundInnerLocked(ActiveServices.java:2182)
	at com.android.server.am.ActiveServices.setServiceForegroundLocked(ActiveServices.java:1806)
	at com.android.server.am.ActivityManagerService.setServiceForeground(ActivityManagerService.java:13795)
	at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:3483)

Does the tasker side support it and it's just adding the fix in the library side or not ?

@joaomgcd
Copy link
Owner

Hi. Sorry for the late reply.

Unless I'm mistaken, the line that is calling that is this one.

The service that is trying to start in the foreground in question already has the specialUse flag in the manifest here.

I don't see the issue myself here... Am I missing something? Thanks in advance!

@joaomgcd joaomgcd reopened this Sep 24, 2024
@Tolriq
Copy link

Tolriq commented Sep 24, 2024

@joaomgcd Well yes we discussed about users being able to remove the specialUse to avoid the pain of Google form reviews.
You did the work for the other service via binds and even noted in #24 (comment) that it's needed in the other service too.

As you know Google reviews are a pain, and avoiding the form via the binds is a life saver :)

Already too much pain to deal with like their new PHOTO/VIDEO form ...

@joaomgcd
Copy link
Owner

Oh, oops! I totally forgot about that 😅Sorry!

I haven't implemented the binding in the condition service yet. Does Yatse have any Tasker conditions?

BTW, I actually just put an app in production with the speacialUse permission (again, forgot about the binding thing :P), and Google actually allowed it, with no back and forth at all.

The app is AutoSheets and I simply justified it like this:
**AutoSheets, being a Tasker plugin, runs in the background, without any user interaction, whenever an automation that the user has setup triggers.

For example, a user might want to log each time they connect to a wifi network in a Google Spreadsheet, and that would have to happen immediately after the user connects to a wifi network and must complete right away (so it can't be paused) so that the rest of the task can run normally.**

@Tolriq
Copy link

Tolriq commented Sep 25, 2024

Yes Yatse have conditions and it crashes currently on Android 14 :)

And since Yatse have Android Auto, Wear and many advanced things that the reviewer have issues with, every review now nearly take a week for a simple update.

So not having to deal with one more form that will makes each review a little more risky on each of their change of mind is better.

@joaomgcd
Copy link
Owner

Thanks. Just to clarify, those conditions are events, correct?

@Tolriq
Copy link

Tolriq commented Sep 25, 2024

Yes I push the states, not really sure how they are used by users.

@joaomgcd
Copy link
Owner

joaomgcd commented Sep 25, 2024

Ok, I've made the change now.

First, you have to do 2 changes to the plugin code (I'll change it myself for everyone once this Tasker version is publicly available):

In the manifest change this:

    <service
        android:name=".condition.IntentServiceCondition"
        android:exported="true"
        android:foregroundServiceType="specialUse"
        tools:ignore="ExportedService">
        <property
            android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
            android:value="@string/explanation_for_special_use_condition" />
        <intent-filter>
            <action android:name="com.twofortyfouram.locale.intent.action.QUERY_CONDITION" />
        </intent-filter>
    </service>

to this

    <service
        android:name=".condition.IntentServiceCondition"
        android:exported="true"
        tools:ignore="ExportedService">
        <meta-data
            android:name="canBind"
            android:value="true" />
        <intent-filter>
            <action android:name="com.twofortyfouram.locale.intent.action.QUERY_CONDITION" />
        </intent-filter>
    </service>

Of course, you can also remove the relevant permissions at the top.

Then in the ConditionReceivers.kt file change this

startForegroundIfNeeded()

to this

startForegroundIfNeeded(intent.mayNeedToStartForeground)

Then can you please try this version of Tasker and then trigger one of your events in Tasker and see if you no longer get the crash?

Hope this helps and again, sorry for the trouble!

@Tolriq
Copy link

Tolriq commented Sep 25, 2024

No trouble here, it's all Google fault :p

I'll try to test soon, but probably next week now :(

@joaomgcd
Copy link
Owner

👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants