summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzelidrag@chromium.org <zelidrag@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-09 00:43:10 +0000
committerzelidrag@chromium.org <zelidrag@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-09 00:43:10 +0000
commit4333f21ceae038eb3a0756c9b83b57672d84e7c6 (patch)
tree358c479bd23d9b639bd3545c57a6c98e940d0ac6
parentf18e74688fbc5215295841815c2c7c895e4ac7cd (diff)
downloadchromium_src-4333f21ceae038eb3a0756c9b83b57672d84e7c6.zip
chromium_src-4333f21ceae038eb3a0756c9b83b57672d84e7c6.tar.gz
chromium_src-4333f21ceae038eb3a0756c9b83b57672d84e7c6.tar.bz2
Merge 225400 "Add "kiosk_only" manifest attribute for platform a..."
> Add "kiosk_only" manifest attribute for platform apps. > > This top-level manifest attribute enforces that the app can only be installed and run in ChromeOS kiosk mode. > > BUG=284964 > TEST=added new tests > > Review URL: https://codereview.chromium.org/23604068 TBR=tengs@chromium.org Review URL: https://codereview.chromium.org/26227005 git-svn-id: svn://svn.chromium.org/chrome/branches/1650/src@227636 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--apps/DEPS2
-rw-r--r--apps/launcher.cc33
-rw-r--r--chrome/app/generated_resources.grd3
-rw-r--r--chrome/browser/chromeos/app_mode/startup_app_launcher.cc4
-rw-r--r--chrome/browser/chromeos/login/fake_user_manager.cc26
-rw-r--r--chrome/browser/chromeos/login/fake_user_manager.h10
-rw-r--r--chrome/browser/extensions/api/system_display/system_display_api.cc4
-rw-r--r--chrome/browser/extensions/crx_installer.cc18
-rw-r--r--chrome/browser/extensions/crx_installer_browsertest.cc21
-rw-r--r--chrome/browser/ui/webui/extensions/extension_basic_info.cc7
-rw-r--r--chrome/chrome_common.gypi4
-rw-r--r--chrome/common/extensions/api/_manifest_features.json6
-rw-r--r--chrome/common/extensions/chrome_manifest_handlers.cc4
-rw-r--r--chrome/common/extensions/docs/templates/articles/manifest/kiosk_enabled.html7
-rw-r--r--chrome/common/extensions/docs/templates/json/manifest.json6
-rw-r--r--chrome/common/extensions/manifest_handlers/kiosk_enabled_info.cc60
-rw-r--r--chrome/common/extensions/manifest_handlers/kiosk_enabled_info.h42
-rw-r--r--chrome/common/extensions/manifest_handlers/kiosk_mode_info.cc89
-rw-r--r--chrome/common/extensions/manifest_handlers/kiosk_mode_info.h55
-rw-r--r--chrome/common/extensions/manifest_tests/extension_manifests_kiosk_unittest.cc72
-rw-r--r--chrome/test/data/extensions/manifest_tests/kiosk_only_extension.json6
-rw-r--r--chrome/test/data/extensions/manifest_tests/kiosk_only_hosted_app.json15
-rw-r--r--chrome/test/data/extensions/manifest_tests/kiosk_only_invalid.json11
-rw-r--r--chrome/test/data/extensions/manifest_tests/kiosk_only_not_enabled.json10
-rw-r--r--chrome/test/data/extensions/manifest_tests/kiosk_only_packaged_app.json11
-rw-r--r--chrome/test/data/extensions/manifest_tests/kiosk_only_platform_app.json11
-rw-r--r--extensions/common/manifest_constants.cc6
-rw-r--r--extensions/common/manifest_constants.h4
28 files changed, 403 insertions, 144 deletions
diff --git a/apps/DEPS b/apps/DEPS
index 25b5188..62d6854 100644
--- a/apps/DEPS
+++ b/apps/DEPS
@@ -15,6 +15,7 @@ include_rules = [
"+chrome/browser/browser_process.h",
"+chrome/browser/chrome_notification_types.h",
"+chrome/browser/chromeos/drive",
+ "+chrome/browser/chromeos/login/user_manager.h",
"+chrome/browser/lifetime/application_lifetime.h",
"+chrome/browser/profiles",
"+chrome/browser/sessions/session_id.h",
@@ -47,6 +48,7 @@ include_rules = [
"+chrome/common/extensions/extension_messages.h",
"+chrome/common/extensions/extension_set.h",
"+chrome/common/extensions/manifest_handlers/icons_handler.h",
+ "+chrome/common/extensions/manifest_handlers/kiosk_mode_info.h",
"+chrome/common/extensions/permissions/api_permission.h",
"+chrome/common/extensions/permissions/permission_set.h",
]
diff --git a/apps/launcher.cc b/apps/launcher.cc
index aae298f..384d271 100644
--- a/apps/launcher.cc
+++ b/apps/launcher.cc
@@ -26,6 +26,7 @@
#include "chrome/common/extensions/api/app_runtime.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_messages.h"
+#include "chrome/common/extensions/manifest_handlers/kiosk_mode_info.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
@@ -37,6 +38,7 @@
#include "chrome/browser/chromeos/drive/file_errors.h"
#include "chrome/browser/chromeos/drive/file_system_interface.h"
#include "chrome/browser/chromeos/drive/file_system_util.h"
+#include "chrome/browser/chromeos/login/user_manager.h"
#endif
#if defined(OS_WIN)
@@ -313,15 +315,32 @@ void LaunchPlatformAppWithCommandLine(Profile* profile,
const CommandLine* command_line,
const base::FilePath& current_directory) {
#if defined(OS_WIN)
- // On Windows 8's single window Metro mode we can not launch platform apps.
- // Offer to switch Chrome to desktop mode.
- if (win8::IsSingleWindowMetroMode()) {
- AppMetroInfoBarDelegateWin::Create(
- profile, AppMetroInfoBarDelegateWin::LAUNCH_PACKAGED_APP,
- extension->id());
+ // On Windows 8's single window Metro mode we can not launch platform apps.
+ // Offer to switch Chrome to desktop mode.
+ if (win8::IsSingleWindowMetroMode()) {
+ AppMetroInfoBarDelegateWin::Create(
+ profile, AppMetroInfoBarDelegateWin::LAUNCH_PACKAGED_APP,
+ extension->id());
+ return;
+ }
+#endif
+
+ // An app with "kiosk_only" should not be installed and launched
+ // outside of ChromeOS kiosk mode in the first place. This is a defensive
+ // check in case this scenario does occur.
+ if (extensions::KioskModeInfo::IsKioskOnly(extension)) {
+ bool in_kiosk_mode = false;
+#if defined(OS_CHROMEOS)
+ chromeos::UserManager* user_manager = chromeos::UserManager::Get();
+ in_kiosk_mode = user_manager && user_manager->IsLoggedInAsKioskApp();
+#endif
+ if (!in_kiosk_mode) {
+ LOG(ERROR) << "App with 'kiosk_only' attribute must be run in "
+ << " ChromeOS kiosk mode.";
+ NOTREACHED();
return;
}
-#endif
+ }
base::FilePath path;
if (!GetAbsolutePathFromCommandLine(command_line, current_directory, &path)) {
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 479c166..d413c77 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -4445,6 +4445,9 @@ Make sure you do not expose any sensitive information.
<message name="IDS_EXTENSION_INSTALL_DEPENDENCY_NOT_SHARED_MODULE" desc="Error displayed during installation of an extension which tries to imports resources from an extension which is not a shared module.">
Unable to import extension with ID "<ph name="IMPORT_ID">$1<ex>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</ex></ph>" because it is not a shared module.
</message>
+ <message name="IDS_EXTENSION_INSTALL_KIOSK_MODE_ONLY" desc="Error displayed during installation of an app with 'kiosk_only' attribute but user is not in ChromeOS kiosk mode.">
+ App with 'kiosk_only' manifest attribute must be installed in ChromeOS kiosk mode.
+ </message>
<message name="IDS_EXTENSION_OVERLAPPING_WEB_EXTENT" desc="Error message when a user tries to install an app with a web extent that overlaps another installed app.">
Could not add application because it conflicts with "<ph name="APP_NAME">$1<ex>Google Mail</ex></ph>".
</message>
diff --git a/chrome/browser/chromeos/app_mode/startup_app_launcher.cc b/chrome/browser/chromeos/app_mode/startup_app_launcher.cc
index 319e9aa..1a6444c 100644
--- a/chrome/browser/chromeos/app_mode/startup_app_launcher.cc
+++ b/chrome/browser/chromeos/app_mode/startup_app_launcher.cc
@@ -26,7 +26,7 @@
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension.h"
-#include "chrome/common/extensions/manifest_handlers/kiosk_enabled_info.h"
+#include "chrome/common/extensions/manifest_handlers/kiosk_mode_info.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "google_apis/gaia/gaia_auth_consumer.h"
@@ -222,7 +222,7 @@ void StartupAppLauncher::LaunchApp() {
extension_service()->GetInstalledExtension(app_id_);
CHECK(extension);
- if (!extensions::KioskEnabledInfo::IsKioskEnabled(extension)) {
+ if (!extensions::KioskModeInfo::IsKioskEnabled(extension)) {
OnLaunchFailure(KioskAppLaunchError::NOT_KIOSK_ENABLED);
return;
}
diff --git a/chrome/browser/chromeos/login/fake_user_manager.cc b/chrome/browser/chromeos/login/fake_user_manager.cc
index 7539d72..b6b311f 100644
--- a/chrome/browser/chromeos/login/fake_user_manager.cc
+++ b/chrome/browser/chromeos/login/fake_user_manager.cc
@@ -30,6 +30,12 @@ void FakeUserManager::AddUser(const std::string& email) {
user_list_.push_back(user);
}
+void FakeUserManager::AddKioskAppUser(const std::string& kiosk_app_username) {
+ User* user = User::CreateKioskAppUser(kiosk_app_username);
+ user->set_username_hash(kiosk_app_username + kUserIdHashSuffix);
+ user_list_.push_back(user);
+}
+
void FakeUserManager::LoginUser(const std::string& email) {
UserLoggedIn(email, email + kUserIdHashSuffix, false);
}
@@ -70,15 +76,18 @@ void FakeUserManager::UserLoggedIn(const std::string& email,
}
}
+User* FakeUserManager::GetActiveUserInternal() const {
+ if (user_list_.size())
+ return user_list_[0];
+ return NULL;
+}
+
const User* FakeUserManager::GetActiveUser() const {
- return GetActiveUser();
+ return GetActiveUserInternal();
}
User* FakeUserManager::GetActiveUser() {
- // Just return the first user.
- if (user_list_.size())
- return user_list_[0];
- return NULL;
+ return GetActiveUserInternal();
}
void FakeUserManager::SaveUserDisplayName(
@@ -198,7 +207,7 @@ bool FakeUserManager::CanCurrentUserLock() const {
}
bool FakeUserManager::IsUserLoggedIn() const {
- return true;
+ return logged_in_users_.size() > 0;
}
bool FakeUserManager::IsLoggedInAsRegularUser() const {
@@ -222,7 +231,10 @@ bool FakeUserManager::IsLoggedInAsLocallyManagedUser() const {
}
bool FakeUserManager::IsLoggedInAsKioskApp() const {
- return false;
+ const User* active_user = GetActiveUser();
+ return active_user ?
+ active_user->GetType() == User::USER_TYPE_KIOSK_APP :
+ false;
}
bool FakeUserManager::IsLoggedInAsStub() const {
diff --git a/chrome/browser/chromeos/login/fake_user_manager.h b/chrome/browser/chromeos/login/fake_user_manager.h
index 850a4f4..c7ca185 100644
--- a/chrome/browser/chromeos/login/fake_user_manager.h
+++ b/chrome/browser/chromeos/login/fake_user_manager.h
@@ -24,8 +24,11 @@ class FakeUserManager : public UserManager {
// Create and add a new user.
void AddUser(const std::string& email);
- // Calculates the user name hash and calls UserLoggedIn to login a user.
- void LoginUser(const std::string& email);
+ // Create and add a kiosk app user.
+ void AddKioskAppUser(const std::string& kiosk_app_username);
+
+ // Calculates the user name hash and calls UserLoggedIn to login a user.
+ void LoginUser(const std::string& email);
// UserManager overrides.
virtual const UserList& GetUsers() const OVERRIDE;
@@ -134,6 +137,9 @@ class FakeUserManager : public UserManager {
}
private:
+ // We use this internal function for const-correctness.
+ User* GetActiveUserInternal() const;
+
UserList user_list_;
UserList logged_in_users_;
std::string owner_email_;
diff --git a/chrome/browser/extensions/api/system_display/system_display_api.cc b/chrome/browser/extensions/api/system_display/system_display_api.cc
index 36dd2f2..775a429 100644
--- a/chrome/browser/extensions/api/system_display/system_display_api.cc
+++ b/chrome/browser/extensions/api/system_display/system_display_api.cc
@@ -5,7 +5,7 @@
#include "chrome/browser/extensions/api/system_display/system_display_api.h"
#include "base/memory/scoped_ptr.h"
-#include "chrome/common/extensions/manifest_handlers/kiosk_enabled_info.h"
+#include "chrome/common/extensions/manifest_handlers/kiosk_mode_info.h"
namespace extensions {
@@ -37,7 +37,7 @@ bool SystemDisplaySetDisplayPropertiesFunction::RunImpl() {
SetError("Function available only on ChromeOS.");
return false;
#else
- if (!KioskEnabledInfo::IsKioskEnabled(GetExtension())) {
+ if (!KioskModeInfo::IsKioskEnabled(GetExtension())) {
SetError("The extension needs to be kiosk enabled to use the function.");
return false;
}
diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc
index 2f793a2..2205608 100644
--- a/chrome/browser/extensions/crx_installer.cc
+++ b/chrome/browser/extensions/crx_installer.cc
@@ -38,6 +38,7 @@
#include "chrome/common/extensions/extension_file_util.h"
#include "chrome/common/extensions/extension_icon_set.h"
#include "chrome/common/extensions/feature_switch.h"
+#include "chrome/common/extensions/manifest_handlers/kiosk_mode_info.h"
#include "chrome/common/extensions/manifest_handlers/shared_module_info.h"
#include "chrome/common/extensions/manifest_url_handler.h"
#include "chrome/common/extensions/permissions/permission_set.h"
@@ -55,6 +56,10 @@
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
+#if defined(OS_CHROMEOS)
+#include "chrome/browser/chromeos/login/user_manager.h"
+#endif
+
using content::BrowserThread;
using content::UserMetricsAction;
using extensions::SharedModuleInfo;
@@ -512,6 +517,19 @@ void CrxInstaller::ConfirmInstall() {
if (!service || service->browser_terminating())
return;
+ if (KioskModeInfo::IsKioskOnly(installer_.extension())) {
+ bool in_kiosk_mode = false;
+#if defined(OS_CHROMEOS)
+ chromeos::UserManager* user_manager = chromeos::UserManager::Get();
+ in_kiosk_mode = user_manager && user_manager->IsLoggedInAsKioskApp();
+#endif
+ if (!in_kiosk_mode) {
+ ReportFailureFromUIThread(CrxInstallerError(
+ l10n_util::GetStringUTF16(
+ IDS_EXTENSION_INSTALL_KIOSK_MODE_ONLY)));
+ }
+ }
+
string16 error = installer_.CheckManagementPolicy();
if (!error.empty()) {
// We don't want to show the error infobar for installs from the WebStore,
diff --git a/chrome/browser/extensions/crx_installer_browsertest.cc b/chrome/browser/extensions/crx_installer_browsertest.cc
index 105b4c6..a916842 100644
--- a/chrome/browser/extensions/crx_installer_browsertest.cc
+++ b/chrome/browser/extensions/crx_installer_browsertest.cc
@@ -25,6 +25,11 @@
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
+#if defined(OS_CHROMEOS)
+#include "chrome/browser/chromeos/login/fake_user_manager.h"
+#include "chrome/browser/chromeos/login/user_manager.h"
+#endif
+
class SkBitmap;
namespace extensions {
@@ -477,4 +482,20 @@ IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, NonStrictManifestCheck) {
EXPECT_TRUE(mock_prompt->did_succeed());
}
+IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, KioskOnlyTest) {
+ base::FilePath crx_path =
+ test_data_dir_.AppendASCII("kiosk/kiosk_only.crx");
+ EXPECT_FALSE(InstallExtension(crx_path, 0));
+#if defined(OS_CHROMEOS)
+ // Simulate ChromeOS kiosk mode. |scoped_user_manager| will take over
+ // lifetime of |user_manager|.
+ chromeos::FakeUserManager* fake_user_manager =
+ new chromeos::FakeUserManager();
+ fake_user_manager->AddKioskAppUser("example@example.com");
+ fake_user_manager->LoginUser("example@example.com");
+ chromeos::ScopedUserManagerEnabler scoped_user_manager(fake_user_manager);
+ EXPECT_TRUE(InstallExtension(crx_path, 1));
+#endif
+}
+
} // namespace extensions
diff --git a/chrome/browser/ui/webui/extensions/extension_basic_info.cc b/chrome/browser/ui/webui/extensions/extension_basic_info.cc
index 606ee2b..0e6b3e5 100644
--- a/chrome/browser/ui/webui/extensions/extension_basic_info.cc
+++ b/chrome/browser/ui/webui/extensions/extension_basic_info.cc
@@ -6,7 +6,7 @@
#include "base/values.h"
#include "chrome/common/extensions/extension.h"
-#include "chrome/common/extensions/manifest_handlers/kiosk_enabled_info.h"
+#include "chrome/common/extensions/manifest_handlers/kiosk_mode_info.h"
#include "chrome/common/extensions/manifest_handlers/offline_enabled_info.h"
#include "chrome/common/extensions/manifest_url_handler.h"
@@ -19,6 +19,7 @@ const char kHomepageUrlKey[] = "homepageUrl";
const char kIdKey[] = "id";
const char kNameKey[] = "name";
const char kKioskEnabledKey[] = "kioskEnabled";
+const char kKioskOnlyKey[] = "kioskOnly";
const char kOfflineEnabledKey[] = "offlineEnabled";
const char kOptionsUrlKey[] = "optionsUrl";
const char kDetailsUrlKey[] = "detailsUrl";
@@ -36,7 +37,9 @@ void GetExtensionBasicInfo(const Extension* extension,
info->SetString(kNameKey, extension->name());
info->SetBoolean(kEnabledKey, enabled);
info->SetBoolean(kKioskEnabledKey,
- KioskEnabledInfo::IsKioskEnabled(extension));
+ KioskModeInfo::IsKioskEnabled(extension));
+ info->SetBoolean(kKioskOnlyKey,
+ KioskModeInfo::IsKioskOnly(extension));
info->SetBoolean(kOfflineEnabledKey,
OfflineEnabledInfo::IsOfflineEnabled(extension));
info->SetString(kVersionKey, extension->VersionString());
diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi
index 7a95ad7..3157836 100644
--- a/chrome/chrome_common.gypi
+++ b/chrome/chrome_common.gypi
@@ -283,8 +283,8 @@
'common/extensions/manifest_handlers/externally_connectable.h',
'common/extensions/manifest_handlers/icons_handler.cc',
'common/extensions/manifest_handlers/icons_handler.h',
- 'common/extensions/manifest_handlers/kiosk_enabled_info.cc',
- 'common/extensions/manifest_handlers/kiosk_enabled_info.h',
+ 'common/extensions/manifest_handlers/kiosk_mode_info.cc',
+ 'common/extensions/manifest_handlers/kiosk_mode_info.h',
'common/extensions/manifest_handlers/minimum_chrome_version_checker.cc',
'common/extensions/manifest_handlers/minimum_chrome_version_checker.h',
'common/extensions/manifest_handlers/nacl_modules_handler.cc',
diff --git a/chrome/common/extensions/api/_manifest_features.json b/chrome/common/extensions/api/_manifest_features.json
index 81a8427..1a86f92 100644
--- a/chrome/common/extensions/api/_manifest_features.json
+++ b/chrome/common/extensions/api/_manifest_features.json
@@ -204,6 +204,12 @@
"platform_app"
]
},
+ "kiosk_only": {
+ "channel": "dev",
+ "extension_types": [
+ "platform_app"
+ ]
+ },
"manifest_version": {
"channel": "stable",
"extension_types": "all"
diff --git a/chrome/common/extensions/chrome_manifest_handlers.cc b/chrome/common/extensions/chrome_manifest_handlers.cc
index 07137d9..3a97cca 100644
--- a/chrome/common/extensions/chrome_manifest_handlers.cc
+++ b/chrome/common/extensions/chrome_manifest_handlers.cc
@@ -32,7 +32,7 @@
#include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
#include "chrome/common/extensions/manifest_handlers/externally_connectable.h"
#include "chrome/common/extensions/manifest_handlers/icons_handler.h"
-#include "chrome/common/extensions/manifest_handlers/kiosk_enabled_info.h"
+#include "chrome/common/extensions/manifest_handlers/kiosk_mode_info.h"
#include "chrome/common/extensions/manifest_handlers/minimum_chrome_version_checker.h"
#include "chrome/common/extensions/manifest_handlers/nacl_modules_handler.h"
#include "chrome/common/extensions/manifest_handlers/offline_enabled_info.h"
@@ -70,7 +70,7 @@ void RegisterChromeManifestHandlers() {
#if defined(OS_CHROMEOS)
(new InputComponentsHandler)->Register();
#endif
- (new KioskEnabledHandler)->Register();
+ (new KioskModeHandler)->Register();
(new ManagedModeHandler)->Register();
(new MediaGalleriesHandlerParser)->Register();
(new MimeTypesHandlerParser)->Register();
diff --git a/chrome/common/extensions/docs/templates/articles/manifest/kiosk_enabled.html b/chrome/common/extensions/docs/templates/articles/manifest/kiosk_enabled.html
index 0256389..8eb7b58 100644
--- a/chrome/common/extensions/docs/templates/articles/manifest/kiosk_enabled.html
+++ b/chrome/common/extensions/docs/templates/articles/manifest/kiosk_enabled.html
@@ -6,3 +6,10 @@ In kiosk mode, the platform app window will cover the entire surface of the
display (forced full screen). The kiosk-enabled apps are expected to be designed
with this constraint in mind.
</p>
+
+<h1 id="kiosk_only">Manifest - Kiosk Only</h1>
+
+<p>
+Whether the packaged app is only intended to be installed and run in ChromeOS
+kiosk mode. This field is only valid if the <code>kiosk_enabled</code> field is <code>true</code>.
+</p>
diff --git a/chrome/common/extensions/docs/templates/json/manifest.json b/chrome/common/extensions/docs/templates/json/manifest.json
index b3ac91f..2cb5331 100644
--- a/chrome/common/extensions/docs/templates/json/manifest.json
+++ b/chrome/common/extensions/docs/templates/json/manifest.json
@@ -75,7 +75,11 @@
"example": "publicKey"
},
"kiosk_enabled": {
- "documentation": "manifest/kiosk_enabled.html",
+ "documentation": "manifest/kiosk_enabled.html#kiosk_enabled",
+ "example": true
+ },
+ "kiosk_only": {
+ "documentation": "manifest/kiosk_enabled.html#kiosk_only",
"example": true
},
"manifest_version": {
diff --git a/chrome/common/extensions/manifest_handlers/kiosk_enabled_info.cc b/chrome/common/extensions/manifest_handlers/kiosk_enabled_info.cc
deleted file mode 100644
index 4c50de5..0000000
--- a/chrome/common/extensions/manifest_handlers/kiosk_enabled_info.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 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/common/extensions/manifest_handlers/kiosk_enabled_info.h"
-
-#include "base/memory/scoped_ptr.h"
-#include "base/strings/string16.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/values.h"
-#include "extensions/common/manifest_constants.h"
-
-namespace extensions {
-
-namespace keys = manifest_keys;
-
-KioskEnabledInfo::KioskEnabledInfo(bool is_kiosk_enabled)
- : kiosk_enabled(is_kiosk_enabled) {
-}
-
-KioskEnabledInfo::~KioskEnabledInfo() {
-}
-
-// static
-bool KioskEnabledInfo::IsKioskEnabled(const Extension* extension) {
- KioskEnabledInfo* info = static_cast<KioskEnabledInfo*>(
- extension->GetManifestData(keys::kKioskEnabled));
- return info ? info->kiosk_enabled : false;
-}
-
-KioskEnabledHandler::KioskEnabledHandler() {
-}
-
-KioskEnabledHandler::~KioskEnabledHandler() {
-}
-
-bool KioskEnabledHandler::Parse(Extension* extension, string16* error) {
- DCHECK(extension->manifest()->HasKey(keys::kKioskEnabled));
-
- bool kiosk_enabled = false;
- if (!extension->manifest()->GetBoolean(keys::kKioskEnabled, &kiosk_enabled)) {
- *error = ASCIIToUTF16(manifest_errors::kInvalidKioskEnabled);
- return false;
- }
-
- // All other use cases should be already filtered out by manifest feature
- // checks.
- DCHECK(extension->is_platform_app());
-
- extension->SetManifestData(keys::kKioskEnabled,
- new KioskEnabledInfo(kiosk_enabled));
- return true;
-}
-
-const std::vector<std::string> KioskEnabledHandler::Keys() const {
- return SingleKey(keys::kKioskEnabled);
-}
-
-} // namespace extensions
diff --git a/chrome/common/extensions/manifest_handlers/kiosk_enabled_info.h b/chrome/common/extensions/manifest_handlers/kiosk_enabled_info.h
deleted file mode 100644
index 3c61b08..0000000
--- a/chrome/common/extensions/manifest_handlers/kiosk_enabled_info.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 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_COMMON_EXTENSIONS_MANIFEST_HANDLERS_KIOSK_ENABLED_INFO_H_
-#define CHROME_COMMON_EXTENSIONS_MANIFEST_HANDLERS_KIOSK_ENABLED_INFO_H_
-
-#include <string>
-#include <vector>
-
-#include "chrome/common/extensions/extension.h"
-#include "chrome/common/extensions/manifest_handler.h"
-#include "extensions/common/manifest.h"
-
-namespace extensions {
-
-struct KioskEnabledInfo : public Extension::ManifestData {
- explicit KioskEnabledInfo(bool is_kiosk_enabled);
- virtual ~KioskEnabledInfo();
-
- bool kiosk_enabled;
-
- // Whether the extension or app should be enabled in app kiosk mode.
- static bool IsKioskEnabled(const Extension* extension);
-};
-
-// Parses the "kiosk_enabled" manifest key.
-class KioskEnabledHandler : public ManifestHandler {
- public:
- KioskEnabledHandler();
- virtual ~KioskEnabledHandler();
-
- virtual bool Parse(Extension* extension, string16* error) OVERRIDE;
- private:
- virtual const std::vector<std::string> Keys() const OVERRIDE;
-
- DISALLOW_COPY_AND_ASSIGN(KioskEnabledHandler);
-};
-
-} // namespace extensions
-
-#endif // CHROME_COMMON_EXTENSIONS_MANIFEST_HANDLERS_KIOSK_ENABLED_INFO_H_
diff --git a/chrome/common/extensions/manifest_handlers/kiosk_mode_info.cc b/chrome/common/extensions/manifest_handlers/kiosk_mode_info.cc
new file mode 100644
index 0000000..e610490
--- /dev/null
+++ b/chrome/common/extensions/manifest_handlers/kiosk_mode_info.cc
@@ -0,0 +1,89 @@
+// 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/common/extensions/manifest_handlers/kiosk_mode_info.h"
+
+#include "base/memory/scoped_ptr.h"
+#include "base/strings/string16.h"
+#include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/values.h"
+#include "extensions/common/manifest_constants.h"
+
+namespace extensions {
+
+namespace keys = manifest_keys;
+
+KioskModeInfo::KioskModeInfo(KioskStatus kiosk_status)
+ : kiosk_status(kiosk_status) {
+}
+
+KioskModeInfo::~KioskModeInfo() {
+}
+
+// static
+bool KioskModeInfo::IsKioskEnabled(const Extension* extension) {
+ KioskModeInfo* info = static_cast<KioskModeInfo*>(
+ extension->GetManifestData(keys::kKioskMode));
+ return info ? info->kiosk_status != NONE : false;
+}
+
+// static
+bool KioskModeInfo::IsKioskOnly(const Extension* extension) {
+ KioskModeInfo* info = static_cast<KioskModeInfo*>(
+ extension->GetManifestData(keys::kKioskMode));
+ return info ? info->kiosk_status == ONLY : false;
+}
+
+KioskModeHandler::KioskModeHandler() {
+ supported_keys_.push_back(keys::kKioskEnabled);
+ supported_keys_.push_back(keys::kKioskOnly);
+}
+
+KioskModeHandler::~KioskModeHandler() {
+}
+
+bool KioskModeHandler::Parse(Extension* extension, string16* error) {
+ const Manifest* manifest = extension->manifest();
+ DCHECK(manifest->HasKey(keys::kKioskEnabled) ||
+ manifest->HasKey(keys::kKioskOnly));
+
+ bool kiosk_enabled = false;
+ if (manifest->HasKey(keys::kKioskEnabled) &&
+ !manifest->GetBoolean(keys::kKioskEnabled, &kiosk_enabled)) {
+ *error = ASCIIToUTF16(manifest_errors::kInvalidKioskEnabled);
+ return false;
+ }
+
+ bool kiosk_only = false;
+ if (manifest->HasKey(keys::kKioskOnly) &&
+ !manifest->GetBoolean(keys::kKioskOnly, &kiosk_only)) {
+ *error = ASCIIToUTF16(manifest_errors::kInvalidKioskOnly);
+ return false;
+ }
+
+ if (kiosk_only && !kiosk_enabled) {
+ *error = ASCIIToUTF16(manifest_errors::kInvalidKioskOnlyButNotEnabled);
+ return false;
+ }
+
+ // All other use cases should be already filtered out by manifest feature
+ // checks.
+ DCHECK(extension->is_platform_app());
+
+ KioskModeInfo::KioskStatus kiosk_status = KioskModeInfo::NONE;
+ if (kiosk_enabled)
+ kiosk_status = kiosk_only ? KioskModeInfo::ONLY : KioskModeInfo::ENABLED;
+
+ extension->SetManifestData(keys::kKioskMode,
+ new KioskModeInfo(kiosk_status));
+
+ return true;
+}
+
+const std::vector<std::string> KioskModeHandler::Keys() const {
+ return supported_keys_;
+}
+
+} // namespace extensions
diff --git a/chrome/common/extensions/manifest_handlers/kiosk_mode_info.h b/chrome/common/extensions/manifest_handlers/kiosk_mode_info.h
new file mode 100644
index 0000000..05a553a
--- /dev/null
+++ b/chrome/common/extensions/manifest_handlers/kiosk_mode_info.h
@@ -0,0 +1,55 @@
+// 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_COMMON_EXTENSIONS_MANIFEST_HANDLERS_KIOSK_MODE_INFO_H_
+#define CHROME_COMMON_EXTENSIONS_MANIFEST_HANDLERS_KIOSK_MODE_INFO_H_
+
+#include <string>
+#include <vector>
+
+#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/manifest_handler.h"
+#include "extensions/common/manifest.h"
+
+namespace extensions {
+
+struct KioskModeInfo : public Extension::ManifestData {
+ public:
+ enum KioskStatus {
+ NONE,
+ ENABLED,
+ ONLY
+ };
+
+ explicit KioskModeInfo(KioskStatus kiosk_status);
+ virtual ~KioskModeInfo();
+
+ KioskStatus kiosk_status;
+
+ // Whether the extension or app is enabled for app kiosk mode.
+ static bool IsKioskEnabled(const Extension* extension);
+
+ // Whether the extension or app should only be available in kiosk mode.
+ static bool IsKioskOnly(const Extension* extension);
+};
+
+// Parses the "kiosk_enabled" and "kiosk_only" manifest keys.
+class KioskModeHandler : public ManifestHandler {
+ public:
+ KioskModeHandler();
+ virtual ~KioskModeHandler();
+
+ virtual bool Parse(Extension* extension, string16* error) OVERRIDE;
+
+ private:
+ virtual const std::vector<std::string> Keys() const OVERRIDE;
+
+ std::vector<std::string> supported_keys_;
+
+ DISALLOW_COPY_AND_ASSIGN(KioskModeHandler);
+};
+
+} // namespace extensions
+
+#endif // CHROME_COMMON_EXTENSIONS_MANIFEST_HANDLERS_KIOSK_MODE_INFO_H_
diff --git a/chrome/common/extensions/manifest_tests/extension_manifests_kiosk_unittest.cc b/chrome/common/extensions/manifest_tests/extension_manifests_kiosk_unittest.cc
index b63abee..fa00693 100644
--- a/chrome/common/extensions/manifest_tests/extension_manifests_kiosk_unittest.cc
+++ b/chrome/common/extensions/manifest_tests/extension_manifests_kiosk_unittest.cc
@@ -3,55 +3,97 @@
// found in the LICENSE file.
#include "chrome/common/extensions/extension.h"
-#include "chrome/common/extensions/manifest_handlers/kiosk_enabled_info.h"
+#include "chrome/common/extensions/manifest_handlers/kiosk_mode_info.h"
#include "chrome/common/extensions/manifest_tests/extension_manifest_test.h"
#include "extensions/common/manifest_constants.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace extensions {
-class ExtensionManifestKioskEnabledTest : public ExtensionManifestTest {
+class ExtensionManifestKioskModeTest : public ExtensionManifestTest {
};
-TEST_F(ExtensionManifestKioskEnabledTest, InvalidKioskEnabled) {
+TEST_F(ExtensionManifestKioskModeTest, InvalidKioskEnabled) {
LoadAndExpectError("kiosk_enabled_invalid.json",
manifest_errors::kInvalidKioskEnabled);
}
-TEST_F(ExtensionManifestKioskEnabledTest, KioskEnabledHostedApp) {
+TEST_F(ExtensionManifestKioskModeTest, KioskEnabledHostedApp) {
scoped_refptr<Extension> extension(
LoadAndExpectSuccess("kiosk_enabled_hosted_app.json"));
- EXPECT_FALSE(KioskEnabledInfo::IsKioskEnabled(extension.get()));
+ EXPECT_FALSE(KioskModeInfo::IsKioskEnabled(extension.get()));
}
-TEST_F(ExtensionManifestKioskEnabledTest, KioskEnabledPackagedApp) {
+TEST_F(ExtensionManifestKioskModeTest, KioskEnabledPackagedApp) {
scoped_refptr<Extension> extension(
LoadAndExpectSuccess("kiosk_enabled_packaged_app.json"));
- EXPECT_FALSE(KioskEnabledInfo::IsKioskEnabled(extension.get()));
+ EXPECT_FALSE(KioskModeInfo::IsKioskEnabled(extension.get()));
}
-TEST_F(ExtensionManifestKioskEnabledTest, KioskEnabledExtension) {
+TEST_F(ExtensionManifestKioskModeTest, KioskEnabledExtension) {
scoped_refptr<Extension> extension(
LoadAndExpectSuccess("kiosk_enabled_extension.json"));
- EXPECT_FALSE(KioskEnabledInfo::IsKioskEnabled(extension.get()));
+ EXPECT_FALSE(KioskModeInfo::IsKioskEnabled(extension.get()));
}
-TEST_F(ExtensionManifestKioskEnabledTest, KioskEnabledPlatformApp) {
+TEST_F(ExtensionManifestKioskModeTest, KioskEnabledPlatformApp) {
scoped_refptr<Extension> extension(
LoadAndExpectSuccess("kiosk_enabled_platform_app.json"));
- EXPECT_TRUE(KioskEnabledInfo::IsKioskEnabled(extension.get()));
+ EXPECT_TRUE(KioskModeInfo::IsKioskEnabled(extension.get()));
}
-TEST_F(ExtensionManifestKioskEnabledTest, KioskDisabledPlatformApp) {
+TEST_F(ExtensionManifestKioskModeTest, KioskDisabledPlatformApp) {
scoped_refptr<Extension> extension(
LoadAndExpectSuccess("kiosk_disabled_platform_app.json"));
- EXPECT_FALSE(KioskEnabledInfo::IsKioskEnabled(extension.get()));
+ EXPECT_FALSE(KioskModeInfo::IsKioskEnabled(extension.get()));
}
-TEST_F(ExtensionManifestKioskEnabledTest, KioskDefaultPlatformApp) {
+TEST_F(ExtensionManifestKioskModeTest, KioskDefaultPlatformApp) {
scoped_refptr<Extension> extension(
LoadAndExpectSuccess("kiosk_default_platform_app.json"));
- EXPECT_FALSE(KioskEnabledInfo::IsKioskEnabled(extension.get()));
+ EXPECT_FALSE(KioskModeInfo::IsKioskEnabled(extension.get()));
+ EXPECT_FALSE(KioskModeInfo::IsKioskOnly(extension.get()));
+}
+
+TEST_F(ExtensionManifestKioskModeTest, KioskEnabledDefaultRequired) {
+ scoped_refptr<Extension> extension(
+ LoadAndExpectSuccess("kiosk_enabled_platform_app.json"));
+ EXPECT_TRUE(KioskModeInfo::IsKioskEnabled(extension.get()));
+ EXPECT_FALSE(KioskModeInfo::IsKioskOnly(extension.get()));
+}
+
+TEST_F(ExtensionManifestKioskModeTest, KioskOnlyPlatformApp) {
+ scoped_refptr<Extension> extension(
+ LoadAndExpectSuccess("kiosk_only_platform_app.json"));
+ EXPECT_TRUE(KioskModeInfo::IsKioskOnly(extension.get()));
+}
+
+TEST_F(ExtensionManifestKioskModeTest, KioskOnlyInvalid) {
+ LoadAndExpectError("kiosk_only_invalid.json",
+ manifest_errors::kInvalidKioskOnly);
+}
+
+TEST_F(ExtensionManifestKioskModeTest, KioskOnlyButNotEnabled) {
+ LoadAndExpectError("kiosk_only_not_enabled.json",
+ manifest_errors::kInvalidKioskOnlyButNotEnabled);
+}
+
+TEST_F(ExtensionManifestKioskModeTest, KioskOnlyHostedApp) {
+ scoped_refptr<Extension> extension(
+ LoadAndExpectSuccess("kiosk_only_hosted_app.json"));
+ EXPECT_FALSE(KioskModeInfo::IsKioskOnly(extension.get()));
+}
+
+TEST_F(ExtensionManifestKioskModeTest, KioskOnlyPackagedApp) {
+ scoped_refptr<Extension> extension(
+ LoadAndExpectSuccess("kiosk_only_packaged_app.json"));
+ EXPECT_FALSE(KioskModeInfo::IsKioskOnly(extension.get()));
+}
+
+TEST_F(ExtensionManifestKioskModeTest, KioskOnlyExtension) {
+ scoped_refptr<Extension> extension(
+ LoadAndExpectSuccess("kiosk_only_extension.json"));
+ EXPECT_FALSE(KioskModeInfo::IsKioskOnly(extension.get()));
}
} // namespace extensions
diff --git a/chrome/test/data/extensions/manifest_tests/kiosk_only_extension.json b/chrome/test/data/extensions/manifest_tests/kiosk_only_extension.json
new file mode 100644
index 0000000..f72a461
--- /dev/null
+++ b/chrome/test/data/extensions/manifest_tests/kiosk_only_extension.json
@@ -0,0 +1,6 @@
+{
+ "name": "kiosk only extension",
+ "version": "1",
+ "kiosk_enabled": true,
+ "kiosk_only": true
+}
diff --git a/chrome/test/data/extensions/manifest_tests/kiosk_only_hosted_app.json b/chrome/test/data/extensions/manifest_tests/kiosk_only_hosted_app.json
new file mode 100644
index 0000000..9e7c8f4
--- /dev/null
+++ b/chrome/test/data/extensions/manifest_tests/kiosk_only_hosted_app.json
@@ -0,0 +1,15 @@
+{
+ "name": "kiosk only hosted app",
+ "version": "1",
+ "app": {
+ "urls": [
+ "http://www.google.com/mail/",
+ "http://www.google.com/foobar/"
+ ],
+ "launch": {
+ "web_url": "http://www.google.com/mail/"
+ }
+ },
+ "kiosk_enabled": true,
+ "kiosk_only": true
+}
diff --git a/chrome/test/data/extensions/manifest_tests/kiosk_only_invalid.json b/chrome/test/data/extensions/manifest_tests/kiosk_only_invalid.json
new file mode 100644
index 0000000..596595e
--- /dev/null
+++ b/chrome/test/data/extensions/manifest_tests/kiosk_only_invalid.json
@@ -0,0 +1,11 @@
+{
+ "name": "invalid kiosk only value",
+ "version": "1",
+ "app": {
+ "background": {
+ "scripts": ["background.js"]
+ }
+ },
+ "kiosk_enabled": true,
+ "kiosk_only": "nope"
+}
diff --git a/chrome/test/data/extensions/manifest_tests/kiosk_only_not_enabled.json b/chrome/test/data/extensions/manifest_tests/kiosk_only_not_enabled.json
new file mode 100644
index 0000000..13ee398
--- /dev/null
+++ b/chrome/test/data/extensions/manifest_tests/kiosk_only_not_enabled.json
@@ -0,0 +1,10 @@
+{
+ "name": "kiosk only not enabled",
+ "version": "1",
+ "app": {
+ "background": {
+ "scripts": ["background.js"]
+ }
+ },
+ "kiosk_only": true
+}
diff --git a/chrome/test/data/extensions/manifest_tests/kiosk_only_packaged_app.json b/chrome/test/data/extensions/manifest_tests/kiosk_only_packaged_app.json
new file mode 100644
index 0000000..b1b705b
--- /dev/null
+++ b/chrome/test/data/extensions/manifest_tests/kiosk_only_packaged_app.json
@@ -0,0 +1,11 @@
+{
+ "name": "kiosk only packaged app",
+ "version": "1",
+ "app": {
+ "launch": {
+ "local_path": "loco.html"
+ }
+ },
+ "kiosk_enabled": true,
+ "kiosk_only": true
+}
diff --git a/chrome/test/data/extensions/manifest_tests/kiosk_only_platform_app.json b/chrome/test/data/extensions/manifest_tests/kiosk_only_platform_app.json
new file mode 100644
index 0000000..e45a0ce
--- /dev/null
+++ b/chrome/test/data/extensions/manifest_tests/kiosk_only_platform_app.json
@@ -0,0 +1,11 @@
+{
+ "name": "kiosk only platform app",
+ "version": "1",
+ "app": {
+ "background": {
+ "scripts": ["background.js"]
+ }
+ },
+ "kiosk_enabled": true,
+ "kiosk_only": true
+}
diff --git a/extensions/common/manifest_constants.cc b/extensions/common/manifest_constants.cc
index 7ab1d23..43feb2c 100644
--- a/extensions/common/manifest_constants.cc
+++ b/extensions/common/manifest_constants.cc
@@ -58,6 +58,8 @@ const char kJs[] = "js";
const char kKey[] = "key";
const char kKeycode[] = "keyCode";
const char kKioskEnabled[] = "kiosk_enabled";
+const char kKioskOnly[] = "kiosk_only";
+const char kKioskMode[] = "kiosk_mode";
const char kLanguage[] = "language";
const char kLaunch[] = "app.launch";
const char kLaunchContainer[] = "app.launch.container";
@@ -417,6 +419,10 @@ const char kInvalidKeyBindingUnknownPlatform[] =
" 'chromeos', 'linux' and 'default'.";
const char kInvalidKioskEnabled[] =
"Invalid value for 'kiosk_enabled'.";
+const char kInvalidKioskOnly[] =
+ "Invalid value for 'kiosk_only'.";
+const char kInvalidKioskOnlyButNotEnabled[] =
+ "The 'kiosk_only' key is set, but 'kiosk_enabled' is not set.";
const char kInvalidLaunchContainer[] =
"Invalid value for 'app.launch.container'.";
const char kInvalidLaunchValue[] =
diff --git a/extensions/common/manifest_constants.h b/extensions/common/manifest_constants.h
index 53fb1ef..42071d9 100644
--- a/extensions/common/manifest_constants.h
+++ b/extensions/common/manifest_constants.h
@@ -66,6 +66,8 @@ extern const char kJs[];
extern const char kKey[];
extern const char kKeycode[];
extern const char kKioskEnabled[];
+extern const char kKioskOnly[];
+extern const char kKioskMode[];
extern const char kLanguage[];
extern const char kLaunch[];
extern const char kLaunchContainer[];
@@ -316,6 +318,8 @@ extern const char kInvalidKeyBindingMissingPlatform[];
extern const char kInvalidKeyBindingTooMany[];
extern const char kInvalidKeyBindingUnknownPlatform[];
extern const char kInvalidKioskEnabled[];
+extern const char kInvalidKioskOnly[];
+extern const char kInvalidKioskOnlyButNotEnabled[];
extern const char kInvalidLaunchContainer[];
extern const char kInvalidLaunchValue[];
extern const char kInvalidLaunchValueContainer[];