Closed Bug 1465102 Opened Last year Closed Last year

Android O NotificationService startForeground changes

Categories

(Firefox for Android :: General, defect, critical)

All
Android
defect
Not set
critical

Tracking

()

RESOLVED FIXED
Firefox 62
Tracking Status
firefox63 --- fixed

People

(Reporter: vlad.baicu, Assigned: vlad.baicu)

References

Details

Attachments

(2 files, 1 obsolete file)

On Android O you can no longer call startService if the app is in background, use startForegroundService with a following call to startForeground.
Blocks: 1384866
Comment on attachment 8981555 [details]
Bug 1465102 - Updated NotificationService for Oreo.

https://reviewboard.mozilla.org/r/247654/#review253702

The basic idea of the patch is absolutely fine, but the issues below need fixing before this can land.

::: commit-message-f01bb:3
(Diff revision 1)
> +Bug 1465102 - Updated NotificationService for Oreo. r?sdaswani
> +
> +Using stopService instead of calling startService with a null notification in order to stop NotificationService.

Not a terrible issue, but for the future, can you please add line breaks to the extended commit message so as to stay at or below 80 characters per line? I've been guilty of this myself for a long time, but I've since noticed that not everything handling commit messages will automatically break overly long lines.

The only exception is the first line, since fitting bug number, reviewer(s) and a reasonable summary in 80 characters or less would be a bit challenging, so exceeding the limit there a little is nothing to worry about.

::: commit-message-f01bb:3
(Diff revision 1)
> +Bug 1465102 - Updated NotificationService for Oreo. r?sdaswani
> +
> +Using stopService instead of calling startService with a null notification in order to stop NotificationService.

Can you expand on the reasoning a little more, like e.g. adding "That way, starting the service will always result in a call to startForeground, meaning that startForegroundService on Android O can be used without risk."

