Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / download / download_crx_util.cc
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 // Download code which handles CRX files (extensions, themes, apps, ...).
6
7 #include "chrome/browser/download/download_crx_util.h"
8
9 #include "chrome/browser/chrome_notification_types.h"
10 #include "chrome/browser/extensions/crx_installer.h"
11 #include "chrome/browser/extensions/extension_install_prompt.h"
12 #include "chrome/browser/extensions/extension_service.h"
13 #include "chrome/browser/extensions/webstore_installer.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/ui/browser_finder.h"
16 #include "chrome/browser/ui/host_desktop.h"
17 #include "chrome/browser/ui/tabs/tab_strip_model.h"
18 #include "content/public/browser/download_item.h"
19 #include "content/public/browser/notification_service.h"
20 #include "extensions/browser/extension_system.h"
21 #include "extensions/common/user_script.h"
22
23 using content::BrowserThread;
24 using content::DownloadItem;
25 using extensions::WebstoreInstaller;
26
27 namespace download_crx_util {
28
29 namespace {
30
31 // Hold a mock ExtensionInstallPrompt object that will be used when the
32 // download system opens a CRX.
33 ExtensionInstallPrompt* mock_install_prompt_for_testing = NULL;
34
35 // Called to get an extension install UI object.  In tests, will return
36 // a mock if the test calls download_util::SetMockInstallPromptForTesting()
37 // to set one.
38 scoped_ptr<ExtensionInstallPrompt> CreateExtensionInstallPrompt(
39     Profile* profile,
40     const DownloadItem& download_item) {
41   // Use a mock if one is present.  Otherwise, create a real extensions
42   // install UI.
43   if (mock_install_prompt_for_testing) {
44     ExtensionInstallPrompt* result = mock_install_prompt_for_testing;
45     mock_install_prompt_for_testing = NULL;
46     return scoped_ptr<ExtensionInstallPrompt>(result);
47   } else {
48     content::WebContents* web_contents = download_item.GetWebContents();
49     if (!web_contents) {
50       chrome::HostDesktopType active_desktop = chrome::GetActiveDesktop();
51       Browser* browser = chrome::FindLastActiveWithProfile(profile,
52           active_desktop);
53       if (!browser)
54         browser = new Browser(Browser::CreateParams(Browser::TYPE_TABBED,
55                                                     profile, active_desktop));
56       web_contents = browser->tab_strip_model()->GetActiveWebContents();
57     }
58     return scoped_ptr<ExtensionInstallPrompt>(
59         new ExtensionInstallPrompt(web_contents));
60   }
61 }
62
63 }  // namespace
64
65 // Tests can call this method to inject a mock ExtensionInstallPrompt
66 // to be used to confirm permissions on a downloaded CRX.
67 void SetMockInstallPromptForTesting(
68     scoped_ptr<ExtensionInstallPrompt> mock_prompt) {
69   mock_install_prompt_for_testing = mock_prompt.release();
70 }
71
72 scoped_refptr<extensions::CrxInstaller> OpenChromeExtension(
73     Profile* profile,
74     const DownloadItem& download_item) {
75   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
76
77   ExtensionService* service = extensions::ExtensionSystem::Get(profile)->
78       extension_service();
79   CHECK(service);
80
81   scoped_refptr<extensions::CrxInstaller> installer(
82       extensions::CrxInstaller::Create(
83           service,
84           CreateExtensionInstallPrompt(profile, download_item),
85           WebstoreInstaller::GetAssociatedApproval(download_item)));
86
87   installer->set_error_on_unsupported_requirements(true);
88   installer->set_delete_source(true);
89   installer->set_install_cause(extension_misc::INSTALL_CAUSE_USER_DOWNLOAD);
90
91   if (OffStoreInstallAllowedByPrefs(profile, download_item)) {
92     installer->set_off_store_install_allow_reason(
93         extensions::CrxInstaller::OffStoreInstallAllowedBecausePref);
94   }
95
96   if (extensions::UserScript::IsURLUserScript(download_item.GetURL(),
97                                               download_item.GetMimeType())) {
98     installer->InstallUserScript(download_item.GetFullPath(),
99                                  download_item.GetURL());
100   } else {
101     bool is_gallery_download =
102         WebstoreInstaller::GetAssociatedApproval(download_item) != NULL;
103     installer->set_original_mime_type(download_item.GetOriginalMimeType());
104     installer->set_apps_require_extension_mime_type(true);
105     installer->set_download_url(download_item.GetURL());
106     installer->set_is_gallery_install(is_gallery_download);
107     if (is_gallery_download)
108       installer->set_original_download_url(download_item.GetOriginalUrl());
109     installer->set_allow_silent_install(is_gallery_download);
110     installer->InstallCrx(download_item.GetFullPath());
111   }
112
113   return installer;
114 }
115
116 bool IsExtensionDownload(const DownloadItem& download_item) {
117   if (download_item.GetTargetDisposition() ==
118       DownloadItem::TARGET_DISPOSITION_PROMPT)
119     return false;
120
121   if (download_item.GetMimeType() == extensions::Extension::kMimeType ||
122       extensions::UserScript::IsURLUserScript(download_item.GetURL(),
123                                               download_item.GetMimeType())) {
124     return true;
125   } else {
126     return false;
127   }
128 }
129
130 bool OffStoreInstallAllowedByPrefs(Profile* profile, const DownloadItem& item) {
131   ExtensionService* service = extensions::ExtensionSystem::Get(
132       profile)->extension_service();
133   if (!service)
134     return false;
135
136   extensions::ExtensionPrefs* prefs = service->extension_prefs();
137   CHECK(prefs);
138
139   extensions::URLPatternSet url_patterns = prefs->GetAllowedInstallSites();
140
141   if (!url_patterns.MatchesURL(item.GetURL()))
142     return false;
143
144   // The referrer URL must also be whitelisted, unless the URL has the file
145   // scheme (there's no referrer for those URLs).
146   // TODO(aa): RefererURL is cleared in some cases, for example when going
147   // between secure and non-secure URLs. It would be better if DownloadItem
148   // tracked the initiating page explicitly.
149   return url_patterns.MatchesURL(item.GetReferrerUrl()) ||
150          item.GetURL().SchemeIsFile();
151 }
152
153 }  // namespace download_crx_util