<commit_before>// Copyright (c) 2009 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 <algorithm>

#include "app/menus/simple_menu_model.h"
#include "app/theme_provider.h"
#include "base/command_line.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/chromeos/compact_location_bar.h"
#include "chrome/browser/chromeos/compact_navigation_bar.h"
#include "chrome/browser/chromeos/main_menu.h"
#include "chrome/browser/chromeos/status_area_view.h"
#include "chrome/browser/chromeos/panel_controller.h"
#include "chrome/browser/views/frame/browser_extender.h"
#include "chrome/browser/views/frame/browser_frame_gtk.h"
#include "chrome/browser/views/frame/browser_view.h"
#include "chrome/browser/views/tabs/tab_overview_types.h"
#include "chrome/browser/views/tabs/tab_strip.h"
#include "chrome/browser/views/toolbar_view.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/x11_util.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "views/controls/button/button.h"
#include "views/controls/button/image_button.h"
#include "views/controls/menu/menu_2.h"
#include "views/window/window.h"

namespace {

const char* kChromeOsWindowManagerName = "chromeos-wm";

// NormalExtender adds ChromeOS specific controls and menus to a BrowserView
// created with Browser::TYPE_NORMAL. This extender adds controls to
// the title bar as follows:
//                  ____  __ __
//      [MainMenu] /    \   \  \     [StatusArea]
//
// and adds the system context menu to the remaining arae of the titlebar.
//
// For Browser::TYPE_POPUP type of BrowserView, see PopupExtender class below.
class NormalExtender : public BrowserExtender,
                       public views::ButtonListener,
                       public views::ContextMenuController {
 public:
  explicit NormalExtender(BrowserView* browser_view)
      : BrowserExtender(browser_view),
        main_menu_(NULL),
        status_area_(NULL),
        compact_navigation_bar_(NULL),
        // CompactNavigationBar is disabled by default.
        // TODO(oshima): Get this info from preference.
        compact_navigation_bar_enabled_(false),
        force_maximized_window_(false) {
  }
  virtual ~NormalExtender() {}

 protected:
  // BrowserExtender overrides.
  virtual void Init() {
    main_menu_ = new views::ImageButton(this);
    ThemeProvider* theme_provider =
        browser_view()->frame()->GetThemeProviderForFrame();
    SkBitmap* image = theme_provider->GetBitmapNamed(IDR_MAIN_MENU_BUTTON);
    main_menu_->SetImage(views::CustomButton::BS_NORMAL, image);
    main_menu_->SetImage(views::CustomButton::BS_HOT, image);
    main_menu_->SetImage(views::CustomButton::BS_PUSHED, image);
    browser_view()->AddChildView(main_menu_);

    Browser* browser = browser_view()->browser();
    compact_location_bar_.reset(
        new chromeos::CompactLocationBar(browser_view()));
    compact_navigation_bar_ = new chromeos::CompactNavigationBar(browser);
    browser_view()->AddChildView(compact_navigation_bar_);
    compact_navigation_bar_->Init();
    status_area_ = new chromeos::StatusAreaView(
        browser,
        browser_view()->GetWindow()->GetNativeWindow());
    browser_view()->AddChildView(status_area_);
    status_area_->Init();

    InitSystemMenu();
    chromeos::MainMenu::ScheduleCreation();

    // The ContextMenuController has to be set to a NonClientView but
    // not to a NonClientFrameView because a TabStrip is not a child of
    // a NonClientFrameView even though visually a TabStrip is over a
    // NonClientFrameView.
    BrowserFrameGtk* gtk_frame =
        static_cast<BrowserFrameGtk*>(browser_view()->frame());
    gtk_frame->GetNonClientView()->SetContextMenuController(this);

    if (browser->type() == Browser::TYPE_NORMAL) {
      std::string wm_name;
      bool wm_name_valid = x11_util::GetWindowManagerName(&wm_name);
      // NOTE: On Chrome OS the wm and Chrome are started in parallel. This
      // means it's possible for us not to be able to get the name of the window
      // manager. We assume that when this happens we're on Chrome OS.
      force_maximized_window_ = (!wm_name_valid ||
                                 wm_name == kChromeOsWindowManagerName ||
                                 CommandLine::ForCurrentProcess()->HasSwitch(
                                     switches::kChromeosFrame));
    }
  }

  virtual gfx::Rect Layout(const gfx::Rect& bounds) {
    // Skip if there is no space to layout, or if the browser is in
    // fullscreen mode.
    if (bounds.IsEmpty() || browser_view()->IsFullscreen()) {
      main_menu_->SetVisible(false);
      compact_navigation_bar_->SetVisible(false);
      status_area_->SetVisible(false);
      return bounds;
    } else {
      main_menu_->SetVisible(true);
      compact_navigation_bar_->SetVisible(compact_navigation_bar_enabled_);
      status_area_->SetVisible(true);
    }

    /* TODO(oshima):
     * Disabling the ability to update location bar on re-layout bacause
     * tabstrip state may not be in sync with the browser's state when
     * new tab is added. We should decide when we know more about this
     * feature. May be we should simply hide the location?
     * Filed a bug: http://crbug.com/30612.
    if (compact_navigation_bar_->IsVisible()) {
      // Update the size and location of the compact location bar.
      compact_location_bar_->UpdateBounds(
          browser_view()->tabstrip()->GetSelectedTab());
    }
    */

    // Layout main menu before tab strip.
    gfx::Size main_menu_size = main_menu_->GetPreferredSize();
    main_menu_->SetBounds(bounds.x(), bounds.y(),
                          main_menu_size.width(), bounds.height());

    // Layout status area after tab strip.
    gfx::Size status_size = status_area_->GetPreferredSize();
    status_area_->SetBounds(bounds.x() + bounds.width() - status_size.width(),
                            bounds.y(), status_size.width(),
                            status_size.height());
    int curx = bounds.x() + main_menu_size.width();
    int width = bounds.width() - main_menu_size.width() - status_size.width();

    if (compact_navigation_bar_->IsVisible()) {
      gfx::Size cnb_bounds = compact_navigation_bar_->GetPreferredSize();
      // This (+1/-1) is a quick hack for the bug
      // http://code.google.com/p/chromium-os/issues/detail?id=1010
      // while investigating the issue. It could be in gtk or around
      // NativeViewHostGtk::CreateFixed, but it will take some time.
      compact_navigation_bar_->SetBounds(curx, bounds.y() + 1,
                                         cnb_bounds.width(),
                                         bounds.height() - 1);
      curx += cnb_bounds.width();
      width -= cnb_bounds.width();
    }
    width = std::max(0, width);  // In case there is no space left.
    return gfx::Rect(curx, bounds.y(), width, bounds.height());
  }

  virtual bool NonClientHitTest(const gfx::Point& point) {
    gfx::Point point_in_main_menu_coords(point);
    views::View::ConvertPointToView(browser_view(), main_menu_,
                                    &point_in_main_menu_coords);
    if (main_menu_->HitTest(point_in_main_menu_coords))
      return true;

    gfx::Point point_in_status_area_coords(point);
    views::View::ConvertPointToView(browser_view(), status_area_,
                                    &point_in_status_area_coords);
    if (status_area_->HitTest(point_in_status_area_coords))
      return true;

    if (compact_navigation_bar_->IsVisible()) {
      gfx::Point point_in_cnb_coords(point);
      views::View::ConvertPointToView(browser_view(),
                                      compact_navigation_bar_,
                                      &point_in_cnb_coords);
      return compact_navigation_bar_->HitTest(point_in_cnb_coords);
    }
    return false;
  }

  virtual void UpdateTitleBar() {}

  virtual void Show() {
    TabOverviewTypes::instance()->SetWindowType(
        GTK_WIDGET(GetBrowserWindow()->GetNativeWindow()),
        TabOverviewTypes::WINDOW_TYPE_CHROME_TOPLEVEL,
        NULL);
  }

  virtual void Close() {}

  virtual void ActivationChanged() {}

  virtual bool ShouldForceHideToolbar() {
    return compact_navigation_bar_enabled_;
  }

  virtual bool SetFocusToCompactNavigationBar() {
    if (compact_navigation_bar_->IsFocusable()) {
      compact_navigation_bar_->FocusLocation();
      return true;
    } else {
      return false;
    }
  }

  virtual void ToggleCompactNavigationBar() {
    compact_navigation_bar_enabled_ = !compact_navigation_bar_enabled_;
    compact_navigation_bar_->SetFocusable(compact_navigation_bar_enabled_);
    status_area_->Update();
  }

  virtual void OnMouseEnteredToTab(Tab* tab) {
    ShowCompactLocationBarUnderSelectedTab();
  }

  virtual void OnMouseMovedOnTab(Tab* tab) {
    ShowCompactLocationBarUnderSelectedTab();
  }

  virtual void OnMouseExitedFromTab(Tab* tab) {
    compact_location_bar_->StartPopupTimer();
  }

  virtual bool ShouldForceMaximizedWindow() {
    return force_maximized_window_;
  }

 private:
  // Shows the compact location bar under the selected tab.
  void ShowCompactLocationBarUnderSelectedTab() {
    if (!compact_navigation_bar_enabled_)
      return;
    compact_location_bar_->Update(
        browser_view()->tabstrip()->GetSelectedTab(),
        browser_view()->browser()->GetSelectedTabContents());
  }

  // Creates system menu.
  void InitSystemMenu() {
    system_menu_contents_.reset(new menus::SimpleMenuModel(browser_view()));
    system_menu_contents_->AddItemWithStringId(IDC_RESTORE_TAB,
                                               IDS_RESTORE_TAB);
    system_menu_contents_->AddItemWithStringId(IDC_NEW_TAB, IDS_NEW_TAB);
    system_menu_contents_->AddSeparator();
    system_menu_contents_->AddItemWithStringId(IDC_TASK_MANAGER,
                                               IDS_TASK_MANAGER);
    system_menu_menu_.reset(new views::Menu2(system_menu_contents_.get()));
  }

  // views::ButtonListener overrides.
  virtual void ButtonPressed(views::Button* sender, const views::Event& event) {
    chromeos::MainMenu::Show(browser_view()->browser());
  }

  // views::ContextMenuController overrides.
  virtual void ShowContextMenu(views::View* source,
                               int x,
                               int y,
                               bool is_mouse_gesture) {
    system_menu_menu_->RunMenuAt(gfx::Point(x, y), views::Menu2::ALIGN_TOPLEFT);
  }

  // Main menu button.
  views::ImageButton* main_menu_;

  // Status Area view.
  chromeos::StatusAreaView* status_area_;

  // System menus.
  scoped_ptr<menus::SimpleMenuModel> system_menu_contents_;
  scoped_ptr<views::Menu2> system_menu_menu_;

  // CompactNavigationBar view.
  chromeos::CompactNavigationBar* compact_navigation_bar_;

  // A toggle flag to show/hide the compact navigation bar.
  bool compact_navigation_bar_enabled_;

  // CompactLocationBar view.
  scoped_ptr<chromeos::CompactLocationBar> compact_location_bar_;

  // A flag to specify if the browser window should be maximized.
  bool force_maximized_window_;

  DISALLOW_COPY_AND_ASSIGN(NormalExtender);
};

// PopupExtender class creates dedicated title window for popup window.
// The size and location of the created title window is controlled by
// by window manager.
class PopupExtender : public BrowserExtender {
 public:
  explicit PopupExtender(BrowserView* browser_view)
      : BrowserExtender(browser_view) {
  }
  virtual ~PopupExtender() {}

