Add an API for hosted apps to check their install and running states.
BUG=107216
TEST=ChromeAppAPITest.*
Review URL: http://codereview.chromium.org/10174001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@133722 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/extensions/chrome_app_api_browsertest.cc b/chrome/browser/extensions/chrome_app_api_browsertest.cc
index 44e91cc..865c44e 100644
--- a/chrome/browser/extensions/chrome_app_api_browsertest.cc
+++ b/chrome/browser/extensions/chrome_app_api_browsertest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -10,6 +10,8 @@
#include "base/string_number_conversions.h"
#include "base/values.h"
#include "chrome/browser/extensions/extension_browsertest.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension.h"
@@ -21,14 +23,41 @@
class ChromeAppAPITest : public ExtensionBrowserTest {
protected:
- bool IsAppInstalled() {
+ bool IsAppInstalled() { return IsAppInstalled(L""); }
+ bool IsAppInstalled(const std::wstring& frame_xpath) {
std::wstring get_app_is_installed =
L"window.domAutomationController.send(window.chrome.app.isInstalled);";
bool result;
CHECK(
ui_test_utils::ExecuteJavaScriptAndExtractBool(
browser()->GetSelectedWebContents()->GetRenderViewHost(),
- L"", get_app_is_installed, &result));
+ frame_xpath, get_app_is_installed, &result));
+ return result;
+ }
+
+ std::string InstallState() { return InstallState(L""); }
+ std::string InstallState(const std::wstring& frame_xpath) {
+ std::wstring get_app_install_state =
+ L"window.chrome.app.installState("
+ L"function(s) { window.domAutomationController.send(s); });";
+ std::string result;
+ CHECK(
+ ui_test_utils::ExecuteJavaScriptAndExtractString(
+ browser()->GetSelectedWebContents()->GetRenderViewHost(),
+ frame_xpath, get_app_install_state, &result));
+ return result;
+ }
+
+ std::string RunningState() { return RunningState(L""); }
+ std::string RunningState(const std::wstring& frame_xpath) {
+ std::wstring get_app_install_state =
+ L"window.domAutomationController.send("
+ L"window.chrome.app.runningState());";
+ std::string result;
+ CHECK(
+ ui_test_utils::ExecuteJavaScriptAndExtractString(
+ browser()->GetSelectedWebContents()->GetRenderViewHost(),
+ frame_xpath, get_app_install_state, &result));
return result;
}
@@ -181,3 +210,97 @@
EXPECT_TRUE(app_details.get());
EXPECT_TRUE(app_details->Equals(extension->manifest()->value()));
}
+
+
+IN_PROC_BROWSER_TEST_F(ChromeAppAPITest, InstallAndRunningState) {
+ std::string app_host("app.com");
+ std::string non_app_host("nonapp.com");
+
+ host_resolver()->AddRule(app_host, "127.0.0.1");
+ host_resolver()->AddRule(non_app_host, "127.0.0.1");
+ ASSERT_TRUE(test_server()->Start());
+
+ GURL test_file_url(test_server()->GetURL(
+ "files/extensions/get_app_details_for_frame.html"));
+ GURL::Replacements replace_host;
+
+ replace_host.SetHostStr(app_host);
+ GURL app_url(test_file_url.ReplaceComponents(replace_host));
+
+ replace_host.SetHostStr(non_app_host);
+ GURL non_app_url(test_file_url.ReplaceComponents(replace_host));
+
+ // Before the app is installed, app.com does not think that it is installed
+ ui_test_utils::NavigateToURL(browser(), app_url);
+
+ EXPECT_EQ("not_installed", InstallState());
+ EXPECT_EQ("cannot_run", RunningState());
+ EXPECT_FALSE(IsAppInstalled());
+
+ const Extension* extension = LoadExtension(
+ test_data_dir_.AppendASCII("app_dot_com_app"));
+ ASSERT_TRUE(extension);
+
+ EXPECT_EQ("installed", InstallState());
+ EXPECT_EQ("ready_to_run", RunningState());
+ EXPECT_FALSE(IsAppInstalled());
+
+ // Reloading the page should put the tab in an app process.
+ ui_test_utils::NavigateToURL(browser(), app_url);
+ EXPECT_EQ("installed", InstallState());
+ EXPECT_EQ("running", RunningState());
+ EXPECT_TRUE(IsAppInstalled());
+
+ // Disable the extension and verify the state.
+ browser()->profile()->GetExtensionService()->DisableExtension(
+ extension->id(), Extension::DISABLE_PERMISSIONS_INCREASE);
+ ui_test_utils::NavigateToURL(browser(), app_url);
+
+ EXPECT_EQ("disabled", InstallState());
+ EXPECT_EQ("cannot_run", RunningState());
+ EXPECT_FALSE(IsAppInstalled());
+
+ browser()->profile()->GetExtensionService()->EnableExtension(extension->id());
+ EXPECT_EQ("installed", InstallState());
+ EXPECT_EQ("ready_to_run", RunningState());
+ EXPECT_FALSE(IsAppInstalled());
+
+ // The non-app URL should still not be installed or running.
+ ui_test_utils::NavigateToURL(browser(), non_app_url);
+
+ EXPECT_EQ("not_installed", InstallState());
+ EXPECT_EQ("cannot_run", RunningState());
+ EXPECT_FALSE(IsAppInstalled());
+
+ EXPECT_EQ("installed", InstallState(L"//html/iframe[1]"));
+ EXPECT_EQ("cannot_run", RunningState(L"//html/iframe[1]"));
+ EXPECT_FALSE(IsAppInstalled(L"//html/iframe[1]"));
+
+}
+
+IN_PROC_BROWSER_TEST_F(ChromeAppAPITest, InstallAndRunningStateFrame) {
+ std::string app_host("app.com");
+ std::string non_app_host("nonapp.com");
+
+ host_resolver()->AddRule(app_host, "127.0.0.1");
+ host_resolver()->AddRule(non_app_host, "127.0.0.1");
+ ASSERT_TRUE(test_server()->Start());
+
+ GURL test_file_url(test_server()->GetURL(
+ "files/extensions/get_app_details_for_frame_reversed.html"));
+ GURL::Replacements replace_host;
+
+ replace_host.SetHostStr(app_host);
+ GURL app_url(test_file_url.ReplaceComponents(replace_host));
+
+ replace_host.SetHostStr(non_app_host);
+ GURL non_app_url(test_file_url.ReplaceComponents(replace_host));
+
+ // Check the install and running state of a non-app iframe running
+ // within an app.
+ ui_test_utils::NavigateToURL(browser(), app_url);
+
+ EXPECT_EQ("not_installed", InstallState(L"//html/iframe[1]"));
+ EXPECT_EQ("cannot_run", RunningState(L"//html/iframe[1]"));
+ EXPECT_FALSE(IsAppInstalled(L"//html/iframe[1]"));
+}
diff --git a/chrome/browser/extensions/extension_service.h b/chrome/browser/extensions/extension_service.h
index 68e2e5f..7ddbca4 100644
--- a/chrome/browser/extensions/extension_service.h
+++ b/chrome/browser/extensions/extension_service.h
@@ -710,7 +710,6 @@
scoped_ptr<extensions::SettingsFrontend> settings_frontend_;
// The current list of installed extensions.
- // TODO(aa): This should use chrome/common/extensions/extension_set.h.
ExtensionSet extensions_;
// The list of installed extensions that have been disabled.
diff --git a/chrome/browser/extensions/extension_tab_helper.cc b/chrome/browser/extensions/extension_tab_helper.cc
index b45b0adf..ab65db37 100644
--- a/chrome/browser/extensions/extension_tab_helper.cc
+++ b/chrome/browser/extensions/extension_tab_helper.cc
@@ -137,6 +137,8 @@
OnInlineWebstoreInstall)
IPC_MESSAGE_HANDLER(ExtensionHostMsg_GetAppNotifyChannel,
OnGetAppNotifyChannel)
+ IPC_MESSAGE_HANDLER(ExtensionHostMsg_GetAppInstallState,
+ OnGetAppInstallState);
IPC_MESSAGE_HANDLER(ExtensionHostMsg_Request, OnRequest)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
@@ -223,6 +225,28 @@
// We'll get called back in AppNotifyChannelSetupComplete.
}
+void ExtensionTabHelper::OnGetAppInstallState(const GURL& requestor_url,
+ int return_route_id,
+ int callback_id) {
+ Profile* profile =
+ Profile::FromBrowserContext(web_contents()->GetBrowserContext());
+ ExtensionService* extension_service = profile->GetExtensionService();
+ const ExtensionSet* extensions = extension_service->extensions();
+ const ExtensionSet* disabled = extension_service->disabled_extensions();
+
+ ExtensionURLInfo url(requestor_url);
+ std::string state;
+ if (extensions->GetHostedAppByURL(url))
+ state = extension_misc::kAppStateInstalled;
+ else if (disabled->GetHostedAppByURL(url))
+ state = extension_misc::kAppStateDisabled;
+ else
+ state = extension_misc::kAppStateNotInstalled;
+
+ Send(new ExtensionMsg_GetAppInstallStateResponse(
+ return_route_id, state, callback_id));
+}
+
void ExtensionTabHelper::AppNotifyChannelSetupComplete(
const std::string& channel_id,
const std::string& error,
diff --git a/chrome/browser/extensions/extension_tab_helper.h b/chrome/browser/extensions/extension_tab_helper.h
index 79d108b..e0bbd26 100644
--- a/chrome/browser/extensions/extension_tab_helper.h
+++ b/chrome/browser/extensions/extension_tab_helper.h
@@ -116,6 +116,9 @@
const std::string& client_id,
int return_route_id,
int callback_id);
+ void OnGetAppInstallState(const GURL& requestor_url,
+ int return_route_id,
+ int callback_id);
void OnRequest(const ExtensionHostMsg_Request_Params& params);
// App extensions related methods: