<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/login/webui_login_view.h"

#include <vector>

#include "base/logging.h"
#include "chrome/browser/chromeos/login/login_utils.h"
#include "chrome/browser/chromeos/login/proxy_settings_dialog.h"
#include "chrome/browser/chromeos/status/clock_menu_button.h"
#include "chrome/browser/chromeos/status/input_method_menu_button.h"
#include "chrome/browser/chromeos/status/network_menu_button.h"
#include "chrome/browser/chromeos/status/status_area_view.h"
#include "chrome/browser/chromeos/wm_ipc.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/renderer_host/render_widget_host_view_views.h"
#include "chrome/browser/ui/touch/frame/keyboard_container_view.h"
#include "chrome/browser/ui/views/dom_view.h"
#include "chrome/browser/ui/views/tab_contents/tab_contents_view_touch.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/common/notification_service.h"
#include "googleurl/src/gurl.h"
#include "ui/base/x/x11_util.h"
#include "ui/gfx/transform.h"
#include "views/controls/textfield/textfield.h"
#include "views/widget/widget.h"

// TODO(rharrison): Modify this class to support both touch and non-touch

namespace {

const int kKeyboardHeight = 300;
const int kKeyboardSlideDuration = 500;  // In milliseconds

PropertyAccessor<bool>* GetFocusedStateAccessor() {
  static PropertyAccessor<bool> state;
  return &state;
}

bool TabContentsHasFocus(const TabContents* contents) {
  views::View* view = static_cast<TabContentsViewTouch*>(contents->view());
  return view->Contains(view->GetFocusManager()->GetFocusedView());
}

}  // namespace

namespace chromeos {

// static
const char WebUILoginView::kViewClassName[] =
    "browser/chromeos/login/WebUILoginView";

// WebUILoginView public: ------------------------------------------------------

WebUILoginView::WebUILoginView()
    : profile_(NULL),
      status_area_(NULL),
      webui_login_(NULL),
      keyboard_showing_(false),
      focus_listener_added_(false),
      keyboard_(NULL) {
}

void WebUILoginView::Init(const GURL& login_url) {
  CHECK(!login_url.is_empty());

  profile_ = ProfileManager::GetDefaultProfile();

  webui_login_ = new DOMView();
  AddChildView(webui_login_);
  webui_login_->Init(profile_, NULL);
  webui_login_->LoadURL(login_url);
  webui_login_->SetVisible(true);

  InitStatusArea();

  registrar_.Add(this,
                 NotificationType::FOCUS_CHANGED_IN_PAGE,
                 NotificationService::AllSources());
  registrar_.Add(this,
                 NotificationType::TAB_CONTENTS_DESTROYED,
                 NotificationService::AllSources());
}

// static
views::Widget* WebUILoginView::CreateWindowContainingView(
    const gfx::Rect& bounds,
    const GURL& login_url,
    WebUILoginView** view) {
  views::Widget* window = new views::Widget;
  views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
  params.bounds = bounds;
  window->Init(params);
  *view = new WebUILoginView();
  (*view)->Init(login_url);

  window->SetContentsView(*view);

  (*view)->UpdateWindowType();

  return window;
}

std::string WebUILoginView::GetClassName() const {
  return kViewClassName;
}

gfx::NativeWindow WebUILoginView::GetNativeWindow() const {
  return GetWidget()->GetNativeWindow();
}

void WebUILoginView::FocusWillChange(views::View* focused_before,
                                     views::View* focused_now) {
  VirtualKeyboardType before = DecideKeyboardStateForView(focused_before);
  VirtualKeyboardType now = DecideKeyboardStateForView(focused_now);
  if (before != now) {
    // TODO(varunjain): support other types of keyboard.
    UpdateKeyboardAndLayout(now == GENERIC);
  }
}

// WebUILoginView protected: ---------------------------------------------------

void WebUILoginView::Layout() {
  const int kCornerPadding = 5;
  gfx::Size status_area_size = status_area_->GetPreferredSize();
  status_area_->SetBounds(
      width() - status_area_size.width() - kCornerPadding,
      kCornerPadding,
      status_area_size.width(),
      status_area_size.height());

  if (webui_login_)
    webui_login_->SetBoundsRect(bounds());

  // TODO(rharrison): Hide touch specific code behind TOUCH_UI defines
  if (!keyboard_)
    return;

  keyboard_->SetVisible(keyboard_showing_);
  gfx::Rect keyboard_bounds = bounds();
  keyboard_bounds.set_y(keyboard_bounds.height() - kKeyboardHeight);
  keyboard_bounds.set_height(kKeyboardHeight);
  keyboard_->SetBoundsRect(keyboard_bounds);
}

void WebUILoginView::ChildPreferredSizeChanged(View* child) {
  Layout();
  SchedulePaint();
}

Profile* WebUILoginView::GetProfile() const {
  return NULL;
}

void WebUILoginView::ExecuteBrowserCommand(int id) const {
}

bool WebUILoginView::ShouldOpenButtonOptions(
    const views::View* button_view) const {
  if (button_view == status_area_->network_view())
    return true;

  if (button_view == status_area_->clock_view() ||
      button_view == status_area_->input_method_view())
    return false;

  return true;
}

void WebUILoginView::OpenButtonOptions(const views::View* button_view) {
  if (button_view == status_area_->network_view()) {
    if (proxy_settings_dialog_.get() == NULL) {
      proxy_settings_dialog_.reset(new ProxySettingsDialog(
          this, GetNativeWindow()));
    }
    proxy_settings_dialog_->Show();
  }
}

StatusAreaHost::ScreenMode WebUILoginView::GetScreenMode() const {
  return kLoginMode;
}

StatusAreaHost::TextStyle WebUILoginView::GetTextStyle() const {
  return kWhitePlain;
}

void WebUILoginView::OnDialogClosed() {
}

void WebUILoginView::OnLocaleChanged() {
  // Proxy settings dialog contains localized strings.
  proxy_settings_dialog_.reset();
  SchedulePaint();
}

// WebUILoginView private: -----------------------------------------------------

void WebUILoginView::InitStatusArea() {
  DCHECK(status_area_ == NULL);
  status_area_ = new StatusAreaView(this);
  status_area_->Init();
  AddChildView(status_area_);
}

void WebUILoginView::UpdateWindowType() {
  std::vector<int> params;
  WmIpc::instance()->SetWindowType(
      GTK_WIDGET(GetNativeWindow()),
      WM_IPC_WINDOW_LOGIN_WEBUI,
      &params);
}

void WebUILoginView::InitVirtualKeyboard() {
  if (keyboard_)
    return;

  keyboard_ = new KeyboardContainerView(profile_, NULL);
  keyboard_->SetVisible(false);
  AddChildView(keyboard_);
}

void WebUILoginView::UpdateKeyboardAndLayout(bool should_show_keyboard) {
  if (should_show_keyboard)
    InitVirtualKeyboard();

  if (should_show_keyboard == keyboard_showing_)
    return;

  DCHECK(keyboard_);

  keyboard_showing_ = should_show_keyboard;
  Layout();
}

WebUILoginView::VirtualKeyboardType
    WebUILoginView::DecideKeyboardStateForView(views::View* view) {
  if (!view)
    return NONE;

  std::string cname = view->GetClassName();
  if (cname == views::Textfield::kViewClassName) {
    return GENERIC;
  } else if (cname == RenderWidgetHostViewViews::kViewClassName) {
    TabContents* contents = webui_login_->tab_contents();
    bool* editable = contents ? GetFocusedStateAccessor()->GetProperty(
        contents->property_bag()) : NULL;
    if (editable && *editable)
      return GENERIC;
  }
  return NONE;
}

void WebUILoginView::Observe(NotificationType type,
                             const NotificationSource& source,
                             const NotificationDetails& details) {
  if (type == NotificationType::FOCUS_CHANGED_IN_PAGE) {
    // Only modify the keyboard state if the currently active tab sent the
    // notification.
    const TabContents* current_tab = webui_login_->tab_contents();
    TabContents* source_tab = Source<TabContents>(source).ptr();
    const bool editable = *Details<const bool>(details).ptr();

    if (current_tab == source_tab && TabContentsHasFocus(source_tab))
      UpdateKeyboardAndLayout(editable);

    // Save the state of the focused field so that the keyboard visibility
    // can be determined after tab switching.
    GetFocusedStateAccessor()->SetProperty(
        source_tab->property_bag(), editable);
  } else if (type == NotificationType::TAB_CONTENTS_DESTROYED) {
    GetFocusedStateAccessor()->DeleteProperty(
        Source<TabContents>(source).ptr()->property_bag());
  }
}

}  // namespace chromeos
<commit_msg>Changed kKeyboardHeight in WebUILoginView to reflect change in TouchBrowserFrameView<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/login/webui_login_view.h"

#include <vector>

#include "base/logging.h"
#include "chrome/browser/chromeos/login/login_utils.h"
#include "chrome/browser/chromeos/login/proxy_settings_dialog.h"
#include "chrome/browser/chromeos/status/clock_menu_button.h"
#include "chrome/browser/chromeos/status/input_method_menu_button.h"
#include "chrome/browser/chromeos/status/network_menu_button.h"
#include "chrome/browser/chromeos/status/status_area_view.h"
#include "chrome/browser/chromeos/wm_ipc.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/renderer_host/render_widget_host_view_views.h"
#include "chrome/browser/ui/touch/frame/keyboard_container_view.h"
#include "chrome/browser/ui/views/dom_view.h"
#include "chrome/browser/ui/views/tab_contents/tab_contents_view_touch.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/common/notification_service.h"
#include "googleurl/src/gurl.h"
#include "ui/base/x/x11_util.h"
#include "ui/gfx/transform.h"
#include "views/controls/textfield/textfield.h"
#include "views/widget/widget.h"

// TODO(rharrison): Modify this class to support both touch and non-touch

namespace {

const int kKeyboardHeight = 360;
const int kKeyboardSlideDuration = 500;  // In milliseconds

PropertyAccessor<bool>* GetFocusedStateAccessor() {
  static PropertyAccessor<bool> state;
  return &state;
}

bool TabContentsHasFocus(const TabContents* contents) {
  views::View* view = static_cast<TabContentsViewTouch*>(contents->view());
  return view->Contains(view->GetFocusManager()->GetFocusedView());
}

}  // namespace

namespace chromeos {

// static
const char WebUILoginView::kViewClassName[] =
    "browser/chromeos/login/WebUILoginView";

// WebUILoginView public: ------------------------------------------------------

WebUILoginView::WebUILoginView()
    : profile_(NULL),
      status_area_(NULL),
      webui_login_(NULL),
      keyboard_showing_(false),
      focus_listener_added_(false),
      keyboard_(NULL) {
}

void WebUILoginView::Init(const GURL& login_url) {
  CHECK(!login_url.is_empty());

  profile_ = ProfileManager::GetDefaultProfile();

  webui_login_ = new DOMView();
  AddChildView(webui_login_);
  webui_login_->Init(profile_, NULL);
  webui_login_->LoadURL(login_url);
  webui_login_->SetVisible(true);

  InitStatusArea();

  registrar_.Add(this,
                 NotificationType::FOCUS_CHANGED_IN_PAGE,
                 NotificationService::AllSources());
  registrar_.Add(this,
                 NotificationType::TAB_CONTENTS_DESTROYED,
                 NotificationService::AllSources());
}

// static
views::Widget* WebUILoginView::CreateWindowContainingView(
    const gfx::Rect& bounds,
    const GURL& login_url,
    WebUILoginView** view) {
  views::Widget* window = new views::Widget;
  views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
  params.bounds = bounds;
  window->Init(params);
  *view = new WebUILoginView();
  (*view)->Init(login_url);

  window->SetContentsView(*view);

  (*view)->UpdateWindowType();

  return window;
}

std::string WebUILoginView::GetClassName() const {
  return kViewClassName;
}

gfx::NativeWindow WebUILoginView::GetNativeWindow() const {
  return GetWidget()->GetNativeWindow();
}

void WebUILoginView::FocusWillChange(views::View* focused_before,
                                     views::View* focused_now) {
  VirtualKeyboardType before = DecideKeyboardStateForView(focused_before);
  VirtualKeyboardType now = DecideKeyboardStateForView(focused_now);
  if (before != now) {
    // TODO(varunjain): support other types of keyboard.
    UpdateKeyboardAndLayout(now == GENERIC);
  }
}

// WebUILoginView protected: ---------------------------------------------------

void WebUILoginView::Layout() {
  const int kCornerPadding = 5;
  gfx::Size status_area_size = status_area_->GetPreferredSize();
  status_area_->SetBounds(
      width() - status_area_size.width() - kCornerPadding,
      kCornerPadding,
      status_area_size.width(),
      status_area_size.height());

  if (webui_login_)
    webui_login_->SetBoundsRect(bounds());

  // TODO(rharrison): Hide touch specific code behind TOUCH_UI defines
  if (!keyboard_)
    return;

  keyboard_->SetVisible(keyboard_showing_);
  gfx::Rect keyboard_bounds = bounds();
  keyboard_bounds.set_y(keyboard_bounds.height() - kKeyboardHeight);
  keyboard_bounds.set_height(kKeyboardHeight);
  keyboard_->SetBoundsRect(keyboard_bounds);
}

void WebUILoginView::ChildPreferredSizeChanged(View* child) {
  Layout();
  SchedulePaint();
}

Profile* WebUILoginView::GetProfile() const {
  return NULL;
}

void WebUILoginView::ExecuteBrowserCommand(int id) const {
}

bool WebUILoginView::ShouldOpenButtonOptions(
    const views::View* button_view) const {
  if (button_view == status_area_->network_view())
    return true;

  if (button_view == status_area_->clock_view() ||
      button_view == status_area_->input_method_view())
    return false;

  return true;
}

void WebUILoginView::OpenButtonOptions(const views::View* button_view) {
  if (button_view == status_area_->network_view()) {
    if (proxy_settings_dialog_.get() == NULL) {
      proxy_settings_dialog_.reset(new ProxySettingsDialog(
          this, GetNativeWindow()));
    }
    proxy_settings_dialog_->Show();
  }
}

StatusAreaHost::ScreenMode WebUILoginView::GetScreenMode() const {
  return kLoginMode;
}

StatusAreaHost::TextStyle WebUILoginView::GetTextStyle() const {
  return kWhitePlain;
}

void WebUILoginView::OnDialogClosed() {
}

void WebUILoginView::OnLocaleChanged() {
  // Proxy settings dialog contains localized strings.
  proxy_settings_dialog_.reset();
  SchedulePaint();
}

// WebUILoginView private: -----------------------------------------------------

void WebUILoginView::InitStatusArea() {
  DCHECK(status_area_ == NULL);
  status_area_ = new StatusAreaView(this);
  status_area_->Init();
  AddChildView(status_area_);
}

void WebUILoginView::UpdateWindowType() {
  std::vector<int> params;
  WmIpc::instance()->SetWindowType(
      GTK_WIDGET(GetNativeWindow()),
      WM_IPC_WINDOW_LOGIN_WEBUI,
      &params);
}

void WebUILoginView::InitVirtualKeyboard() {
  if (keyboard_)
    return;

  keyboard_ = new KeyboardContainerView(profile_, NULL);
  keyboard_->SetVisible(false);
  AddChildView(keyboard_);
}

void WebUILoginView::UpdateKeyboardAndLayout(bool should_show_keyboard) {
  if (should_show_keyboard)
    InitVirtualKeyboard();

  if (should_show_keyboard == keyboard_showing_)
    return;

  DCHECK(keyboard_);

  keyboard_showing_ = should_show_keyboard;
  Layout();
}

WebUILoginView::VirtualKeyboardType
    WebUILoginView::DecideKeyboardStateForView(views::View* view) {
  if (!view)
    return NONE;

  std::string cname = view->GetClassName();
  if (cname == views::Textfield::kViewClassName) {
    return GENERIC;
  } else if (cname == RenderWidgetHostViewViews::kViewClassName) {
    TabContents* contents = webui_login_->tab_contents();
    bool* editable = contents ? GetFocusedStateAccessor()->GetProperty(
        contents->property_bag()) : NULL;
    if (editable && *editable)
      return GENERIC;
  }
  return NONE;
}

void WebUILoginView::Observe(NotificationType type,
                             const NotificationSource& source,
                             const NotificationDetails& details) {
  if (type == NotificationType::FOCUS_CHANGED_IN_PAGE) {
    // Only modify the keyboard state if the currently active tab sent the
    // notification.
    const TabContents* current_tab = webui_login_->tab_contents();
    TabContents* source_tab = Source<TabContents>(source).ptr();
    const bool editable = *Details<const bool>(details).ptr();

    if (current_tab == source_tab && TabContentsHasFocus(source_tab))
      UpdateKeyboardAndLayout(editable);

    // Save the state of the focused field so that the keyboard visibility
    // can be determined after tab switching.
    GetFocusedStateAccessor()->SetProperty(
        source_tab->property_bag(), editable);
  } else if (type == NotificationType::TAB_CONTENTS_DESTROYED) {
    GetFocusedStateAccessor()->DeleteProperty(
        Source<TabContents>(source).ptr()->property_bag());
  }
}

}  // namespace chromeos
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/extensions/extension_install_ui.h"

#include <map>

#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/file_util.h"
#include "base/rand_util.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/extensions/theme_installed_infobar_delegate.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#if defined(TOOLKIT_VIEWS)  // TODO(port)
#include "chrome/browser/views/extensions/extension_installed_bubble.h"
#elif defined(TOOLKIT_GTK)
#include "chrome/browser/gtk/extension_installed_bubble_gtk.h"
#endif
#include "chrome/common/extensions/extension.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/platform_util.h"
#include "chrome/common/url_constants.h"
#include "grit/browser_resources.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"

#if defined(TOOLKIT_GTK)
#include "chrome/browser/extensions/gtk_theme_installed_infobar_delegate.h"
#include "chrome/browser/gtk/gtk_theme_provider.h"
#endif

#if defined(OS_MACOSX)
#include "chrome/browser/cocoa/extension_installed_bubble_bridge.h"
#endif

// static
const int ExtensionInstallUI::kTitleIds[NUM_PROMPT_TYPES] = {
  IDS_EXTENSION_INSTALL_PROMPT_TITLE,
  IDS_EXTENSION_UNINSTALL_PROMPT_TITLE
};
// static
const int ExtensionInstallUI::kHeadingIds[NUM_PROMPT_TYPES] = {
  IDS_EXTENSION_INSTALL_PROMPT_HEADING,
  IDS_EXTENSION_UNINSTALL_PROMPT_HEADING
};
// static
const int ExtensionInstallUI::kButtonIds[NUM_PROMPT_TYPES] = {
  IDS_EXTENSION_PROMPT_INSTALL_BUTTON,
  IDS_EXTENSION_PROMPT_UNINSTALL_BUTTON
};

namespace {

// We also show the severe warning if the extension has access to any file://
// URLs. They aren't *quite* as dangerous as full access to the system via
// NPAPI, but pretty dang close. Content scripts are currently the only way
// that extension can get access to file:// URLs.
static bool ExtensionHasFileAccess(Extension* extension) {
  for (UserScriptList::const_iterator script =
           extension->content_scripts().begin();
       script != extension->content_scripts().end();
       ++script) {
    for (UserScript::PatternList::const_iterator pattern =
             script->url_patterns().begin();
         pattern != script->url_patterns().end();
         ++pattern) {
      if (pattern->scheme() == chrome::kFileScheme)
        return true;
    }
  }

  return false;
}

static void GetV2Warnings(Extension* extension,
                          std::vector<string16>* warnings) {
  if (!extension->plugins().empty() || ExtensionHasFileAccess(extension)) {
    // TODO(aa): This one is a bit awkward. Should we have a separate
    // presentation for this case?
    warnings->push_back(
        l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT2_WARNING_FULL_ACCESS));
    return;
  }

  if (extension->HasAccessToAllHosts()) {
    warnings->push_back(
        l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT2_WARNING_ALL_HOSTS));
  } else {
    std::set<std::string> hosts = extension->GetEffectiveHostPermissions();
    if (hosts.size() == 1) {
      warnings->push_back(
          l10n_util::GetStringFUTF16(IDS_EXTENSION_PROMPT2_WARNING_1_HOST,
                                     UTF8ToUTF16(*hosts.begin())));
    } else if (hosts.size() == 2) {
      warnings->push_back(
          l10n_util::GetStringFUTF16(IDS_EXTENSION_PROMPT2_WARNING_2_HOSTS,
                                     UTF8ToUTF16(*hosts.begin()),
                                     UTF8ToUTF16(*(++hosts.begin()))));
    } else if (hosts.size() == 3) {
      warnings->push_back(
          l10n_util::GetStringFUTF16(IDS_EXTENSION_PROMPT2_WARNING_3_HOSTS,
                                     UTF8ToUTF16(*hosts.begin()),
                                     UTF8ToUTF16(*(++hosts.begin())),
                                     UTF8ToUTF16(*(++++hosts.begin()))));
    } else if (hosts.size() >= 4) {
      warnings->push_back(
          l10n_util::GetStringFUTF16(
              IDS_EXTENSION_PROMPT2_WARNING_4_OR_MORE_HOSTS,
              UTF8ToUTF16(*hosts.begin()),
              UTF8ToUTF16(*(++hosts.begin())),
              IntToString16(hosts.size() - 2)));
    }
  }

  if (extension->HasEffectiveBrowsingHistoryPermission()) {
    warnings->push_back(
        l10n_util::GetStringUTF16(
            IDS_EXTENSION_PROMPT2_WARNING_BROWSING_HISTORY));
  }

  // TODO(aa): Geolocation, camera/mic, what else?
}

}  // namespace

ExtensionInstallUI::ExtensionInstallUI(Profile* profile)
    : profile_(profile),
      ui_loop_(MessageLoop::current()),
      previous_use_system_theme_(false),
      extension_(NULL),
      delegate_(NULL),
      prompt_type_(NUM_PROMPT_TYPES),
      ALLOW_THIS_IN_INITIALIZER_LIST(tracker_(this)) {}

void ExtensionInstallUI::ConfirmInstall(Delegate* delegate,
                                        Extension* extension) {
  DCHECK(ui_loop_ == MessageLoop::current());
  extension_ = extension;
  delegate_ = delegate;

  // We special-case themes to not show any confirm UI. Instead they are
  // immediately installed, and then we show an infobar (see OnInstallSuccess)
  // to allow the user to revert if they don't like it.
  if (extension->IsTheme()) {
    // Remember the current theme in case the user pressed undo.
    Extension* previous_theme = profile_->GetTheme();
    if (previous_theme)
      previous_theme_id_ = previous_theme->id();

#if defined(TOOLKIT_GTK)
    // On Linux, we also need to take the user's system settings into account
    // to undo theme installation.
    previous_use_system_theme_ =
        GtkThemeProvider::GetFrom(profile_)->UseGtkTheme();
#else
    DCHECK(!previous_use_system_theme_);
#endif

    delegate->InstallUIProceed(false);
    return;
  }

  ShowConfirmation(INSTALL_PROMPT);
}

void ExtensionInstallUI::ConfirmUninstall(Delegate* delegate,
                                          Extension* extension) {
  DCHECK(ui_loop_ == MessageLoop::current());
  extension_ = extension;
  delegate_ = delegate;

  ShowConfirmation(UNINSTALL_PROMPT);
}

void ExtensionInstallUI::OnInstallSuccess(Extension* extension) {
  if (extension->IsTheme()) {
    ShowThemeInfoBar(previous_theme_id_, previous_use_system_theme_,
                     extension, profile_);
    return;
  }

  // GetLastActiveWithProfile will fail on the build bots. This needs to be
  // implemented differently if any test is created which depends on
  // ExtensionInstalledBubble showing.
  Browser* browser = BrowserList::GetLastActiveWithProfile(profile_);

#if defined(TOOLKIT_VIEWS)
  if (!browser)
    return;

  ExtensionInstalledBubble::Show(extension, browser, icon_);
#elif defined(OS_MACOSX)
  DCHECK(browser);
  // Note that browser actions don't appear in incognito mode initially,
  // so fall back to the generic case.
  if ((extension->browser_action() && !browser->profile()->IsOffTheRecord()) ||
      (extension->page_action() &&
      !extension->page_action()->default_icon_path().empty())) {
    ExtensionInstalledBubbleCocoa::ShowExtensionInstalledBubble(
        browser->window()->GetNativeHandle(),
        extension, browser, icon_);
  }  else {
    // If the extension is of type GENERIC, meaning it doesn't have a UI
    // surface to display for this window, launch infobar instead of popup
    // bubble, because we have no guaranteed wrench menu button to point to.
    ShowGenericExtensionInstalledInfoBar(extension);
  }
#elif defined(TOOLKIT_GTK)
  if (!browser)
    return;
  ExtensionInstalledBubbleGtk::Show(extension, browser, icon_);
#endif  // TOOLKIT_VIEWS
}

void ExtensionInstallUI::OnInstallFailure(const std::string& error) {
  DCHECK(ui_loop_ == MessageLoop::current());

  Browser* browser = BrowserList::GetLastActiveWithProfile(profile_);
  platform_util::SimpleErrorBox(
      browser ? browser->window()->GetNativeHandle() : NULL,
      l10n_util::GetStringUTF16(IDS_EXTENSION_INSTALL_FAILURE_TITLE),
      UTF8ToUTF16(error));
}

void ExtensionInstallUI::OnOverinstallAttempted(Extension* extension) {
  ShowThemeInfoBar(previous_theme_id_, previous_use_system_theme_,
                   extension, profile_);
}

void ExtensionInstallUI::OnImageLoaded(
    SkBitmap* image, ExtensionResource resource, int index) {
  if (image)
    icon_ = *image;
  else
    icon_ = SkBitmap();
  if (icon_.empty()) {
    icon_ = *ResourceBundle::GetSharedInstance().GetBitmapNamed(
        IDR_EXTENSION_DEFAULT_ICON);
  }

  switch (prompt_type_) {
    case INSTALL_PROMPT: {
      NotificationService* service = NotificationService::current();
      service->Notify(NotificationType::EXTENSION_WILL_SHOW_CONFIRM_DIALOG,
          Source<ExtensionInstallUI>(this),
          NotificationService::NoDetails());

      std::vector<string16> warnings;
      GetV2Warnings(extension_, &warnings);
      ShowExtensionInstallUIPrompt2Impl(
          profile_, delegate_, extension_, &icon_, warnings);
      break;
    }
    case UNINSTALL_PROMPT: {
      string16 message =
          l10n_util::GetStringUTF16(IDS_EXTENSION_UNINSTALL_CONFIRMATION);
      ShowExtensionInstallUIPromptImpl(profile_, delegate_, extension_, &icon_,
          message, UNINSTALL_PROMPT);
      break;
    }
    default:
      NOTREACHED() << "Unknown message";
      break;
  }
}

void ExtensionInstallUI::ShowThemeInfoBar(
    const std::string& previous_theme_id, bool previous_use_system_theme,
    Extension* new_theme, Profile* profile) {
  if (!new_theme->IsTheme())
    return;

  Browser* browser = BrowserList::GetLastActiveWithProfile(profile);
  if (!browser)
    return;

  TabContents* tab_contents = browser->GetSelectedTabContents();
  if (!tab_contents)
    return;

  // First find any previous theme preview infobars.
  InfoBarDelegate* old_delegate = NULL;
  for (int i = 0; i < tab_contents->infobar_delegate_count(); ++i) {
    InfoBarDelegate* delegate = tab_contents->GetInfoBarDelegateAt(i);
    if (delegate->AsThemePreviewInfobarDelegate()) {
      old_delegate = delegate;
      break;
    }
  }

  // Then either replace that old one or add a new one.
  InfoBarDelegate* new_delegate =
      GetNewThemeInstalledInfoBarDelegate(
          tab_contents, new_theme,
          previous_theme_id, previous_use_system_theme);

  if (old_delegate)
    tab_contents->ReplaceInfoBar(old_delegate, new_delegate);
  else
    tab_contents->AddInfoBar(new_delegate);
}

void ExtensionInstallUI::ShowConfirmation(PromptType prompt_type) {
  // Load the image asynchronously. For the response, check OnImageLoaded.
  prompt_type_ = prompt_type;
  ExtensionResource image =
      extension_->GetIconPath(Extension::EXTENSION_ICON_LARGE);
  tracker_.LoadImage(extension_, image,
                     gfx::Size(Extension::EXTENSION_ICON_LARGE,
                               Extension::EXTENSION_ICON_LARGE),
                     ImageLoadingTracker::DONT_CACHE);
}

#if defined(OS_MACOSX)
void ExtensionInstallUI::ShowGenericExtensionInstalledInfoBar(
    Extension* new_extension) {
  Browser* browser = BrowserList::GetLastActiveWithProfile(profile_);
  if (!browser)
    return;

  TabContents* tab_contents = browser->GetSelectedTabContents();
  if (!tab_contents)
    return;

  std::wstring msg = l10n_util::GetStringF(IDS_EXTENSION_INSTALLED_HEADING,
                                           UTF8ToWide(new_extension->name())) +
         L" " + l10n_util::GetString(IDS_EXTENSION_INSTALLED_MANAGE_INFO_MAC);
  InfoBarDelegate* delegate = new SimpleAlertInfoBarDelegate(
      tab_contents, msg, new SkBitmap(icon_), true);
  tab_contents->AddInfoBar(delegate);
}
#endif

InfoBarDelegate* ExtensionInstallUI::GetNewThemeInstalledInfoBarDelegate(
    TabContents* tab_contents, Extension* new_theme,
    const std::string& previous_theme_id, bool previous_use_system_theme) {
#if defined(TOOLKIT_GTK)
  return new GtkThemeInstalledInfoBarDelegate(tab_contents, new_theme,
      previous_theme_id, previous_use_system_theme);
#else
  return new ThemeInstalledInfoBarDelegate(tab_contents, new_theme,
      previous_theme_id);
#endif
}
<commit_msg>Auto-launch apps after installation.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/extensions/extension_install_ui.h"

#include <map>

#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/file_util.h"
#include "base/rand_util.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/extensions/theme_installed_infobar_delegate.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#if defined(TOOLKIT_VIEWS)  // TODO(port)
#include "chrome/browser/views/extensions/extension_installed_bubble.h"
#elif defined(TOOLKIT_GTK)
#include "chrome/browser/gtk/extension_installed_bubble_gtk.h"
#endif
#include "chrome/common/extensions/extension.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/platform_util.h"
#include "chrome/common/url_constants.h"
#include "grit/browser_resources.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"

#if defined(TOOLKIT_GTK)
#include "chrome/browser/extensions/gtk_theme_installed_infobar_delegate.h"
#include "chrome/browser/gtk/gtk_theme_provider.h"
#endif

#if defined(OS_MACOSX)
#include "chrome/browser/cocoa/extension_installed_bubble_bridge.h"
#endif

// static
const int ExtensionInstallUI::kTitleIds[NUM_PROMPT_TYPES] = {
  IDS_EXTENSION_INSTALL_PROMPT_TITLE,
  IDS_EXTENSION_UNINSTALL_PROMPT_TITLE
};
// static
const int ExtensionInstallUI::kHeadingIds[NUM_PROMPT_TYPES] = {
  IDS_EXTENSION_INSTALL_PROMPT_HEADING,
  IDS_EXTENSION_UNINSTALL_PROMPT_HEADING
};
// static
const int ExtensionInstallUI::kButtonIds[NUM_PROMPT_TYPES] = {
  IDS_EXTENSION_PROMPT_INSTALL_BUTTON,
  IDS_EXTENSION_PROMPT_UNINSTALL_BUTTON
};