 private:
  // BrowserExtender overrides.
  virtual void Init() {
    // The visibility of toolbar is controlled in
    // the BrowserView::IsToolbarVisible method.

    views::Window* window = GetBrowserWindow();
    gfx::NativeWindow native_window = window->GetNativeWindow();
    // The window manager needs the min size for popups.
    gfx::Rect bounds = window->GetBounds();
    gtk_widget_set_size_request(
        GTK_WIDGET(native_window), bounds.width(), bounds.height());
    // If we don't explicitly resize here there is a race condition between
    // the X Server and the window manager. Windows will appear with a default
    // size of 200x200 if this happens.
    gtk_window_resize(native_window, bounds.width(), bounds.height());
  }

  virtual gfx::Rect Layout(const gfx::Rect& bounds) {
    return bounds;
  }

  virtual bool NonClientHitTest(const gfx::Point& point) {
    return false;
  }

  virtual void Show() {
    panel_controller_.reset(new chromeos::PanelController(browser_view()));
  }

  virtual void Close() {
    if (panel_controller_.get())
      panel_controller_->Close();
  }

  virtual void UpdateTitleBar() {
    if (panel_controller_.get())
      panel_controller_->UpdateTitleBar();
  }

  virtual void ActivationChanged() {
    if (panel_controller_.get()) {
      if (GetBrowserWindow()->IsActive())
        panel_controller_->OnFocusIn();
      else
        panel_controller_->OnFocusOut();
    }
  }

  virtual bool ShouldForceHideToolbar() {
    // Always hide toolbar for popups.
    return true;
  }

  virtual bool SetFocusToCompactNavigationBar() {
    return false;
  }

  virtual void ToggleCompactNavigationBar() {}

  virtual void OnMouseEnteredToTab(Tab* tab) {}

  virtual void OnMouseMovedOnTab(Tab* tab) {}

  virtual void OnMouseExitedFromTab(Tab* tab) {}

  virtual bool ShouldForceMaximizedWindow() {
    return false;
  }

  // Controls interactions with the window manager for popup panels.
  scoped_ptr<chromeos::PanelController> panel_controller_;

  DISALLOW_COPY_AND_ASSIGN(PopupExtender);
};

}  // namespace

////////////////////////////////////////////////////////////////////////////////
// BrowserExtender, public:

// static
BrowserExtender* BrowserExtender::Create(BrowserView* browser_view) {
  BrowserExtender* extender;
  if (browser_view->browser()->type() & Browser::TYPE_POPUP)
    extender = new PopupExtender(browser_view);
  else
    extender = new NormalExtender(browser_view);
  extender->Init();
  return extender;
}
<commit_msg>Don't show app menu when wrench menu is shown at startup.<commit_after>// Copyright (c) 2009 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 <algorithm>

#include "app/menus/simple_menu_model.h"
#include "app/theme_provider.h"
#include "base/command_line.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/chromeos/compact_location_bar.h"
#include "chrome/browser/chromeos/compact_navigation_bar.h"
#include "chrome/browser/chromeos/main_menu.h"
#include "chrome/browser/chromeos/status_area_view.h"
#include "chrome/browser/chromeos/panel_controller.h"
#include "chrome/browser/views/frame/browser_extender.h"
#include "chrome/browser/views/frame/browser_frame_gtk.h"
#include "chrome/browser/views/frame/browser_view.h"
#include "chrome/browser/views/tabs/tab_overview_types.h"
#include "chrome/browser/views/tabs/tab_strip.h"
#include "chrome/browser/views/toolbar_view.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/x11_util.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "views/controls/button/button.h"
#include "views/controls/button/image_button.h"
#include "views/controls/menu/menu_2.h"
#include "views/window/window.h"

namespace {

const char* kChromeOsWindowManagerName = "chromeos-wm";

// NormalExtender adds ChromeOS specific controls and menus to a BrowserView
// created with Browser::TYPE_NORMAL. This extender adds controls to
// the title bar as follows:
//                  ____  __ __
//      [MainMenu] /    \   \  \     [StatusArea]
//
// and adds the system context menu to the remaining arae of the titlebar.
//
// For Browser::TYPE_POPUP type of BrowserView, see PopupExtender class below.
class NormalExtender : public BrowserExtender,
                       public views::ButtonListener,
                       public views::ContextMenuController {
 public:
  explicit NormalExtender(BrowserView* browser_view)
      : BrowserExtender(browser_view),
        main_menu_(NULL),
        status_area_(NULL),
        compact_navigation_bar_(NULL),
        // CompactNavigationBar is disabled by default.
        // TODO(oshima): Get this info from preference.
        compact_navigation_bar_enabled_(false),
        force_maximized_window_(false) {
  }
  virtual ~NormalExtender() {}

 protected:
  // BrowserExtender overrides.
  virtual void Init() {
    main_menu_ = new views::ImageButton(this);
    ThemeProvider* theme_provider =
        browser_view()->frame()->GetThemeProviderForFrame();
    SkBitmap* image = theme_provider->GetBitmapNamed(IDR_MAIN_MENU_BUTTON);
    main_menu_->SetImage(views::CustomButton::BS_NORMAL, image);
    main_menu_->SetImage(views::CustomButton::BS_HOT, image);
    main_menu_->SetImage(views::CustomButton::BS_PUSHED, image);
    browser_view()->AddChildView(main_menu_);

    Browser* browser = browser_view()->browser();
    compact_location_bar_.reset(
        new chromeos::CompactLocationBar(browser_view()));
    compact_navigation_bar_ = new chromeos::CompactNavigationBar(browser);
    browser_view()->AddChildView(compact_navigation_bar_);
    compact_navigation_bar_->Init();
    status_area_ = new chromeos::StatusAreaView(
        browser,
        browser_view()->GetWindow()->GetNativeWindow());
    browser_view()->AddChildView(status_area_);
    status_area_->Init();

    InitSystemMenu();
    chromeos::MainMenu::ScheduleCreation();

    // The ContextMenuController has to be set to a NonClientView but
    // not to a NonClientFrameView because a TabStrip is not a child of
    // a NonClientFrameView even though visually a TabStrip is over a
    // NonClientFrameView.
    BrowserFrameGtk* gtk_frame =
        static_cast<BrowserFrameGtk*>(browser_view()->frame());
    gtk_frame->GetNonClientView()->SetContextMenuController(this);

    if (browser->type() == Browser::TYPE_NORMAL) {
      std::string wm_name;
      bool wm_name_valid = x11_util::GetWindowManagerName(&wm_name);
      // NOTE: On Chrome OS the wm and Chrome are started in parallel. This
      // means it's possible for us not to be able to get the name of the window
      // manager. We assume that when this happens we're on Chrome OS.
      force_maximized_window_ = (!wm_name_valid ||
                                 wm_name == kChromeOsWindowManagerName ||
                                 CommandLine::ForCurrentProcess()->HasSwitch(
                                     switches::kChromeosFrame));
    }
  }

  virtual gfx::Rect Layout(const gfx::Rect& bounds) {
    // Skip if there is no space to layout, or if the browser is in
    // fullscreen mode.
    if (bounds.IsEmpty() || browser_view()->IsFullscreen()) {
      main_menu_->SetVisible(false);
      compact_navigation_bar_->SetVisible(false);
      status_area_->SetVisible(false);
      return bounds;
    } else {
      main_menu_->SetVisible(true);
      compact_navigation_bar_->SetVisible(compact_navigation_bar_enabled_);
      status_area_->SetVisible(true);
    }

    /* TODO(oshima):
     * Disabling the ability to update location bar on re-layout bacause
     * tabstrip state may not be in sync with the browser's state when
     * new tab is added. We should decide when we know more about this
     * feature. May be we should simply hide the location?
     * Filed a bug: http://crbug.com/30612.
    if (compact_navigation_bar_->IsVisible()) {
      // Update the size and location of the compact location bar.
      compact_location_bar_->UpdateBounds(
          browser_view()->tabstrip()->GetSelectedTab());
    }
    */

    // Layout main menu before tab strip.
    gfx::Size main_menu_size = main_menu_->GetPreferredSize();
    main_menu_->SetBounds(bounds.x(), bounds.y(),
                          main_menu_size.width(), bounds.height());

    // Layout status area after tab strip.
    status_area_->Update();
    gfx::Size status_size = status_area_->GetPreferredSize();
    status_area_->SetBounds(bounds.x() + bounds.width() - status_size.width(),
                            bounds.y(), status_size.width(),
                            status_size.height());
    int curx = bounds.x() + main_menu_size.width();
    int width = bounds.width() - main_menu_size.width() - status_size.width();

    if (compact_navigation_bar_->IsVisible()) {
      gfx::Size cnb_bounds = compact_navigation_bar_->GetPreferredSize();
      // This (+1/-1) is a quick hack for the bug
      // http://code.google.com/p/chromium-os/issues/detail?id=1010
      // while investigating the issue. It could be in gtk or around
      // NativeViewHostGtk::CreateFixed, but it will take some time.
      compact_navigation_bar_->SetBounds(curx, bounds.y() + 1,
                                         cnb_bounds.width(),
                                         bounds.height() - 1);
      curx += cnb_bounds.width();
      width -= cnb_bounds.width();
    }
    width = std::max(0, width);  // In case there is no space left.
    return gfx::Rect(curx, bounds.y(), width, bounds.height());
  }

  virtual bool NonClientHitTest(const gfx::Point& point) {
    gfx::Point point_in_main_menu_coords(point);
    views::View::ConvertPointToView(browser_view(), main_menu_,
                                    &point_in_main_menu_coords);
    if (main_menu_->HitTest(point_in_main_menu_coords))
      return true;

    gfx::Point point_in_status_area_coords(point);
    views::View::ConvertPointToView(browser_view(), status_area_,
                                    &point_in_status_area_coords);
    if (status_area_->HitTest(point_in_status_area_coords))
      return true;

    if (compact_navigation_bar_->IsVisible()) {
      gfx::Point point_in_cnb_coords(point);
      views::View::ConvertPointToView(browser_view(),
                                      compact_navigation_bar_,
                                      &point_in_cnb_coords);
      return compact_navigation_bar_->HitTest(point_in_cnb_coords);
    }
    return false;
  }

  virtual void UpdateTitleBar() {}

  virtual void Show() {
    TabOverviewTypes::instance()->SetWindowType(
        GTK_WIDGET(GetBrowserWindow()->GetNativeWindow()),
        TabOverviewTypes::WINDOW_TYPE_CHROME_TOPLEVEL,
        NULL);
  }

  virtual void Close() {}

  virtual void ActivationChanged() {}

  virtual bool ShouldForceHideToolbar() {
    return compact_navigation_bar_enabled_;
  }

  virtual bool SetFocusToCompactNavigationBar() {
    if (compact_navigation_bar_->IsFocusable()) {
      compact_navigation_bar_->FocusLocation();
      return true;
    } else {
      return false;
    }
  }

  virtual void ToggleCompactNavigationBar() {
    compact_navigation_bar_enabled_ = !compact_navigation_bar_enabled_;
    compact_navigation_bar_->SetFocusable(compact_navigation_bar_enabled_);
  }

  virtual void OnMouseEnteredToTab(Tab* tab) {
    ShowCompactLocationBarUnderSelectedTab();
  }

  virtual void OnMouseMovedOnTab(Tab* tab) {
    ShowCompactLocationBarUnderSelectedTab();
  }

  virtual void OnMouseExitedFromTab(Tab* tab) {
    compact_location_bar_->StartPopupTimer();
  }

  virtual bool ShouldForceMaximizedWindow() {
    return force_maximized_window_;
  }

 private:
  // Shows the compact location bar under the selected tab.
  void ShowCompactLocationBarUnderSelectedTab() {
    if (!compact_navigation_bar_enabled_)
      return;
    compact_location_bar_->Update(
        browser_view()->tabstrip()->GetSelectedTab(),
        browser_view()->browser()->GetSelectedTabContents());
  }

  // Creates system menu.
  void InitSystemMenu() {
    system_menu_contents_.reset(new menus::SimpleMenuModel(browser_view()));
    system_menu_contents_->AddItemWithStringId(IDC_RESTORE_TAB,
                                               IDS_RESTORE_TAB);
    system_menu_contents_->AddItemWithStringId(IDC_NEW_TAB, IDS_NEW_TAB);
    system_menu_contents_->AddSeparator();
    system_menu_contents_->AddItemWithStringId(IDC_TASK_MANAGER,
                                               IDS_TASK_MANAGER);
    system_menu_menu_.reset(new views::Menu2(system_menu_contents_.get()));
  }

  // views::ButtonListener overrides.
  virtual void ButtonPressed(views::Button* sender, const views::Event& event) {
    chromeos::MainMenu::Show(browser_view()->browser());
  }

  // views::ContextMenuController overrides.
  virtual void ShowContextMenu(views::View* source,
                               int x,
                               int y,
                               bool is_mouse_gesture) {
    system_menu_menu_->RunMenuAt(gfx::Point(x, y), views::Menu2::ALIGN_TOPLEFT);
  }

  // Main menu button.
  views::ImageButton* main_menu_;

  // Status Area view.
  chromeos::StatusAreaView* status_area_;

  // System menus.
  scoped_ptr<menus::SimpleMenuModel> system_menu_contents_;
  scoped_ptr<views::Menu2> system_menu_menu_;

  // CompactNavigationBar view.
  chromeos::CompactNavigationBar* compact_navigation_bar_;

  // A toggle flag to show/hide the compact navigation bar.
  bool compact_navigation_bar_enabled_;

  // CompactLocationBar view.
  scoped_ptr<chromeos::CompactLocationBar> compact_location_bar_;

  // A flag to specify if the browser window should be maximized.
  bool force_maximized_window_;

  DISALLOW_COPY_AND_ASSIGN(NormalExtender);
};

// PopupExtender class creates dedicated title window for popup window.
// The size and location of the created title window is controlled by
// by window manager.
class PopupExtender : public BrowserExtender {
 public:
  explicit PopupExtender(BrowserView* browser_view)
      : BrowserExtender(browser_view) {
  }
  virtual ~PopupExtender() {}

