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 #ifndef CHROME_BROWSER_COOKIES_TREE_MODEL_H_ 6 #define CHROME_BROWSER_COOKIES_TREE_MODEL_H_ 7 #pragma once 8 9 // TODO(viettrungluu): This header file #includes far too much and has too much 10 // inline code (which shouldn't be inline). 11 12 #include <string> 13 #include <vector> 14 15 #include "base/memory/ref_counted.h" 16 #include "base/observer_list.h" 17 #include "base/string16.h" 18 #include "base/utf_string_conversions.h" 19 #include "chrome/browser/browsing_data_appcache_helper.h" 20 #include "chrome/browser/browsing_data_database_helper.h" 21 #include "chrome/browser/browsing_data_indexed_db_helper.h" 22 #include "chrome/browser/browsing_data_local_storage_helper.h" 23 #include "net/base/cookie_monster.h" 24 #include "ui/base/models/tree_node_model.h" 25 26 class CookiesTreeModel; 27 class CookieTreeAppCacheNode; 28 class CookieTreeAppCachesNode; 29 class CookieTreeCookieNode; 30 class CookieTreeCookiesNode; 31 class CookieTreeDatabaseNode; 32 class CookieTreeDatabasesNode; 33 class CookieTreeLocalStorageNode; 34 class CookieTreeLocalStoragesNode; 35 class CookieTreeSessionStorageNode; 36 class CookieTreeSessionStoragesNode; 37 class CookieTreeIndexedDBNode; 38 class CookieTreeIndexedDBsNode; 39 class CookieTreeOriginNode; 40 41 // CookieTreeNode ------------------------------------------------------------- 42 // The base node type in the Cookies, Databases, and Local Storage options 43 // view, from which all other types are derived. Specialized from TreeNode in 44 // that it has a notion of deleting objects stored in the profile, and being 45 // able to have its children do the same. 46 class CookieTreeNode : public ui::TreeNode<CookieTreeNode> { 47 public: 48 // Used to pull out information for the InfoView (the details display below 49 // the tree control.) 50 struct DetailedInfo { 51 // NodeType corresponds to the various CookieTreeNode types. 52 enum NodeType { 53 TYPE_ROOT, // This is used for CookieTreeRootNode nodes. 54 TYPE_ORIGIN, // This is used for CookieTreeOriginNode nodes. 55 TYPE_COOKIES, // This is used for CookieTreeCookiesNode nodes. 56 TYPE_COOKIE, // This is used for CookieTreeCookieNode nodes. 57 TYPE_DATABASES, // This is used for CookieTreeDatabasesNode. 58 TYPE_DATABASE, // This is used for CookieTreeDatabaseNode. 59 TYPE_LOCAL_STORAGES, // This is used for CookieTreeLocalStoragesNode. 60 TYPE_LOCAL_STORAGE, // This is used for CookieTreeLocalStorageNode. 61 TYPE_SESSION_STORAGES, // This is used for CookieTreeSessionStoragesNode. 62 TYPE_SESSION_STORAGE, // This is used for CookieTreeSessionStorageNode. 63 TYPE_APPCACHES, // This is used for CookieTreeAppCachesNode. 64 TYPE_APPCACHE, // This is used for CookieTreeAppCacheNode. 65 TYPE_INDEXED_DBS, // This is used for CookieTreeIndexedDBsNode. 66 TYPE_INDEXED_DB, // This is used for CookieTreeIndexedDBNode. 67 }; 68 69 // TODO(viettrungluu): Figure out whether we want to store |origin| as a 70 // |string16| or a (UTF-8) |std::string|, and convert. Remove constructor 71 // taking an |std::wstring|. 72 DetailedInfo(const string16& origin, NodeType node_type, 73 const net::CookieMonster::CanonicalCookie* cookie, 74 const BrowsingDataDatabaseHelper::DatabaseInfo* database_info, 75 const BrowsingDataLocalStorageHelper::LocalStorageInfo* 76 local_storage_info, 77 const BrowsingDataLocalStorageHelper::LocalStorageInfo* 78 session_storage_info, 79 const appcache::AppCacheInfo* appcache_info, 80 const BrowsingDataIndexedDBHelper::IndexedDBInfo* indexed_db_info) 81 : origin(UTF16ToWideHack(origin)), 82 node_type(node_type), 83 cookie(cookie), 84 database_info(database_info), 85 local_storage_info(local_storage_info), 86 session_storage_info(session_storage_info), 87 appcache_info(appcache_info), 88 indexed_db_info(indexed_db_info) { 89 DCHECK((node_type != TYPE_DATABASE) || database_info); 90 DCHECK((node_type != TYPE_LOCAL_STORAGE) || local_storage_info); 91 DCHECK((node_type != TYPE_SESSION_STORAGE) || session_storage_info); 92 DCHECK((node_type != TYPE_APPCACHE) || appcache_info); 93 DCHECK((node_type != TYPE_INDEXED_DB) || indexed_db_info); 94 } 95 #if !defined(WCHAR_T_IS_UTF16) 96 DetailedInfo(const std::wstring& origin, NodeType node_type, 97 const net::CookieMonster::CanonicalCookie* cookie, 98 const BrowsingDataDatabaseHelper::DatabaseInfo* database_info, 99 const BrowsingDataLocalStorageHelper::LocalStorageInfo* 100 local_storage_info, 101 const BrowsingDataLocalStorageHelper::LocalStorageInfo* 102 session_storage_info, 103 const appcache::AppCacheInfo* appcache_info, 104 const BrowsingDataIndexedDBHelper::IndexedDBInfo* indexed_db_info) 105 : origin(origin), 106 node_type(node_type), 107 cookie(cookie), 108 database_info(database_info), 109 local_storage_info(local_storage_info), 110 session_storage_info(session_storage_info), 111 appcache_info(appcache_info), 112 indexed_db_info(indexed_db_info) { 113 DCHECK((node_type != TYPE_DATABASE) || database_info); 114 DCHECK((node_type != TYPE_LOCAL_STORAGE) || local_storage_info); 115 DCHECK((node_type != TYPE_SESSION_STORAGE) || session_storage_info); 116 DCHECK((node_type != TYPE_APPCACHE) || appcache_info); 117 DCHECK((node_type != TYPE_INDEXED_DB) || indexed_db_info); 118 } 119 #endif 120 121 std::wstring origin; 122 NodeType node_type; 123 const net::CookieMonster::CanonicalCookie* cookie; 124 const BrowsingDataDatabaseHelper::DatabaseInfo* database_info; 125 const BrowsingDataLocalStorageHelper::LocalStorageInfo* local_storage_info; 126 const BrowsingDataLocalStorageHelper::LocalStorageInfo* 127 session_storage_info; 128 const appcache::AppCacheInfo* appcache_info; 129 const BrowsingDataIndexedDBHelper::IndexedDBInfo* indexed_db_info; 130 }; 131 132 CookieTreeNode() {} 133 explicit CookieTreeNode(const string16& title) 134 : ui::TreeNode<CookieTreeNode>(title) {} 135 virtual ~CookieTreeNode() {} 136 137 // Delete backend storage for this node, and any children nodes. (E.g. delete 138 // the cookie from CookieMonster, clear the database, and so forth.) 139 virtual void DeleteStoredObjects(); 140 141 // Gets a pointer back to the associated model for the tree we are in. 142 virtual CookiesTreeModel* GetModel() const; 143 144 // Returns a struct with detailed information used to populate the details 145 // part of the view. 146 virtual DetailedInfo GetDetailedInfo() const = 0; 147 148 protected: 149 class NodeTitleComparator { 150 public: 151 bool operator() (const CookieTreeNode* lhs, const CookieTreeNode* rhs); 152 }; 153 154 void AddChildSortedByTitle(CookieTreeNode* new_child); 155 156 private: 157 158 DISALLOW_COPY_AND_ASSIGN(CookieTreeNode); 159 }; 160 161 // CookieTreeRootNode --------------------------------------------------------- 162 // The node at the root of the CookieTree that gets inserted into the view. 163 class CookieTreeRootNode : public CookieTreeNode { 164 public: 165 explicit CookieTreeRootNode(CookiesTreeModel* model); 166 virtual ~CookieTreeRootNode(); 167 168 CookieTreeOriginNode* GetOrCreateOriginNode(const GURL& url); 169 170 // CookieTreeNode methods: 171 virtual CookiesTreeModel* GetModel() const; 172 virtual DetailedInfo GetDetailedInfo() const; 173 174 private: 175 CookiesTreeModel* model_; 176 177 DISALLOW_COPY_AND_ASSIGN(CookieTreeRootNode); 178 }; 179 180 // CookieTreeOriginNode ------------------------------------------------------- 181 class CookieTreeOriginNode : public CookieTreeNode { 182 public: 183 // Returns the origin node's title to use for a given URL. 184 static std::wstring TitleForUrl(const GURL& url); 185 186 explicit CookieTreeOriginNode(const GURL& url); 187 virtual ~CookieTreeOriginNode(); 188 189 // CookieTreeNode methods: 190 virtual DetailedInfo GetDetailedInfo() const; 191 192 // CookieTreeOriginNode methods: 193 CookieTreeCookiesNode* GetOrCreateCookiesNode(); 194 CookieTreeDatabasesNode* GetOrCreateDatabasesNode(); 195 CookieTreeLocalStoragesNode* GetOrCreateLocalStoragesNode(); 196 CookieTreeSessionStoragesNode* GetOrCreateSessionStoragesNode(); 197 CookieTreeAppCachesNode* GetOrCreateAppCachesNode(); 198 CookieTreeIndexedDBsNode* GetOrCreateIndexedDBsNode(); 199 200 // Creates an content exception for this origin of type 201 // CONTENT_SETTINGS_TYPE_COOKIES. 202 void CreateContentException(HostContentSettingsMap* content_settings, 203 ContentSetting setting) const; 204 205 // True if a content exception can be created for this origin. 206 bool CanCreateContentException() const; 207 208 private: 209 // Pointers to the cookies, databases, local and session storage and appcache 210 // nodes. When we build up the tree we need to quickly get a reference to 211 // the COOKIES node to add children. Checking each child and interrogating 212 // them to see if they are a COOKIES, APPCACHES, DATABASES etc node seems 213 // less preferable than storing an extra pointer per origin. 214 CookieTreeCookiesNode* cookies_child_; 215 CookieTreeDatabasesNode* databases_child_; 216 CookieTreeLocalStoragesNode* local_storages_child_; 217 CookieTreeSessionStoragesNode* session_storages_child_; 218 CookieTreeAppCachesNode* appcaches_child_; 219 CookieTreeIndexedDBsNode* indexed_dbs_child_; 220 221 // The URL for which this node was initially created. 222 GURL url_; 223 224 DISALLOW_COPY_AND_ASSIGN(CookieTreeOriginNode); 225 }; 226 227 // CookieTreeCookieNode ------------------------------------------------------ 228 class CookieTreeCookieNode : public CookieTreeNode { 229 public: 230 friend class CookieTreeCookiesNode; 231 232 // Does not take ownership of cookie, and cookie should remain valid at least 233 // as long as the CookieTreeCookieNode is valid. 234 explicit CookieTreeCookieNode(net::CookieMonster::CanonicalCookie* cookie); 235 virtual ~CookieTreeCookieNode(); 236 237 // CookieTreeNode methods: 238 virtual void DeleteStoredObjects(); 239 virtual DetailedInfo GetDetailedInfo() const; 240 241 private: 242 // Cookie_ is not owned by the node, and is expected to remain valid as long 243 // as the CookieTreeCookieNode is valid. 244 net::CookieMonster::CanonicalCookie* cookie_; 245 246 DISALLOW_COPY_AND_ASSIGN(CookieTreeCookieNode); 247 }; 248 249 class CookieTreeCookiesNode : public CookieTreeNode { 250 public: 251 CookieTreeCookiesNode(); 252 virtual ~CookieTreeCookiesNode(); 253 254 virtual DetailedInfo GetDetailedInfo() const; 255 256 void AddCookieNode(CookieTreeCookieNode* child) { 257 AddChildSortedByTitle(child); 258 } 259 260 private: 261 DISALLOW_COPY_AND_ASSIGN(CookieTreeCookiesNode); 262 }; 263 264 // CookieTreeAppCacheNode ----------------------------------------------------- 265 class CookieTreeAppCacheNode : public CookieTreeNode { 266 public: 267 friend class CookieTreeAppCachesNode; 268 269 // Does not take ownership of appcache_info, and appcache_info should remain 270 // valid at least as long as the CookieTreeAppCacheNode is valid. 271 explicit CookieTreeAppCacheNode( 272 const appcache::AppCacheInfo* appcache_info); 273 virtual ~CookieTreeAppCacheNode() {} 274 275 virtual void DeleteStoredObjects(); 276 virtual DetailedInfo GetDetailedInfo() const; 277 278 private: 279 const appcache::AppCacheInfo* appcache_info_; 280 DISALLOW_COPY_AND_ASSIGN(CookieTreeAppCacheNode); 281 }; 282 283 class CookieTreeAppCachesNode : public CookieTreeNode { 284 public: 285 CookieTreeAppCachesNode(); 286 virtual ~CookieTreeAppCachesNode(); 287 288 virtual DetailedInfo GetDetailedInfo() const; 289 290 void AddAppCacheNode(CookieTreeAppCacheNode* child) { 291 AddChildSortedByTitle(child); 292 } 293 294 private: 295 DISALLOW_COPY_AND_ASSIGN(CookieTreeAppCachesNode); 296 }; 297 298 // CookieTreeDatabaseNode ----------------------------------------------------- 299 class CookieTreeDatabaseNode : public CookieTreeNode { 300 public: 301 friend class CookieTreeDatabasesNode; 302 303 // Does not take ownership of database_info, and database_info should remain 304 // valid at least as long as the CookieTreeDatabaseNode is valid. 305 explicit CookieTreeDatabaseNode( 306 BrowsingDataDatabaseHelper::DatabaseInfo* database_info); 307 virtual ~CookieTreeDatabaseNode(); 308 309 virtual void DeleteStoredObjects(); 310 virtual DetailedInfo GetDetailedInfo() const; 311 312 private: 313 // database_info_ is not owned by the node, and is expected to remain 314 // valid as long as the CookieTreeDatabaseNode is valid. 315 BrowsingDataDatabaseHelper::DatabaseInfo* database_info_; 316 317 DISALLOW_COPY_AND_ASSIGN(CookieTreeDatabaseNode); 318 }; 319 320 class CookieTreeDatabasesNode : public CookieTreeNode { 321 public: 322 CookieTreeDatabasesNode(); 323 virtual ~CookieTreeDatabasesNode(); 324 325 virtual DetailedInfo GetDetailedInfo() const; 326 327 void AddDatabaseNode(CookieTreeDatabaseNode* child) { 328 AddChildSortedByTitle(child); 329 } 330 331 private: 332 DISALLOW_COPY_AND_ASSIGN(CookieTreeDatabasesNode); 333 }; 334 335 336 // CookieTreeLocalStorageNode ------------------------------------------------- 337 class CookieTreeLocalStorageNode : public CookieTreeNode { 338 public: 339 // Does not take ownership of local_storage_info, and local_storage_info 340 // should remain valid at least as long as the CookieTreeLocalStorageNode is 341 // valid. 342 explicit CookieTreeLocalStorageNode( 343 BrowsingDataLocalStorageHelper::LocalStorageInfo* local_storage_info); 344 virtual ~CookieTreeLocalStorageNode(); 345 346 // CookieTreeNode methods: 347 virtual void DeleteStoredObjects(); 348 virtual DetailedInfo GetDetailedInfo() const; 349 350 private: 351 // local_storage_info_ is not owned by the node, and is expected to remain 352 // valid as long as the CookieTreeLocalStorageNode is valid. 353 BrowsingDataLocalStorageHelper::LocalStorageInfo* local_storage_info_; 354 355 DISALLOW_COPY_AND_ASSIGN(CookieTreeLocalStorageNode); 356 }; 357 358 class CookieTreeLocalStoragesNode : public CookieTreeNode { 359 public: 360 CookieTreeLocalStoragesNode(); 361 virtual ~CookieTreeLocalStoragesNode(); 362 363 virtual DetailedInfo GetDetailedInfo() const; 364 365 void AddLocalStorageNode(CookieTreeLocalStorageNode* child) { 366 AddChildSortedByTitle(child); 367 } 368 369 private: 370 371 DISALLOW_COPY_AND_ASSIGN(CookieTreeLocalStoragesNode); 372 }; 373 374 375 // CookieTreeSessionStorageNode ----------------------------------------------- 376 class CookieTreeSessionStorageNode : public CookieTreeNode { 377 public: 378 // Does not take ownership of session_storage_info, and session_storage_info 379 // should remain valid at least as long as the CookieTreeSessionStorageNode 380 // is valid. 381 explicit CookieTreeSessionStorageNode( 382 BrowsingDataLocalStorageHelper::LocalStorageInfo* session_storage_info); 383 virtual ~CookieTreeSessionStorageNode(); 384 385 // CookieTreeNode methods: 386 virtual DetailedInfo GetDetailedInfo() const; 387 388 private: 389 // session_storage_info_ is not owned by the node, and is expected to remain 390 // valid as long as the CookieTreeSessionStorageNode is valid. 391 BrowsingDataLocalStorageHelper::LocalStorageInfo* session_storage_info_; 392 393 DISALLOW_COPY_AND_ASSIGN(CookieTreeSessionStorageNode); 394 }; 395 396 class CookieTreeSessionStoragesNode : public CookieTreeNode { 397 public: 398 CookieTreeSessionStoragesNode(); 399 virtual ~CookieTreeSessionStoragesNode(); 400 401 virtual DetailedInfo GetDetailedInfo() const; 402 403 void AddSessionStorageNode(CookieTreeSessionStorageNode* child) { 404 AddChildSortedByTitle(child); 405 } 406 407 private: 408 409 DISALLOW_COPY_AND_ASSIGN(CookieTreeSessionStoragesNode); 410 }; 411 412 // CookieTreeIndexedDBNode ----------------------------------------------- 413 class CookieTreeIndexedDBNode : public CookieTreeNode { 414 public: 415 // Does not take ownership of session_storage_info, and session_storage_info 416 // should remain valid at least as long as the CookieTreeSessionStorageNode 417 // is valid. 418 explicit CookieTreeIndexedDBNode( 419 BrowsingDataIndexedDBHelper::IndexedDBInfo* indexed_db_info); 420 virtual ~CookieTreeIndexedDBNode(); 421 422 // CookieTreeNode methods: 423 virtual void DeleteStoredObjects(); 424 virtual DetailedInfo GetDetailedInfo() const; 425 426 private: 427 // indexed_db_info_ is not owned by the node, and is expected to remain 428 // valid as long as the CookieTreeIndexedDBNode is valid. 429 BrowsingDataIndexedDBHelper::IndexedDBInfo* indexed_db_info_; 430 431 DISALLOW_COPY_AND_ASSIGN(CookieTreeIndexedDBNode); 432 }; 433 434 class CookieTreeIndexedDBsNode : public CookieTreeNode { 435 public: 436 CookieTreeIndexedDBsNode(); 437 virtual ~CookieTreeIndexedDBsNode(); 438 439 virtual DetailedInfo GetDetailedInfo() const; 440 441 void AddIndexedDBNode(CookieTreeIndexedDBNode* child) { 442 AddChildSortedByTitle(child); 443 } 444 445 private: 446 DISALLOW_COPY_AND_ASSIGN(CookieTreeIndexedDBsNode); 447 }; 448 449 450 // CookiesTreeModel ----------------------------------------------------------- 451 class CookiesTreeModel : public ui::TreeNodeModel<CookieTreeNode> { 452 public: 453 // Because non-cookie nodes are fetched in a background thread, they are not 454 // present at the time the Model is created. The Model then notifies its 455 // observers for every item added from databases, local storage, and 456 // appcache. We extend the Observer interface to add notifications before and 457 // after these batch inserts. 458 class Observer : public ui::TreeModelObserver { 459 public: 460 virtual void TreeModelBeginBatch(CookiesTreeModel* model) {} 461 virtual void TreeModelEndBatch(CookiesTreeModel* model) {} 462 }; 463 464 CookiesTreeModel( 465 net::CookieMonster* cookie_monster_, 466 BrowsingDataDatabaseHelper* database_helper, 467 BrowsingDataLocalStorageHelper* local_storage_helper, 468 BrowsingDataLocalStorageHelper* session_storage_helper, 469 BrowsingDataAppCacheHelper* appcache_helper, 470 BrowsingDataIndexedDBHelper* indexed_db_helper, 471 bool use_cookie_source); 472 virtual ~CookiesTreeModel(); 473 474 // ui::TreeModel methods: 475 // Returns the set of icons for the nodes in the tree. You only need override 476 // this if you don't want to use the default folder icons. 477 virtual void GetIcons(std::vector<SkBitmap>* icons); 478 479 // Returns the index of the icon to use for |node|. Return -1 to use the 480 // default icon. The index is relative to the list of icons returned from 481 // GetIcons. 482 virtual int GetIconIndex(ui::TreeModelNode* node); 483 484 // CookiesTreeModel methods: 485 void DeleteAllStoredObjects(); 486 void DeleteCookieNode(CookieTreeNode* cookie_node); 487 488 // Filter the origins to only display matched results. 489 void UpdateSearchResults(const std::wstring& filter); 490 491 // Manages CookiesTreeModel::Observers. This will also call 492 // TreeNodeModel::AddObserver so that it gets all the proper notifications. 493 // Note that the converse is not true: simply adding a TreeModelObserver will 494 // not get CookiesTreeModel::Observer notifications. 495 virtual void AddCookiesTreeObserver(Observer* observer); 496 virtual void RemoveCookiesTreeObserver(Observer* observer); 497 498 private: 499 enum CookieIconIndex { 500 ORIGIN = 0, 501 COOKIE = 1, 502 DATABASE = 2 503 }; 504 typedef net::CookieList CookieList; 505 typedef std::vector<BrowsingDataDatabaseHelper::DatabaseInfo> 506 DatabaseInfoList; 507 typedef std::vector<BrowsingDataLocalStorageHelper::LocalStorageInfo> 508 LocalStorageInfoList; 509 typedef std::vector<BrowsingDataLocalStorageHelper::LocalStorageInfo> 510 SessionStorageInfoList; 511 typedef std::vector<BrowsingDataIndexedDBHelper::IndexedDBInfo> 512 IndexedDBInfoList; 513 514 void LoadCookies(); 515 void LoadCookiesWithFilter(const std::wstring& filter); 516 517 void OnAppCacheModelInfoLoaded(); 518 void OnDatabaseModelInfoLoaded(const DatabaseInfoList& database_info); 519 void OnLocalStorageModelInfoLoaded( 520 const LocalStorageInfoList& local_storage_info); 521 void OnSessionStorageModelInfoLoaded( 522 const LocalStorageInfoList& local_storage_info); 523 void OnIndexedDBModelInfoLoaded( 524 const IndexedDBInfoList& indexed_db_info); 525 526 void PopulateAppCacheInfoWithFilter(const std::wstring& filter); 527 void PopulateDatabaseInfoWithFilter(const std::wstring& filter); 528 void PopulateLocalStorageInfoWithFilter(const std::wstring& filter); 529 void PopulateSessionStorageInfoWithFilter(const std::wstring& filter); 530 void PopulateIndexedDBInfoWithFilter(const std::wstring& filter); 531 532 void NotifyObserverBeginBatch(); 533 void NotifyObserverEndBatch(); 534 535 scoped_refptr<net::CookieMonster> cookie_monster_; 536 CookieList all_cookies_; 537 538 scoped_refptr<BrowsingDataAppCacheHelper> appcache_helper_; 539 scoped_refptr<BrowsingDataDatabaseHelper> database_helper_; 540 scoped_refptr<appcache::AppCacheInfoCollection> appcache_info_; 541 DatabaseInfoList database_info_list_; 542 543 scoped_refptr<BrowsingDataLocalStorageHelper> local_storage_helper_; 544 scoped_refptr<BrowsingDataLocalStorageHelper> session_storage_helper_; 545 scoped_refptr<BrowsingDataIndexedDBHelper> indexed_db_helper_; 546 LocalStorageInfoList local_storage_info_list_; 547 LocalStorageInfoList session_storage_info_list_; 548 IndexedDBInfoList indexed_db_info_list_; 549 550 // The CookiesTreeModel maintains a separate list of observers that are 551 // specifically of the type CookiesTreeModel::Observer. 552 ObserverList<Observer> cookies_observer_list_; 553 554 // If this is non-zero, then this model is batching updates (there's a lot of 555 // notifications coming down the pipe). This is an integer is used to balance 556 // calls to Begin/EndBatch() if they're called in a nested manner. 557 int batch_update_; 558 559 // If true, use the CanonicalCookie::Source attribute to group cookies. 560 // Otherwise, use the CanonicalCookie::Domain attribute. 561 bool use_cookie_source_; 562 563 friend class CookieTreeAppCacheNode; 564 friend class CookieTreeCookieNode; 565 friend class CookieTreeDatabaseNode; 566 friend class CookieTreeLocalStorageNode; 567 friend class CookieTreeIndexedDBNode; 568 569 DISALLOW_COPY_AND_ASSIGN(CookiesTreeModel); 570 }; 571 572 #endif // CHROME_BROWSER_COOKIES_TREE_MODEL_H_ 573