1 // Copyright 2018 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 "content/public/browser/download_item_utils.h"
6
7 #include "components/download/public/common/download_item.h"
8 #include "content/public/browser/web_contents.h"
9 #include "content/public/browser/web_contents_observer.h"
10
11 namespace content {
12
13 namespace {
14
15 // This is a UserData::Data that will be attached to a DownloadItem as a
16 // side-channel for passing WebContents and BrowserContext.
17 class DownloadItemData : public base::SupportsUserData::Data,
18 public WebContentsObserver {
19 public:
20 DownloadItemData(BrowserContext* browser_context, WebContents* web_contents);
21 ~DownloadItemData() override = default;
22
23 static void Attach(download::DownloadItem* download_item,
24 BrowserContext* browser_context,
25 WebContents* web_contents);
26 static DownloadItemData* Get(const download::DownloadItem* download_item);
27 static void Detach(download::DownloadItem* download_item);
28
browser_context() const29 BrowserContext* browser_context() const { return browser_context_; }
30
31 private:
32 // WebContentsObserver methods.
33 void WebContentsDestroyed() override;
34
35 static const char kKey[];
36 BrowserContext* browser_context_;
37 };
38
39 // static
40 const char DownloadItemData::kKey[] = "DownloadItemUtils DownloadItemData";
41
DownloadItemData(BrowserContext * browser_context,WebContents * web_contents)42 DownloadItemData::DownloadItemData(BrowserContext* browser_context,
43 WebContents* web_contents)
44 : WebContentsObserver(web_contents),
45 browser_context_(browser_context) {}
46
47 // static
Attach(download::DownloadItem * download_item,BrowserContext * browser_context,WebContents * web_contents)48 void DownloadItemData::Attach(download::DownloadItem* download_item,
49 BrowserContext* browser_context,
50 WebContents* web_contents) {
51 auto data = std::make_unique<DownloadItemData>(browser_context, web_contents);
52 download_item->SetUserData(&kKey, std::move(data));
53 }
54
55 // static
Get(const download::DownloadItem * download_item)56 DownloadItemData* DownloadItemData::Get(
57 const download::DownloadItem* download_item) {
58 return static_cast<DownloadItemData*>(download_item->GetUserData(&kKey));
59 }
60
61 // static
Detach(download::DownloadItem * download_item)62 void DownloadItemData::Detach(download::DownloadItem* download_item) {
63 download_item->RemoveUserData(&kKey);
64 }
65
WebContentsDestroyed()66 void DownloadItemData::WebContentsDestroyed() {
67 Observe(nullptr);
68 }
69
70 } // namespace
71
72 // static
GetBrowserContext(const download::DownloadItem * download_item)73 BrowserContext* DownloadItemUtils::GetBrowserContext(
74 const download::DownloadItem* download_item) {
75 DownloadItemData* data = DownloadItemData::Get(download_item);
76 if (!data)
77 return nullptr;
78 return data->browser_context();
79 }
80
81 // static
GetWebContents(const download::DownloadItem * download_item)82 WebContents* DownloadItemUtils::GetWebContents(
83 const download::DownloadItem* download_item) {
84 DownloadItemData* data = DownloadItemData::Get(download_item);
85 if (!data)
86 return nullptr;
87 return data->web_contents();
88 }
89
90 // static
AttachInfo(download::DownloadItem * download_item,BrowserContext * browser_context,WebContents * web_contents)91 void DownloadItemUtils::AttachInfo(download::DownloadItem* download_item,
92 BrowserContext* browser_context,
93 WebContents* web_contents) {
94 DownloadItemData::Attach(download_item, browser_context, web_contents);
95 }
96
97 } // namespace content
98