 private:
  // BrowserExtender overrides.
  virtual void Init() {
    // The visibility of toolbar is controlled in
    // the BrowserView::IsToolbarVisible method.

    views::Window* window = GetBrowserWindow();
    gfx::NativeWindow native_window = window->GetNativeWindow();
    // The window manager needs the min size for popups.
    gfx::Rect bounds = window->GetBounds();
    gtk_widget_set_size_request(
        GTK_WIDGET(native_window), bounds.width(), bounds.height());
    // If we don't explicitly resize here there is a race condition between
    // the X Server and the window manager. Windows will appear with a default
    // size of 200x200 if this happens.
    gtk_window_resize(native_window, bounds.width(), bounds.height());
  }

  virtual gfx::Rect Layout(const gfx::Rect& bounds) {
    return bounds;
  }

  virtual bool NonClientHitTest(const gfx::Point& point) {
    return false;
  }

  virtual void Show() {
    panel_controller_.reset(new chromeos::PanelController(browser_view()));
  }

  virtual void Close() {
    if (panel_controller_.get())
      panel_controller_->Close();
  }

  virtual void UpdateTitleBar() {
    if (panel_controller_.get())
      panel_controller_->UpdateTitleBar();
  }

  virtual void ActivationChanged() {
    if (panel_controller_.get()) {
      if (GetBrowserWindow()->IsActive())
        panel_controller_->OnFocusIn();
      else
        panel_controller_->OnFocusOut();
    }
  }

  virtual bool ShouldForceHideToolbar() {
    // Always hide toolbar for popups.
    return true;
  }

  virtual bool SetFocusToCompactNavigationBar() {
    return false;
  }

  virtual void ToggleCompactNavigationBar() {}

  virtual void OnMouseEnteredToTab(Tab* tab) {}

  virtual void OnMouseMovedOnTab(Tab* tab) {}

  virtual void OnMouseExitedFromTab(Tab* tab) {}

  virtual bool ShouldForceMaximizedWindow() {
    return false;
  }

  // Controls interactions with the window manager for popup panels.
  scoped_ptr<chromeos::PanelController> panel_controller_;

  DISALLOW_COPY_AND_ASSIGN(PopupExtender);
};

}  // namespace

////////////////////////////////////////////////////////////////////////////////
// BrowserExtender, public:

// static
BrowserExtender* BrowserExtender::Create(BrowserView* browser_view) {
  BrowserExtender* extender;
  if (browser_view->browser()->type() & Browser::TYPE_POPUP)
    extender = new PopupExtender(browser_view);
  else
    extender = new NormalExtender(browser_view);
  extender->Init();
  return extender;
}
<|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 "base/file_path.h"
#include "chrome/browser/tab_contents/navigation_entry.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/notification_type.h"
#include "chrome/common/page_transition_types.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

void SimulateRendererCrash(Browser* browser) {
  browser->OpenURL(GURL(chrome::kAboutCrashURL), GURL(), CURRENT_TAB,
                   PageTransition::TYPED);
  ui_test_utils::WaitForNotification(
      NotificationType::TAB_CONTENTS_DISCONNECTED);
}

}  // namespace

class CrashRecoveryBrowserTest : public InProcessBrowserTest {
};

// http://crbug.com/29331 - Causes an OS crash dialog in release mode, needs to
// be fixed before it can be enabled to not cause the bots issues.
#if defined(OS_MACOSX)
#define MAYBE_Reload DISABLED_Reload
#else
#define MAYBE_Reload Reload
#endif

// Test that reload works after a crash.
IN_PROC_BROWSER_TEST_F(CrashRecoveryBrowserTest, MAYBE_Reload) {
  // The title of the active tab should change each time this URL is loaded.
  GURL url(
      "data:text/html,<script>document.title=new Date().valueOf()</script>");
  ui_test_utils::NavigateToURL(browser(), url);

  string16 title_before_crash;
  string16 title_after_crash;

  ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(),
                                                &title_before_crash));
  SimulateRendererCrash(browser());
  browser()->Reload(CURRENT_TAB);
  ASSERT_TRUE(ui_test_utils::WaitForNavigationInCurrentTab(browser()));
  ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(),
                                                &title_after_crash));
  EXPECT_NE(title_before_crash, title_after_crash);
}

// Tests that loading a crashed page in a new tab correctly updates the title.
// There was an earlier bug (1270510) in process-per-site in which the max page
// ID of the RenderProcessHost was stale, so the NavigationEntry in the new tab
// was not committed.  This prevents regression of that bug.
// http://crbug.com/57158 - Times out sometimes on all platforms.
IN_PROC_BROWSER_TEST_F(CrashRecoveryBrowserTest, DISABLED_LoadInNewTab) {
  const FilePath::CharType* kTitle2File = FILE_PATH_LITERAL("title2.html");

  ui_test_utils::NavigateToURL(browser(),
      ui_test_utils::GetTestUrl(FilePath(FilePath::kCurrentDirectory),
                                FilePath(kTitle2File)));

  string16 title_before_crash;
  string16 title_after_crash;

  ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(),
                                                &title_before_crash));
  SimulateRendererCrash(browser());
  browser()->Reload(CURRENT_TAB);
  ASSERT_TRUE(ui_test_utils::WaitForNavigationInCurrentTab(browser()));
  ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(),
                                                &title_after_crash));
  EXPECT_EQ(title_before_crash, title_after_crash);
}
<commit_msg>Disable CrashRecoveryBrowserTest.Reload, flakily times out<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 "base/file_path.h"
#include "chrome/browser/tab_contents/navigation_entry.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/notification_type.h"
#include "chrome/common/page_transition_types.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

void SimulateRendererCrash(Browser* browser) {
  browser->OpenURL(GURL(chrome::kAboutCrashURL), GURL(), CURRENT_TAB,
                   PageTransition::TYPED);
  ui_test_utils::WaitForNotification(
      NotificationType::TAB_CONTENTS_DISCONNECTED);
}

}  // namespace

class CrashRecoveryBrowserTest : public InProcessBrowserTest {
};

// Test that reload works after a crash.
// Disabled, http://crbug.com/29331, http://crbug.com/69637.
IN_PROC_BROWSER_TEST_F(CrashRecoveryBrowserTest, DISABLED_Reload) {
  // The title of the active tab should change each time this URL is loaded.
  GURL url(
      "data:text/html,<script>document.title=new Date().valueOf()</script>");
  ui_test_utils::NavigateToURL(browser(), url);

  string16 title_before_crash;
  string16 title_after_crash;

  ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(),
                                                &title_before_crash));
  SimulateRendererCrash(browser());
  browser()->Reload(CURRENT_TAB);
  ASSERT_TRUE(ui_test_utils::WaitForNavigationInCurrentTab(browser()));
  ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(),
                                                &title_after_crash));
  EXPECT_NE(title_before_crash, title_after_crash);
}

// Tests that loading a crashed page in a new tab correctly updates the title.
// There was an earlier bug (1270510) in process-per-site in which the max page
// ID of the RenderProcessHost was stale, so the NavigationEntry in the new tab
// was not committed.  This prevents regression of that bug.
// http://crbug.com/57158 - Times out sometimes on all platforms.
IN_PROC_BROWSER_TEST_F(CrashRecoveryBrowserTest, DISABLED_LoadInNewTab) {
  const FilePath::CharType* kTitle2File = FILE_PATH_LITERAL("title2.html");

  ui_test_utils::NavigateToURL(browser(),
      ui_test_utils::GetTestUrl(FilePath(FilePath::kCurrentDirectory),
                                FilePath(kTitle2File)));

  string16 title_before_crash;
  string16 title_after_crash;

  ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(),
                                                &title_before_crash));
  SimulateRendererCrash(browser());
  browser()->Reload(CURRENT_TAB);
  ASSERT_TRUE(ui_test_utils::WaitForNavigationInCurrentTab(browser()));
  ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(),
                                                &title_after_crash));
  EXPECT_EQ(title_before_crash, title_after_crash);
}
<|endoftext|>


<commit_before>// Copyright (c) 2009 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/gtk/constrained_window_gtk.h"

#include <gdk/gdkkeysyms.h>

#include "chrome/browser/browser_list.h"
#include "chrome/browser/gtk/gtk_util.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tab_contents/tab_contents_view_gtk.h"

ConstrainedWindowGtk::ConstrainedWindowGtk(
    TabContents* owner, ConstrainedWindowGtkDelegate* delegate)
    : owner_(owner),
      delegate_(delegate),
      visible_(false),
      accel_group_(gtk_accel_group_new()) {
  DCHECK(owner);
  DCHECK(delegate);
  GtkWidget* dialog = delegate->GetWidgetRoot();

  // Unlike other users of CreateBorderBin, we need a dedicated frame around
  // our "window".
  GtkWidget* ebox = gtk_event_box_new();
  GtkWidget* frame = gtk_frame_new(NULL);
  gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_OUT);
  GtkWidget* alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
  gtk_alignment_set_padding(GTK_ALIGNMENT(alignment),
      gtk_util::kContentAreaBorder, gtk_util::kContentAreaBorder,
      gtk_util::kContentAreaBorder, gtk_util::kContentAreaBorder);
  gtk_container_add(GTK_CONTAINER(alignment), dialog);
  gtk_container_add(GTK_CONTAINER(frame), alignment);
  gtk_container_add(GTK_CONTAINER(ebox), frame);
  border_.Own(ebox);
  ConnectAccelerators();
}

ConstrainedWindowGtk::~ConstrainedWindowGtk() {
  border_.Destroy();

  gtk_accel_group_disconnect_key(accel_group_, GDK_Escape,
                                 static_cast<GdkModifierType>(0));
  gtk_window_remove_accel_group(
      GTK_WINDOW(ContainingView()->GetTopLevelNativeWindow()),
      accel_group_);
  g_object_unref(accel_group_);
}

void ConstrainedWindowGtk::ShowConstrainedWindow() {
  gtk_widget_show_all(border_.get());

  // We collaborate with TabContentsViewGtk and stick ourselves in the
  // TabContentsViewGtk's floating container.
  ContainingView()->AttachConstrainedWindow(this);

  visible_ = true;
}

void ConstrainedWindowGtk::CloseConstrainedWindow() {
  if (visible_)
    ContainingView()->RemoveConstrainedWindow(this);
  delegate_->DeleteDelegate();
  owner_->WillClose(this);

  delete this;
}

TabContentsViewGtk* ConstrainedWindowGtk::ContainingView() {
  return static_cast<TabContentsViewGtk*>(owner_->view());
}

void ConstrainedWindowGtk::ConnectAccelerators() {
  gtk_accel_group_connect(accel_group_,
                          GDK_Escape, static_cast<GdkModifierType>(0),
                          static_cast<GtkAccelFlags>(0),
                          g_cclosure_new(G_CALLBACK(OnEscapeThunk),
                                         this, NULL));
  gtk_window_add_accel_group(
      GTK_WINDOW(ContainingView()->GetTopLevelNativeWindow()),
      accel_group_);
}

gboolean ConstrainedWindowGtk::OnEscape() {
  // Handle this accelerator only if this is on the currently selected tab.
  Browser* browser = BrowserList::GetLastActive();
  if (!browser || browser->GetSelectedTabContents() != owner_)
    return FALSE;

  CloseConstrainedWindow();
  return TRUE;
}

// static
ConstrainedWindow* ConstrainedWindow::CreateConstrainedDialog(
    TabContents* parent,
    ConstrainedWindowGtkDelegate* delegate) {
  return new ConstrainedWindowGtk(parent, delegate);
}

<commit_msg>Fix for LoginPromptTesti.CancelRedundantAuths and related tests on linux views.<commit_after>// Copyright (c) 2009 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/gtk/constrained_window_gtk.h"

#include <gdk/gdkkeysyms.h>

#include "chrome/browser/browser_list.h"
#include "chrome/browser/gtk/gtk_util.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tab_contents/tab_contents_view_gtk.h"

ConstrainedWindowGtk::ConstrainedWindowGtk(
    TabContents* owner, ConstrainedWindowGtkDelegate* delegate)
    : owner_(owner),
      delegate_(delegate),
      visible_(false),
      accel_group_(gtk_accel_group_new()) {
  DCHECK(owner);
  DCHECK(delegate);
  GtkWidget* dialog = delegate->GetWidgetRoot();

  // Unlike other users of CreateBorderBin, we need a dedicated frame around
  // our "window".
  GtkWidget* ebox = gtk_event_box_new();
  GtkWidget* frame = gtk_frame_new(NULL);
  gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_OUT);
  GtkWidget* alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
  gtk_alignment_set_padding(GTK_ALIGNMENT(alignment),
      gtk_util::kContentAreaBorder, gtk_util::kContentAreaBorder,
      gtk_util::kContentAreaBorder, gtk_util::kContentAreaBorder);
  gtk_container_add(GTK_CONTAINER(alignment), dialog);
  gtk_container_add(GTK_CONTAINER(frame), alignment);
  gtk_container_add(GTK_CONTAINER(ebox), frame);
  border_.Own(ebox);
  ConnectAccelerators();
}

ConstrainedWindowGtk::~ConstrainedWindowGtk() {
  border_.Destroy();

  gtk_accel_group_disconnect_key(accel_group_, GDK_Escape,
                                 static_cast<GdkModifierType>(0));
  if (ContainingView() && ContainingView()->GetTopLevelNativeWindow()) {
    gtk_window_remove_accel_group(
        GTK_WINDOW(ContainingView()->GetTopLevelNativeWindow()),
        accel_group_);
  }
  g_object_unref(accel_group_);
}

void ConstrainedWindowGtk::ShowConstrainedWindow() {
  gtk_widget_show_all(border_.get());

  // We collaborate with TabContentsViewGtk and stick ourselves in the
  // TabContentsViewGtk's floating container.
  ContainingView()->AttachConstrainedWindow(this);

  visible_ = true;
}

void ConstrainedWindowGtk::CloseConstrainedWindow() {
  if (visible_)
    ContainingView()->RemoveConstrainedWindow(this);
  delegate_->DeleteDelegate();
  owner_->WillClose(this);

  delete this;
}

TabContentsViewGtk* ConstrainedWindowGtk::ContainingView() {
  return static_cast<TabContentsViewGtk*>(owner_->view());
}

void ConstrainedWindowGtk::ConnectAccelerators() {
  gtk_accel_group_connect(accel_group_,
                          GDK_Escape, static_cast<GdkModifierType>(0),
                          static_cast<GtkAccelFlags>(0),
                          g_cclosure_new(G_CALLBACK(OnEscapeThunk),
                                         this, NULL));
  gtk_window_add_accel_group(
      GTK_WINDOW(ContainingView()->GetTopLevelNativeWindow()),
      accel_group_);
}

gboolean ConstrainedWindowGtk::OnEscape() {
  // Handle this accelerator only if this is on the currently selected tab.
  Browser* browser = BrowserList::GetLastActive();
  if (!browser || browser->GetSelectedTabContents() != owner_)
    return FALSE;

  CloseConstrainedWindow();
  return TRUE;
}

// static
ConstrainedWindow* ConstrainedWindow::CreateConstrainedDialog(
    TabContents* parent,
    ConstrainedWindowGtkDelegate* delegate) {
  return new ConstrainedWindowGtk(parent, delegate);
}

<|endoftext|>


<commit_before>/* exception_handler.cc
   Jeremy Barnes, 26 February 2008
   Copyright (c) 2009 Jeremy Barnes.  All rights reserved.

*/

#include <cxxabi.h>
#include <cstring>
#include <fstream>

#include "jml/compiler/compiler.h"
#include "jml/utils/environment.h"

#include "backtrace.h"
#include "demangle.h"
#include "exception.h"
#include "exception_hook.h"
#include "format.h"
#include "threads.h"

using namespace std;

namespace ML {

void (*exception_tracer) (void *, const std::type_info *) JML_WEAK_FN = 0;

Env_Option<bool> TRACE_EXCEPTIONS("JML_TRACE_EXCEPTIONS", true);

__thread bool trace_exceptions = false;
__thread bool trace_exceptions_initialized = false;

void set_default_trace_exceptions(bool val)
{
    TRACE_EXCEPTIONS.set(val);
}

bool get_default_trace_exceptions()
{
    return TRACE_EXCEPTIONS;
}

void set_trace_exceptions(bool trace)
{
    //cerr << "set_trace_exceptions to " << trace << " at " << &trace_exceptions
    //     << endl;
    trace_exceptions = trace;
    trace_exceptions_initialized = true;
}

bool get_trace_exceptions()
{
    if (!trace_exceptions_initialized) {
        //cerr << "trace_exceptions initialized to = "
        //     << trace_exceptions << " at " << &trace_exceptions << endl;
        set_trace_exceptions(TRACE_EXCEPTIONS);
        trace_exceptions_initialized = true;
    }

    //cerr << "get_trace_exceptions returned " << trace_exceptions
    //     << " at " << &trace_exceptions << endl;

    return trace_exceptions;
}

static const std::exception *
to_std_exception(void* object, const std::type_info * tinfo)
{
    /* Check if its a class.  If not, we can't see if it's a std::exception.
       The abi::__class_type_info is the base class of all types of type
       info for types that are classes (of which std::exception is one).
    */
    const abi::__class_type_info * ctinfo
        = dynamic_cast<const abi::__class_type_info *>(tinfo);

    if (!ctinfo) return 0;

    /* The thing thrown was an object.  Now, check if it is derived from
    std::exception. */
    const std::type_info * etinfo = &typeid(std::exception);

    /* See if the exception could catch this.  This is the mechanism
    used internally by the compiler in catch {} blocks to see if
    the exception matches the catch type.

    In the case of success, the object will be adjusted to point to
    the start of the std::exception object.
    */
    void * obj_ptr = object;
    bool can_catch = etinfo->__do_catch(tinfo, &obj_ptr, 0);

    if (!can_catch) return 0;

    /* obj_ptr points to a std::exception; extract it and get the
    exception message.
    */
    return (const std::exception *)obj_ptr;
}

/** We install this handler for when an exception is thrown. */

void trace_exception(void * object, const std::type_info * tinfo)
{
    //cerr << "trace_exception: trace_exceptions = " << get_trace_exceptions()
    //     << " at " << &trace_exceptions << endl;

    if (!get_trace_exceptions()) return;

    const std::exception * exc = to_std_exception(object, tinfo);

    // We don't want these exceptions to be printed out.
    if (dynamic_cast<const ML::SilentException *>(exc)) return;

    /* avoid allocations when std::bad_alloc is thrown */
    bool noAlloc = dynamic_cast<const std::bad_alloc *>(exc);

    size_t bufferSize(1024*1024);
    char buffer[bufferSize];
    char datetime[128];
    size_t totalWritten(0), written, remaining(bufferSize);

    time_t now;
    time(&now);
    strftime(datetime, sizeof(datetime), "%FT%H:%M:%S", localtime(&now));

    const char * demangled;
    char * heapDemangled;
    if (noAlloc) {
        heapDemangled = nullptr;
        demangled = "std::bad_alloc";
    }
    else {
        heapDemangled = char_demangle(tinfo->name());
        demangled = heapDemangled;
    }
    auto pid = getpid();
    auto tid = gettid();

    written = ::snprintf(buffer, remaining,
                         "\n"
                         "--------------------------[Exception thrown]"
                         "---------------------------\n"
                         "time:   %s\n"
                         "type:   %s\n"
                         "pid:    %d; tid: %d\n",
                         datetime, demangled, pid, tid);
    if (heapDemangled) {
        free(heapDemangled);
    }
    if (written >= remaining) {
        goto end;
    }
    totalWritten += written;
    remaining -= written;

    if (exc) {
        written = snprintf(buffer + totalWritten, remaining,
                           "what:   %s\n", exc->what());
        if (written >= remaining) {
            goto end;
        }
        totalWritten += written;
        remaining -= written;
    }

    if (noAlloc) {
        goto end;
    }

    written = snprintf(buffer + totalWritten, remaining, "stack:\n");
    if (written >= remaining) {
        goto end;
    }
    totalWritten += written;
    remaining -= written;

    written = backtrace(buffer + totalWritten, remaining, 3);
    if (written >= remaining) {
        goto end;
    }
    totalWritten += written;

    if (totalWritten < bufferSize - 1) {
        strcpy(buffer + totalWritten, "\n");
    }

end:
    cerr << buffer;

    char const * reports = getenv("ENABLE_EXCEPTION_REPORTS");
    if (!noAlloc && reports) {
        std::string path = ML::format("%s/exception-report-%s-%d-%d.log",
                                      reports, datetime, pid, tid);

        std::ofstream file(path, std::ios_base::app);
        if(file) {
            file << getenv("_") << endl;
            backtrace(file, 3);
            file.close();
        }
    }
}

namespace {
struct Install_Handler {
    Install_Handler()
    {
        //cerr << "installing exception tracer" << endl;
        exception_tracer = trace_exception;
    }
    ~Install_Handler()
    {
        if (exception_tracer == trace_exception)
            exception_tracer = 0;
    }
} install_handler;

} // file scope

} // namespace ML
<commit_msg>PLAT-605: make use of "localtime_r" rather than "localtime", which is not thread safe and can cause deadlocks within the libc<commit_after>/* exception_handler.cc
   Jeremy Barnes, 26 February 2008
   Copyright (c) 2009 Jeremy Barnes.  All rights reserved.

*/

