OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 <map> | 5 #include <map> |
6 #include <string> | 6 #include <string> |
7 | 7 |
8 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" |
10 #include "base/callback.h" | 11 #include "base/callback.h" |
11 #include "base/command_line.h" | 12 #include "base/command_line.h" |
12 #include "base/file_util.h" | 13 #include "base/file_util.h" |
13 #include "base/files/file_path.h" | 14 #include "base/files/file_path.h" |
14 #include "base/json/json_reader.h" | 15 #include "base/json/json_reader.h" |
15 #include "base/memory/scoped_ptr.h" | 16 #include "base/memory/scoped_ptr.h" |
16 #include "base/message_loop/message_loop.h" | 17 #include "base/message_loop/message_loop.h" |
17 #include "base/path_service.h" | 18 #include "base/path_service.h" |
18 #include "base/run_loop.h" | 19 #include "base/run_loop.h" |
19 #include "base/strings/string_util.h" | 20 #include "base/strings/string_util.h" |
| 21 #include "base/strings/stringprintf.h" |
20 #include "base/strings/utf_string_conversions.h" | 22 #include "base/strings/utf_string_conversions.h" |
21 #include "base/values.h" | 23 #include "base/values.h" |
22 #include "chrome/browser/browser_process.h" | 24 #include "chrome/browser/browser_process.h" |
23 #include "chrome/browser/chrome_notification_types.h" | 25 #include "chrome/browser/chrome_notification_types.h" |
24 #include "chrome/browser/chromeos/login/existing_user_controller.h" | 26 #include "chrome/browser/chromeos/login/existing_user_controller.h" |
25 #include "chrome/browser/chromeos/login/login_display_host.h" | 27 #include "chrome/browser/chromeos/login/login_display_host.h" |
26 #include "chrome/browser/chromeos/login/login_display_host_impl.h" | 28 #include "chrome/browser/chromeos/login/login_display_host_impl.h" |
27 #include "chrome/browser/chromeos/login/mock_login_status_consumer.h" | 29 #include "chrome/browser/chromeos/login/mock_login_status_consumer.h" |
28 #include "chrome/browser/chromeos/login/screens/wizard_screen.h" | 30 #include "chrome/browser/chromeos/login/screens/wizard_screen.h" |
29 #include "chrome/browser/chromeos/login/user.h" | 31 #include "chrome/browser/chromeos/login/user.h" |
30 #include "chrome/browser/chromeos/login/user_manager.h" | 32 #include "chrome/browser/chromeos/login/user_manager.h" |
31 #include "chrome/browser/chromeos/login/webui_login_view.h" | 33 #include "chrome/browser/chromeos/login/webui_login_view.h" |
32 #include "chrome/browser/chromeos/login/wizard_controller.h" | 34 #include "chrome/browser/chromeos/login/wizard_controller.h" |
33 #include "chrome/browser/chromeos/policy/device_local_account.h" | 35 #include "chrome/browser/chromeos/policy/device_local_account.h" |
34 #include "chrome/browser/chromeos/policy/device_policy_builder.h" | 36 #include "chrome/browser/chromeos/policy/device_policy_builder.h" |
35 #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h" | 37 #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h" |
| 38 #include "chrome/browser/extensions/extension_service.h" |
| 39 #include "chrome/browser/extensions/extension_system.h" |
36 #include "chrome/browser/lifetime/application_lifetime.h" | 40 #include "chrome/browser/lifetime/application_lifetime.h" |
37 #include "chrome/browser/policy/cloud/cloud_policy_constants.h" | 41 #include "chrome/browser/policy/cloud/cloud_policy_constants.h" |
38 #include "chrome/browser/policy/cloud/policy_builder.h" | 42 #include "chrome/browser/policy/cloud/policy_builder.h" |
39 #include "chrome/browser/policy/policy_service.h" | 43 #include "chrome/browser/policy/policy_service.h" |
40 #include "chrome/browser/policy/proto/chromeos/chrome_device_policy.pb.h" | 44 #include "chrome/browser/policy/proto/chromeos/chrome_device_policy.pb.h" |
41 #include "chrome/browser/policy/test/local_policy_test_server.h" | 45 #include "chrome/browser/policy/test/local_policy_test_server.h" |
42 #include "chrome/browser/prefs/session_startup_pref.h" | 46 #include "chrome/browser/prefs/session_startup_pref.h" |
43 #include "chrome/browser/profiles/profile.h" | 47 #include "chrome/browser/profiles/profile.h" |
44 #include "chrome/browser/profiles/profile_manager.h" | 48 #include "chrome/browser/profiles/profile_manager.h" |
45 #include "chrome/browser/ui/browser.h" | 49 #include "chrome/browser/ui/browser.h" |
46 #include "chrome/browser/ui/browser_commands.h" | 50 #include "chrome/browser/ui/browser_commands.h" |
47 #include "chrome/browser/ui/browser_finder.h" | 51 #include "chrome/browser/ui/browser_finder.h" |
48 #include "chrome/browser/ui/browser_list.h" | 52 #include "chrome/browser/ui/browser_list.h" |
49 #include "chrome/browser/ui/browser_window.h" | 53 #include "chrome/browser/ui/browser_window.h" |
50 #include "chrome/browser/ui/host_desktop.h" | 54 #include "chrome/browser/ui/host_desktop.h" |
51 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 55 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
52 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" | 56 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" |
53 #include "chrome/common/chrome_paths.h" | 57 #include "chrome/common/chrome_paths.h" |
54 #include "chrome/common/chrome_switches.h" | 58 #include "chrome/common/chrome_switches.h" |
| 59 #include "chrome/common/extensions/extension.h" |
55 #include "chromeos/chromeos_switches.h" | 60 #include "chromeos/chromeos_switches.h" |
56 #include "chromeos/dbus/cryptohome_client.h" | 61 #include "chromeos/dbus/cryptohome_client.h" |
57 #include "chromeos/dbus/dbus_method_call_status.h" | 62 #include "chromeos/dbus/dbus_method_call_status.h" |
58 #include "chromeos/dbus/fake_session_manager_client.h" | 63 #include "chromeos/dbus/fake_session_manager_client.h" |
59 #include "chromeos/dbus/session_manager_client.h" | 64 #include "chromeos/dbus/session_manager_client.h" |
| 65 #include "content/public/browser/notification_details.h" |
| 66 #include "content/public/browser/notification_source.h" |
60 #include "content/public/browser/web_contents.h" | 67 #include "content/public/browser/web_contents.h" |
61 #include "content/public/browser/web_ui.h" | 68 #include "content/public/browser/web_ui.h" |
62 #include "content/public/test/browser_test_utils.h" | 69 #include "content/public/test/browser_test_utils.h" |
63 #include "content/public/test/test_utils.h" | 70 #include "content/public/test/test_utils.h" |
64 #include "crypto/rsa_private_key.h" | 71 #include "crypto/rsa_private_key.h" |
65 #include "grit/chromium_strings.h" | 72 #include "grit/chromium_strings.h" |
66 #include "grit/generated_resources.h" | 73 #include "grit/generated_resources.h" |
| 74 #include "net/base/url_util.h" |
| 75 #include "net/http/http_status_code.h" |
67 #include "net/test/embedded_test_server/embedded_test_server.h" | 76 #include "net/test/embedded_test_server/embedded_test_server.h" |
| 77 #include "net/test/embedded_test_server/http_request.h" |
| 78 #include "net/test/embedded_test_server/http_response.h" |
68 #include "testing/gmock/include/gmock/gmock.h" | 79 #include "testing/gmock/include/gmock/gmock.h" |
69 #include "third_party/cros_system_api/dbus/service_constants.h" | 80 #include "third_party/cros_system_api/dbus/service_constants.h" |
70 #include "ui/base/l10n/l10n_util.h" | 81 #include "ui/base/l10n/l10n_util.h" |
71 #include "url/gurl.h" | 82 #include "url/gurl.h" |
72 | 83 |
73 namespace em = enterprise_management; | 84 namespace em = enterprise_management; |
74 | 85 |
75 using testing::InvokeWithoutArgs; | 86 using testing::InvokeWithoutArgs; |
76 using testing::Return; | 87 using testing::Return; |
77 using testing::_; | 88 using testing::_; |
78 | 89 |
79 namespace policy { | 90 namespace policy { |
80 | 91 |
81 namespace { | 92 namespace { |
82 | 93 |
83 const char kDomain[] = "example.com"; | 94 const char kDomain[] = "example.com"; |
84 const char kAccountId1[] = "dla1@example.com"; | 95 const char kAccountId1[] = "dla1@example.com"; |
85 const char kAccountId2[] = "dla2@example.com"; | 96 const char kAccountId2[] = "dla2@example.com"; |
86 const char kDisplayName[] = "display name"; | 97 const char kDisplayName[] = "display name"; |
87 const char* kStartupURLs[] = { | 98 const char* kStartupURLs[] = { |
88 "chrome://policy", | 99 "chrome://policy", |
89 "chrome://about", | 100 "chrome://about", |
90 }; | 101 }; |
91 const char kExistentTermsOfServicePath[] = "chromeos/enterprise/tos.txt"; | 102 const char kExistentTermsOfServicePath[] = "chromeos/enterprise/tos.txt"; |
92 const char kNonexistentTermsOfServicePath[] = "chromeos/enterprise/tos404.txt"; | 103 const char kNonexistentTermsOfServicePath[] = "chromeos/enterprise/tos404.txt"; |
| 104 const char kRelativeUpdateURL[] = "/service/update2/crx"; |
| 105 const char kUpdateManifestHeader[] = |
| 106 "<?xml version='1.0' encoding='UTF-8'?>\n" |
| 107 "<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>\n"; |
| 108 const char kUpdateManifestTemplate[] = |
| 109 " <app appid='%s'>\n" |
| 110 " <updatecheck codebase='%s' version='%s' />\n" |
| 111 " </app>\n"; |
| 112 const char kUpdateManifestFooter[] = |
| 113 "</gupdate>\n"; |
| 114 const char kHostedAppID[] = "kbmnembihfiondgfjekmnmcbddelicoi"; |
| 115 const char kHostedAppCRXPath[] = "extensions/hosted_app.crx"; |
| 116 const char kHostedAppVersion[] = "0.1"; |
| 117 const char kGoodExtensionID[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf"; |
| 118 const char kGoodExtensionPath[] = "extensions/good.crx"; |
| 119 const char kGoodExtensionVersion[] = "1.0"; |
| 120 |
| 121 // Helper that serves extension update manifests to Chrome. |
| 122 class TestingUpdateManifestProvider { |
| 123 public: |
| 124 |
| 125 // Update manifests will be served at |relative_update_url|. |
| 126 explicit TestingUpdateManifestProvider( |
| 127 const std::string& relative_update_url); |
| 128 ~TestingUpdateManifestProvider(); |
| 129 |
| 130 // When an update manifest is requested for the given extension |id|, indicate |
| 131 // that |version| of the extension can be downloaded at |crx_url|. |
| 132 void AddUpdate(const std::string& id, |
| 133 const std::string& version, |
| 134 const GURL& crx_url); |
| 135 |
| 136 // This method must be registered with the test's EmbeddedTestServer to start |
| 137 // serving update manifests. |
| 138 scoped_ptr<net::test_server::HttpResponse> HandleRequest( |
| 139 const net::test_server::HttpRequest& request); |
| 140 |
| 141 private: |
| 142 struct Update { |
| 143 public: |
| 144 Update(const std::string& version, const GURL& crx_url); |
| 145 Update(); |
| 146 |
| 147 std::string version; |
| 148 GURL crx_url; |
| 149 }; |
| 150 typedef std::map<std::string, Update> UpdateMap; |
| 151 UpdateMap updates_; |
| 152 |
| 153 const std::string relative_update_url_; |
| 154 |
| 155 DISALLOW_COPY_AND_ASSIGN(TestingUpdateManifestProvider); |
| 156 }; |
| 157 |
| 158 TestingUpdateManifestProvider::Update::Update(const std::string& version, |
| 159 const GURL& crx_url) |
| 160 : version(version), |
| 161 crx_url(crx_url) { |
| 162 } |
| 163 |
| 164 TestingUpdateManifestProvider::Update::Update() { |
| 165 } |
| 166 |
| 167 TestingUpdateManifestProvider::TestingUpdateManifestProvider( |
| 168 const std::string& relative_update_url) |
| 169 : relative_update_url_(relative_update_url) { |
| 170 } |
| 171 |
| 172 TestingUpdateManifestProvider::~TestingUpdateManifestProvider() { |
| 173 } |
| 174 |
| 175 void TestingUpdateManifestProvider::AddUpdate(const std::string& id, |
| 176 const std::string& version, |
| 177 const GURL& crx_url) { |
| 178 updates_[id] = Update(version, crx_url); |
| 179 } |
| 180 |
| 181 scoped_ptr<net::test_server::HttpResponse> |
| 182 TestingUpdateManifestProvider::HandleRequest( |
| 183 const net::test_server::HttpRequest& request) { |
| 184 const GURL url("http://localhost" + request.relative_url); |
| 185 if (url.path() != relative_update_url_) |
| 186 return scoped_ptr<net::test_server::HttpResponse>(); |
| 187 |
| 188 std::string content = kUpdateManifestHeader; |
| 189 for (net::QueryIterator it(url); !it.IsAtEnd(); it.Advance()) { |
| 190 if (it.GetKey() != "x") |
| 191 continue; |
| 192 // Extract the extension id from the subquery. Since GetValueForKeyInQuery() |
| 193 // expects a complete URL, dummy scheme and host must be prepended. |
| 194 std::string id; |
| 195 net::GetValueForKeyInQuery(GURL("http://dummy?" + it.GetUnescapedValue()), |
| 196 "id", &id); |
| 197 UpdateMap::const_iterator entry = updates_.find(id); |
| 198 if (entry != updates_.end()) { |
| 199 content += base::StringPrintf(kUpdateManifestTemplate, |
| 200 id.c_str(), |
| 201 entry->second.crx_url.spec().c_str(), |
| 202 entry->second.version.c_str()); |
| 203 } |
| 204 } |
| 205 content += kUpdateManifestFooter; |
| 206 scoped_ptr<net::test_server::BasicHttpResponse> |
| 207 http_response(new net::test_server::BasicHttpResponse); |
| 208 http_response->set_code(net::HTTP_OK); |
| 209 http_response->set_content(content); |
| 210 http_response->set_content_type("text/xml"); |
| 211 return http_response.PassAs<net::test_server::HttpResponse>(); |
| 212 } |
| 213 |
| 214 bool DoesInstallSuccessReferToId(const std::string& id, |
| 215 const content::NotificationSource& source, |
| 216 const content::NotificationDetails& details) { |
| 217 return content::Details<const extensions::InstalledExtensionInfo>(details)-> |
| 218 extension->id() == id; |
| 219 } |
| 220 |
| 221 bool DoesInstallFailureReferToId(const std::string& id, |
| 222 const content::NotificationSource& source, |
| 223 const content::NotificationDetails& details) { |
| 224 return content::Details<const string16>(details)->find(UTF8ToUTF16(id)) != |
| 225 string16::npos; |
| 226 } |
93 | 227 |
94 } // namespace | 228 } // namespace |
95 | 229 |
96 class DeviceLocalAccountTest : public DevicePolicyCrosBrowserTest { | 230 class DeviceLocalAccountTest : public DevicePolicyCrosBrowserTest { |
97 protected: | 231 protected: |
98 DeviceLocalAccountTest() | 232 DeviceLocalAccountTest() |
99 : user_id_1_(GenerateDeviceLocalAccountUserId( | 233 : user_id_1_(GenerateDeviceLocalAccountUserId( |
100 kAccountId1, DeviceLocalAccount::TYPE_PUBLIC_SESSION)), | 234 kAccountId1, DeviceLocalAccount::TYPE_PUBLIC_SESSION)), |
101 user_id_2_(GenerateDeviceLocalAccountUserId( | 235 user_id_2_(GenerateDeviceLocalAccountUserId( |
102 kAccountId2, DeviceLocalAccount::TYPE_PUBLIC_SESSION)) {} | 236 kAccountId2, DeviceLocalAccount::TYPE_PUBLIC_SESSION)) {} |
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
413 BrowserWindow* browser_window = browser->window(); | 547 BrowserWindow* browser_window = browser->window(); |
414 ASSERT_TRUE(browser_window); | 548 ASSERT_TRUE(browser_window); |
415 chrome::EndKeepAlive(); | 549 chrome::EndKeepAlive(); |
416 | 550 |
417 // Verify that an attempt to enter fullscreen mode is denied. | 551 // Verify that an attempt to enter fullscreen mode is denied. |
418 EXPECT_FALSE(browser_window->IsFullscreen()); | 552 EXPECT_FALSE(browser_window->IsFullscreen()); |
419 chrome::ToggleFullscreenMode(browser); | 553 chrome::ToggleFullscreenMode(browser); |
420 EXPECT_FALSE(browser_window->IsFullscreen()); | 554 EXPECT_FALSE(browser_window->IsFullscreen()); |
421 } | 555 } |
422 | 556 |
| 557 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, ExtensionWhitelist) { |
| 558 // Make it possible to force-install a hosted app and an extension. |
| 559 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); |
| 560 TestingUpdateManifestProvider testing_update_manifest_provider( |
| 561 kRelativeUpdateURL); |
| 562 testing_update_manifest_provider.AddUpdate( |
| 563 kHostedAppID, |
| 564 kHostedAppVersion, |
| 565 embedded_test_server()->GetURL(std::string("/") + kHostedAppCRXPath)); |
| 566 testing_update_manifest_provider.AddUpdate( |
| 567 kGoodExtensionID, |
| 568 kGoodExtensionVersion, |
| 569 embedded_test_server()->GetURL(std::string("/") + kGoodExtensionPath)); |
| 570 embedded_test_server()->RegisterRequestHandler( |
| 571 base::Bind(&TestingUpdateManifestProvider::HandleRequest, |
| 572 base::Unretained(&testing_update_manifest_provider))); |
| 573 |
| 574 // Specify policy to force-install the hosted app and the extension. |
| 575 em::StringList* forcelist = device_local_account_policy_.payload() |
| 576 .mutable_extensioninstallforcelist()->mutable_value(); |
| 577 forcelist->add_entries(base::StringPrintf( |
| 578 "%s;%s", |
| 579 kHostedAppID, |
| 580 embedded_test_server()->GetURL(kRelativeUpdateURL).spec().c_str())); |
| 581 forcelist->add_entries(base::StringPrintf( |
| 582 "%s;%s", |
| 583 kGoodExtensionID, |
| 584 embedded_test_server()->GetURL(kRelativeUpdateURL).spec().c_str())); |
| 585 |
| 586 UploadAndInstallDeviceLocalAccountPolicy(); |
| 587 AddPublicSessionToDevicePolicy(kAccountId1); |
| 588 |
| 589 // This observes the display name becoming available as this indicates |
| 590 // device-local account policy is fully loaded, which is a prerequisite for |
| 591 // successful login. |
| 592 content::WindowedNotificationObserver( |
| 593 chrome::NOTIFICATION_USER_LIST_CHANGED, |
| 594 base::Bind(&DisplayNameMatches, user_id_1_, kDisplayName)).Wait(); |
| 595 |
| 596 // Wait for the login UI to be ready. |
| 597 chromeos::LoginDisplayHostImpl* host = |
| 598 reinterpret_cast<chromeos::LoginDisplayHostImpl*>( |
| 599 chromeos::LoginDisplayHostImpl::default_host()); |
| 600 ASSERT_TRUE(host); |
| 601 chromeos::OobeUI* oobe_ui = host->GetOobeUI(); |
| 602 ASSERT_TRUE(oobe_ui); |
| 603 base::RunLoop run_loop; |
| 604 const bool oobe_ui_ready = oobe_ui->IsJSReady(run_loop.QuitClosure()); |
| 605 if (!oobe_ui_ready) |
| 606 run_loop.Run(); |
| 607 |
| 608 // Ensure that the browser stays alive, even though no windows are opened |
| 609 // during session start. |
| 610 chrome::StartKeepAlive(); |
| 611 |
| 612 // Start listening for app/extension installation results. |
| 613 content::WindowedNotificationObserver hosted_app_observer( |
| 614 chrome::NOTIFICATION_EXTENSION_INSTALLED, |
| 615 base::Bind(DoesInstallSuccessReferToId, kHostedAppID)); |
| 616 content::WindowedNotificationObserver extension_observer( |
| 617 chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR, |
| 618 base::Bind(DoesInstallFailureReferToId, kGoodExtensionID)); |
| 619 |
| 620 // Start login into the device-local account. |
| 621 host->StartSignInScreen(); |
| 622 chromeos::ExistingUserController* controller = |
| 623 chromeos::ExistingUserController::current_controller(); |
| 624 ASSERT_TRUE(controller); |
| 625 controller->LoginAsPublicAccount(user_id_1_); |
| 626 |
| 627 // Wait for the hosted app installation to succeed and the extension |
| 628 // installation to fail. |
| 629 hosted_app_observer.Wait(); |
| 630 extension_observer.Wait(); |
| 631 |
| 632 // Verify that the hosted app was installed. |
| 633 Profile* profile = ProfileManager::GetDefaultProfile(); |
| 634 ASSERT_TRUE(profile); |
| 635 ExtensionService* extension_service = |
| 636 extensions::ExtensionSystem::Get(profile)->extension_service(); |
| 637 EXPECT_TRUE(extension_service->GetExtensionById(kHostedAppID, true)); |
| 638 |
| 639 // Verify that the extension was not installed. |
| 640 EXPECT_FALSE(extension_service->GetExtensionById(kGoodExtensionID, true)); |
| 641 } |
| 642 |
423 class TermsOfServiceTest : public DeviceLocalAccountTest, | 643 class TermsOfServiceTest : public DeviceLocalAccountTest, |
424 public testing::WithParamInterface<bool> { | 644 public testing::WithParamInterface<bool> { |
425 }; | 645 }; |
426 | 646 |
427 IN_PROC_BROWSER_TEST_P(TermsOfServiceTest, TermsOfServiceScreen) { | 647 IN_PROC_BROWSER_TEST_P(TermsOfServiceTest, TermsOfServiceScreen) { |
428 // Specify Terms of Service URL. | 648 // Specify Terms of Service URL. |
429 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); | 649 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); |
430 device_local_account_policy_.payload().mutable_termsofserviceurl()->set_value( | 650 device_local_account_policy_.payload().mutable_termsofserviceurl()->set_value( |
431 embedded_test_server()->GetURL( | 651 embedded_test_server()->GetURL( |
432 std::string("/") + | 652 std::string("/") + |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
574 if (!IsSessionStarted()) { | 794 if (!IsSessionStarted()) { |
575 content::WindowedNotificationObserver(chrome::NOTIFICATION_SESSION_STARTED, | 795 content::WindowedNotificationObserver(chrome::NOTIFICATION_SESSION_STARTED, |
576 base::Bind(IsSessionStarted)).Wait(); | 796 base::Bind(IsSessionStarted)).Wait(); |
577 } | 797 } |
578 } | 798 } |
579 | 799 |
580 INSTANTIATE_TEST_CASE_P(TermsOfServiceTestInstance, | 800 INSTANTIATE_TEST_CASE_P(TermsOfServiceTestInstance, |
581 TermsOfServiceTest, testing::Bool()); | 801 TermsOfServiceTest, testing::Bool()); |
582 | 802 |
583 } // namespace policy | 803 } // namespace policy |
OLD | NEW |