1 // Copyright 2014 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.
5 #include "chrome/browser/extensions/extension_reenabler.h"
7 #include "base/logging.h"
8 #include "chrome/browser/extensions/extension_service.h"
9 #include "chrome/browser/extensions/webstore_data_fetcher.h"
10 #include "chrome/browser/extensions/webstore_inline_installer.h"
11 #include "content/public/browser/browser_context.h"
12 #include "content/public/browser/web_contents.h"
13 #include "extensions/browser/extension_prefs.h"
14 #include "extensions/browser/extension_registry.h"
15 #include "extensions/browser/extension_system.h"
16 #include "extensions/common/extension.h"
18 namespace extensions
{
20 ExtensionReenabler::~ExtensionReenabler() {
26 scoped_ptr
<ExtensionReenabler
> ExtensionReenabler::PromptForReenable(
27 const scoped_refptr
<const Extension
>& extension
,
28 content::BrowserContext
* browser_context
,
29 content::WebContents
* web_contents
,
30 const GURL
& referrer_url
,
31 const Callback
& callback
) {
33 // We should only try to reenable an extension that is, in fact, disabled.
34 DCHECK(ExtensionRegistry::Get(browser_context
)->disabled_extensions().
35 Contains(extension
->id()));
36 // Currently, this should only be used for extensions that are disabled due
37 // to a permissions increase.
39 ExtensionPrefs::Get(browser_context
)->GetDisableReasons(extension
->id());
40 DCHECK_NE(0, disable_reasons
& Extension::DISABLE_PERMISSIONS_INCREASE
);
41 #endif // DCHECK_IS_ON()
43 return make_scoped_ptr(new ExtensionReenabler(
48 make_scoped_ptr(new ExtensionInstallPrompt(web_contents
))));
52 scoped_ptr
<ExtensionReenabler
>
53 ExtensionReenabler::PromptForReenableWithPromptForTest(
54 const scoped_refptr
<const Extension
>& extension
,
55 content::BrowserContext
* browser_context
,
56 const Callback
& callback
,
57 scoped_ptr
<ExtensionInstallPrompt
> install_prompt
) {
58 return make_scoped_ptr(new ExtensionReenabler(extension
,
62 install_prompt
.Pass()));
65 ExtensionReenabler::ExtensionReenabler(
66 const scoped_refptr
<const Extension
>& extension
,
67 content::BrowserContext
* browser_context
,
68 const GURL
& referrer_url
,
69 const Callback
& callback
,
70 scoped_ptr
<ExtensionInstallPrompt
> install_prompt
)
71 : extension_(extension
),
72 browser_context_(browser_context
),
73 referrer_url_(referrer_url
),
75 install_prompt_(install_prompt
.Pass()),
77 registry_observer_(this) {
78 DCHECK(extension_
.get());
79 registry_observer_
.Add(ExtensionRegistry::Get(browser_context_
));
81 // If we have a non-empty referrer, then we have to validate that it's a valid
82 // url for the extension.
83 if (!referrer_url_
.is_empty()) {
84 webstore_data_fetcher_
.reset(new WebstoreDataFetcher(
86 browser_context_
->GetRequestContext(),
89 webstore_data_fetcher_
->Start();
91 install_prompt_
->ConfirmReEnable(this, extension
.get());
95 void ExtensionReenabler::InstallUIProceed() {
96 // Stop observing - we don't want to see our own enablement.
97 registry_observer_
.RemoveAll();
99 ExtensionService
* extension_service
=
100 ExtensionSystem::Get(browser_context_
)->extension_service();
101 if (extension_service
->browser_terminating()) {
104 extension_service
->GrantPermissionsAndEnableExtension(extension_
.get());
105 // The re-enable could have failed if the extension is disallowed by
107 bool enabled
= ExtensionRegistry::Get(browser_context_
)->
108 enabled_extensions().GetByID(extension_
->id()) != nullptr;
109 Finish(enabled
? REENABLE_SUCCESS
: NOT_ALLOWED
);
113 void ExtensionReenabler::InstallUIAbort(bool user_initiated
) {
114 Finish(user_initiated
? USER_CANCELED
: ABORTED
);
117 void ExtensionReenabler::OnExtensionLoaded(
118 content::BrowserContext
* browser_context
,
119 const Extension
* extension
) {
120 // If the user chose to manually re-enable the extension then, for all
121 // intents and purposes, this was a success.
122 if (extension
== extension_
.get())
123 Finish(REENABLE_SUCCESS
);
126 void ExtensionReenabler::OnExtensionUninstalled(
127 content::BrowserContext
* browser_context
,
128 const Extension
* extension
,
129 UninstallReason reason
) {
130 if (extension
== extension_
.get())
131 Finish(USER_CANCELED
);
134 void ExtensionReenabler::OnWebstoreRequestFailure() {
138 void ExtensionReenabler::OnWebstoreResponseParseSuccess(
139 scoped_ptr
<base::DictionaryValue
> webstore_data
) {
140 DCHECK(!referrer_url_
.is_empty());
142 if (!WebstoreInlineInstaller::IsRequestorPermitted(*webstore_data
,
147 install_prompt_
->ConfirmReEnable(this, extension_
.get());
151 void ExtensionReenabler::OnWebstoreResponseParseFailure(
152 const std::string
& error
) {
156 void ExtensionReenabler::Finish(ReenableResult result
) {
159 registry_observer_
.RemoveAll();
160 callback_
.Run(result
);
163 } // namespace extensions