::: mobile/android/base/java/org/mozilla/gecko/notifications/NotificationClient.java:304
(Diff revision 1)
>          }
>          return false;
>      }
>  
> +    @SuppressLint("NewApi")
>      private void setForegroundNotificationLocked(final String name,

Since we've now got a special method for getting rid of the notification again and the NotificationService now assumes it can always get a notification from the intent, can you make both parameters @NonNull please?

::: mobile/android/base/java/org/mozilla/gecko/notifications/NotificationClient.java:317
(Diff revision 1)
> +        } else {
> +            mContext.startForegroundService(intent);
> +        }
>      }
>  
> +    private void setForegroundNotificationClosed() {

`removeForegroundNotification` might be more succint?

Also, because you're going to be touching `mForegroundNotification` (see below), I think you should add a "locked" suffix to indicate that this method should be called only from within a synchronised method/block, so make it `removeForegroundNotificationLocked`, please.

::: mobile/android/base/java/org/mozilla/gecko/notifications/NotificationClient.java:318
(Diff revision 1)
> +            mContext.startForegroundService(intent);
> +        }
>      }
>  
> +    private void setForegroundNotificationClosed() {
> +        mContext.stopService(new Intent(mContext, NotificationService.class));

To fully replicate the effect of a `setForegroundNotificationLocked(null, null)` call, you also need to clear mForegroundNotification here.
Attachment #8981555 - Flags: review?(jh+bugzilla) → review-
Assignee: nobody → vlad.baicu
Attachment #8981555 - Attachment is obsolete: true
Comment on attachment 8981915 [details]
Bug 1465102 - Updated NotificationService for Oreo.

https://reviewboard.mozilla.org/r/247938/#review254368

Looks good, thanks.

::: commit-message-f01bb:8
(Diff revision 1)
> +Changed NotificationClient to use stopService instead of calling startService
> +with a null notification in order to stop NotificationService.
> +This way, we always have a guaranteed call to startForeground in our service,
> +abiding by Android Oreo regulations.
> +
> +MozReview-Commit-ID: 4CzM4pvANJt

I'm not sure what exactly you're doing, but can you please try *amending/histediting* the original commit and most importantly, try keeping the MozReview-Commit-ID intact?

Whatever you're doing right now leads Mozreview into thinking you've completely abandoned the original commit series, which means that instead of *adding* a new revision for an existing review request you're opening a completely fresh review.

This means that all the issues and review comments opened for the previous revision will be lost in Mozreview (well, not completely lost, but they're no longer linked to the current review request) and the interdiff facility doesn't work either.

::: mobile/android/base/java/org/mozilla/gecko/notifications/NotificationClient.java:308
(Diff revision 1)
> +                                                 @NonNull final Notification notification) {
>          mForegroundNotification = name;
>  
>          final Intent intent = new Intent(mContext, NotificationService.class);
>          intent.putExtra(NotificationService.EXTRA_NOTIFICATION, notification);
> +        if (AppConstants.Versions.preO) {

Please don't forget that you either
- need to wait for bug 1444776 to land first
- or else add this in AppConstants.java.in yourself

::: mobile/android/base/java/org/mozilla/gecko/notifications/NotificationClient.java:320
(Diff revision 1)
> +    private void removeForegroundNotificationLocked() {
> +        mForegroundNotification = null;
> +        mContext.stopService(new Intent(mContext, NotificationService.class));
> +    }
> +
> +

Nit: Additional unnecessary newline.
Attachment #8981915 - Flags: review?(jh+bugzilla) → review+
I'm gonna sync with Andrei and ask for this to get landed after his one does. Thanks
OS: Unspecified → Android
Hardware: Unspecified → All
Fixed the extraneous newline and pushed it for you, so you can close the review in Mozreview as submitted.
https://hg.mozilla.org/mozilla-central/rev/0581ff7ccfef
Status: NEW → RESOLVED
Closed: Last year
Resolution: --- → FIXED
Target Milestone: --- → Firefox 62
Depends on: 1469086
Backout by csabou@mozilla.com:
https://hg.mozilla.org/mozilla-central/rev/b73265d537e6
Backed out changeset 0581ff7ccfef because of a possible framework issue as request by vladbaicu. a=backout
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
From what I gathered during investigation and testing I can see two possible cases where this might crash in our case. We either call stopService before startForeground has a chance to get called or startForeground simply does not get called within the timer allocated by Android. 

I can think of two possible designs of how we can avoid this:

- make the service a bound service and use startForeground/stopForeground accordingly

- implement queueing logic and check whether our service has actually called startForeground

I think that the second option is less elegant than the first one, Jan what do you think about this ?
Flags: needinfo?(jh+bugzilla)
(In reply to Vlad Baicu from comment #10)
> - make the service a bound service and use startForeground/stopForeground
> accordingly

From what I remember from the attempt to use a bound service construct in bug 1384866, isn't it a problem that startForeground/stopForeground only works for services that have actually been started (as opposed to merely having been bound to), so we'd still have to start and stop the service as well in order to show a foreground notification?
Plus binding to a service is async, too, so we'd still have to track the current state so as to know what to do if multiple events arrive in short succession.

So please correct me if I'm wrong here, but I think we'd need some sort of queuing logic regardless of which way the service was launched, and since we still need to actually *start* the service in order to show the foreground notification, it's easier to just stick to that and let the NotificationClient/Service keep track among themselves when it is safe to stop the service again.
Flags: needinfo?(jh+bugzilla)
Updated the patch with a fix, I think it's cleaner to take advantage of the start service calls but with different intents instead of making our own logic for queueing.
Flags: needinfo?(jh+bugzilla)
Attachment #8981915 - Flags: review?(sdaswani)
Comment on attachment 8981915 [details]
Bug 1465102 - Updated NotificationService for Oreo.

https://reviewboard.mozilla.org/r/247938/#review262154
Attachment #8981915 - Flags: review+
Flags: needinfo?(jh+bugzilla)
Keywords: checkin-needed
https://hg.mozilla.org/mozilla-central/rev/1022b1a54372
Status: REOPENED → RESOLVED
Closed: Last yearLast year
Resolution: --- → FIXED
Attachment #8992035 - Flags: review?(sdaswani) → review?(nchen)
You need to log in before you can comment on or make changes to this bug.