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

Improve background behavior (timers, refreshes, control center) #182

Closed
defagos opened this issue Oct 1, 2019 · 8 comments
Closed

Improve background behavior (timers, refreshes, control center) #182

defagos opened this issue Oct 1, 2019 · 8 comments

Comments

@defagos
Copy link
Member

defagos commented Oct 1, 2019

A vanilla application (with no use of audio) will stop NSTimers when the application is sent to the background.

If audio is playing, if the application has the background audio capability enabled, and if the audio session is properly configured to AVAudioSessionCategoryPlayback, timers will not be paused when the application is sent to the background.

As we are using several timers in Letterbox (e.g. for analytics heartbeat purposes), and since we have recently removed audio session management entirely, it would be very interesting to have a look at Letterbox behavior in general, especially in long-running background sessions.

@defagos
Copy link
Member Author

defagos commented Oct 22, 2019

Our background behavior is probably sub-optimal, as the detailed feedback from one of our users seems to confirm. We should probably:

  • Reduce the need for periodic updates, especially when there is no need to.
  • Ensure that no timer keeps the application alive in the background if there is no need to (this can be checked with the energy log built in iOS, though with quite a delay. Maybe Instruments energy log tool can provide the information earlier).

In particular, there is no need for too many now playing info refreshes, as the player is able to infer the playback position based on the player rate. See WWDC 501 for more information.

@defagos defagos changed the title Correct background behavior for timers? Improve background behavior (timers, refreshes, control center) Oct 22, 2019
@defagos
Copy link
Member Author

defagos commented Nov 4, 2019

There is indeed unnecessary background activity. Here is what is reported by the system after I barely used RTS Info, after letting the phone rest for a while:

IMG_2713
IMG_2714

In consider this to be a major issue since it affects all our clients. I thus update this issue to major.

@defagos
Copy link
Member Author

defagos commented Nov 8, 2019

We should rewrite our control center implementation so that changes are minimized. In doing so, we should use the new API available on iOS 12 and tvOS, see #176.

@defagos
Copy link
Member Author

defagos commented Nov 12, 2019

To minimize the need for control center updates, it suffices to provide rate information so that the device can guess the current playback position, based on the last position it was provided. This information can only be updated when playback state changes, or simply when the rate changes, which should be sufficient for the system to properly interpolate positions.

This works fine for on-demand streams, but is tricky for DVR streams whose window changes and should be updated every now and then. We should find a way to have this need covered, while still avoiding unnecessary updates keeping activity in background unnecessarily. Here is an idea:

  • Have SRG Media Player controller broadcast time range changes through notifications, only if a change is detected. We can then listen to these notifications for DVR streams and trigger a control center playback status update.
  • Have SRG Letterbox controller broadcast current program changes through notifications, only if a change is detected. We can then listen to these notifications for DVR streams and trigger a control center metadata update.

If done correctly, the associated background activity can probably be eliminated. Some updates will probably not occur for paused DVR streams while the app is inactive, but this a small price to pay to reduce background activity to a minimum.

Another idea would be to have periodic time observers implemented using AVPlayer periodic time observers. If DVR is treated as a separate case with its limitations, or other approaches are found, we could reduce the need for NSTimer (or entirely eliminate it), so that timers are only in place when playback is running. This avoids frequent timers keeping the app alive in background unnecessarily. If not possible, then maybe our SRG Media Player observers could provide two modes:

  • Only active when playing (based on AVPlayer time observers).
  • Always active (based on NSTimer).

The advantage of keeping our time observers is that they are associated with the controller and will not die with AVPlayer, whose lifecycle is managed by SRG Media Player internally.

Letterbox view and controller can then also listen to these changes, which might help us in completely eliminating their periodic time observers.

@defagos
Copy link
Member Author

defagos commented Nov 21, 2019

SRG Media Player was updated to reduce the need for periodic observers. These can now be eliminated in most cases where constant monitoring of playback is not required, replaced with either notifications or KVO.

Most SRGMediaPlayerController properties, like timeRange, streamType, mediaType or live, have been made KVO-observable (except e.g. the current time for which it would be equivalent to the use of a periodic time observer). The question is now whether the similar properties for Letterbox (currently only forwarding the underlying value) should support KVO as well.

The answer might be delivered by #181. Doing the same as for playbackState currently has some drawbacks and leads to additional bookkeeping code. If we want to support KVO, I see a few options:

  • Proceed as for playbackState and forward KVO changes through Letterbox controller.
  • Expose the underlying mediaPlayerController for KVO-purposes only (loosening encapsulation), but keeping and documenting the forwarded Letterbox properties as not supporting KVO. The fate of playbackState could then be discussed (removal of KVO support).
  • Expose the underlying mediaPlayerController, and remove all equivalent properties from Letterbox controller public interface. For KVO purposes and to check these values, clients would then need to consistently access the underlying controller. Encapsulation is loosened as well, but the API would be more consistent.

@defagos
Copy link
Member Author

defagos commented Nov 29, 2019

Here is a procedure to hopefully reliably compare battery usage of various Letterbox versions:

  1. Install the Letterbox demo version to test.
  2. Setup the phone appropriately. I would recommend:
    • Having an iPhone with stock applications and no iCloud account setup. This avoids background activity from other applications.
    • Disabling Bluetooth.
    • Ensure Network Link Conditioner is not active.
    • Choosing to use WiFi or Mobile Data (Mobile Data has the advantage to provide data volume information as well).
    • Setting the screen brightness to a minimum. Be sure to disable auto-adjusting brightness in the Accessibility settings.
  3. Hard-reboot the device.
  4. Go to the Developer settings and enable Energy logging.
  5. Connect the device to a Mac with Coconut Battery installed. Charge the device near 100% and write down the corresponding capacity in mAh.
  6. Disconnect the Mac
  7. Open Letterbox demo and play some content for 1 hour (see content types below).
  8. After 1 hour, stop playback.
  9. Connect the iPhone to a Mac and write down the capacity in mAh.
  10. Go to the developer settings and stop Energy logging.
  11. Launch Instruments, select the Energy instrument, then your device, and import the battery log from the corresponding menu entry.

Such a run provides battery drain rate in mAh / h as well as a matching trace for Instruments. It should be repeated with Letterbox versions to compare (attempting to start with similar mAh values by charging the device again first), as well as the following content types:

  1. Radio livestream.
  2. TV livestream.
  3. Radio OD (e.g. Forum, exactly 1h).
  4. Video OD (e.g. Forum, exactly 1h).

Following setups should be investigated:

  1. Application in foreground, no screen lock.
  2. Application in background (screen lock). Requires background video playback to be enabled in the app settings for video content.

@defagos
Copy link
Member Author

defagos commented Dec 11, 2019

Forum VOD, 1h foreground playback, screen always on at min brightness, iPhone 7:

Forum AOD, 1h foreground playback, screen locked, iPhone 7:

@defagos
Copy link
Member Author

defagos commented Dec 15, 2019

One behavior that should be monitored more closely: What is the system reported background activity for a paused livestream / on-demand stream?

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

No branches or pull requests

2 participants