Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / ui / webui / cookies_tree_model_util.cc
blob968f9def46c98a833721c82b324030cd6fcd1e20
1 // Copyright (c) 2012 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 "chrome/browser/ui/webui/cookies_tree_model_util.h"
7 #include <vector>
9 #include "base/i18n/time_formatting.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/stl_util.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/string_split.h"
14 #include "base/strings/string_util.h"
15 #include "base/values.h"
16 #include "chrome/browser/browsing_data/cookies_tree_model.h"
17 #include "chrome/grit/generated_resources.h"
18 #include "content/public/browser/cache_storage_context.h"
19 #include "content/public/browser/indexed_db_context.h"
20 #include "content/public/browser/service_worker_context.h"
21 #include "net/cookies/canonical_cookie.h"
22 #include "storage/common/fileapi/file_system_types.h"
23 #include "ui/base/l10n/l10n_util.h"
24 #include "ui/base/text/bytes_formatting.h"
26 #if defined(ENABLE_EXTENSIONS)
27 #include "extensions/common/extension_set.h"
28 #endif
30 namespace {
32 const char kKeyId[] = "id";
33 const char kKeyTitle[] = "title";
34 const char kKeyIcon[] = "icon";
35 const char kKeyType[] = "type";
36 const char kKeyHasChildren[] = "hasChildren";
38 #if defined(ENABLE_EXTENSIONS)
39 const char kKeyAppsProtectingThis[] = "appsProtectingThis";
40 #endif
41 const char kKeyName[] = "name";
42 const char kKeyContent[] = "content";
43 const char kKeyDomain[] = "domain";
44 const char kKeyPath[] = "path";
45 const char kKeySendFor[] = "sendfor";
46 const char kKeyAccessibleToScript[] = "accessibleToScript";
47 const char kKeyDesc[] = "desc";
48 const char kKeySize[] = "size";
49 const char kKeyOrigin[] = "origin";
50 const char kKeyManifest[] = "manifest";
51 const char kKeyServerId[] = "serverId";
53 const char kKeyAccessed[] = "accessed";
54 const char kKeyCreated[] = "created";
55 const char kKeyExpires[] = "expires";
56 const char kKeyModified[] = "modified";
58 const char kKeyPersistent[] = "persistent";
59 const char kKeyTemporary[] = "temporary";
61 const char kKeyTotalUsage[] = "totalUsage";
62 const char kKeyTemporaryUsage[] = "temporaryUsage";
63 const char kKeyPersistentUsage[] = "persistentUsage";
65 const char kKeyCertType[] = "certType";
67 const char kKeyScopes[] = "scopes";
69 const int64 kNegligibleUsage = 1024; // 1KiB
71 } // namespace
73 CookiesTreeModelUtil::CookiesTreeModelUtil() {
76 CookiesTreeModelUtil::~CookiesTreeModelUtil() {
79 std::string CookiesTreeModelUtil::GetTreeNodeId(const CookieTreeNode* node) {
80 CookieTreeNodeMap::const_iterator iter = node_map_.find(node);
81 if (iter != node_map_.end())
82 return base::IntToString(iter->second);
84 int32 new_id = id_map_.Add(node);
85 node_map_[node] = new_id;
86 return base::IntToString(new_id);
89 bool CookiesTreeModelUtil::GetCookieTreeNodeDictionary(
90 const CookieTreeNode& node,
91 base::DictionaryValue* dict) {
92 // Use node's address as an id for WebUI to look it up.
93 dict->SetString(kKeyId, GetTreeNodeId(&node));
94 dict->SetString(kKeyTitle, node.GetTitle());
95 dict->SetBoolean(kKeyHasChildren, !node.empty());
97 switch (node.GetDetailedInfo().node_type) {
98 case CookieTreeNode::DetailedInfo::TYPE_HOST: {
99 dict->SetString(kKeyType, "origin");
100 #if defined(OS_MACOSX)
101 dict->SetString(kKeyIcon, "chrome://theme/IDR_BOOKMARK_BAR_FOLDER");
102 #endif
103 break;
105 case CookieTreeNode::DetailedInfo::TYPE_COOKIE: {
106 dict->SetString(kKeyType, "cookie");
107 dict->SetString(kKeyIcon, "chrome://theme/IDR_COOKIE_ICON");
109 const net::CanonicalCookie& cookie = *node.GetDetailedInfo().cookie;
111 dict->SetString(kKeyName, cookie.Name());
112 dict->SetString(kKeyContent, cookie.Value());
113 dict->SetString(kKeyDomain, cookie.Domain());
114 dict->SetString(kKeyPath, cookie.Path());
115 dict->SetString(kKeySendFor,
116 l10n_util::GetStringUTF16(
117 CookiesTreeModel::GetSendForMessageID(cookie)));
118 std::string accessible = cookie.IsHttpOnly() ?
119 l10n_util::GetStringUTF8(IDS_COOKIES_COOKIE_ACCESSIBLE_TO_SCRIPT_NO) :
120 l10n_util::GetStringUTF8(IDS_COOKIES_COOKIE_ACCESSIBLE_TO_SCRIPT_YES);
121 dict->SetString(kKeyAccessibleToScript, accessible);
122 dict->SetString(kKeyCreated, base::UTF16ToUTF8(
123 base::TimeFormatFriendlyDateAndTime(cookie.CreationDate())));
124 dict->SetString(kKeyExpires, cookie.IsPersistent() ? base::UTF16ToUTF8(
125 base::TimeFormatFriendlyDateAndTime(cookie.ExpiryDate())) :
126 l10n_util::GetStringUTF8(IDS_COOKIES_COOKIE_EXPIRES_SESSION));
128 break;
130 case CookieTreeNode::DetailedInfo::TYPE_DATABASE: {
131 dict->SetString(kKeyType, "database");
132 dict->SetString(kKeyIcon, "chrome://theme/IDR_COOKIE_STORAGE_ICON");
134 const BrowsingDataDatabaseHelper::DatabaseInfo& database_info =
135 *node.GetDetailedInfo().database_info;
137 dict->SetString(kKeyName, database_info.database_name.empty() ?
138 l10n_util::GetStringUTF8(IDS_COOKIES_WEB_DATABASE_UNNAMED_NAME) :
139 database_info.database_name);
140 dict->SetString(kKeyDesc, database_info.description);
141 dict->SetString(kKeySize, ui::FormatBytes(database_info.size));
142 dict->SetString(kKeyModified, base::UTF16ToUTF8(
143 base::TimeFormatFriendlyDateAndTime(database_info.last_modified)));
145 break;
147 case CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE: {
148 dict->SetString(kKeyType, "local_storage");
149 dict->SetString(kKeyIcon, "chrome://theme/IDR_COOKIE_STORAGE_ICON");
151 const BrowsingDataLocalStorageHelper::LocalStorageInfo&
152 local_storage_info = *node.GetDetailedInfo().local_storage_info;
154 dict->SetString(kKeyOrigin, local_storage_info.origin_url.spec());
155 dict->SetString(kKeySize, ui::FormatBytes(local_storage_info.size));
156 dict->SetString(kKeyModified, base::UTF16ToUTF8(
157 base::TimeFormatFriendlyDateAndTime(
158 local_storage_info.last_modified)));
160 break;
162 case CookieTreeNode::DetailedInfo::TYPE_APPCACHE: {
163 dict->SetString(kKeyType, "app_cache");
164 dict->SetString(kKeyIcon, "chrome://theme/IDR_COOKIE_STORAGE_ICON");
166 const content::AppCacheInfo& appcache_info =
167 *node.GetDetailedInfo().appcache_info;
169 dict->SetString(kKeyManifest, appcache_info.manifest_url.spec());
170 dict->SetString(kKeySize, ui::FormatBytes(appcache_info.size));
171 dict->SetString(kKeyCreated, base::UTF16ToUTF8(
172 base::TimeFormatFriendlyDateAndTime(appcache_info.creation_time)));
173 dict->SetString(kKeyAccessed, base::UTF16ToUTF8(
174 base::TimeFormatFriendlyDateAndTime(appcache_info.last_access_time)));
176 break;
178 case CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB: {
179 dict->SetString(kKeyType, "indexed_db");
180 dict->SetString(kKeyIcon, "chrome://theme/IDR_COOKIE_STORAGE_ICON");
182 const content::IndexedDBInfo& indexed_db_info =
183 *node.GetDetailedInfo().indexed_db_info;
185 dict->SetString(kKeyOrigin, indexed_db_info.origin.spec());
186 dict->SetString(kKeySize, ui::FormatBytes(indexed_db_info.size));
187 dict->SetString(kKeyModified,
188 base::UTF16ToUTF8(base::TimeFormatFriendlyDateAndTime(
189 indexed_db_info.last_modified)));
190 break;
192 case CookieTreeNode::DetailedInfo::TYPE_FILE_SYSTEM: {
193 dict->SetString(kKeyType, "file_system");
194 dict->SetString(kKeyIcon, "chrome://theme/IDR_COOKIE_STORAGE_ICON");
196 const BrowsingDataFileSystemHelper::FileSystemInfo& file_system_info =
197 *node.GetDetailedInfo().file_system_info;
198 const storage::FileSystemType kPerm = storage::kFileSystemTypePersistent;
199 const storage::FileSystemType kTemp = storage::kFileSystemTypeTemporary;
201 dict->SetString(kKeyOrigin, file_system_info.origin.spec());
202 dict->SetString(kKeyPersistent,
203 ContainsKey(file_system_info.usage_map, kPerm) ?
204 base::UTF16ToUTF8(ui::FormatBytes(
205 file_system_info.usage_map.find(kPerm)->second)) :
206 l10n_util::GetStringUTF8(
207 IDS_COOKIES_FILE_SYSTEM_USAGE_NONE));
208 dict->SetString(kKeyTemporary,
209 ContainsKey(file_system_info.usage_map, kTemp) ?
210 base::UTF16ToUTF8(ui::FormatBytes(
211 file_system_info.usage_map.find(kTemp)->second)) :
212 l10n_util::GetStringUTF8(
213 IDS_COOKIES_FILE_SYSTEM_USAGE_NONE));
214 break;
216 case CookieTreeNode::DetailedInfo::TYPE_QUOTA: {
217 dict->SetString(kKeyType, "quota");
218 dict->SetString(kKeyIcon, "chrome://theme/IDR_COOKIE_STORAGE_ICON");
220 const BrowsingDataQuotaHelper::QuotaInfo& quota_info =
221 *node.GetDetailedInfo().quota_info;
222 if (quota_info.temporary_usage + quota_info.persistent_usage <=
223 kNegligibleUsage)
224 return false;
226 dict->SetString(kKeyOrigin, quota_info.host);
227 dict->SetString(kKeyTotalUsage,
228 base::UTF16ToUTF8(ui::FormatBytes(
229 quota_info.temporary_usage +
230 quota_info.persistent_usage)));
231 dict->SetString(kKeyTemporaryUsage,
232 base::UTF16ToUTF8(ui::FormatBytes(
233 quota_info.temporary_usage)));
234 dict->SetString(kKeyPersistentUsage,
235 base::UTF16ToUTF8(ui::FormatBytes(
236 quota_info.persistent_usage)));
237 break;
239 case CookieTreeNode::DetailedInfo::TYPE_CHANNEL_ID: {
240 dict->SetString(kKeyType, "channel_id");
241 dict->SetString(kKeyIcon, "chrome://theme/IDR_COOKIE_ICON");
243 const net::ChannelIDStore::ChannelID& channel_id =
244 *node.GetDetailedInfo().channel_id;
246 dict->SetString(kKeyServerId, channel_id.server_identifier());
247 dict->SetString(kKeyCertType,
248 l10n_util::GetStringUTF8(IDS_CLIENT_CERT_ECDSA_SIGN));
249 dict->SetString(kKeyCreated, base::UTF16ToUTF8(
250 base::TimeFormatFriendlyDateAndTime(
251 channel_id.creation_time())));
252 break;
254 case CookieTreeNode::DetailedInfo::TYPE_SERVICE_WORKER: {
255 dict->SetString(kKeyType, "service_worker");
256 dict->SetString(kKeyIcon, "chrome://theme/IDR_COOKIE_STORAGE_ICON");
258 const content::ServiceWorkerUsageInfo& service_worker_info =
259 *node.GetDetailedInfo().service_worker_info;
261 dict->SetString(kKeyOrigin, service_worker_info.origin.spec());
262 dict->SetString(kKeySize,
263 ui::FormatBytes(service_worker_info.total_size_bytes));
264 base::ListValue* scopes = new base::ListValue;
265 for (std::vector<GURL>::const_iterator it =
266 service_worker_info.scopes.begin();
267 it != service_worker_info.scopes.end();
268 ++it) {
269 scopes->AppendString(it->spec());
271 dict->Set(kKeyScopes, scopes);
272 break;
274 case CookieTreeNode::DetailedInfo::TYPE_CACHE_STORAGE: {
275 dict->SetString(kKeyType, "cache_storage");
276 dict->SetString(kKeyIcon, "chrome://theme/IDR_COOKIE_STORAGE_ICON");
278 const content::CacheStorageUsageInfo& cache_storage_info =
279 *node.GetDetailedInfo().cache_storage_info;
281 dict->SetString(kKeyOrigin, cache_storage_info.origin.spec());
282 dict->SetString(kKeySize,
283 ui::FormatBytes(cache_storage_info.total_size_bytes));
284 dict->SetString(kKeyModified,
285 base::UTF16ToUTF8(base::TimeFormatFriendlyDateAndTime(
286 cache_storage_info.last_modified)));
287 break;
289 case CookieTreeNode::DetailedInfo::TYPE_FLASH_LSO: {
290 dict->SetString(kKeyType, "flash_lso");
291 dict->SetString(kKeyIcon, "chrome://theme/IDR_COOKIE_ICON");
293 dict->SetString(kKeyDomain, node.GetDetailedInfo().flash_lso_domain);
295 default:
296 #if defined(OS_MACOSX)
297 dict->SetString(kKeyIcon, "chrome://theme/IDR_BOOKMARK_BAR_FOLDER");
298 #endif
299 break;
302 #if defined(ENABLE_EXTENSIONS)
303 const extensions::ExtensionSet* protecting_apps =
304 node.GetModel()->ExtensionsProtectingNode(node);
305 if (protecting_apps && !protecting_apps->is_empty()) {
306 base::ListValue* app_infos = new base::ListValue;
307 for (extensions::ExtensionSet::const_iterator it = protecting_apps->begin();
308 it != protecting_apps->end(); ++it) {
309 base::DictionaryValue* app_info = new base::DictionaryValue();
310 app_info->SetString(kKeyId, (*it)->id());
311 app_info->SetString(kKeyName, (*it)->name());
312 app_infos->Append(app_info);
314 dict->Set(kKeyAppsProtectingThis, app_infos);
316 #endif
318 return true;
321 void CookiesTreeModelUtil::GetChildNodeList(const CookieTreeNode* parent,
322 int start,
323 int count,
324 base::ListValue* nodes) {
325 for (int i = 0; i < count; ++i) {
326 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
327 const CookieTreeNode* child = parent->GetChild(start + i);
328 if (GetCookieTreeNodeDictionary(*child, dict.get()))
329 nodes->Append(dict.release());
333 const CookieTreeNode* CookiesTreeModelUtil::GetTreeNodeFromPath(
334 const CookieTreeNode* root,
335 const std::string& path) {
336 const CookieTreeNode* child = NULL;
337 const CookieTreeNode* parent = root;
338 int child_index = -1;
340 // Validate the tree path and get the node pointer.
341 for (const base::StringPiece& cur_node : base::SplitStringPiece(
342 path, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) {
343 int32 node_id = 0;
344 if (!base::StringToInt(cur_node, &node_id))
345 break;
347 child = id_map_.Lookup(node_id);
348 child_index = parent->GetIndexOf(child);
349 if (child_index == -1)
350 break;
352 parent = child;
355 return child_index >= 0 ? child : NULL;