namespace {

// We also show the severe warning if the extension has access to any file://
// URLs. They aren't *quite* as dangerous as full access to the system via
// NPAPI, but pretty dang close. Content scripts are currently the only way
// that extension can get access to file:// URLs.
static bool ExtensionHasFileAccess(Extension* extension) {
  for (UserScriptList::const_iterator script =
           extension->content_scripts().begin();
       script != extension->content_scripts().end();
       ++script) {
    for (UserScript::PatternList::const_iterator pattern =
             script->url_patterns().begin();
         pattern != script->url_patterns().end();
         ++pattern) {
      if (pattern->scheme() == chrome::kFileScheme)
        return true;
    }
  }

  return false;
}

static void GetV2Warnings(Extension* extension,
                          std::vector<string16>* warnings) {
  if (!extension->plugins().empty() || ExtensionHasFileAccess(extension)) {
    // TODO(aa): This one is a bit awkward. Should we have a separate
    // presentation for this case?
    warnings->push_back(
        l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT2_WARNING_FULL_ACCESS));
    return;
  }

  if (extension->HasAccessToAllHosts()) {
    warnings->push_back(
        l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT2_WARNING_ALL_HOSTS));
  } else {
    std::set<std::string> hosts = extension->GetEffectiveHostPermissions();
    if (hosts.size() == 1) {
      warnings->push_back(
          l10n_util::GetStringFUTF16(IDS_EXTENSION_PROMPT2_WARNING_1_HOST,
                                     UTF8ToUTF16(*hosts.begin())));
    } else if (hosts.size() == 2) {
      warnings->push_back(
          l10n_util::GetStringFUTF16(IDS_EXTENSION_PROMPT2_WARNING_2_HOSTS,
                                     UTF8ToUTF16(*hosts.begin()),
                                     UTF8ToUTF16(*(++hosts.begin()))));
    } else if (hosts.size() == 3) {
      warnings->push_back(
          l10n_util::GetStringFUTF16(IDS_EXTENSION_PROMPT2_WARNING_3_HOSTS,
                                     UTF8ToUTF16(*hosts.begin()),
                                     UTF8ToUTF16(*(++hosts.begin())),
                                     UTF8ToUTF16(*(++++hosts.begin()))));
    } else if (hosts.size() >= 4) {
      warnings->push_back(
          l10n_util::GetStringFUTF16(
              IDS_EXTENSION_PROMPT2_WARNING_4_OR_MORE_HOSTS,
              UTF8ToUTF16(*hosts.begin()),
              UTF8ToUTF16(*(++hosts.begin())),
              IntToString16(hosts.size() - 2)));
    }
  }

  if (extension->HasEffectiveBrowsingHistoryPermission()) {
    warnings->push_back(
        l10n_util::GetStringUTF16(
            IDS_EXTENSION_PROMPT2_WARNING_BROWSING_HISTORY));
  }

  // TODO(aa): Geolocation, camera/mic, what else?
}

}  // namespace

ExtensionInstallUI::ExtensionInstallUI(Profile* profile)
    : profile_(profile),
      ui_loop_(MessageLoop::current()),
      previous_use_system_theme_(false),
      extension_(NULL),
      delegate_(NULL),
      prompt_type_(NUM_PROMPT_TYPES),
      ALLOW_THIS_IN_INITIALIZER_LIST(tracker_(this)) {}

void ExtensionInstallUI::ConfirmInstall(Delegate* delegate,
                                        Extension* extension) {
  DCHECK(ui_loop_ == MessageLoop::current());
  extension_ = extension;
  delegate_ = delegate;

  // We special-case themes to not show any confirm UI. Instead they are
  // immediately installed, and then we show an infobar (see OnInstallSuccess)
  // to allow the user to revert if they don't like it.
  if (extension->IsTheme()) {
    // Remember the current theme in case the user pressed undo.
    Extension* previous_theme = profile_->GetTheme();
    if (previous_theme)
      previous_theme_id_ = previous_theme->id();

#if defined(TOOLKIT_GTK)
    // On Linux, we also need to take the user's system settings into account
    // to undo theme installation.
    previous_use_system_theme_ =
        GtkThemeProvider::GetFrom(profile_)->UseGtkTheme();
#else
    DCHECK(!previous_use_system_theme_);
#endif

    delegate->InstallUIProceed(false);
    return;
  }

  ShowConfirmation(INSTALL_PROMPT);
}

void ExtensionInstallUI::ConfirmUninstall(Delegate* delegate,
                                          Extension* extension) {
  DCHECK(ui_loop_ == MessageLoop::current());
  extension_ = extension;
  delegate_ = delegate;

  ShowConfirmation(UNINSTALL_PROMPT);
}

void ExtensionInstallUI::OnInstallSuccess(Extension* extension) {
  if (extension->IsTheme()) {
    ShowThemeInfoBar(previous_theme_id_, previous_use_system_theme_,
                     extension, profile_);
    return;
  }

  if (extension->GetFullLaunchURL().is_valid()) {
    Browser::OpenApplicationTab(profile_, extension);
    return;
  }

  // GetLastActiveWithProfile will fail on the build bots. This needs to be
  // implemented differently if any test is created which depends on
  // ExtensionInstalledBubble showing.
  Browser* browser = BrowserList::GetLastActiveWithProfile(profile_);

#if defined(TOOLKIT_VIEWS)
  if (!browser)
    return;

  ExtensionInstalledBubble::Show(extension, browser, icon_);
#elif defined(OS_MACOSX)
  DCHECK(browser);
  // Note that browser actions don't appear in incognito mode initially,
  // so fall back to the generic case.
  if ((extension->browser_action() && !browser->profile()->IsOffTheRecord()) ||
      (extension->page_action() &&
      !extension->page_action()->default_icon_path().empty())) {
    ExtensionInstalledBubbleCocoa::ShowExtensionInstalledBubble(
        browser->window()->GetNativeHandle(),
        extension, browser, icon_);
  }  else {
    // If the extension is of type GENERIC, meaning it doesn't have a UI
    // surface to display for this window, launch infobar instead of popup
    // bubble, because we have no guaranteed wrench menu button to point to.
    ShowGenericExtensionInstalledInfoBar(extension);
  }
#elif defined(TOOLKIT_GTK)
  if (!browser)
    return;
  ExtensionInstalledBubbleGtk::Show(extension, browser, icon_);
#endif  // TOOLKIT_VIEWS
}

void ExtensionInstallUI::OnInstallFailure(const std::string& error) {
  DCHECK(ui_loop_ == MessageLoop::current());

  Browser* browser = BrowserList::GetLastActiveWithProfile(profile_);
  platform_util::SimpleErrorBox(
      browser ? browser->window()->GetNativeHandle() : NULL,
      l10n_util::GetStringUTF16(IDS_EXTENSION_INSTALL_FAILURE_TITLE),
      UTF8ToUTF16(error));
}

void ExtensionInstallUI::OnOverinstallAttempted(Extension* extension) {
  ShowThemeInfoBar(previous_theme_id_, previous_use_system_theme_,
                   extension, profile_);
}

void ExtensionInstallUI::OnImageLoaded(
    SkBitmap* image, ExtensionResource resource, int index) {
  if (image)
    icon_ = *image;
  else
    icon_ = SkBitmap();
  if (icon_.empty()) {
    icon_ = *ResourceBundle::GetSharedInstance().GetBitmapNamed(
        IDR_EXTENSION_DEFAULT_ICON);
  }

  switch (prompt_type_) {
    case INSTALL_PROMPT: {
      NotificationService* service = NotificationService::current();
      service->Notify(NotificationType::EXTENSION_WILL_SHOW_CONFIRM_DIALOG,
          Source<ExtensionInstallUI>(this),
          NotificationService::NoDetails());

      std::vector<string16> warnings;
      GetV2Warnings(extension_, &warnings);
      ShowExtensionInstallUIPrompt2Impl(
          profile_, delegate_, extension_, &icon_, warnings);
      break;
    }
    case UNINSTALL_PROMPT: {
      string16 message =
          l10n_util::GetStringUTF16(IDS_EXTENSION_UNINSTALL_CONFIRMATION);
      ShowExtensionInstallUIPromptImpl(profile_, delegate_, extension_, &icon_,
          message, UNINSTALL_PROMPT);
      break;
    }
    default:
      NOTREACHED() << "Unknown message";
      break;
  }
}

void ExtensionInstallUI::ShowThemeInfoBar(
    const std::string& previous_theme_id, bool previous_use_system_theme,
    Extension* new_theme, Profile* profile) {
  if (!new_theme->IsTheme())
    return;

  Browser* browser = BrowserList::GetLastActiveWithProfile(profile);
  if (!browser)
    return;

  TabContents* tab_contents = browser->GetSelectedTabContents();
  if (!tab_contents)
    return;

  // First find any previous theme preview infobars.
  InfoBarDelegate* old_delegate = NULL;
  for (int i = 0; i < tab_contents->infobar_delegate_count(); ++i) {
    InfoBarDelegate* delegate = tab_contents->GetInfoBarDelegateAt(i);
    if (delegate->AsThemePreviewInfobarDelegate()) {
      old_delegate = delegate;
      break;
    }
  }

  // Then either replace that old one or add a new one.
  InfoBarDelegate* new_delegate =
      GetNewThemeInstalledInfoBarDelegate(
          tab_contents, new_theme,
          previous_theme_id, previous_use_system_theme);

  if (old_delegate)
    tab_contents->ReplaceInfoBar(old_delegate, new_delegate);
  else
    tab_contents->AddInfoBar(new_delegate);
}

void ExtensionInstallUI::ShowConfirmation(PromptType prompt_type) {
  // Load the image asynchronously. For the response, check OnImageLoaded.
  prompt_type_ = prompt_type;
  ExtensionResource image =
      extension_->GetIconPath(Extension::EXTENSION_ICON_LARGE);
  tracker_.LoadImage(extension_, image,
                     gfx::Size(Extension::EXTENSION_ICON_LARGE,
                               Extension::EXTENSION_ICON_LARGE),
                     ImageLoadingTracker::DONT_CACHE);
}

#if defined(OS_MACOSX)
void ExtensionInstallUI::ShowGenericExtensionInstalledInfoBar(
    Extension* new_extension) {
  Browser* browser = BrowserList::GetLastActiveWithProfile(profile_);
  if (!browser)
    return;

  TabContents* tab_contents = browser->GetSelectedTabContents();
  if (!tab_contents)
    return;

  std::wstring msg = l10n_util::GetStringF(IDS_EXTENSION_INSTALLED_HEADING,
                                           UTF8ToWide(new_extension->name())) +
         L" " + l10n_util::GetString(IDS_EXTENSION_INSTALLED_MANAGE_INFO_MAC);
  InfoBarDelegate* delegate = new SimpleAlertInfoBarDelegate(
      tab_contents, msg, new SkBitmap(icon_), true);
  tab_contents->AddInfoBar(delegate);
}
#endif

InfoBarDelegate* ExtensionInstallUI::GetNewThemeInstalledInfoBarDelegate(
    TabContents* tab_contents, Extension* new_theme,
    const std::string& previous_theme_id, bool previous_use_system_theme) {
#if defined(TOOLKIT_GTK)
  return new GtkThemeInstalledInfoBarDelegate(tab_contents, new_theme,
      previous_theme_id, previous_use_system_theme);
#else
  return new ThemeInstalledInfoBarDelegate(tab_contents, new_theme,
      previous_theme_id);
#endif
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/prerender/prerender_field_trial.h"

#include "base/command_line.h"
#include "base/logging.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "chrome/browser/metrics/metrics_service.h"
#include "chrome/browser/predictors/autocomplete_action_predictor.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/prerender/prerender_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_version_info.h"

using base::FieldTrial;
using base::FieldTrialList;

namespace prerender {

namespace {

const char kOmniboxTrialName[] = "PrerenderFromOmnibox";
int g_omnibox_trial_default_group_number = kint32min;

const char kSpeculativePrefetchingTrialName[] = "SpeculativePrefetching";
int g_speculative_prefetching_learning_group = kint32min;
int g_speculative_prefetching_prefetching_group = kint32min;

const char kLocalPredictorTrialName[] = "PrerenderLocalPredictor";
int g_local_predictor_default_group_number = kint32min;

void SetupPrefetchFieldTrial() {
  chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
  if (channel == chrome::VersionInfo::CHANNEL_STABLE ||
      channel == chrome::VersionInfo::CHANNEL_BETA) {
    return;
  }

  const FieldTrial::Probability divisor = 1000;
  const FieldTrial::Probability prefetch_probability = 500;
  scoped_refptr<FieldTrial> trial(
      FieldTrialList::FactoryGetFieldTrial(
          "Prefetch", divisor, "ContentPrefetchPrefetchOff",
          2013, 6, 30, NULL));
  const int kPrefetchOnGroup = trial->AppendGroup("ContentPrefetchPrefetchOn",
                                                  prefetch_probability);
  PrerenderManager::SetIsPrefetchEnabled(trial->group() == kPrefetchOnGroup);
}

void SetupPrerenderFieldTrial() {
  const FieldTrial::Probability divisor = 1000;

  FieldTrial::Probability control_probability;
  FieldTrial::Probability experiment_multi_prerender_probability;
  FieldTrial::Probability experiment_15min_ttl_probability;
  FieldTrial::Probability experiment_no_use_probability;

  chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
  if (channel == chrome::VersionInfo::CHANNEL_STABLE ||
      channel == chrome::VersionInfo::CHANNEL_BETA) {
    // Use very conservatives and stable settings in beta and stable.
    const FieldTrial::Probability release_prerender_enabled_probability = 980;
    const FieldTrial::Probability release_control_probability = 10;
    const FieldTrial::Probability
        release_experiment_multi_prerender_probability = 0;
    const FieldTrial::Probability release_experiment_15min_ttl_probability = 10;
    const FieldTrial::Probability release_experiment_no_use_probability = 0;
    COMPILE_ASSERT(
        release_prerender_enabled_probability + release_control_probability +
        release_experiment_multi_prerender_probability +
        release_experiment_15min_ttl_probability +
        release_experiment_no_use_probability == divisor,
        release_experiment_probabilities_must_equal_divisor);

    control_probability = release_experiment_15min_ttl_probability;
    experiment_multi_prerender_probability =
        release_experiment_multi_prerender_probability;
    experiment_15min_ttl_probability = release_control_probability;
    experiment_no_use_probability = release_experiment_no_use_probability;
  } else {
    // In testing channels, use more experiments and a larger control group to
    // improve quality of data.
    const FieldTrial::Probability dev_prerender_enabled_probability = 250;
    const FieldTrial::Probability dev_control_probability = 250;
    const FieldTrial::Probability
        dev_experiment_multi_prerender_probability = 250;
    const FieldTrial::Probability dev_experiment_15min_ttl_probability = 125;
    const FieldTrial::Probability dev_experiment_no_use_probability = 125;
    COMPILE_ASSERT(dev_prerender_enabled_probability + dev_control_probability +
                   dev_experiment_multi_prerender_probability +
                   dev_experiment_15min_ttl_probability +
                   dev_experiment_no_use_probability == divisor,
                   dev_experiment_probabilities_must_equal_divisor);

    control_probability = dev_experiment_15min_ttl_probability;
    experiment_multi_prerender_probability =
        dev_experiment_multi_prerender_probability;
    experiment_15min_ttl_probability = dev_control_probability;
    experiment_no_use_probability = dev_experiment_no_use_probability;
  }

  int prerender_enabled_group = -1;
  scoped_refptr<FieldTrial> trial(
      FieldTrialList::FactoryGetFieldTrial(
          "Prerender", divisor, "PrerenderEnabled",
          2013, 6, 30, &prerender_enabled_group));
  const int control_group =
      trial->AppendGroup("PrerenderControl",
                         control_probability);
  const int experiment_multi_prerender_group =
      trial->AppendGroup("PrerenderMulti",
                         experiment_multi_prerender_probability);
  const int experiment_15_min_TTL_group =
      trial->AppendGroup("Prerender15minTTL",
                         experiment_15min_ttl_probability);
  const int experiment_no_use_group =
      trial->AppendGroup("PrerenderNoUse",
                         experiment_no_use_probability);

  const int trial_group = trial->group();
  if (trial_group == prerender_enabled_group) {
    PrerenderManager::SetMode(
        PrerenderManager::PRERENDER_MODE_EXPERIMENT_PRERENDER_GROUP);
  } else if (trial_group == control_group) {
    PrerenderManager::SetMode(
        PrerenderManager::PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP);
  } else if (trial_group == experiment_multi_prerender_group) {
    PrerenderManager::SetMode(
        PrerenderManager::PRERENDER_MODE_EXPERIMENT_MULTI_PRERENDER_GROUP);
  } else if (trial_group == experiment_15_min_TTL_group) {
    PrerenderManager::SetMode(
        PrerenderManager::PRERENDER_MODE_EXPERIMENT_15MIN_TTL_GROUP);
  } else if (trial_group == experiment_no_use_group) {
    PrerenderManager::SetMode(
        PrerenderManager::PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP);
  } else {
    NOTREACHED();
  }
}

}  // end namespace

void ConfigureOmniboxPrerender();
void ConfigureSpeculativePrefetching();
void ConfigureLocalPredictor();

void ConfigurePrefetchAndPrerender(const CommandLine& command_line) {
  enum PrerenderOption {
    PRERENDER_OPTION_AUTO,
    PRERENDER_OPTION_DISABLED,
    PRERENDER_OPTION_ENABLED,
    PRERENDER_OPTION_PREFETCH_ONLY,
  };

  PrerenderOption prerender_option = PRERENDER_OPTION_AUTO;
  if (command_line.HasSwitch(switches::kPrerenderMode)) {
    const std::string switch_value =
        command_line.GetSwitchValueASCII(switches::kPrerenderMode);

    if (switch_value == switches::kPrerenderModeSwitchValueAuto) {
      prerender_option = PRERENDER_OPTION_AUTO;
    } else if (switch_value == switches::kPrerenderModeSwitchValueDisabled) {
      prerender_option = PRERENDER_OPTION_DISABLED;
    } else if (switch_value.empty() ||
               switch_value == switches::kPrerenderModeSwitchValueEnabled) {
      // The empty string means the option was provided with no value, and that
      // means enable.
      prerender_option = PRERENDER_OPTION_ENABLED;
    } else if (switch_value ==
               switches::kPrerenderModeSwitchValuePrefetchOnly) {
      prerender_option = PRERENDER_OPTION_PREFETCH_ONLY;
    } else {
      prerender_option = PRERENDER_OPTION_DISABLED;
      LOG(ERROR) << "Invalid --prerender option received on command line: "
                 << switch_value;
      LOG(ERROR) << "Disabling prerendering!";
    }
  }

  switch (prerender_option) {
    case PRERENDER_OPTION_AUTO:
      SetupPrefetchFieldTrial();
      SetupPrerenderFieldTrial();
      break;
    case PRERENDER_OPTION_DISABLED:
      PrerenderManager::SetIsPrefetchEnabled(false);
      PrerenderManager::SetMode(PrerenderManager::PRERENDER_MODE_DISABLED);
      break;
    case PRERENDER_OPTION_ENABLED:
      PrerenderManager::SetIsPrefetchEnabled(true);
      PrerenderManager::SetMode(PrerenderManager::PRERENDER_MODE_ENABLED);
      break;
    case PRERENDER_OPTION_PREFETCH_ONLY:
      PrerenderManager::SetIsPrefetchEnabled(true);
      PrerenderManager::SetMode(PrerenderManager::PRERENDER_MODE_DISABLED);
      break;
    default:
      NOTREACHED();
  }

  UMA_HISTOGRAM_ENUMERATION("Prerender.Sessions",
                            PrerenderManager::GetMode(),
                            PrerenderManager::PRERENDER_MODE_MAX);

  ConfigureOmniboxPrerender();
  ConfigureSpeculativePrefetching();
  ConfigureLocalPredictor();
}

void ConfigureOmniboxPrerender() {
  // Field trial to see if we're enabled.
  const FieldTrial::Probability kDivisor = 100;

  FieldTrial::Probability kDisabledProbability = 10;
  chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
  if (channel == chrome::VersionInfo::CHANNEL_STABLE ||
      channel == chrome::VersionInfo::CHANNEL_BETA) {
    kDisabledProbability = 1;
  }
  scoped_refptr<FieldTrial> omnibox_prerender_trial(
      FieldTrialList::FactoryGetFieldTrial(
          kOmniboxTrialName, kDivisor, "OmniboxPrerenderEnabled",
          2012, 12, 30, &g_omnibox_trial_default_group_number));
  omnibox_prerender_trial->AppendGroup("OmniboxPrerenderDisabled",
                                       kDisabledProbability);
}

bool IsOmniboxEnabled(Profile* profile) {
  if (!profile)
    return false;

  if (!PrerenderManager::IsPrerenderingPossible())
    return false;

  // Override any field trial groups if the user has set a command line flag.
  if (CommandLine::ForCurrentProcess()->HasSwitch(
      switches::kPrerenderFromOmnibox)) {
    const std::string switch_value =
        CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
            switches::kPrerenderFromOmnibox);

    if (switch_value == switches::kPrerenderFromOmniboxSwitchValueEnabled)
      return true;

    if (switch_value == switches::kPrerenderFromOmniboxSwitchValueDisabled)
      return false;

    DCHECK(switch_value == switches::kPrerenderFromOmniboxSwitchValueAuto);
  }

  const int group = FieldTrialList::FindValue(kOmniboxTrialName);
  return group == FieldTrial::kNotFinalized ||
         group == g_omnibox_trial_default_group_number;
}

void ConfigureSpeculativePrefetching() {
  // Field trial to see if we're enabled.
  const FieldTrial::Probability kDivisor = 100;

  FieldTrial::Probability kLearningProbability = 0;
  FieldTrial::Probability kPrefetchingProbability = 0;

  chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
  switch (channel) {
    case chrome::VersionInfo::CHANNEL_CANARY:
    case chrome::VersionInfo::CHANNEL_DEV:
      kLearningProbability = 90;
      kPrefetchingProbability = 1;
      break;

    case chrome::VersionInfo::CHANNEL_BETA:
      kLearningProbability = 5;
      break;

    case chrome::VersionInfo::CHANNEL_STABLE:
    case chrome::VersionInfo::CHANNEL_UNKNOWN:
      break;
  }

  scoped_refptr<FieldTrial> speculative_prefetching_trial(
      FieldTrialList::FactoryGetFieldTrial(
          kSpeculativePrefetchingTrialName,
          kDivisor,
          "Disabled",
          2012, 12, 30,
          NULL));

  if (kLearningProbability > 0) {
    g_speculative_prefetching_learning_group =
        speculative_prefetching_trial->AppendGroup("Learning",
                                                   kLearningProbability);
  }
  if (kPrefetchingProbability > 0) {
    g_speculative_prefetching_prefetching_group =
        speculative_prefetching_trial->AppendGroup("Prefetching",
                                                   kPrefetchingProbability);
  }
}

bool IsSpeculativeResourcePrefetchingLearningEnabled(Profile* profile) {
  if (!profile || profile->IsOffTheRecord())
    return false;

  // Override any field trial groups if the user has set a command line flag.
  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kSpeculativeResourcePrefetching)) {
    const std::string switch_value =
        CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
            switches::kSpeculativeResourcePrefetching);

    return switch_value == switches::kSpeculativeResourcePrefetchingLearning;
  }

  const int group = FieldTrialList::FindValue(
      kSpeculativePrefetchingTrialName);
  return group == g_speculative_prefetching_learning_group;
}

