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