1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/common/chrome_content_client.h"
6
7 #include <string>
8
9 #include "base/strings/string_split.h"
10 #include "base/strings/string_util.h"
11 #include "base/test/scoped_command_line.h"
12 #include "base/threading/platform_thread.h"
13 #include "build/build_config.h"
14 #include "content/public/common/content_switches.h"
15 #include "content/public/common/origin_util.h"
16 #include "content/public/test/test_utils.h"
17 #include "extensions/common/constants.h"
18 #include "ppapi/buildflags/buildflags.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "third_party/blink/public/common/loader/network_utils.h"
21 #include "url/gurl.h"
22 #include "url/origin.h"
23 #include "url/url_util.h"
24
25 namespace chrome_common {
26
27 #if BUILDFLAG(ENABLE_PLUGINS)
TEST(ChromeContentClientTest,FindMostRecent)28 TEST(ChromeContentClientTest, FindMostRecent) {
29 std::vector<std::unique_ptr<content::PepperPluginInfo>> version_vector;
30 // Test an empty vector.
31 EXPECT_EQ(nullptr, ChromeContentClient::FindMostRecentPlugin(version_vector));
32
33 // Now test the vector with one element.
34 content::PepperPluginInfo info;
35 info.version = "1.0.0.0";
36 version_vector.push_back(std::make_unique<content::PepperPluginInfo>(info));
37
38 content::PepperPluginInfo* most_recent =
39 ChromeContentClient::FindMostRecentPlugin(version_vector);
40 EXPECT_EQ("1.0.0.0", most_recent->version);
41
42 content::PepperPluginInfo info5;
43 info5.version = "5.0.12.1";
44 content::PepperPluginInfo info6_12;
45 info6_12.version = "6.0.0.12";
46 content::PepperPluginInfo info6_13;
47 info6_13.version = "6.0.0.13";
48
49 // Test highest version is picked.
50 version_vector.clear();
51 version_vector.push_back(std::make_unique<content::PepperPluginInfo>(info5));
52 version_vector.push_back(
53 std::make_unique<content::PepperPluginInfo>(info6_12));
54 version_vector.push_back(
55 std::make_unique<content::PepperPluginInfo>(info6_13));
56
57 most_recent = ChromeContentClient::FindMostRecentPlugin(version_vector);
58 EXPECT_EQ("6.0.0.13", most_recent->version);
59
60 // Test that order does not matter, validates tests below.
61 version_vector.clear();
62 version_vector.push_back(
63 std::make_unique<content::PepperPluginInfo>(info6_13));
64 version_vector.push_back(
65 std::make_unique<content::PepperPluginInfo>(info6_12));
66 version_vector.push_back(std::make_unique<content::PepperPluginInfo>(info5));
67
68 most_recent = ChromeContentClient::FindMostRecentPlugin(version_vector);
69 EXPECT_EQ("6.0.0.13", most_recent->version);
70
71 // Test real scenarios.
72 content::PepperPluginInfo component_flash;
73 component_flash.version = "4.3.2.1";
74 component_flash.is_external = false;
75 component_flash.name = "component_flash";
76
77 content::PepperPluginInfo system_flash;
78 system_flash.version = "4.3.2.1";
79 system_flash.is_external = true;
80 system_flash.name = "system_flash";
81
82 // The order here should be:
83 // 1. System Flash.
84 // 2. Component update.
85 version_vector.clear();
86 version_vector.push_back(
87 std::make_unique<content::PepperPluginInfo>(system_flash));
88 version_vector.push_back(
89 std::make_unique<content::PepperPluginInfo>(component_flash));
90 most_recent = ChromeContentClient::FindMostRecentPlugin(version_vector);
91 EXPECT_STREQ("system_flash", most_recent->name.c_str());
92 }
93 #endif // BUILDFLAG(ENABLE_PLUGINS)
94
TEST(ChromeContentClientTest,AdditionalSchemes)95 TEST(ChromeContentClientTest, AdditionalSchemes) {
96 EXPECT_TRUE(url::IsStandard(
97 extensions::kExtensionScheme,
98 url::Component(0, strlen(extensions::kExtensionScheme))));
99
100 GURL extension_url(
101 "chrome-extension://abcdefghijklmnopqrstuvwxyzabcdef/foo.html");
102 url::Origin origin = url::Origin::Create(extension_url);
103 EXPECT_EQ("chrome-extension://abcdefghijklmnopqrstuvwxyzabcdef",
104 origin.Serialize());
105
106 EXPECT_TRUE(
107 blink::network_utils::IsOriginSecure(GURL("chrome-native://newtab/")));
108
109 GURL chrome_url(content::GetWebUIURL("dummyurl"));
110 EXPECT_TRUE(blink::network_utils::IsOriginSecure(chrome_url));
111 EXPECT_FALSE(content::OriginCanAccessServiceWorkers(chrome_url));
112 EXPECT_TRUE(
113 content::IsPotentiallyTrustworthyOrigin(url::Origin::Create(chrome_url)));
114 }
115
116 class OriginTrialInitializationTestThread
117 : public base::PlatformThread::Delegate {
118 public:
OriginTrialInitializationTestThread(ChromeContentClient * chrome_client)119 explicit OriginTrialInitializationTestThread(
120 ChromeContentClient* chrome_client)
121 : chrome_client_(chrome_client) {}
122
ThreadMain()123 void ThreadMain() override { AccessPolicy(chrome_client_, &policy_objects_); }
124
125 // Static helper which can also be called from the main thread.
AccessPolicy(ChromeContentClient * content_client,std::vector<blink::OriginTrialPolicy * > * policy_objects)126 static void AccessPolicy(
127 ChromeContentClient* content_client,
128 std::vector<blink::OriginTrialPolicy*>* policy_objects) {
129 // Repeatedly access the lazily-created origin trial policy
130 for (int i = 0; i < 20; i++) {
131 blink::OriginTrialPolicy* policy = content_client->GetOriginTrialPolicy();
132 policy_objects->push_back(policy);
133 base::PlatformThread::YieldCurrentThread();
134 }
135 }
136
policy_objects() const137 const std::vector<blink::OriginTrialPolicy*>* policy_objects() const {
138 return &policy_objects_;
139 }
140
141 private:
142 ChromeContentClient* chrome_client_;
143 std::vector<blink::OriginTrialPolicy*> policy_objects_;
144
145 DISALLOW_COPY_AND_ASSIGN(OriginTrialInitializationTestThread);
146 };
147
148 // Test that the lazy initialization of Origin Trial policy is resistant to
149 // races with concurrent access. Failures (especially flaky) indicate that the
150 // race prevention is no longer sufficient.
TEST(ChromeContentClientTest,OriginTrialPolicyConcurrentInitialization)151 TEST(ChromeContentClientTest, OriginTrialPolicyConcurrentInitialization) {
152 ChromeContentClient content_client;
153 std::vector<blink::OriginTrialPolicy*> policy_objects;
154 OriginTrialInitializationTestThread thread(&content_client);
155 base::PlatformThreadHandle handle;
156
157 ASSERT_TRUE(base::PlatformThread::Create(0, &thread, &handle));
158
159 // Repeatedly access the lazily-created origin trial policy
160 OriginTrialInitializationTestThread::AccessPolicy(&content_client,
161 &policy_objects);
162
163 base::PlatformThread::Join(handle);
164
165 ASSERT_EQ(20UL, policy_objects.size());
166
167 blink::OriginTrialPolicy* first_policy = policy_objects[0];
168
169 const std::vector<blink::OriginTrialPolicy*>* all_policy_objects[] = {
170 &policy_objects, thread.policy_objects(),
171 };
172
173 for (const std::vector<blink::OriginTrialPolicy*>* thread_policy_objects :
174 all_policy_objects) {
175 EXPECT_GE(20UL, thread_policy_objects->size());
176 for (blink::OriginTrialPolicy* policy : *(thread_policy_objects)) {
177 EXPECT_EQ(first_policy, policy);
178 }
179 }
180 }
181
182 } // namespace chrome_common
183