OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/external_install_ui.h" | 5 #include "chrome/browser/extensions/external_install_ui.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
11 #include "base/memory/ref_counted.h" | 11 #include "base/memory/ref_counted.h" |
12 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
13 #include "base/message_loop/message_loop.h" | 13 #include "base/message_loop/message_loop.h" |
14 #include "base/metrics/histogram.h" | 14 #include "base/metrics/histogram.h" |
| 15 #include "base/scoped_observer.h" |
15 #include "base/strings/utf_string_conversions.h" | 16 #include "base/strings/utf_string_conversions.h" |
16 #include "chrome/app/chrome_command_ids.h" | 17 #include "chrome/app/chrome_command_ids.h" |
17 #include "chrome/browser/chrome_notification_types.h" | 18 #include "chrome/browser/chrome_notification_types.h" |
18 #include "chrome/browser/extensions/extension_install_prompt.h" | 19 #include "chrome/browser/extensions/extension_install_prompt.h" |
19 #include "chrome/browser/extensions/extension_install_ui.h" | 20 #include "chrome/browser/extensions/extension_install_ui.h" |
20 #include "chrome/browser/extensions/extension_service.h" | 21 #include "chrome/browser/extensions/extension_service.h" |
21 #include "chrome/browser/extensions/extension_uninstall_dialog.h" | 22 #include "chrome/browser/extensions/extension_uninstall_dialog.h" |
22 #include "chrome/browser/extensions/webstore_data_fetcher.h" | 23 #include "chrome/browser/extensions/webstore_data_fetcher.h" |
23 #include "chrome/browser/extensions/webstore_data_fetcher_delegate.h" | 24 #include "chrome/browser/extensions/webstore_data_fetcher_delegate.h" |
24 #include "chrome/browser/profiles/profile.h" | 25 #include "chrome/browser/profiles/profile.h" |
25 #include "chrome/browser/ui/browser.h" | 26 #include "chrome/browser/ui/browser.h" |
26 #include "chrome/browser/ui/browser_finder.h" | 27 #include "chrome/browser/ui/browser_finder.h" |
27 #include "chrome/browser/ui/global_error/global_error.h" | 28 #include "chrome/browser/ui/global_error/global_error.h" |
28 #include "chrome/browser/ui/global_error/global_error_service.h" | 29 #include "chrome/browser/ui/global_error/global_error_service.h" |
29 #include "chrome/browser/ui/global_error/global_error_service_factory.h" | 30 #include "chrome/browser/ui/global_error/global_error_service_factory.h" |
30 #include "chrome/browser/ui/host_desktop.h" | |
31 #include "chrome/common/extensions/extension_constants.h" | |
32 #include "chrome/common/extensions/manifest_url_handler.h" | 31 #include "chrome/common/extensions/manifest_url_handler.h" |
33 #include "content/public/browser/notification_details.h" | 32 #include "content/public/browser/notification_details.h" |
34 #include "content/public/browser/notification_observer.h" | 33 #include "content/public/browser/notification_observer.h" |
35 #include "content/public/browser/notification_registrar.h" | 34 #include "content/public/browser/notification_registrar.h" |
36 #include "content/public/browser/notification_source.h" | 35 #include "content/public/browser/notification_source.h" |
37 #include "extensions/common/extension.h" | 36 #include "extensions/browser/extension_registry.h" |
38 #include "grit/chromium_strings.h" | 37 #include "extensions/browser/extension_registry_observer.h" |
39 #include "grit/generated_resources.h" | 38 #include "grit/generated_resources.h" |
40 #include "grit/theme_resources.h" | |
41 #include "ui/base/l10n/l10n_util.h" | 39 #include "ui/base/l10n/l10n_util.h" |
42 #include "ui/gfx/image/image.h" | 40 #include "ui/gfx/image/image.h" |
43 #include "ui/gfx/image/image_skia_operations.h" | 41 #include "ui/gfx/image/image_skia_operations.h" |
44 #include "ui/gfx/size.h" | |
45 | 42 |
46 namespace extensions { | 43 namespace extensions { |
47 | 44 |
48 namespace { | 45 namespace { |
49 | 46 |
50 // Whether the external extension can use the streamlined bubble install flow. | 47 // Whether the external extension can use the streamlined bubble install flow. |
51 bool UseBubbleInstall(const Extension* extension, bool is_new_profile) { | 48 bool UseBubbleInstall(const Extension* extension, bool is_new_profile) { |
52 return ManifestURL::UpdatesFromGallery(extension) && !is_new_profile; | 49 return ManifestURL::UpdatesFromGallery(extension) && !is_new_profile; |
53 } | 50 } |
54 | 51 |
55 } // namespace | 52 } // namespace |
56 | 53 |
57 static const int kMenuCommandId = IDC_EXTERNAL_EXTENSION_ALERT; | 54 static const int kMenuCommandId = IDC_EXTERNAL_EXTENSION_ALERT; |
58 | 55 |
59 class ExternalInstallGlobalError; | 56 class ExternalInstallGlobalError; |
60 | 57 |
| 58 namespace extensions { |
| 59 class ExtensionRegistry; |
| 60 } |
| 61 |
61 // This class is refcounted to stay alive while we try and pull webstore data. | 62 // This class is refcounted to stay alive while we try and pull webstore data. |
62 class ExternalInstallDialogDelegate | 63 class ExternalInstallDialogDelegate |
63 : public ExtensionInstallPrompt::Delegate, | 64 : public ExtensionInstallPrompt::Delegate, |
64 public WebstoreDataFetcherDelegate, | 65 public WebstoreDataFetcherDelegate, |
65 public content::NotificationObserver, | 66 public content::NotificationObserver, |
66 public base::RefCountedThreadSafe<ExternalInstallDialogDelegate> { | 67 public base::RefCountedThreadSafe<ExternalInstallDialogDelegate> { |
67 public: | 68 public: |
68 ExternalInstallDialogDelegate(Browser* browser, | 69 ExternalInstallDialogDelegate(Browser* browser, |
69 ExtensionService* service, | 70 ExtensionService* service, |
70 const Extension* extension, | 71 const Extension* extension, |
(...skipping 11 matching lines...) Expand all Loading... |
82 virtual void InstallUIProceed() OVERRIDE; | 83 virtual void InstallUIProceed() OVERRIDE; |
83 virtual void InstallUIAbort(bool user_initiated) OVERRIDE; | 84 virtual void InstallUIAbort(bool user_initiated) OVERRIDE; |
84 | 85 |
85 // WebstoreDataFetcherDelegate: | 86 // WebstoreDataFetcherDelegate: |
86 virtual void OnWebstoreRequestFailure() OVERRIDE; | 87 virtual void OnWebstoreRequestFailure() OVERRIDE; |
87 virtual void OnWebstoreResponseParseSuccess( | 88 virtual void OnWebstoreResponseParseSuccess( |
88 scoped_ptr<base::DictionaryValue> webstore_data) OVERRIDE; | 89 scoped_ptr<base::DictionaryValue> webstore_data) OVERRIDE; |
89 virtual void OnWebstoreResponseParseFailure( | 90 virtual void OnWebstoreResponseParseFailure( |
90 const std::string& error) OVERRIDE; | 91 const std::string& error) OVERRIDE; |
91 | 92 |
92 // NotificationObserver: | 93 // content::NotificationObserver: |
93 virtual void Observe(int type, | 94 virtual void Observe(int type, |
94 const content::NotificationSource& source, | 95 const content::NotificationSource& source, |
95 const content::NotificationDetails& details) OVERRIDE; | 96 const content::NotificationDetails& details) OVERRIDE; |
96 | 97 |
97 // Show the install dialog to the user. | 98 // Show the install dialog to the user. |
98 void ShowInstallUI(); | 99 void ShowInstallUI(); |
99 | 100 |
100 // The UI for showing the install dialog when enabling. | 101 // The UI for showing the install dialog when enabling. |
101 scoped_ptr<ExtensionInstallPrompt> install_ui_; | 102 scoped_ptr<ExtensionInstallPrompt> install_ui_; |
102 scoped_ptr<ExtensionInstallPrompt::Prompt> prompt_; | 103 scoped_ptr<ExtensionInstallPrompt::Prompt> prompt_; |
103 | 104 |
104 Browser* browser_; | 105 Browser* browser_; |
105 base::WeakPtr<ExtensionService> service_weak_; | 106 base::WeakPtr<ExtensionService> service_weak_; |
106 scoped_ptr<WebstoreDataFetcher> webstore_data_fetcher_; | 107 scoped_ptr<WebstoreDataFetcher> webstore_data_fetcher_; |
107 content::NotificationRegistrar registrar_; | 108 content::NotificationRegistrar registrar_; |
108 std::string extension_id_; | 109 std::string extension_id_; |
109 bool use_global_error_; | 110 bool use_global_error_; |
110 | 111 |
111 DISALLOW_COPY_AND_ASSIGN(ExternalInstallDialogDelegate); | 112 DISALLOW_COPY_AND_ASSIGN(ExternalInstallDialogDelegate); |
112 }; | 113 }; |
113 | 114 |
114 // Only shows a menu item, no bubble. Clicking the menu item shows | 115 // Only shows a menu item, no bubble. Clicking the menu item shows |
115 // an external install dialog. | 116 // an external install dialog. |
116 class ExternalInstallMenuAlert : public GlobalErrorWithStandardBubble, | 117 class ExternalInstallMenuAlert : public GlobalErrorWithStandardBubble, |
117 public content::NotificationObserver { | 118 public content::NotificationObserver, |
| 119 public ExtensionRegistryObserver { |
118 public: | 120 public: |
119 ExternalInstallMenuAlert(ExtensionService* service, | 121 ExternalInstallMenuAlert(ExtensionService* service, |
120 const Extension* extension); | 122 const Extension* extension); |
121 virtual ~ExternalInstallMenuAlert(); | 123 virtual ~ExternalInstallMenuAlert(); |
122 | 124 |
123 // GlobalError implementation. | 125 // GlobalError implementation. |
124 virtual Severity GetSeverity() OVERRIDE; | 126 virtual Severity GetSeverity() OVERRIDE; |
125 virtual bool HasMenuItem() OVERRIDE; | 127 virtual bool HasMenuItem() OVERRIDE; |
126 virtual int MenuItemCommandID() OVERRIDE; | 128 virtual int MenuItemCommandID() OVERRIDE; |
127 virtual base::string16 MenuItemLabel() OVERRIDE; | 129 virtual base::string16 MenuItemLabel() OVERRIDE; |
128 virtual void ExecuteMenuItem(Browser* browser) OVERRIDE; | 130 virtual void ExecuteMenuItem(Browser* browser) OVERRIDE; |
129 virtual bool HasBubbleView() OVERRIDE; | 131 virtual bool HasBubbleView() OVERRIDE; |
130 virtual base::string16 GetBubbleViewTitle() OVERRIDE; | 132 virtual base::string16 GetBubbleViewTitle() OVERRIDE; |
131 virtual std::vector<base::string16> GetBubbleViewMessages() OVERRIDE; | 133 virtual std::vector<base::string16> GetBubbleViewMessages() OVERRIDE; |
132 virtual base::string16 GetBubbleViewAcceptButtonLabel() OVERRIDE; | 134 virtual base::string16 GetBubbleViewAcceptButtonLabel() OVERRIDE; |
133 virtual base::string16 GetBubbleViewCancelButtonLabel() OVERRIDE; | 135 virtual base::string16 GetBubbleViewCancelButtonLabel() OVERRIDE; |
134 virtual void OnBubbleViewDidClose(Browser* browser) OVERRIDE; | 136 virtual void OnBubbleViewDidClose(Browser* browser) OVERRIDE; |
135 virtual void BubbleViewAcceptButtonPressed(Browser* browser) OVERRIDE; | 137 virtual void BubbleViewAcceptButtonPressed(Browser* browser) OVERRIDE; |
136 virtual void BubbleViewCancelButtonPressed(Browser* browser) OVERRIDE; | 138 virtual void BubbleViewCancelButtonPressed(Browser* browser) OVERRIDE; |
137 | 139 |
| 140 protected: |
| 141 ExtensionService* service_; |
| 142 const Extension* extension_; |
| 143 |
| 144 private: |
| 145 // Delete this instance after cleaning jobs. |
| 146 void Clean(); |
| 147 |
138 // content::NotificationObserver implementation. | 148 // content::NotificationObserver implementation. |
139 virtual void Observe(int type, | 149 virtual void Observe(int type, |
140 const content::NotificationSource& source, | 150 const content::NotificationSource& source, |
141 const content::NotificationDetails& details) OVERRIDE; | 151 const content::NotificationDetails& details) OVERRIDE; |
142 | 152 |
143 protected: | 153 // ExtensionRegistryObserver implementation. |
144 ExtensionService* service_; | 154 virtual void OnExtensionLoaded(content::BrowserContext* browser_context, |
145 const Extension* extension_; | 155 const Extension* extension) OVERRIDE; |
| 156 |
146 content::NotificationRegistrar registrar_; | 157 content::NotificationRegistrar registrar_; |
147 | 158 |
148 private: | 159 // Listen to extension load notifications. |
| 160 ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> |
| 161 extension_registry_observer_; |
| 162 |
149 DISALLOW_COPY_AND_ASSIGN(ExternalInstallMenuAlert); | 163 DISALLOW_COPY_AND_ASSIGN(ExternalInstallMenuAlert); |
150 }; | 164 }; |
151 | 165 |
152 // Shows a menu item and a global error bubble, replacing the install dialog. | 166 // Shows a menu item and a global error bubble, replacing the install dialog. |
153 class ExternalInstallGlobalError : public ExternalInstallMenuAlert { | 167 class ExternalInstallGlobalError : public ExternalInstallMenuAlert { |
154 public: | 168 public: |
155 ExternalInstallGlobalError(ExtensionService* service, | 169 ExternalInstallGlobalError(ExtensionService* service, |
156 const Extension* extension, | 170 const Extension* extension, |
157 ExternalInstallDialogDelegate* delegate, | 171 ExternalInstallDialogDelegate* delegate, |
158 const ExtensionInstallPrompt::Prompt& prompt); | 172 const ExtensionInstallPrompt::Prompt& prompt); |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 const Extension* extension = NULL; | 342 const Extension* extension = NULL; |
329 if (service_weak_.get() && | 343 if (service_weak_.get() && |
330 (extension = service_weak_->GetInstalledExtension(extension_id_))) { | 344 (extension = service_weak_->GetInstalledExtension(extension_id_))) { |
331 service_weak_->UninstallExtension(extension_id_, false, NULL); | 345 service_weak_->UninstallExtension(extension_id_, false, NULL); |
332 } | 346 } |
333 Release(); | 347 Release(); |
334 } | 348 } |
335 | 349 |
336 // ExternalInstallMenuAlert ------------------------------------------------- | 350 // ExternalInstallMenuAlert ------------------------------------------------- |
337 | 351 |
338 ExternalInstallMenuAlert::ExternalInstallMenuAlert( | 352 ExternalInstallMenuAlert::ExternalInstallMenuAlert(ExtensionService* service, |
339 ExtensionService* service, | 353 const Extension* extension) |
340 const Extension* extension) | |
341 : service_(service), | 354 : service_(service), |
342 extension_(extension) { | 355 extension_(extension), |
343 registrar_.Add(this, | 356 extension_registry_observer_(this) { |
344 chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED, | 357 extension_registry_observer_.Add(ExtensionRegistry::Get(service->profile())); |
345 content::Source<Profile>(service->profile())); | |
346 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_REMOVED, | 358 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_REMOVED, |
347 content::Source<Profile>(service->profile())); | 359 content::Source<Profile>(service->profile())); |
348 } | 360 } |
349 | 361 |
350 ExternalInstallMenuAlert::~ExternalInstallMenuAlert() { | 362 ExternalInstallMenuAlert::~ExternalInstallMenuAlert() { |
351 } | 363 } |
352 | 364 |
353 GlobalError::Severity ExternalInstallMenuAlert::GetSeverity() { | 365 GlobalError::Severity ExternalInstallMenuAlert::GetSeverity() { |
354 return SEVERITY_LOW; | 366 return SEVERITY_LOW; |
355 } | 367 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
403 void ExternalInstallMenuAlert::BubbleViewAcceptButtonPressed( | 415 void ExternalInstallMenuAlert::BubbleViewAcceptButtonPressed( |
404 Browser* browser) { | 416 Browser* browser) { |
405 NOTREACHED(); | 417 NOTREACHED(); |
406 } | 418 } |
407 | 419 |
408 void ExternalInstallMenuAlert::BubbleViewCancelButtonPressed( | 420 void ExternalInstallMenuAlert::BubbleViewCancelButtonPressed( |
409 Browser* browser) { | 421 Browser* browser) { |
410 NOTREACHED(); | 422 NOTREACHED(); |
411 } | 423 } |
412 | 424 |
| 425 void ExternalInstallMenuAlert::OnExtensionLoaded( |
| 426 content::BrowserContext* browser_context, |
| 427 const Extension* extension) { |
| 428 if (extension == extension_) |
| 429 Clean(); |
| 430 } |
| 431 |
413 void ExternalInstallMenuAlert::Observe( | 432 void ExternalInstallMenuAlert::Observe( |
414 int type, | 433 int type, |
415 const content::NotificationSource& source, | 434 const content::NotificationSource& source, |
416 const content::NotificationDetails& details) { | 435 const content::NotificationDetails& details) { |
417 // The error is invalidated if the extension has been loaded or removed. | 436 // The error is invalidated if the extension has been loaded or removed. |
418 DCHECK(type == chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED || | 437 DCHECK_EQ(type, chrome::NOTIFICATION_EXTENSION_REMOVED); |
419 type == chrome::NOTIFICATION_EXTENSION_REMOVED); | |
420 const Extension* extension = content::Details<const Extension>(details).ptr(); | 438 const Extension* extension = content::Details<const Extension>(details).ptr(); |
421 if (extension != extension_) | 439 if (extension == extension_) |
422 return; | 440 Clean(); |
| 441 } |
| 442 |
| 443 void ExternalInstallMenuAlert::Clean() { |
423 GlobalErrorService* error_service = | 444 GlobalErrorService* error_service = |
424 GlobalErrorServiceFactory::GetForProfile(service_->profile()); | 445 GlobalErrorServiceFactory::GetForProfile(service_->profile()); |
425 error_service->RemoveGlobalError(this); | 446 error_service->RemoveGlobalError(this); |
426 service_->AcknowledgeExternalExtension(extension_->id()); | 447 service_->AcknowledgeExternalExtension(extension_->id()); |
427 delete this; | 448 delete this; |
428 } | 449 } |
429 | 450 |
430 // ExternalInstallGlobalError ----------------------------------------------- | 451 // ExternalInstallGlobalError ----------------------------------------------- |
431 | 452 |
432 ExternalInstallGlobalError::ExternalInstallGlobalError( | 453 ExternalInstallGlobalError::ExternalInstallGlobalError( |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
553 | 574 |
554 bool HasExternalInstallBubble(ExtensionService* service) { | 575 bool HasExternalInstallBubble(ExtensionService* service) { |
555 GlobalErrorService* error_service = | 576 GlobalErrorService* error_service = |
556 GlobalErrorServiceFactory::GetForProfile(service->profile()); | 577 GlobalErrorServiceFactory::GetForProfile(service->profile()); |
557 GlobalError* error = error_service->GetGlobalErrorByMenuItemCommandID( | 578 GlobalError* error = error_service->GetGlobalErrorByMenuItemCommandID( |
558 kMenuCommandId); | 579 kMenuCommandId); |
559 return error && error->HasBubbleView(); | 580 return error && error->HasBubbleView(); |
560 } | 581 } |
561 | 582 |
562 } // namespace extensions | 583 } // namespace extensions |
OLD | NEW |