#include <cxxabi.h>
#include <cstring>
#include <fstream>

#include "jml/compiler/compiler.h"
#include "jml/utils/environment.h"

#include "backtrace.h"
#include "demangle.h"
#include "exception.h"
#include "exception_hook.h"
#include "format.h"
#include "threads.h"

using namespace std;

namespace ML {

void (*exception_tracer) (void *, const std::type_info *) JML_WEAK_FN = 0;

Env_Option<bool> TRACE_EXCEPTIONS("JML_TRACE_EXCEPTIONS", true);

__thread bool trace_exceptions = false;
__thread bool trace_exceptions_initialized = false;

void set_default_trace_exceptions(bool val)
{
    TRACE_EXCEPTIONS.set(val);
}

bool get_default_trace_exceptions()
{
    return TRACE_EXCEPTIONS;
}

void set_trace_exceptions(bool trace)
{
    //cerr << "set_trace_exceptions to " << trace << " at " << &trace_exceptions
    //     << endl;
    trace_exceptions = trace;
    trace_exceptions_initialized = true;
}

bool get_trace_exceptions()
{
    if (!trace_exceptions_initialized) {
        //cerr << "trace_exceptions initialized to = "
        //     << trace_exceptions << " at " << &trace_exceptions << endl;
        set_trace_exceptions(TRACE_EXCEPTIONS);
        trace_exceptions_initialized = true;
    }

    //cerr << "get_trace_exceptions returned " << trace_exceptions
    //     << " at " << &trace_exceptions << endl;

    return trace_exceptions;
}

static const std::exception *
to_std_exception(void* object, const std::type_info * tinfo)
{
    /* Check if its a class.  If not, we can't see if it's a std::exception.
       The abi::__class_type_info is the base class of all types of type
       info for types that are classes (of which std::exception is one).
    */
    const abi::__class_type_info * ctinfo
        = dynamic_cast<const abi::__class_type_info *>(tinfo);

    if (!ctinfo) return 0;

    /* The thing thrown was an object.  Now, check if it is derived from
    std::exception. */
    const std::type_info * etinfo = &typeid(std::exception);

    /* See if the exception could catch this.  This is the mechanism
    used internally by the compiler in catch {} blocks to see if
    the exception matches the catch type.

    In the case of success, the object will be adjusted to point to
    the start of the std::exception object.
    */
    void * obj_ptr = object;
    bool can_catch = etinfo->__do_catch(tinfo, &obj_ptr, 0);

    if (!can_catch) return 0;

    /* obj_ptr points to a std::exception; extract it and get the
    exception message.
    */
    return (const std::exception *)obj_ptr;
}

/** We install this handler for when an exception is thrown. */

void trace_exception(void * object, const std::type_info * tinfo)
{
    //cerr << "trace_exception: trace_exceptions = " << get_trace_exceptions()
    //     << " at " << &trace_exceptions << endl;

    if (!get_trace_exceptions()) return;

    const std::exception * exc = to_std_exception(object, tinfo);

    // We don't want these exceptions to be printed out.
    if (dynamic_cast<const ML::SilentException *>(exc)) return;

    /* avoid allocations when std::bad_alloc is thrown */
    bool noAlloc = dynamic_cast<const std::bad_alloc *>(exc);

    size_t bufferSize(1024*1024);
    char buffer[bufferSize];
    char datetime[128];
    size_t totalWritten(0), written, remaining(bufferSize);

    time_t now;
    time(&now);

    struct tm lt_tm;
    strftime(datetime, sizeof(datetime), "%FT%H:%M:%S",
             localtime_r(&now, &lt_tm));

    const char * demangled;
    char * heapDemangled;
    if (noAlloc) {
        heapDemangled = nullptr;
        demangled = "std::bad_alloc";
    }
    else {
        heapDemangled = char_demangle(tinfo->name());
        demangled = heapDemangled;
    }
    auto pid = getpid();
    auto tid = gettid();

    written = ::snprintf(buffer, remaining,
                         "\n"
                         "--------------------------[Exception thrown]"
                         "---------------------------\n"
                         "time:   %s\n"
                         "type:   %s\n"
                         "pid:    %d; tid: %d\n",
                         datetime, demangled, pid, tid);
    if (heapDemangled) {
        free(heapDemangled);
    }
    if (written >= remaining) {
        goto end;
    }
    totalWritten += written;
    remaining -= written;

    if (exc) {
        written = snprintf(buffer + totalWritten, remaining,
                           "what:   %s\n", exc->what());
        if (written >= remaining) {
            goto end;
        }
        totalWritten += written;
        remaining -= written;
    }

    if (noAlloc) {
        goto end;
    }

    written = snprintf(buffer + totalWritten, remaining, "stack:\n");
    if (written >= remaining) {
        goto end;
    }
    totalWritten += written;
    remaining -= written;

    written = backtrace(buffer + totalWritten, remaining, 3);
    if (written >= remaining) {
        goto end;
    }
    totalWritten += written;

    if (totalWritten < bufferSize - 1) {
        strcpy(buffer + totalWritten, "\n");
    }

end:
    cerr << buffer;

    char const * reports = getenv("ENABLE_EXCEPTION_REPORTS");
    if (!noAlloc && reports) {
        std::string path = ML::format("%s/exception-report-%s-%d-%d.log",
                                      reports, datetime, pid, tid);

        std::ofstream file(path, std::ios_base::app);
        if(file) {
            file << getenv("_") << endl;
            backtrace(file, 3);
            file.close();
        }
    }
}

namespace {
struct Install_Handler {
    Install_Handler()
    {
        //cerr << "installing exception tracer" << endl;
        exception_tracer = trace_exception;
    }
    ~Install_Handler()
    {
        if (exception_tracer == trace_exception)
            exception_tracer = 0;
    }
} install_handler;

} // file scope

} // namespace ML
<|endoftext|>


<commit_before>#ifndef __ENCODER_HPP
#define __ENCODER_HPP

#ifndef __ODRIVE_MAIN_H
#error "This file should not be included directly. Include odrive_main.h instead."
#endif

class Encoder {
public:
    enum Error_t {
        ERROR_NONE = 0,
        ERROR_UNSTABLE_GAIN = 0x01,
        ERROR_CPR_OUT_OF_RANGE = 0x02,
        ERROR_NO_RESPONSE = 0x04,
        ERROR_UNSUPPORTED_ENCODER_MODE = 0x08,
        ERROR_ILLEGAL_HALL_STATE = 0x10,
        ERROR_INDEX_NOT_FOUND_YET = 0x20,
    };

    enum Mode_t {
        MODE_INCREMENTAL,
        MODE_HALL,
        MODE_SINCOS
    };

    struct Config_t {
        Encoder::Mode_t mode = Encoder::MODE_INCREMENTAL;
        bool use_index = false;
        bool pre_calibrated = false; // If true, this means the offset stored in
                                    // configuration is valid and does not need
                                    // be determined by run_offset_calibration.
                                    // In this case the encoder will enter ready
                                    // state as soon as the index is found.
        bool zero_count_on_find_idx = true;
        int32_t cpr = (2048 * 4);   // Default resolution of CUI-AMT102 encoder,
        int32_t offset = 0;        // Offset between encoder count and rotor electrical phase
        float offset_float = 0.0f; // Sub-count phase alignment offset
        bool enable_phase_interpolation = true; // Use velocity to interpolate inside the count state
        float calib_range = 0.02f; // Accuracy required to pass encoder cpr check
        float calib_scan_distance = 16.0f * M_PI; // rad electrical
        float calib_scan_omega = 4.0f * M_PI; // rad/s electrical
        float bandwidth = 1000.0f;
        bool find_idx_on_lockin_only = false; // Only be sensitive during lockin scan constant vel state
        bool idx_search_unidirectional = false; // Only allow index search in known direction
        bool ignore_illegal_hall_state = false; // dont error on bad states like 000 or 111
    };

    Encoder(const EncoderHardwareConfig_t& hw_config,
                     Config_t& config);

    void setup();
    void set_error(Error_t error);
    bool do_checks();

    void enc_index_cb();
    void set_idx_subscribe(bool override_enable = false);
    void update_pll_gains();
    void check_pre_calibrated();

    void set_linear_count(int32_t count);
    void set_circular_count(int32_t count, bool update_offset);
    bool calib_enc_offset(float voltage_magnitude);

    bool run_index_search();
    bool run_direction_find();
    bool run_offset_calibration();
    void sample_now();
    bool update();

    const EncoderHardwareConfig_t& hw_config_;
    Config_t& config_;
    Axis* axis_ = nullptr; // set by Axis constructor

    Error_t error_ = ERROR_NONE;
    bool index_found_ = false;
    bool is_ready_ = false;
    int32_t shadow_count_ = 0;
    int32_t count_in_cpr_ = 0;
    float interpolation_ = 0.0f;
    float phase_ = 0.0f;    // [count]
    float pos_estimate_ = 0.0f;  // [count]
    float pos_cpr_ = 0.0f;  // [count]
    float vel_estimate_ = 0.0f;  // [count/s]
    float pll_kp_ = 0.0f;   // [count/s / count]
    float pll_ki_ = 0.0f;   // [(count/s^2) / count]
    float calib_scan_response_ = 0.0f; // debug report from offset calib

    int16_t tim_cnt_sample_ = 0; //
    // Updated by low_level pwm_adc_cb
    uint8_t hall_state_ = 0x0; // bit[0] = HallA, .., bit[2] = HallC
    float sincos_sample_s_ = 0.0f;
    float sincos_sample_c_ = 0.0f;

