This is part of an effort to resolve deprecation warnings.
Most of this is simple refactoring of interfaces that change between
the two Player implementations. There are a few other changes that
deserve further explanation.
Testing indicated that the play/pause button was being reset to pause
in MainActivity:refreshCurrentTrack. In the past this was likely
masked by the ordering of other callbacks. We have removed the
nowPlayingToggle.icon update from MainActivity, leaving that UI update
to PlayerService.
One of the bigger refactorings in PlayerService was forced by the
deprecation of Player.EventListener.onPlayerStateChanged. That forced
separation of handling playWhenReady and playbackState transitions.
In the SimpleExoPlayer implementations, where these transitions were
combined, the module attempted to work out playing state from a
combination of these two state variables.
In addition to separating the reaction to these state changes, we have
added a listener to onIsPlayingChanged, eliminating the need for some
of the earlier logic in Player.EventListener.onPlayerStateChanged.
This addition, along with the separation of state transition
processing, seems to provide a simpler implementation. But it is,
certainly, a possible source of bugs.
Migrate startActivityForResult/onActivityResult to
StartActivityForResult/registerForActivityResult in
LoginActivity/OAuth.
This moves responsibility for scheduling the starting Intent from
OAuth to LoginActivity.
OAuth still generates the Intent. But instead of starting the intent
directly in OAuth, the intent is returned to LoginActivity. This
better associates processing the activity result with its invocation.
OAuthTest module updated to accommodate internal API change.
Replace FragmentPagerAdapter with FragmentStateAdapter in
BrowseTabsAdapter.kt. Refactored getPageTitle as a function that
returns tab name. Tab text update moved to BrowseFragment.
This requires replacement of setupWithViewPager with
TabMediator.attach in BrowseFragment.
Also requires replacing widget declaration
androidx.viewpager.widget.ViewPager with
androidx.viewpager2.widget.ViewPager2 in fragment_browwse.xml.
With Oreo and later, Bluetooth control buttons may kill FFA if it is
not the foreground application. Once this happens to resume playback,
one needs to restart playback from the phone, rather than the
play/pause action of Bluetooth headset.
For example:
D MediaSessionService: Sending KeyEvent { action=ACTION_UP, keyCode=KEYCODE_MEDIA_PLAY, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=0, downTime=0, deviceId=-1, source=0x0 } to audio.funkwhale.ffa.dev/audio.funkwhale.ffa.dev (
W ActivityManager: Background start not allowed: service Intent { act=android.intent.action.MEDIA_BUTTON cmp=audio.funkwhale.ffa.dev/audio.funkwhale.ffa.playback.PlayerService (has extras) } to audio.funkwhale.ffa.dev/audio.funkwhale.ffa.play
549 uid=10149 pkg=audio.funkwhale.ffa.dev startFg?=false
D AndroidRuntime: Shutting down VM
--------- beginning of crash
E AndroidRuntime: FATAL EXCEPTION: main
E AndroidRuntime: Process: audio.funkwhale.ffa.dev, PID: 14549
E AndroidRuntime: java.lang.IllegalStateException: Not allowed to start service Intent { act=android.intent.action.MEDIA_BUTTON cmp=audio.funkwhale.ffa.dev/audio.funkwhale.ffa.playback.PlayerService (has extras) }: app is in background uid UidRecord{72fa8f8 u0a149 CAC bg:+11m56s597ms idle change:cached procs:1 seq(0,0,0)}
E AndroidRuntime: at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1577)
E AndroidRuntime: at android.app.ContextImpl.startService(ContextImpl.java:1532)
E AndroidRuntime: at android.content.ContextWrapper.startService(ContextWrapper.java:664)
E AndroidRuntime: at audio.funkwhale.ffa.playback.MediaSession$connector$2.invoke$lambda-3$lambda-2(MediaSession.kt:47)
E AndroidRuntime: at audio.funkwhale.ffa.playback.MediaSession$connector$2.$r8$lambda$jU84j_zRyeYuvwLrRY0b6XyQBMs(Unknown Source:0)
E AndroidRuntime: at audio.funkwhale.ffa.playback.MediaSession$connector$2$$ExternalSyntheticLambda0.onMediaButtonEvent(Unknown Source:2)
E AndroidRuntime: at com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector$ComponentListener.onMediaButtonEvent(MediaSessionConnector.java:1396)
E AndroidRuntime: at android.support.v4.media.session.MediaSessionCompat$Callback$MediaSessionCallbackApi21.onMediaButtonEvent(MediaSessionCompat.java:1602)
E AndroidRuntime: at android.media.session.MediaSession$CallbackMessageHandler.handleMessage(MediaSession.java:1471)
E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:106)
E AndroidRuntime: at android.os.Looper.loop(Looper.java:193)
E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:6718)
E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:491)
E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
W ActivityManager: Force finishing activity audio.funkwhale.ffa.dev/audio.funkwhale.ffa.activities.MainActivity
xref: https://stackoverflow.com/questions/46445265/android-8-0-java-lang-illegalstateexception-not-allowed-to-start-service-inten