mirror of
https://github.com/androidx/media.git
synced 2025-05-12 01:59:50 +08:00
Avoid DefaultDrmSessionManager releasing too many session references
Before this fix, if DefaultDrmSessionManager.release() was called while there was at least one 'external' session reference still active (i.e. session.referenceCount > 1) then the manager will release it's reference immediately but when the session's reference count subsequently drops to 1 (due to external references being released) the manager will schedule a task to release its internal reference *again*. This change fixes the problem by only scheduling the timed release if the manager is unreleased. This ensures that the internal references are only released once. Issue: #9193 PiperOrigin-RevId: 385580741
This commit is contained in:
parent
0ae71e22f7
commit
dbebd279c4
@ -45,6 +45,10 @@
|
||||
([#9106](https://github.com/google/ExoPlayer/issues/9106).
|
||||
* DRM:
|
||||
* Allow repeated provisioning in `DefaultDrmSession(Manager)`.
|
||||
* Fix a crash due to `DefaultDrmSessionManager.release()` incorrectly
|
||||
releasing too many keep-alive `DefaultDrmSession` references, resulting
|
||||
in `DefaultDrmSession.release()` throwing an `IllegalStateException`
|
||||
([#9193](https://github.com/google/ExoPlayer/issues/9193)).
|
||||
* Metadata:
|
||||
* Fix handling of emsg messages with an unset duration
|
||||
([#9123](https://github.com/google/ExoPlayer/issues/9123)).
|
||||
|
@ -911,8 +911,10 @@ public class DefaultDrmSessionManager implements DrmSessionManager {
|
||||
|
||||
@Override
|
||||
public void onReferenceCountDecremented(DefaultDrmSession session, int newReferenceCount) {
|
||||
if (newReferenceCount == 1 && sessionKeepaliveMs != C.TIME_UNSET) {
|
||||
// Only the internal keep-alive reference remains, so we can start the timeout.
|
||||
if (newReferenceCount == 1 && prepareCallsCount > 0 && sessionKeepaliveMs != C.TIME_UNSET) {
|
||||
// Only the internal keep-alive reference remains, so we can start the timeout. We only
|
||||
// do this if the manager isn't released, because a released manager has already released
|
||||
// all its internal session keep-alive references.
|
||||
keepaliveSessions.add(session);
|
||||
checkNotNull(playbackHandler)
|
||||
.postAtTime(
|
||||
|
@ -222,6 +222,44 @@ public class DefaultDrmSessionManagerTest {
|
||||
exoMediaDrm.release();
|
||||
}
|
||||
|
||||
// https://github.com/google/ExoPlayer/issues/9193
|
||||
@Test(timeout = 10_000)
|
||||
public void
|
||||
managerReleasedBeforeSession_keepaliveEnabled_managerOnlyReleasesOneKeepaliveReference()
|
||||
throws Exception {
|
||||
FakeExoMediaDrm.LicenseServer licenseServer =
|
||||
FakeExoMediaDrm.LicenseServer.allowingSchemeDatas(DRM_SCHEME_DATAS);
|
||||
FakeExoMediaDrm exoMediaDrm = new FakeExoMediaDrm.Builder().build();
|
||||
DrmSessionManager drmSessionManager =
|
||||
new DefaultDrmSessionManager.Builder()
|
||||
.setUuidAndExoMediaDrmProvider(DRM_SCHEME_UUID, new AppManagedProvider(exoMediaDrm))
|
||||
.setSessionKeepaliveMs(10_000)
|
||||
.build(/* mediaDrmCallback= */ licenseServer);
|
||||
|
||||
drmSessionManager.prepare();
|
||||
DrmSession drmSession =
|
||||
checkNotNull(
|
||||
drmSessionManager.acquireSession(
|
||||
/* playbackLooper= */ checkNotNull(Looper.myLooper()),
|
||||
/* eventDispatcher= */ null,
|
||||
FORMAT_WITH_DRM_INIT_DATA));
|
||||
waitForOpenedWithKeys(drmSession);
|
||||
|
||||
// Release the manager (there's still an explicit reference to the session from acquireSession).
|
||||
// This should immediately release the manager's internal keepalive session reference.
|
||||
drmSessionManager.release();
|
||||
assertThat(drmSession.getState()).isEqualTo(DrmSession.STATE_OPENED_WITH_KEYS);
|
||||
|
||||
// Ensure the manager doesn't release a *second* keepalive session reference after the timer
|
||||
// expires.
|
||||
ShadowLooper.idleMainLooper(10, SECONDS);
|
||||
assertThat(drmSession.getState()).isEqualTo(DrmSession.STATE_OPENED_WITH_KEYS);
|
||||
|
||||
// Release the explicit session reference.
|
||||
drmSession.release(/* eventDispatcher= */ null);
|
||||
assertThat(drmSession.getState()).isEqualTo(DrmSession.STATE_RELEASED);
|
||||
}
|
||||
|
||||
@Test(timeout = 10_000)
|
||||
public void maxConcurrentSessionsExceeded_allKeepAliveSessionsEagerlyReleased() throws Exception {
|
||||
ImmutableList<DrmInitData.SchemeData> secondSchemeDatas =
|
||||
|
Loading…
x
Reference in New Issue
Block a user