    // Communication protocol definitions
    auto make_protocol_definitions() {
        return make_protocol_member_list(
            make_protocol_property("error", &error_),
            make_protocol_property("is_ready", &is_ready_),
            make_protocol_property("index_found", const_cast<bool*>(&index_found_)),
            make_protocol_property("shadow_count", &shadow_count_),
            make_protocol_property("count_in_cpr", &count_in_cpr_),
            make_protocol_property("interpolation", &interpolation_),
            make_protocol_ro_property("phase", &phase_),
            make_protocol_property("pos_estimate", &pos_estimate_),
            make_protocol_property("pos_cpr", &pos_cpr_),
            make_protocol_ro_property("hall_state", &hall_state_),
            make_protocol_property("vel_estimate", &vel_estimate_),
            make_protocol_ro_property("calib_scan_response", &calib_scan_response_),
            // make_protocol_property("pll_kp", &pll_kp_),
            // make_protocol_property("pll_ki", &pll_ki_),
            make_protocol_object("config",
                make_protocol_property("mode", &config_.mode),
                make_protocol_property("use_index", &config_.use_index,
                    [](void* ctx) { static_cast<Encoder*>(ctx)->set_idx_subscribe(); }, this),
                make_protocol_property("find_idx_on_lockin_only", &config_.find_idx_on_lockin_only,
                    [](void* ctx) { static_cast<Encoder*>(ctx)->set_idx_subscribe(); }, this),
                make_protocol_property("pre_calibrated", &config_.pre_calibrated,
                    [](void* ctx) { static_cast<Encoder*>(ctx)->check_pre_calibrated(); }, this),
                make_protocol_property("zero_count_on_find_idx", &config_.zero_count_on_find_idx),
                make_protocol_property("cpr", &config_.cpr),
                make_protocol_property("offset", &config_.offset),
                make_protocol_property("offset_float", &config_.offset_float),
                make_protocol_property("enable_phase_interpolation", &config_.enable_phase_interpolation),
                make_protocol_property("bandwidth", &config_.bandwidth,
                    [](void* ctx) { static_cast<Encoder*>(ctx)->update_pll_gains(); }, this),
                make_protocol_property("calib_range", &config_.calib_range),
                make_protocol_property("calib_scan_distance", &config_.calib_scan_distance),
                make_protocol_property("calib_scan_omega", &config_.calib_scan_omega),
                make_protocol_property("idx_search_unidirectional", &config_.idx_search_unidirectional),
                make_protocol_property("ignore_illegal_hall_state", &config_.ignore_illegal_hall_state)
            ),
            make_protocol_function("set_linear_count", *this, &Encoder::set_linear_count, "count")
        );
    }
};

DEFINE_ENUM_FLAG_OPERATORS(Encoder::Error_t)

#endif // __ENCODER_HPP
<commit_msg>Make encoder properties read-only<commit_after>#ifndef __ENCODER_HPP
#define __ENCODER_HPP

#ifndef __ODRIVE_MAIN_H
#error "This file should not be included directly. Include odrive_main.h instead."
#endif

class Encoder {
public:
    enum Error_t {
        ERROR_NONE = 0,
        ERROR_UNSTABLE_GAIN = 0x01,
        ERROR_CPR_OUT_OF_RANGE = 0x02,
        ERROR_NO_RESPONSE = 0x04,
        ERROR_UNSUPPORTED_ENCODER_MODE = 0x08,
        ERROR_ILLEGAL_HALL_STATE = 0x10,
        ERROR_INDEX_NOT_FOUND_YET = 0x20,
    };

    enum Mode_t {
        MODE_INCREMENTAL,
        MODE_HALL,
        MODE_SINCOS
    };

    struct Config_t {
        Encoder::Mode_t mode = Encoder::MODE_INCREMENTAL;
        bool use_index = false;
        bool pre_calibrated = false; // If true, this means the offset stored in
                                    // configuration is valid and does not need
                                    // be determined by run_offset_calibration.
                                    // In this case the encoder will enter ready
                                    // state as soon as the index is found.
        bool zero_count_on_find_idx = true;
        int32_t cpr = (2048 * 4);   // Default resolution of CUI-AMT102 encoder,
        int32_t offset = 0;        // Offset between encoder count and rotor electrical phase
        float offset_float = 0.0f; // Sub-count phase alignment offset
        bool enable_phase_interpolation = true; // Use velocity to interpolate inside the count state
        float calib_range = 0.02f; // Accuracy required to pass encoder cpr check
        float calib_scan_distance = 16.0f * M_PI; // rad electrical
        float calib_scan_omega = 4.0f * M_PI; // rad/s electrical
        float bandwidth = 1000.0f;
        bool find_idx_on_lockin_only = false; // Only be sensitive during lockin scan constant vel state
        bool idx_search_unidirectional = false; // Only allow index search in known direction
        bool ignore_illegal_hall_state = false; // dont error on bad states like 000 or 111
    };

    Encoder(const EncoderHardwareConfig_t& hw_config,
                     Config_t& config);

    void setup();
    void set_error(Error_t error);
    bool do_checks();

    void enc_index_cb();
    void set_idx_subscribe(bool override_enable = false);
    void update_pll_gains();
    void check_pre_calibrated();

    void set_linear_count(int32_t count);
    void set_circular_count(int32_t count, bool update_offset);
    bool calib_enc_offset(float voltage_magnitude);

    bool run_index_search();
    bool run_direction_find();
    bool run_offset_calibration();
    void sample_now();
    bool update();

    const EncoderHardwareConfig_t& hw_config_;
    Config_t& config_;
    Axis* axis_ = nullptr; // set by Axis constructor

    Error_t error_ = ERROR_NONE;
    bool index_found_ = false;
    bool is_ready_ = false;
    int32_t shadow_count_ = 0;
    int32_t count_in_cpr_ = 0;
    float interpolation_ = 0.0f;
    float phase_ = 0.0f;    // [count]
    float pos_estimate_ = 0.0f;  // [count]
    float pos_cpr_ = 0.0f;  // [count]
    float vel_estimate_ = 0.0f;  // [count/s]
    float pll_kp_ = 0.0f;   // [count/s / count]
    float pll_ki_ = 0.0f;   // [(count/s^2) / count]
    float calib_scan_response_ = 0.0f; // debug report from offset calib

    int16_t tim_cnt_sample_ = 0; //
    // Updated by low_level pwm_adc_cb
    uint8_t hall_state_ = 0x0; // bit[0] = HallA, .., bit[2] = HallC
    float sincos_sample_s_ = 0.0f;
    float sincos_sample_c_ = 0.0f;

    // Communication protocol definitions
    auto make_protocol_definitions() {
        return make_protocol_member_list(
            make_protocol_property("error", &error_),
            make_protocol_ro_property("is_ready", &is_ready_),
            make_protocol_ro_property("index_found", const_cast<bool*>(&index_found_)),
            make_protocol_ro_property("shadow_count", &shadow_count_),
            make_protocol_ro_property("count_in_cpr", &count_in_cpr_),
            make_protocol_ro_property("interpolation", &interpolation_),
            make_protocol_ro_property("phase", &phase_),
            make_protocol_ro_property("pos_estimate", &pos_estimate_),
            make_protocol_ro_property("pos_cpr", &pos_cpr_),
            make_protocol_ro_property("hall_state", &hall_state_),
            make_protocol_ro_property("vel_estimate", &vel_estimate_),
            make_protocol_ro_property("calib_scan_response", &calib_scan_response_),
            // make_protocol_property("pll_kp", &pll_kp_),
            // make_protocol_property("pll_ki", &pll_ki_),
            make_protocol_object("config",
                make_protocol_property("mode", &config_.mode),
                make_protocol_property("use_index", &config_.use_index,
                    [](void* ctx) { static_cast<Encoder*>(ctx)->set_idx_subscribe(); }, this),
                make_protocol_property("find_idx_on_lockin_only", &config_.find_idx_on_lockin_only,
                    [](void* ctx) { static_cast<Encoder*>(ctx)->set_idx_subscribe(); }, this),
                make_protocol_property("pre_calibrated", &config_.pre_calibrated,
                    [](void* ctx) { static_cast<Encoder*>(ctx)->check_pre_calibrated(); }, this),
                make_protocol_property("zero_count_on_find_idx", &config_.zero_count_on_find_idx),
                make_protocol_property("cpr", &config_.cpr),
                make_protocol_property("offset", &config_.offset),
                make_protocol_property("offset_float", &config_.offset_float),
                make_protocol_property("enable_phase_interpolation", &config_.enable_phase_interpolation),
                make_protocol_property("bandwidth", &config_.bandwidth,
                    [](void* ctx) { static_cast<Encoder*>(ctx)->update_pll_gains(); }, this),
                make_protocol_property("calib_range", &config_.calib_range),
                make_protocol_property("calib_scan_distance", &config_.calib_scan_distance),
                make_protocol_property("calib_scan_omega", &config_.calib_scan_omega),
                make_protocol_property("idx_search_unidirectional", &config_.idx_search_unidirectional),
                make_protocol_property("ignore_illegal_hall_state", &config_.ignore_illegal_hall_state)
            ),
            make_protocol_function("set_linear_count", *this, &Encoder::set_linear_count, "count")
        );
    }
};

DEFINE_ENUM_FLAG_OPERATORS(Encoder::Error_t)

#endif // __ENCODER_HPP
<|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 <string>

#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/net/url_fixer_upper.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "net/test/test_server.h"

namespace {

const FilePath::CharType kDocRoot[] = FILE_PATH_LITERAL("chrome/test/data");

}  // namespace

typedef UITest RepostFormWarningTest;

#if defined(OS_WIN)
// http://crbug.com/47228
#define MAYBE_TestDoubleReload FLAKY_TestDoubleReload
#else
#define MAYBE_TestDoubleReload TestDoubleReload
#endif

TEST_F(RepostFormWarningTest, MAYBE_TestDoubleReload) {
  net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  scoped_refptr<TabProxy> tab(browser->GetTab(0));
  ASSERT_TRUE(tab.get());

  // Load a form.
  ASSERT_TRUE(tab->NavigateToURL(test_server.GetURL("files/form.html")));
  // Submit it.
  ASSERT_TRUE(tab->NavigateToURL(GURL(
      "javascript:document.getElementById('form').submit()")));

  // Try to reload it twice, checking for repost.
  tab->ReloadAsync();
  tab->ReloadAsync();

  // Navigate away from the page (this is when the test usually crashes).
  ASSERT_TRUE(tab->NavigateToURL(test_server.GetURL("bar")));
}

#if defined(OS_WIN) || defined(OS_LINUX)
// http://crbug.com/47228 && http://crbug.com/56401
#define MAYBE_TestLoginAfterRepost FLAKY_TestLoginAfterRepost
#else
#define MAYBE_TestLoginAfterRepost TestLoginAfterRepost
#endif

TEST_F(RepostFormWarningTest, MAYBE_TestLoginAfterRepost) {
  net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  scoped_refptr<TabProxy> tab(browser->GetTab(0));
  ASSERT_TRUE(tab.get());

  // Load a form.
  ASSERT_TRUE(tab->NavigateToURL(test_server.GetURL("files/form.html")));
  // Submit it.
  ASSERT_TRUE(tab->NavigateToURL(GURL(
      "javascript:document.getElementById('form').submit()")));

  // Try to reload it, checking for repost.
  tab->ReloadAsync();

  // Navigate to a page that requires authentication, bringing up another
  // tab-modal sheet.
  ASSERT_TRUE(tab->NavigateToURL(test_server.GetURL("auth-basic")));

  // Try to reload it again.
  tab->ReloadAsync();

  // Navigate away from the page.
  ASSERT_TRUE(tab->NavigateToURL(test_server.GetURL("bar")));
}
<commit_msg>Remove the FLAKY mark from RepostFormWarningTest.TestLoginAfterRepost on Linux.<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 <string>

#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/net/url_fixer_upper.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "net/test/test_server.h"

namespace {

const FilePath::CharType kDocRoot[] = FILE_PATH_LITERAL("chrome/test/data");

}  // namespace

typedef UITest RepostFormWarningTest;