bool IsSpeculativeResourcePrefetchingEnabled(Profile* profile) {
  if (!profile)
    return false;

  // Check if the user has set a command line flag.
  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kSpeculativeResourcePrefetching)) {
    const std::string switch_value =
        CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
            switches::kSpeculativeResourcePrefetching);
    return switch_value == switches::kSpeculativeResourcePrefetchingEnabled;
  }

  const int group = FieldTrialList::FindValue(
      kSpeculativePrefetchingTrialName);
  return group == g_speculative_prefetching_prefetching_group;
}

void ConfigureLocalPredictor() {
  const FieldTrial::Probability kDivisor = 100;

  FieldTrial::Probability kEnableProbability = 90;
  chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
  if (channel == chrome::VersionInfo::CHANNEL_STABLE ||
      channel == chrome::VersionInfo::CHANNEL_BETA) {
    kEnableProbability = 1;
  }
  scoped_refptr<FieldTrial> local_predictor_trial(
      FieldTrialList::FactoryGetFieldTrial(
          kLocalPredictorTrialName, kDivisor, "Disabled",
          2013, 12, 31, &g_local_predictor_default_group_number));
  local_predictor_trial->AppendGroup("Enabled", kEnableProbability);
}

bool IsLocalPredictorEnabled() {
  const int group = FieldTrialList::FindValue(kLocalPredictorTrialName);
  return (group != FieldTrial::kNotFinalized &&
          group != g_omnibox_trial_default_group_number);
}

}  // namespace prerender
<commit_msg>Remove Prerender.Sessions histogram, which was just making sure the field trials groups were being set up correctly.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/prerender/prerender_field_trial.h"

#include "base/command_line.h"
#include "base/logging.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "chrome/browser/metrics/metrics_service.h"
#include "chrome/browser/predictors/autocomplete_action_predictor.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/prerender/prerender_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_version_info.h"

using base::FieldTrial;
using base::FieldTrialList;

namespace prerender {

namespace {

const char kOmniboxTrialName[] = "PrerenderFromOmnibox";
int g_omnibox_trial_default_group_number = kint32min;

const char kSpeculativePrefetchingTrialName[] = "SpeculativePrefetching";
int g_speculative_prefetching_learning_group = kint32min;
int g_speculative_prefetching_prefetching_group = kint32min;

const char kLocalPredictorTrialName[] = "PrerenderLocalPredictor";
int g_local_predictor_default_group_number = kint32min;

void SetupPrefetchFieldTrial() {
  chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
  if (channel == chrome::VersionInfo::CHANNEL_STABLE ||
      channel == chrome::VersionInfo::CHANNEL_BETA) {
    return;
  }

  const FieldTrial::Probability divisor = 1000;
  const FieldTrial::Probability prefetch_probability = 500;
  scoped_refptr<FieldTrial> trial(
      FieldTrialList::FactoryGetFieldTrial(
          "Prefetch", divisor, "ContentPrefetchPrefetchOff",
          2013, 6, 30, NULL));
  const int kPrefetchOnGroup = trial->AppendGroup("ContentPrefetchPrefetchOn",
                                                  prefetch_probability);
  PrerenderManager::SetIsPrefetchEnabled(trial->group() == kPrefetchOnGroup);
}

void SetupPrerenderFieldTrial() {
  const FieldTrial::Probability divisor = 1000;

  FieldTrial::Probability control_probability;
  FieldTrial::Probability experiment_multi_prerender_probability;
  FieldTrial::Probability experiment_15min_ttl_probability;
  FieldTrial::Probability experiment_no_use_probability;

  chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
  if (channel == chrome::VersionInfo::CHANNEL_STABLE ||
      channel == chrome::VersionInfo::CHANNEL_BETA) {
    // Use very conservatives and stable settings in beta and stable.
    const FieldTrial::Probability release_prerender_enabled_probability = 980;
    const FieldTrial::Probability release_control_probability = 10;
    const FieldTrial::Probability
        release_experiment_multi_prerender_probability = 0;
    const FieldTrial::Probability release_experiment_15min_ttl_probability = 10;
    const FieldTrial::Probability release_experiment_no_use_probability = 0;
    COMPILE_ASSERT(
        release_prerender_enabled_probability + release_control_probability +
        release_experiment_multi_prerender_probability +
        release_experiment_15min_ttl_probability +
        release_experiment_no_use_probability == divisor,
        release_experiment_probabilities_must_equal_divisor);

    control_probability = release_experiment_15min_ttl_probability;
    experiment_multi_prerender_probability =
        release_experiment_multi_prerender_probability;
    experiment_15min_ttl_probability = release_control_probability;
    experiment_no_use_probability = release_experiment_no_use_probability;
  } else {
    // In testing channels, use more experiments and a larger control group to
    // improve quality of data.
    const FieldTrial::Probability dev_prerender_enabled_probability = 250;
    const FieldTrial::Probability dev_control_probability = 250;
    const FieldTrial::Probability
        dev_experiment_multi_prerender_probability = 250;
    const FieldTrial::Probability dev_experiment_15min_ttl_probability = 125;
    const FieldTrial::Probability dev_experiment_no_use_probability = 125;
    COMPILE_ASSERT(dev_prerender_enabled_probability + dev_control_probability +
                   dev_experiment_multi_prerender_probability +
                   dev_experiment_15min_ttl_probability +
                   dev_experiment_no_use_probability == divisor,
                   dev_experiment_probabilities_must_equal_divisor);

    control_probability = dev_experiment_15min_ttl_probability;
    experiment_multi_prerender_probability =
        dev_experiment_multi_prerender_probability;
    experiment_15min_ttl_probability = dev_control_probability;
    experiment_no_use_probability = dev_experiment_no_use_probability;
  }

  int prerender_enabled_group = -1;
  scoped_refptr<FieldTrial> trial(
      FieldTrialList::FactoryGetFieldTrial(
          "Prerender", divisor, "PrerenderEnabled",
          2013, 6, 30, &prerender_enabled_group));
  const int control_group =
      trial->AppendGroup("PrerenderControl",
                         control_probability);
  const int experiment_multi_prerender_group =
      trial->AppendGroup("PrerenderMulti",
                         experiment_multi_prerender_probability);
  const int experiment_15_min_TTL_group =
      trial->AppendGroup("Prerender15minTTL",
                         experiment_15min_ttl_probability);
  const int experiment_no_use_group =
      trial->AppendGroup("PrerenderNoUse",
                         experiment_no_use_probability);

  const int trial_group = trial->group();
  if (trial_group == prerender_enabled_group) {
    PrerenderManager::SetMode(
        PrerenderManager::PRERENDER_MODE_EXPERIMENT_PRERENDER_GROUP);
  } else if (trial_group == control_group) {
    PrerenderManager::SetMode(
        PrerenderManager::PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP);
  } else if (trial_group == experiment_multi_prerender_group) {
    PrerenderManager::SetMode(
        PrerenderManager::PRERENDER_MODE_EXPERIMENT_MULTI_PRERENDER_GROUP);
  } else if (trial_group == experiment_15_min_TTL_group) {
    PrerenderManager::SetMode(
        PrerenderManager::PRERENDER_MODE_EXPERIMENT_15MIN_TTL_GROUP);
  } else if (trial_group == experiment_no_use_group) {
    PrerenderManager::SetMode(
        PrerenderManager::PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP);
  } else {
    NOTREACHED();
  }
}

}  // end namespace

void ConfigureOmniboxPrerender();
void ConfigureSpeculativePrefetching();
void ConfigureLocalPredictor();

void ConfigurePrefetchAndPrerender(const CommandLine& command_line) {
  enum PrerenderOption {
    PRERENDER_OPTION_AUTO,
    PRERENDER_OPTION_DISABLED,
    PRERENDER_OPTION_ENABLED,
    PRERENDER_OPTION_PREFETCH_ONLY,
  };

  PrerenderOption prerender_option = PRERENDER_OPTION_AUTO;
  if (command_line.HasSwitch(switches::kPrerenderMode)) {
    const std::string switch_value =
        command_line.GetSwitchValueASCII(switches::kPrerenderMode);

    if (switch_value == switches::kPrerenderModeSwitchValueAuto) {
      prerender_option = PRERENDER_OPTION_AUTO;
    } else if (switch_value == switches::kPrerenderModeSwitchValueDisabled) {
      prerender_option = PRERENDER_OPTION_DISABLED;
    } else if (switch_value.empty() ||
               switch_value == switches::kPrerenderModeSwitchValueEnabled) {
      // The empty string means the option was provided with no value, and that
      // means enable.
      prerender_option = PRERENDER_OPTION_ENABLED;
    } else if (switch_value ==
               switches::kPrerenderModeSwitchValuePrefetchOnly) {
      prerender_option = PRERENDER_OPTION_PREFETCH_ONLY;
    } else {
      prerender_option = PRERENDER_OPTION_DISABLED;
      LOG(ERROR) << "Invalid --prerender option received on command line: "
                 << switch_value;
      LOG(ERROR) << "Disabling prerendering!";
    }
  }

  switch (prerender_option) {
    case PRERENDER_OPTION_AUTO:
      SetupPrefetchFieldTrial();
      SetupPrerenderFieldTrial();
      break;
    case PRERENDER_OPTION_DISABLED:
      PrerenderManager::SetIsPrefetchEnabled(false);
      PrerenderManager::SetMode(PrerenderManager::PRERENDER_MODE_DISABLED);
      break;
    case PRERENDER_OPTION_ENABLED:
      PrerenderManager::SetIsPrefetchEnabled(true);
      PrerenderManager::SetMode(PrerenderManager::PRERENDER_MODE_ENABLED);
      break;
    case PRERENDER_OPTION_PREFETCH_ONLY:
      PrerenderManager::SetIsPrefetchEnabled(true);
      PrerenderManager::SetMode(PrerenderManager::PRERENDER_MODE_DISABLED);
      break;
    default:
      NOTREACHED();
  }

  ConfigureOmniboxPrerender();
  ConfigureSpeculativePrefetching();
  ConfigureLocalPredictor();
}

void ConfigureOmniboxPrerender() {
  // Field trial to see if we're enabled.
  const FieldTrial::Probability kDivisor = 100;

  FieldTrial::Probability kDisabledProbability = 10;
  chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
  if (channel == chrome::VersionInfo::CHANNEL_STABLE ||
      channel == chrome::VersionInfo::CHANNEL_BETA) {
    kDisabledProbability = 1;
  }
  scoped_refptr<FieldTrial> omnibox_prerender_trial(
      FieldTrialList::FactoryGetFieldTrial(
          kOmniboxTrialName, kDivisor, "OmniboxPrerenderEnabled",
          2012, 12, 30, &g_omnibox_trial_default_group_number));
  omnibox_prerender_trial->AppendGroup("OmniboxPrerenderDisabled",
                                       kDisabledProbability);
}

bool IsOmniboxEnabled(Profile* profile) {
  if (!profile)
    return false;

  if (!PrerenderManager::IsPrerenderingPossible())
    return false;

  // Override any field trial groups if the user has set a command line flag.
  if (CommandLine::ForCurrentProcess()->HasSwitch(
      switches::kPrerenderFromOmnibox)) {
    const std::string switch_value =
        CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
            switches::kPrerenderFromOmnibox);

    if (switch_value == switches::kPrerenderFromOmniboxSwitchValueEnabled)
      return true;

    if (switch_value == switches::kPrerenderFromOmniboxSwitchValueDisabled)
      return false;

    DCHECK(switch_value == switches::kPrerenderFromOmniboxSwitchValueAuto);
  }

  const int group = FieldTrialList::FindValue(kOmniboxTrialName);
  return group == FieldTrial::kNotFinalized ||
         group == g_omnibox_trial_default_group_number;
}

void ConfigureSpeculativePrefetching() {
  // Field trial to see if we're enabled.
  const FieldTrial::Probability kDivisor = 100;

  FieldTrial::Probability kLearningProbability = 0;
  FieldTrial::Probability kPrefetchingProbability = 0;

  chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
  switch (channel) {
    case chrome::VersionInfo::CHANNEL_CANARY:
    case chrome::VersionInfo::CHANNEL_DEV:
      kLearningProbability = 90;
      kPrefetchingProbability = 1;
      break;

    case chrome::VersionInfo::CHANNEL_BETA:
      kLearningProbability = 5;
      break;

    case chrome::VersionInfo::CHANNEL_STABLE:
    case chrome::VersionInfo::CHANNEL_UNKNOWN:
      break;
  }

  scoped_refptr<FieldTrial> speculative_prefetching_trial(
      FieldTrialList::FactoryGetFieldTrial(
          kSpeculativePrefetchingTrialName,
          kDivisor,
          "Disabled",
          2012, 12, 30,
          NULL));

  if (kLearningProbability > 0) {
    g_speculative_prefetching_learning_group =
        speculative_prefetching_trial->AppendGroup("Learning",
                                                   kLearningProbability);
  }
  if (kPrefetchingProbability > 0) {
    g_speculative_prefetching_prefetching_group =
        speculative_prefetching_trial->AppendGroup("Prefetching",
                                                   kPrefetchingProbability);
  }
}

bool IsSpeculativeResourcePrefetchingLearningEnabled(Profile* profile) {
  if (!profile || profile->IsOffTheRecord())
    return false;

  // Override any field trial groups if the user has set a command line flag.
  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kSpeculativeResourcePrefetching)) {
    const std::string switch_value =
        CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
            switches::kSpeculativeResourcePrefetching);

    return switch_value == switches::kSpeculativeResourcePrefetchingLearning;
  }

  const int group = FieldTrialList::FindValue(
      kSpeculativePrefetchingTrialName);
  return group == g_speculative_prefetching_learning_group;
}

bool IsSpeculativeResourcePrefetchingEnabled(Profile* profile) {
  if (!profile)
    return false;

  // Check if the user has set a command line flag.
  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kSpeculativeResourcePrefetching)) {
    const std::string switch_value =
        CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
            switches::kSpeculativeResourcePrefetching);
    return switch_value == switches::kSpeculativeResourcePrefetchingEnabled;
  }

  const int group = FieldTrialList::FindValue(
      kSpeculativePrefetchingTrialName);
  return group == g_speculative_prefetching_prefetching_group;
}

void ConfigureLocalPredictor() {
  const FieldTrial::Probability kDivisor = 100;

  FieldTrial::Probability kEnableProbability = 90;
  chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
  if (channel == chrome::VersionInfo::CHANNEL_STABLE ||
      channel == chrome::VersionInfo::CHANNEL_BETA) {
    kEnableProbability = 1;
  }
  scoped_refptr<FieldTrial> local_predictor_trial(
      FieldTrialList::FactoryGetFieldTrial(
          kLocalPredictorTrialName, kDivisor, "Disabled",
          2013, 12, 31, &g_local_predictor_default_group_number));
  local_predictor_trial->AppendGroup("Enabled", kEnableProbability);
}

bool IsLocalPredictorEnabled() {
  const int group = FieldTrialList::FindValue(kLocalPredictorTrialName);
  return (group != FieldTrial::kNotFinalized &&
          group != g_omnibox_trial_default_group_number);
}

}  // namespace prerender
<|endoftext|>


<commit_before>#include <string.h>

#include "serial/ASIOSerialPort.h"
#include <iostream>
#include "actuators/motors/OSMC_driver/OSMC_driver.hpp"
#include <time.h>

using namespace std;

ASIOSerialPort arduinoLeft("/dev/igvc_2012_left_motor_shield", 9600);
ASIOSerialPort arduinoRight("/dev/igvc_2012_right_motor_shield", 9600);
ASIOSerialPort arduinoEncoder("/dev/igvc_2012_right_encoder_shield", 9600);

OSMC_driver::~OSMC_driver()
{
	stopMotors();
	arduinoRight.close();
	arduinoLeft.close();
	arduinoEncoder.close();
}

//Checks we are connected and able to send and receive data from the arduinos
bool OSMC_driver::arduinoCheck()
{
	std::cout << "Testing serial API..." << std::endl;
	arduinoLeft.write("T");
	arduinoRight.write("T");
	sleep(0.01);
	if (arduinoRight.readln() == "T" and arduinoLeft.readln() == "T")
	{
		std::cout<<"Successfully read from Arduinos" << std::endl;
		return true;
	}
	else
	{
		std::cout<<"Failed to read from Arduinos"<<std::endl;
		arduinoLeft.close();
		arduinoRight.close();
		return false;
	}
}

//writes pwm to arduinos setting both motors to the same pwm and direction (0 = forwards, 1 = backwards)
void OSMC_driver::setPwm(char pwm, Direction dir)
{
    if(dir==FORWARD)
    {
        setRightLeftPwm(pwm, 0, pwm, 0);
    }
    else if(dir==BACKWARD)
    {

    }
    else
    {
        cout<<"Bad Direction"<<endl;
    }
}

// Writes to arduinos a string of ints dirRight, pwmRight, dirLeft, pwmLeft.
void OSMC_driver::setRightLeftPwm(char pwmRight, char dirRight, char pwmLeft, char dirLeft)
{
    pwmRight = adjustSpeedRight(pwmRight, dirRight);
    dirLeft = adjustDirLeft(dirLeft);
    pwmLeft = adjustSpeedLeft(pwmLeft, dirLeft);
    string w = "SW";
    w.append(intToString(dirRight));
    w.append(" ");
    w.append(intToString(pwmRight));
    w.append(" ");
    w.append(intToString(dirLeft));
    w.append(" ");
    w.append(intToString(pwmLeft));
    arduinoRight.write(w);
    string w1 = "SW";
    w1.append(intToString(dirLeft));
    w1.append(" ");
    w1.append(intToString(pwmLeft));
    w1.append(" ");
    w1.append(intToString(dirRight));
    w1.append(" ");
    w1.append(intToString(pwmRight));
    arduinoLeft.write(w1);
}

//adjusts the pwm of the right motors based on the direction
char OSMC_driver::adjustSpeedRight(char pwm, char dir)
{
    if (dir == 1)
    {
        pwm = 255-pwm;
    }
    if (dir == 0)
    {
        pwm = pwm;
    }
    return (pwm);
}

