external_install_ui.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
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"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/message_loop.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/utf_string_conversions.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/app/chrome_command_ids.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_install_prompt.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_install_ui.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_uninstall_dialog.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/global_error/global_error.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/global_error/global_error_service.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/global_error/global_error_service_factory.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_notification_types.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_details.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_observer.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_registrar.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/chromium_strings.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/theme_resources.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace {
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Whether the external extension can use the streamlined bubble install flow.
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool UseBubbleInstall(const Extension* extension, bool is_new_profile) {
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return extension->UpdatesFromGallery() && !is_new_profile;
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kMenuCommandId = IDC_EXTERNAL_EXTENSION_ALERT;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class ExternalInstallGlobalError;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(mpcomplete): Get rid of the refcounting on this class, or document
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// why it's necessary. Will do after refactoring to merge back with
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ExtensionDisabledDialogDelegate.
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ExternalInstallDialogDelegate
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public ExtensionInstallPrompt::Delegate,
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      public base::RefCountedThreadSafe<ExternalInstallDialogDelegate> {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExternalInstallDialogDelegate(Browser* browser,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                ExtensionService* service,
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                const Extension* extension,
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                ExternalInstallGlobalError* global_error);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class base::RefCountedThreadSafe<ExternalInstallDialogDelegate>;
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  friend class ExternalInstallGlobalError;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ExternalInstallDialogDelegate();
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ExtensionInstallPrompt::Delegate:
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void InstallUIProceed() OVERRIDE;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void InstallUIAbort(bool user_initiated) OVERRIDE;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The UI for showing the install dialog when enabling.
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ExtensionInstallPrompt> install_ui_;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionService* service_;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Extension* extension_;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Only shows a menu item, no bubble. Clicking the menu item shows
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// an external install dialog.
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class ExternalInstallMenuAlert : public GlobalError,
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 public content::NotificationObserver {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExternalInstallMenuAlert(ExtensionService* service,
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                           const Extension* extension);
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~ExternalInstallMenuAlert();
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Extension* extension() const { return extension_; }
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // GlobalError implementation.
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual Severity GetSeverity() OVERRIDE;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool HasMenuItem() OVERRIDE;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int MenuItemCommandID() OVERRIDE;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual string16 MenuItemLabel() OVERRIDE;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ExecuteMenuItem(Browser* browser) OVERRIDE;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool HasBubbleView() OVERRIDE;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual string16 GetBubbleViewTitle() OVERRIDE;
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual std::vector<string16> GetBubbleViewMessages() OVERRIDE;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual string16 GetBubbleViewAcceptButtonLabel() OVERRIDE;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual string16 GetBubbleViewCancelButtonLabel() OVERRIDE;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnBubbleViewDidClose(Browser* browser) OVERRIDE;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void BubbleViewAcceptButtonPressed(Browser* browser) OVERRIDE;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void BubbleViewCancelButtonPressed(Browser* browser) OVERRIDE;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // content::NotificationObserver implementation.
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Observe(int type,
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const content::NotificationSource& source,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const content::NotificationDetails& details) OVERRIDE;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionService* service_;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Extension* extension_;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationRegistrar registrar_;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Shows a menu item and a global error bubble, replacing the install dialog.
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class ExternalInstallGlobalError : public ExternalInstallMenuAlert {
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExternalInstallGlobalError(ExtensionService* service,
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             const Extension* extension);
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~ExternalInstallGlobalError();
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void set_prompt(const ExtensionInstallPrompt::Prompt& prompt) {
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    prompt_ = &prompt;
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void ExecuteMenuItem(Browser* browser) OVERRIDE;
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual bool HasBubbleView() OVERRIDE;
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual string16 GetBubbleViewTitle() OVERRIDE;
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual std::vector<string16> GetBubbleViewMessages() OVERRIDE;
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual string16 GetBubbleViewAcceptButtonLabel() OVERRIDE;
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual string16 GetBubbleViewCancelButtonLabel() OVERRIDE;
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void OnBubbleViewDidClose(Browser* browser) OVERRIDE;
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void BubbleViewAcceptButtonPressed(Browser* browser) OVERRIDE;
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void BubbleViewCancelButtonPressed(Browser* browser) OVERRIDE;
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Ref-counted, but needs to be disposed of if we are dismissed without
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // having been clicked (perhaps because the user enabled the extension
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // manually).
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExternalInstallDialogDelegate* delegate_;
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const ExtensionInstallPrompt::Prompt* prompt_;
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static void SetExternalInstallBubble(
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ExternalInstallGlobalError* global_error,
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ExtensionInstallPrompt::ShowParams& show_params,
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ExtensionInstallPrompt::Delegate* delegate,
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ExtensionInstallPrompt::Prompt& prompt) {
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  global_error->set_prompt(prompt);
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static void ShowExternalInstallDialog(
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ExtensionService* service,
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Browser* browser,
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const Extension* extension) {
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // This object manages its own lifetime.
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  new ExternalInstallDialogDelegate(browser, service, extension, NULL);
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// ExternalInstallDialogDelegate --------------------------------------------
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ExternalInstallDialogDelegate::ExternalInstallDialogDelegate(
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Browser* browser,
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ExtensionService* service,
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const Extension* extension,
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ExternalInstallGlobalError* global_error)
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : service_(service), extension_(extension) {
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AddRef();  // Balanced in Proceed or Abort.
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  install_ui_.reset(
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ExtensionInstallUI::CreateInstallPromptWithBrowser(browser));
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const ExtensionInstallPrompt::ShowDialogCallback callback =
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      global_error ?
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&SetExternalInstallBubble, global_error) :
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ExtensionInstallPrompt::GetDefaultShowDialogCallback();
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  install_ui_->ConfirmExternalInstall(this, extension_, callback);
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ExternalInstallDialogDelegate::~ExternalInstallDialogDelegate() {
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExternalInstallDialogDelegate::InstallUIProceed() {
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  service_->GrantPermissionsAndEnableExtension(extension_);
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Release();
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExternalInstallDialogDelegate::InstallUIAbort(bool user_initiated) {
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  service_->UninstallExtension(extension_->id(), false, NULL);
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Release();
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// ExternalInstallMenuAlert -------------------------------------------------
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ExternalInstallMenuAlert::ExternalInstallMenuAlert(
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExtensionService* service,
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Extension* extension)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : service_(service),
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension_(extension) {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 content::Source<Profile>(service->profile()));
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 content::Source<Profile>(service->profile()));
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ExternalInstallMenuAlert::~ExternalInstallMenuAlert() {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)GlobalError::Severity ExternalInstallMenuAlert::GetSeverity() {
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return SEVERITY_LOW;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ExternalInstallMenuAlert::HasMenuItem() {
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int ExternalInstallMenuAlert::MenuItemCommandID() {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return kMenuCommandId;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)string16 ExternalInstallMenuAlert::MenuItemLabel() {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int id = -1;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (extension_->is_app())
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    id = IDS_EXTENSION_EXTERNAL_INSTALL_ALERT_APP;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (extension_->is_theme())
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    id = IDS_EXTENSION_EXTERNAL_INSTALL_ALERT_THEME;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    id = IDS_EXTENSION_EXTERNAL_INSTALL_ALERT_EXTENSION;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return l10n_util::GetStringFUTF16(id, UTF8ToUTF16(extension_->name()));
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExternalInstallMenuAlert::ExecuteMenuItem(Browser* browser) {
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ShowExternalInstallDialog(service_, browser, extension_);
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ExternalInstallMenuAlert::HasBubbleView() {
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)string16 ExternalInstallMenuAlert::GetBubbleViewTitle() {
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return string16();
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::vector<string16> ExternalInstallMenuAlert::GetBubbleViewMessages() {
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return std::vector<string16>();
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)string16 ExternalInstallMenuAlert::GetBubbleViewAcceptButtonLabel() {
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return string16();
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)string16 ExternalInstallMenuAlert::GetBubbleViewCancelButtonLabel() {
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return string16();
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExternalInstallMenuAlert::OnBubbleViewDidClose(Browser* browser) {
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExternalInstallMenuAlert::BubbleViewAcceptButtonPressed(
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Browser* browser) {
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExternalInstallMenuAlert::BubbleViewCancelButtonPressed(
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Browser* browser) {
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExternalInstallMenuAlert::Observe(
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int type,
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::NotificationSource& source,
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::NotificationDetails& details) {
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Extension* extension = NULL;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The error is invalidated if the extension has been reloaded or unloaded.
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (type == chrome::NOTIFICATION_EXTENSION_LOADED) {
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension = content::Details<const Extension>(details).ptr();
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK_EQ(chrome::NOTIFICATION_EXTENSION_UNLOADED, type);
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extensions::UnloadedExtensionInfo* info =
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::Details<extensions::UnloadedExtensionInfo>(details).ptr();
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension = info->extension;
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (extension == extension_) {
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GlobalErrorService* error_service =
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GlobalErrorServiceFactory::GetForProfile(service_->profile());
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error_service->RemoveGlobalError(this);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service_->AcknowledgeExternalExtension(extension_->id());
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete this;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// ExternalInstallGlobalError -----------------------------------------------
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ExternalInstallGlobalError::ExternalInstallGlobalError(
298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ExtensionService* service,
299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const Extension* extension)
300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : ExternalInstallMenuAlert(service, extension) {
301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  delegate_ = new ExternalInstallDialogDelegate(
302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      NULL, service_, extension_, this);
303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ExternalInstallGlobalError::~ExternalInstallGlobalError() {
306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (delegate_)
307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    delegate_->Release();
308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExternalInstallGlobalError::ExecuteMenuItem(Browser* browser) {
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ShowBubbleView(browser);
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ExternalInstallGlobalError::HasBubbleView() {
315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return true;
316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)string16 ExternalInstallGlobalError::GetBubbleViewTitle() {
319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return prompt_->GetDialogTitle();
320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::vector<string16> ExternalInstallGlobalError::GetBubbleViewMessages() {
323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector<string16> messages;
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  messages.push_back(prompt_->GetHeading());
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (prompt_->GetPermissionCount()) {
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    messages.push_back(prompt_->GetPermissionsHeading());
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    for (size_t i = 0; i < prompt_->GetPermissionCount(); ++i) {
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      messages.push_back(l10n_util::GetStringFUTF16(
329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          IDS_EXTENSION_PERMISSION_LINE,
330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          prompt_->GetPermission(i)));
331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // TODO(yoz): OAuth issue advice?
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return messages;
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)string16 ExternalInstallGlobalError::GetBubbleViewAcceptButtonLabel() {
338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return prompt_->GetAcceptButtonLabel();
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)string16 ExternalInstallGlobalError::GetBubbleViewCancelButtonLabel() {
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return prompt_->GetAbortButtonLabel();
343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExternalInstallGlobalError::OnBubbleViewDidClose(Browser* browser) {
346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExternalInstallGlobalError::BubbleViewAcceptButtonPressed(
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Browser* browser) {
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  delegate_->InstallUIProceed();
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  delegate_ = NULL;
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExternalInstallGlobalError::BubbleViewCancelButtonPressed(
355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Browser* browser) {
356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  delegate_->InstallUIAbort(true);
357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  delegate_ = NULL;
358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Public interface ---------------------------------------------------------
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AddExternalInstallError(ExtensionService* service,
363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             const Extension* extension,
364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             bool is_new_profile) {
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GlobalErrorService* error_service =
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GlobalErrorServiceFactory::GetForProfile(service->profile());
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GlobalError* error = error_service->GetGlobalErrorByMenuItemCommandID(
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kMenuCommandId);
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (error)
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (UseBubbleInstall(extension, is_new_profile)) {
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    error_service->AddGlobalError(
374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        new ExternalInstallGlobalError(service, extension));
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    error_service->AddGlobalError(
377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        new ExternalInstallMenuAlert(service, extension));
378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RemoveExternalInstallError(ExtensionService* service) {
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GlobalErrorService* error_service =
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GlobalErrorServiceFactory::GetForProfile(service->profile());
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GlobalError* error = error_service->GetGlobalErrorByMenuItemCommandID(
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kMenuCommandId);
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (error) {
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error_service->RemoveGlobalError(error);
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete error;
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HasExternalInstallError(ExtensionService* service) {
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GlobalErrorService* error_service =
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GlobalErrorServiceFactory::GetForProfile(service->profile());
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GlobalError* error = error_service->GetGlobalErrorByMenuItemCommandID(
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kMenuCommandId);
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return !!error;
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool HasExternalInstallBubble(ExtensionService* service) {
402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GlobalErrorService* error_service =
403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      GlobalErrorServiceFactory::GetForProfile(service->profile());
404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GlobalError* error = error_service->GetGlobalErrorByMenuItemCommandID(
405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      kMenuCommandId);
406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return error && error->HasBubbleView();
407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
410