#if defined(OS_WIN)
// http://crbug.com/47228
#define MAYBE_TestDoubleReload FLAKY_TestDoubleReload
#else
#define MAYBE_TestDoubleReload TestDoubleReload
#endif

TEST_F(RepostFormWarningTest, MAYBE_TestDoubleReload) {
  net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  scoped_refptr<TabProxy> tab(browser->GetTab(0));
  ASSERT_TRUE(tab.get());

  // Load a form.
  ASSERT_TRUE(tab->NavigateToURL(test_server.GetURL("files/form.html")));
  // Submit it.
  ASSERT_TRUE(tab->NavigateToURL(GURL(
      "javascript:document.getElementById('form').submit()")));

  // Try to reload it twice, checking for repost.
  tab->ReloadAsync();
  tab->ReloadAsync();

  // Navigate away from the page (this is when the test usually crashes).
  ASSERT_TRUE(tab->NavigateToURL(test_server.GetURL("bar")));
}

#if defined(OS_WIN)
// http://crbug.com/47228
#define MAYBE_TestLoginAfterRepost FLAKY_TestLoginAfterRepost
#else
#define MAYBE_TestLoginAfterRepost TestLoginAfterRepost
#endif

TEST_F(RepostFormWarningTest, MAYBE_TestLoginAfterRepost) {
  net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  scoped_refptr<TabProxy> tab(browser->GetTab(0));
  ASSERT_TRUE(tab.get());

  // Load a form.
  ASSERT_TRUE(tab->NavigateToURL(test_server.GetURL("files/form.html")));
  // Submit it.
  ASSERT_TRUE(tab->NavigateToURL(GURL(
      "javascript:document.getElementById('form').submit()")));

  // Try to reload it, checking for repost.
  tab->ReloadAsync();

  // Navigate to a page that requires authentication, bringing up another
  // tab-modal sheet.
  ASSERT_TRUE(tab->NavigateToURL(test_server.GetURL("auth-basic")));

  // Try to reload it again.
  tab->ReloadAsync();

  // Navigate away from the page.
  ASSERT_TRUE(tab->NavigateToURL(test_server.GetURL("bar")));
}
<|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/ui/input_window_dialog.h"

#include <gtk/gtk.h>

#include "app/gtk_signal.h"
#include "base/message_loop.h"
#include "base/scoped_ptr.h"
#include "base/string_piece.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/gtk/gtk_util.h"

class InputWindowDialogGtk : public InputWindowDialog {
 public:
  // Creates a dialog. Takes ownership of |delegate|.
  InputWindowDialogGtk(GtkWindow* parent,
                       const std::string& window_title,
                       const std::string& label,
                       const std::string& contents,
                       Delegate* delegate);
  virtual ~InputWindowDialogGtk();

  virtual void Show();
  virtual void Close();

 private:
  CHROMEG_CALLBACK_0(InputWindowDialogGtk, void, OnEntryChanged, GtkEditable*);
  CHROMEGTK_CALLBACK_1(InputWindowDialogGtk, void, OnResponse, int);
  CHROMEGTK_CALLBACK_1(InputWindowDialogGtk, gboolean,
                       OnWindowDeleteEvent, GdkEvent*);
  CHROMEGTK_CALLBACK_0(InputWindowDialogGtk, void, OnWindowDestroy);

  // The underlying gtk dialog window.
  GtkWidget* dialog_;

  // The GtkEntry in this form.
  GtkWidget* input_;

  // Our delegate. Consumes the window's output.
  scoped_ptr<InputWindowDialog::Delegate> delegate_;
};

InputWindowDialogGtk::InputWindowDialogGtk(GtkWindow* parent,
                                           const std::string& window_title,
                                           const std::string& label,
                                           const std::string& contents,
                                           Delegate* delegate)
    : dialog_(gtk_dialog_new_with_buttons(
                  window_title.c_str(),
                  parent,
                  GTK_DIALOG_MODAL,
                  GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
                  GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
                  NULL)),
      delegate_(delegate) {
  gtk_dialog_set_default_response(GTK_DIALOG(dialog_), GTK_RESPONSE_ACCEPT);
  gtk_dialog_set_has_separator(GTK_DIALOG(dialog_), FALSE);

  GtkWidget* content_area = GTK_DIALOG(dialog_)->vbox;
  gtk_box_set_spacing(GTK_BOX(content_area), 18);

  GtkWidget* hbox = gtk_hbox_new(FALSE, 6);
  GtkWidget* label_widget = gtk_label_new(label.c_str());
  gtk_box_pack_start(GTK_BOX(hbox), label_widget, FALSE, FALSE, 0);

  input_ = gtk_entry_new();
  gtk_entry_set_text(GTK_ENTRY(input_), contents.c_str());
  g_signal_connect(input_, "changed",
                   G_CALLBACK(OnEntryChangedThunk), this);
  g_object_set(G_OBJECT(input_), "activates-default", TRUE, NULL);
  gtk_box_pack_start(GTK_BOX(hbox), input_, TRUE, TRUE, 0);

  gtk_widget_show_all(hbox);

  gtk_box_pack_start(GTK_BOX(content_area), hbox, FALSE, FALSE, 0);

  g_signal_connect(dialog_, "response",
                   G_CALLBACK(OnResponseThunk), this);
  g_signal_connect(dialog_, "delete-event",
                   G_CALLBACK(OnWindowDeleteEventThunk), this);
  g_signal_connect(dialog_, "destroy",
                   G_CALLBACK(OnWindowDestroyThunk), this);
}

InputWindowDialogGtk::~InputWindowDialogGtk() {
}

void InputWindowDialogGtk::Show() {
  gtk_util::ShowDialog(dialog_);
}

void InputWindowDialogGtk::Close() {
  // Under the model that we've inherited from Windows, dialogs can receive
  // more than one Close() call inside the current message loop event.
  if (dialog_) {
    gtk_widget_destroy(GTK_WIDGET(dialog_));
    dialog_ = NULL;
  }
}

void InputWindowDialogGtk::OnEntryChanged(GtkEditable* entry) {
  std::wstring value(UTF8ToWide(gtk_entry_get_text(GTK_ENTRY(entry))));
  gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog_),
                                    GTK_RESPONSE_ACCEPT,
                                    delegate_->IsValid(value));
}

void InputWindowDialogGtk::OnResponse(GtkWidget* dialog, int response_id) {
  if (response_id == GTK_RESPONSE_ACCEPT) {
    std::wstring value(UTF8ToWide(gtk_entry_get_text(GTK_ENTRY(input_))));
    delegate_->InputAccepted(value);
  } else {
    delegate_->InputCanceled();
  }
  Close();
}

gboolean InputWindowDialogGtk::OnWindowDeleteEvent(GtkWidget* widget,
                                                   GdkEvent* event) {
  Close();

  // Return true to prevent the gtk dialog from being destroyed. Close will
  // destroy it for us and the default gtk_dialog_delete_event_handler() will
  // force the destruction without us being able to stop it.
  return TRUE;
}

void InputWindowDialogGtk::OnWindowDestroy(GtkWidget* widget) {
  MessageLoop::current()->DeleteSoon(FROM_HERE, this);
}

InputWindowDialog* InputWindowDialog::Create(gfx::NativeWindow parent,
                                             const std::wstring& window_title,
                                             const std::wstring& label,
                                             const std::wstring& contents,
                                             Delegate* delegate) {
  return new InputWindowDialogGtk(parent,
                                  WideToUTF8(window_title),
                                  WideToUTF8(label),
                                  WideToUTF8(contents),
                                  delegate);
}
<commit_msg>gtk: Do not make folder editor dialog resizable.<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/ui/input_window_dialog.h"

#include <gtk/gtk.h>

#include "app/gtk_signal.h"
#include "base/message_loop.h"
#include "base/scoped_ptr.h"
#include "base/string_piece.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/gtk/gtk_util.h"

class InputWindowDialogGtk : public InputWindowDialog {
 public:
  // Creates a dialog. Takes ownership of |delegate|.
  InputWindowDialogGtk(GtkWindow* parent,
                       const std::string& window_title,
                       const std::string& label,
                       const std::string& contents,
                       Delegate* delegate);
  virtual ~InputWindowDialogGtk();

  virtual void Show();
  virtual void Close();

 private:
  CHROMEG_CALLBACK_0(InputWindowDialogGtk, void, OnEntryChanged, GtkEditable*);
  CHROMEGTK_CALLBACK_1(InputWindowDialogGtk, void, OnResponse, int);
  CHROMEGTK_CALLBACK_1(InputWindowDialogGtk, gboolean,
                       OnWindowDeleteEvent, GdkEvent*);
  CHROMEGTK_CALLBACK_0(InputWindowDialogGtk, void, OnWindowDestroy);

  // The underlying gtk dialog window.
  GtkWidget* dialog_;

  // The GtkEntry in this form.
  GtkWidget* input_;

  // Our delegate. Consumes the window's output.
  scoped_ptr<InputWindowDialog::Delegate> delegate_;
};

InputWindowDialogGtk::InputWindowDialogGtk(GtkWindow* parent,
                                           const std::string& window_title,
                                           const std::string& label,
                                           const std::string& contents,
                                           Delegate* delegate)
    : dialog_(gtk_dialog_new_with_buttons(
                  window_title.c_str(),
                  parent,
                  GTK_DIALOG_MODAL,
                  GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
                  GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
                  NULL)),
      delegate_(delegate) {
  gtk_dialog_set_default_response(GTK_DIALOG(dialog_), GTK_RESPONSE_ACCEPT);
  gtk_dialog_set_has_separator(GTK_DIALOG(dialog_), FALSE);
  gtk_window_set_resizable(GTK_WINDOW(dialog_), FALSE);

  GtkWidget* content_area = GTK_DIALOG(dialog_)->vbox;
  gtk_box_set_spacing(GTK_BOX(content_area), 18);

  GtkWidget* hbox = gtk_hbox_new(FALSE, 6);
  GtkWidget* label_widget = gtk_label_new(label.c_str());
  gtk_box_pack_start(GTK_BOX(hbox), label_widget, FALSE, FALSE, 0);

  input_ = gtk_entry_new();
  gtk_entry_set_text(GTK_ENTRY(input_), contents.c_str());
  g_signal_connect(input_, "changed",
                   G_CALLBACK(OnEntryChangedThunk), this);
  g_object_set(G_OBJECT(input_), "activates-default", TRUE, NULL);
  gtk_box_pack_start(GTK_BOX(hbox), input_, TRUE, TRUE, 0);

  gtk_widget_show_all(hbox);

  gtk_box_pack_start(GTK_BOX(content_area), hbox, FALSE, FALSE, 0);

  g_signal_connect(dialog_, "response",
                   G_CALLBACK(OnResponseThunk), this);
  g_signal_connect(dialog_, "delete-event",
                   G_CALLBACK(OnWindowDeleteEventThunk), this);
  g_signal_connect(dialog_, "destroy",
                   G_CALLBACK(OnWindowDestroyThunk), this);
}

InputWindowDialogGtk::~InputWindowDialogGtk() {
}

void InputWindowDialogGtk::Show() {
  gtk_util::ShowDialog(dialog_);
}

void InputWindowDialogGtk::Close() {
  // Under the model that we've inherited from Windows, dialogs can receive
  // more than one Close() call inside the current message loop event.
  if (dialog_) {
    gtk_widget_destroy(GTK_WIDGET(dialog_));
    dialog_ = NULL;
  }
}

