Commit 51ed9b75 authored by Mugdha Lakhani's avatar Mugdha Lakhani Committed by Commit Bot

[Weblayer] Integrate with NetworkChangeNotifier.

This change adds an observer class to BrowserFragmentImpl, so we can
observer when the first fragment using WebLayer is attached, and when
the last such fragment is detached.

For this duration, logic has been added to listen to changes using
NetworkChangeNotifier.

Manually tested using chrome://inspect and navigator.online().

Not able to test a javatest because the instrumentation test and the
activity under test use different class loaders, causing two instances
of the NetworkChangeNotifier singleton. It's thus hard to force/mock
network connectivity state to observe changes to navigator.online() as a
result.

Bug: 1018848
Change-Id: I4a4c990ee6e98d5b35f91a68c15baa97def7cd6d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1971926
Commit-Queue: Mugdha Lakhani <nator@chromium.org>
Reviewed-by: default avatarTobias Sargeant <tobiasjs@chromium.org>
Cr-Commit-Position: refs/heads/master@{#726414}
parent ce9573d0
...@@ -53,6 +53,7 @@ android_library("java") { ...@@ -53,6 +53,7 @@ android_library("java") {
"org/chromium/weblayer_private/WebContentsGestureStateTracker.java", "org/chromium/weblayer_private/WebContentsGestureStateTracker.java",
"org/chromium/weblayer_private/WebLayerFactoryImpl.java", "org/chromium/weblayer_private/WebLayerFactoryImpl.java",
"org/chromium/weblayer_private/WebLayerImpl.java", "org/chromium/weblayer_private/WebLayerImpl.java",
"org/chromium/weblayer_private/WebLayerNetworkChangeNotifierRegistrationPolicy.java",
"org/chromium/weblayer_private/metrics/UmaUtils.java", "org/chromium/weblayer_private/metrics/UmaUtils.java",
] ]
...@@ -70,6 +71,7 @@ android_library("java") { ...@@ -70,6 +71,7 @@ android_library("java") {
"//components/spellcheck/browser/android:java", "//components/spellcheck/browser/android:java",
"//components/version_info/android:version_constants_java", "//components/version_info/android:version_constants_java",
"//content/public/android:content_java", "//content/public/android:content_java",
"//net/android:net_java",
"//third_party/android_deps:com_android_support_support_compat_java", "//third_party/android_deps:com_android_support_support_compat_java",
"//ui/android:ui_java", "//ui/android:ui_java",
] ]
......
...@@ -9,6 +9,7 @@ import android.content.Intent; ...@@ -9,6 +9,7 @@ import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.view.View; import android.view.View;
import org.chromium.base.ObserverList;
import org.chromium.components.embedder_support.application.ClassLoaderContextWrapperFactory; import org.chromium.components.embedder_support.application.ClassLoaderContextWrapperFactory;
import org.chromium.weblayer_private.interfaces.BrowserFragmentArgs; import org.chromium.weblayer_private.interfaces.BrowserFragmentArgs;
import org.chromium.weblayer_private.interfaces.IBrowser; import org.chromium.weblayer_private.interfaces.IBrowser;
...@@ -21,11 +22,32 @@ import org.chromium.weblayer_private.interfaces.StrictModeWorkaround; ...@@ -21,11 +22,32 @@ import org.chromium.weblayer_private.interfaces.StrictModeWorkaround;
* Implementation of RemoteFragmentImpl which forwards logic to BrowserImpl. * Implementation of RemoteFragmentImpl which forwards logic to BrowserImpl.
*/ */
public class BrowserFragmentImpl extends RemoteFragmentImpl { public class BrowserFragmentImpl extends RemoteFragmentImpl {
/**
* Observer interface that can be implemented to observe when the first
* fragment requiring WebLayer is attached, and when the last such fragment
* is detached.
*/
public static interface Observer {
public void onFirstBrowserFragmentAttached();
public void onLastBrowserFragmentDetached();
}
private static int sNumAttachedBrowserFragments;
private static final ObserverList<Observer> sLifecycleObservers = new ObserverList<Observer>();
private final ProfileImpl mProfile; private final ProfileImpl mProfile;
private BrowserImpl mBrowser; private BrowserImpl mBrowser;
private Context mContext; private Context mContext;
public static void addObserver(Observer observer) {
sLifecycleObservers.addObserver(observer);
}
public static void removeObserver(Observer observer) {
sLifecycleObservers.removeObserver(observer);
}
public BrowserFragmentImpl( public BrowserFragmentImpl(
ProfileManager profileManager, IRemoteFragmentClient client, Bundle fragmentArgs) { ProfileManager profileManager, IRemoteFragmentClient client, Bundle fragmentArgs) {
super(client); super(client);
...@@ -33,6 +55,24 @@ public class BrowserFragmentImpl extends RemoteFragmentImpl { ...@@ -33,6 +55,24 @@ public class BrowserFragmentImpl extends RemoteFragmentImpl {
profileManager.getProfile(fragmentArgs.getString(BrowserFragmentArgs.PROFILE_NAME)); profileManager.getProfile(fragmentArgs.getString(BrowserFragmentArgs.PROFILE_NAME));
} }
private void incrementBrowserFramentsAndNotifyObservers() {
assert sNumAttachedBrowserFragments >= 0;
sNumAttachedBrowserFragments++;
if (sNumAttachedBrowserFragments != 1) return;
for (Observer observer : sLifecycleObservers) {
observer.onFirstBrowserFragmentAttached();
}
}
private void decrementBrowserFragmentsAndNotifyObservers() {
sNumAttachedBrowserFragments--;
if (sNumAttachedBrowserFragments == 0) {
for (Observer observer : sLifecycleObservers) {
observer.onLastBrowserFragmentDetached();
}
}
}
@Override @Override
public void onAttach(Context context) { public void onAttach(Context context) {
StrictModeWorkaround.apply(); StrictModeWorkaround.apply();
...@@ -40,6 +80,7 @@ public class BrowserFragmentImpl extends RemoteFragmentImpl { ...@@ -40,6 +80,7 @@ public class BrowserFragmentImpl extends RemoteFragmentImpl {
mContext = ClassLoaderContextWrapperFactory.get(context); mContext = ClassLoaderContextWrapperFactory.get(context);
if (mBrowser != null) { // On first creation, onAttach is called before onCreate if (mBrowser != null) { // On first creation, onAttach is called before onCreate
mBrowser.onFragmentAttached(mContext, new FragmentWindowAndroid(mContext, this)); mBrowser.onFragmentAttached(mContext, new FragmentWindowAndroid(mContext, this));
incrementBrowserFramentsAndNotifyObservers();
} }
} }
...@@ -50,6 +91,7 @@ public class BrowserFragmentImpl extends RemoteFragmentImpl { ...@@ -50,6 +91,7 @@ public class BrowserFragmentImpl extends RemoteFragmentImpl {
mBrowser = new BrowserImpl(mProfile, savedInstanceState); mBrowser = new BrowserImpl(mProfile, savedInstanceState);
if (mContext != null) { if (mContext != null) {
mBrowser.onFragmentAttached(mContext, new FragmentWindowAndroid(mContext, this)); mBrowser.onFragmentAttached(mContext, new FragmentWindowAndroid(mContext, this));
incrementBrowserFramentsAndNotifyObservers();
} }
} }
...@@ -78,6 +120,7 @@ public class BrowserFragmentImpl extends RemoteFragmentImpl { ...@@ -78,6 +120,7 @@ public class BrowserFragmentImpl extends RemoteFragmentImpl {
super.onDestroy(); super.onDestroy();
mBrowser.destroy(); mBrowser.destroy();
mBrowser = null; mBrowser = null;
decrementBrowserFragmentsAndNotifyObservers();
} }
@Override @Override
...@@ -86,7 +129,9 @@ public class BrowserFragmentImpl extends RemoteFragmentImpl { ...@@ -86,7 +129,9 @@ public class BrowserFragmentImpl extends RemoteFragmentImpl {
super.onDetach(); super.onDetach();
// mBrowser != null if fragment is retained, otherwise onDestroy is called first. // mBrowser != null if fragment is retained, otherwise onDestroy is called first.
if (mBrowser != null) { if (mBrowser != null) {
assert sNumAttachedBrowserFragments > 0;
mBrowser.onFragmentDetached(); mBrowser.onFragmentDetached();
decrementBrowserFragmentsAndNotifyObservers();
} }
mContext = null; mContext = null;
} }
......
...@@ -33,6 +33,7 @@ import org.chromium.components.embedder_support.application.ClassLoaderContextWr ...@@ -33,6 +33,7 @@ import org.chromium.components.embedder_support.application.ClassLoaderContextWr
import org.chromium.content_public.browser.BrowserStartupController; import org.chromium.content_public.browser.BrowserStartupController;
import org.chromium.content_public.browser.ChildProcessCreationParams; import org.chromium.content_public.browser.ChildProcessCreationParams;
import org.chromium.content_public.browser.DeviceUtils; import org.chromium.content_public.browser.DeviceUtils;
import org.chromium.net.NetworkChangeNotifier;
import org.chromium.ui.base.ResourceBundle; import org.chromium.ui.base.ResourceBundle;
import org.chromium.weblayer_private.interfaces.IBrowserFragment; import org.chromium.weblayer_private.interfaces.IBrowserFragment;
import org.chromium.weblayer_private.interfaces.ICrashReporterController; import org.chromium.weblayer_private.interfaces.ICrashReporterController;
...@@ -186,6 +187,12 @@ public final class WebLayerImpl extends IWebLayer.Stub { ...@@ -186,6 +187,12 @@ public final class WebLayerImpl extends IWebLayer.Stub {
LibraryLoader.getInstance().ensureInitialized(); LibraryLoader.getInstance().ensureInitialized();
} }
GmsBridge.getInstance().setSafeBrowsingHandler(); GmsBridge.getInstance().setSafeBrowsingHandler();
// Configure NetworkChangeNotifier to auto detect changes in network
// connectivity.
NetworkChangeNotifier.init();
NetworkChangeNotifier.setAutoDetectConnectivityState(
new WebLayerNetworkChangeNotifierRegistrationPolicy());
} }
@Override @Override
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.weblayer_private;
import org.chromium.net.NetworkChangeNotifierAutoDetect;
/**
* Registration policy to make sure we only listen to network changes when
* WebLayer is loaded in a fragment.
*/
public class WebLayerNetworkChangeNotifierRegistrationPolicy
extends NetworkChangeNotifierAutoDetect.RegistrationPolicy
implements BrowserFragmentImpl.Observer {
@Override
protected void init(NetworkChangeNotifierAutoDetect notifier) {
super.init(notifier);
BrowserFragmentImpl.addObserver(this);
}
@Override
protected void destroy() {
BrowserFragmentImpl.removeObserver(this);
}
// BrowserFragmentImpl.Observer
@Override
public void onFirstBrowserFragmentAttached() {
register();
}
@Override
public void onLastBrowserFragmentDetached() {
unregister();
}
}
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