Fix crash on app list start page contents not existing.
[chromium-blink-merge.git] / extensions / common / permissions / media_galleries_permission.cc
blob7f0133217e9f470a275e598cb014ab3a85f8b439
1 // Copyright 2014 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.
5 #include "extensions/common/permissions/media_galleries_permission.h"
7 #include <set>
8 #include <string>
10 #include "base/logging.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "extensions/common/permissions/permissions_info.h"
13 #include "grit/extensions_strings.h"
14 #include "ui/base/l10n/l10n_util.h"
16 namespace extensions {
18 namespace {
20 // copyTo permission requires delete permission as a prerequisite.
21 // delete permission requires read permission as a prerequisite.
22 bool IsValidPermissionSet(bool has_read, bool has_copy_to, bool has_delete,
23 std::string* error) {
24 if (has_copy_to) {
25 if (has_read && has_delete)
26 return true;
27 if (error)
28 *error = "copyTo permission requires read and delete permissions";
29 return false;
31 if (has_delete) {
32 if (has_read)
33 return true;
34 if (error)
35 *error = "delete permission requires read permission";
36 return false;
38 return true;
41 // Adds the permissions from the |data_set| to the permission lists that are
42 // not NULL. If NULL, that list is ignored.
43 void AddPermissionsToLists(
44 const std::set<MediaGalleriesPermissionData>& data_set,
45 PermissionIDSet* ids,
46 PermissionMessages* messages) {
47 // TODO(sashab): Once GetMessages() is deprecated, move this logic back into
48 // GetPermissions().
49 bool has_all_auto_detected = false;
50 bool has_read = false;
51 bool has_copy_to = false;
52 bool has_delete = false;
54 for (std::set<MediaGalleriesPermissionData>::const_iterator it =
55 data_set.begin();
56 it != data_set.end(); ++it) {
57 if (it->permission() ==
58 MediaGalleriesPermission::kAllAutoDetectedPermission)
59 has_all_auto_detected = true;
60 else if (it->permission() == MediaGalleriesPermission::kReadPermission)
61 has_read = true;
62 else if (it->permission() == MediaGalleriesPermission::kCopyToPermission)
63 has_copy_to = true;
64 else if (it->permission() == MediaGalleriesPermission::kDeletePermission)
65 has_delete = true;
68 if (!IsValidPermissionSet(has_read, has_copy_to, has_delete, NULL)) {
69 NOTREACHED();
70 return;
73 // If |has_all_auto_detected| is false, then Chrome will prompt the user at
74 // runtime when the extension call the getMediaGalleries API.
75 if (!has_all_auto_detected)
76 return;
77 // No access permission case.
78 if (!has_read)
79 return;
81 // Separate PermissionMessage IDs for read, copyTo, and delete. Otherwise an
82 // extension can silently gain new access capabilities.
83 if (messages) {
84 messages->push_back(PermissionMessage(
85 PermissionMessage::kMediaGalleriesAllGalleriesRead,
86 l10n_util::GetStringUTF16(
87 IDS_EXTENSION_PROMPT_WARNING_MEDIA_GALLERIES_READ)));
89 if (ids)
90 ids->insert(APIPermission::kMediaGalleriesAllGalleriesRead);
92 // For copyTo and delete, the proper combined permission message will be
93 // derived in ChromePermissionMessageProvider::GetWarningMessages(), such
94 // that the user get 1 entry for all media galleries access permissions,
95 // rather than several separate entries.
96 if (has_copy_to) {
97 if (messages) {
98 messages->push_back(PermissionMessage(
99 PermissionMessage::kMediaGalleriesAllGalleriesCopyTo,
100 base::string16()));
102 if (ids)
103 ids->insert(APIPermission::kMediaGalleriesAllGalleriesCopyTo);
105 if (has_delete) {
106 if (messages) {
107 messages->push_back(PermissionMessage(
108 PermissionMessage::kMediaGalleriesAllGalleriesDelete,
109 base::string16()));
111 if (ids)
112 ids->insert(APIPermission::kMediaGalleriesAllGalleriesDelete);
114 return;
117 } // namespace
119 const char MediaGalleriesPermission::kAllAutoDetectedPermission[] =
120 "allAutoDetected";
121 const char MediaGalleriesPermission::kScanPermission[] = "scan";
122 const char MediaGalleriesPermission::kReadPermission[] = "read";
123 const char MediaGalleriesPermission::kCopyToPermission[] = "copyTo";
124 const char MediaGalleriesPermission::kDeletePermission[] = "delete";
126 MediaGalleriesPermission::MediaGalleriesPermission(
127 const APIPermissionInfo* info)
128 : SetDisjunctionPermission<MediaGalleriesPermissionData,
129 MediaGalleriesPermission>(info) {
132 MediaGalleriesPermission::~MediaGalleriesPermission() {
135 bool MediaGalleriesPermission::FromValue(
136 const base::Value* value,
137 std::string* error,
138 std::vector<std::string>* unhandled_permissions) {
139 size_t unhandled_permissions_count = 0;
140 if (unhandled_permissions)
141 unhandled_permissions_count = unhandled_permissions->size();
142 bool parsed_ok =
143 SetDisjunctionPermission<MediaGalleriesPermissionData,
144 MediaGalleriesPermission>::FromValue(
145 value, error, unhandled_permissions);
146 if (unhandled_permissions) {
147 for (size_t i = unhandled_permissions_count;
148 i < unhandled_permissions->size();
149 i++) {
150 (*unhandled_permissions)[i] =
151 "{\"mediaGalleries\": [" + (*unhandled_permissions)[i] + "]}";
154 if (!parsed_ok)
155 return false;
157 bool has_read = false;
158 bool has_copy_to = false;
159 bool has_delete = false;
160 for (std::set<MediaGalleriesPermissionData>::const_iterator it =
161 data_set_.begin(); it != data_set_.end(); ++it) {
162 if (it->permission() == kAllAutoDetectedPermission ||
163 it->permission() == kScanPermission) {
164 continue;
166 if (it->permission() == kReadPermission) {
167 has_read = true;
168 continue;
170 if (it->permission() == kCopyToPermission) {
171 has_copy_to = true;
172 continue;
174 if (it->permission() == kDeletePermission) {
175 has_delete = true;
176 continue;
179 // No other permissions, so reaching this means
180 // MediaGalleriesPermissionData is probably out of sync in some way.
181 // Fail so developers notice this.
182 NOTREACHED();
183 return false;
186 return IsValidPermissionSet(has_read, has_copy_to, has_delete, error);
189 PermissionIDSet MediaGalleriesPermission::GetPermissions() const {
190 DCHECK(HasMessages());
191 PermissionIDSet result;
192 AddPermissionsToLists(data_set_, &result, NULL);
193 return result;
196 PermissionMessages MediaGalleriesPermission::GetMessages() const {
197 DCHECK(HasMessages());
198 PermissionMessages result;
199 AddPermissionsToLists(data_set_, NULL, &result);
200 return result;
203 } // namespace extensions