Commit 16879424 authored by Zhiqiang Zhang's avatar Zhiqiang Zhang Committed by Commit Bot

Fix notification/media session in Cast and MediaFling

There was a bug that BaseSessionController holds weak reference to
callbacks to avoid holding callback references unnecessary. This was to
prevent potential memory leaks, however the BaseNotificationController
instance was somehow dereferenced in public release build (perhaps due
to some optimization).

This causes Cast/MediaFling to not set up media notification and
MediaSession properly.

This CL fixes the issue by making BaseSessionController holding strong
references. Clients are responsible to remove the callbacks when not
needed.

Bug: 978940
Change-Id: If2146cd2a5c3036897c61cf842e7054182b46055
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1843959Reviewed-by: default avatarThomas Guilbert <tguilbert@chromium.org>
Commit-Queue: Zhiqiang Zhang <zqzhang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#703448}
parent 15be48ad
...@@ -22,9 +22,7 @@ import org.chromium.chrome.browser.media.router.FlingingController; ...@@ -22,9 +22,7 @@ import org.chromium.chrome.browser.media.router.FlingingController;
import org.chromium.chrome.browser.media.router.MediaSink; import org.chromium.chrome.browser.media.router.MediaSink;
import org.chromium.chrome.browser.media.router.MediaSource; import org.chromium.chrome.browser.media.router.MediaSource;
import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
...@@ -57,7 +55,7 @@ public abstract class BaseSessionController { ...@@ -57,7 +55,7 @@ public abstract class BaseSessionController {
private final CafBaseMediaRouteProvider mProvider; private final CafBaseMediaRouteProvider mProvider;
private CreateRouteRequestInfo mRouteCreationInfo; private CreateRouteRequestInfo mRouteCreationInfo;
private final RemoteMediaClient.Callback mRemoteMediaClientCallback; private final RemoteMediaClient.Callback mRemoteMediaClientCallback;
private final List<WeakReference<Callback>> mCallbacks = new ArrayList<>(); private final List<Callback> mCallbacks = new ArrayList<>();
public BaseSessionController(CafBaseMediaRouteProvider provider) { public BaseSessionController(CafBaseMediaRouteProvider provider) {
mProvider = provider; mProvider = provider;
...@@ -65,17 +63,11 @@ public abstract class BaseSessionController { ...@@ -65,17 +63,11 @@ public abstract class BaseSessionController {
} }
public void addCallback(Callback callback) { public void addCallback(Callback callback) {
mCallbacks.add(new WeakReference<>(callback)); mCallbacks.add(callback);
} }
public void removeCallback(Callback callback) { public void removeCallback(Callback callback) {
Iterator<WeakReference<Callback>> iterator = mCallbacks.iterator(); mCallbacks.remove(callback);
while (iterator.hasNext()) {
if (iterator.next().get() == callback) {
iterator.remove();
}
}
} }
public void requestSessionLaunch() { public void requestSessionLaunch() {
...@@ -266,15 +258,8 @@ public abstract class BaseSessionController { ...@@ -266,15 +258,8 @@ public abstract class BaseSessionController {
} }
private void notifyCallback(NotifyCallbackAction action) { private void notifyCallback(NotifyCallbackAction action) {
Iterator<WeakReference<Callback>> iterator = mCallbacks.iterator(); for (Callback callback : mCallbacks) {
action.notify(callback);
while (iterator.hasNext()) {
Callback callback = iterator.next().get();
if (callback == null) {
iterator.remove();
} else {
action.notify(callback);
}
} }
} }
......
...@@ -152,6 +152,12 @@ public class CafExpandedControllerActivity ...@@ -152,6 +152,12 @@ public class CafExpandedControllerActivity
} }
} }
@Override
protected void onDestroy() {
mSessionController.removeCallback(this);
super.onDestroy();
}
@Override @Override
public void onSessionStarted() {} public void onSessionStarted() {}
......
...@@ -164,6 +164,18 @@ public class BaseSessionControllerTest { ...@@ -164,6 +164,18 @@ public class BaseSessionControllerTest {
verify(mNotificationController).onSessionEnded(); verify(mNotificationController).onSessionEnded();
} }
@Test
public void testSessionLifecyleNotNotifiedAfterCallbackRemoved() {
mController.removeCallback(mNotificationController);
mController.attachToCastSession(mCastSession);
mController.onSessionStarted();
verify(mNotificationController, never()).onSessionStarted();
mController.onSessionEnded();
verify(mNotificationController, never()).onSessionEnded();
}
@Test @Test
public void testGetCapabilities() { public void testGetCapabilities() {
mController.attachToCastSession(mCastSession); mController.attachToCastSession(mCastSession);
......
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 to comment