void InputWindowDialogGtk::OnEntryChanged(GtkEditable* entry) {
  std::wstring value(UTF8ToWide(gtk_entry_get_text(GTK_ENTRY(entry))));
  gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog_),
                                    GTK_RESPONSE_ACCEPT,
                                    delegate_->IsValid(value));
}

void InputWindowDialogGtk::OnResponse(GtkWidget* dialog, int response_id) {
  if (response_id == GTK_RESPONSE_ACCEPT) {
    std::wstring value(UTF8ToWide(gtk_entry_get_text(GTK_ENTRY(input_))));
    delegate_->InputAccepted(value);
  } else {
    delegate_->InputCanceled();
  }
  Close();
}

gboolean InputWindowDialogGtk::OnWindowDeleteEvent(GtkWidget* widget,
                                                   GdkEvent* event) {
  Close();

  // Return true to prevent the gtk dialog from being destroyed. Close will
  // destroy it for us and the default gtk_dialog_delete_event_handler() will
  // force the destruction without us being able to stop it.
  return TRUE;
}

void InputWindowDialogGtk::OnWindowDestroy(GtkWidget* widget) {
  MessageLoop::current()->DeleteSoon(FROM_HERE, this);
}

InputWindowDialog* InputWindowDialog::Create(gfx::NativeWindow parent,
                                             const std::wstring& window_title,
                                             const std::wstring& label,
                                             const std::wstring& contents,
                                             Delegate* delegate) {
  return new InputWindowDialogGtk(parent,
                                  WideToUTF8(window_title),
                                  WideToUTF8(label),
                                  WideToUTF8(contents),
                                  delegate);
}
<|endoftext|>


<commit_before>
#include "AConfig.h"
#if(HAS_STD_PILOT)
#include "Device.h"
#include "Pin.h"
#include "Pilot.h"
#include "Timer.h"

Timer pilotTimer;
bool _headingHoldEnabled = false;
int  _headingHoldTarget = 0;
int hdg = 0;
int hdg_Error;
int raw_Left, raw_Right;
int left, right;  // motor outputs in microseconds, +/-500
int loop_Gain = 1;
int integral_Divisor = 100;
long hdg_Error_Integral = 0;
int tgt_Hdg = 0;
bool _depthHoldEnabled = false;
int _depthHoldTarget = 0;
int depth = 0;
int depth_Error = 0;
int raw_lift =0;
int lift = 0;
int target_depth;
int raw_yaw, yaw;

void Pilot::device_setup(){
  pilotTimer.reset();
  Serial.println(F("log:pilot setup complete;"));
}

void Pilot::device_loop(Command command){
//intended to respond to fly by wire commands: MaintainHeading(); TurnTo(compassheading); DiveTo(depth);
    if( command.cmp("holdHeading_toggle")){
      if (_headingHoldEnabled) {
        _headingHoldEnabled = false;
        raw_Left = 0;
        raw_Right = 0;
        hdg_Error_Integral = 0;  // Reset error integrator
        tgt_Hdg = 0;  // 500 = system not in hdg hold

        int argsToSend[] = {1,00}; //include number of parms as last parm
        command.pushCommand("yaw",argsToSend);
        Serial.println(F("log:heading_hold_disabled;"));

      } else {
        _headingHoldEnabled = true;
        if(command.args[0]==0){
          _headingHoldTarget = navdata::HDGD;
        } else {
          _headingHoldTarget = command.args[1];
        }
        tgt_Hdg = _headingHoldTarget;
        Serial.print(F("log:heading_hold_enabled on="));
        Serial.print(tgt_Hdg);
        Serial.println(';');
      }
      Serial.print(F("targetHeading:"));
      Serial.print(tgt_Hdg);
      Serial.println(';');
    }

    if( command.cmp("holdDepth_toggle")){
      if (_depthHoldEnabled) {
        _depthHoldEnabled = false;
        raw_lift = 0;
        target_depth = -500;  // -500 = system not in hdg hold

        int argsToSend[] = {1,0}; //include number of parms as last parm
        command.pushCommand("lift",argsToSend);
        Serial.println(F("log:depth_hold_disabled;"));

      } else {
        _depthHoldEnabled = true;
        if(command.args[0]==0){
          _depthHoldTarget = navdata::DEAP*100;  //casting to cm
        } else {
          _depthHoldTarget = command.args[1];
        }
        target_depth = _depthHoldTarget;
        Serial.print(F("log:depth_hold_enabled on="));
        Serial.print(target_depth);
        Serial.println(';');
      }
      Serial.print(F("targetDepth:"));
      Serial.print(target_depth);
      Serial.println(';');
    }

    if (pilotTimer.elapsed (50)) {

      // Autopilot Test #3 6 Jan 2014
      // Hold vehicle at arbitrary heading
      // Integer math; proportional control plus basic integrator
      // No hysteresis around 180 degree error

      // Check whether hold mode is on

      if (_depthHoldEnabled)
      {
        depth = navdata::DEAP*100;
        depth_Error = target_depth-depth;  //positive error = positive lift = go deaper.

        raw_lift = depth_Error * loop_Gain;
        lift = constrain(raw_lift, -50, 50);

        Serial.println(F("log:dhold pushing command;"));
        Serial.print(F("dp_er:"));
        Serial.print(depth_Error);
        Serial.println(';');
        int argsToSend[] = {1,lift}; //include number of parms as last parm
        command.pushCommand("lift",argsToSend);

      }

      if (_headingHoldEnabled)
      {

        // Code for hold mode here
        hdg = navdata::HDGD;

        // Calculate heading error

        hdg_Error = hdg - tgt_Hdg;

        if (hdg_Error > 180)
        {
        hdg_Error = hdg_Error - 360;
        }

        if (hdg_Error < -179)
        {
        hdg_Error = hdg_Error + 360;
        }

        // Run error accumulator (integrator)
        hdg_Error_Integral = hdg_Error_Integral + hdg_Error;

        // Calculator motor outputs
        raw_yaw = -1 * hdg_Error * loop_Gain;

        // raw_Left = raw_Left - (hdg_Error_Integral / integral_Divisor);
        // raw_Right = raw_Right + (hdg_Error_Integral / integral_Divisor);

        // Constrain and output to motors

        yaw = constrain(raw_yaw, -50, 50);
        Serial.println(F("log:hold pushing command;"));
        Serial.print(F("p_er:"));
        Serial.print(hdg_Error);
        Serial.println(';');

        int argsToSend[] = {1,yaw}; //include number of parms as last parm
        command.pushCommand("yaw",argsToSend);
      }

    }
}
#endif

<commit_msg>Revert "Revert "Fixing heading hold disable""<commit_after>
#include "AConfig.h"
#if(HAS_STD_PILOT)
#include "Device.h"
#include "Pin.h"
#include "Pilot.h"
#include "Timer.h"

Timer pilotTimer;
bool _headingHoldEnabled = false;
int  _headingHoldTarget = 0;
int hdg = 0;
int hdg_Error;
int raw_Left, raw_Right;
int left, right;  // motor outputs in microseconds, +/-500
int loop_Gain = 1;
int integral_Divisor = 100;
long hdg_Error_Integral = 0;
int tgt_Hdg = 0;
bool _depthHoldEnabled = false;
int _depthHoldTarget = 0;
int depth = 0;
int depth_Error = 0;
int raw_lift =0;
int lift = 0;
int target_depth;
int raw_yaw, yaw;

void Pilot::device_setup(){
  pilotTimer.reset();
  Serial.println(F("log:pilot setup complete;"));
}

void Pilot::device_loop(Command command){
//intended to respond to fly by wire commands: MaintainHeading(); TurnTo(compassheading); DiveTo(depth);
    if( command.cmp("holdHeading_toggle")){
      if (_headingHoldEnabled) {
        _headingHoldEnabled = false;
        raw_Left = 0;
        raw_Right = 0;
        hdg_Error_Integral = 0;  // Reset error integrator
        tgt_Hdg = -500;  // -500 = system not in hdg hold

        int argsToSend[] = {1,00}; //include number of parms as last parm
        command.pushCommand("yaw",argsToSend);
        Serial.println(F("log:heading_hold_disabled;"));

      } else {
        _headingHoldEnabled = true;
        if(command.args[0]==0){
          _headingHoldTarget = navdata::HDGD;
        } else {
          _headingHoldTarget = command.args[1];
        }
        tgt_Hdg = _headingHoldTarget;
        Serial.print(F("log:heading_hold_enabled on="));
        Serial.print(tgt_Hdg);
        Serial.println(';');
      }
      Serial.print(F("targetHeading:"));
      Serial.print(tgt_Hdg);
      Serial.println(';');
    }

    if( command.cmp("holdDepth_toggle")){
      if (_depthHoldEnabled) {
        _depthHoldEnabled = false;
        raw_lift = 0;
        target_depth = -500;  // -500 = system not in hdg hold

        int argsToSend[] = {1,0}; //include number of parms as last parm
        command.pushCommand("lift",argsToSend);
        Serial.println(F("log:depth_hold_disabled;"));

      } else {
        _depthHoldEnabled = true;
        if(command.args[0]==0){
          _depthHoldTarget = navdata::DEAP*100;  //casting to cm
        } else {
          _depthHoldTarget = command.args[1];
        }
        target_depth = _depthHoldTarget;
        Serial.print(F("log:depth_hold_enabled on="));
        Serial.print(target_depth);
        Serial.println(';');
      }
      Serial.print(F("targetDepth:"));
      Serial.print(target_depth);
      Serial.println(';');
    }

    if (pilotTimer.elapsed (50)) {

      // Autopilot Test #3 6 Jan 2014
      // Hold vehicle at arbitrary heading
      // Integer math; proportional control plus basic integrator
      // No hysteresis around 180 degree error

      // Check whether hold mode is on

      if (_depthHoldEnabled)
      {
        depth = navdata::DEAP*100;
        depth_Error = target_depth-depth;  //positive error = positive lift = go deaper.

        raw_lift = depth_Error * loop_Gain;
        lift = constrain(raw_lift, -50, 50);

        Serial.println(F("log:dhold pushing command;"));
        Serial.print(F("dp_er:"));
        Serial.print(depth_Error);
        Serial.println(';');
        int argsToSend[] = {1,lift}; //include number of parms as last parm
        command.pushCommand("lift",argsToSend);

      }

      if (_headingHoldEnabled)
      {

        // Code for hold mode here
        hdg = navdata::HDGD;

        // Calculate heading error

        hdg_Error = hdg - tgt_Hdg;

        if (hdg_Error > 180)
        {
        hdg_Error = hdg_Error - 360;
        }

        if (hdg_Error < -179)
        {
        hdg_Error = hdg_Error + 360;
        }

        // Run error accumulator (integrator)
        hdg_Error_Integral = hdg_Error_Integral + hdg_Error;

        // Calculator motor outputs
        raw_yaw = -1 * hdg_Error * loop_Gain;

        // raw_Left = raw_Left - (hdg_Error_Integral / integral_Divisor);
        // raw_Right = raw_Right + (hdg_Error_Integral / integral_Divisor);

        // Constrain and output to motors

        yaw = constrain(raw_yaw, -50, 50);
        Serial.println(F("log:hold pushing command;"));
        Serial.print(F("p_er:"));
        Serial.print(hdg_Error);
        Serial.println(';');

        int argsToSend[] = {1,yaw}; //include number of parms as last parm
        command.pushCommand("yaw",argsToSend);
      }

    }
}
#endif

<|endoftext|>