| // Copyright 2021 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| package org.chromium.net; |
| |
| import android.content.Context; |
| import android.net.ConnectivityManager; |
| |
| import org.chromium.base.ContextUtils; |
| import org.chromium.base.annotations.CalledByNative; |
| import org.chromium.base.annotations.JNINamespace; |
| import org.chromium.base.annotations.NativeClassQualifiedName; |
| import org.chromium.base.annotations.NativeMethods; |
| |
| /** |
| * Triggers updates to the underlying network state in Chrome alongside NetworkChangeNotifier. |
| * |
| * Differently from NetworkChangeNotifier, this handles default network active type of |
| * notifications. These are handled separately for two main reasons: |
| * 1. They are more expensive to listen to and currently only used by bidi streams connection status |
| * check. Hence, we only enable them when they are actually required. |
| * 2. The default network active value is not cacheable, what observers are interested in is the |
| * event itself (usually to send out packets which were being batched). For this reason the |
| * architecture of NetworkChangeNotifier doesn't make much sense for this notification type. |
| * |
| * Note: ConnectivityManager.OnNetworkActiveListener has been introduced in Android API level 21, so |
| * loading this class will fail on older Android versions (no sdk checks are needed for this |
| * reason). |
| */ |
| @JNINamespace("net") |
| public class NetworkActiveNotifier implements ConnectivityManager.OnNetworkActiveListener { |
| private final ConnectivityManager mConnectivityManager; |
| // Native-side observer of the default network active events. |
| private final long mNativeNetworkActiveObserver; |
| // Used for testing, keeps track of when platform notification are enabled (or disabled). |
| private boolean mAreNotificationsEnabled; |
| |
| /** |
| * Used to build a Java object from native code. |
| */ |
| @CalledByNative |
| public static NetworkActiveNotifier build(long nativeNetworkActiveNotifier) { |
| return new NetworkActiveNotifier(nativeNetworkActiveNotifier); |
| } |
| |
| @CalledByNative |
| public void enableNotifications() { |
| mAreNotificationsEnabled = true; |
| mConnectivityManager.addDefaultNetworkActiveListener(this); |
| } |
| |
| @CalledByNative |
| public void disableNotifications() { |
| mAreNotificationsEnabled = false; |
| mConnectivityManager.removeDefaultNetworkActiveListener(this); |
| } |
| |
| @CalledByNative |
| public boolean isDefaultNetworkActive() { |
| return mConnectivityManager.isDefaultNetworkActive(); |
| } |
| |
| @Override |
| public void onNetworkActive() { |
| NetworkActiveNotifierJni.get().notifyOfDefaultNetworkActive(mNativeNetworkActiveObserver); |
| } |
| |
| /** |
| * For testing, called by native code to trigger a fake platform notification. |
| */ |
| @CalledByNative |
| public void fakeDefaultNetworkActive() { |
| if (mAreNotificationsEnabled) { |
| // Platform notifications should only be received when enabled. |
| onNetworkActive(); |
| } |
| } |
| |
| @NativeMethods |
| interface Natives { |
| @NativeClassQualifiedName("NetworkChangeNotifierDelegateAndroid") |
| void notifyOfDefaultNetworkActive(long nativePtr); |
| } |
| |
| private NetworkActiveNotifier(long nativeNetworkActiveNotifier) { |
| mNativeNetworkActiveObserver = nativeNetworkActiveNotifier; |
| Context ctx = ContextUtils.getApplicationContext(); |
| mConnectivityManager = |
| (ConnectivityManager) ctx.getSystemService(Context.CONNECTIVITY_SERVICE); |
| } |
| } |