//adjusts the pwm of the left motors based on the direction
char OSMC_driver::adjustSpeedLeft(char pwm, char dir)
{
    if (dir == 1)
    {
        pwm = 255-pwm;
    }
    if (dir == 0)
    {
        pwm = pwm;
    }
    return (pwm);
}

//adjusts the direction of the left motors because they are mirrors of the right motors
char OSMC_driver::adjustDirLeft(char dirLeft)
{
    dirLeft = 1-dirLeft;
    return (dirLeft);
}

//turn the robot at a pwm around a circle of a certain radius with a direction
void OSMC_driver::turn(double radius, int pwm, Direction dir)    //dir = 0 Right  dir = 1 Left
{
    double v1 = 0;
    double v2 = 0;
    double halfWB = WHEELBASE/2;
    double comp1 = (radius+halfWB)/(radius-halfWB);
    v2 = (2*pwm*comp1)/(1+comp1);
    v1 = 2*pwm-v2;
    if (dir == RIGHT)
    {
        setRightLeftPwm(v1, 0, v2, 0);
    }
    else if(dir == LEFT)
    {
        setRightLeftPwm(v2, 0, v1, 0);
    }
    else
    {
        cout<<"Bad direction"<<endl;
    }

}

//Used in writing integers to the arduinos as strings
string OSMC_driver::intToString(int input)
{
    std::ostringstream s;
    s << input;
    return s.str();
}

//Used in writing doubles to the arduinos as strings
string OSMC_driver::doubleToString(double input)
{
    std::ostringstream s;
    s << input;
    return s.str();
}

/*
//Go forward a set distance at a set speed in a certain direction
void OSMC_driver::forward(char pwm, char dir, double dist)
{
    setPwm(pwm, dir)
    string d = " ";
    d.append(doubleToString(dist));
    arduino.write(d);
    //TODO event listener for a ! from arduino
    //while(arduino.readln() != "!") {};
}

void OSMC_driver::turn(double radius, double degree, int pwm, char dir)    //dir = 0 Right  dir = 1 Left
{
    double v1 = 0;
    double v2 = 0;
    double halfWB = WHEELBASE/2;
    double comp1 = (radius+halfWB)/(radius-halfWB);
    v2 = (2*pwm*comp1)/(1+comp1);
    v1 = 2*pwm-v2;
    if (dir == 0)
    {
        setRightLeftPwm(v1, 0, v2, 0);
    }
    else if(dir == 1)
    {
        setRightLeftPwm(v2, 0, v1, 0);
    }
    else
    {
        cout<<"Bad direction"<<endl;
    }
    string r = "SR";
    r.append(doubleToString(degree))
    arduino.write(r);
}
*/

//Dont quite work at the moment
//functions for reading encoder data from the arduinos and moving a set distance
/*
double OSMC_driver::readEncoder()
{
    string r = "R";
    arduinoEncoder.write("R");
    sleep(0.1);
    std::string dist1 = arduinoEncoder.readln();
    double dist = ::atof(dist1.c_str());
    return dist;
}

void OSMC_driver::encoderLoop(double totalDist)
{
    double dist = readEncoder();
    while (dist<totalDist)
    {
        dist = readEncoder();
        cout<<dist<<endl;
        sleep(0.05);
    }
    cout<<"Dropped Loop"<<endl;
    stopMotors();
}

void OSMC_driver::goForwardOld(double totalDist, char pwm, char dir)
{
    string f = "F";
    arduinoEncoder.write(f);
    sleep(1);
    string var;
    var = "";
    var = arduinoEncoder.readln();
    setRightLeftPwm(pwm, dir, pwm, dir);
    encoderLoop(totalDist);
}
*/

//Stops the motors
void OSMC_driver::stopMotors()
{
    setRightLeftPwm(0,1,0,1);
}

<commit_msg>working on enums<commit_after>#include <string.h>

#include "serial/ASIOSerialPort.h"
#include <iostream>
#include "actuators/motors/OSMC_driver/OSMC_driver.hpp"
#include <time.h>

using namespace std;

ASIOSerialPort arduinoLeft("/dev/igvc_2012_left_motor_shield", 9600);
ASIOSerialPort arduinoRight("/dev/igvc_2012_right_motor_shield", 9600);
ASIOSerialPort arduinoEncoder("/dev/igvc_2012_right_encoder_shield", 9600);

OSMC_driver::~OSMC_driver()
{
	stopMotors();
	arduinoRight.close();
	arduinoLeft.close();
	arduinoEncoder.close();
}

//Checks we are connected and able to send and receive data from the arduinos
bool OSMC_driver::arduinoCheck()
{
	std::cout << "Testing serial API..." << std::endl;
	arduinoLeft.write("T");
	arduinoRight.write("T");
	sleep(0.01);
	if (arduinoRight.readln() == "T" and arduinoLeft.readln() == "T")
	{
		std::cout<<"Successfully read from Arduinos" << std::endl;
		return true;
	}
	else
	{
		std::cout<<"Failed to read from Arduinos"<<std::endl;
		arduinoLeft.close();
		arduinoRight.close();
		return false;
	}
}

//writes pwm to arduinos setting both motors to the same pwm and direction (0 = forwards, 1 = backwards)
void OSMC_driver::setPwm(char pwm, char dir)
{
    /*
    if(dir==FORWARD)
    {
        setRightLeftPwm(pwm, 0, pwm, 0);
    }
    else if(dir==BACKWARD)
    {

    }
    else
    {
        cout<<"Bad Direction"<<endl;
    }
    */
    setRightLeftPwm(pwm,dir,pwm,dir);
}

// Writes to arduinos a string of ints dirRight, pwmRight, dirLeft, pwmLeft.
void OSMC_driver::setRightLeftPwm(char pwmRight, char dirRight, char pwmLeft, char dirLeft)
{
    pwmRight = adjustSpeedRight(pwmRight, dirRight);
    dirLeft = adjustDirLeft(dirLeft);
    pwmLeft = adjustSpeedLeft(pwmLeft, dirLeft);
    string w = "SW";
    w.append(intToString(dirRight));
    w.append(" ");
    w.append(intToString(pwmRight));
    w.append(" ");
    w.append(intToString(dirLeft));
    w.append(" ");
    w.append(intToString(pwmLeft));
    arduinoRight.write(w);
    string w1 = "SW";
    w1.append(intToString(dirLeft));
    w1.append(" ");
    w1.append(intToString(pwmLeft));
    w1.append(" ");
    w1.append(intToString(dirRight));
    w1.append(" ");
    w1.append(intToString(pwmRight));
    arduinoLeft.write(w1);
}

//adjusts the pwm of the right motors based on the direction
char OSMC_driver::adjustSpeedRight(char pwm, char dir)
{
    if (dir == 1)
    {
        pwm = 255-pwm;
    }
    if (dir == 0)
    {
        pwm = pwm;
    }
    return (pwm);
}

//adjusts the pwm of the left motors based on the direction
char OSMC_driver::adjustSpeedLeft(char pwm, char dir)
{
    if (dir == 1)
    {
        pwm = 255-pwm;
    }
    if (dir == 0)
    {
        pwm = pwm;
    }
    return (pwm);
}

//adjusts the direction of the left motors because they are mirrors of the right motors
char OSMC_driver::adjustDirLeft(char dirLeft)
{
    dirLeft = 1-dirLeft;
    return (dirLeft);
}

//turn the robot at a pwm around a circle of a certain radius with a direction
void OSMC_driver::turn(double radius, int pwm, Direction dir)    //dir = 0 Right  dir = 1 Left
{
    double v1 = 0;
    double v2 = 0;
    double halfWB = WHEELBASE/2;
    double comp1 = (radius+halfWB)/(radius-halfWB);
    v2 = (2*pwm*comp1)/(1+comp1);
    v1 = 2*pwm-v2;
    if (dir == RIGHT)
    {
        setRightLeftPwm(v1, 0, v2, 0);
    }
    else if(dir == LEFT)
    {
        setRightLeftPwm(v2, 0, v1, 0);
    }
    else
    {
        cout<<"Bad direction"<<endl;
    }

}

//Used in writing integers to the arduinos as strings
string OSMC_driver::intToString(int input)
{
    std::ostringstream s;
    s << input;
    return s.str();
}

//Used in writing doubles to the arduinos as strings
string OSMC_driver::doubleToString(double input)
{
    std::ostringstream s;
    s << input;
    return s.str();
}

/*
//Go forward a set distance at a set speed in a certain direction
void OSMC_driver::forward(char pwm, char dir, double dist)
{
    setPwm(pwm, dir)
    string d = " ";
    d.append(doubleToString(dist));
    arduino.write(d);
    //TODO event listener for a ! from arduino
    //while(arduino.readln() != "!") {};
}

void OSMC_driver::turn(double radius, double degree, int pwm, char dir)    //dir = 0 Right  dir = 1 Left
{
    double v1 = 0;
    double v2 = 0;
    double halfWB = WHEELBASE/2;
    double comp1 = (radius+halfWB)/(radius-halfWB);
    v2 = (2*pwm*comp1)/(1+comp1);
    v1 = 2*pwm-v2;
    if (dir == 0)
    {
        setRightLeftPwm(v1, 0, v2, 0);
    }
    else if(dir == 1)
    {
        setRightLeftPwm(v2, 0, v1, 0);
    }
    else
    {
        cout<<"Bad direction"<<endl;
    }
    string r = "SR";
    r.append(doubleToString(degree))
    arduino.write(r);
}
*/

//Dont quite work at the moment
//functions for reading encoder data from the arduinos and moving a set distance
/*
double OSMC_driver::readEncoder()
{
    string r = "R";
    arduinoEncoder.write("R");
    sleep(0.1);
    std::string dist1 = arduinoEncoder.readln();
    double dist = ::atof(dist1.c_str());
    return dist;
}

void OSMC_driver::encoderLoop(double totalDist)
{
    double dist = readEncoder();
    while (dist<totalDist)
    {
        dist = readEncoder();
        cout<<dist<<endl;
        sleep(0.05);
    }
    cout<<"Dropped Loop"<<endl;
    stopMotors();
}

void OSMC_driver::goForwardOld(double totalDist, char pwm, char dir)
{
    string f = "F";
    arduinoEncoder.write(f);
    sleep(1);
    string var;
    var = "";
    var = arduinoEncoder.readln();
    setRightLeftPwm(pwm, dir, pwm, dir);
    encoderLoop(totalDist);
}
*/

//Stops the motors
void OSMC_driver::stopMotors()
{
    setRightLeftPwm(0,1,0,1);
}

<|endoftext|>