joaomgcd / TaskerPluginSample

A library to help speed up building a Tasker plugin
GNU General Public License v3.0
63 stars 24 forks source link

Android 14 requires a foreground service type for startForeground #24

Open KieronQuinn opened 1 year ago

KieronQuinn commented 1 year ago

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.

Tolriq commented 11 months ago

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

Tolriq commented 10 months ago

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 commented 10 months ago

Oh yeah, sorry that I forgot to mention it!

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

Tolriq commented 10 months ago

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 commented 10 months ago

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

joaomgcd commented 10 months ago

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 commented 10 months ago

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 commented 1 month ago

@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 commented 1 month ago

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!

Tolriq commented 1 month ago

@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 https://github.com/joaomgcd/TaskerPluginSample/issues/24#issuecomment-1889432850 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 commented 1 month ago

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 commented 1 month ago

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 commented 1 month ago

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

Tolriq commented 1 month ago

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

joaomgcd commented 1 month ago

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 commented 1 month ago

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

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

joaomgcd commented 1 month ago

👍