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

Side by Side Diff: chrome/browser/ui/extensions/hosted_app_browsertest.cc

Issue 2840383002: Disable top-document-isolation if the parent SiteInstance is a hosted app. (Closed)
Patch Set: Addressing CR feedback. Created 3 years, 7 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 <string> 5 #include <string>
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/compiler_specific.h" 8 #include "base/compiler_specific.h"
9 #include "base/strings/stringprintf.h"
9 #include "base/test/scoped_feature_list.h" 10 #include "base/test/scoped_feature_list.h"
10 #include "chrome/browser/extensions/extension_browsertest.h" 11 #include "chrome/browser/extensions/extension_browsertest.h"
11 #include "chrome/browser/extensions/extension_service.h" 12 #include "chrome/browser/extensions/extension_service.h"
12 #include "chrome/browser/extensions/extension_util.h" 13 #include "chrome/browser/extensions/extension_util.h"
14 #include "chrome/browser/extensions/test_extension_dir.h"
13 #include "chrome/browser/ui/browser_list.h" 15 #include "chrome/browser/ui/browser_list.h"
14 #include "chrome/browser/ui/extensions/app_launch_params.h" 16 #include "chrome/browser/ui/extensions/app_launch_params.h"
15 #include "chrome/browser/ui/extensions/application_launch.h" 17 #include "chrome/browser/ui/extensions/application_launch.h"
16 #include "chrome/browser/ui/extensions/hosted_app_browser_controller.h" 18 #include "chrome/browser/ui/extensions/hosted_app_browser_controller.h"
17 #include "chrome/browser/ui/tabs/tab_strip_model.h" 19 #include "chrome/browser/ui/tabs/tab_strip_model.h"
18 #include "chrome/browser/web_applications/web_app.h" 20 #include "chrome/browser/web_applications/web_app.h"
19 #include "chrome/test/base/ui_test_utils.h" 21 #include "chrome/test/base/ui_test_utils.h"
22 #include "content/public/browser/render_frame_host.h"
20 #include "content/public/browser/web_contents.h" 23 #include "content/public/browser/web_contents.h"
24 #include "content/public/common/content_switches.h"
25 #include "content/public/test/browser_test_utils.h"
26 #include "content/public/test/test_utils.h"
21 #include "extensions/browser/extension_registry.h" 27 #include "extensions/browser/extension_registry.h"
22 #include "extensions/common/constants.h" 28 #include "extensions/common/constants.h"
23 #include "extensions/common/extension.h" 29 #include "extensions/common/extension.h"
24 #include "extensions/common/extension_set.h" 30 #include "extensions/common/extension_set.h"
31 #include "net/dns/mock_host_resolver.h"
32 #include "net/test/embedded_test_server/embedded_test_server.h"
25 33
26 #if defined(OS_MACOSX) 34 #if defined(OS_MACOSX)
27 #include "chrome/common/chrome_features.h" 35 #include "chrome/common/chrome_features.h"
28 #endif 36 #endif
29 37
30 using content::WebContents; 38 using content::WebContents;
31 using extensions::Extension; 39 using extensions::Extension;
32 40
33 namespace { 41 namespace {
34 42
(...skipping 18 matching lines...) Expand all
53 // testing::Test: 61 // testing::Test:
54 void SetUp() override { 62 void SetUp() override {
55 ExtensionBrowserTest::SetUp(); 63 ExtensionBrowserTest::SetUp();
56 #if defined(OS_MACOSX) 64 #if defined(OS_MACOSX)
57 scoped_feature_list_.InitAndEnableFeature(features::kBookmarkApps); 65 scoped_feature_list_.InitAndEnableFeature(features::kBookmarkApps);
58 #endif 66 #endif
59 } 67 }
60 68
61 protected: 69 protected:
62 void SetupApp(const std::string& app_folder, bool is_bookmark_app) { 70 void SetupApp(const std::string& app_folder, bool is_bookmark_app) {
71 SetupApp(test_data_dir_.AppendASCII(app_folder), is_bookmark_app);
72 }
73
74 void SetupApp(const base::FilePath& app_folder, bool is_bookmark_app) {
63 const Extension* app = InstallExtensionWithSourceAndFlags( 75 const Extension* app = InstallExtensionWithSourceAndFlags(
64 test_data_dir_.AppendASCII(app_folder), 1, 76 app_folder, 1, extensions::Manifest::INTERNAL,
65 extensions::Manifest::INTERNAL,
66 is_bookmark_app ? extensions::Extension::FROM_BOOKMARK 77 is_bookmark_app ? extensions::Extension::FROM_BOOKMARK
67 : extensions::Extension::NO_FLAGS); 78 : extensions::Extension::NO_FLAGS);
68 ASSERT_TRUE(app); 79 ASSERT_TRUE(app);
69 80
70 // Launch it in a window. 81 // Launch it in a window.
71 ASSERT_TRUE(OpenApplication(AppLaunchParams( 82 ASSERT_TRUE(OpenApplication(AppLaunchParams(
72 browser()->profile(), app, extensions::LAUNCH_CONTAINER_WINDOW, 83 browser()->profile(), app, extensions::LAUNCH_CONTAINER_WINDOW,
73 WindowOpenDisposition::NEW_WINDOW, extensions::SOURCE_TEST))); 84 WindowOpenDisposition::NEW_WINDOW, extensions::SOURCE_TEST)));
74 85
75 for (auto* b : *BrowserList::GetInstance()) { 86 for (auto* b : *BrowserList::GetInstance()) {
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 190
180 // Navigate to the app's launch page with the 'www.' prefis; the location bar 191 // Navigate to the app's launch page with the 'www.' prefis; the location bar
181 // should be hidden. 192 // should be hidden.
182 NavigateAndCheckForLocationBar( 193 NavigateAndCheckForLocationBar(
183 app_browser_, "http://www.example.com/empty.html", false); 194 app_browser_, "http://www.example.com/empty.html", false);
184 195
185 // Navigate to different origin; the location bar should now be visible. 196 // Navigate to different origin; the location bar should now be visible.
186 NavigateAndCheckForLocationBar( 197 NavigateAndCheckForLocationBar(
187 app_browser_, "http://www.foo.com/blah", true); 198 app_browser_, "http://www.foo.com/blah", true);
188 } 199 }
200
201 class HostedAppVsTdiTest : public HostedAppTest {
202 public:
203 HostedAppVsTdiTest() {}
204 ~HostedAppVsTdiTest() override {}
205
206 void SetUpCommandLine(base::CommandLine* command_line) override {
207 HostedAppTest::SetUpCommandLine(command_line);
208 command_line->AppendSwitch(switches::kTopDocumentIsolation);
209 }
210
211 void SetUpOnMainThread() override {
212 HostedAppTest::SetUpOnMainThread();
213 host_resolver()->AddRule("*", "127.0.0.1");
214 ASSERT_TRUE(embedded_test_server()->Start());
215 }
216 };
217
218 // Tests that even with --top-document-isolation, app.site.com (covered by app's
219 // web extent) main frame and foo.site.com (not covered by app's web extent)
220 // share the same renderer process. See also https://crbug.com/679011.
221 //
222 // Relevant frames in the test:
223 // - |app| - app.site.com/frame_tree/cross_origin_but_same_site_frames.html
224 // Main frame, launch URL of the hosted app (i.e. app.launch.web_url).
225 // - |same_dir| - app.site.com/frame_tree/simple.htm
226 // Another URL, but still covered by hosted app's web extent
227 // (i.e. by app.urls).
228 // - |diff_dir| - app.site.com/save_page/a.htm
229 // Same origin as |same_dir| and |app|, but not covered by app's
230 // extent.
231 // - |same_site| - other.site.com/title1.htm
232 // Different origin, but same site as |app|, |same_dir|,
233 // |diff_dir|.
234 // - |cross_site| - cross.domain.com/title1.htm
235 // Cross-site from all the other frames.
236 //
237 // Verifications of |*_site| (e.g. EXPECT_EQ(same_dir_site, app_site) are
238 // sanity checks of the test setup.
239 //
240 // First real verification in the test is whether |same_dir| and |diff_dir| can
241 // script each other (despite their effective URLs being cross-site, because
242 // |same_dir| is mapped to a chrome-extension URL). This was a functionality
243 // problem caused by https://crbug.com/679011.
244 //
245 // The test also verifies that all same-site frames (i.e. |app|, |same_dir|,
246 // |diff_dir|, |same_site|) share the same renderer process. This was a small
247 // performance problem caused by https://crbug.com/679011.
248 IN_PROC_BROWSER_TEST_F(HostedAppVsTdiTest, ProcessAllocation) {
249 // Setup and launch the hosted app.
250 GURL url = embedded_test_server()->GetURL(
251 "app.site.com", "/frame_tree/cross_origin_but_same_site_frames.html");
252
253 extensions::TestExtensionDir test_app_dir;
254 test_app_dir.WriteManifest(base::StringPrintf(
255 R"( { "name": "Hosted App vs TDI Test",
256 "version": "1",
257 "manifest_version": 2,
258 "app": {
259 "launch": {
260 "web_url": "%s"
261 },
262 "urls": ["*://app.site.com/frame_tree"]
263 }
264 } )",
265 url.spec().c_str()));
266 SetupApp(test_app_dir.UnpackedPath(), false);
267
268 content::WebContents* web_contents =
269 app_browser_->tab_strip_model()->GetActiveWebContents();
270 content::WaitForLoadStop(web_contents);
271
272 auto find_frame = [web_contents](const std::string& name) {
273 return content::FrameMatchingPredicate(
274 web_contents, base::Bind(&content::FrameMatchesName, name));
275 };
276 content::RenderFrameHost* app = web_contents->GetMainFrame();
277 content::RenderFrameHost* same_dir = find_frame("SameOrigin-SamePath");
278 content::RenderFrameHost* diff_dir = find_frame("SameOrigin-DifferentPath");
279 content::RenderFrameHost* same_site = find_frame("OtherSubdomain-SameSite");
280 content::RenderFrameHost* cross_site = find_frame("CrossSite");
281
282 // Sanity-check sites of all relevant frames to verify test setup.
283 GURL app_site = content::SiteInstance::GetSiteForURL(
284 app_browser_->profile(), app->GetLastCommittedURL());
285 EXPECT_EQ(extensions::kExtensionScheme, app_site.scheme());
286
287 GURL same_dir_site = content::SiteInstance::GetSiteForURL(
288 app_browser_->profile(), same_dir->GetLastCommittedURL());
289 EXPECT_EQ(extensions::kExtensionScheme, same_dir_site.scheme());
290 EXPECT_EQ(same_dir_site, app_site);
291
292 GURL diff_dir_site = content::SiteInstance::GetSiteForURL(
293 app_browser_->profile(), diff_dir->GetLastCommittedURL());
294 EXPECT_NE(extensions::kExtensionScheme, diff_dir_site.scheme());
295 EXPECT_NE(diff_dir_site, app_site);
296
297 GURL same_site_site = content::SiteInstance::GetSiteForURL(
298 app_browser_->profile(), same_site->GetLastCommittedURL());
299 EXPECT_NE(extensions::kExtensionScheme, same_site_site.scheme());
300 EXPECT_NE(same_site_site, app_site);
301 EXPECT_EQ(same_site_site, diff_dir_site);
302
303 GURL cross_site_site = content::SiteInstance::GetSiteForURL(
304 app_browser_->profile(), cross_site->GetLastCommittedURL());
305 EXPECT_NE(cross_site_site, app_site);
306 EXPECT_NE(cross_site_site, same_site_site);
307
308 // Verify that |same_dir| and |diff_dir| have the same origin according to
309 // |window.origin| (even though they have different |same_dir_site| and
310 // |diff_dir_site|).
311 std::string same_dir_origin;
312 EXPECT_TRUE(content::ExecuteScriptAndExtractString(
313 same_dir, "domAutomationController.send(window.origin)",
314 &same_dir_origin));
315
316 std::string diff_dir_origin;
317 EXPECT_TRUE(content::ExecuteScriptAndExtractString(
318 diff_dir, "domAutomationController.send(window.origin)",
319 &diff_dir_origin));
320
321 EXPECT_EQ(diff_dir_origin, same_dir_origin);
322
323 // Verify scriptability and process placement.
324 EXPECT_EQ(same_dir->GetProcess(), app->GetProcess());
325 if (!content::AreAllSitesIsolatedForTesting()) {
326 // Verify that |same_dir| and |diff_dir| can script each other.
327 // (they should - they have the same origin).
328 std::string inner_text_from_other_frame;
329 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
330 diff_dir,
331 R"( var w = window.open('', 'SameOrigin-SamePath');
332 domAutomationController.send(w.document.body.innerText); )",
333 &inner_text_from_other_frame));
334 EXPECT_EQ("Simple test page.", inner_text_from_other_frame);
335
336 // Verify there are no additional processes for same-site frames.
337 EXPECT_EQ(diff_dir->GetProcess(), app->GetProcess());
338 EXPECT_EQ(same_site->GetProcess(), app->GetProcess());
339 // TODO(lukasza): https://crbug.com/718516: For now it is okay for
340 // |cross_site| to be in any process, but we should probably revisit
341 // before launching --top-document-isolation more broadly.
342 } else {
343 // TODO(lukasza): https://crbug.com/718516: Process policy is not
344 // well-defined / settled wrt relationship between 1) hosted apps and 2)
345 // same-site web content outside of hosted app's extent. When this test was
346 // authored --site-per-process would put |app| in a separate renderer
347 // process from |diff_dir| and |same_site|, even though such process
348 // placement can be problematic (if |app| tries to synchronously script
349 // |diff_dir| and/or |same_site|).
350 }
351 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698