1 // Copyright 2021 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.net; 6 7 import android.content.Context; 8 import android.net.ConnectivityManager; 9 10 import org.chromium.base.ContextUtils; 11 import org.chromium.base.annotations.CalledByNative; 12 import org.chromium.base.annotations.JNINamespace; 13 import org.chromium.base.annotations.NativeClassQualifiedName; 14 import org.chromium.base.annotations.NativeMethods; 15 16 /** 17 * Triggers updates to the underlying network state in Chrome alongside NetworkChangeNotifier. 18 * 19 * Differently from NetworkChangeNotifier, this handles default network active type of 20 * notifications. These are handled separately for two main reasons: 21 * 1. They are more expensive to listen to and currently only used by bidi streams connection status 22 * check. Hence, we only enable them when they are actually required. 23 * 2. The default network active value is not cacheable, what observers are interested in is the 24 * event itself (usually to send out packets which were being batched). For this reason the 25 * architecture of NetworkChangeNotifier doesn't make much sense for this notification type. 26 * 27 * Note: ConnectivityManager.OnNetworkActiveListener has been introduced in Android API level 21, so 28 * loading this class will fail on older Android versions (no sdk checks are needed for this 29 * reason). 30 */ 31 @JNINamespace("net") 32 public class NetworkActiveNotifier implements ConnectivityManager.OnNetworkActiveListener { 33 private final ConnectivityManager mConnectivityManager; 34 // Native-side observer of the default network active events. 35 private final long mNativeNetworkActiveObserver; 36 // Used for testing, keeps track of when platform notification are enabled (or disabled). 37 private boolean mAreNotificationsEnabled; 38 39 /** 40 * Used to build a Java object from native code. 41 */ 42 @CalledByNative build(long nativeNetworkActiveNotifier)43 public static NetworkActiveNotifier build(long nativeNetworkActiveNotifier) { 44 return new NetworkActiveNotifier(nativeNetworkActiveNotifier); 45 } 46 47 @CalledByNative enableNotifications()48 public void enableNotifications() { 49 mAreNotificationsEnabled = true; 50 mConnectivityManager.addDefaultNetworkActiveListener(this); 51 } 52 53 @CalledByNative disableNotifications()54 public void disableNotifications() { 55 mAreNotificationsEnabled = false; 56 mConnectivityManager.removeDefaultNetworkActiveListener(this); 57 } 58 59 @CalledByNative isDefaultNetworkActive()60 public boolean isDefaultNetworkActive() { 61 return mConnectivityManager.isDefaultNetworkActive(); 62 } 63 64 @Override onNetworkActive()65 public void onNetworkActive() { 66 NetworkActiveNotifierJni.get().notifyOfDefaultNetworkActive(mNativeNetworkActiveObserver); 67 } 68 69 /** 70 * For testing, called by native code to trigger a fake platform notification. 71 */ 72 @CalledByNative fakeDefaultNetworkActive()73 public void fakeDefaultNetworkActive() { 74 if (mAreNotificationsEnabled) { 75 // Platform notifications should only be received when enabled. 76 onNetworkActive(); 77 } 78 } 79 80 @NativeMethods 81 interface Natives { 82 @NativeClassQualifiedName("NetworkChangeNotifierDelegateAndroid") notifyOfDefaultNetworkActive(long nativePtr)83 void notifyOfDefaultNetworkActive(long nativePtr); 84 } 85 NetworkActiveNotifier(long nativeNetworkActiveNotifier)86 private NetworkActiveNotifier(long nativeNetworkActiveNotifier) { 87 mNativeNetworkActiveObserver = nativeNetworkActiveNotifier; 88 Context ctx = ContextUtils.getApplicationContext(); 89 mConnectivityManager = 90 (ConnectivityManager) ctx.getSystemService(Context.CONNECTIVITY_SERVICE); 91 } 92 } 93