15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/external_install_ui.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
13ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h"
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/app/chrome_command_ids.h"
177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_install_prompt.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_install_ui.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_uninstall_dialog.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/browser_finder.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/global_error/global_error.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/global_error/global_error_service.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/global_error/global_error_service_factory.h"
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/host_desktop.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension.h"
30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/common/extensions/extension_constants.h"
31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/common/extensions/manifest_url_handler.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_details.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_observer.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_registrar.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/chromium_strings.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/theme_resources.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ui/gfx/image/image.h"
41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ui/gfx/image/image_skia_operations.h"
42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ui/gfx/size.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace {
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Whether the external extension can use the streamlined bubble install flow.
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool UseBubbleInstall(const Extension* extension, bool is_new_profile) {
50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return ManifestURL::UpdatesFromGallery(extension) && !is_new_profile;
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kMenuCommandId = IDC_EXTERNAL_EXTENSION_ALERT;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class ExternalInstallGlobalError;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(mpcomplete): Get rid of the refcounting on this class, or document
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// why it's necessary. Will do after refactoring to merge back with
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ExtensionDisabledDialogDelegate.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ExternalInstallDialogDelegate
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public ExtensionInstallPrompt::Delegate,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      public base::RefCountedThreadSafe<ExternalInstallDialogDelegate> {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExternalInstallDialogDelegate(Browser* browser,
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                ExtensionService* service,
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                const Extension* extension,
69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                bool use_global_error);
70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  Browser* browser() { return browser_; }
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class base::RefCountedThreadSafe<ExternalInstallDialogDelegate>;
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  friend class ExternalInstallGlobalError;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ExternalInstallDialogDelegate();
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ExtensionInstallPrompt::Delegate:
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void InstallUIProceed() OVERRIDE;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void InstallUIAbort(bool user_initiated) OVERRIDE;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The UI for showing the install dialog when enabling.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ExtensionInstallPrompt> install_ui_;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  Browser* browser_;
877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::WeakPtr<ExtensionService> service_weak_;
887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const std::string extension_id_;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Only shows a menu item, no bubble. Clicking the menu item shows
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// an external install dialog.
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class ExternalInstallMenuAlert : public GlobalError,
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 public content::NotificationObserver {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExternalInstallMenuAlert(ExtensionService* service,
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                           const Extension* extension);
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~ExternalInstallMenuAlert();
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Extension* extension() const { return extension_; }
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // GlobalError implementation.
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual Severity GetSeverity() OVERRIDE;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool HasMenuItem() OVERRIDE;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int MenuItemCommandID() OVERRIDE;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual string16 MenuItemLabel() OVERRIDE;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ExecuteMenuItem(Browser* browser) OVERRIDE;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool HasBubbleView() OVERRIDE;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual string16 GetBubbleViewTitle() OVERRIDE;
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual std::vector<string16> GetBubbleViewMessages() OVERRIDE;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual string16 GetBubbleViewAcceptButtonLabel() OVERRIDE;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual string16 GetBubbleViewCancelButtonLabel() OVERRIDE;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnBubbleViewDidClose(Browser* browser) OVERRIDE;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void BubbleViewAcceptButtonPressed(Browser* browser) OVERRIDE;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void BubbleViewCancelButtonPressed(Browser* browser) OVERRIDE;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // content::NotificationObserver implementation.
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Observe(int type,
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const content::NotificationSource& source,
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const content::NotificationDetails& details) OVERRIDE;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionService* service_;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Extension* extension_;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationRegistrar registrar_;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Shows a menu item and a global error bubble, replacing the install dialog.
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class ExternalInstallGlobalError : public ExternalInstallMenuAlert {
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExternalInstallGlobalError(ExtensionService* service,
132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                             const Extension* extension,
133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                             ExternalInstallDialogDelegate* delegate,
134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                             const ExtensionInstallPrompt::Prompt& prompt);
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~ExternalInstallGlobalError();
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void ExecuteMenuItem(Browser* browser) OVERRIDE;
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual bool HasBubbleView() OVERRIDE;
139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual gfx::Image GetBubbleViewIcon() OVERRIDE;
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual string16 GetBubbleViewTitle() OVERRIDE;
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual std::vector<string16> GetBubbleViewMessages() OVERRIDE;
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual string16 GetBubbleViewAcceptButtonLabel() OVERRIDE;
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual string16 GetBubbleViewCancelButtonLabel() OVERRIDE;
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void OnBubbleViewDidClose(Browser* browser) OVERRIDE;
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void BubbleViewAcceptButtonPressed(Browser* browser) OVERRIDE;
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void BubbleViewCancelButtonPressed(Browser* browser) OVERRIDE;
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Ref-counted, but needs to be disposed of if we are dismissed without
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // having been clicked (perhaps because the user enabled the extension
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // manually).
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExternalInstallDialogDelegate* delegate_;
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const ExtensionInstallPrompt::Prompt* prompt_;
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static void CreateExternalInstallGlobalError(
157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    base::WeakPtr<ExtensionService> service,
158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const std::string& extension_id,
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ExtensionInstallPrompt::ShowParams& show_params,
160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ExtensionInstallPrompt::Delegate* prompt_delegate,
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ExtensionInstallPrompt::Prompt& prompt) {
162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!service.get())
163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const Extension* extension = service->GetInstalledExtension(extension_id);
165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!extension)
166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  GlobalErrorService* error_service =
168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GlobalErrorServiceFactory::GetForProfile(service->profile());
169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (error_service->GetGlobalErrorByMenuItemCommandID(kMenuCommandId))
170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ExternalInstallDialogDelegate* delegate =
173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      static_cast<ExternalInstallDialogDelegate*>(prompt_delegate);
174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ExternalInstallGlobalError* error_bubble = new ExternalInstallGlobalError(
175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      service.get(), extension, delegate, prompt);
176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  error_service->AddGlobalError(error_bubble);
177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Show bubble immediately if possible.
178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (delegate->browser())
179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    error_bubble->ShowBubbleView(delegate->browser());
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static void ShowExternalInstallDialog(
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ExtensionService* service,
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Browser* browser,
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const Extension* extension) {
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // This object manages its own lifetime.
187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  new ExternalInstallDialogDelegate(browser, service, extension, false);
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// ExternalInstallDialogDelegate --------------------------------------------
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ExternalInstallDialogDelegate::ExternalInstallDialogDelegate(
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Browser* browser,
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ExtensionService* service,
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const Extension* extension,
196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    bool use_global_error)
1977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    : browser_(browser),
1987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      service_weak_(service->AsWeakPtr()),
1997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      extension_id_(extension->id()) {
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AddRef();  // Balanced in Proceed or Abort.
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  install_ui_.reset(
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ExtensionInstallUI::CreateInstallPromptWithBrowser(browser));
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const ExtensionInstallPrompt::ShowDialogCallback callback =
206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      use_global_error ?
207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::Bind(&CreateExternalInstallGlobalError,
2087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 service_weak_, extension_id_) :
209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ExtensionInstallPrompt::GetDefaultShowDialogCallback();
2107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  install_ui_->ConfirmExternalInstall(this, extension, callback);
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ExternalInstallDialogDelegate::~ExternalInstallDialogDelegate() {
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExternalInstallDialogDelegate::InstallUIProceed() {
2177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!service_weak_.get())
2187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
2197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const Extension* extension =
2207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      service_weak_->GetInstalledExtension(extension_id_);
2217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!extension)
2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
2237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  service_weak_->GrantPermissionsAndEnableExtension(extension);
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Release();
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExternalInstallDialogDelegate::InstallUIAbort(bool user_initiated) {
2287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!service_weak_.get())
2297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
2307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const Extension* extension =
2317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      service_weak_->GetInstalledExtension(extension_id_);
2327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!extension)
2337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
2347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  service_weak_->UninstallExtension(extension_id_, false, NULL);
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Release();
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// ExternalInstallMenuAlert -------------------------------------------------
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ExternalInstallMenuAlert::ExternalInstallMenuAlert(
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExtensionService* service,
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Extension* extension)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : service_(service),
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension_(extension) {
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 content::Source<Profile>(service->profile()));
247a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_REMOVED,
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 content::Source<Profile>(service->profile()));
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ExternalInstallMenuAlert::~ExternalInstallMenuAlert() {
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)GlobalError::Severity ExternalInstallMenuAlert::GetSeverity() {
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return SEVERITY_LOW;
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ExternalInstallMenuAlert::HasMenuItem() {
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int ExternalInstallMenuAlert::MenuItemCommandID() {
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return kMenuCommandId;
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)string16 ExternalInstallMenuAlert::MenuItemLabel() {
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int id = -1;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (extension_->is_app())
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    id = IDS_EXTENSION_EXTERNAL_INSTALL_ALERT_APP;
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (extension_->is_theme())
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    id = IDS_EXTENSION_EXTERNAL_INSTALL_ALERT_THEME;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    id = IDS_EXTENSION_EXTERNAL_INSTALL_ALERT_EXTENSION;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return l10n_util::GetStringFUTF16(id, UTF8ToUTF16(extension_->name()));
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExternalInstallMenuAlert::ExecuteMenuItem(Browser* browser) {
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ShowExternalInstallDialog(service_, browser, extension_);
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ExternalInstallMenuAlert::HasBubbleView() {
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)string16 ExternalInstallMenuAlert::GetBubbleViewTitle() {
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return string16();
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::vector<string16> ExternalInstallMenuAlert::GetBubbleViewMessages() {
289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return std::vector<string16>();
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)string16 ExternalInstallMenuAlert::GetBubbleViewAcceptButtonLabel() {
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return string16();
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)string16 ExternalInstallMenuAlert::GetBubbleViewCancelButtonLabel() {
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return string16();
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExternalInstallMenuAlert::OnBubbleViewDidClose(Browser* browser) {
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExternalInstallMenuAlert::BubbleViewAcceptButtonPressed(
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Browser* browser) {
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExternalInstallMenuAlert::BubbleViewCancelButtonPressed(
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Browser* browser) {
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExternalInstallMenuAlert::Observe(
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int type,
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::NotificationSource& source,
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::NotificationDetails& details) {
318a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // The error is invalidated if the extension has been loaded or removed.
319a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(type == chrome::NOTIFICATION_EXTENSION_LOADED ||
320a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)         type == chrome::NOTIFICATION_EXTENSION_REMOVED);
321a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  const Extension* extension = content::Details<const Extension>(details).ptr();
322a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (extension != extension_)
323a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return;
324a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  GlobalErrorService* error_service =
325a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      GlobalErrorServiceFactory::GetForProfile(service_->profile());
326a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  error_service->RemoveGlobalError(this);
327a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  service_->AcknowledgeExternalExtension(extension_->id());
328a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  delete this;
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// ExternalInstallGlobalError -----------------------------------------------
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ExternalInstallGlobalError::ExternalInstallGlobalError(
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ExtensionService* service,
335868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const Extension* extension,
336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ExternalInstallDialogDelegate* delegate,
337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const ExtensionInstallPrompt::Prompt& prompt)
338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    : ExternalInstallMenuAlert(service, extension),
339868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      delegate_(delegate),
340868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      prompt_(&prompt) {
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ExternalInstallGlobalError::~ExternalInstallGlobalError() {
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (delegate_)
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    delegate_->Release();
346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExternalInstallGlobalError::ExecuteMenuItem(Browser* browser) {
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ShowBubbleView(browser);
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ExternalInstallGlobalError::HasBubbleView() {
353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return true;
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)gfx::Image ExternalInstallGlobalError::GetBubbleViewIcon() {
357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (prompt_->icon().IsEmpty())
358868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return GlobalError::GetBubbleViewIcon();
359868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Scale icon to a reasonable size.
360868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return gfx::Image(gfx::ImageSkiaOperations::CreateResizedImage(
361868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      *prompt_->icon().ToImageSkia(),
362868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      skia::ImageOperations::RESIZE_BEST,
363868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      gfx::Size(extension_misc::EXTENSION_ICON_SMALL,
364868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                extension_misc::EXTENSION_ICON_SMALL)));
365868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)string16 ExternalInstallGlobalError::GetBubbleViewTitle() {
368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return prompt_->GetDialogTitle();
369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::vector<string16> ExternalInstallGlobalError::GetBubbleViewMessages() {
372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector<string16> messages;
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  messages.push_back(prompt_->GetHeading());
374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (prompt_->GetPermissionCount()) {
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    messages.push_back(prompt_->GetPermissionsHeading());
376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    for (size_t i = 0; i < prompt_->GetPermissionCount(); ++i) {
377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      messages.push_back(l10n_util::GetStringFUTF16(
378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          IDS_EXTENSION_PERMISSION_LINE,
379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          prompt_->GetPermission(i)));
380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // TODO(yoz): OAuth issue advice?
383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return messages;
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)string16 ExternalInstallGlobalError::GetBubbleViewAcceptButtonLabel() {
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return prompt_->GetAcceptButtonLabel();
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)string16 ExternalInstallGlobalError::GetBubbleViewCancelButtonLabel() {
391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return prompt_->GetAbortButtonLabel();
392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExternalInstallGlobalError::OnBubbleViewDidClose(Browser* browser) {
395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExternalInstallGlobalError::BubbleViewAcceptButtonPressed(
398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Browser* browser) {
39990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ExternalInstallDialogDelegate* delegate = delegate_;
400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  delegate_ = NULL;
40190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  delegate->InstallUIProceed();
402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExternalInstallGlobalError::BubbleViewCancelButtonPressed(
405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Browser* browser) {
40690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ExternalInstallDialogDelegate* delegate = delegate_;
407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  delegate_ = NULL;
40890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  delegate->InstallUIAbort(true);
409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Public interface ---------------------------------------------------------
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
413868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AddExternalInstallError(ExtensionService* service,
414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             const Extension* extension,
415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             bool is_new_profile) {
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GlobalErrorService* error_service =
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GlobalErrorServiceFactory::GetForProfile(service->profile());
418868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (error_service->GetGlobalErrorByMenuItemCommandID(kMenuCommandId))
419868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (UseBubbleInstall(extension, is_new_profile)) {
422868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    Browser* browser = NULL;
42390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if !defined(OS_ANDROID)
424868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    browser = chrome::FindTabbedBrowser(service->profile(),
425868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                        true,
426868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                        chrome::GetActiveDesktop());
42790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif
428868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    new ExternalInstallDialogDelegate(browser, service, extension, true);
429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    error_service->AddGlobalError(
431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        new ExternalInstallMenuAlert(service, extension));
432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RemoveExternalInstallError(ExtensionService* service) {
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GlobalErrorService* error_service =
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GlobalErrorServiceFactory::GetForProfile(service->profile());
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GlobalError* error = error_service->GetGlobalErrorByMenuItemCommandID(
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kMenuCommandId);
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (error) {
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error_service->RemoveGlobalError(error);
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete error;
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HasExternalInstallError(ExtensionService* service) {
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GlobalErrorService* error_service =
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GlobalErrorServiceFactory::GetForProfile(service->profile());
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GlobalError* error = error_service->GetGlobalErrorByMenuItemCommandID(
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kMenuCommandId);
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return !!error;
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool HasExternalInstallBubble(ExtensionService* service) {
455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GlobalErrorService* error_service =
456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      GlobalErrorServiceFactory::GetForProfile(service->profile());
457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GlobalError* error = error_service->GetGlobalErrorByMenuItemCommandID(
458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      kMenuCommandId);
459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return error && error->HasBubbleView();
460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
463