summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortmdiep@chromium.org <tmdiep@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-19 05:40:21 +0000
committertmdiep@chromium.org <tmdiep@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-19 05:40:21 +0000
commit5ec6705b1f3b41c294b9ecda323df951230a5169 (patch)
tree5a86b72c42f419eb35f99c1591a97e96047ac4da
parent9904c6de07de8a9ca73cb29132d959d11168ea2a (diff)
downloadchromium_src-5ec6705b1f3b41c294b9ecda323df951230a5169.zip
chromium_src-5ec6705b1f3b41c294b9ecda323df951230a5169.tar.gz
chromium_src-5ec6705b1f3b41c294b9ecda323df951230a5169.tar.bz2
Reinstate linkable ephemeral apps experiment
Reverts https://codereview.chromium.org/100553002 Reason for revert: The reverted patch was requested by the security team, but there was a misunderstanding about whether this was a finch experiment or a feature behind command line flags. There is one difference with the original patch: This patch restricts the ability to launch ephemeral apps to https://www.google.com (previously allowed both http and https). The "enable-linkable-ephemeral-apps" command line flag still must be enabled. BUG=312460 TBR=sky@chromium.org, benwells@chromium.org Review URL: https://codereview.chromium.org/100133005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@241807 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/app/generated_resources.grd6
-rw-r--r--chrome/browser/about_flags.cc7
-rw-r--r--chrome/browser/apps/ephemeral_app_throttle.cc114
-rw-r--r--chrome/browser/apps/ephemeral_app_throttle.h33
-rw-r--r--chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc8
-rw-r--r--chrome/chrome_browser_extensions.gypi2
-rw-r--r--chrome/common/chrome_switches.cc3
-rw-r--r--chrome/common/chrome_switches.h1
8 files changed, 174 insertions, 0 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 1e2f571..d279e23 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -6718,6 +6718,12 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_FLAGS_ENABLE_EPHEMERAL_APPS_DESCRIPTION" desc="Description for the flag to enable ephemeral apps.">
Enables experimentation with ephemeral apps, which are launched without installing in Chrome.
</message>
+ <message name="IDS_FLAGS_ENABLE_LINKABLE_EPHEMERAL_APPS_NAME" desc="Name of the flag to enable linkable ephemeral apps.">
+ Enable experimental linkable ephemeral apps.
+ </message>
+ <message name="IDS_FLAGS_ENABLE_LINKABLE_EPHEMERAL_APPS_DESCRIPTION" desc="Description for the flag to enable linkable ephemeral apps.">
+ Enables experimentation with launching ephemeral apps from hyperlinks. For example, links to Chrome Web Store app detail pages in Google search results will launch the app rather than navigate to the detail page.
+ </message>
<message name="IDS_FLAGS_ENABLE_SERVICE_WORKER_NAME" desc="Name of the flag to enable streamlined ServiceWorker.">
Enable support for ServiceWorker.
</message>
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 95de305..ff9d3e5 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -1842,6 +1842,13 @@ const Experiment kExperiments[] = {
SINGLE_VALUE_TYPE(switches::kEnableEphemeralApps)
},
{
+ "enable-linkable-ephemeral-apps",
+ IDS_FLAGS_ENABLE_LINKABLE_EPHEMERAL_APPS_NAME,
+ IDS_FLAGS_ENABLE_LINKABLE_EPHEMERAL_APPS_DESCRIPTION,
+ kOsWin | kOsLinux | kOsCrOS,
+ SINGLE_VALUE_TYPE(switches::kEnableLinkableEphemeralApps)
+ },
+ {
"enable-service-worker",
IDS_FLAGS_ENABLE_SERVICE_WORKER_NAME,
IDS_FLAGS_ENABLE_SERVICE_WORKER_DESCRIPTION,
diff --git a/chrome/browser/apps/ephemeral_app_throttle.cc b/chrome/browser/apps/ephemeral_app_throttle.cc
new file mode 100644
index 0000000..fafda3f
--- /dev/null
+++ b/chrome/browser/apps/ephemeral_app_throttle.cc
@@ -0,0 +1,114 @@
+// Copyright 2013 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.
+
+#include "chrome/browser/apps/ephemeral_app_throttle.h"
+
+#include "base/command_line.h"
+#include "chrome/browser/apps/ephemeral_app_launcher.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/extensions/extension_system.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_io_data.h"
+#include "chrome/browser/ui/extensions/application_launch.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/extensions/extension_constants.h"
+#include "components/navigation_interception/intercept_navigation_resource_throttle.h"
+#include "components/navigation_interception/navigation_params.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/resource_throttle.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_view.h"
+#include "net/url_request/url_request.h"
+
+using content::BrowserThread;
+using content::WebContents;
+using extensions::Extension;
+
+namespace {
+
+bool LaunchEphemeralApp(
+ const std::string& app_id,
+ content::RenderViewHost* source,
+ const navigation_interception::NavigationParams& params) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ // Redirect top-level navigations only.
+ if (source->IsSubframe())
+ return false;
+
+ WebContents* web_contents = WebContents::FromRenderViewHost(source);
+ if (!web_contents)
+ return false;
+
+ Profile* profile =
+ Profile::FromBrowserContext(web_contents->GetBrowserContext());
+ if (!profile)
+ return false;
+
+ ExtensionService* service =
+ extensions::ExtensionSystem::Get(profile)->extension_service();
+ DCHECK(service);
+ const Extension* extension = service->GetExtensionById(app_id, false);
+
+ if (extension && extension->is_app()) {
+ // If the app is already installed, launch it.
+ AppLaunchParams params(profile, extension, NEW_FOREGROUND_TAB);
+ params.desktop_type = chrome::GetHostDesktopTypeForNativeView(
+ web_contents->GetView()->GetNativeView());
+ OpenApplication(params);
+ return true;
+ }
+
+ if (!extension) {
+ // Install ephemeral app and launch.
+ scoped_refptr<EphemeralAppLauncher> installer =
+ EphemeralAppLauncher::CreateForLink(app_id, web_contents);
+ installer->Start();
+ return true;
+ }
+
+ return false;
+}
+
+} // namespace
+
+// static
+content::ResourceThrottle*
+EphemeralAppThrottle::MaybeCreateThrottleForLaunch(
+ net::URLRequest* request,
+ ProfileIOData* profile_io_data) {
+ if (!CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableLinkableEphemeralApps))
+ return NULL;
+
+ if (request->method() != "GET" || !request->url().SchemeIsHTTPOrHTTPS())
+ return NULL;
+
+ // Not supported for incognito profiles.
+ if (profile_io_data->is_incognito())
+ return NULL;
+
+ // Only watch for links in Google search results.
+ if (request->referrer().find("https://www.google.com") == std::string::npos)
+ return NULL;
+
+ // Crudely watch for links to Chrome Web Store detail pages and assume that
+ // the app ID will be after the last slash of the URL. We cannot even
+ // differentiate between apps and extensions, so attempt to launch both.
+ // This is obviously for demonstration purposes only and will be implemented
+ // properly in production code - for example, links to ephemeral apps could
+ // have a new scheme.
+ if (request->url().spec().find(
+ extension_urls::GetWebstoreItemDetailURLPrefix()) != 0)
+ return NULL;
+
+ std::string app_id(request->url().ExtractFileName());
+ if (!Extension::IdIsValid(app_id))
+ return NULL;
+
+ return new navigation_interception::InterceptNavigationResourceThrottle(
+ request,
+ base::Bind(&LaunchEphemeralApp, app_id));
+}
diff --git a/chrome/browser/apps/ephemeral_app_throttle.h b/chrome/browser/apps/ephemeral_app_throttle.h
new file mode 100644
index 0000000..3ae429f
--- /dev/null
+++ b/chrome/browser/apps/ephemeral_app_throttle.h
@@ -0,0 +1,33 @@
+// Copyright 2013 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_APPS_EPHEMERAL_APP_THROTTLE_H_
+#define CHROME_BROWSER_APPS_EPHEMERAL_APP_THROTTLE_H_
+
+#include "base/basictypes.h"
+
+namespace content {
+class ResourceThrottle;
+}
+
+namespace net {
+class URLRequest;
+}
+
+class ProfileIOData;
+
+// This class creates resource throttles that will launch ephemeral apps for
+// links to Chrome Web Store detail pages instead of opening the page in the
+// browser. This will only occur if the enable-ephemeral-apps switch is enabled.
+class EphemeralAppThrottle {
+ public:
+ static content::ResourceThrottle* MaybeCreateThrottleForLaunch(
+ net::URLRequest* request,
+ ProfileIOData* profile_io_data);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(EphemeralAppThrottle);
+};
+
+#endif // CHROME_BROWSER_APPS_EPHEMERAL_APP_THROTTLE_H_
diff --git a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc
index 9dd6550..8393659 100644
--- a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc
+++ b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc
@@ -77,6 +77,7 @@
#include "components/navigation_interception/intercept_navigation_delegate.h"
#else
#include "chrome/browser/apps/app_url_redirector.h"
+#include "chrome/browser/apps/ephemeral_app_throttle.h"
#endif
#if defined(OS_CHROMEOS)
@@ -257,6 +258,13 @@ void ChromeResourceDispatcherHostDelegate::RequestBeginning(
AppUrlRedirector::MaybeCreateThrottleFor(request, io_data);
if (url_to_app_throttle)
throttles->push_back(url_to_app_throttle);
+
+ // Experimental: Launch ephemeral apps from search results.
+ content::ResourceThrottle* ephemeral_app_throttle =
+ EphemeralAppThrottle::MaybeCreateThrottleForLaunch(
+ request, io_data);
+ if (ephemeral_app_throttle)
+ throttles->push_back(ephemeral_app_throttle);
#endif
}
diff --git a/chrome/chrome_browser_extensions.gypi b/chrome/chrome_browser_extensions.gypi
index f391e4d..3990850 100644
--- a/chrome/chrome_browser_extensions.gypi
+++ b/chrome/chrome_browser_extensions.gypi
@@ -76,6 +76,8 @@
'browser/apps/ephemeral_app_service.h',
'browser/apps/ephemeral_app_service_factory.cc',
'browser/apps/ephemeral_app_service_factory.h',
+ 'browser/apps/ephemeral_app_throttle.cc',
+ 'browser/apps/ephemeral_app_throttle.h',
'browser/apps/shortcut_manager.cc',
'browser/apps/shortcut_manager.h',
'browser/apps/shortcut_manager_factory.cc',
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 70802d5..1238342 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -662,6 +662,9 @@ const char kEnableIPv6[] = "enable-ipv6";
// attempt to use the existing connection.
const char kEnableIPPooling[] = "enable-ip-pooling";
+// Enables experimentation with launching ephemeral apps via hyperlinks.
+const char kEnableLinkableEphemeralApps[] = "enable-linkable-ephemeral-apps";
+
// Enable always using the local NTP for the first NTP load of a new window.
const char kEnableLocalFirstLoadNTP[] = "enable-local-first-load-ntp";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index dba16e7..687fa7c 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -188,6 +188,7 @@ extern const char kEnableHttp2Draft04[];
extern const char kEnableInlineSignin[];
extern const char kEnableIPPooling[];
extern const char kEnableIPv6[];
+extern const char kEnableLinkableEphemeralApps[];
extern const char kEnableLocalFirstLoadNTP[];
extern const char kEnableManagedStorage[];
extern const char kEnableMemoryInfo[];