mirror of
https://github.com/samsonjs/media.git
synced 2026-04-05 11:15:46 +00:00
Fix leaks of media session service.
References to the service are kept from MediaSessionStub
and from a long-delayed Handler messages in ConnectionTimeoutHandler.
Remove strong references from these places by making the timeout
handler static and ensuring ConnectedControllersManager only keeps
a weak reference to the service (as it's part of MediaSessionStub).
Issue: androidx/media#346
PiperOrigin-RevId: 527543396
(cherry picked from commit 8c262d6c07)
This commit is contained in:
parent
3406334ee8
commit
40ef64ac3a
3 changed files with 24 additions and 6 deletions
|
|
@ -20,6 +20,8 @@
|
|||
a call from System UI to `Callback.onGetLibraryRoot` with
|
||||
`params.isRecent == true` on API 30
|
||||
([#355](https://github.com/androidx/media/issues/355)).
|
||||
* Fix memory leak of `MediaSessionService` or `MediaLibraryService`
|
||||
([#346](https://github.com/androidx/media/issues/346)).
|
||||
|
||||
### 1.0.1 (2023-04-18)
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import androidx.media3.session.MediaSession.ControllerInfo;
|
|||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.common.util.concurrent.MoreExecutors;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
|
@ -62,14 +63,14 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
|||
private final ArrayMap<ControllerInfo, ConnectedControllerRecord<T>> controllerRecords =
|
||||
new ArrayMap<>();
|
||||
|
||||
private final MediaSessionImpl sessionImpl;
|
||||
private final WeakReference<MediaSessionImpl> sessionImpl;
|
||||
|
||||
public ConnectedControllersManager(MediaSessionImpl session) {
|
||||
// Initialize default values.
|
||||
lock = new Object();
|
||||
|
||||
// Initialize members with params.
|
||||
sessionImpl = session;
|
||||
sessionImpl = new WeakReference<>(session);
|
||||
}
|
||||
|
||||
public void addController(
|
||||
|
|
@ -136,6 +137,10 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
|||
}
|
||||
|
||||
record.sequencedFutureManager.release();
|
||||
@Nullable MediaSessionImpl sessionImpl = this.sessionImpl.get();
|
||||
if (sessionImpl == null || sessionImpl.isReleased()) {
|
||||
return;
|
||||
}
|
||||
postOrRun(
|
||||
sessionImpl.getApplicationHandler(),
|
||||
() -> {
|
||||
|
|
@ -214,8 +219,10 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
|||
synchronized (lock) {
|
||||
info = controllerRecords.get(controllerInfo);
|
||||
}
|
||||
@Nullable MediaSessionImpl sessionImpl = this.sessionImpl.get();
|
||||
return info != null
|
||||
&& info.playerCommands.contains(commandCode)
|
||||
&& sessionImpl != null
|
||||
&& sessionImpl.getPlayerWrapper().getAvailableCommands().contains(commandCode);
|
||||
}
|
||||
|
||||
|
|
@ -248,6 +255,10 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
|||
|
||||
@GuardedBy("lock")
|
||||
private void flushCommandQueue(ConnectedControllerRecord<T> info) {
|
||||
@Nullable MediaSessionImpl sessionImpl = this.sessionImpl.get();
|
||||
if (sessionImpl == null) {
|
||||
return;
|
||||
}
|
||||
AtomicBoolean continueRunning = new AtomicBoolean(true);
|
||||
while (continueRunning.get()) {
|
||||
continueRunning.set(false);
|
||||
|
|
|
|||
|
|
@ -147,12 +147,13 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||
appPackageName = context.getPackageName();
|
||||
sessionManager = MediaSessionManager.getSessionManager(context);
|
||||
controllerLegacyCbForBroadcast = new ControllerLegacyCbForBroadcast();
|
||||
connectionTimeoutHandler =
|
||||
new ConnectionTimeoutHandler(session.getApplicationHandler().getLooper());
|
||||
mediaPlayPauseKeyHandler =
|
||||
new MediaPlayPauseKeyHandler(session.getApplicationHandler().getLooper());
|
||||
connectedControllersManager = new ConnectedControllersManager<>(session);
|
||||
connectionTimeoutMs = DEFAULT_CONNECTION_TIMEOUT_MS;
|
||||
connectionTimeoutHandler =
|
||||
new ConnectionTimeoutHandler(
|
||||
session.getApplicationHandler().getLooper(), connectedControllersManager);
|
||||
|
||||
// Select a media button receiver component.
|
||||
ComponentName receiverComponentName = queryPackageManagerForMediaButtonReceiver(context);
|
||||
|
|
@ -1372,12 +1373,16 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||
}
|
||||
}
|
||||
|
||||
private class ConnectionTimeoutHandler extends Handler {
|
||||
private static class ConnectionTimeoutHandler extends Handler {
|
||||
|
||||
private static final int MSG_CONNECTION_TIMED_OUT = 1001;
|
||||
|
||||
public ConnectionTimeoutHandler(Looper looper) {
|
||||
private final ConnectedControllersManager<RemoteUserInfo> connectedControllersManager;
|
||||
|
||||
public ConnectionTimeoutHandler(
|
||||
Looper looper, ConnectedControllersManager<RemoteUserInfo> connectedControllersManager) {
|
||||
super(looper);
|
||||
this.connectedControllersManager = connectedControllersManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
Loading…
Reference in a new issue