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. 4 5 #ifndef CHROME_BROWSER_BROWSING_DATA_COOKIES_TREE_MODEL_H_ 6 #define CHROME_BROWSER_BROWSING_DATA_COOKIES_TREE_MODEL_H_ 7 8 #include <list> 9 #include <memory> 10 #include <string> 11 #include <vector> 12 13 #include "base/macros.h" 14 #include "base/observer_list.h" 15 #include "base/strings/string16.h" 16 #include "build/build_config.h" 17 #include "chrome/browser/browsing_data/local_data_container.h" 18 #include "components/content_settings/core/common/content_settings.h" 19 #include "extensions/buildflags/buildflags.h" 20 #include "ui/base/models/tree_node_model.h" 21 22 #if !defined(OS_ANDROID) 23 #include "chrome/browser/browsing_data/access_context_audit_database.h" 24 #endif // !defined(OS_ANDROID) 25 26 class AccessContextAuditService; 27 class CookiesTreeModel; 28 class CookieTreeAppCacheNode; 29 class CookieTreeAppCachesNode; 30 class CookieTreeCacheStorageNode; 31 class CookieTreeCacheStoragesNode; 32 class CookieTreeCookieNode; 33 class CookieTreeCookiesNode; 34 class CookieTreeDatabaseNode; 35 class CookieTreeDatabasesNode; 36 class CookieTreeFileSystemNode; 37 class CookieTreeFileSystemsNode; 38 class CookieTreeHostNode; 39 class CookieTreeIndexedDBNode; 40 class CookieTreeIndexedDBsNode; 41 class CookieTreeLocalStorageNode; 42 class CookieTreeLocalStoragesNode; 43 class CookieTreeMediaLicenseNode; 44 class CookieTreeMediaLicensesNode; 45 class CookieTreeQuotaNode; 46 class CookieTreeServiceWorkerNode; 47 class CookieTreeServiceWorkersNode; 48 class CookieTreeSharedWorkerNode; 49 class CookieTreeSharedWorkersNode; 50 class CookieTreeSessionStorageNode; 51 class CookieTreeSessionStoragesNode; 52 class ExtensionSpecialStoragePolicy; 53 54 namespace content_settings { 55 class CookieSettings; 56 } 57 58 namespace extensions { 59 class ExtensionSet; 60 } 61 62 namespace net { 63 class CanonicalCookie; 64 } 65 66 // CookieTreeNode ------------------------------------------------------------- 67 // The base node type in the Cookies, Databases, and Local Storage options 68 // view, from which all other types are derived. Specialized from TreeNode in 69 // that it has a notion of deleting objects stored in the profile, and being 70 // able to have its children do the same. 71 class CookieTreeNode : public ui::TreeNode<CookieTreeNode> { 72 public: 73 // Used to pull out information for the InfoView (the details display below 74 // the tree control.) 75 struct DetailedInfo { 76 // NodeType corresponds to the various CookieTreeNode types. 77 enum NodeType { 78 TYPE_NONE, 79 TYPE_ROOT, // This is used for CookieTreeRootNode nodes. 80 TYPE_HOST, // This is used for CookieTreeHostNode nodes. 81 TYPE_COOKIES, // This is used for CookieTreeCookiesNode nodes. 82 TYPE_COOKIE, // This is used for CookieTreeCookieNode nodes. 83 TYPE_DATABASES, // This is used for CookieTreeDatabasesNode. 84 TYPE_DATABASE, // This is used for CookieTreeDatabaseNode. 85 TYPE_LOCAL_STORAGES, // This is used for CookieTreeLocalStoragesNode. 86 TYPE_LOCAL_STORAGE, // This is used for CookieTreeLocalStorageNode. 87 TYPE_SESSION_STORAGES, // This is used for CookieTreeSessionStoragesNode. 88 TYPE_SESSION_STORAGE, // This is used for CookieTreeSessionStorageNode. 89 TYPE_APPCACHES, // This is used for CookieTreeAppCachesNode. 90 TYPE_APPCACHE, // This is used for CookieTreeAppCacheNode. 91 TYPE_INDEXED_DBS, // This is used for CookieTreeIndexedDBsNode. 92 TYPE_INDEXED_DB, // This is used for CookieTreeIndexedDBNode. 93 TYPE_FILE_SYSTEMS, // This is used for CookieTreeFileSystemsNode. 94 TYPE_FILE_SYSTEM, // This is used for CookieTreeFileSystemNode. 95 TYPE_QUOTA, // This is used for CookieTreeQuotaNode. 96 TYPE_SERVICE_WORKERS, // This is used for CookieTreeServiceWorkersNode. 97 TYPE_SERVICE_WORKER, // This is used for CookieTreeServiceWorkerNode. 98 TYPE_SHARED_WORKERS, // This is used for CookieTreeSharedWorkersNode. 99 TYPE_SHARED_WORKER, // This is used for CookieTreeSharedWorkerNode. 100 TYPE_CACHE_STORAGES, // This is used for CookieTreeCacheStoragesNode. 101 TYPE_CACHE_STORAGE, // This is used for CookieTreeCacheStorageNode. 102 TYPE_MEDIA_LICENSES, // This is used for CookieTreeMediaLicensesNode. 103 TYPE_MEDIA_LICENSE, // This is used for CookieTreeMediaLicenseNode. 104 }; 105 106 DetailedInfo(); 107 DetailedInfo(const DetailedInfo& other); 108 ~DetailedInfo(); 109 110 DetailedInfo& Init(NodeType type); 111 DetailedInfo& InitHost(const GURL& origin); 112 DetailedInfo& InitCookie(const net::CanonicalCookie* cookie); 113 DetailedInfo& InitDatabase(const content::StorageUsageInfo* usage_info); 114 DetailedInfo& InitLocalStorage( 115 const content::StorageUsageInfo* local_storage_info); 116 DetailedInfo& InitSessionStorage( 117 const content::StorageUsageInfo* session_storage_info); 118 DetailedInfo& InitAppCache(const content::StorageUsageInfo* usage_info); 119 DetailedInfo& InitIndexedDB(const content::StorageUsageInfo* usage_info); 120 DetailedInfo& InitFileSystem( 121 const browsing_data::FileSystemHelper::FileSystemInfo* 122 file_system_info); 123 DetailedInfo& InitQuota( 124 const BrowsingDataQuotaHelper::QuotaInfo* quota_info); 125 DetailedInfo& InitServiceWorker( 126 const content::StorageUsageInfo* usage_info); 127 DetailedInfo& InitSharedWorker( 128 const browsing_data::SharedWorkerHelper::SharedWorkerInfo* 129 shared_worker_info); 130 DetailedInfo& InitCacheStorage(const content::StorageUsageInfo* usage_info); 131 DetailedInfo& InitMediaLicense( 132 const BrowsingDataMediaLicenseHelper::MediaLicenseInfo* 133 media_license_info); 134 135 NodeType node_type; 136 url::Origin origin; 137 const net::CanonicalCookie* cookie = nullptr; 138 // Used for AppCache, Database (WebSQL), IndexedDB, Service Worker, and 139 // Cache Storage node types. 140 const content::StorageUsageInfo* usage_info = nullptr; 141 const browsing_data::FileSystemHelper::FileSystemInfo* file_system_info = 142 nullptr; 143 const BrowsingDataQuotaHelper::QuotaInfo* quota_info = nullptr; 144 const browsing_data::SharedWorkerHelper::SharedWorkerInfo* 145 shared_worker_info = nullptr; 146 const BrowsingDataMediaLicenseHelper::MediaLicenseInfo* media_license_info = 147 nullptr; 148 }; 149 CookieTreeNode()150 CookieTreeNode() {} CookieTreeNode(const base::string16 & title)151 explicit CookieTreeNode(const base::string16& title) 152 : ui::TreeNode<CookieTreeNode>(title) {} ~CookieTreeNode()153 ~CookieTreeNode() override {} 154 155 // Recursively traverse the child nodes of this node and collect the storage 156 // size data. 157 virtual int64_t InclusiveSize() const; 158 159 // Recursively traverse the child nodes and calculate the number of nodes of 160 // type CookieTreeCookieNode. 161 virtual int NumberOfCookies() const; 162 163 // Delete backend storage for this node, and any children nodes. (E.g. delete 164 // the cookie from CookieMonster, clear the database, and so forth.) 165 virtual void DeleteStoredObjects(); 166 167 // Gets a pointer back to the associated model for the tree we are in. 168 virtual CookiesTreeModel* GetModel() const; 169 170 // Returns a struct with detailed information used to populate the details 171 // part of the view. 172 virtual DetailedInfo GetDetailedInfo() const = 0; 173 174 protected: 175 void AddChildSortedByTitle(std::unique_ptr<CookieTreeNode> new_child); 176 177 #if !defined(OS_ANDROID) 178 // TODO (crbug.com/1113602): Remove this when all storage deletions from 179 // the browser process use the StoragePartition directly. 180 void ReportDeletionToAuditService( 181 const url::Origin& origin, 182 AccessContextAuditDatabase::StorageAPIType type); 183 #endif // !defined(OS_ANDROID) 184 185 private: 186 DISALLOW_COPY_AND_ASSIGN(CookieTreeNode); 187 }; 188 189 // CookieTreeRootNode --------------------------------------------------------- 190 // The node at the root of the CookieTree that gets inserted into the view. 191 class CookieTreeRootNode : public CookieTreeNode { 192 public: 193 explicit CookieTreeRootNode(CookiesTreeModel* model); 194 ~CookieTreeRootNode() override; 195 196 CookieTreeHostNode* GetOrCreateHostNode(const GURL& url); 197 198 // CookieTreeNode methods: 199 CookiesTreeModel* GetModel() const override; 200 DetailedInfo GetDetailedInfo() const override; 201 202 private: 203 CookiesTreeModel* model_; 204 205 DISALLOW_COPY_AND_ASSIGN(CookieTreeRootNode); 206 }; 207 208 // CookieTreeHostNode ------------------------------------------------------- 209 class CookieTreeHostNode : public CookieTreeNode { 210 public: 211 // Returns the host node's title to use for a given URL. 212 static base::string16 TitleForUrl(const GURL& url); 213 214 explicit CookieTreeHostNode(const GURL& url); 215 ~CookieTreeHostNode() override; 216 217 // CookieTreeNode methods: 218 DetailedInfo GetDetailedInfo() const override; 219 int64_t InclusiveSize() const override; 220 221 // CookieTreeHostNode methods: 222 CookieTreeCookiesNode* GetOrCreateCookiesNode(); 223 CookieTreeDatabasesNode* GetOrCreateDatabasesNode(); 224 CookieTreeLocalStoragesNode* GetOrCreateLocalStoragesNode(); 225 CookieTreeSessionStoragesNode* GetOrCreateSessionStoragesNode(); 226 CookieTreeAppCachesNode* GetOrCreateAppCachesNode(); 227 CookieTreeIndexedDBsNode* GetOrCreateIndexedDBsNode(); 228 CookieTreeFileSystemsNode* GetOrCreateFileSystemsNode(); 229 CookieTreeServiceWorkersNode* GetOrCreateServiceWorkersNode(); 230 CookieTreeSharedWorkersNode* GetOrCreateSharedWorkersNode(); 231 CookieTreeCacheStoragesNode* GetOrCreateCacheStoragesNode(); 232 CookieTreeQuotaNode* UpdateOrCreateQuotaNode( 233 std::list<BrowsingDataQuotaHelper::QuotaInfo>::iterator quota_info); 234 CookieTreeMediaLicensesNode* GetOrCreateMediaLicensesNode(); 235 canonicalized_host()236 std::string canonicalized_host() const { return canonicalized_host_; } 237 238 // Creates an content exception for this origin of type 239 // ContentSettingsType::COOKIES. 240 void CreateContentException(content_settings::CookieSettings* cookie_settings, 241 ContentSetting setting) const; 242 243 // True if a content exception can be created for this origin. 244 bool CanCreateContentException() const; 245 246 std::string GetHost() const; 247 248 void UpdateHostUrl(const GURL& url); 249 250 private: 251 // Pointers to the cookies, databases, local and session storage and appcache 252 // nodes. When we build up the tree we need to quickly get a reference to 253 // the COOKIES node to add children. Checking each child and interrogating 254 // them to see if they are a COOKIES, APPCACHES, DATABASES etc node seems 255 // less preferable than storing an extra pointer per origin. 256 CookieTreeCookiesNode* cookies_child_ = nullptr; 257 CookieTreeDatabasesNode* databases_child_ = nullptr; 258 CookieTreeLocalStoragesNode* local_storages_child_ = nullptr; 259 CookieTreeSessionStoragesNode* session_storages_child_ = nullptr; 260 CookieTreeAppCachesNode* appcaches_child_ = nullptr; 261 CookieTreeIndexedDBsNode* indexed_dbs_child_ = nullptr; 262 CookieTreeFileSystemsNode* file_systems_child_ = nullptr; 263 CookieTreeQuotaNode* quota_child_ = nullptr; 264 CookieTreeServiceWorkersNode* service_workers_child_ = nullptr; 265 CookieTreeSharedWorkersNode* shared_workers_child_ = nullptr; 266 CookieTreeCacheStoragesNode* cache_storages_child_ = nullptr; 267 CookieTreeMediaLicensesNode* media_licenses_child_ = nullptr; 268 269 // The URL for which this node was initially created. 270 GURL url_; 271 272 std::string canonicalized_host_; 273 274 DISALLOW_COPY_AND_ASSIGN(CookieTreeHostNode); 275 }; 276 277 // CookiesTreeModel ----------------------------------------------------------- 278 class CookiesTreeModel : public ui::TreeNodeModel<CookieTreeNode> { 279 public: 280 CookiesTreeModel(std::unique_ptr<LocalDataContainer> data_container, 281 ExtensionSpecialStoragePolicy* special_storage_policy); 282 // As above, but also provides the tree model with a pointer to the Access 283 // Context Audit service. This allows the tree model to report deletion events 284 // to the service. This must be used whenever the service exists to ensure 285 // audit record consistency. 286 // TODO (crbug.com/1113602): Remove this constructor when all deletions are 287 // performed directly against the StoragePartition and the tree model doesn't 288 // require knowledge of the audit service. 289 CookiesTreeModel(std::unique_ptr<LocalDataContainer> data_container, 290 ExtensionSpecialStoragePolicy* special_storage_policy, 291 AccessContextAuditService* access_context_audit_service); 292 ~CookiesTreeModel() override; 293 294 // Given a CanonicalCookie, return the ID of the message which should be 295 // displayed in various ports' "Send for:" UI. 296 static int GetSendForMessageID(const net::CanonicalCookie& cookie); 297 298 // Because non-cookie nodes are fetched in a background thread, they are not 299 // present at the time the Model is created. The Model then notifies its 300 // observers for every item added from databases, local storage, and 301 // appcache. We extend the Observer interface to add notifications before and 302 // after these batch inserts. 303 class Observer : public ui::TreeModelObserver { 304 public: TreeModelBeginBatch(CookiesTreeModel * model)305 virtual void TreeModelBeginBatch(CookiesTreeModel* model) {} TreeModelEndBatch(CookiesTreeModel * model)306 virtual void TreeModelEndBatch(CookiesTreeModel* model) {} 307 }; 308 309 // This class defines the scope for batch updates. It can be created as a 310 // local variable and the destructor will terminate the batch update, if one 311 // has been started. 312 class ScopedBatchUpdateNotifier { 313 public: 314 ScopedBatchUpdateNotifier(CookiesTreeModel* model, 315 CookieTreeNode* node); 316 ~ScopedBatchUpdateNotifier(); 317 318 void StartBatchUpdate(); 319 320 private: 321 CookiesTreeModel* model_; 322 CookieTreeNode* node_; 323 bool batch_in_progress_ = false; 324 }; 325 326 // ui::TreeModel methods: 327 // Returns the set of icons for the nodes in the tree. You only need override 328 // this if you don't want to use the default folder icons. 329 void GetIcons(std::vector<gfx::ImageSkia>* icons) override; 330 331 // Returns the index of the icon to use for |node|. Return -1 to use the 332 // default icon. The index is relative to the list of icons returned from 333 // GetIcons. 334 int GetIconIndex(ui::TreeModelNode* node) override; 335 336 // CookiesTreeModel methods: 337 void DeleteAllStoredObjects(); 338 339 // Deletes a specific node in the tree, identified by |cookie_node|, and its 340 // subtree. 341 void DeleteCookieNode(CookieTreeNode* cookie_node); 342 343 // Filter the origins to only display matched results. 344 void UpdateSearchResults(const base::string16& filter); 345 346 #if BUILDFLAG(ENABLE_EXTENSIONS) 347 // Returns the set of extensions which protect the data item represented by 348 // this node from deletion. 349 // Returns nullptr if the node doesn't represent a protected data item or the 350 // special storage policy is nullptr. 351 const extensions::ExtensionSet* ExtensionsProtectingNode( 352 const CookieTreeNode& cookie_node); 353 #endif 354 355 // Manages CookiesTreeModel::Observers. This will also call 356 // TreeNodeModel::AddObserver so that it gets all the proper notifications. 357 // Note that the converse is not true: simply adding a TreeModelObserver will 358 // not get CookiesTreeModel::Observer notifications. 359 virtual void AddCookiesTreeObserver(Observer* observer); 360 virtual void RemoveCookiesTreeObserver(Observer* observer); 361 362 // Methods that update the model based on the data retrieved by the browsing 363 // data helpers. 364 void PopulateAppCacheInfo(LocalDataContainer* container); 365 void PopulateCookieInfo(LocalDataContainer* container); 366 void PopulateDatabaseInfo(LocalDataContainer* container); 367 void PopulateLocalStorageInfo(LocalDataContainer* container); 368 void PopulateSessionStorageInfo(LocalDataContainer* container); 369 void PopulateIndexedDBInfo(LocalDataContainer* container); 370 void PopulateFileSystemInfo(LocalDataContainer* container); 371 void PopulateQuotaInfo(LocalDataContainer* container); 372 void PopulateServiceWorkerUsageInfo(LocalDataContainer* container); 373 void PopulateSharedWorkerInfo(LocalDataContainer* container); 374 void PopulateCacheStorageUsageInfo(LocalDataContainer* container); 375 void PopulateMediaLicenseInfo(LocalDataContainer* container); 376 377 // Returns the Access Context Audit service provided to the cookies tree model 378 // as part of the constructor, or nullptr if no service was provided. access_context_audit_service()379 AccessContextAuditService* access_context_audit_service() { 380 return access_context_audit_service_; 381 } 382 data_container()383 LocalDataContainer* data_container() { 384 return data_container_.get(); 385 } 386 387 // Set the number of |batches_expected| this class should expect to receive. 388 // If |reset| is true, then this is a new set of batches, but if false, then 389 // this is a revised number (batches originally counted should no longer be 390 // expected). 391 void SetBatchExpectation(int batches_expected, bool reset); 392 393 // Create CookiesTreeModel by profile info. 394 static std::unique_ptr<CookiesTreeModel> CreateForProfile(Profile* profile); 395 396 static browsing_data::CookieHelper::IsDeletionDisabledCallback 397 GetCookieDeletionDisabledCallback(Profile* profile); 398 399 private: 400 enum CookieIconIndex { COOKIE = 0, DATABASE = 1 }; 401 402 // Record that one batch has been delivered. 403 void RecordBatchSeen(); 404 405 // Record that one batch has begun processing. If this is the first batch then 406 // observers will be notified that batch processing has started. 407 void NotifyObserverBeginBatch(); 408 409 // Record that one batch has finished processing. If this is the last batch 410 // then observers will be notified that batch processing has ended. 411 void NotifyObserverEndBatch(); 412 413 // Notifies observers if expected batch count has been delievered and all 414 // batches have finished processing. 415 void MaybeNotifyBatchesEnded(); 416 417 void PopulateAppCacheInfoWithFilter(LocalDataContainer* container, 418 ScopedBatchUpdateNotifier* notifier, 419 const base::string16& filter); 420 void PopulateCookieInfoWithFilter(LocalDataContainer* container, 421 ScopedBatchUpdateNotifier* notifier, 422 const base::string16& filter); 423 void PopulateDatabaseInfoWithFilter(LocalDataContainer* container, 424 ScopedBatchUpdateNotifier* notifier, 425 const base::string16& filter); 426 void PopulateLocalStorageInfoWithFilter(LocalDataContainer* container, 427 ScopedBatchUpdateNotifier* notifier, 428 const base::string16& filter); 429 void PopulateSessionStorageInfoWithFilter(LocalDataContainer* container, 430 ScopedBatchUpdateNotifier* notifier, 431 const base::string16& filter); 432 void PopulateIndexedDBInfoWithFilter(LocalDataContainer* container, 433 ScopedBatchUpdateNotifier* notifier, 434 const base::string16& filter); 435 void PopulateFileSystemInfoWithFilter(LocalDataContainer* container, 436 ScopedBatchUpdateNotifier* notifier, 437 const base::string16& filter); 438 void PopulateQuotaInfoWithFilter(LocalDataContainer* container, 439 ScopedBatchUpdateNotifier* notifier, 440 const base::string16& filter); 441 void PopulateServiceWorkerUsageInfoWithFilter( 442 LocalDataContainer* container, 443 ScopedBatchUpdateNotifier* notifier, 444 const base::string16& filter); 445 void PopulateSharedWorkerInfoWithFilter(LocalDataContainer* container, 446 ScopedBatchUpdateNotifier* notifier, 447 const base::string16& filter); 448 void PopulateCacheStorageUsageInfoWithFilter( 449 LocalDataContainer* container, 450 ScopedBatchUpdateNotifier* notifier, 451 const base::string16& filter); 452 void PopulateMediaLicenseInfoWithFilter(LocalDataContainer* container, 453 ScopedBatchUpdateNotifier* notifier, 454 const base::string16& filter); 455 456 #if BUILDFLAG(ENABLE_EXTENSIONS) 457 // The extension special storage policy; see ExtensionsProtectingNode() above. 458 scoped_refptr<ExtensionSpecialStoragePolicy> special_storage_policy_; 459 #endif 460 461 // Map of app ids to LocalDataContainer objects to use when retrieving 462 // locally stored data. 463 std::unique_ptr<LocalDataContainer> data_container_; 464 465 // The CookiesTreeModel maintains a separate list of observers that are 466 // specifically of the type CookiesTreeModel::Observer. 467 base::ObserverList<Observer>::Unchecked cookies_observer_list_; 468 469 AccessContextAuditService* access_context_audit_service_ = nullptr; 470 471 // Keeps track of how many batches the consumer of this class says it is going 472 // to send. 473 int batches_expected_ = 0; 474 475 // Keeps track of how many batches we've seen. 476 int batches_seen_ = 0; 477 478 // Counts how many batches have started already. If this is non-zero and lower 479 // than batches_ended_, then this model is still batching updates. 480 int batches_started_ = 0; 481 482 // Counts how many batches have finished. 483 int batches_ended_ = 0; 484 }; 485 486 #endif // CHROME_BROWSER_BROWSING_DATA_COOKIES_TREE_MODEL_H_ 487