Commit 6aacbc6b by ibaker Committed by Rohit Singh

Ensure `DrmSessionManager.setPlayer()` is called before `prepare()`

`prepare()` now logs a warning if it's called before `setPlayer()`
because it's not possible to tell if it's being called on the wrong
thread (since https://github.com/androidx/media/commit/3480a27994ef9e06bd7574bad4656eb8c7677971).

This change finds all the places one is called immediately after the
other and flips the order to be more correct.

Issue: androidx/media#350

#minor-release

PiperOrigin-RevId: 526582294
parent de32536e
...@@ -278,9 +278,9 @@ public final class ProgressiveMediaSource extends BaseMediaSource ...@@ -278,9 +278,9 @@ public final class ProgressiveMediaSource extends BaseMediaSource
@Override @Override
protected void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) { protected void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) {
transferListener = mediaTransferListener; transferListener = mediaTransferListener;
drmSessionManager.prepare();
drmSessionManager.setPlayer( drmSessionManager.setPlayer(
/* playbackLooper= */ checkNotNull(Looper.myLooper()), getPlayerId()); /* playbackLooper= */ checkNotNull(Looper.myLooper()), getPlayerId());
drmSessionManager.prepare();
notifySourceInfoRefreshed(); notifySourceInfoRefreshed();
} }
......
...@@ -68,8 +68,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -68,8 +68,8 @@ public class DefaultDrmSessionManagerTest {
new DefaultDrmSessionManager.Builder() new DefaultDrmSessionManager.Builder()
.setUuidAndExoMediaDrmProvider(DRM_SCHEME_UUID, uuid -> new FakeExoMediaDrm()) .setUuidAndExoMediaDrmProvider(DRM_SCHEME_UUID, uuid -> new FakeExoMediaDrm())
.build(/* mediaDrmCallback= */ licenseServer); .build(/* mediaDrmCallback= */ licenseServer);
drmSessionManager.prepare();
drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET); drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET);
drmSessionManager.prepare();
DrmSession drmSession = DrmSession drmSession =
checkNotNull( checkNotNull(
drmSessionManager.acquireSession( drmSessionManager.acquireSession(
...@@ -91,8 +91,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -91,8 +91,8 @@ public class DefaultDrmSessionManagerTest {
.setSessionKeepaliveMs(10_000) .setSessionKeepaliveMs(10_000)
.build(/* mediaDrmCallback= */ licenseServer); .build(/* mediaDrmCallback= */ licenseServer);
drmSessionManager.prepare();
drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET); drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET);
drmSessionManager.prepare();
DrmSession drmSession = DrmSession drmSession =
checkNotNull( checkNotNull(
drmSessionManager.acquireSession( drmSessionManager.acquireSession(
...@@ -116,8 +116,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -116,8 +116,8 @@ public class DefaultDrmSessionManagerTest {
.setSessionKeepaliveMs(C.TIME_UNSET) .setSessionKeepaliveMs(C.TIME_UNSET)
.build(/* mediaDrmCallback= */ licenseServer); .build(/* mediaDrmCallback= */ licenseServer);
drmSessionManager.prepare();
drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET); drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET);
drmSessionManager.prepare();
DrmSession drmSession = DrmSession drmSession =
checkNotNull( checkNotNull(
drmSessionManager.acquireSession( drmSessionManager.acquireSession(
...@@ -138,8 +138,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -138,8 +138,8 @@ public class DefaultDrmSessionManagerTest {
.setSessionKeepaliveMs(10_000) .setSessionKeepaliveMs(10_000)
.build(/* mediaDrmCallback= */ licenseServer); .build(/* mediaDrmCallback= */ licenseServer);
drmSessionManager.prepare();
drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET); drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET);
drmSessionManager.prepare();
DrmSession drmSession = DrmSession drmSession =
checkNotNull( checkNotNull(
drmSessionManager.acquireSession( drmSessionManager.acquireSession(
...@@ -162,8 +162,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -162,8 +162,8 @@ public class DefaultDrmSessionManagerTest {
.setSessionKeepaliveMs(C.TIME_UNSET) .setSessionKeepaliveMs(C.TIME_UNSET)
.build(/* mediaDrmCallback= */ licenseServer); .build(/* mediaDrmCallback= */ licenseServer);
drmSessionManager.prepare();
drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET); drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET);
drmSessionManager.prepare();
DrmSession drmSession = DrmSession drmSession =
checkNotNull( checkNotNull(
drmSessionManager.acquireSession( drmSessionManager.acquireSession(
...@@ -188,8 +188,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -188,8 +188,8 @@ public class DefaultDrmSessionManagerTest {
.setSessionKeepaliveMs(10_000) .setSessionKeepaliveMs(10_000)
.build(/* mediaDrmCallback= */ licenseServer); .build(/* mediaDrmCallback= */ licenseServer);
drmSessionManager.prepare();
drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET); drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET);
drmSessionManager.prepare();
DrmSession drmSession = DrmSession drmSession =
checkNotNull( checkNotNull(
drmSessionManager.acquireSession( drmSessionManager.acquireSession(
...@@ -233,8 +233,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -233,8 +233,8 @@ public class DefaultDrmSessionManagerTest {
.setSessionKeepaliveMs(10_000) .setSessionKeepaliveMs(10_000)
.build(/* mediaDrmCallback= */ licenseServer); .build(/* mediaDrmCallback= */ licenseServer);
drmSessionManager.prepare();
drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET); drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET);
drmSessionManager.prepare();
DrmSession drmSession = DrmSession drmSession =
checkNotNull( checkNotNull(
drmSessionManager.acquireSession( drmSessionManager.acquireSession(
...@@ -272,8 +272,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -272,8 +272,8 @@ public class DefaultDrmSessionManagerTest {
.setMultiSession(true) .setMultiSession(true)
.build(/* mediaDrmCallback= */ licenseServer); .build(/* mediaDrmCallback= */ licenseServer);
drmSessionManager.prepare();
drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET); drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET);
drmSessionManager.prepare();
DrmSession firstDrmSession = DrmSession firstDrmSession =
checkNotNull( checkNotNull(
drmSessionManager.acquireSession( drmSessionManager.acquireSession(
...@@ -313,8 +313,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -313,8 +313,8 @@ public class DefaultDrmSessionManagerTest {
.setMultiSession(true) .setMultiSession(true)
.build(/* mediaDrmCallback= */ licenseServer); .build(/* mediaDrmCallback= */ licenseServer);
drmSessionManager.prepare();
drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET); drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET);
drmSessionManager.prepare();
DrmSessionReference firstDrmSessionReference = DrmSessionReference firstDrmSessionReference =
checkNotNull( checkNotNull(
drmSessionManager.preacquireSession( drmSessionManager.preacquireSession(
...@@ -358,8 +358,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -358,8 +358,8 @@ public class DefaultDrmSessionManagerTest {
.setSessionKeepaliveMs(10_000) .setSessionKeepaliveMs(10_000)
.build(/* mediaDrmCallback= */ licenseServer); .build(/* mediaDrmCallback= */ licenseServer);
drmSessionManager.prepare();
drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET); drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET);
drmSessionManager.prepare();
DrmSession firstDrmSession = DrmSession firstDrmSession =
checkNotNull( checkNotNull(
drmSessionManager.acquireSession( drmSessionManager.acquireSession(
...@@ -405,8 +405,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -405,8 +405,8 @@ public class DefaultDrmSessionManagerTest {
.setSessionKeepaliveMs(C.TIME_UNSET) .setSessionKeepaliveMs(C.TIME_UNSET)
.build(/* mediaDrmCallback= */ licenseServer); .build(/* mediaDrmCallback= */ licenseServer);
drmSessionManager.prepare();
drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET); drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET);
drmSessionManager.prepare();
DrmSessionReference sessionReference = DrmSessionReference sessionReference =
drmSessionManager.preacquireSession(eventDispatcher, FORMAT_WITH_DRM_INIT_DATA); drmSessionManager.preacquireSession(eventDispatcher, FORMAT_WITH_DRM_INIT_DATA);
...@@ -450,8 +450,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -450,8 +450,8 @@ public class DefaultDrmSessionManagerTest {
.setSessionKeepaliveMs(C.TIME_UNSET) .setSessionKeepaliveMs(C.TIME_UNSET)
.build(/* mediaDrmCallback= */ licenseServer); .build(/* mediaDrmCallback= */ licenseServer);
drmSessionManager.prepare();
drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET); drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET);
drmSessionManager.prepare();
DrmSessionReference sessionReference = DrmSessionReference sessionReference =
drmSessionManager.preacquireSession(/* eventDispatcher= */ null, FORMAT_WITH_DRM_INIT_DATA); drmSessionManager.preacquireSession(/* eventDispatcher= */ null, FORMAT_WITH_DRM_INIT_DATA);
...@@ -486,8 +486,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -486,8 +486,8 @@ public class DefaultDrmSessionManagerTest {
.setSessionKeepaliveMs(C.TIME_UNSET) .setSessionKeepaliveMs(C.TIME_UNSET)
.build(/* mediaDrmCallback= */ licenseServer); .build(/* mediaDrmCallback= */ licenseServer);
drmSessionManager.prepare();
drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET); drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET);
drmSessionManager.prepare();
DrmSessionReference sessionReference = DrmSessionReference sessionReference =
drmSessionManager.preacquireSession(/* eventDispatcher= */ null, FORMAT_WITH_DRM_INIT_DATA); drmSessionManager.preacquireSession(/* eventDispatcher= */ null, FORMAT_WITH_DRM_INIT_DATA);
...@@ -530,8 +530,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -530,8 +530,8 @@ public class DefaultDrmSessionManagerTest {
.setUuidAndExoMediaDrmProvider(DRM_SCHEME_UUID, new AppManagedProvider(exoMediaDrm)) .setUuidAndExoMediaDrmProvider(DRM_SCHEME_UUID, new AppManagedProvider(exoMediaDrm))
.build(/* mediaDrmCallback= */ licenseServer); .build(/* mediaDrmCallback= */ licenseServer);
drmSessionManager.prepare();
drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET); drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET);
drmSessionManager.prepare();
DefaultDrmSession drmSession = DefaultDrmSession drmSession =
(DefaultDrmSession) (DefaultDrmSession)
...@@ -571,8 +571,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -571,8 +571,8 @@ public class DefaultDrmSessionManagerTest {
.setUuidAndExoMediaDrmProvider(DRM_SCHEME_UUID, new AppManagedProvider(exoMediaDrm)) .setUuidAndExoMediaDrmProvider(DRM_SCHEME_UUID, new AppManagedProvider(exoMediaDrm))
.build(/* mediaDrmCallback= */ licenseServer); .build(/* mediaDrmCallback= */ licenseServer);
drmSessionManager.prepare();
drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET); drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET);
drmSessionManager.prepare();
DefaultDrmSession drmSession = DefaultDrmSession drmSession =
(DefaultDrmSession) (DefaultDrmSession)
...@@ -615,8 +615,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -615,8 +615,8 @@ public class DefaultDrmSessionManagerTest {
DRM_SCHEME_UUID, DRM_SCHEME_UUID,
uuid -> new FakeExoMediaDrm.Builder().setProvisionsRequired(1).build()) uuid -> new FakeExoMediaDrm.Builder().setProvisionsRequired(1).build())
.build(/* mediaDrmCallback= */ licenseServer); .build(/* mediaDrmCallback= */ licenseServer);
drmSessionManager.prepare();
drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET); drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET);
drmSessionManager.prepare();
DrmSession drmSession = DrmSession drmSession =
checkNotNull( checkNotNull(
drmSessionManager.acquireSession( drmSessionManager.acquireSession(
...@@ -648,8 +648,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -648,8 +648,8 @@ public class DefaultDrmSessionManagerTest {
.throwNotProvisionedExceptionFromGetKeyRequest() .throwNotProvisionedExceptionFromGetKeyRequest()
.build()) .build())
.build(/* mediaDrmCallback= */ licenseServer); .build(/* mediaDrmCallback= */ licenseServer);
drmSessionManager.prepare();
drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET); drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET);
drmSessionManager.prepare();
DrmSession drmSession = DrmSession drmSession =
checkNotNull( checkNotNull(
drmSessionManager.acquireSession( drmSessionManager.acquireSession(
...@@ -674,8 +674,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -674,8 +674,8 @@ public class DefaultDrmSessionManagerTest {
DRM_SCHEME_UUID, DRM_SCHEME_UUID,
uuid -> new FakeExoMediaDrm.Builder().setProvisionsRequired(2).build()) uuid -> new FakeExoMediaDrm.Builder().setProvisionsRequired(2).build())
.build(/* mediaDrmCallback= */ licenseServer); .build(/* mediaDrmCallback= */ licenseServer);
drmSessionManager.prepare();
drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET); drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET);
drmSessionManager.prepare();
DrmSession drmSession = DrmSession drmSession =
checkNotNull( checkNotNull(
drmSessionManager.acquireSession( drmSessionManager.acquireSession(
...@@ -702,8 +702,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -702,8 +702,8 @@ public class DefaultDrmSessionManagerTest {
.setUuidAndExoMediaDrmProvider( .setUuidAndExoMediaDrmProvider(
DRM_SCHEME_UUID, uuid -> new FakeExoMediaDrm.Builder().build()) DRM_SCHEME_UUID, uuid -> new FakeExoMediaDrm.Builder().build())
.build(/* mediaDrmCallback= */ licenseServer); .build(/* mediaDrmCallback= */ licenseServer);
drmSessionManager.prepare();
drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET); drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET);
drmSessionManager.prepare();
DrmSession drmSession = DrmSession drmSession =
checkNotNull( checkNotNull(
drmSessionManager.acquireSession( drmSessionManager.acquireSession(
...@@ -728,8 +728,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -728,8 +728,8 @@ public class DefaultDrmSessionManagerTest {
.setUuidAndExoMediaDrmProvider(DRM_SCHEME_UUID, new AppManagedProvider(mediaDrm)) .setUuidAndExoMediaDrmProvider(DRM_SCHEME_UUID, new AppManagedProvider(mediaDrm))
.setSessionKeepaliveMs(C.TIME_UNSET) .setSessionKeepaliveMs(C.TIME_UNSET)
.build(/* mediaDrmCallback= */ licenseServer); .build(/* mediaDrmCallback= */ licenseServer);
drmSessionManager.prepare();
drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET); drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET);
drmSessionManager.prepare();
DrmSession drmSession = DrmSession drmSession =
checkNotNull( checkNotNull(
drmSessionManager.acquireSession( drmSessionManager.acquireSession(
...@@ -783,8 +783,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -783,8 +783,8 @@ public class DefaultDrmSessionManagerTest {
.setUuidAndExoMediaDrmProvider(DRM_SCHEME_UUID, uuid -> new FakeExoMediaDrm()) .setUuidAndExoMediaDrmProvider(DRM_SCHEME_UUID, uuid -> new FakeExoMediaDrm())
.build(/* mediaDrmCallback= */ licenseServer); .build(/* mediaDrmCallback= */ licenseServer);
drmSessionManager.prepare();
drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET); drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), PlayerId.UNSET);
drmSessionManager.prepare();
DrmSession drmSession = DrmSession drmSession =
checkNotNull( checkNotNull(
drmSessionManager.acquireSession( drmSessionManager.acquireSession(
......
...@@ -449,8 +449,8 @@ public final class DashMediaSource extends BaseMediaSource { ...@@ -449,8 +449,8 @@ public final class DashMediaSource extends BaseMediaSource {
@Override @Override
protected void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) { protected void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) {
this.mediaTransferListener = mediaTransferListener; this.mediaTransferListener = mediaTransferListener;
drmSessionManager.prepare();
drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), getPlayerId()); drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), getPlayerId());
drmSessionManager.prepare();
if (sideloadedManifest) { if (sideloadedManifest) {
processManifest(false); processManifest(false);
} else { } else {
......
...@@ -417,9 +417,9 @@ public final class HlsMediaSource extends BaseMediaSource ...@@ -417,9 +417,9 @@ public final class HlsMediaSource extends BaseMediaSource
@Override @Override
protected void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) { protected void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) {
this.mediaTransferListener = mediaTransferListener; this.mediaTransferListener = mediaTransferListener;
drmSessionManager.prepare();
drmSessionManager.setPlayer( drmSessionManager.setPlayer(
/* playbackLooper= */ checkNotNull(Looper.myLooper()), getPlayerId()); /* playbackLooper= */ checkNotNull(Looper.myLooper()), getPlayerId());
drmSessionManager.prepare();
MediaSourceEventListener.EventDispatcher eventDispatcher = MediaSourceEventListener.EventDispatcher eventDispatcher =
createEventDispatcher(/* mediaPeriodId= */ null); createEventDispatcher(/* mediaPeriodId= */ null);
playlistTracker.start( playlistTracker.start(
......
...@@ -374,8 +374,8 @@ public final class SsMediaSource extends BaseMediaSource ...@@ -374,8 +374,8 @@ public final class SsMediaSource extends BaseMediaSource
@Override @Override
protected void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) { protected void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) {
this.mediaTransferListener = mediaTransferListener; this.mediaTransferListener = mediaTransferListener;
drmSessionManager.prepare();
drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), getPlayerId()); drmSessionManager.setPlayer(/* playbackLooper= */ Looper.myLooper(), getPlayerId());
drmSessionManager.prepare();
if (sideloadedManifest) { if (sideloadedManifest) {
manifestLoaderErrorThrower = new LoaderErrorThrower.Dummy(); manifestLoaderErrorThrower = new LoaderErrorThrower.Dummy();
processManifest(); processManifest();
......
...@@ -215,9 +215,9 @@ public class FakeMediaSource extends BaseMediaSource { ...@@ -215,9 +215,9 @@ public class FakeMediaSource extends BaseMediaSource {
public synchronized void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) { public synchronized void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) {
assertThat(preparedSource).isFalse(); assertThat(preparedSource).isFalse();
transferListener = mediaTransferListener; transferListener = mediaTransferListener;
drmSessionManager.prepare();
drmSessionManager.setPlayer( drmSessionManager.setPlayer(
/* playbackLooper= */ checkNotNull(Looper.myLooper()), getPlayerId()); /* playbackLooper= */ checkNotNull(Looper.myLooper()), getPlayerId());
drmSessionManager.prepare();
preparedSource = true; preparedSource = true;
releasedSource = false; releasedSource = false;
sourceInfoRefreshHandler = Util.createHandlerForCurrentLooper(); sourceInfoRefreshHandler = Util.createHandlerForCurrentLooper();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment