Show origin for hosted apps that navigate away from their start origin.

This is only for hosted apps that run in their own window.

BUG=467844

Review URL: https://codereview.chromium.org/1164873003

Cr-Commit-Position: refs/heads/master@{#333009}
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index 6ccb52ca..1cc78f2 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -107,7 +107,7 @@
 #include "chrome/browser/ui/chrome_select_file_policy.h"
 #include "chrome/browser/ui/exclusive_access/fullscreen_controller.h"
 #include "chrome/browser/ui/exclusive_access/mouse_lock_controller.h"
-#include "chrome/browser/ui/extensions/bookmark_app_browser_controller.h"
+#include "chrome/browser/ui/extensions/hosted_app_browser_controller.h"
 #include "chrome/browser/ui/fast_unload_controller.h"
 #include "chrome/browser/ui/find_bar/find_bar.h"
 #include "chrome/browser/ui/find_bar/find_bar_controller.h"
@@ -418,9 +418,9 @@
   if (chrome::IsInstantExtendedAPIEnabled() && is_type_tabbed())
     instant_controller_.reset(new BrowserInstantController(this));
 
-  if (extensions::BookmarkAppBrowserController::IsForBookmarkApp(this)) {
-    bookmark_app_controller_.reset(
-        new extensions::BookmarkAppBrowserController(this));
+  if (extensions::HostedAppBrowserController::IsForHostedApp(this)) {
+    hosted_app_controller_.reset(
+        new extensions::HostedAppBrowserController(this));
   }
 
   UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_INIT);
@@ -429,8 +429,8 @@
 
   window_ = params.window ? params.window : CreateBrowserWindow(this);
 
-  if (bookmark_app_controller_)
-    bookmark_app_controller_->UpdateLocationBarVisibility(false);
+  if (hosted_app_controller_)
+    hosted_app_controller_->UpdateLocationBarVisibility(false);
 
   // Create the extension window controller before sending notifications.
   extension_window_controller_.reset(
@@ -1438,8 +1438,8 @@
                        content::INVALIDATE_TYPE_LOAD))
     command_controller_->TabStateChanged();
 
-  if (bookmark_app_controller_)
-    bookmark_app_controller_->UpdateLocationBarVisibility(true);
+  if (hosted_app_controller_)
+    hosted_app_controller_->UpdateLocationBarVisibility(true);
 }
 
 void Browser::VisibleSSLStateChanged(const WebContents* source) {
@@ -2429,8 +2429,8 @@
   if (!is_app())
     return !is_trusted_source();
 
-  if (bookmark_app_controller_)
-    return bookmark_app_controller_->SupportsLocationBar();
+  if (hosted_app_controller_)
+    return hosted_app_controller_->SupportsLocationBar();
 
   return false;
 }
@@ -2441,8 +2441,8 @@
   if (!is_app())
     return false;
 
-  if (bookmark_app_controller_)
-    return bookmark_app_controller_->should_use_web_app_frame();
+  if (hosted_app_controller_)
+    return hosted_app_controller_->should_use_web_app_frame();
 
   return false;
 }
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h
index 0fee68b7..c4a3a62c 100644
--- a/chrome/browser/ui/browser.h
+++ b/chrome/browser/ui/browser.h
@@ -81,7 +81,7 @@
 }
 
 namespace extensions {
-class BookmarkAppBrowserController;
+class HostedAppBrowserController;
 class Extension;
 class ExtensionRegistry;
 class WindowController;
@@ -283,8 +283,8 @@
   BrowserInstantController* instant_controller() {
     return instant_controller_.get();
   }
-  extensions::BookmarkAppBrowserController* bookmark_app_controller() {
-    return bookmark_app_controller_.get();
+  extensions::HostedAppBrowserController* hosted_app_controller() {
+    return hosted_app_controller_.get();
   }
 
   // Get the FindBarController for this browser, creating it if it does not
@@ -963,7 +963,7 @@
   scoped_ptr<BrowserInstantController> instant_controller_;
 
   // Helper which handles bookmark app specific browser configuration.
-  scoped_ptr<extensions::BookmarkAppBrowserController> bookmark_app_controller_;
+  scoped_ptr<extensions::HostedAppBrowserController> hosted_app_controller_;
 
   BookmarkBar::State bookmark_bar_state_;
 
diff --git a/chrome/browser/ui/browser_browsertest.cc b/chrome/browser/ui/browser_browsertest.cc
index 9cf66fa..451c41f 100644
--- a/chrome/browser/ui/browser_browsertest.cc
+++ b/chrome/browser/ui/browser_browsertest.cc
@@ -1415,7 +1415,10 @@
 
   EXPECT_FALSE(
       dev_tools_browser->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR));
-  EXPECT_FALSE(
+
+  // App windows can show location bars, for example when they navigate away
+  // from their starting origin.
+  EXPECT_TRUE(
       app_browser->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR));
 
   DevToolsWindowTesting::CloseDevToolsWindowSync(devtools_window);
diff --git a/chrome/browser/ui/extensions/bookmark_app_browser_controller.h b/chrome/browser/ui/extensions/bookmark_app_browser_controller.h
deleted file mode 100644
index e47aaf39..0000000
--- a/chrome/browser/ui/extensions/bookmark_app_browser_controller.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_UI_EXTENSIONS_BOOKMARK_APP_BROWSER_CONTROLLER_H_
-#define CHROME_BROWSER_UI_EXTENSIONS_BOOKMARK_APP_BROWSER_CONTROLLER_H_
-
-#include <string>
-
-#include "base/macros.h"
-
-class Browser;
-class Profile;
-
-namespace extensions {
-
-// Class to encapsulate logic to control the browser UI for bookmark apps.
-class BookmarkAppBrowserController {
- public:
-  // Indicates whether |browser| is a bookmark app browser.
-  static bool IsForBookmarkApp(Browser* browser);
-
-  explicit BookmarkAppBrowserController(Browser* browser);
-  ~BookmarkAppBrowserController();
-
-  // Whether the browser being controlled can ever show the location bar.
-  bool SupportsLocationBar();
-
-  // Whether the browser being controlled should be currently showing the
-  // location bar.
-  bool ShouldShowLocationBar();
-
-  // Updates the location bar visibility based on whether it should be
-  // currently visible or not. If |animate| is set, the change will be
-  // animated.
-  void UpdateLocationBarVisibility(bool animate);
-
-  // Whether the controlled browser should use the web app style frame.
-  bool should_use_web_app_frame() { return should_use_web_app_frame_; }
-
- private:
-  Browser* browser_;
-  const std::string extension_id_;
-  const bool should_use_web_app_frame_;
-
-  DISALLOW_COPY_AND_ASSIGN(BookmarkAppBrowserController);
-};
-
-}  // namespace extensions
-
-#endif  // CHROME_BROWSER_UI_EXTENSIONS_BOOKMARK_APP_BROWSER_CONTROLLER_H_
diff --git a/chrome/browser/ui/extensions/bookmark_app_browser_controller.cc b/chrome/browser/ui/extensions/hosted_app_browser_controller.cc
similarity index 73%
rename from chrome/browser/ui/extensions/bookmark_app_browser_controller.cc
rename to chrome/browser/ui/extensions/hosted_app_browser_controller.cc
index 773250a..7a3a930 100644
--- a/chrome/browser/ui/extensions/bookmark_app_browser_controller.cc
+++ b/chrome/browser/ui/extensions/hosted_app_browser_controller.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/ui/extensions/bookmark_app_browser_controller.h"
+#include "chrome/browser/ui/extensions/hosted_app_browser_controller.h"
 
 #include "base/command_line.h"
 #include "chrome/browser/profiles/profile.h"
@@ -18,6 +18,7 @@
 #include "content/public/browser/web_contents.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/common/extension.h"
+#include "net/base/net_util.h"
 #include "url/gurl.h"
 
 namespace extensions {
@@ -25,9 +26,11 @@
 namespace {
 
 bool IsSameOriginOrMoreSecure(const GURL& app_url, const GURL& page_url) {
+  const std::string www("www.");
   return (app_url.scheme() == page_url.scheme() ||
           page_url.scheme() == url::kHttpsScheme) &&
-         app_url.host() == page_url.host() &&
+         (app_url.host() == page_url.host() ||
+          www + app_url.host() == page_url.host()) &&
          app_url.port() == page_url.port();
 }
 
@@ -39,32 +42,37 @@
 }  // namespace
 
 // static
-bool BookmarkAppBrowserController::IsForBookmarkApp(Browser* browser) {
+bool HostedAppBrowserController::IsForHostedApp(Browser* browser) {
   const std::string extension_id =
       web_app::GetExtensionIdFromApplicationName(browser->app_name());
   const Extension* extension =
       ExtensionRegistry::Get(browser->profile())->GetExtensionById(
           extension_id, ExtensionRegistry::EVERYTHING);
-  return extension && extension->from_bookmark();
+  return extension && extension->is_hosted_app();
 }
 
-BookmarkAppBrowserController::BookmarkAppBrowserController(Browser* browser)
+HostedAppBrowserController::HostedAppBrowserController(Browser* browser)
     : browser_(browser),
       extension_id_(
-          web_app::GetExtensionIdFromApplicationName(browser->app_name())),
-      should_use_web_app_frame_(browser->host_desktop_type() ==
-                                    chrome::HOST_DESKTOP_TYPE_ASH &&
-                                IsWebAppFrameEnabled()) {
+          web_app::GetExtensionIdFromApplicationName(browser->app_name())) {
+  const Extension* extension =
+      ExtensionRegistry::Get(browser->profile())->GetExtensionById(
+          extension_id_, ExtensionRegistry::EVERYTHING);
+  DCHECK(extension);
+  should_use_web_app_frame_ =
+      extension->from_bookmark() &&
+      browser->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_ASH &&
+      IsWebAppFrameEnabled();
 }
 
-BookmarkAppBrowserController::~BookmarkAppBrowserController() {
+HostedAppBrowserController::~HostedAppBrowserController() {
 }
 
-bool BookmarkAppBrowserController::SupportsLocationBar() {
+bool HostedAppBrowserController::SupportsLocationBar() const {
   return !should_use_web_app_frame();
 }
 
-bool BookmarkAppBrowserController::ShouldShowLocationBar() {
+bool HostedAppBrowserController::ShouldShowLocationBar() const {
   const Extension* extension =
       ExtensionRegistry::Get(browser_->profile())->GetExtensionById(
           extension_id_, ExtensionRegistry::EVERYTHING);
@@ -77,7 +85,7 @@
   if (!extension || !web_contents)
     return false;
 
-  if (!extension->from_bookmark())
+  if (!extension->is_hosted_app())
     return false;
 
   // Don't show a location bar until a navigation has occurred.
@@ -96,7 +104,8 @@
                                     web_contents->GetLastCommittedURL()));
 }
 
-void BookmarkAppBrowserController::UpdateLocationBarVisibility(bool animate) {
+void HostedAppBrowserController::UpdateLocationBarVisibility(
+    bool animate) const {
   if (!SupportsLocationBar())
     return;
 
diff --git a/chrome/browser/ui/extensions/hosted_app_browser_controller.h b/chrome/browser/ui/extensions/hosted_app_browser_controller.h
new file mode 100644
index 0000000..09384d07
--- /dev/null
+++ b/chrome/browser/ui/extensions/hosted_app_browser_controller.h
@@ -0,0 +1,51 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_EXTENSIONS_HOSTED_APP_BROWSER_CONTROLLER_H_
+#define CHROME_BROWSER_UI_EXTENSIONS_HOSTED_APP_BROWSER_CONTROLLER_H_
+
+#include <string>
+
+#include "base/macros.h"
+
+class Browser;
+class Profile;
+
+namespace extensions {
+
+// Class to encapsulate logic to control the browser UI for hosted apps.
+class HostedAppBrowserController {
+ public:
+  // Indicates whether |browser| is a hosted app browser.
+  static bool IsForHostedApp(Browser* browser);
+
+  explicit HostedAppBrowserController(Browser* browser);
+  ~HostedAppBrowserController();
+
+  // Whether the browser being controlled can ever show the location bar.
+  bool SupportsLocationBar() const;
+
+  // Whether the browser being controlled should be currently showing the
+  // location bar.
+  bool ShouldShowLocationBar() const;
+
+  // Updates the location bar visibility based on whether it should be
+  // currently visible or not. If |animate| is set, the change will be
+  // animated.
+  void UpdateLocationBarVisibility(bool animate) const;
+
+  // Whether the controlled browser should use the web app style frame.
+  bool should_use_web_app_frame() const { return should_use_web_app_frame_; }
+
+ private:
+  Browser* browser_;
+  const std::string extension_id_;
+  bool should_use_web_app_frame_;
+
+  DISALLOW_COPY_AND_ASSIGN(HostedAppBrowserController);
+};
+
+}  // namespace extensions
+
+#endif  // CHROME_BROWSER_UI_EXTENSIONS_HOSTED_APP_BROWSER_CONTROLLER_H_
diff --git a/chrome/browser/ui/extensions/bookmark_app_browsertest.cc b/chrome/browser/ui/extensions/hosted_app_browsertest.cc
similarity index 60%
rename from chrome/browser/ui/extensions/bookmark_app_browsertest.cc
rename to chrome/browser/ui/extensions/hosted_app_browsertest.cc
index 186029b..fa96455 100644
--- a/chrome/browser/ui/extensions/bookmark_app_browsertest.cc
+++ b/chrome/browser/ui/extensions/hosted_app_browsertest.cc
@@ -14,7 +14,7 @@
 #include "chrome/browser/ui/browser_iterator.h"
 #include "chrome/browser/ui/extensions/app_launch_params.h"
 #include "chrome/browser/ui/extensions/application_launch.h"
-#include "chrome/browser/ui/extensions/bookmark_app_browser_controller.h"
+#include "chrome/browser/ui/extensions/hosted_app_browser_controller.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/web_applications/web_app.h"
 #include "chrome/common/chrome_switches.h"
@@ -28,8 +28,6 @@
 using content::WebContents;
 using extensions::Extension;
 
-typedef ExtensionBrowserTest BookmarkAppTest;
-
 namespace {
 
 // Used by ShouldLocationBarForXXX. Performs a navigation and then checks that
@@ -40,141 +38,174 @@
   GURL url(url_string);
   ui_test_utils::NavigateToURL(browser, url);
   EXPECT_EQ(expected_visibility,
-      browser->bookmark_app_controller()->ShouldShowLocationBar());
+      browser->hosted_app_controller()->ShouldShowLocationBar());
 }
 
 }  // namespace
 
+class HostedAppTest : public ExtensionBrowserTest {
+ public:
+  HostedAppTest() : app_browser_(nullptr) {}
+  ~HostedAppTest() override {}
+
+ protected:
+  void SetupApp(const std::string& app_folder, bool is_bookmark_app) {
+    const Extension* app = InstallExtensionWithSourceAndFlags(
+        test_data_dir_.AppendASCII(app_folder), 1,
+        extensions::Manifest::INTERNAL,
+        is_bookmark_app ? extensions::Extension::FROM_BOOKMARK
+                        : extensions::Extension::NO_FLAGS);
+    ASSERT_TRUE(app);
+
+    // Launch it in a window.
+    ASSERT_TRUE(OpenApplication(AppLaunchParams(
+        browser()->profile(), app, extensions::LAUNCH_CONTAINER_WINDOW,
+        NEW_WINDOW, extensions::SOURCE_TEST)));
+
+    for (chrome::BrowserIterator it; !it.done(); it.Next()) {
+      if (*it == browser())
+        continue;
+
+      std::string browser_app_id =
+          web_app::GetExtensionIdFromApplicationName((*it)->app_name());
+      if (browser_app_id == app->id()) {
+        app_browser_ = *it;
+        break;
+      }
+    }
+
+    ASSERT_TRUE(app_browser_);
+    ASSERT_TRUE(app_browser_ != browser());
+  }
+
+  Browser* app_browser_;
+};
+
 // Check that the location bar is shown correctly for HTTP bookmark apps.
-IN_PROC_BROWSER_TEST_F(BookmarkAppTest,
+IN_PROC_BROWSER_TEST_F(HostedAppTest,
                        ShouldShowLocationBarForHTTPBookmarkApp) {
   base::CommandLine::ForCurrentProcess()->AppendSwitch(
       switches::kEnableNewBookmarkApps);
-  ASSERT_TRUE(test_server()->Start());
 
-  // Load a http bookmark app.
-  const Extension* http_bookmark_app = InstallExtensionWithSourceAndFlags(
-      test_data_dir_.AppendASCII("app/"),
-      1,
-      extensions::Manifest::INTERNAL,
-      extensions::Extension::FROM_BOOKMARK);
-  ASSERT_TRUE(http_bookmark_app);
-
-  // Launch it in a window.
-  WebContents* app_window = OpenApplication(AppLaunchParams(
-      browser()->profile(), http_bookmark_app,
-      extensions::LAUNCH_CONTAINER_WINDOW, NEW_WINDOW,
-      extensions::SOURCE_TEST));
-  ASSERT_TRUE(app_window);
-
-  // Find the new browser.
-  Browser* http_app_browser = NULL;
-  for (chrome::BrowserIterator it; !it.done(); it.Next()) {
-    std::string app_id =
-        web_app::GetExtensionIdFromApplicationName((*it)->app_name());
-    if (*it == browser()) {
-      continue;
-    } else if (app_id == http_bookmark_app->id()) {
-      http_app_browser = *it;
-    }
-  }
-  ASSERT_TRUE(http_app_browser);
-  ASSERT_TRUE(http_app_browser != browser());
+  SetupApp("app", true);
 
   // Navigate to the app's launch page; the location bar should be hidden.
   NavigateAndCheckForLocationBar(
-      http_app_browser, "http://www.example.com/empty.html", false);
+      app_browser_, "http://www.example.com/empty.html", false);
 
   // Navigate to another page on the same origin; the location bar should still
   // hidden.
   NavigateAndCheckForLocationBar(
-      http_app_browser, "http://www.example.com/blah", false);
+      app_browser_, "http://www.example.com/blah", false);
 
   // Navigate to the https version of the site; the location bar should
-  // be hidden for both browsers.
+  // be hidden.
   NavigateAndCheckForLocationBar(
-      http_app_browser, "https://www.example.com/blah", false);
+      app_browser_, "https://www.example.com/blah", false);
 
   // Navigate to different origin; the location bar should now be visible.
   NavigateAndCheckForLocationBar(
-      http_app_browser, "http://www.foo.com/blah", true);
+      app_browser_, "http://www.foo.com/blah", true);
 
   // Navigate back to the app's origin; the location bar should now be hidden.
   NavigateAndCheckForLocationBar(
-      http_app_browser, "http://www.example.com/blah", false);
+      app_browser_, "http://www.example.com/blah", false);
 }
 
 // Check that the location bar is shown correctly for HTTPS bookmark apps.
-IN_PROC_BROWSER_TEST_F(BookmarkAppTest,
+IN_PROC_BROWSER_TEST_F(HostedAppTest,
                        ShouldShowLocationBarForHTTPSBookmarkApp) {
   base::CommandLine::ForCurrentProcess()->AppendSwitch(
       switches::kEnableNewBookmarkApps);
-  ASSERT_TRUE(test_server()->Start());
 
-  // Load a https bookmark app.
-  const Extension* https_bookmark_app = InstallExtensionWithSourceAndFlags(
-      test_data_dir_.AppendASCII("https_app/"),
-      1,
-      extensions::Manifest::INTERNAL,
-      extensions::Extension::FROM_BOOKMARK);
-  ASSERT_TRUE(https_bookmark_app);
-
-  // Launch it in a window.
-  WebContents* app_window = OpenApplication(AppLaunchParams(
-      browser()->profile(), https_bookmark_app,
-      extensions::LAUNCH_CONTAINER_WINDOW, NEW_WINDOW,
-      extensions::SOURCE_TEST));
-  ASSERT_TRUE(app_window);
-
-  // Find the new browser.
-  Browser* https_app_browser = NULL;
-  for (chrome::BrowserIterator it; !it.done(); it.Next()) {
-    std::string app_id =
-        web_app::GetExtensionIdFromApplicationName((*it)->app_name());
-    if (*it == browser()) {
-      continue;
-    } else if (app_id == https_bookmark_app->id()) {
-      https_app_browser = *it;
-    }
-  }
-  ASSERT_TRUE(https_app_browser);
-  ASSERT_TRUE(https_app_browser != browser());
+  SetupApp("https_app", true);
 
   // Navigate to the app's launch page; the location bar should be hidden.
   NavigateAndCheckForLocationBar(
-      https_app_browser, "https://www.example.com/empty.html", false);
+      app_browser_, "https://www.example.com/empty.html", false);
 
   // Navigate to another page on the same origin; the location bar should still
   // hidden.
   NavigateAndCheckForLocationBar(
-      https_app_browser, "https://www.example.com/blah", false);
+      app_browser_, "https://www.example.com/blah", false);
 
   // Navigate to the http version of the site; the location bar should
   // be visible for the https version as it is now on a less secure version
   // of its host.
   NavigateAndCheckForLocationBar(
-      https_app_browser, "http://www.example.com/blah", true);
+      app_browser_, "http://www.example.com/blah", true);
 
   // Navigate to different origin; the location bar should now be visible.
   NavigateAndCheckForLocationBar(
-      https_app_browser, "http://www.foo.com/blah", true);
+      app_browser_, "http://www.foo.com/blah", true);
 
   // Navigate back to the app's origin; the location bar should now be hidden.
   NavigateAndCheckForLocationBar(
-      https_app_browser, "https://www.example.com/blah", false);
+      app_browser_, "https://www.example.com/blah", false);
+}
+
+// Check that the location bar is shown correctly for normal hosted apps.
+IN_PROC_BROWSER_TEST_F(HostedAppTest,
+                       ShouldShowLocationBarForHostedApp) {
+  SetupApp("app", false);
+
+  // Navigate to the app's launch page; the location bar should be hidden.
+  NavigateAndCheckForLocationBar(
+      app_browser_, "http://www.example.com/empty.html", false);
+
+  // Navigate to another page on the same origin; the location bar should still
+  // hidden.
+  NavigateAndCheckForLocationBar(
+      app_browser_, "http://www.example.com/blah", false);
+
+  // Navigate to the https version of the site; the location bar should
+  // be hidden.
+  NavigateAndCheckForLocationBar(
+      app_browser_, "https://www.example.com/blah", false);
+
+  // Navigate to different origin; the location bar should now be visible.
+  NavigateAndCheckForLocationBar(
+      app_browser_, "http://www.foo.com/blah", true);
+
+  // Navigate back to the app's origin; the location bar should now be hidden.
+  NavigateAndCheckForLocationBar(
+      app_browser_, "http://www.example.com/blah", false);
+}
+
+// Check that the location bar is shown correctly for hosted apps that specify
+// start URLs without the 'www.' prefix.
+IN_PROC_BROWSER_TEST_F(HostedAppTest,
+                       LocationBarForHostedAppWithoutWWW) {
+  SetupApp("app_no_www", false);
+
+  // Navigate to the app's launch page; the location bar should be hidden.
+  NavigateAndCheckForLocationBar(
+      app_browser_, "http://example.com/empty.html", false);
+
+  // Navigate to the app's launch page with the 'www.' prefis; the location bar
+  // should be hidden.
+  NavigateAndCheckForLocationBar(
+      app_browser_, "http://www.example.com/empty.html", false);
+
+  // Navigate to different origin; the location bar should now be visible.
+  NavigateAndCheckForLocationBar(
+      app_browser_, "http://www.foo.com/blah", true);
+
+  // Navigate back to the app's origin; the location bar should now be hidden.
+  NavigateAndCheckForLocationBar(
+      app_browser_, "http://example.com/blah", false);
 }
 
 // Open a normal browser window, a hosted app window, a legacy packaged app
 // window and a dev tools window, and check that the web app frame feature is
 // supported correctly.
-IN_PROC_BROWSER_TEST_F(BookmarkAppTest, ShouldUseWebAppFrame) {
-  ASSERT_TRUE(test_server()->Start());
+IN_PROC_BROWSER_TEST_F(HostedAppTest, ShouldUseWebAppFrame) {
   base::CommandLine::ForCurrentProcess()->AppendSwitch(
       switches::kEnableWebAppFrame);
 
   // Load a hosted app.
    const Extension* bookmark_app = InstallExtensionWithSourceAndFlags(
-      test_data_dir_.AppendASCII("app/"),
+      test_data_dir_.AppendASCII("app"),
       1,
       extensions::Manifest::INTERNAL,
       extensions::Extension::FROM_BOOKMARK);
@@ -187,7 +218,7 @@
   ASSERT_TRUE(bookmark_app_window);
 
   //  Load a packaged app.
-  ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("packaged_app/")));
+  ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("packaged_app")));
   const Extension* packaged_app = nullptr;
   extensions::ExtensionRegistry* registry =
       extensions::ExtensionRegistry::Get(browser()->profile());
@@ -212,9 +243,9 @@
                                         browser()->host_desktop_type()));
 
   // Find the new browsers.
-  Browser* bookmark_app_browser = NULL;
-  Browser* packaged_app_browser = NULL;
-  Browser* dev_tools_browser = NULL;
+  Browser* bookmark_app_browser = nullptr;
+  Browser* packaged_app_browser = nullptr;
+  Browser* dev_tools_browser = nullptr;
   for (chrome::BrowserIterator it; !it.done(); it.Next()) {
     if (*it == browser()) {
       continue;
diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi
index b13a2fa..58ee9ce 100644
--- a/chrome/chrome_browser_ui.gypi
+++ b/chrome/chrome_browser_ui.gypi
@@ -2607,8 +2607,6 @@
       'browser/ui/extensions/app_launch_params.h',
       'browser/ui/extensions/application_launch.cc',
       'browser/ui/extensions/application_launch.h',
-      'browser/ui/extensions/bookmark_app_browser_controller.cc',
-      'browser/ui/extensions/bookmark_app_browser_controller.h',
       'browser/ui/extensions/extension_action_platform_delegate.h',
       'browser/ui/extensions/extension_action_view_controller.cc',
       'browser/ui/extensions/extension_action_view_controller.h',
@@ -2625,6 +2623,8 @@
       'browser/ui/extensions/extension_message_bubble_factory.h',
       'browser/ui/extensions/extension_toolbar_icon_surfacing_bubble_delegate.cc',
       'browser/ui/extensions/extension_toolbar_icon_surfacing_bubble_delegate.h',
+      'browser/ui/extensions/hosted_app_browser_controller.cc',
+      'browser/ui/extensions/hosted_app_browser_controller.h',
       'browser/ui/webui/extensions/chromeos/kiosk_apps_handler.cc',
       'browser/ui/webui/extensions/chromeos/kiosk_apps_handler.h',
       'browser/ui/webui/extensions/extension_basic_info.cc',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 6f5c61e..88a3180 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -467,9 +467,9 @@
       'browser/ui/cocoa/content_settings/content_setting_bubble_cocoa_unittest.mm',
       'browser/ui/cocoa/dev_tools_controller_browsertest.mm',
       'browser/ui/cocoa/extensions/extension_install_dialog_controller_browsertest.mm',
-      'browser/ui/cocoa/extensions/extension_message_bubble_browsertest_mac.mm',
       'browser/ui/cocoa/extensions/extension_install_prompt_test_utils.h',
       'browser/ui/cocoa/extensions/extension_install_prompt_test_utils.mm',
+      'browser/ui/cocoa/extensions/extension_message_bubble_browsertest_mac.mm',
       'browser/ui/cocoa/extensions/media_galleries_dialog_cocoa_browsertest.mm',
       'browser/ui/cocoa/extensions/windowed_install_dialog_controller_browsertest.mm',
       'browser/ui/cocoa/find_bar/find_bar_browsertest.mm',
@@ -487,7 +487,7 @@
       'browser/ui/exclusive_access/fullscreen_controller_browsertest.cc',
       'browser/ui/extensions/extension_message_bubble_browsertest.cc',
       'browser/ui/extensions/extension_message_bubble_browsertest.h',
-      'browser/ui/extensions/bookmark_app_browsertest.cc',
+      'browser/ui/extensions/hosted_app_browsertest.cc',
       'browser/ui/find_bar/find_bar_host_browsertest.cc',
       'browser/ui/global_error/global_error_service_browsertest.cc',
       'browser/ui/location_bar/location_bar_browsertest.cc',
@@ -506,8 +506,6 @@
       'browser/ui/tab_modal_confirm_dialog_browsertest.h',
       'browser/ui/test/scoped_fake_nswindow_main_status.h',
       'browser/ui/test/scoped_fake_nswindow_main_status.mm',
-      'browser/ui/website_settings/permission_bubble_browser_test_util.cc',
-      'browser/ui/website_settings/permission_bubble_browser_test_util.h',
       'browser/ui/toolbar/browser_actions_bar_browsertest.cc',
       'browser/ui/toolbar/browser_actions_bar_browsertest.h',
       'browser/ui/toolbar/component_toolbar_actions_browsertest.cc',
@@ -515,6 +513,8 @@
       'browser/ui/toolbar/test_toolbar_model.h',
       'browser/ui/website_settings/mock_permission_bubble_view.cc',
       'browser/ui/website_settings/mock_permission_bubble_view.h',
+      'browser/ui/website_settings/permission_bubble_browser_test_util.cc',
+      'browser/ui/website_settings/permission_bubble_browser_test_util.h',
       'browser/ui/webui/bidi_checker_web_ui_test.cc',
       'browser/ui/webui/bidi_checker_web_ui_test.h',
       'browser/ui/webui/bookmarks_ui_browsertest.cc',
@@ -718,8 +718,8 @@
       'browser/chromeos/login/screens/network_screen_browsertest.cc',
       'browser/chromeos/login/screens/update_screen_browsertest.cc',
       'browser/chromeos/login/session_login_browsertest.cc',
-      'browser/chromeos/login/signin/oauth2_browsertest.cc',
       'browser/chromeos/login/signin/device_id_browsertest.cc',
+      'browser/chromeos/login/signin/oauth2_browsertest.cc',
       'browser/chromeos/login/supervised/supervised_user_creation_browsertest.cc',
       'browser/chromeos/login/supervised/supervised_user_password_browsertest.cc',
       'browser/chromeos/login/supervised/supervised_user_test_base.cc',
@@ -2204,9 +2204,9 @@
           'sources': [ '<@(chrome_browser_tests_chromeos_sources)' ],
           'sources!': [
             '../apps/load_and_launch_browsertest.cc',
+            'browser/policy/policy_startup_browsertest.cc',
             'browser/printing/cloud_print/test/cloud_print_policy_browsertest.cc',
             'browser/printing/cloud_print/test/cloud_print_proxy_process_browsertest.cc',
-            'browser/policy/policy_startup_browsertest.cc',
             # chromeos does not support profile list avatar menu
             'browser/profiles/profile_list_desktop_browsertest.cc',
             'browser/service_process/service_process_control_browsertest.cc',
diff --git a/chrome/test/data/extensions/app_no_www/manifest.json b/chrome/test/data/extensions/app_no_www/manifest.json
new file mode 100644
index 0000000..9a413dc
--- /dev/null
+++ b/chrome/test/data/extensions/app_no_www/manifest.json
@@ -0,0 +1,13 @@
+{
+  "name": "App Test",
+  "version": "1",
+  "manifest_version": 2,
+  "permissions": [
+    "notifications"
+  ],
+  "app": {
+    "launch": {
+      "web_url": "http://example.com/"
+    }
+  }
+}