mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Use experimental release timeout in setForgroundMode(false).
The setForeground mode method blocks in the same way as release and should use the same timeout if configured. In case the method runs into the timeout, a player error is reported. PiperOrigin-RevId: 317283808
This commit is contained in:
parent
63ae4cc54b
commit
457b215565
2 changed files with 46 additions and 53 deletions
|
|
@ -659,7 +659,14 @@ import java.util.concurrent.TimeoutException;
|
||||||
public void setForegroundMode(boolean foregroundMode) {
|
public void setForegroundMode(boolean foregroundMode) {
|
||||||
if (this.foregroundMode != foregroundMode) {
|
if (this.foregroundMode != foregroundMode) {
|
||||||
this.foregroundMode = foregroundMode;
|
this.foregroundMode = foregroundMode;
|
||||||
internalPlayer.setForegroundMode(foregroundMode);
|
if (!internalPlayer.setForegroundMode(foregroundMode)) {
|
||||||
|
notifyListeners(
|
||||||
|
listener ->
|
||||||
|
listener.onPlayerError(
|
||||||
|
ExoPlaybackException.createForUnexpected(
|
||||||
|
new RuntimeException(
|
||||||
|
new TimeoutException("Setting foreground mode timed out.")))));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ import com.google.android.exoplayer2.util.Assertions;
|
||||||
import com.google.android.exoplayer2.util.Clock;
|
import com.google.android.exoplayer2.util.Clock;
|
||||||
import com.google.android.exoplayer2.util.HandlerWrapper;
|
import com.google.android.exoplayer2.util.HandlerWrapper;
|
||||||
import com.google.android.exoplayer2.util.Log;
|
import com.google.android.exoplayer2.util.Log;
|
||||||
|
import com.google.android.exoplayer2.util.Supplier;
|
||||||
import com.google.android.exoplayer2.util.TraceUtil;
|
import com.google.android.exoplayer2.util.TraceUtil;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
@ -296,29 +297,24 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
handler.obtainMessage(MSG_SEND_MESSAGE, message).sendToTarget();
|
handler.obtainMessage(MSG_SEND_MESSAGE, message).sendToTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void setForegroundMode(boolean foregroundMode) {
|
public synchronized boolean setForegroundMode(boolean foregroundMode) {
|
||||||
if (released || !internalPlaybackThread.isAlive()) {
|
if (released || !internalPlaybackThread.isAlive()) {
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
if (foregroundMode) {
|
if (foregroundMode) {
|
||||||
handler.obtainMessage(MSG_SET_FOREGROUND_MODE, /* foregroundMode */ 1, 0).sendToTarget();
|
handler.obtainMessage(MSG_SET_FOREGROUND_MODE, /* foregroundMode */ 1, 0).sendToTarget();
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
AtomicBoolean processedFlag = new AtomicBoolean();
|
AtomicBoolean processedFlag = new AtomicBoolean();
|
||||||
handler
|
handler
|
||||||
.obtainMessage(MSG_SET_FOREGROUND_MODE, /* foregroundMode */ 0, 0, processedFlag)
|
.obtainMessage(MSG_SET_FOREGROUND_MODE, /* foregroundMode */ 0, 0, processedFlag)
|
||||||
.sendToTarget();
|
.sendToTarget();
|
||||||
boolean wasInterrupted = false;
|
if (releaseTimeoutMs > 0) {
|
||||||
while (!processedFlag.get()) {
|
waitUninterruptibly(/* condition= */ processedFlag::get, releaseTimeoutMs);
|
||||||
try {
|
} else {
|
||||||
wait();
|
waitUninterruptibly(/* condition= */ processedFlag::get);
|
||||||
} catch (InterruptedException e) {
|
|
||||||
wasInterrupted = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (wasInterrupted) {
|
|
||||||
// Restore the interrupted status.
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
}
|
||||||
|
return processedFlag.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -328,16 +324,11 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
handler.sendEmptyMessage(MSG_RELEASE);
|
handler.sendEmptyMessage(MSG_RELEASE);
|
||||||
try {
|
if (releaseTimeoutMs > 0) {
|
||||||
if (releaseTimeoutMs > 0) {
|
waitUninterruptibly(/* condition= */ () -> released, releaseTimeoutMs);
|
||||||
waitUntilReleased(releaseTimeoutMs);
|
} else {
|
||||||
} else {
|
waitUninterruptibly(/* condition= */ () -> released);
|
||||||
waitUntilReleased();
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return released;
|
return released;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -505,59 +496,54 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
// Private methods.
|
// Private methods.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Blocks the current thread until {@link #releaseInternal()} is executed on the playback Thread.
|
* Blocks the current thread until a condition becomes true.
|
||||||
*
|
*
|
||||||
* <p>If the current thread is interrupted while waiting for {@link #releaseInternal()} to
|
* <p>If the current thread is interrupted while waiting for the condition to become true, this
|
||||||
* complete, this method will delay throwing the {@link InterruptedException} to ensure that the
|
* method will restore the interrupt <b>after</b> the condition became true.
|
||||||
* underlying resources have been released, and will an {@link InterruptedException} <b>after</b>
|
|
||||||
* {@link #releaseInternal()} is complete.
|
|
||||||
*
|
*
|
||||||
* @throws {@link InterruptedException} if the current Thread was interrupted while waiting for
|
* @param condition The condition.
|
||||||
* {@link #releaseInternal()} to complete.
|
|
||||||
*/
|
*/
|
||||||
private synchronized void waitUntilReleased() throws InterruptedException {
|
private synchronized void waitUninterruptibly(Supplier<Boolean> condition) {
|
||||||
InterruptedException interruptedException = null;
|
boolean wasInterrupted = false;
|
||||||
while (!released) {
|
while (!condition.get()) {
|
||||||
try {
|
try {
|
||||||
wait();
|
wait();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
interruptedException = e;
|
wasInterrupted = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (wasInterrupted) {
|
||||||
if (interruptedException != null) {
|
// Restore the interrupted status.
|
||||||
throw interruptedException;
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Blocks the current thread until {@link #releaseInternal()} is performed on the playback Thread
|
* Blocks the current thread until a condition becomes true or the specified amount of time has
|
||||||
* or the specified amount of time has elapsed.
|
* elapsed.
|
||||||
*
|
*
|
||||||
* <p>If the current thread is interrupted while waiting for {@link #releaseInternal()} to
|
* <p>If the current thread is interrupted while waiting for the condition to become true, this
|
||||||
* complete, this method will delay throwing the {@link InterruptedException} to ensure that the
|
* method will restore the interrupt <b>after</b> the condition became true or the operation times
|
||||||
* underlying resources have been released or the operation timed out, and will throw an {@link
|
* out.
|
||||||
* InterruptedException} afterwards.
|
|
||||||
*
|
*
|
||||||
* @param timeoutMs the time in milliseconds to wait for {@link #releaseInternal()} to complete.
|
* @param condition The condition.
|
||||||
* @throws {@link InterruptedException} if the current Thread was interrupted while waiting for
|
* @param timeoutMs The time in milliseconds to wait for the condition to become true.
|
||||||
* {@link #releaseInternal()} to complete.
|
|
||||||
*/
|
*/
|
||||||
private synchronized void waitUntilReleased(long timeoutMs) throws InterruptedException {
|
private synchronized void waitUninterruptibly(Supplier<Boolean> condition, long timeoutMs) {
|
||||||
long deadlineMs = clock.elapsedRealtime() + timeoutMs;
|
long deadlineMs = clock.elapsedRealtime() + timeoutMs;
|
||||||
long remainingMs = timeoutMs;
|
long remainingMs = timeoutMs;
|
||||||
InterruptedException interruptedException = null;
|
boolean wasInterrupted = false;
|
||||||
while (!released && remainingMs > 0) {
|
while (!condition.get() && remainingMs > 0) {
|
||||||
try {
|
try {
|
||||||
wait(remainingMs);
|
wait(remainingMs);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
interruptedException = e;
|
wasInterrupted = true;
|
||||||
}
|
}
|
||||||
remainingMs = deadlineMs - clock.elapsedRealtime();
|
remainingMs = deadlineMs - clock.elapsedRealtime();
|
||||||
}
|
}
|
||||||
|
if (wasInterrupted) {
|
||||||
if (interruptedException != null) {
|
// Restore the interrupted status.
|
||||||
throw interruptedException;
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue