This source file includes following definitions.
- CreateSetAsDefaultBrowserUIHTMLSource
 
- response_delegate_
 
- RegisterMessages
 
- SetDefaultWebClientUIState
 
- OnSetAsDefaultConcluded
 
- IsInteractiveSetDefaultPermitted
 
- HandleLaunchSetDefaultBrowserFlow
 
- ConcludeInteraction
 
- ShouldAttemptImmersiveRestart
 
- dialog_interaction_result_
 
- ShowDialog
 
- GetDialogModalType
 
- GetDialogTitle
 
- GetDialogContentURL
 
- GetWebUIMessageHandlers
 
- GetDialogSize
 
- GetDialogArgs
 
- OnDialogClosed
 
- OnCloseContents
 
- ShouldShowDialogTitle
 
- HandleContextMenu
 
- SetDialogInteractionResult
 
- OnBrowserRemoved
 
- AttemptImmersiveFirstRunRestartOnFileThread
 
- Show
 
#include "chrome/browser/ui/webui/set_as_default_browser_ui.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/memory/weak_ptr.h"
#include "base/metrics/histogram.h"
#include "base/path_service.h"
#include "base/prefs/pref_service.h"
#include "base/win/win_util.h"
#include "chrome/browser/first_run/first_run.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/shell_integration.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_list_observer.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/chrome_pages.h"
#include "chrome/browser/ui/singleton_tabs.h"
#include "chrome/browser/ui/sync/sync_promo_ui.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "chrome/installer/util/install_util.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_contents_view.h"
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_data_source.h"
#include "content/public/browser/web_ui_message_handler.h"
#include "grit/browser_resources.h"
#include "grit/generated_resources.h"
#include "grit/locale_settings.h"
#include "ui/base/l10n/l10n_font_util.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/font.h"
#include "ui/views/widget/widget.h"
#include "ui/web_dialogs/web_dialog_delegate.h"
using content::BrowserThread;
using content::WebContents;
using content::WebUIMessageHandler;
namespace {
const char kSetAsDefaultBrowserHistogram[] = "DefaultBrowser.InteractionResult";
enum MakeChromeDefaultResult {
  MAKE_CHROME_DEFAULT_ACCEPTED,
  MAKE_CHROME_DEFAULT_DECLINED,
  MAKE_CHROME_DEFAULT_REGRETTED,
  MAKE_CHROME_DEFAULT_ACCEPTED_IMMERSE,
  MAKE_CHROME_DEFAULT_MAX
};
content::WebUIDataSource* CreateSetAsDefaultBrowserUIHTMLSource() {
  content::WebUIDataSource* data_source = content::WebUIDataSource::Create(
      chrome::kChromeUIMetroFlowHost);
  data_source->AddLocalizedString("page-title", IDS_METRO_FLOW_TAB_TITLE);
  data_source->AddLocalizedString("flowTitle", IDS_METRO_FLOW_TITLE_SHORT);
  data_source->AddLocalizedString("flowDescription",
                                  IDS_METRO_FLOW_DESCRIPTION);
  data_source->AddLocalizedString("flowNext",
                                  IDS_METRO_FLOW_SET_DEFAULT);
  data_source->AddLocalizedString("chromeLogoString",
                                  IDS_METRO_FLOW_LOGO_STRING_ALT);
  data_source->SetJsonPath("strings.js");
  data_source->AddResourcePath("set_as_default_browser.js",
      IDR_SET_AS_DEFAULT_BROWSER_JS);
  data_source->SetDefaultResource(IDR_SET_AS_DEFAULT_BROWSER_HTML);
  return data_source;
}
class ResponseDelegate {
 public:
  virtual void SetDialogInteractionResult(MakeChromeDefaultResult result) = 0;
 protected:
  virtual ~ResponseDelegate() { }
};
class SetAsDefaultBrowserHandler
    : public WebUIMessageHandler,
      public base::SupportsWeakPtr<SetAsDefaultBrowserHandler>,
      public ShellIntegration::DefaultWebClientObserver {
 public:
  explicit SetAsDefaultBrowserHandler(
      const base::WeakPtr<ResponseDelegate>& response_delegate);
  virtual ~SetAsDefaultBrowserHandler();
  
  virtual void RegisterMessages() OVERRIDE;
  
  virtual void SetDefaultWebClientUIState(
      ShellIntegration::DefaultWebClientUIState state) OVERRIDE;
  virtual void OnSetAsDefaultConcluded(bool close_chrome)  OVERRIDE;
  virtual bool IsInteractiveSetDefaultPermitted() OVERRIDE;
 private:
  
  void HandleLaunchSetDefaultBrowserFlow(const base::ListValue* args);
  
  void ConcludeInteraction(MakeChromeDefaultResult interaction_result);
  
  
  bool ShouldAttemptImmersiveRestart();
  scoped_refptr<ShellIntegration::DefaultBrowserWorker> default_browser_worker_;
  bool set_default_returned_;
  bool set_default_result_;
  base::WeakPtr<ResponseDelegate> response_delegate_;
  DISALLOW_COPY_AND_ASSIGN(SetAsDefaultBrowserHandler);
};
SetAsDefaultBrowserHandler::SetAsDefaultBrowserHandler(
    const base::WeakPtr<ResponseDelegate>& response_delegate)
    : default_browser_worker_(new ShellIntegration::DefaultBrowserWorker(this)),
      set_default_returned_(false), set_default_result_(false),
      response_delegate_(response_delegate) {
}
SetAsDefaultBrowserHandler::~SetAsDefaultBrowserHandler() {
  default_browser_worker_->ObserverDestroyed();
}
void SetAsDefaultBrowserHandler::RegisterMessages() {
  web_ui()->RegisterMessageCallback(
      "SetAsDefaultBrowser:LaunchSetDefaultBrowserFlow",
      base::Bind(&SetAsDefaultBrowserHandler::HandleLaunchSetDefaultBrowserFlow,
                 base::Unretained(this)));
}
void SetAsDefaultBrowserHandler::SetDefaultWebClientUIState(
    ShellIntegration::DefaultWebClientUIState state) {
  
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  if (!set_default_returned_)
    return;
  if (state == ShellIntegration::STATE_NOT_DEFAULT && set_default_result_) {
    
    
    
    ConcludeInteraction(MAKE_CHROME_DEFAULT_REGRETTED);
  } else if (state == ShellIntegration::STATE_IS_DEFAULT) {
    ConcludeInteraction(ShouldAttemptImmersiveRestart() ?
        MAKE_CHROME_DEFAULT_ACCEPTED_IMMERSE : MAKE_CHROME_DEFAULT_ACCEPTED);
  }
  
  
}
void SetAsDefaultBrowserHandler::OnSetAsDefaultConcluded(bool call_result) {
  set_default_returned_ = true;
  set_default_result_ = call_result;
}
bool SetAsDefaultBrowserHandler::IsInteractiveSetDefaultPermitted() {
  return true;
}
void SetAsDefaultBrowserHandler::HandleLaunchSetDefaultBrowserFlow(
    const base::ListValue* args) {
  set_default_returned_ = false;
  set_default_result_ = false;
  default_browser_worker_->StartSetAsDefault();
}
void SetAsDefaultBrowserHandler::ConcludeInteraction(
    MakeChromeDefaultResult interaction_result) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  if (response_delegate_)
    response_delegate_->SetDialogInteractionResult(interaction_result);
  WebContents* contents = web_ui()->GetWebContents();
  if (contents) {
    content::WebContentsDelegate* delegate = contents->GetDelegate();
    if (delegate)
      delegate->CloseContents(contents);
  }
}
bool SetAsDefaultBrowserHandler::ShouldAttemptImmersiveRestart() {
  return (base::win::IsTouchEnabledDevice() &&
          !Profile::FromWebUI(web_ui())->GetPrefs()->GetBoolean(
              prefs::kSuppressSwitchToMetroModeOnSetDefault));
}
class SetAsDefaultBrowserDialogImpl : public ui::WebDialogDelegate,
                                      public ResponseDelegate,
                                      public chrome::BrowserListObserver {
 public:
  SetAsDefaultBrowserDialogImpl(Profile* profile, Browser* browser);
  virtual ~SetAsDefaultBrowserDialogImpl();
  
  void ShowDialog();
 protected:
  
  virtual ui::ModalType GetDialogModalType() const OVERRIDE;
  virtual base::string16 GetDialogTitle() const OVERRIDE;
  virtual GURL GetDialogContentURL() const OVERRIDE;
  virtual void GetWebUIMessageHandlers(
      std::vector<WebUIMessageHandler*>* handlers) const OVERRIDE;
  virtual void GetDialogSize(gfx::Size* size) const OVERRIDE;
  virtual std::string GetDialogArgs() const OVERRIDE;
  virtual void OnDialogClosed(const std::string& json_retval) OVERRIDE;
  virtual void OnCloseContents(WebContents* source,
                               bool* out_close_dialog) OVERRIDE;
  virtual bool ShouldShowDialogTitle() const OVERRIDE;
  virtual bool HandleContextMenu(
      const content::ContextMenuParams& params) OVERRIDE;
  
  virtual void SetDialogInteractionResult(MakeChromeDefaultResult result);
  
  virtual void OnBrowserRemoved(Browser* browser) OVERRIDE;
 private:
  
  
  
  
  static void AttemptImmersiveFirstRunRestartOnFileThread();
  Profile* profile_;
  Browser* browser_;
  mutable bool owns_handler_;
  base::WeakPtrFactory<ResponseDelegate> response_delegate_ptr_factory_;
  SetAsDefaultBrowserHandler* handler_;
  MakeChromeDefaultResult dialog_interaction_result_;
  DISALLOW_COPY_AND_ASSIGN(SetAsDefaultBrowserDialogImpl);
};
SetAsDefaultBrowserDialogImpl::SetAsDefaultBrowserDialogImpl(Profile* profile,
                                                             Browser* browser)
    : profile_(profile),
      browser_(browser),
      owns_handler_(true),
      response_delegate_ptr_factory_(this),
      handler_(new SetAsDefaultBrowserHandler(
          response_delegate_ptr_factory_.GetWeakPtr())),
      dialog_interaction_result_(MAKE_CHROME_DEFAULT_DECLINED) {
  BrowserList::AddObserver(this);
}
SetAsDefaultBrowserDialogImpl::~SetAsDefaultBrowserDialogImpl() {
  if (browser_)
    BrowserList::RemoveObserver(this);
  if (owns_handler_)
    delete handler_;
}
void SetAsDefaultBrowserDialogImpl::ShowDialog() {
  
  
  
  gfx::NativeWindow native_window = chrome::ShowWebDialog(NULL, profile_, this);
  views::Widget* widget = views::Widget::GetWidgetForNativeWindow(
      native_window);
  widget->FlashFrame(true);
}
ui::ModalType SetAsDefaultBrowserDialogImpl::GetDialogModalType() const {
  return ui::MODAL_TYPE_SYSTEM;
}
base::string16 SetAsDefaultBrowserDialogImpl::GetDialogTitle() const {
  return l10n_util::GetStringUTF16(IDS_METRO_FLOW_TAB_TITLE);
}
GURL SetAsDefaultBrowserDialogImpl::GetDialogContentURL() const {
  std::string url_string(chrome::kChromeUIMetroFlowURL);
  return GURL(url_string);
}
void SetAsDefaultBrowserDialogImpl::GetWebUIMessageHandlers(
    std::vector<WebUIMessageHandler*>* handlers) const {
  handlers->push_back(handler_);
  owns_handler_ = false;
}
void SetAsDefaultBrowserDialogImpl::GetDialogSize(gfx::Size* size) const {
  PrefService* prefs = profile_->GetPrefs();
  gfx::Font approximate_web_font(
      prefs->GetString(prefs::kWebKitSansSerifFontFamily),
      prefs->GetInteger(prefs::kWebKitDefaultFontSize));
  *size = ui::GetLocalizedContentsSizeForFont(
      IDS_METRO_FLOW_WIDTH_CHARS, IDS_METRO_FLOW_HEIGHT_LINES,
      approximate_web_font);
}
std::string SetAsDefaultBrowserDialogImpl::GetDialogArgs() const {
  return "[]";
}
void SetAsDefaultBrowserDialogImpl::OnDialogClosed(
    const std::string& json_retval) {
  
  UMA_HISTOGRAM_ENUMERATION(kSetAsDefaultBrowserHistogram,
                            dialog_interaction_result_,
                            MAKE_CHROME_DEFAULT_MAX);
  if (dialog_interaction_result_ == MAKE_CHROME_DEFAULT_ACCEPTED_IMMERSE) {
    BrowserThread::PostTask(
        BrowserThread::FILE, FROM_HERE,
        base::Bind(&SetAsDefaultBrowserDialogImpl::
            AttemptImmersiveFirstRunRestartOnFileThread));
  } else {
    
    
    if (dialog_interaction_result_ == MAKE_CHROME_DEFAULT_REGRETTED) {
      PrefService* prefs = profile_->GetPrefs();
      prefs->SetBoolean(prefs::kCheckDefaultBrowser, false);
    }
    
    
    
    if (browser_) {
      BrowserWindow* window = browser_->window();
      WebContents* contents =
          browser_->tab_strip_model()->GetActiveWebContents();
      window->Show();
      if (contents)
        contents->GetView()->SetInitialFocus();
    }
  }
  delete this;
}
void SetAsDefaultBrowserDialogImpl::OnCloseContents(WebContents* source,
                                                    bool* out_close_dialog) {
  *out_close_dialog = true;
}
bool SetAsDefaultBrowserDialogImpl::ShouldShowDialogTitle() const {
  return true;
}
bool SetAsDefaultBrowserDialogImpl::HandleContextMenu(
    const content::ContextMenuParams& params) {
  return true;
}
void SetAsDefaultBrowserDialogImpl::SetDialogInteractionResult(
    MakeChromeDefaultResult result) {
  dialog_interaction_result_ = result;
}
void SetAsDefaultBrowserDialogImpl::OnBrowserRemoved(Browser* browser) {
  if (browser_ == browser) {
    browser_ = NULL;
    BrowserList::RemoveObserver(this);
  }
}
void SetAsDefaultBrowserDialogImpl::
    AttemptImmersiveFirstRunRestartOnFileThread() {
  DCHECK_CURRENTLY_ON(BrowserThread::FILE);
  
  
  
  if (first_run::IsChromeFirstRun())
    first_run::RemoveSentinel();
  
  
  
  
  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
                          base::Bind(&chrome::AttemptRestart));
}
}  
SetAsDefaultBrowserUI::SetAsDefaultBrowserUI(content::WebUI* web_ui)
    : ui::WebDialogUI(web_ui) {
  content::WebUIDataSource::Add(
      Profile::FromWebUI(web_ui), CreateSetAsDefaultBrowserUIHTMLSource());
}
void SetAsDefaultBrowserUI::Show(Profile* profile, Browser* browser) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  SetAsDefaultBrowserDialogImpl* dialog =
      new SetAsDefaultBrowserDialogImpl(profile, browser);
  dialog->ShowDialog();
}