summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorxiyuan <xiyuan@chromium.org>2016-02-08 15:27:57 -0800
committerCommit bot <commit-bot@chromium.org>2016-02-08 23:28:50 +0000
commitd07e4c4d345a7b808510bdcff1f4ac739548e8d4 (patch)
tree9e6b4e129893139706727d259df3b9e33a3dea07
parentdf175a8c3d1c1060f96d123a5896fdfbe4b3782d (diff)
downloadchromium_src-d07e4c4d345a7b808510bdcff1f4ac739548e8d4.zip
chromium_src-d07e4c4d345a7b808510bdcff1f4ac739548e8d4.tar.gz
chromium_src-d07e4c4d345a7b808510bdcff1f4ac739548e8d4.tar.bz2
kiosk: Cache required_platform_version info
- Cache required_platform_version info in KioskAppData and in LocalState; - Add a KioskAppManager::GetAutoLaunchAppRequiredPlatformVersion to expose the info for auto launched app; BUG=577783 TEST=KioskAppManagerTest.* Review URL: https://codereview.chromium.org/1636813002 Cr-Commit-Position: refs/heads/master@{#374214}
-rw-r--r--chrome/browser/chromeos/app_mode/kiosk_app_data.cc81
-rw-r--r--chrome/browser/chromeos/app_mode/kiosk_app_data.h17
-rw-r--r--chrome/browser/chromeos/app_mode/kiosk_app_manager.cc27
-rw-r--r--chrome/browser/chromeos/app_mode/kiosk_app_manager.h4
-rw-r--r--chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc355
-rw-r--r--chrome/test/data/chromeos/app_mode/offline_enabled_kiosk_app/v2_required_platform_version_added.crxbin0 -> 2228 bytes
-rw-r--r--chrome/test/data/chromeos/app_mode/offline_enabled_kiosk_app/v2_required_platform_version_added/app_main.html6
-rw-r--r--chrome/test/data/chromeos/app_mode/offline_enabled_kiosk_app/v2_required_platform_version_added/app_main.js8
-rw-r--r--chrome/test/data/chromeos/app_mode/offline_enabled_kiosk_app/v2_required_platform_version_added/icon-128.pngbin0 -> 343 bytes
-rw-r--r--chrome/test/data/chromeos/app_mode/offline_enabled_kiosk_app/v2_required_platform_version_added/icon-16.pngbin0 -> 94 bytes
-rw-r--r--chrome/test/data/chromeos/app_mode/offline_enabled_kiosk_app/v2_required_platform_version_added/main.js12
-rw-r--r--chrome/test/data/chromeos/app_mode/offline_enabled_kiosk_app/v2_required_platform_version_added/manifest.json20
-rw-r--r--chrome/test/data/chromeos/app_mode/webstore/inlineinstall/detail/app_with_bad_required_platform_version10
-rw-r--r--chrome/test/data/chromeos/app_mode/webstore/inlineinstall/detail/app_with_required_platform_version11
-rw-r--r--extensions/common/manifest_handlers/kiosk_mode_info.cc19
-rw-r--r--extensions/common/manifest_handlers/kiosk_mode_info.h4
16 files changed, 426 insertions, 148 deletions
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_data.cc b/chrome/browser/chromeos/app_mode/kiosk_app_data.cc
index 1c5a874..85da09c 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_app_data.cc
+++ b/chrome/browser/chromeos/app_mode/kiosk_app_data.cc
@@ -33,6 +33,7 @@
#include "extensions/common/manifest.h"
#include "extensions/common/manifest_constants.h"
#include "extensions/common/manifest_handlers/icons_handler.h"
+#include "extensions/common/manifest_handlers/kiosk_mode_info.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/image/image.h"
@@ -45,6 +46,7 @@ namespace {
// Keys for local state data. See sample layout in KioskAppManager.
const char kKeyName[] = "name";
const char kKeyIcon[] = "icon";
+const char kKeyRequiredPlatformVersion[] = "required_platform_version";
const char kInvalidWebstoreResponseError[] = "Invalid Chrome Web Store reponse";
@@ -113,6 +115,9 @@ class KioskAppData::CrxLoader : public extensions::SandboxedUnpackerClient {
const base::FilePath& crx_file() const { return crx_file_; }
const std::string& name() const { return name_; }
const SkBitmap& icon() const { return icon_; }
+ const std::string& required_platform_version() const {
+ return required_platform_version_;
+ }
private:
~CrxLoader() override {};
@@ -128,6 +133,8 @@ class KioskAppData::CrxLoader : public extensions::SandboxedUnpackerClient {
success_ = true;
name_ = extension->name();
icon_ = install_icon;
+ required_platform_version_ =
+ extensions::KioskModeInfo::Get(extension)->required_platform_version;
NotifyFinishedOnBlockingPool();
}
void OnUnpackFailure(const extensions::CrxInstallError& error) override {
@@ -183,6 +190,7 @@ class KioskAppData::CrxLoader : public extensions::SandboxedUnpackerClient {
// Extracted meta data.
std::string name_;
SkBitmap icon_;
+ std::string required_platform_version_;
DISALLOW_COPY_AND_ASSIGN(CrxLoader);
};
@@ -349,8 +357,20 @@ class KioskAppData::WebstoreDataParser
return;
}
+ std::string required_platform_version;
+ if (manifest.HasPath(
+ extensions::manifest_keys::kKioskRequiredPlatformVersion) &&
+ (!manifest.GetString(
+ extensions::manifest_keys::kKioskRequiredPlatformVersion,
+ &required_platform_version) ||
+ !extensions::KioskModeInfo::IsValidPlatformVersion(
+ required_platform_version))) {
+ ReportFailure();
+ return;
+ }
+
if (client_)
- client_->OnWebstoreParseSuccess(icon);
+ client_->OnWebstoreParseSuccess(icon, required_platform_version);
delete this;
}
void OnWebstoreParseFailure(const std::string& id,
@@ -418,6 +438,8 @@ void KioskAppData::LoadFromInstalledApp(Profile* profile,
DCHECK_EQ(app_id_, app->id());
name_ = app->name();
+ required_platform_version_ =
+ extensions::KioskModeInfo::Get(app)->required_platform_version;
const int kIconSize = extension_misc::EXTENSION_ICON_LARGE;
extensions::ExtensionResource image = extensions::IconsInfo::GetIconResource(
@@ -444,6 +466,10 @@ bool KioskAppData::IsFromWebStore() const {
extension_urls::IsWebstoreUpdateUrl(update_url_);
}
+void KioskAppData::SetStatusForTest(Status status) {
+ SetStatus(status);
+}
+
void KioskAppData::SetStatus(Status status) {
if (status_ == status)
return;
@@ -471,9 +497,12 @@ net::URLRequestContextGetter* KioskAppData::GetRequestContextGetter() {
}
bool KioskAppData::LoadFromCache() {
- std::string app_key = std::string(KioskAppManager::kKeyApps) + '.' + app_id_;
- std::string name_key = app_key + '.' + kKeyName;
- std::string icon_path_key = app_key + '.' + kKeyIcon;
+ const std::string app_key =
+ std::string(KioskAppManager::kKeyApps) + '.' + app_id_;
+ const std::string name_key = app_key + '.' + kKeyName;
+ const std::string icon_path_key = app_key + '.' + kKeyIcon;
+ const std::string required_platform_version_key =
+ app_key + '.' + kKeyRequiredPlatformVersion;
PrefService* local_state = g_browser_process->local_state();
const base::DictionaryValue* dict =
@@ -482,7 +511,9 @@ bool KioskAppData::LoadFromCache() {
icon_path_.clear();
std::string icon_path_string;
if (!dict->GetString(name_key, &name_) ||
- !dict->GetString(icon_path_key, &icon_path_string)) {
+ !dict->GetString(icon_path_key, &icon_path_string) ||
+ !dict->GetString(required_platform_version_key,
+ &required_platform_version_)) {
return false;
}
icon_path_ = base::FilePath(icon_path_string);
@@ -493,22 +524,31 @@ bool KioskAppData::LoadFromCache() {
}
void KioskAppData::SetCache(const std::string& name,
- const base::FilePath& icon_path) {
- std::string app_key = std::string(KioskAppManager::kKeyApps) + '.' + app_id_;
- std::string name_key = app_key + '.' + kKeyName;
- std::string icon_path_key = app_key + '.' + kKeyIcon;
+ const base::FilePath& icon_path,
+ const std::string& required_platform_version) {
+ name_ = name;
+ icon_path_ = icon_path;
+ required_platform_version_ = required_platform_version;
+
+ const std::string app_key =
+ std::string(KioskAppManager::kKeyApps) + '.' + app_id_;
+ const std::string name_key = app_key + '.' + kKeyName;
+ const std::string icon_path_key = app_key + '.' + kKeyIcon;
+ const std::string required_platform_version_key =
+ app_key + '.' + kKeyRequiredPlatformVersion;
PrefService* local_state = g_browser_process->local_state();
DictionaryPrefUpdate dict_update(local_state,
KioskAppManager::kKioskDictionaryName);
dict_update->SetString(name_key, name);
dict_update->SetString(icon_path_key, icon_path.value());
- icon_path_ = icon_path;
+ dict_update->SetString(required_platform_version_key,
+ required_platform_version);
}
-void KioskAppData::SetCache(const std::string& name, const SkBitmap& icon) {
- name_ = name;
-
+void KioskAppData::SetCache(const std::string& name,
+ const SkBitmap& icon,
+ const std::string& required_platform_version) {
icon_ = gfx::ImageSkia::CreateFrom1xBitmap(icon);
icon_.MakeThreadSafe();
@@ -527,16 +567,17 @@ void KioskAppData::SetCache(const std::string& name, const SkBitmap& icon) {
FROM_HERE,
base::Bind(&SaveIconToLocalOnBlockingPool, icon_path, raw_icon));
- SetCache(name, icon_path);
+ SetCache(name, icon_path, required_platform_version);
}
void KioskAppData::OnExtensionIconLoaded(const gfx::Image& icon) {
if (icon.IsEmpty()) {
LOG(WARNING) << "Failed to load icon from installed app"
<< ", id=" << app_id_;
- SetCache(name_, *extensions::util::GetDefaultAppIcon().bitmap());
+ SetCache(name_, *extensions::util::GetDefaultAppIcon().bitmap(),
+ required_platform_version_);
} else {
- SetCache(name_, icon.AsBitmap());
+ SetCache(name_, icon.AsBitmap(), required_platform_version_);
}
SetStatus(STATUS_LOADED);
@@ -553,8 +594,10 @@ void KioskAppData::OnIconLoadFailure() {
StartFetch();
}
-void KioskAppData::OnWebstoreParseSuccess(const SkBitmap& icon) {
- SetCache(name_, icon);
+void KioskAppData::OnWebstoreParseSuccess(
+ const SkBitmap& icon,
+ const std::string& required_platform_version) {
+ SetCache(name_, icon, required_platform_version);
SetStatus(STATUS_LOADED);
}
@@ -655,7 +698,7 @@ void KioskAppData::OnCrxLoadFinished(const CrxLoader* crx_loader) {
SkBitmap icon = crx_loader->icon();
if (icon.empty())
icon = *extensions::util::GetDefaultAppIcon().bitmap();
- SetCache(crx_loader->name(), icon);
+ SetCache(crx_loader->name(), icon, crx_loader->required_platform_version());
SetStatus(STATUS_LOADED);
}
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_data.h b/chrome/browser/chromeos/app_mode/kiosk_app_data.h
index 57509e6..c50fec8 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_app_data.h
+++ b/chrome/browser/chromeos/app_mode/kiosk_app_data.h
@@ -77,8 +77,13 @@ class KioskAppData : public base::SupportsWeakPtr<KioskAppData>,
const std::string& name() const { return name_; }
const GURL& update_url() const { return update_url_; }
const gfx::ImageSkia& icon() const { return icon_; }
+ const std::string& required_platform_version() const {
+ return required_platform_version_;
+ }
Status status() const { return status_; }
+ void SetStatusForTest(Status status);
+
private:
class CrxLoader;
class IconLoader;
@@ -93,10 +98,14 @@ class KioskAppData : public base::SupportsWeakPtr<KioskAppData>,
bool LoadFromCache();
// Sets the cached data.
- void SetCache(const std::string& name, const base::FilePath& icon_path);
+ void SetCache(const std::string& name,
+ const base::FilePath& icon_path,
+ const std::string& required_platform_version);
// Helper to set the cached data using a SkBitmap icon.
- void SetCache(const std::string& name, const SkBitmap& icon);
+ void SetCache(const std::string& name,
+ const SkBitmap& icon,
+ const std::string& required_platform_version);
// Callback for extensions::ImageLoader.
void OnExtensionIconLoaded(const gfx::Image& icon);
@@ -106,7 +115,8 @@ class KioskAppData : public base::SupportsWeakPtr<KioskAppData>,
void OnIconLoadFailure();
// Callbacks for WebstoreDataParser
- void OnWebstoreParseSuccess(const SkBitmap& icon);
+ void OnWebstoreParseSuccess(const SkBitmap& icon,
+ const std::string& required_platform_version);
void OnWebstoreParseFailure();
// Starts to fetch data from web store.
@@ -139,6 +149,7 @@ class KioskAppData : public base::SupportsWeakPtr<KioskAppData>,
std::string name_;
GURL update_url_;
gfx::ImageSkia icon_;
+ std::string required_platform_version_;
scoped_ptr<extensions::WebstoreDataFetcher> webstore_fetcher_;
base::FilePath icon_path_;
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc b/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc
index f20e31c..84b3eb2 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc
+++ b/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc
@@ -72,7 +72,7 @@ void ScheduleDelayedCryptohomeRemoval(const std::string& user_id,
void CancelDelayedCryptohomeRemoval(const std::string& user_id) {
PrefService* local_state = g_browser_process->local_state();
DictionaryPrefUpdate dict_update(local_state, kKioskUsersToRemove);
- dict_update->RemoveWithoutPathExpansion(user_id, NULL);
+ dict_update->RemoveWithoutPathExpansion(user_id, nullptr);
local_state->CommitPendingWrite();
}
@@ -147,7 +147,7 @@ KioskAppManager* KioskAppManager::Get() {
// static
void KioskAppManager::Shutdown() {
- if (instance == NULL)
+ if (instance == nullptr)
return;
instance.Pointer()->CleanUp();
@@ -167,17 +167,16 @@ void KioskAppManager::RemoveObsoleteCryptohomes() {
base::Bind(&PerformDelayedCryptohomeRemovals));
}
-KioskAppManager::App::App(
- const KioskAppData& data,
- bool is_extension_pending,
- bool auto_launched_with_zero_delay)
+KioskAppManager::App::App(const KioskAppData& data,
+ bool is_extension_pending,
+ bool auto_launched_with_zero_delay)
: app_id(data.app_id()),
user_id(data.user_id()),
name(data.name()),
icon(data.icon()),
+ required_platform_version(data.required_platform_version()),
is_loading(data.IsLoading() || is_extension_pending),
- was_auto_launched_with_zero_delay(auto_launched_with_zero_delay) {
-}
+ was_auto_launched_with_zero_delay(auto_launched_with_zero_delay) {}
KioskAppManager::App::App() : is_loading(false),
was_auto_launched_with_zero_delay(false) {}
@@ -345,6 +344,14 @@ bool KioskAppManager::IsAutoLaunchEnabled() const {
return GetAutoLoginState() == AUTOLOGIN_APPROVED;
}
+std::string KioskAppManager::GetAutoLaunchAppRequiredPlatformVersion() const {
+ if (!IsAutoLaunchEnabled())
+ return std::string();
+
+ const KioskAppData* data = GetAppData(GetAutoLaunchApp());
+ return data == nullptr ? std::string() : data->required_platform_version();
+}
+
void KioskAppManager::AddApp(const std::string& app_id,
OwnerSettingsServiceChromeOS* service) {
std::vector<policy::DeviceLocalAccount> device_local_accounts =
@@ -500,7 +507,7 @@ KioskAppManager::CreateSecondaryAppExternalLoader() {
}
void KioskAppManager::InstallFromCache(const std::string& id) {
- const base::DictionaryValue* extension = NULL;
+ const base::DictionaryValue* extension = nullptr;
if (external_cache_->cached_extensions()->GetDictionary(id, &extension)) {
scoped_ptr<base::DictionaryValue> prefs(new base::DictionaryValue);
base::DictionaryValue* extension_copy = extension->DeepCopy();
@@ -603,7 +610,7 @@ const KioskAppData* KioskAppManager::GetAppData(
return data;
}
- return NULL;
+ return nullptr;
}
KioskAppData* KioskAppManager::GetAppDataMutable(const std::string& app_id) {
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_manager.h b/chrome/browser/chromeos/app_mode/kiosk_app_manager.h
index ee80b49..85cb345 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_app_manager.h
+++ b/chrome/browser/chromeos/app_mode/kiosk_app_manager.h
@@ -72,6 +72,7 @@ class KioskAppManager : public KioskAppDataDelegate,
std::string user_id;
std::string name;
gfx::ImageSkia icon;
+ std::string required_platform_version;
bool is_loading;
bool was_auto_launched_with_zero_delay;
};
@@ -136,6 +137,9 @@ class KioskAppManager : public KioskAppDataDelegate,
// Enable auto launch setter.
void SetEnableAutoLaunch(bool value);
+ // Returns the cached required platform version of the auto launch kiosk app.
+ std::string GetAutoLaunchAppRequiredPlatformVersion() const;
+
// Adds/removes a kiosk app by id. When removed, all locally cached data
// will be removed as well.
void AddApp(const std::string& app_id, OwnerSettingsServiceChromeOS* service);
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc b/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc
index 545646b..418b0b7 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc
+++ b/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc
@@ -5,18 +5,19 @@
#include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
#include <stddef.h>
+#include <utility>
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
-#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/app_mode/fake_cws.h"
+#include "chrome/browser/chromeos/app_mode/kiosk_app_data.h"
#include "chrome/browser/chromeos/app_mode/kiosk_app_manager_observer.h"
#include "chrome/browser/chromeos/ownership/fake_owner_settings_service.h"
#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
@@ -85,15 +86,21 @@ void OnEnterpriseDeviceLock(
runner_quit_task.Run();
}
-scoped_refptr<extensions::Extension> MakeApp(const std::string& name,
- const std::string& version,
- const std::string& url,
- const std::string& id) {
- std::string err;
+scoped_refptr<extensions::Extension> MakeKioskApp(
+ const std::string& name,
+ const std::string& version,
+ const std::string& id,
+ const std::string& required_platform_version) {
base::DictionaryValue value;
value.SetString("name", name);
value.SetString("version", version);
- value.SetString("app.launch.web_url", url);
+ scoped_ptr<base::ListValue> scripts(new base::ListValue);
+ scripts->AppendString("main.js");
+ value.Set("app.background.scripts", std::move(scripts));
+ value.SetBoolean("kiosk_enabled", true);
+ value.SetString("kiosk.required_platform_version", required_platform_version);
+
+ std::string err;
scoped_refptr<extensions::Extension> app =
extensions::Extension::Create(
base::FilePath(),
@@ -108,13 +115,8 @@ scoped_refptr<extensions::Extension> MakeApp(const std::string& name,
class AppDataLoadWaiter : public KioskAppManagerObserver {
public:
- AppDataLoadWaiter(KioskAppManager* manager, int data_loaded_threshold)
- : runner_(NULL),
- manager_(manager),
- loaded_(false),
- quit_(false),
- data_change_count_(0),
- data_loaded_threshold_(data_loaded_threshold) {
+ AppDataLoadWaiter(KioskAppManager* manager, int expected_data_change)
+ : manager_(manager), expected_data_change_(expected_data_change) {
manager_->AddObserver(this);
}
@@ -127,13 +129,20 @@ class AppDataLoadWaiter : public KioskAppManagerObserver {
runner_->Run();
}
+ void Reset() {
+ quit_ = false;
+ data_change_count_ = 0;
+ data_load_failure_count_ = 0;
+ }
+
bool loaded() const { return loaded_; }
+ int data_load_failure_count() const { return data_load_failure_count_; }
private:
// KioskAppManagerObserver overrides:
void OnKioskAppDataChanged(const std::string& app_id) override {
++data_change_count_;
- if (data_change_count_ < data_loaded_threshold_)
+ if (data_change_count_ < expected_data_change_)
return;
loaded_ = true;
quit_ = true;
@@ -142,6 +151,7 @@ class AppDataLoadWaiter : public KioskAppManagerObserver {
}
void OnKioskAppDataLoadFailure(const std::string& app_id) override {
+ ++data_load_failure_count_;
loaded_ = false;
quit_ = true;
if (runner_.get())
@@ -158,14 +168,45 @@ class AppDataLoadWaiter : public KioskAppManagerObserver {
scoped_refptr<content::MessageLoopRunner> runner_;
KioskAppManager* manager_;
- bool loaded_;
- bool quit_;
- int data_change_count_;
- int data_loaded_threshold_;
+ bool loaded_ = false;
+ bool quit_ = false;
+ int data_change_count_ = 0;
+ int expected_data_change_;
+ int data_load_failure_count_ = 0;
DISALLOW_COPY_AND_ASSIGN(AppDataLoadWaiter);
};
+// A class to wait for ExternalCache to finish putting the extension crx.
+class ExternalCachePutWaiter {
+ public:
+ ExternalCachePutWaiter() {}
+ ~ExternalCachePutWaiter() {}
+
+ void Wait() {
+ if (quit_)
+ return;
+ runner_ = new content::MessageLoopRunner;
+ runner_->Run();
+ }
+
+ void OnPutExtension(const std::string& id, bool success) {
+ success_ = success;
+ quit_ = true;
+ if (runner_.get())
+ runner_->Quit();
+ }
+
+ bool success() const { return success_; }
+
+ private:
+ scoped_refptr<content::MessageLoopRunner> runner_;
+ bool quit_ = false;
+ bool success_ = false;
+
+ DISALLOW_COPY_AND_ASSIGN(ExternalCachePutWaiter);
+};
+
} // namespace
class KioskAppManagerTest : public InProcessBrowserTest {
@@ -250,19 +291,22 @@ class KioskAppManagerTest : public InProcessBrowserTest {
void SetExistingApp(const std::string& app_id,
const std::string& app_name,
- const std::string& icon_file_name) {
+ const std::string& icon_file_name,
+ const std::string& required_platform_version) {
base::FilePath test_dir;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_dir));
base::FilePath data_dir = test_dir.AppendASCII("chromeos/app_mode/");
// Copy the icon file to temp dir for using because ClearAppData test
// deletes it.
- base::FilePath icon_path = temp_dir_.path().AppendASCII(icon_file_name);
- base::CopyFile(data_dir.AppendASCII(icon_file_name), icon_path);
+ base::FilePath icon_path =
+ CopyFileToTempDir(data_dir.AppendASCII(icon_file_name));
scoped_ptr<base::DictionaryValue> apps_dict(new base::DictionaryValue);
apps_dict->SetString(app_id + ".name", app_name);
apps_dict->SetString(app_id + ".icon", icon_path.MaybeAsASCII());
+ apps_dict->SetString(app_id + ".required_platform_version",
+ required_platform_version);
PrefService* local_state = g_browser_process->local_state();
DictionaryPrefUpdate dict_update(local_state,
@@ -272,16 +316,18 @@ class KioskAppManagerTest : public InProcessBrowserTest {
// Make the app appear in device settings.
base::ListValue device_local_accounts;
scoped_ptr<base::DictionaryValue> entry(new base::DictionaryValue);
- entry->SetStringWithoutPathExpansion(
- kAccountsPrefDeviceLocalAccountsKeyId,
- app_id + "_id");
+ // Fake an account id. Note this needs to match GenerateKioskAppAccountId
+ // in kiosk_app_manager.cc to make SetAutoLaunchApp work with the
+ // existing app entry created here.
+ entry->SetStringWithoutPathExpansion(kAccountsPrefDeviceLocalAccountsKeyId,
+ app_id + "@kiosk-apps");
entry->SetIntegerWithoutPathExpansion(
kAccountsPrefDeviceLocalAccountsKeyType,
policy::DeviceLocalAccount::TYPE_KIOSK_APP);
entry->SetStringWithoutPathExpansion(
kAccountsPrefDeviceLocalAccountsKeyKioskAppId,
app_id);
- device_local_accounts.Append(entry.release());
+ device_local_accounts.Append(std::move(entry));
owner_settings_service_->Set(kAccountsPrefDeviceLocalAccounts,
device_local_accounts);
}
@@ -294,11 +340,62 @@ class KioskAppManagerTest : public InProcessBrowserTest {
void UpdateAppData() { manager()->UpdateAppData(); }
+ void CheckAppData(const std::string& app_id,
+ const std::string& expected_app_name,
+ const std::string& expected_required_platform_version) {
+ // Check manifest data is cached correctly.
+ KioskAppManager::Apps apps;
+ manager()->GetApps(&apps);
+ ASSERT_EQ(1u, apps.size());
+ EXPECT_EQ(app_id, apps[0].app_id);
+ EXPECT_EQ(expected_app_name, apps[0].name);
+ EXPECT_FALSE(apps[0].icon.size().IsEmpty());
+ EXPECT_EQ(expected_required_platform_version,
+ apps[0].required_platform_version);
+ }
+
+ void CheckAppDataAndCache(
+ const std::string& app_id,
+ const std::string& expected_app_name,
+ const std::string& expected_required_platform_version) {
+ CheckAppData(app_id, expected_app_name, expected_required_platform_version);
+
+ // Check data is cached in local state correctly.
+ PrefService* local_state = g_browser_process->local_state();
+ const base::DictionaryValue* dict =
+ local_state->GetDictionary(KioskAppManager::kKioskDictionaryName);
+
+ std::string name;
+ const std::string name_key = "apps." + app_id + ".name";
+ EXPECT_TRUE(dict->GetString(name_key, &name));
+ EXPECT_EQ(expected_app_name, name);
+
+ std::string icon_path_string;
+ const std::string icon_path_key = "apps." + app_id + ".icon";
+ EXPECT_TRUE(dict->GetString(icon_path_key, &icon_path_string));
+
+ std::string required_platform_version;
+ const std::string required_platform_version_key =
+ "apps." + app_id + ".required_platform_version";
+ EXPECT_TRUE(dict->GetString(required_platform_version_key,
+ &required_platform_version));
+ EXPECT_EQ(expected_required_platform_version, required_platform_version);
+
+ base::FilePath expected_icon_path;
+ ASSERT_TRUE(PathService::Get(chrome::DIR_USER_DATA, &expected_icon_path));
+ expected_icon_path =
+ expected_icon_path.AppendASCII(KioskAppManager::kIconCacheDir)
+ .AppendASCII(app_id)
+ .AddExtension(".png");
+ EXPECT_EQ(expected_icon_path.value(), icon_path_string);
+ }
+
void RunAddNewAppTest(const std::string& id,
- const std::string& version,
- const std::string& app_name) {
+ const std::string& expected_version,
+ const std::string& expected_app_name,
+ const std::string& expected_required_platform_version) {
std::string crx_file_name = id + ".crx";
- fake_cws_->SetUpdateCrx(id, crx_file_name, version);
+ fake_cws_->SetUpdateCrx(id, crx_file_name, expected_version);
AppDataLoadWaiter waiter(manager(), 3);
manager()->AddApp(id, owner_settings_service_.get());
@@ -310,7 +407,7 @@ class KioskAppManagerTest : public InProcessBrowserTest {
std::string crx_version;
EXPECT_TRUE(GetCachedCrx(id, &crx_path, &crx_version));
EXPECT_TRUE(base::PathExists(crx_path));
- EXPECT_EQ(version, crx_version);
+ EXPECT_EQ(expected_version, crx_version);
// Verify the original crx file is identical to the cached file.
base::FilePath test_data_dir;
PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir);
@@ -320,35 +417,20 @@ class KioskAppManagerTest : public InProcessBrowserTest {
EXPECT_TRUE(base::PathExists(src_file_path));
EXPECT_TRUE(base::ContentsEqual(src_file_path, crx_path));
- // Check manifest data is cached correctly.
- KioskAppManager::Apps apps;
- manager()->GetApps(&apps);
- ASSERT_EQ(1u, apps.size());
- EXPECT_EQ(id, apps[0].app_id);
- EXPECT_EQ(app_name, apps[0].name);
- EXPECT_EQ(gfx::Size(16, 16), apps[0].icon.size());
-
- // Check data is cached in local state.
- PrefService* local_state = g_browser_process->local_state();
- const base::DictionaryValue* dict =
- local_state->GetDictionary(KioskAppManager::kKioskDictionaryName);
-
- std::string name;
- std::string name_key = "apps." + id + ".name";
- EXPECT_TRUE(dict->GetString(name_key, &name));
- EXPECT_EQ(apps[0].name, name);
+ CheckAppDataAndCache(id, expected_app_name,
+ expected_required_platform_version);
+ }
- std::string icon_path_string;
- std::string icon_path_key = "apps." + id + ".icon";
- EXPECT_TRUE(dict->GetString(icon_path_key, &icon_path_string));
+ // Copies the given file into temp dir and returns the full path
+ // of the copied file.
+ base::FilePath CopyFileToTempDir(const base::FilePath& file) {
+ base::FilePath target_file = temp_dir_.path().Append(file.BaseName());
+ CHECK(base::CopyFile(file, target_file));
+ return target_file;
+ }
- base::FilePath expected_icon_path;
- ASSERT_TRUE(PathService::Get(chrome::DIR_USER_DATA, &expected_icon_path));
- expected_icon_path =
- expected_icon_path.AppendASCII(KioskAppManager::kIconCacheDir)
- .AppendASCII(apps[0].app_id)
- .AddExtension(".png");
- EXPECT_EQ(expected_icon_path.value(), icon_path_string);
+ KioskAppData* GetAppDataMutable(const std::string& app_id) {
+ return manager()->GetAppDataMutable(app_id);
}
KioskAppManager* manager() const { return KioskAppManager::Get(); }
@@ -429,23 +511,18 @@ IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, Basic) {
}
IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, LoadCached) {
- SetExistingApp("app_1", "Cached App1 Name", "red16x16.png");
+ SetExistingApp("app_1", "Cached App1 Name", "red16x16.png", "1234");
fake_cws()->SetNoUpdate("app_1");
AppDataLoadWaiter waiter(manager(), 1);
waiter.Wait();
EXPECT_TRUE(waiter.loaded());
- KioskAppManager::Apps apps;
- manager()->GetApps(&apps);
- EXPECT_EQ(1u, apps.size());
- EXPECT_EQ("app_1", apps[0].app_id);
- EXPECT_EQ("Cached App1 Name", apps[0].name);
- EXPECT_EQ(gfx::Size(16, 16), apps[0].icon.size());
+ CheckAppData("app_1", "Cached App1 Name", "1234");
}
IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, ClearAppData) {
- SetExistingApp("app_1", "Cached App1 Name", "red16x16.png");
+ SetExistingApp("app_1", "Cached App1 Name", "red16x16.png", "");
PrefService* local_state = g_browser_process->local_state();
const base::DictionaryValue* dict =
@@ -460,31 +537,73 @@ IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, ClearAppData) {
}
IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, UpdateAppDataFromProfile) {
- SetExistingApp("app_1", "Cached App1 Name", "red16x16.png");
+ SetExistingApp("app_1", "Cached App1 Name", "red16x16.png", "");
fake_cws()->SetNoUpdate("app_1");
AppDataLoadWaiter waiter(manager(), 1);
waiter.Wait();
EXPECT_TRUE(waiter.loaded());
- KioskAppManager::Apps apps;
- manager()->GetApps(&apps);
- EXPECT_EQ(1u, apps.size());
- EXPECT_EQ("app_1", apps[0].app_id);
- EXPECT_EQ("Cached App1 Name", apps[0].name);
+ CheckAppData("app_1", "Cached App1 Name", "");
scoped_refptr<extensions::Extension> updated_app =
- MakeApp("Updated App1 Name", "2.0", "http://localhost/", "app_1");
+ MakeKioskApp("Updated App1 Name", "2.0", "app_1", "1234");
manager()->UpdateAppDataFromProfile(
"app_1", browser()->profile(), updated_app.get());
+ waiter.Reset();
waiter.Wait();
EXPECT_TRUE(waiter.loaded());
- manager()->GetApps(&apps);
- EXPECT_EQ(1u, apps.size());
- EXPECT_EQ("app_1", apps[0].app_id);
- EXPECT_EQ("Updated App1 Name", apps[0].name);
+ CheckAppData("app_1", "Updated App1 Name", "1234");
+}
+
+IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, UpdateAppDataFromCrx) {
+ const char kAppId[] = "ajoggoflpgplnnjkjamcmbepjdjdnpdp";
+ const char kAppName[] = "Test Kiosk App";
+
+ SetExistingApp(kAppId, kAppName, "red16x16.png", "");
+ fake_cws()->SetNoUpdate(kAppId);
+ AppDataLoadWaiter waiter(manager(), 1);
+ waiter.Wait();
+ EXPECT_TRUE(waiter.loaded());
+
+ CheckAppData(kAppId, kAppName, "");
+
+ // Fake app data load failure so that the manager will attempt to
+ // load it from crx.
+ KioskAppData* app_data = GetAppDataMutable(kAppId);
+ app_data->SetStatusForTest(KioskAppData::STATUS_ERROR);
+
+ // Copy test crx file to temp dir because the cache moves the file.
+ base::FilePath test_dir;
+ ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_dir));
+ base::FilePath data_dir =
+ test_dir.AppendASCII("chromeos/app_mode/offline_enabled_kiosk_app");
+ base::FilePath crx_file =
+ data_dir.AppendASCII("v2_required_platform_version_added.crx");
+ crx_file = CopyFileToTempDir(crx_file);
+
+ ExternalCachePutWaiter put_waiter;
+ manager()->PutValidatedExternalExtension(
+ kAppId, crx_file, "2.0.0",
+ base::Bind(&ExternalCachePutWaiter::OnPutExtension,
+ base::Unretained(&put_waiter)));
+ put_waiter.Wait();
+ ASSERT_TRUE(put_waiter.success());
+
+ // Wait for 3 data loaded events at the most. One for crx putting into cache,
+ // one for update check and one for app data is updated from crx.
+ const size_t kMaxDataChange = 3;
+ for (size_t i = 0;
+ i < kMaxDataChange && app_data->status() != KioskAppData::STATUS_LOADED;
+ ++i) {
+ waiter.Reset();
+ waiter.Wait();
+ }
+ ASSERT_EQ(KioskAppData::STATUS_LOADED, app_data->status());
+
+ CheckAppData(kAppId, kAppName, "1234");
}
IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, BadApp) {
@@ -498,47 +617,52 @@ IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, BadApp) {
IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, GoodApp) {
// Webstore data json is in
// chrome/test/data/chromeos/app_mode/webstore/inlineinstall/detail/app_1
- fake_cws()->SetNoUpdate("app_1");
+ const char kAppId[] = "app_1";
+ fake_cws()->SetNoUpdate(kAppId);
AppDataLoadWaiter waiter(manager(), 2);
- manager()->AddApp("app_1", owner_settings_service_.get());
+ manager()->AddApp(kAppId, owner_settings_service_.get());
waiter.Wait();
EXPECT_TRUE(waiter.loaded());
- // Check data is correct.
- KioskAppManager::Apps apps;
- manager()->GetApps(&apps);
- ASSERT_EQ(1u, apps.size());
- EXPECT_EQ("app_1", apps[0].app_id);
- EXPECT_EQ("Name of App 1", apps[0].name);
- EXPECT_EQ(gfx::Size(16, 16), apps[0].icon.size());
+ CheckAppDataAndCache(kAppId, "Name of App 1", "");
+}
- // Check data is cached in local state.
- PrefService* local_state = g_browser_process->local_state();
- const base::DictionaryValue* dict =
- local_state->GetDictionary(KioskAppManager::kKioskDictionaryName);
+IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, AppWithRequiredPlatformVersion) {
+ // Webstore data json is in
+ // chrome/test/data/chromeos/app_mode/webstore/inlineinstall/detail/
+ // app_with_required_platform_version
+ const char kAppId[] = "app_with_required_platform_version";
+ fake_cws()->SetNoUpdate(kAppId);
+ AppDataLoadWaiter waiter(manager(), 2);
+ manager()->AddApp(kAppId, owner_settings_service_.get());
+ waiter.Wait();
+ EXPECT_TRUE(waiter.loaded());
- std::string name;
- EXPECT_TRUE(dict->GetString("apps.app_1.name", &name));
- EXPECT_EQ(apps[0].name, name);
+ CheckAppDataAndCache(kAppId, "App with required platform version", "1234");
+}
- std::string icon_path_string;
- EXPECT_TRUE(dict->GetString("apps.app_1.icon", &icon_path_string));
+IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, AppWithBadRequiredPlatformVersion) {
+ // Webstore data json is in
+ // chrome/test/data/chromeos/app_mode/webstore/inlineinstall/detail/
+ // app_with_bad_required_platform_version
+ const char kAppId[] = "app_with_bad_required_platform_version";
+ fake_cws()->SetNoUpdate(kAppId);
+ AppDataLoadWaiter waiter(manager(), 2);
+ manager()->AddApp(kAppId, owner_settings_service_.get());
+ waiter.Wait();
+ EXPECT_FALSE(waiter.loaded());
+ EXPECT_EQ(1, waiter.data_load_failure_count());
- base::FilePath expected_icon_path;
- ASSERT_TRUE(PathService::Get(chrome::DIR_USER_DATA, &expected_icon_path));
- expected_icon_path = expected_icon_path.
- AppendASCII(KioskAppManager::kIconCacheDir).
- AppendASCII(apps[0].app_id).AddExtension(".png");
- EXPECT_EQ(expected_icon_path.value(), icon_path_string);
+ EXPECT_EQ("", GetAppIds());
}
IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, DownloadNewApp) {
- RunAddNewAppTest(kTestLocalFsKioskApp, "1.0.0", kTestLocalFsKioskAppName);
+ RunAddNewAppTest(kTestLocalFsKioskApp, "1.0.0", kTestLocalFsKioskAppName, "");
}
IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, RemoveApp) {
// Add a new app.
- RunAddNewAppTest(kTestLocalFsKioskApp, "1.0.0", kTestLocalFsKioskAppName);
+ RunAddNewAppTest(kTestLocalFsKioskApp, "1.0.0", kTestLocalFsKioskAppName, "");
KioskAppManager::Apps apps;
manager()->GetApps(&apps);
ASSERT_EQ(1u, apps.size());
@@ -559,7 +683,7 @@ IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, RemoveApp) {
IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, UpdateApp) {
// Add a version 1 app first.
- RunAddNewAppTest(kTestLocalFsKioskApp, "1.0.0", kTestLocalFsKioskAppName);
+ RunAddNewAppTest(kTestLocalFsKioskApp, "1.0.0", kTestLocalFsKioskAppName, "");
KioskAppManager::Apps apps;
manager()->GetApps(&apps);
ASSERT_EQ(1u, apps.size());
@@ -599,7 +723,7 @@ IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, UpdateApp) {
IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, UpdateAndRemoveApp) {
// Add a version 1 app first.
- RunAddNewAppTest(kTestLocalFsKioskApp, "1.0.0", kTestLocalFsKioskAppName);
+ RunAddNewAppTest(kTestLocalFsKioskApp, "1.0.0", kTestLocalFsKioskAppName, "");
KioskAppManager::Apps apps;
manager()->GetApps(&apps);
ASSERT_EQ(1u, apps.size());
@@ -718,4 +842,27 @@ IN_PROC_BROWSER_TEST_F(KioskAppManagerTest,
KioskAppManager::CONSUMER_KIOSK_AUTO_LAUNCH_DISABLED);
}
+IN_PROC_BROWSER_TEST_F(KioskAppManagerTest,
+ GetAutoLaunchAppRequiredPlatformVersion) {
+ const char kAppId[] = "app_with_required_platform_version";
+ const char kRequiredPlatformVersion[] = "1234";
+ SetExistingApp(kAppId, "App Name", "red16x16.png", kRequiredPlatformVersion);
+
+ fake_cws()->SetNoUpdate(kAppId);
+ AppDataLoadWaiter waiter(manager(), 1);
+ waiter.Wait();
+ EXPECT_TRUE(waiter.loaded());
+
+ EXPECT_FALSE(manager()->IsAutoLaunchEnabled());
+ EXPECT_EQ("", manager()->GetAutoLaunchAppRequiredPlatformVersion());
+
+ manager()->SetAutoLaunchApp(kAppId, owner_settings_service_.get());
+ EXPECT_EQ("", manager()->GetAutoLaunchAppRequiredPlatformVersion());
+
+ manager()->SetEnableAutoLaunch(true);
+ EXPECT_TRUE(manager()->IsAutoLaunchEnabled());
+ EXPECT_EQ(kRequiredPlatformVersion,
+ manager()->GetAutoLaunchAppRequiredPlatformVersion());
+}
+
} // namespace chromeos
diff --git a/chrome/test/data/chromeos/app_mode/offline_enabled_kiosk_app/v2_required_platform_version_added.crx b/chrome/test/data/chromeos/app_mode/offline_enabled_kiosk_app/v2_required_platform_version_added.crx
new file mode 100644
index 0000000..d4e8674
--- /dev/null
+++ b/chrome/test/data/chromeos/app_mode/offline_enabled_kiosk_app/v2_required_platform_version_added.crx
Binary files differ
diff --git a/chrome/test/data/chromeos/app_mode/offline_enabled_kiosk_app/v2_required_platform_version_added/app_main.html b/chrome/test/data/chromeos/app_mode/offline_enabled_kiosk_app/v2_required_platform_version_added/app_main.html
new file mode 100644
index 0000000..e0aa0f6
--- /dev/null
+++ b/chrome/test/data/chromeos/app_mode/offline_enabled_kiosk_app/v2_required_platform_version_added/app_main.html
@@ -0,0 +1,6 @@
+<html>
+<script src="app_main.js"></script>
+<body>
+<h1>Test Kiosk App!!!</h1>
+</body>
+<hmtl>
diff --git a/chrome/test/data/chromeos/app_mode/offline_enabled_kiosk_app/v2_required_platform_version_added/app_main.js b/chrome/test/data/chromeos/app_mode/offline_enabled_kiosk_app/v2_required_platform_version_added/app_main.js
new file mode 100644
index 0000000..6201556
--- /dev/null
+++ b/chrome/test/data/chromeos/app_mode/offline_enabled_kiosk_app/v2_required_platform_version_added/app_main.js
@@ -0,0 +1,8 @@
+// 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.
+
+window.addEventListener('load', function onload() {
+ window.close();
+});
+
diff --git a/chrome/test/data/chromeos/app_mode/offline_enabled_kiosk_app/v2_required_platform_version_added/icon-128.png b/chrome/test/data/chromeos/app_mode/offline_enabled_kiosk_app/v2_required_platform_version_added/icon-128.png
new file mode 100644
index 0000000..5c226f3
--- /dev/null
+++ b/chrome/test/data/chromeos/app_mode/offline_enabled_kiosk_app/v2_required_platform_version_added/icon-128.png
Binary files differ
diff --git a/chrome/test/data/chromeos/app_mode/offline_enabled_kiosk_app/v2_required_platform_version_added/icon-16.png b/chrome/test/data/chromeos/app_mode/offline_enabled_kiosk_app/v2_required_platform_version_added/icon-16.png
new file mode 100644
index 0000000..c7510d38
--- /dev/null
+++ b/chrome/test/data/chromeos/app_mode/offline_enabled_kiosk_app/v2_required_platform_version_added/icon-16.png
Binary files differ
diff --git a/chrome/test/data/chromeos/app_mode/offline_enabled_kiosk_app/v2_required_platform_version_added/main.js b/chrome/test/data/chromeos/app_mode/offline_enabled_kiosk_app/v2_required_platform_version_added/main.js
new file mode 100644
index 0000000..842ca23
--- /dev/null
+++ b/chrome/test/data/chromeos/app_mode/offline_enabled_kiosk_app/v2_required_platform_version_added/main.js
@@ -0,0 +1,12 @@
+// 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.
+
+chrome.app.runtime.onLaunched.addListener(function(launchData) {
+ if (launchData.isKioskSession)
+ chrome.test.sendMessage('launchData.isKioskSession = true');
+
+ chrome.app.window.create('app_main.html',
+ { 'width': 1920,
+ 'height': 1080 });
+});
diff --git a/chrome/test/data/chromeos/app_mode/offline_enabled_kiosk_app/v2_required_platform_version_added/manifest.json b/chrome/test/data/chromeos/app_mode/offline_enabled_kiosk_app/v2_required_platform_version_added/manifest.json
new file mode 100644
index 0000000..4a9789a
--- /dev/null
+++ b/chrome/test/data/chromeos/app_mode/offline_enabled_kiosk_app/v2_required_platform_version_added/manifest.json
@@ -0,0 +1,20 @@
+{
+ "manifest_version": 2,
+ "name": "Test Kiosk App",
+ "minimum_chrome_version": "24.0.1307.0",
+ "version": "2.0.0",
+ "icons": {
+ "128": "icon-128.png",
+ "16": "icon-16.png"
+ },
+ "app": {
+ "background": {
+ "scripts": ["main.js"]
+ }
+ },
+ "kiosk_enabled": true,
+ "kiosk": {
+ "required_platform_version": "1234"
+ },
+ "offline_enabled": true
+}
diff --git a/chrome/test/data/chromeos/app_mode/webstore/inlineinstall/detail/app_with_bad_required_platform_version b/chrome/test/data/chromeos/app_mode/webstore/inlineinstall/detail/app_with_bad_required_platform_version
new file mode 100644
index 0000000..0af85ac
--- /dev/null
+++ b/chrome/test/data/chromeos/app_mode/webstore/inlineinstall/detail/app_with_bad_required_platform_version
@@ -0,0 +1,10 @@
+{
+ "id": "app_with_bad_required_platform_version",
+ "users": "1234",
+ "average_rating": 1.0,
+ "rating_count": 999,
+ "verified_site": "chrome.google.com",
+ "localized_name": "App with bad required platform version",
+ "localized_description": "Description of app with bad required_platform_version",
+ "icon_url": "webstore/inlineinstall/detail/app_1_green16x16.png", "manifest":"{\n \"name\": \"__MSG_appName__\",\n \"version\": \"1\",\n \"manifest_version\": 2,\n \"description\": \"__MSG_appDesc__\",\n \"default_locale\": \"en\",\n \"app\": {\n \"background\": {\n \"scripts\": [\"background.js\"]\n },\n \"launch\": {\n \"local_path\": \"index.html\"\n }\n },\n \"icons\": {\n \"16\": \"favicon.png\",\n \"128\": \"128.png\"\n },\n \"kiosk_enabled\": true,\n \"kiosk\": {\"required_platform_version\": \"bad\"},\n \"permissions\": [] }"
+}
diff --git a/chrome/test/data/chromeos/app_mode/webstore/inlineinstall/detail/app_with_required_platform_version b/chrome/test/data/chromeos/app_mode/webstore/inlineinstall/detail/app_with_required_platform_version
new file mode 100644
index 0000000..e76a63470d
--- /dev/null
+++ b/chrome/test/data/chromeos/app_mode/webstore/inlineinstall/detail/app_with_required_platform_version
@@ -0,0 +1,11 @@
+{
+ "id": "app_with_required_platform_version",
+ "users": "1234",
+ "average_rating": 1.0,
+ "rating_count": 999,
+ "verified_site": "chrome.google.com",
+ "localized_name": "App with required platform version",
+ "localized_description": "Description of app with required_platform_version",
+ "icon_url": "webstore/inlineinstall/detail/app_1_green16x16.png",
+ "manifest":"{\n \"name\": \"__MSG_appName__\",\n \"version\": \"1\",\n \"manifest_version\": 2,\n \"description\": \"__MSG_appDesc__\",\n \"default_locale\": \"en\",\n \"app\": {\n \"background\": {\n \"scripts\": [\"background.js\"]\n },\n \"launch\": {\n \"local_path\": \"index.html\"\n }\n },\n \"icons\": {\n \"16\": \"favicon.png\",\n \"128\": \"128.png\"\n },\n \"kiosk_enabled\": true,\n \"kiosk\": {\"required_platform_version\": \"1234\"},\n \"permissions\": [] }"
+}
diff --git a/extensions/common/manifest_handlers/kiosk_mode_info.cc b/extensions/common/manifest_handlers/kiosk_mode_info.cc
index 5ab5656..d625bfd 100644
--- a/extensions/common/manifest_handlers/kiosk_mode_info.cc
+++ b/extensions/common/manifest_handlers/kiosk_mode_info.cc
@@ -13,17 +13,6 @@
#include "extensions/common/api/extensions_manifest_types.h"
#include "extensions/common/manifest_constants.h"
-namespace {
-
-// Whether the given |version_string| is a valid ChromeOS platform version.
-// The acceptable format is major[.minor[.micro]].
-bool IsValidPlatformVersion(const std::string& version_string) {
- const base::Version version(version_string);
- return version.IsValid() && version.components().size() <= 3u;
-}
-
-} // namespace
-
namespace extensions {
namespace keys = manifest_keys;
@@ -64,6 +53,12 @@ bool KioskModeInfo::HasSecondaryApps(const Extension* extension) {
return info && !info->secondary_app_ids.empty();
}
+// static
+bool KioskModeInfo::IsValidPlatformVersion(const std::string& version_string) {
+ const base::Version version(version_string);
+ return version.IsValid() && version.components().size() <= 3u;
+}
+
KioskModeHandler::KioskModeHandler() {
supported_keys_.push_back(keys::kKiosk);
supported_keys_.push_back(keys::kKioskEnabled);
@@ -135,7 +130,7 @@ bool KioskModeHandler::Parse(Extension* extension, base::string16* error) {
if (manifest->HasPath(keys::kKioskRequiredPlatformVersion) &&
(!manifest->GetString(keys::kKioskRequiredPlatformVersion,
&required_platform_version) ||
- !IsValidPlatformVersion(required_platform_version))) {
+ !KioskModeInfo::IsValidPlatformVersion(required_platform_version))) {
*error = base::ASCIIToUTF16(
manifest_errors::kInvalidKioskRequiredPlatformVersion);
return false;
diff --git a/extensions/common/manifest_handlers/kiosk_mode_info.h b/extensions/common/manifest_handlers/kiosk_mode_info.h
index 514e78e..bd37f96 100644
--- a/extensions/common/manifest_handlers/kiosk_mode_info.h
+++ b/extensions/common/manifest_handlers/kiosk_mode_info.h
@@ -41,6 +41,10 @@ struct KioskModeInfo : public Extension::ManifestData {
// Returns true if |extension| declares kiosk secondary apps.
static bool HasSecondaryApps(const Extension* extension);
+ // Whether the given |version_string| is a valid ChromeOS platform version.
+ // The acceptable format is major[.minor[.micro]].
+ static bool IsValidPlatformVersion(const std::string& version_string);
+
KioskStatus kiosk_status;
// The IDs of the kiosk secondary apps.