app_isolation_info.cc revision 7d4cd473f85ac64c3747c96c277f9e506a0d2246
1// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/common/extensions/manifest_handlers/app_isolation_info.h"
6
7#include "base/memory/scoped_ptr.h"
8#include "base/strings/string16.h"
9#include "base/strings/string_number_conversions.h"
10#include "base/strings/utf_string_conversions.h"
11#include "base/values.h"
12#include "chrome/common/extensions/extension_manifest_constants.h"
13#include "chrome/common/extensions/permissions/api_permission_set.h"
14#include "chrome/common/extensions/permissions/permissions_data.h"
15#include "extensions/common/error_utils.h"
16
17namespace keys = extension_manifest_keys;
18
19namespace extensions {
20
21AppIsolationInfo::AppIsolationInfo(bool isolated_storage)
22    : has_isolated_storage(isolated_storage) {
23}
24
25AppIsolationInfo::~AppIsolationInfo() {
26}
27
28// static
29bool AppIsolationInfo::HasIsolatedStorage(const Extension* extension) {
30  AppIsolationInfo* info = static_cast<AppIsolationInfo*>(
31      extension->GetManifestData(keys::kIsolation));
32  return info ? info->has_isolated_storage : false;
33}
34
35AppIsolationHandler::AppIsolationHandler() {
36}
37
38AppIsolationHandler::~AppIsolationHandler() {
39}
40
41bool AppIsolationHandler::Parse(Extension* extension, string16* error) {
42  // Platform apps always get isolated storage.
43  if (extension->is_platform_app()) {
44    extension->SetManifestData(keys::kIsolation, new AppIsolationInfo(true));
45    return true;
46  }
47
48  // Other apps only get it if it is requested _and_ experimental APIs are
49  // enabled.
50  if (!extension->is_app() ||
51      !PermissionsData::GetInitialAPIPermissions(extension)->count(
52          APIPermission::kExperimental)) {
53    return true;
54  }
55
56  // We should only be parsing if the extension has the key in the manifest,
57  // or is a platform app (which we already handled).
58  DCHECK(extension->manifest()->HasPath(keys::kIsolation));
59
60  const base::ListValue* isolation_list = NULL;
61  if (!extension->manifest()->GetList(keys::kIsolation, &isolation_list)) {
62    *error = ASCIIToUTF16(extension_manifest_errors::kInvalidIsolation);
63    return false;
64  }
65
66  bool has_isolated_storage = false;
67  for (size_t i = 0; i < isolation_list->GetSize(); ++i) {
68    std::string isolation_string;
69    if (!isolation_list->GetString(i, &isolation_string)) {
70      *error = ErrorUtils::FormatErrorMessageUTF16(
71          extension_manifest_errors::kInvalidIsolationValue,
72          base::UintToString(i));
73      return false;
74    }
75
76    // Check for isolated storage.
77    if (isolation_string == extension_manifest_values::kIsolatedStorage) {
78      has_isolated_storage = true;
79    } else {
80      DLOG(WARNING) << "Did not recognize isolation type: " << isolation_string;
81    }
82  }
83
84  if (has_isolated_storage)
85    extension->SetManifestData(keys::kIsolation, new AppIsolationInfo(true));
86
87  return true;
88}
89
90bool AppIsolationHandler::AlwaysParseForType(Manifest::Type type) const {
91  return type == Manifest::TYPE_PLATFORM_APP;
92}
93
94const std::vector<std::string> AppIsolationHandler::Keys() const {
95  return SingleKey(keys::kIsolation);
96}
97
98}  // namespace extensions
99