Commit aa4e0080 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/google/ExoPlayer/commit/9d028b33017e82b05a9de4e231355667b1b78264).

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 6da93062
...@@ -276,9 +276,9 @@ public final class ProgressiveMediaSource extends BaseMediaSource ...@@ -276,9 +276,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();
} }
......
...@@ -67,8 +67,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -67,8 +67,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(
...@@ -90,8 +90,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -90,8 +90,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(
...@@ -115,8 +115,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -115,8 +115,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(
...@@ -137,8 +137,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -137,8 +137,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(
...@@ -161,8 +161,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -161,8 +161,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(
...@@ -187,8 +187,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -187,8 +187,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(
...@@ -232,8 +232,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -232,8 +232,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(
...@@ -271,8 +271,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -271,8 +271,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(
...@@ -312,8 +312,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -312,8 +312,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(
...@@ -357,8 +357,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -357,8 +357,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(
...@@ -404,8 +404,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -404,8 +404,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);
...@@ -449,8 +449,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -449,8 +449,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);
...@@ -485,8 +485,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -485,8 +485,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);
...@@ -529,8 +529,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -529,8 +529,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)
...@@ -570,8 +570,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -570,8 +570,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)
...@@ -614,8 +614,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -614,8 +614,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(
...@@ -647,8 +647,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -647,8 +647,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(
...@@ -673,8 +673,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -673,8 +673,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(
...@@ -701,8 +701,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -701,8 +701,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(
...@@ -727,8 +727,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -727,8 +727,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(
...@@ -782,8 +782,8 @@ public class DefaultDrmSessionManagerTest { ...@@ -782,8 +782,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(
......
...@@ -447,8 +447,8 @@ public final class DashMediaSource extends BaseMediaSource { ...@@ -447,8 +447,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 {
......
...@@ -415,9 +415,9 @@ public final class HlsMediaSource extends BaseMediaSource ...@@ -415,9 +415,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(
......
...@@ -372,8 +372,8 @@ public final class SsMediaSource extends BaseMediaSource ...@@ -372,8 +372,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();
......
...@@ -213,9 +213,9 @@ public class FakeMediaSource extends BaseMediaSource { ...@@ -213,9 +213,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