1 // Copyright (c) 2011 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/browser/ui/webui/cookies_tree_model_util.h" 6 7 #include "base/i18n/time_formatting.h" 8 #include "base/string_number_conversions.h" 9 #include "base/string_split.h" 10 #include "base/string_util.h" 11 #include "base/values.h" 12 #include "chrome/browser/cookies_tree_model.h" 13 #include "grit/generated_resources.h" 14 #include "ui/base/l10n/l10n_util.h" 15 16 namespace { 17 18 static const char kKeyId[] = "id"; 19 static const char kKeyTitle[] = "title"; 20 static const char kKeyIcon[] = "icon"; 21 static const char kKeyType[] = "type"; 22 static const char kKeyHasChildren[] = "hasChildren"; 23 24 static const char kKeyName[] = "name"; 25 static const char kKeyContent[] = "content"; 26 static const char kKeyDomain[] = "domain"; 27 static const char kKeyPath[] = "path"; 28 static const char kKeySendFor[] = "sendfor"; 29 static const char kKeyAccessibleToScript[] = "accessibleToScript"; 30 static const char kKeyDesc[] = "desc"; 31 static const char kKeySize[] = "size"; 32 static const char kKeyOrigin[] = "origin"; 33 static const char kKeyManifest[] = "manifest"; 34 35 static const char kKeyAccessed[] = "accessed"; 36 static const char kKeyCreated[] = "created"; 37 static const char kKeyExpires[] = "expires"; 38 static const char kKeyModified[] = "modified"; 39 40 // Encodes a pointer value into a hex string. 41 std::string PointerToHexString(const void* pointer) { 42 return base::HexEncode(&pointer, sizeof(pointer)); 43 } 44 45 // Decodes a pointer from a hex string. 46 void* HexStringToPointer(const std::string& str) { 47 std::vector<uint8> buffer; 48 if (!base::HexStringToBytes(str, &buffer) || 49 buffer.size() != sizeof(void*)) { 50 return NULL; 51 } 52 53 return *reinterpret_cast<void**>(&buffer[0]); 54 } 55 56 } // namespace 57 58 namespace cookies_tree_model_util { 59 60 std::string GetTreeNodeId(CookieTreeNode* node) { 61 return PointerToHexString(node); 62 } 63 64 void GetCookieTreeNodeDictionary(const CookieTreeNode& node, 65 DictionaryValue* dict) { 66 // Use node's address as an id for WebUI to look it up. 67 dict->SetString(kKeyId, PointerToHexString(&node)); 68 dict->SetString(kKeyTitle, node.GetTitle()); 69 dict->SetBoolean(kKeyHasChildren, !!node.child_count()); 70 71 switch (node.GetDetailedInfo().node_type) { 72 case CookieTreeNode::DetailedInfo::TYPE_ORIGIN: { 73 dict->SetString(kKeyType, "origin"); 74 #if defined(OS_MACOSX) 75 dict->SetString(kKeyIcon, "chrome://theme/IDR_BOOKMARK_BAR_FOLDER"); 76 #endif 77 break; 78 } 79 case CookieTreeNode::DetailedInfo::TYPE_COOKIE: { 80 dict->SetString(kKeyType, "cookie"); 81 dict->SetString(kKeyIcon, "chrome://theme/IDR_COOKIE_ICON"); 82 83 const net::CookieMonster::CanonicalCookie& cookie = 84 *node.GetDetailedInfo().cookie; 85 86 dict->SetString(kKeyName, cookie.Name()); 87 dict->SetString(kKeyContent, cookie.Value()); 88 dict->SetString(kKeyDomain, cookie.Domain()); 89 dict->SetString(kKeyPath, cookie.Path()); 90 dict->SetString(kKeySendFor, cookie.IsSecure() ? 91 l10n_util::GetStringUTF8(IDS_COOKIES_COOKIE_SENDFOR_SECURE) : 92 l10n_util::GetStringUTF8(IDS_COOKIES_COOKIE_SENDFOR_ANY)); 93 std::string accessible = cookie.IsHttpOnly() ? 94 l10n_util::GetStringUTF8(IDS_COOKIES_COOKIE_ACCESSIBLE_TO_SCRIPT_NO) : 95 l10n_util::GetStringUTF8(IDS_COOKIES_COOKIE_ACCESSIBLE_TO_SCRIPT_YES); 96 dict->SetString(kKeyAccessibleToScript, accessible); 97 dict->SetString(kKeyCreated, UTF16ToUTF8( 98 base::TimeFormatFriendlyDateAndTime(cookie.CreationDate()))); 99 dict->SetString(kKeyExpires, cookie.DoesExpire() ? UTF16ToUTF8( 100 base::TimeFormatFriendlyDateAndTime(cookie.ExpiryDate())) : 101 l10n_util::GetStringUTF8(IDS_COOKIES_COOKIE_EXPIRES_SESSION)); 102 103 break; 104 } 105 case CookieTreeNode::DetailedInfo::TYPE_DATABASE: { 106 dict->SetString(kKeyType, "database"); 107 dict->SetString(kKeyIcon, "chrome://theme/IDR_COOKIE_STORAGE_ICON"); 108 109 const BrowsingDataDatabaseHelper::DatabaseInfo& database_info = 110 *node.GetDetailedInfo().database_info; 111 112 dict->SetString(kKeyName, database_info.database_name.empty() ? 113 l10n_util::GetStringUTF8(IDS_COOKIES_WEB_DATABASE_UNNAMED_NAME) : 114 database_info.database_name); 115 dict->SetString(kKeyDesc, database_info.description); 116 dict->SetString(kKeySize, 117 FormatBytes(database_info.size, 118 GetByteDisplayUnits(database_info.size), 119 true)); 120 dict->SetString(kKeyModified, UTF16ToUTF8( 121 base::TimeFormatFriendlyDateAndTime(database_info.last_modified))); 122 123 break; 124 } 125 case CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE: { 126 dict->SetString(kKeyType, "local_storage"); 127 dict->SetString(kKeyIcon, "chrome://theme/IDR_COOKIE_STORAGE_ICON"); 128 129 const BrowsingDataLocalStorageHelper::LocalStorageInfo& 130 local_storage_info = *node.GetDetailedInfo().local_storage_info; 131 132 dict->SetString(kKeyOrigin, local_storage_info.origin); 133 dict->SetString(kKeySize, 134 FormatBytes(local_storage_info.size, 135 GetByteDisplayUnits(local_storage_info.size), 136 true)); 137 dict->SetString(kKeyModified, UTF16ToUTF8( 138 base::TimeFormatFriendlyDateAndTime( 139 local_storage_info.last_modified))); 140 141 break; 142 } 143 case CookieTreeNode::DetailedInfo::TYPE_APPCACHE: { 144 dict->SetString(kKeyType, "app_cache"); 145 dict->SetString(kKeyIcon, "chrome://theme/IDR_COOKIE_STORAGE_ICON"); 146 147 const appcache::AppCacheInfo& appcache_info = 148 *node.GetDetailedInfo().appcache_info; 149 150 dict->SetString(kKeyManifest, appcache_info.manifest_url.spec()); 151 dict->SetString(kKeySize, 152 FormatBytes(appcache_info.size, 153 GetByteDisplayUnits(appcache_info.size), 154 true)); 155 dict->SetString(kKeyCreated, UTF16ToUTF8( 156 base::TimeFormatFriendlyDateAndTime(appcache_info.creation_time))); 157 dict->SetString(kKeyAccessed, UTF16ToUTF8( 158 base::TimeFormatFriendlyDateAndTime(appcache_info.last_access_time))); 159 160 break; 161 } 162 case CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB: { 163 dict->SetString(kKeyType, "indexed_db"); 164 dict->SetString(kKeyIcon, "chrome://theme/IDR_COOKIE_STORAGE_ICON"); 165 166 const BrowsingDataIndexedDBHelper::IndexedDBInfo& indexed_db_info = 167 *node.GetDetailedInfo().indexed_db_info; 168 169 dict->SetString(kKeyOrigin, indexed_db_info.origin); 170 dict->SetString(kKeySize, 171 FormatBytes(indexed_db_info.size, 172 GetByteDisplayUnits(indexed_db_info.size), 173 true)); 174 dict->SetString(kKeyModified, UTF16ToUTF8( 175 base::TimeFormatFriendlyDateAndTime(indexed_db_info.last_modified))); 176 177 break; 178 } 179 default: 180 #if defined(OS_MACOSX) 181 dict->SetString(kKeyIcon, "chrome://theme/IDR_BOOKMARK_BAR_FOLDER"); 182 #endif 183 break; 184 } 185 } 186 187 void GetChildNodeList(CookieTreeNode* parent, int start, int count, 188 ListValue* nodes) { 189 for (int i = 0; i < count; ++i) { 190 DictionaryValue* dict = new DictionaryValue; 191 CookieTreeNode* child = parent->GetChild(start + i); 192 GetCookieTreeNodeDictionary(*child, dict); 193 nodes->Append(dict); 194 } 195 } 196 197 CookieTreeNode* GetTreeNodeFromPath(CookieTreeNode* root, 198 const std::string& path) { 199 std::vector<std::string> node_ids; 200 base::SplitString(path, ',', &node_ids); 201 202 CookieTreeNode* child = NULL; 203 CookieTreeNode* parent = root; 204 int child_index = -1; 205 206 // Validate the tree path and get the node pointer. 207 for (size_t i = 0; i < node_ids.size(); ++i) { 208 child = reinterpret_cast<CookieTreeNode*>( 209 HexStringToPointer(node_ids[i])); 210 211 child_index = parent->GetIndexOf(child); 212 if (child_index == -1) 213 break; 214 215 parent = child; 216 } 217 218 return child_index >= 0 ? child : NULL; 219 } 220 221 } // namespace cookies_tree_model_util 222