mirror of
https://github.com/androidx/media.git
synced 2025-05-13 02:29:52 +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).
|
([#9106](https://github.com/google/ExoPlayer/issues/9106).
|
||||||
* DRM:
|
* DRM:
|
||||||
* Allow repeated provisioning in `DefaultDrmSession(Manager)`.
|
* 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:
|
* Metadata:
|
||||||
* Fix handling of emsg messages with an unset duration
|
* Fix handling of emsg messages with an unset duration
|
||||||
([#9123](https://github.com/google/ExoPlayer/issues/9123)).
|
([#9123](https://github.com/google/ExoPlayer/issues/9123)).
|
||||||
|
@ -911,8 +911,10 @@ public class DefaultDrmSessionManager implements DrmSessionManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReferenceCountDecremented(DefaultDrmSession session, int newReferenceCount) {
|
public void onReferenceCountDecremented(DefaultDrmSession session, int newReferenceCount) {
|
||||||
if (newReferenceCount == 1 && sessionKeepaliveMs != C.TIME_UNSET) {
|
if (newReferenceCount == 1 && prepareCallsCount > 0 && sessionKeepaliveMs != C.TIME_UNSET) {
|
||||||
// Only the internal keep-alive reference remains, so we can start the timeout.
|
// 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);
|
keepaliveSessions.add(session);
|
||||||
checkNotNull(playbackHandler)
|
checkNotNull(playbackHandler)
|
||||||
.postAtTime(
|
.postAtTime(
|
||||||
|
@ -222,6 +222,44 @@ public class DefaultDrmSessionManagerTest {
|
|||||||
exoMediaDrm.release();
|
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)
|
@Test(timeout = 10_000)
|
||||||
public void maxConcurrentSessionsExceeded_allKeepAliveSessionsEagerlyReleased() throws Exception {
|
public void maxConcurrentSessionsExceeded_allKeepAliveSessionsEagerlyReleased() throws Exception {
|
||||||
ImmutableList<DrmInitData.SchemeData> secondSchemeDatas =
|
ImmutableList<DrmInitData.SchemeData> secondSchemeDatas =
|
||||||
|
Loading…
x
Reference in New Issue
Block a user