Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(71)

Side by Side Diff: net/android/java/src/org/chromium/net/NetworkChangeNotifierAutoDetect.java

Issue 1358163004: [Android] Introduce RegistrationPolicy for NetworkChangeNotifier. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix compile of tests Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.net; 5 package org.chromium.net;
6 6
7 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; 7 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
8 8
9 import android.Manifest.permission; 9 import android.Manifest.permission;
10 import android.annotation.SuppressLint; 10 import android.annotation.SuppressLint;
11 import android.content.BroadcastReceiver; 11 import android.content.BroadcastReceiver;
12 import android.content.Context; 12 import android.content.Context;
13 import android.content.Intent; 13 import android.content.Intent;
14 import android.content.IntentFilter; 14 import android.content.IntentFilter;
15 import android.content.pm.PackageManager; 15 import android.content.pm.PackageManager;
16 import android.net.ConnectivityManager; 16 import android.net.ConnectivityManager;
17 import android.net.ConnectivityManager.NetworkCallback; 17 import android.net.ConnectivityManager.NetworkCallback;
18 import android.net.Network; 18 import android.net.Network;
19 import android.net.NetworkCapabilities; 19 import android.net.NetworkCapabilities;
20 import android.net.NetworkInfo; 20 import android.net.NetworkInfo;
21 import android.net.NetworkRequest; 21 import android.net.NetworkRequest;
22 import android.net.wifi.WifiInfo; 22 import android.net.wifi.WifiInfo;
23 import android.net.wifi.WifiManager; 23 import android.net.wifi.WifiManager;
24 import android.os.Build; 24 import android.os.Build;
25 import android.telephony.TelephonyManager; 25 import android.telephony.TelephonyManager;
26 import android.util.Log; 26 import android.util.Log;
27 27
28 import org.chromium.base.ApplicationState;
29 import org.chromium.base.ApplicationStatus;
30 import org.chromium.base.ThreadUtils; 28 import org.chromium.base.ThreadUtils;
31 import org.chromium.base.VisibleForTesting; 29 import org.chromium.base.VisibleForTesting;
32 30
33 /** 31 /**
34 * Used by the NetworkChangeNotifier to listens to platform changes in connectiv ity. 32 * Used by the NetworkChangeNotifier to listens to platform changes in connectiv ity.
35 * Note that use of this class requires that the app have the platform 33 * Note that use of this class requires that the app have the platform
36 * ACCESS_NETWORK_STATE permission. 34 * ACCESS_NETWORK_STATE permission.
37 */ 35 */
38 public class NetworkChangeNotifierAutoDetect extends BroadcastReceiver 36 public class NetworkChangeNotifierAutoDetect extends BroadcastReceiver {
39 implements ApplicationStatus.ApplicationStateListener {
40
41 static class NetworkState { 37 static class NetworkState {
42 private final boolean mConnected; 38 private final boolean mConnected;
43 private final int mType; 39 private final int mType;
44 private final int mSubtype; 40 private final int mSubtype;
45 41
46 public NetworkState(boolean connected, int type, int subtype) { 42 public NetworkState(boolean connected, int type, int subtype) {
47 mConnected = connected; 43 mConnected = connected;
48 mType = type; 44 mType = type;
49 mSubtype = subtype; 45 mSubtype = subtype;
50 } 46 }
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 final int netId = networkToNetId(network); 289 final int netId = networkToNetId(network);
294 ThreadUtils.postOnUiThread(new Runnable() { 290 ThreadUtils.postOnUiThread(new Runnable() {
295 @Override 291 @Override
296 public void run() { 292 public void run() {
297 mObserver.onNetworkDisconnect(netId); 293 mObserver.onNetworkDisconnect(netId);
298 } 294 }
299 }); 295 });
300 } 296 }
301 } 297 }
302 298
299 /**
300 * Abstract class for providing a policy regarding when the NetworkChangeNot ifier
301 * should listen for network changes.
302 */
303 public abstract static class RegistrationPolicy {
304 private NetworkChangeNotifierAutoDetect mNotifier;
305
306 /**
307 * Start listening for network changes.
308 */
309 protected final void register() {
310 assert mNotifier != null;
311 mNotifier.register();
312 }
313
314 /**
315 * Stop listening for network changes.
316 */
317 protected final void unregister() {
318 assert mNotifier != null;
319 mNotifier.unregister();
320 }
321
322 /**
323 * Initializes the policy with the notifier, overriding subclasses shoul d always
324 * call this method.
325 */
326 protected void init(NetworkChangeNotifierAutoDetect notifier) {
327 mNotifier = notifier;
328 }
329
330 protected abstract void destroy();
331 }
332
303 private static final String TAG = "NetworkChangeNotifierAutoDetect"; 333 private static final String TAG = "NetworkChangeNotifierAutoDetect";
304 private static final int UNKNOWN_LINK_SPEED = -1; 334 private static final int UNKNOWN_LINK_SPEED = -1;
335
305 private final NetworkConnectivityIntentFilter mIntentFilter; 336 private final NetworkConnectivityIntentFilter mIntentFilter;
337 private final Observer mObserver;
338 private final Context mContext;
339 private final RegistrationPolicy mRegistrationPolicy;
306 340
307 private final Observer mObserver;
308
309 private final Context mContext;
310 // mConnectivityManagerDelegates and mWifiManagerDelegate are only non-final for testing. 341 // mConnectivityManagerDelegates and mWifiManagerDelegate are only non-final for testing.
311 private ConnectivityManagerDelegate mConnectivityManagerDelegate; 342 private ConnectivityManagerDelegate mConnectivityManagerDelegate;
312 private WifiManagerDelegate mWifiManagerDelegate; 343 private WifiManagerDelegate mWifiManagerDelegate;
313 // mNetworkCallback and mNetworkRequest are only non-null in Android L and a bove. 344 // mNetworkCallback and mNetworkRequest are only non-null in Android L and a bove.
314 private final NetworkCallback mNetworkCallback; 345 private final NetworkCallback mNetworkCallback;
315 private final NetworkRequest mNetworkRequest; 346 private final NetworkRequest mNetworkRequest;
316 private boolean mRegistered; 347 private boolean mRegistered;
317 private final boolean mApplicationStateRegistered;
318 private int mConnectionType; 348 private int mConnectionType;
319 private String mWifiSSID; 349 private String mWifiSSID;
320 private double mMaxBandwidthMbps; 350 private double mMaxBandwidthMbps;
321 351
322 /** 352 /**
323 * Observer interface by which observer is notified of network changes. 353 * Observer interface by which observer is notified of network changes.
324 */ 354 */
325 public static interface Observer { 355 public static interface Observer {
326 /** 356 /**
327 * Called when default network changes. 357 * Called when default network changes.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 public void updateActiveNetworkList(int[] activeNetIds); 392 public void updateActiveNetworkList(int[] activeNetIds);
363 } 393 }
364 394
365 /** 395 /**
366 * Constructs a NetworkChangeNotifierAutoDetect. Should only be called on UI thread. 396 * Constructs a NetworkChangeNotifierAutoDetect. Should only be called on UI thread.
367 * @param alwaysWatchForChanges If true, always watch for network changes. 397 * @param alwaysWatchForChanges If true, always watch for network changes.
368 * Otherwise, only watch if app is in foreground. 398 * Otherwise, only watch if app is in foreground.
369 */ 399 */
370 @SuppressLint("NewApi") 400 @SuppressLint("NewApi")
371 public NetworkChangeNotifierAutoDetect( 401 public NetworkChangeNotifierAutoDetect(
372 Observer observer, Context context, boolean alwaysWatchForChanges) { 402 Observer observer, Context context, RegistrationPolicy policy) {
373 // Since BroadcastReceiver is always called back on UI thread, ensure 403 // Since BroadcastReceiver is always called back on UI thread, ensure
374 // running on UI thread so notification logic can be single-threaded. 404 // running on UI thread so notification logic can be single-threaded.
375 ThreadUtils.assertOnUiThread(); 405 ThreadUtils.assertOnUiThread();
376 mObserver = observer; 406 mObserver = observer;
377 mContext = context.getApplicationContext(); 407 mContext = context.getApplicationContext();
378 mConnectivityManagerDelegate = new ConnectivityManagerDelegate(context); 408 mConnectivityManagerDelegate = new ConnectivityManagerDelegate(context);
379 mWifiManagerDelegate = new WifiManagerDelegate(context); 409 mWifiManagerDelegate = new WifiManagerDelegate(context);
380 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 410 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
381 mNetworkCallback = new MyNetworkCallback(); 411 mNetworkCallback = new MyNetworkCallback();
382 mNetworkRequest = 412 mNetworkRequest =
383 new NetworkRequest.Builder().addCapability(NET_CAPABILITY_IN TERNET).build(); 413 new NetworkRequest.Builder().addCapability(NET_CAPABILITY_IN TERNET).build();
384 } else { 414 } else {
385 mNetworkCallback = null; 415 mNetworkCallback = null;
386 mNetworkRequest = null; 416 mNetworkRequest = null;
387 } 417 }
388 final NetworkState networkState = mConnectivityManagerDelegate.getNetwor kState(); 418 final NetworkState networkState = mConnectivityManagerDelegate.getNetwor kState();
389 mConnectionType = getCurrentConnectionType(networkState); 419 mConnectionType = getCurrentConnectionType(networkState);
390 mWifiSSID = getCurrentWifiSSID(networkState); 420 mWifiSSID = getCurrentWifiSSID(networkState);
391 mMaxBandwidthMbps = getCurrentMaxBandwidthInMbps(networkState); 421 mMaxBandwidthMbps = getCurrentMaxBandwidthInMbps(networkState);
392 mIntentFilter = 422 mIntentFilter =
393 new NetworkConnectivityIntentFilter(mWifiManagerDelegate.getHasW ifiPermission()); 423 new NetworkConnectivityIntentFilter(mWifiManagerDelegate.getHasW ifiPermission());
394 424 mRegistrationPolicy = policy;
395 if (alwaysWatchForChanges) { 425 mRegistrationPolicy.init(this);
396 registerReceiver();
397 mApplicationStateRegistered = false;
398 } else {
399 ApplicationStatus.registerApplicationStateListener(this);
400 onApplicationStateChange(getApplicationState());
401 mApplicationStateRegistered = true;
402 }
403 } 426 }
404 427
405 /** 428 /**
406 * Allows overriding the ConnectivityManagerDelegate for tests. 429 * Allows overriding the ConnectivityManagerDelegate for tests.
407 */ 430 */
408 void setConnectivityManagerDelegateForTests(ConnectivityManagerDelegate dele gate) { 431 void setConnectivityManagerDelegateForTests(ConnectivityManagerDelegate dele gate) {
409 mConnectivityManagerDelegate = delegate; 432 mConnectivityManagerDelegate = delegate;
410 } 433 }
411 434
412 /** 435 /**
413 * Allows overriding the WifiManagerDelegate for tests. 436 * Allows overriding the WifiManagerDelegate for tests.
414 */ 437 */
415 void setWifiManagerDelegateForTests(WifiManagerDelegate delegate) { 438 void setWifiManagerDelegateForTests(WifiManagerDelegate delegate) {
416 mWifiManagerDelegate = delegate; 439 mWifiManagerDelegate = delegate;
417 } 440 }
418 441
419 /**
420 * Returns the activity's status.
421 * @return an {@code int} that is one of {@code ApplicationState.HAS_*_ACTIV ITIES}.
422 */
423 @VisibleForTesting 442 @VisibleForTesting
424 int getApplicationState() { 443 RegistrationPolicy getRegistrationPolicy() {
425 return ApplicationStatus.getStateForApplication(); 444 return mRegistrationPolicy;
426 } 445 }
427 446
428 /** 447 /**
429 * Returns whether the object has registered to receive network connectivity intents. 448 * Returns whether the object has registered to receive network connectivity intents.
430 */ 449 */
431 @VisibleForTesting 450 @VisibleForTesting
432 boolean isReceiverRegisteredForTesting() { 451 boolean isReceiverRegisteredForTesting() {
433 return mRegistered; 452 return mRegistered;
434 } 453 }
435 454
436 public void destroy() { 455 public void destroy() {
437 if (mApplicationStateRegistered) ApplicationStatus.unregisterApplication StateListener(this); 456 mRegistrationPolicy.destroy();
438 unregisterReceiver(); 457 unregister();
439 } 458 }
440 459
441 /** 460 /**
442 * Registers a BroadcastReceiver in the given context. 461 * Registers a BroadcastReceiver in the given context.
443 */ 462 */
444 private void registerReceiver() { 463 public void register() {
445 if (!mRegistered) { 464 if (mRegistered) return;
446 mRegistered = true; 465
447 mContext.registerReceiver(this, mIntentFilter); 466 final NetworkState networkState = getCurrentNetworkState();
448 if (mNetworkCallback != null) { 467 connectionTypeChanged(networkState);
449 mConnectivityManagerDelegate.registerNetworkCallback( 468 maxBandwidthChanged(networkState);
450 mNetworkRequest, mNetworkCallback); 469 mContext.registerReceiver(this, mIntentFilter);
451 // registerNetworkCallback() will rematch our NetworkRequest 470 mRegistered = true;
452 // against active networks, so a cached list of active networks 471
453 // will be repopulated immediatly after this. However we need to 472 if (mNetworkCallback != null) {
454 // purge any cached networks as they may have been disconnected 473 mConnectivityManagerDelegate.registerNetworkCallback(mNetworkRequest , mNetworkCallback);
455 // while mNetworkCallback was unregistered. 474 // registerNetworkCallback() will rematch our NetworkRequest
456 final Network[] networks = mConnectivityManagerDelegate.getAllNe tworks(); 475 // against active networks, so a cached list of active networks
457 // Convert Networks to NetIDs. 476 // will be repopulated immediatly after this. However we need to
458 final int[] netIds = new int[networks.length]; 477 // purge any cached networks as they may have been disconnected
459 for (int i = 0; i < networks.length; i++) { 478 // while mNetworkCallback was unregistered.
460 netIds[i] = networkToNetId(networks[i]); 479 final Network[] networks = mConnectivityManagerDelegate.getAllNetwor ks();
461 } 480 // Convert Networks to NetIDs.
462 mObserver.updateActiveNetworkList(netIds); 481 final int[] netIds = new int[networks.length];
482 for (int i = 0; i < networks.length; i++) {
483 netIds[i] = networkToNetId(networks[i]);
463 } 484 }
485 mObserver.updateActiveNetworkList(netIds);
464 } 486 }
465 } 487 }
466 488
467 /** 489 /**
468 * Unregisters the BroadcastReceiver in the given context. 490 * Unregisters a BroadcastReceiver in the given context.
469 */ 491 */
470 private void unregisterReceiver() { 492 public void unregister() {
471 if (mRegistered) { 493 if (!mRegistered) return;
472 mRegistered = false; 494 mContext.unregisterReceiver(this);
473 mContext.unregisterReceiver(this); 495 mRegistered = false;
474 if (mNetworkCallback != null) { 496 if (mNetworkCallback != null) {
475 mConnectivityManagerDelegate.unregisterNetworkCallback(mNetworkC allback); 497 mConnectivityManagerDelegate.unregisterNetworkCallback(mNetworkCallb ack);
476 }
477 } 498 }
478 } 499 }
479 500
480 public NetworkState getCurrentNetworkState() { 501 public NetworkState getCurrentNetworkState() {
481 return mConnectivityManagerDelegate.getNetworkState(); 502 return mConnectivityManagerDelegate.getNetworkState();
482 } 503 }
483 504
484 /** 505 /**
485 * Returns an array of all of the device's currently connected 506 * Returns an array of all of the device's currently connected
486 * networks and ConnectionTypes. Array elements are a repeated sequence of: 507 * networks and ConnectionTypes. Array elements are a repeated sequence of:
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 public void onReceive(Context context, Intent intent) { 666 public void onReceive(Context context, Intent intent) {
646 final NetworkState networkState = getCurrentNetworkState(); 667 final NetworkState networkState = getCurrentNetworkState();
647 if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) { 668 if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
648 connectionTypeChanged(networkState); 669 connectionTypeChanged(networkState);
649 maxBandwidthChanged(networkState); 670 maxBandwidthChanged(networkState);
650 } else if (WifiManager.RSSI_CHANGED_ACTION.equals(intent.getAction())) { 671 } else if (WifiManager.RSSI_CHANGED_ACTION.equals(intent.getAction())) {
651 maxBandwidthChanged(networkState); 672 maxBandwidthChanged(networkState);
652 } 673 }
653 } 674 }
654 675
655 // ApplicationStatus.ApplicationStateListener
656 @Override
657 public void onApplicationStateChange(int newState) {
658 final NetworkState networkState = getCurrentNetworkState();
659 if (newState == ApplicationState.HAS_RUNNING_ACTIVITIES) {
660 connectionTypeChanged(networkState);
661 maxBandwidthChanged(networkState);
662 registerReceiver();
663 } else if (newState == ApplicationState.HAS_PAUSED_ACTIVITIES) {
664 unregisterReceiver();
665 }
666 }
667
668 private void connectionTypeChanged(NetworkState networkState) { 676 private void connectionTypeChanged(NetworkState networkState) {
669 int newConnectionType = getCurrentConnectionType(networkState); 677 int newConnectionType = getCurrentConnectionType(networkState);
670 String newWifiSSID = getCurrentWifiSSID(networkState); 678 String newWifiSSID = getCurrentWifiSSID(networkState);
671 if (newConnectionType == mConnectionType && newWifiSSID.equals(mWifiSSID )) return; 679 if (newConnectionType == mConnectionType && newWifiSSID.equals(mWifiSSID )) return;
672 680
673 mConnectionType = newConnectionType; 681 mConnectionType = newConnectionType;
674 mWifiSSID = newWifiSSID; 682 mWifiSSID = newWifiSSID;
675 Log.d(TAG, "Network connectivity changed, type is: " + mConnectionType); 683 Log.d(TAG, "Network connectivity changed, type is: " + mConnectionType);
676 mObserver.onConnectionTypeChanged(newConnectionType); 684 mObserver.onConnectionTypeChanged(newConnectionType);
677 } 685 }
(...skipping 16 matching lines...) Expand all
694 * Extracts NetID of network. Only available on Lollipop and newer releases. 702 * Extracts NetID of network. Only available on Lollipop and newer releases.
695 */ 703 */
696 @SuppressLint("NewApi") 704 @SuppressLint("NewApi")
697 private static int networkToNetId(Network network) { 705 private static int networkToNetId(Network network) {
698 // NOTE(pauljensen): This depends on Android framework implementation de tails. 706 // NOTE(pauljensen): This depends on Android framework implementation de tails.
699 // Fortunately this functionality is unlikely to ever change. 707 // Fortunately this functionality is unlikely to ever change.
700 // TODO(pauljensen): When we update to Android M SDK, use Network.getNet workHandle(). 708 // TODO(pauljensen): When we update to Android M SDK, use Network.getNet workHandle().
701 return Integer.parseInt(network.toString()); 709 return Integer.parseInt(network.toString());
702 } 710 }
703 } 711 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698