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