Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 #include "chrome/browser/chromeos/cros/network_library.h" | 5 #include "chrome/browser/chromeos/cros/network_library.h" |
| 6 | 6 |
| 7 #include <dbus/dbus-glib.h> | 7 #include <dbus/dbus-glib.h> |
| 8 #include <dbus/dbus-gtype-specialized.h> | 8 #include <dbus/dbus-gtype-specialized.h> |
| 9 #include <glib-object.h> | 9 #include <glib-object.h> |
| 10 | 10 |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 21 #include "base/json/json_writer.h" | 21 #include "base/json/json_writer.h" |
| 22 #include "base/metrics/histogram.h" | 22 #include "base/metrics/histogram.h" |
| 23 #include "base/stl_util.h" | 23 #include "base/stl_util.h" |
| 24 #include "base/string_number_conversions.h" | 24 #include "base/string_number_conversions.h" |
| 25 #include "base/string_tokenizer.h" | 25 #include "base/string_tokenizer.h" |
| 26 #include "base/string_util.h" | 26 #include "base/string_util.h" |
| 27 #include "base/stringprintf.h" | 27 #include "base/stringprintf.h" |
| 28 #include "base/utf_string_conversion_utils.h" | 28 #include "base/utf_string_conversion_utils.h" |
| 29 #include "base/utf_string_conversions.h" | 29 #include "base/utf_string_conversions.h" |
| 30 #include "base/values.h" | 30 #include "base/values.h" |
| 31 #include "chrome/browser/chromeos/cros_settings.h" | |
| 32 #include "chrome/browser/chromeos/cros/cros_library.h" | 31 #include "chrome/browser/chromeos/cros/cros_library.h" |
| 33 #include "chrome/browser/chromeos/cros/native_network_constants.h" | 32 #include "chrome/browser/chromeos/cros/native_network_constants.h" |
| 34 #include "chrome/browser/chromeos/cros/native_network_parser.h" | 33 #include "chrome/browser/chromeos/cros/native_network_parser.h" |
| 35 #include "chrome/browser/chromeos/cros/onc_network_parser.h" | 34 #include "chrome/browser/chromeos/cros/onc_network_parser.h" |
| 35 #include "chrome/browser/chromeos/cros_settings.h" | |
| 36 #include "chrome/browser/chromeos/network_login_observer.h" | 36 #include "chrome/browser/chromeos/network_login_observer.h" |
| 37 #include "chrome/common/time_format.h" | 37 #include "chrome/common/time_format.h" |
| 38 #include "content/public/browser/browser_thread.h" | 38 #include "content/public/browser/browser_thread.h" |
| 39 #include "crypto/nss_util.h" // crypto::GetTPMTokenInfo() for 802.1X and VPN. | 39 #include "crypto/nss_util.h" // crypto::GetTPMTokenInfo() for 802.1X and VPN. |
| 40 #include "grit/generated_resources.h" | 40 #include "grit/generated_resources.h" |
| 41 #include "third_party/cros_system_api/dbus/service_constants.h" | 41 #include "third_party/cros_system_api/dbus/service_constants.h" |
| 42 #include "ui/base/l10n/l10n_util.h" | 42 #include "ui/base/l10n/l10n_util.h" |
| 43 #include "ui/base/text/bytes_formatting.h" | 43 #include "ui/base/text/bytes_formatting.h" |
| 44 | 44 |
| 45 using content::BrowserThread; | 45 using content::BrowserThread; |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 335 void DumpDictionaryValue(const char* desc, const base::DictionaryValue* dict) { | 335 void DumpDictionaryValue(const char* desc, const base::DictionaryValue* dict) { |
| 336 std::string json; | 336 std::string json; |
| 337 base::JSONWriter::Write(dict, false, &json); | 337 base::JSONWriter::Write(dict, false, &json); |
| 338 LOG(WARNING) << desc << ": " << json; | 338 LOG(WARNING) << desc << ": " << json; |
| 339 } | 339 } |
| 340 | 340 |
| 341 } // namespace | 341 } // namespace |
| 342 | 342 |
| 343 // UI data keys. | 343 // UI data keys. |
| 344 const char kUIDataKeyONCSource[] = "onc_source"; | 344 const char kUIDataKeyONCSource[] = "onc_source"; |
| 345 const char kUIDataKeyProperties[] = "properties"; | |
| 346 const char kUIDataKeyPropertiesController[] = "controller"; | |
| 347 const char kUIDataKeyPropertiesControllerPolicy[] = "policy"; | |
| 348 const char kUIDataKeyPropertiesControllerUser[] = "user"; | |
| 349 const char kUIDataKeyPropertiesDefaultValue[] = "default_value"; | |
| 350 | |
| 351 const char kUIDataPropertyAutoConnect[] = "auto_connect"; | |
| 352 const char kUIDataPropertyPreferred[] = "preferred"; | |
| 353 | |
| 354 //////////////////////////////////////////////////////////////////////////////// | |
| 355 // NetworkPropertyUIData | |
| 356 | |
| 357 NetworkPropertyUIData::NetworkPropertyUIData() | |
| 358 : controller_(CONTROLLER_USER) {} | |
| 359 | |
| 360 void NetworkPropertyUIData::UpdateFromNetwork(const Network* network, | |
| 361 const char* property_key) { | |
| 362 // Initialize to defaults. | |
|
stevenjb
2011/11/29 07:23:19
This comment confused me, since setting controller
Mattias Nissler (ping if slow)
2011/11/29 14:48:50
You are right. I clarified the comment.
| |
| 363 controller_ = | |
| 364 network->IsManagedByPolicy() ? CONTROLLER_POLICY : CONTROLLER_USER; | |
| 365 default_value_.reset(); | |
| 366 | |
| 367 if (!property_key) | |
| 368 return; | |
| 369 | |
| 370 const DictionaryValue* ui_data = network->ui_data(); | |
| 371 if (!ui_data) | |
| 372 return; | |
| 373 | |
| 374 base::DictionaryValue* property_map = NULL; | |
| 375 if (!ui_data->GetDictionary(kUIDataKeyProperties, &property_map)) | |
| 376 return; | |
| 377 | |
| 378 base::DictionaryValue* property = NULL; | |
| 379 if (!property_map->GetDictionary(property_key, &property)) | |
| 380 return; | |
| 381 | |
| 382 std::string controller; | |
| 383 if (property->GetString(kUIDataKeyPropertiesController, &controller)) { | |
| 384 if (controller == kUIDataKeyPropertiesControllerPolicy) | |
| 385 controller_ = CONTROLLER_POLICY; | |
| 386 else if (controller == kUIDataKeyPropertiesControllerUser) | |
| 387 controller_ = CONTROLLER_USER; | |
| 388 } | |
| 389 | |
| 390 base::Value* default_value = NULL; | |
| 391 property->Get(kUIDataKeyPropertiesDefaultValue, &default_value); | |
| 392 default_value_.reset(default_value); | |
| 393 } | |
| 345 | 394 |
| 346 //////////////////////////////////////////////////////////////////////////////// | 395 //////////////////////////////////////////////////////////////////////////////// |
| 347 // FoundCellularNetwork | 396 // FoundCellularNetwork |
| 348 | 397 |
| 349 FoundCellularNetwork::FoundCellularNetwork() {} | 398 FoundCellularNetwork::FoundCellularNetwork() {} |
| 350 | 399 |
| 351 FoundCellularNetwork::~FoundCellularNetwork() {} | 400 FoundCellularNetwork::~FoundCellularNetwork() {} |
| 352 | 401 |
| 353 //////////////////////////////////////////////////////////////////////////////// | 402 //////////////////////////////////////////////////////////////////////////////// |
| 354 // NetworkDevice | 403 // NetworkDevice |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 457 unique_id_ = name_; | 506 unique_id_ = name_; |
| 458 } | 507 } |
| 459 | 508 |
| 460 bool Network::RequiresUserProfile() const { | 509 bool Network::RequiresUserProfile() const { |
| 461 return false; | 510 return false; |
| 462 } | 511 } |
| 463 | 512 |
| 464 void Network::CopyCredentialsFromRemembered(Network* remembered) { | 513 void Network::CopyCredentialsFromRemembered(Network* remembered) { |
| 465 } | 514 } |
| 466 | 515 |
| 516 bool Network::IsManagedByPolicy() const { | |
| 517 int source_value = 0; | |
| 518 if (ui_data()->GetInteger(chromeos::kUIDataKeyONCSource, &source_value)) { | |
| 519 chromeos::ONCSource source = static_cast<chromeos::ONCSource>(source_value); | |
| 520 return source == chromeos::ONC_SOURCE_DEVICE_POLICY || | |
| 521 source == chromeos::ONC_SOURCE_USER_POLICY; | |
| 522 } | |
| 523 | |
| 524 return false; | |
| 525 } | |
| 526 | |
| 527 void Network::GetUIDataForPreferred(NetworkPropertyUIData* ui_data) const { | |
| 528 ui_data->UpdateFromNetwork(this, kUIDataPropertyPreferred); | |
| 529 } | |
| 530 | |
| 531 void Network::GetUIDataForAutoConnect(NetworkPropertyUIData* ui_data) const { | |
| 532 ui_data->UpdateFromNetwork(this, kUIDataPropertyAutoConnect); | |
| 533 } | |
| 534 | |
| 535 void Network::GetUIDataForIPConfig(NetworkPropertyUIData* ui_data) const { | |
| 536 ui_data->UpdateFromNetwork(this, NULL); | |
| 537 } | |
| 538 | |
| 467 void Network::SetValueProperty(const char* prop, Value* value) { | 539 void Network::SetValueProperty(const char* prop, Value* value) { |
| 468 DCHECK(prop); | 540 DCHECK(prop); |
| 469 DCHECK(value); | 541 DCHECK(value); |
| 470 if (!EnsureCrosLoaded()) | 542 if (!EnsureCrosLoaded()) |
| 471 return; | 543 return; |
| 472 scoped_ptr<GValue> gvalue(ConvertValueToGValue(value)); | 544 scoped_ptr<GValue> gvalue(ConvertValueToGValue(value)); |
| 473 chromeos::SetNetworkServicePropertyGValue( | 545 chromeos::SetNetworkServicePropertyGValue( |
| 474 service_path_.c_str(), prop, gvalue.get()); | 546 service_path_.c_str(), prop, gvalue.get()); |
| 475 } | 547 } |
| 476 | 548 |
| (...skipping 4395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4872 (1 << TYPE_ETHERNET) | (1 << TYPE_WIFI) | (1 << TYPE_CELLULAR); | 4944 (1 << TYPE_ETHERNET) | (1 << TYPE_WIFI) | (1 << TYPE_CELLULAR); |
| 4873 available_devices_ = devices; | 4945 available_devices_ = devices; |
| 4874 enabled_devices_ = devices; | 4946 enabled_devices_ = devices; |
| 4875 connected_devices_ = devices; | 4947 connected_devices_ = devices; |
| 4876 | 4948 |
| 4877 NetworkDevice* cellular = new NetworkDevice("cellular"); | 4949 NetworkDevice* cellular = new NetworkDevice("cellular"); |
| 4878 cellular->type_ = TYPE_CELLULAR; | 4950 cellular->type_ = TYPE_CELLULAR; |
| 4879 cellular->imsi_ = "123456789012345"; | 4951 cellular->imsi_ = "123456789012345"; |
| 4880 device_map_["cellular"] = cellular; | 4952 device_map_["cellular"] = cellular; |
| 4881 | 4953 |
| 4954 CellularApn apn; | |
| 4955 apn.apn = "apn"; | |
| 4956 apn.network_id = "network_id"; | |
| 4957 apn.username = "username"; | |
| 4958 apn.password = "password"; | |
| 4959 apn.name = "name"; | |
| 4960 apn.localized_name = "localized_name"; | |
| 4961 apn.language = "language"; | |
| 4962 | |
| 4963 CellularApnList apn_list; | |
| 4964 apn_list.push_back(apn); | |
| 4965 | |
| 4966 NetworkDevice* cellular_gsm = new NetworkDevice("cellular_gsm"); | |
| 4967 cellular_gsm->type_ = TYPE_CELLULAR; | |
| 4968 cellular_gsm->set_technology_family(TECHNOLOGY_FAMILY_GSM); | |
| 4969 cellular_gsm->imsi_ = "123456789012345"; | |
| 4970 cellular_gsm->set_sim_pin_required(SIM_PIN_REQUIRED); | |
| 4971 cellular_gsm->set_provider_apn_list(apn_list); | |
| 4972 device_map_["cellular_gsm"] = cellular_gsm; | |
| 4973 | |
| 4882 // Profiles | 4974 // Profiles |
| 4883 AddProfile("default", PROFILE_SHARED); | 4975 AddProfile("default", PROFILE_SHARED); |
| 4884 AddProfile("user", PROFILE_USER); | 4976 AddProfile("user", PROFILE_USER); |
| 4885 | 4977 |
| 4886 // Networks | 4978 // Networks |
| 4887 // If these change, the expectations in network_library_unittest and | 4979 // If these change, the expectations in network_library_unittest and |
| 4888 // network_menu_icon_unittest need to be changed also. | 4980 // network_menu_icon_unittest need to be changed also. |
| 4889 | 4981 |
| 4890 // Networks are added in priority order. | 4982 // Networks are added in priority order. |
| 4891 network_priority_order_ = 0; | 4983 network_priority_order_ = 0; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4931 wifi5->SetSsid("Fake WiFi5 UTF-8 SSID \u3042\u3044\u3046"); | 5023 wifi5->SetSsid("Fake WiFi5 UTF-8 SSID \u3042\u3044\u3046"); |
| 4932 wifi5->set_strength(25); | 5024 wifi5->set_strength(25); |
| 4933 AddStubNetwork(wifi5, PROFILE_NONE); | 5025 AddStubNetwork(wifi5, PROFILE_NONE); |
| 4934 | 5026 |
| 4935 WifiNetwork* wifi6 = new WifiNetwork("wifi6"); | 5027 WifiNetwork* wifi6 = new WifiNetwork("wifi6"); |
| 4936 wifi6->set_name("Fake WiFi6 latin-1 SSID "); | 5028 wifi6->set_name("Fake WiFi6 latin-1 SSID "); |
| 4937 wifi6->SetSsid("Fake WiFi6 latin-1 SSID \xc0\xcb\xcc\xd6\xfb"); | 5029 wifi6->SetSsid("Fake WiFi6 latin-1 SSID \xc0\xcb\xcc\xd6\xfb"); |
| 4938 wifi6->set_strength(20); | 5030 wifi6->set_strength(20); |
| 4939 AddStubNetwork(wifi6, PROFILE_NONE); | 5031 AddStubNetwork(wifi6, PROFILE_NONE); |
| 4940 | 5032 |
| 5033 WifiNetwork* wifi7 = new WifiNetwork("wifi7"); | |
| 5034 wifi7->set_name("Fake Wifi7 (policy-managed)"); | |
| 5035 wifi7->ui_data()->SetInteger("onc_source", ONC_SOURCE_DEVICE_POLICY); | |
| 5036 AddStubNetwork(wifi7, PROFILE_USER); | |
| 5037 | |
| 4941 CellularNetwork* cellular1 = new CellularNetwork("cellular1"); | 5038 CellularNetwork* cellular1 = new CellularNetwork("cellular1"); |
| 4942 cellular1->set_name("Fake Cellular1"); | 5039 cellular1->set_name("Fake Cellular 1"); |
| 4943 cellular1->set_strength(100); | 5040 cellular1->set_strength(100); |
| 4944 cellular1->set_connected(true); | 5041 cellular1->set_connected(true); |
| 4945 cellular1->set_activation_state(ACTIVATION_STATE_ACTIVATED); | 5042 cellular1->set_activation_state(ACTIVATION_STATE_ACTIVATED); |
| 4946 cellular1->set_payment_url(std::string("http://www.google.com")); | 5043 cellular1->set_payment_url(std::string("http://www.google.com")); |
| 4947 cellular1->set_usage_url(std::string("http://www.google.com")); | 5044 cellular1->set_usage_url(std::string("http://www.google.com")); |
| 4948 cellular1->set_network_technology(NETWORK_TECHNOLOGY_EVDO); | 5045 cellular1->set_network_technology(NETWORK_TECHNOLOGY_EVDO); |
| 4949 AddStubNetwork(cellular1, PROFILE_NONE); | 5046 AddStubNetwork(cellular1, PROFILE_NONE); |
| 4950 | 5047 |
| 4951 CellularNetwork* cellular2 = new CellularNetwork("cellular2"); | 5048 CellularNetwork* cellular2 = new CellularNetwork("cellular2"); |
| 4952 cellular2->set_name("Fake Cellular2"); | 5049 cellular2->set_name("Fake Cellular 2"); |
| 4953 cellular2->set_strength(50); | 5050 cellular2->set_strength(50); |
| 4954 cellular2->set_activation_state(ACTIVATION_STATE_NOT_ACTIVATED); | 5051 cellular2->set_activation_state(ACTIVATION_STATE_NOT_ACTIVATED); |
| 4955 cellular2->set_network_technology(NETWORK_TECHNOLOGY_UMTS); | 5052 cellular2->set_network_technology(NETWORK_TECHNOLOGY_UMTS); |
| 4956 cellular2->set_roaming_state(ROAMING_STATE_ROAMING); | 5053 cellular2->set_roaming_state(ROAMING_STATE_ROAMING); |
| 4957 AddStubNetwork(cellular2, PROFILE_NONE); | 5054 AddStubNetwork(cellular2, PROFILE_NONE); |
| 4958 | 5055 |
| 5056 CellularNetwork* cellular3 = new CellularNetwork("cellular3"); | |
| 5057 cellular3->set_name("Fake Cellular 3 (policy-managed)"); | |
| 5058 cellular3->set_device_path(cellular->device_path()); | |
| 5059 cellular3->set_activation_state(ACTIVATION_STATE_ACTIVATED); | |
| 5060 cellular3->set_network_technology(NETWORK_TECHNOLOGY_EVDO); | |
| 5061 cellular3->ui_data()->SetInteger("onc_source", ONC_SOURCE_USER_POLICY); | |
| 5062 AddStubNetwork(cellular3, PROFILE_NONE); | |
| 5063 | |
| 5064 CellularNetwork* cellular4 = new CellularNetwork("cellular4"); | |
| 5065 cellular4->set_name("Fake Cellular 4 (policy-managed)"); | |
| 5066 cellular4->set_device_path(cellular_gsm->device_path()); | |
| 5067 cellular4->set_activation_state(ACTIVATION_STATE_ACTIVATED); | |
| 5068 cellular4->set_network_technology(NETWORK_TECHNOLOGY_GSM); | |
| 5069 cellular4->ui_data()->SetInteger("onc_source", ONC_SOURCE_USER_POLICY); | |
| 5070 AddStubNetwork(cellular4, PROFILE_NONE); | |
| 5071 | |
| 4959 CellularDataPlan* base_plan = new CellularDataPlan(); | 5072 CellularDataPlan* base_plan = new CellularDataPlan(); |
| 4960 base_plan->plan_name = "Base plan"; | 5073 base_plan->plan_name = "Base plan"; |
| 4961 base_plan->plan_type = CELLULAR_DATA_PLAN_METERED_BASE; | 5074 base_plan->plan_type = CELLULAR_DATA_PLAN_METERED_BASE; |
| 4962 base_plan->plan_data_bytes = 100ll * 1024 * 1024; | 5075 base_plan->plan_data_bytes = 100ll * 1024 * 1024; |
| 4963 base_plan->data_bytes_used = base_plan->plan_data_bytes / 4; | 5076 base_plan->data_bytes_used = base_plan->plan_data_bytes / 4; |
| 4964 | 5077 |
| 4965 CellularDataPlan* paid_plan = new CellularDataPlan(); | 5078 CellularDataPlan* paid_plan = new CellularDataPlan(); |
| 4966 paid_plan->plan_name = "Paid plan"; | 5079 paid_plan->plan_name = "Paid plan"; |
| 4967 paid_plan->plan_type = CELLULAR_DATA_PLAN_METERED_PAID; | 5080 paid_plan->plan_type = CELLULAR_DATA_PLAN_METERED_PAID; |
| 4968 paid_plan->plan_data_bytes = 5ll * 1024 * 1024 * 1024; | 5081 paid_plan->plan_data_bytes = 5ll * 1024 * 1024 * 1024; |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 4986 vpn2->set_provider_type(PROVIDER_TYPE_L2TP_IPSEC_USER_CERT); | 5099 vpn2->set_provider_type(PROVIDER_TYPE_L2TP_IPSEC_USER_CERT); |
| 4987 vpn2->set_username("VPN User 2"); | 5100 vpn2->set_username("VPN User 2"); |
| 4988 AddStubNetwork(vpn2, PROFILE_USER); | 5101 AddStubNetwork(vpn2, PROFILE_USER); |
| 4989 | 5102 |
| 4990 VirtualNetwork* vpn3 = new VirtualNetwork("vpn3"); | 5103 VirtualNetwork* vpn3 = new VirtualNetwork("vpn3"); |
| 4991 vpn3->set_name("Fake VPN3"); | 5104 vpn3->set_name("Fake VPN3"); |
| 4992 vpn3->set_server_hostname("vpn3server.fake.com"); | 5105 vpn3->set_server_hostname("vpn3server.fake.com"); |
| 4993 vpn3->set_provider_type(PROVIDER_TYPE_OPEN_VPN); | 5106 vpn3->set_provider_type(PROVIDER_TYPE_OPEN_VPN); |
| 4994 AddStubNetwork(vpn3, PROFILE_USER); | 5107 AddStubNetwork(vpn3, PROFILE_USER); |
| 4995 | 5108 |
| 5109 VirtualNetwork* vpn4 = new VirtualNetwork("vpn4"); | |
| 5110 vpn4->set_name("Fake VPN4 (policy-managed)"); | |
| 5111 vpn4->set_server_hostname("vpn4server.fake.com"); | |
| 5112 vpn4->set_provider_type(PROVIDER_TYPE_OPEN_VPN); | |
| 5113 vpn4->ui_data()->SetInteger("onc_source", ONC_SOURCE_DEVICE_POLICY); | |
| 5114 AddStubNetwork(vpn4, PROFILE_USER); | |
|
stevenjb
2011/11/29 07:23:19
Make sure that these changes don't break the unit
Mattias Nissler (ping if slow)
2011/11/29 14:48:50
Done.
| |
| 5115 | |
| 4996 wifi_scanning_ = false; | 5116 wifi_scanning_ = false; |
| 4997 offline_mode_ = false; | 5117 offline_mode_ = false; |
| 4998 | 5118 |
| 4999 // Ensure our active network is connected and vice versa, otherwise our | 5119 // Ensure our active network is connected and vice versa, otherwise our |
| 5000 // autotest browser_tests sometimes conclude the device is offline. | 5120 // autotest browser_tests sometimes conclude the device is offline. |
| 5001 CHECK(active_network()->connected()); | 5121 CHECK(active_network()->connected()); |
| 5002 CHECK(connected_network()->is_active()); | 5122 CHECK(connected_network()->is_active()); |
| 5003 } | 5123 } |
| 5004 | 5124 |
| 5005 //////////////////////////////////////////////////////////////////////////// | 5125 //////////////////////////////////////////////////////////////////////////// |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5240 return impl; | 5360 return impl; |
| 5241 } | 5361 } |
| 5242 | 5362 |
| 5243 ///////////////////////////////////////////////////////////////////////////// | 5363 ///////////////////////////////////////////////////////////////////////////// |
| 5244 | 5364 |
| 5245 } // namespace chromeos | 5365 } // namespace chromeos |
| 5246 | 5366 |
| 5247 // Allows InvokeLater without adding refcounting. This class is a Singleton and | 5367 // Allows InvokeLater without adding refcounting. This class is a Singleton and |
| 5248 // won't be deleted until its last InvokeLater is run. | 5368 // won't be deleted until its last InvokeLater is run. |
| 5249 DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::NetworkLibraryImplBase); | 5369 DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::NetworkLibraryImplBase); |
| OLD | NEW |