<commit_before>// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//    * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//    * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//    * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "chrome/browser/jsmessage_box_handler.h"

#include "chrome/browser/app_modal_dialog_queue.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/web_contents.h"
#include "chrome/common/l10n_util.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/notification_types.h"
#include "chrome/views/message_box_view.h"
#include "chrome/views/window.h"

#include "generated_resources.h"

///////////////////////////////////////////////////////////////////////////////
// JavascriptMessageBoxHandler, public:

// static
void JavascriptMessageBoxHandler::RunJavascriptMessageBox(
    WebContents* web_contents,
    int dialog_flags,
    const std::wstring& message_text,
    const std::wstring& default_prompt_text,
    bool display_suppress_checkbox,
    IPC::Message* reply_msg) {
  JavascriptMessageBoxHandler* handler =
      new JavascriptMessageBoxHandler(web_contents, dialog_flags,
                                      message_text, default_prompt_text,
                                      display_suppress_checkbox, reply_msg);
  AppModalDialogQueue::AddDialog(handler);
}

JavascriptMessageBoxHandler::~JavascriptMessageBoxHandler() {
  NotificationService::current()->
      RemoveObserver(this, NOTIFY_NAV_STATE_CHANGED,
                     NotificationService::AllSources());
  NotificationService::current()->
      RemoveObserver(this, NOTIFY_TAB_CONTENTS_DESTROYED,
                     NotificationService::AllSources());
}

//////////////////////////////////////////////////////////////////////////////
// JavascriptMessageBoxHandler, ChromeViews::DialogDelegate implementation:

int JavascriptMessageBoxHandler::GetDialogButtons() const {
  int dialog_buttons = 0;
  if (dialog_flags_ & MessageBoxView::kFlagHasOKButton)
    dialog_buttons = DIALOGBUTTON_OK;

  if (dialog_flags_ & MessageBoxView::kFlagHasCancelButton)
    dialog_buttons |= DIALOGBUTTON_CANCEL;

  return dialog_buttons;
}

std::wstring JavascriptMessageBoxHandler::GetWindowTitle() const {
  if (!web_contents_)
    return std::wstring();

  GURL url = web_contents_->GetURL();
  if (!url.has_host())
    return l10n_util::GetString(IDS_JAVASCRIPT_MESSAGEBOX_DEFAULT_TITLE);

  std::string base_address = url.scheme() + "://" + url.host();
  if (url.has_port())
    base_address += ":" + url.port();
  return l10n_util::GetStringF(IDS_JAVASCRIPT_MESSAGEBOX_TITLE,
                               ASCIIToWide(base_address));
}

void JavascriptMessageBoxHandler::WindowClosing() {
  dialog_ = NULL;

  if (message_box_view_->IsCheckBoxSelected() && web_contents_)
    web_contents_->SetSuppressJavascriptMessageBoxes(true);

  delete this;
}

bool JavascriptMessageBoxHandler::Cancel() {
  // We need to do this before WM_DESTROY (WindowClosing()) as any parent frame
  // will receive it's activation messages before this dialog receives
  // WM_DESTROY. The parent frame would then try to activate any modal dialogs
  // that were still open in the ModalDialogQueue, which would send activation
  // back to this one. The framework should be improved to handle this, so this
  // is a temporary workaround.
  AppModalDialogQueue::ShowNextDialog();

  if (web_contents_) {
    web_contents_->OnJavaScriptMessageBoxClosed(reply_msg_, false,
                                                EmptyWString());
  }
  return true;
}

bool JavascriptMessageBoxHandler::Accept() {
  AppModalDialogQueue::ShowNextDialog();

  if (web_contents_) {
    web_contents_->OnJavaScriptMessageBoxClosed(
        reply_msg_, true, message_box_view_->GetInputText());
  }
  return true;
}

//////////////////////////////////////////////////////////////////////////////
// JavascriptMessageBoxHandler, ChromeViews::AppModalDialogDelegate
// implementation:

void JavascriptMessageBoxHandler::ShowModalDialog() {
  // If the WebContents that created this dialog navigated away before this
  // dialog became visible, simply show the next dialog if any.
  if (!web_contents_) {
    AppModalDialogQueue::ShowNextDialog();
    delete this;
    return;
  }

  web_contents_->Activate();
  HWND root_hwnd = GetAncestor(web_contents_->GetHWND(), GA_ROOT);
  dialog_ =
      ChromeViews::Window::CreateChromeWindow(root_hwnd, gfx::Rect(), this);
  dialog_->Show();
}

void JavascriptMessageBoxHandler::ActivateModalDialog() {
  // Ensure that the dialog is visible and at the top of the z-order. These
  // conditions may not be true if the dialog was opened on a different virtual
  // desktop to the one the browser window is on.
  dialog_->Show();
  dialog_->Activate();
}

///////////////////////////////////////////////////////////////////////////////
// JavascriptMessageBoxHandler, ChromeViews::WindowDelegate implementation:

ChromeViews::View* JavascriptMessageBoxHandler::GetContentsView() {
  return message_box_view_;
}

///////////////////////////////////////////////////////////////////////////////
// JavascriptMessageBoxHandler, private:

void JavascriptMessageBoxHandler::Observe(NotificationType type,
                                          const NotificationSource& source,
                                          const NotificationDetails& details) {
  bool web_contents_gone = false;
  if (!web_contents_)
    return;

  if (type == NOTIFY_NAV_STATE_CHANGED &&
      Source<NavigationController>(source).ptr() == web_contents_->controller())
    web_contents_gone = true;

  if (type == NOTIFY_TAB_CONTENTS_DESTROYED &&
      Source<TabContents>(source).ptr() ==
      static_cast<TabContents*>(web_contents_))
    web_contents_gone = true;

  if (web_contents_gone) {
    web_contents_ = NULL;

    // If the dialog is visible close it.
    if (dialog_)
      dialog_->Close();
  }
}

JavascriptMessageBoxHandler::JavascriptMessageBoxHandler(
    WebContents* web_contents,
    int dialog_flags,
    const std::wstring& message_text,
    const std::wstring& default_prompt_text,
    bool display_suppress_checkbox,
    IPC::Message* reply_msg)
      : web_contents_(web_contents),
        reply_msg_(reply_msg),
        dialog_flags_(dialog_flags),
        dialog_(NULL),
        message_box_view_(new MessageBoxView(dialog_flags, message_text,
                                             default_prompt_text)) {
  DCHECK(message_box_view_);
  DCHECK(reply_msg_);

  if (display_suppress_checkbox) {
    message_box_view_->SetCheckBoxLabel(
        l10n_util::GetString(IDS_JAVASCRIPT_MESSAGEBOX_SUPPRESS_OPTION));
  }

  // Make sure we get navigation notifications so we know when our parent
  // contents will disappear or navigate to a different page.
  NotificationService::current()->
      AddObserver(this, NOTIFY_NAV_STATE_CHANGED,
                  NotificationService::AllSources());
  NotificationService::current()->
      AddObserver(this, NOTIFY_TAB_CONTENTS_DESTROYED,
                  NotificationService::AllSources());
}
<commit_msg>Make Javascript alerts do IDN and proper handling of non-standard and file schemes.<commit_after>// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//    * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//    * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//    * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "chrome/browser/jsmessage_box_handler.h"

#include "chrome/browser/app_modal_dialog_queue.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/web_contents.h"
#include "chrome/common/gfx/url_elider.h"
#include "chrome/common/l10n_util.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/notification_types.h"
#include "chrome/common/pref_names.h"
#include "chrome/views/message_box_view.h"
#include "chrome/views/window.h"

#include "generated_resources.h"

///////////////////////////////////////////////////////////////////////////////
// JavascriptMessageBoxHandler, public:

// static
void JavascriptMessageBoxHandler::RunJavascriptMessageBox(
    WebContents* web_contents,
    int dialog_flags,
    const std::wstring& message_text,
    const std::wstring& default_prompt_text,
    bool display_suppress_checkbox,
    IPC::Message* reply_msg) {
  JavascriptMessageBoxHandler* handler =
      new JavascriptMessageBoxHandler(web_contents, dialog_flags,
                                      message_text, default_prompt_text,
                                      display_suppress_checkbox, reply_msg);
  AppModalDialogQueue::AddDialog(handler);
}

JavascriptMessageBoxHandler::~JavascriptMessageBoxHandler() {
  NotificationService::current()->
      RemoveObserver(this, NOTIFY_NAV_STATE_CHANGED,
                     NotificationService::AllSources());
  NotificationService::current()->
      RemoveObserver(this, NOTIFY_TAB_CONTENTS_DESTROYED,
                     NotificationService::AllSources());
}

//////////////////////////////////////////////////////////////////////////////
// JavascriptMessageBoxHandler, ChromeViews::DialogDelegate implementation:

int JavascriptMessageBoxHandler::GetDialogButtons() const {
  int dialog_buttons = 0;
  if (dialog_flags_ & MessageBoxView::kFlagHasOKButton)
    dialog_buttons = DIALOGBUTTON_OK;

  if (dialog_flags_ & MessageBoxView::kFlagHasCancelButton)
    dialog_buttons |= DIALOGBUTTON_CANCEL;

  return dialog_buttons;
}

std::wstring JavascriptMessageBoxHandler::GetWindowTitle() const {
  if (!web_contents_)
    return std::wstring();

  GURL url = web_contents_->GetURL();
  if (!url.has_host())
    return l10n_util::GetString(IDS_JAVASCRIPT_MESSAGEBOX_DEFAULT_TITLE);

  // We really only want the scheme, hostname, and port.
  GURL::Replacements replacements;
  replacements.ClearUsername();
  replacements.ClearPassword();
  replacements.ClearPath();
  replacements.ClearQuery();
  replacements.ClearRef();
  GURL clean_url = url.ReplaceComponents(replacements);

  // TODO(brettw) it should be easier than this to do the correct language
  // handling without getting the accept language from the profil.
  std::wstring base_address = gfx::ElideUrl(clean_url, ChromeFont(), 0,
      web_contents_->profile()->GetPrefs()->GetString(prefs::kAcceptLanguages));
  return l10n_util::GetStringF(IDS_JAVASCRIPT_MESSAGEBOX_TITLE, base_address);
}

void JavascriptMessageBoxHandler::WindowClosing() {
  dialog_ = NULL;

  if (message_box_view_->IsCheckBoxSelected() && web_contents_)
    web_contents_->SetSuppressJavascriptMessageBoxes(true);

  delete this;
}

bool JavascriptMessageBoxHandler::Cancel() {
  // We need to do this before WM_DESTROY (WindowClosing()) as any parent frame
  // will receive it's activation messages before this dialog receives
  // WM_DESTROY. The parent frame would then try to activate any modal dialogs
  // that were still open in the ModalDialogQueue, which would send activation
  // back to this one. The framework should be improved to handle this, so this
  // is a temporary workaround.
  AppModalDialogQueue::ShowNextDialog();

  if (web_contents_) {
    web_contents_->OnJavaScriptMessageBoxClosed(reply_msg_, false,
                                                EmptyWString());
  }
  return true;
}

bool JavascriptMessageBoxHandler::Accept() {
  AppModalDialogQueue::ShowNextDialog();

  if (web_contents_) {
    web_contents_->OnJavaScriptMessageBoxClosed(
        reply_msg_, true, message_box_view_->GetInputText());
  }
  return true;
}

//////////////////////////////////////////////////////////////////////////////
// JavascriptMessageBoxHandler, ChromeViews::AppModalDialogDelegate
// implementation:

void JavascriptMessageBoxHandler::ShowModalDialog() {
  // If the WebContents that created this dialog navigated away before this
  // dialog became visible, simply show the next dialog if any.
  if (!web_contents_) {
    AppModalDialogQueue::ShowNextDialog();
    delete this;
    return;
  }

  web_contents_->Activate();
  HWND root_hwnd = GetAncestor(web_contents_->GetHWND(), GA_ROOT);
  dialog_ =
      ChromeViews::Window::CreateChromeWindow(root_hwnd, gfx::Rect(), this);
  dialog_->Show();
}

void JavascriptMessageBoxHandler::ActivateModalDialog() {
  // Ensure that the dialog is visible and at the top of the z-order. These
  // conditions may not be true if the dialog was opened on a different virtual
  // desktop to the one the browser window is on.
  dialog_->Show();
  dialog_->Activate();
}

///////////////////////////////////////////////////////////////////////////////
// JavascriptMessageBoxHandler, ChromeViews::WindowDelegate implementation:

ChromeViews::View* JavascriptMessageBoxHandler::GetContentsView() {
  return message_box_view_;
}

///////////////////////////////////////////////////////////////////////////////
// JavascriptMessageBoxHandler, private:

void JavascriptMessageBoxHandler::Observe(NotificationType type,
                                          const NotificationSource& source,
                                          const NotificationDetails& details) {
  bool web_contents_gone = false;
  if (!web_contents_)
    return;

  if (type == NOTIFY_NAV_STATE_CHANGED &&
      Source<NavigationController>(source).ptr() == web_contents_->controller())
    web_contents_gone = true;

  if (type == NOTIFY_TAB_CONTENTS_DESTROYED &&
      Source<TabContents>(source).ptr() ==
      static_cast<TabContents*>(web_contents_))
    web_contents_gone = true;

  if (web_contents_gone) {
    web_contents_ = NULL;

    // If the dialog is visible close it.
    if (dialog_)
      dialog_->Close();
  }
}

JavascriptMessageBoxHandler::JavascriptMessageBoxHandler(
    WebContents* web_contents,
    int dialog_flags,
    const std::wstring& message_text,
    const std::wstring& default_prompt_text,
    bool display_suppress_checkbox,
    IPC::Message* reply_msg)
      : web_contents_(web_contents),
        reply_msg_(reply_msg),
        dialog_flags_(dialog_flags),
        dialog_(NULL),
        message_box_view_(new MessageBoxView(dialog_flags, message_text,
                                             default_prompt_text)) {
  DCHECK(message_box_view_);
  DCHECK(reply_msg_);

  if (display_suppress_checkbox) {
    message_box_view_->SetCheckBoxLabel(
        l10n_util::GetString(IDS_JAVASCRIPT_MESSAGEBOX_SUPPRESS_OPTION));
  }

  // Make sure we get navigation notifications so we know when our parent
  // contents will disappear or navigate to a different page.
  NotificationService::current()->
      AddObserver(this, NOTIFY_NAV_STATE_CHANGED,
                  NotificationService::AllSources());
  NotificationService::current()->
      AddObserver(this, NOTIFY_TAB_CONTENTS_DESTROYED,
                  NotificationService::AllSources());
}
<|endoftext|>


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

#include "chrome/browser/ui/tabs/dock_info.h"

#include "base/win/scoped_gdi_object.h"
#include "base/win/windows_version.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/tabs/tab.h"
#include "ui/gfx/screen.h"

namespace {

// BaseWindowFinder -----------------------------------------------------------

// Base class used to locate a window. This is intended to be used with the
// various win32 functions that iterate over windows.
//
// A subclass need only override ShouldStopIterating to determine when
// iteration should stop.
class BaseWindowFinder {
 public:
  // Creates a BaseWindowFinder with the specified set of HWNDs to ignore.
  explicit BaseWindowFinder(const std::set<HWND>& ignore) : ignore_(ignore) {}
  virtual ~BaseWindowFinder() {}

 protected:
  // Returns true if iteration should stop, false if iteration should continue.
  virtual bool ShouldStopIterating(HWND window) = 0;

  static BOOL CALLBACK WindowCallbackProc(HWND hwnd, LPARAM lParam) {
    BaseWindowFinder* finder = reinterpret_cast<BaseWindowFinder*>(lParam);
    if (finder->ignore_.find(hwnd) != finder->ignore_.end())
      return TRUE;

    return finder->ShouldStopIterating(hwnd) ? FALSE : TRUE;
  }

 private:
  const std::set<HWND>& ignore_;

  DISALLOW_COPY_AND_ASSIGN(BaseWindowFinder);
};

// TopMostFinder --------------------------------------------------------------

// Helper class to determine if a particular point of a window is not obscured
// by another window.
class TopMostFinder : public BaseWindowFinder {
 public:
  // Returns true if |window| is the topmost window at the location
  // |screen_loc|, not including the windows in |ignore|.
  static bool IsTopMostWindowAtPoint(HWND window,
                                     const gfx::Point& screen_loc,
                                     const std::set<HWND>& ignore) {
    TopMostFinder finder(window, screen_loc, ignore);
    return finder.is_top_most_;
  }

  virtual bool ShouldStopIterating(HWND hwnd) {
    if (hwnd == target_) {
      // Window is topmost, stop iterating.
      is_top_most_ = true;
      return true;
    }

    if (!IsWindowVisible(hwnd)) {
      // The window isn't visible, keep iterating.
      return false;
    }

    RECT r;
    if (!GetWindowRect(hwnd, &r) || !PtInRect(&r, screen_loc_.ToPOINT())) {
      // The window doesn't contain the point, keep iterating.
      return false;
    }

    LONG ex_styles = GetWindowLong(hwnd, GWL_EXSTYLE);
    if (ex_styles & WS_EX_TRANSPARENT || ex_styles & WS_EX_LAYERED) {
      // Mouse events fall through WS_EX_TRANSPARENT windows, so we ignore them.
      //
      // WS_EX_LAYERED is trickier. Apps like Switcher create a totally
      // transparent WS_EX_LAYERED window that is always on top. If we don't
      // ignore WS_EX_LAYERED windows and there are totally transparent
      // WS_EX_LAYERED windows then there are effectively holes on the screen
      // that the user can't reattach tabs to. So we ignore them. This is a bit
      // problematic in so far as WS_EX_LAYERED windows need not be totally
      // transparent in which case we treat chrome windows as not being obscured
      // when they really are, but this is better than not being able to
      // reattach tabs.
      return false;
    }

    // hwnd is at the point. Make sure the point is within the windows region.
    if (GetWindowRgn(hwnd, tmp_region_.Get()) == ERROR) {
      // There's no region on the window and the window contains the point. Stop
      // iterating.
      return true;
    }

    // The region is relative to the window's rect.
    BOOL is_point_in_region = PtInRegion(tmp_region_.Get(),
        screen_loc_.x() - r.left, screen_loc_.y() - r.top);
    tmp_region_ = CreateRectRgn(0, 0, 0, 0);
    // Stop iterating if the region contains the point.
    return !!is_point_in_region;
  }

 private:
  TopMostFinder(HWND window,
                const gfx::Point& screen_loc,
                const std::set<HWND>& ignore)
      : BaseWindowFinder(ignore),
        target_(window),
        screen_loc_(screen_loc),
        is_top_most_(false),
        tmp_region_(CreateRectRgn(0, 0, 0, 0)) {
    EnumWindows(WindowCallbackProc, reinterpret_cast<LPARAM>(this));
  }

  // The window we're looking for.
  HWND target_;

  // Location of window to find.
  gfx::Point screen_loc_;

  // Is target_ the top most window? This is initially false but set to true
  // in ShouldStopIterating if target_ is passed in.
  bool is_top_most_;

  base::win::ScopedRegion tmp_region_;

  DISALLOW_COPY_AND_ASSIGN(TopMostFinder);
};

// WindowFinder ---------------------------------------------------------------

// Helper class to determine if a particular point contains a window from our
// process.
class LocalProcessWindowFinder : public BaseWindowFinder {
 public:
  // Returns the hwnd from our process at screen_loc that is not obscured by
  // another window. Returns NULL otherwise.
  static HWND GetProcessWindowAtPoint(const gfx::Point& screen_loc,
                                      const std::set<HWND>& ignore) {
    LocalProcessWindowFinder finder(screen_loc, ignore);
    // Windows 8 has a window that appears first in the list of iterated
    // windows, yet is not visually on top of everything.
    // TODO(sky): figure out a better way to ignore this window.
    if (finder.result_ &&
        ((base::win::OSInfo::GetInstance()->version() >=
          base::win::VERSION_WIN8) ||
         TopMostFinder::IsTopMostWindowAtPoint(finder.result_, screen_loc,
                                               ignore))) {
      return finder.result_;
    }
    return NULL;
  }

 protected:
  virtual bool ShouldStopIterating(HWND hwnd) {
    RECT r;
    if (IsWindowVisible(hwnd) && GetWindowRect(hwnd, &r) &&
        PtInRect(&r, screen_loc_.ToPOINT())) {
      result_ = hwnd;
      return true;
    }
    return false;
  }

 private:
  LocalProcessWindowFinder(const gfx::Point& screen_loc,
                           const std::set<HWND>& ignore)
      : BaseWindowFinder(ignore),
        screen_loc_(screen_loc),
        result_(NULL) {
    EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc,
                      reinterpret_cast<LPARAM>(this));
  }

  // Position of the mouse.
  gfx::Point screen_loc_;

  // The resulting window. This is initially null but set to true in
  // ShouldStopIterating if an appropriate window is found.
  HWND result_;

  DISALLOW_COPY_AND_ASSIGN(LocalProcessWindowFinder);
};

// DockToWindowFinder ---------------------------------------------------------

// Helper class for creating a DockInfo from a specified point.
class DockToWindowFinder : public BaseWindowFinder {
 public:
  // Returns the DockInfo for the specified point. If there is no docking
  // position for the specified point the returned DockInfo has a type of NONE.
  static DockInfo GetDockInfoAtPoint(const gfx::Point& screen_loc,
                                     const std::set<HWND>& ignore) {
    DockToWindowFinder finder(screen_loc, ignore);
    if (!finder.result_.window() ||
        !TopMostFinder::IsTopMostWindowAtPoint(finder.result_.window(),
                                               finder.result_.hot_spot(),
                                               ignore)) {
      finder.result_.set_type(DockInfo::NONE);
    }
    return finder.result_;
  }

 protected:
  virtual bool ShouldStopIterating(HWND hwnd) {
    BrowserView* window = BrowserView::GetBrowserViewForNativeWindow(hwnd);
    RECT bounds;
    if (!window || !IsWindowVisible(hwnd) ||
        !GetWindowRect(hwnd, &bounds)) {
      return false;
    }

    // Check the three corners we allow docking to. We don't currently allow
    // docking to top of window as it conflicts with docking to the tab strip.
    if (CheckPoint(hwnd, bounds.left, (bounds.top + bounds.bottom) / 2,
                   DockInfo::LEFT_OF_WINDOW) ||
        CheckPoint(hwnd, bounds.right - 1, (bounds.top + bounds.bottom) / 2,
                   DockInfo::RIGHT_OF_WINDOW) ||
        CheckPoint(hwnd, (bounds.left + bounds.right) / 2, bounds.bottom - 1,
                   DockInfo::BOTTOM_OF_WINDOW)) {
      return true;
    }
    return false;
  }

 private:
  DockToWindowFinder(const gfx::Point& screen_loc,
                     const std::set<HWND>& ignore)
      : BaseWindowFinder(ignore),
        screen_loc_(screen_loc) {
    gfx::Rect work_area = gfx::Screen::GetMonitorWorkAreaNearestPoint(
        screen_loc);
    if (!work_area.IsEmpty()) {
      result_.set_monitor_bounds(work_area);
      EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc,
                        reinterpret_cast<LPARAM>(this));
    }
  }

  bool CheckPoint(HWND hwnd, int x, int y, DockInfo::Type type) {
    bool in_enable_area;
    if (DockInfo::IsCloseToPoint(screen_loc_, x, y, &in_enable_area)) {
      result_.set_in_enable_area(in_enable_area);
      result_.set_window(hwnd);
      result_.set_type(type);
      result_.set_hot_spot(gfx::Point(x, y));
      // Only show the hotspot if the monitor contains the bounds of the popup
      // window. Otherwise we end with a weird situation where the popup window
      // isn't completely visible.
      return result_.monitor_bounds().Contains(result_.GetPopupRect());
    }
    return false;
  }

  // The location to look for.
  gfx::Point screen_loc_;

  // The resulting DockInfo.
  DockInfo result_;

  DISALLOW_COPY_AND_ASSIGN(DockToWindowFinder);
};

}  // namespace

// DockInfo -------------------------------------------------------------------

// static
DockInfo DockInfo::GetDockInfoAtPoint(const gfx::Point& screen_point,
                                      const std::set<HWND>& ignore) {
  if (factory_)
    return factory_->GetDockInfoAtPoint(screen_point, ignore);

  // Try docking to a window first.
  DockInfo info = DockToWindowFinder::GetDockInfoAtPoint(screen_point, ignore);
  if (info.type() != DockInfo::NONE)
    return info;

  // No window relative positions. Try monitor relative positions.
  const gfx::Rect& m_bounds = info.monitor_bounds();
  int mid_x = m_bounds.x() + m_bounds.width() / 2;
  int mid_y = m_bounds.y() + m_bounds.height() / 2;

  bool result =
      info.CheckMonitorPoint(screen_point, mid_x, m_bounds.y(),
                             DockInfo::MAXIMIZE) ||
      info.CheckMonitorPoint(screen_point, mid_x, m_bounds.bottom(),
                             DockInfo::BOTTOM_HALF) ||
      info.CheckMonitorPoint(screen_point, m_bounds.x(), mid_y,
                             DockInfo::LEFT_HALF) ||
      info.CheckMonitorPoint(screen_point, m_bounds.right(), mid_y,
                             DockInfo::RIGHT_HALF);

  return info;
}

HWND DockInfo::GetLocalProcessWindowAtPoint(const gfx::Point& screen_point,
                                            const std::set<HWND>& ignore) {
  if (factory_)
    return factory_->GetLocalProcessWindowAtPoint(screen_point, ignore);
  return
      LocalProcessWindowFinder::GetProcessWindowAtPoint(screen_point, ignore);
}

bool DockInfo::GetWindowBounds(gfx::Rect* bounds) const {
  RECT window_rect;
  if (!window() || !GetWindowRect(window(), &window_rect))
    return false;
  *bounds = gfx::Rect(window_rect);
  return true;
}

void DockInfo::SizeOtherWindowTo(const gfx::Rect& bounds) const {
  if (IsZoomed(window())) {
    // We're docking relative to another window, we need to make sure the
    // window we're docking to isn't maximized.
    ShowWindow(window(), SW_RESTORE | SW_SHOWNA);
  }
  SetWindowPos(window(), HWND_TOP, bounds.x(), bounds.y(), bounds.width(),
               bounds.height(), SWP_NOACTIVATE | SWP_NOOWNERZORDER);
}
<commit_msg>Makes casts in DockInfoWin consistant.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/tabs/dock_info.h"

#include "base/win/scoped_gdi_object.h"
#include "base/win/windows_version.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/tabs/tab.h"
#include "ui/gfx/screen.h"

namespace {

// BaseWindowFinder -----------------------------------------------------------

// Base class used to locate a window. This is intended to be used with the
// various win32 functions that iterate over windows.
//
// A subclass need only override ShouldStopIterating to determine when
// iteration should stop.
class BaseWindowFinder {
 public:
  // Creates a BaseWindowFinder with the specified set of HWNDs to ignore.
  explicit BaseWindowFinder(const std::set<HWND>& ignore) : ignore_(ignore) {}
  virtual ~BaseWindowFinder() {}

 protected:
  static BOOL CALLBACK WindowCallbackProc(HWND hwnd, LPARAM lParam) {
    // Cast must match that in as_lparam().
    BaseWindowFinder* finder = reinterpret_cast<BaseWindowFinder*>(lParam);
    if (finder->ignore_.find(hwnd) != finder->ignore_.end())
      return TRUE;

    return finder->ShouldStopIterating(hwnd) ? FALSE : TRUE;
  }

  LPARAM as_lparam() {
    // Cast must match that in WindowCallbackProc().
    return reinterpret_cast<LPARAM>(static_cast<BaseWindowFinder*>(this));
  }

  // Returns true if iteration should stop, false if iteration should continue.
  virtual bool ShouldStopIterating(HWND window) = 0;

 private:
  const std::set<HWND>& ignore_;

  DISALLOW_COPY_AND_ASSIGN(BaseWindowFinder);
};

// TopMostFinder --------------------------------------------------------------

// Helper class to determine if a particular point of a window is not obscured
// by another window.
class TopMostFinder : public BaseWindowFinder {
 public:
  // Returns true if |window| is the topmost window at the location
  // |screen_loc|, not including the windows in |ignore|.
  static bool IsTopMostWindowAtPoint(HWND window,
                                     const gfx::Point& screen_loc,
                                     const std::set<HWND>& ignore) {
    TopMostFinder finder(window, screen_loc, ignore);
    return finder.is_top_most_;
  }

  virtual bool ShouldStopIterating(HWND hwnd) {
    if (hwnd == target_) {
      // Window is topmost, stop iterating.
      is_top_most_ = true;
      return true;
    }

    if (!IsWindowVisible(hwnd)) {
      // The window isn't visible, keep iterating.
      return false;
    }

    RECT r;
    if (!GetWindowRect(hwnd, &r) || !PtInRect(&r, screen_loc_.ToPOINT())) {
      // The window doesn't contain the point, keep iterating.
      return false;
    }

    LONG ex_styles = GetWindowLong(hwnd, GWL_EXSTYLE);
    if (ex_styles & WS_EX_TRANSPARENT || ex_styles & WS_EX_LAYERED) {
      // Mouse events fall through WS_EX_TRANSPARENT windows, so we ignore them.
      //
      // WS_EX_LAYERED is trickier. Apps like Switcher create a totally
      // transparent WS_EX_LAYERED window that is always on top. If we don't
      // ignore WS_EX_LAYERED windows and there are totally transparent
      // WS_EX_LAYERED windows then there are effectively holes on the screen
      // that the user can't reattach tabs to. So we ignore them. This is a bit
      // problematic in so far as WS_EX_LAYERED windows need not be totally
      // transparent in which case we treat chrome windows as not being obscured
      // when they really are, but this is better than not being able to
      // reattach tabs.
      return false;
    }

    // hwnd is at the point. Make sure the point is within the windows region.
    if (GetWindowRgn(hwnd, tmp_region_.Get()) == ERROR) {
      // There's no region on the window and the window contains the point. Stop
      // iterating.
      return true;
    }

    // The region is relative to the window's rect.
    BOOL is_point_in_region = PtInRegion(tmp_region_.Get(),
        screen_loc_.x() - r.left, screen_loc_.y() - r.top);
    tmp_region_ = CreateRectRgn(0, 0, 0, 0);
    // Stop iterating if the region contains the point.
    return !!is_point_in_region;
  }

 private:
  TopMostFinder(HWND window,
                const gfx::Point& screen_loc,
                const std::set<HWND>& ignore)
      : BaseWindowFinder(ignore),
        target_(window),
        screen_loc_(screen_loc),
        is_top_most_(false),
        tmp_region_(CreateRectRgn(0, 0, 0, 0)) {
    EnumWindows(WindowCallbackProc, as_lparam());
  }

  // The window we're looking for.
  HWND target_;

  // Location of window to find.
  gfx::Point screen_loc_;

  // Is target_ the top most window? This is initially false but set to true
  // in ShouldStopIterating if target_ is passed in.
  bool is_top_most_;

  base::win::ScopedRegion tmp_region_;

  DISALLOW_COPY_AND_ASSIGN(TopMostFinder);
};

// WindowFinder ---------------------------------------------------------------

// Helper class to determine if a particular point contains a window from our
// process.
class LocalProcessWindowFinder : public BaseWindowFinder {
 public:
  // Returns the hwnd from our process at screen_loc that is not obscured by
  // another window. Returns NULL otherwise.
  static HWND GetProcessWindowAtPoint(const gfx::Point& screen_loc,
                                      const std::set<HWND>& ignore) {
    LocalProcessWindowFinder finder(screen_loc, ignore);
    // Windows 8 has a window that appears first in the list of iterated
    // windows, yet is not visually on top of everything.
    // TODO(sky): figure out a better way to ignore this window.
    if (finder.result_ &&
        ((base::win::OSInfo::GetInstance()->version() >=
          base::win::VERSION_WIN8) ||
         TopMostFinder::IsTopMostWindowAtPoint(finder.result_, screen_loc,
                                               ignore))) {
      return finder.result_;
    }
    return NULL;
  }

 protected:
  virtual bool ShouldStopIterating(HWND hwnd) {
    RECT r;
    if (IsWindowVisible(hwnd) && GetWindowRect(hwnd, &r) &&
        PtInRect(&r, screen_loc_.ToPOINT())) {
      result_ = hwnd;
      return true;
    }
    return false;
  }

 private:
  LocalProcessWindowFinder(const gfx::Point& screen_loc,
                           const std::set<HWND>& ignore)
      : BaseWindowFinder(ignore),
        screen_loc_(screen_loc),
        result_(NULL) {
    EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc, as_lparam());
  }

  // Position of the mouse.
  gfx::Point screen_loc_;

  // The resulting window. This is initially null but set to true in
  // ShouldStopIterating if an appropriate window is found.
  HWND result_;

  DISALLOW_COPY_AND_ASSIGN(LocalProcessWindowFinder);
};

// DockToWindowFinder ---------------------------------------------------------

// Helper class for creating a DockInfo from a specified point.
class DockToWindowFinder : public BaseWindowFinder {
 public:
  // Returns the DockInfo for the specified point. If there is no docking
  // position for the specified point the returned DockInfo has a type of NONE.
  static DockInfo GetDockInfoAtPoint(const gfx::Point& screen_loc,
                                     const std::set<HWND>& ignore) {
    DockToWindowFinder finder(screen_loc, ignore);
    if (!finder.result_.window() ||
        !TopMostFinder::IsTopMostWindowAtPoint(finder.result_.window(),
                                               finder.result_.hot_spot(),
                                               ignore)) {
      finder.result_.set_type(DockInfo::NONE);
    }
    return finder.result_;
  }

 protected:
  virtual bool ShouldStopIterating(HWND hwnd) {
    BrowserView* window = BrowserView::GetBrowserViewForNativeWindow(hwnd);
    RECT bounds;
    if (!window || !IsWindowVisible(hwnd) ||
        !GetWindowRect(hwnd, &bounds)) {
      return false;
    }

    // Check the three corners we allow docking to. We don't currently allow
    // docking to top of window as it conflicts with docking to the tab strip.
    if (CheckPoint(hwnd, bounds.left, (bounds.top + bounds.bottom) / 2,
                   DockInfo::LEFT_OF_WINDOW) ||
        CheckPoint(hwnd, bounds.right - 1, (bounds.top + bounds.bottom) / 2,
                   DockInfo::RIGHT_OF_WINDOW) ||
        CheckPoint(hwnd, (bounds.left + bounds.right) / 2, bounds.bottom - 1,
                   DockInfo::BOTTOM_OF_WINDOW)) {
      return true;
    }
    return false;
  }

 private:
  DockToWindowFinder(const gfx::Point& screen_loc,
                     const std::set<HWND>& ignore)
      : BaseWindowFinder(ignore),
        screen_loc_(screen_loc) {
    gfx::Rect work_area = gfx::Screen::GetMonitorWorkAreaNearestPoint(
        screen_loc);
    if (!work_area.IsEmpty()) {
      result_.set_monitor_bounds(work_area);
      EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc, as_lparam());
    }
  }

  bool CheckPoint(HWND hwnd, int x, int y, DockInfo::Type type) {
    bool in_enable_area;
    if (DockInfo::IsCloseToPoint(screen_loc_, x, y, &in_enable_area)) {
      result_.set_in_enable_area(in_enable_area);
      result_.set_window(hwnd);
      result_.set_type(type);
      result_.set_hot_spot(gfx::Point(x, y));
      // Only show the hotspot if the monitor contains the bounds of the popup
      // window. Otherwise we end with a weird situation where the popup window
      // isn't completely visible.
      return result_.monitor_bounds().Contains(result_.GetPopupRect());
    }
    return false;
  }

  // The location to look for.
  gfx::Point screen_loc_;

  // The resulting DockInfo.
  DockInfo result_;

  DISALLOW_COPY_AND_ASSIGN(DockToWindowFinder);
};

}  // namespace

// DockInfo -------------------------------------------------------------------

// static
DockInfo DockInfo::GetDockInfoAtPoint(const gfx::Point& screen_point,
                                      const std::set<HWND>& ignore) {
  if (factory_)
    return factory_->GetDockInfoAtPoint(screen_point, ignore);

  // Try docking to a window first.
  DockInfo info = DockToWindowFinder::GetDockInfoAtPoint(screen_point, ignore);
  if (info.type() != DockInfo::NONE)
    return info;

  // No window relative positions. Try monitor relative positions.
  const gfx::Rect& m_bounds = info.monitor_bounds();
  int mid_x = m_bounds.x() + m_bounds.width() / 2;
  int mid_y = m_bounds.y() + m_bounds.height() / 2;

  bool result =
      info.CheckMonitorPoint(screen_point, mid_x, m_bounds.y(),
                             DockInfo::MAXIMIZE) ||
      info.CheckMonitorPoint(screen_point, mid_x, m_bounds.bottom(),
                             DockInfo::BOTTOM_HALF) ||
      info.CheckMonitorPoint(screen_point, m_bounds.x(), mid_y,
                             DockInfo::LEFT_HALF) ||
      info.CheckMonitorPoint(screen_point, m_bounds.right(), mid_y,
                             DockInfo::RIGHT_HALF);

  return info;
}

HWND DockInfo::GetLocalProcessWindowAtPoint(const gfx::Point& screen_point,
                                            const std::set<HWND>& ignore) {
  if (factory_)
    return factory_->GetLocalProcessWindowAtPoint(screen_point, ignore);
  return
      LocalProcessWindowFinder::GetProcessWindowAtPoint(screen_point, ignore);
}

bool DockInfo::GetWindowBounds(gfx::Rect* bounds) const {
  RECT window_rect;
  if (!window() || !GetWindowRect(window(), &window_rect))
    return false;
  *bounds = gfx::Rect(window_rect);
  return true;
}

void DockInfo::SizeOtherWindowTo(const gfx::Rect& bounds) const {
  if (IsZoomed(window())) {
    // We're docking relative to another window, we need to make sure the
    // window we're docking to isn't maximized.
    ShowWindow(window(), SW_RESTORE | SW_SHOWNA);
  }
  SetWindowPos(window(), HWND_TOP, bounds.x(), bounds.y(), bounds.width(),
               bounds.height(), SWP_NOACTIVATE | SWP_NOOWNERZORDER);
}
<|endoftext|>


<commit_before>/*
Copyright (c) 2010, Roger Light <roger@atchoo.org>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
3. Neither the name of mosquitto nor the names of its
   contributors may be used to endorse or promote products derived from
   this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/

#include <stdint.h>
#include <cstdlib>
#include <mosquitto.h>
#include <mosquittopp.h>

mosquittopp::mosquittopp()
{
}

mosquittopp::~mosquittopp()
{
}

int mosquittopp::connect(const char *host, int port)
{
	return 0;
}

int mosquittopp::disconnect()
{
	return 0;
}

int mosquittopp::publish(const char *topic, uint32_t payloadlen, const uint8_t *payload, int qos, bool retain)
{
	return 0;
}

int mosquittopp::subscribe(const char *sub, int qos)
{
	return 0;
}

int mosquittopp::unsubscribe(const char *sub)
{
	return 0;
}

int mosquittopp::loop()
{
	return 0;
}

int mosquittopp::read()
{
	return 0;
}

int mosquittopp::write()
{
	return 0;
}

<commit_msg>Call C functions from C++ class functions.<commit_after>/*
Copyright (c) 2010, Roger Light <roger@atchoo.org>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
3. Neither the name of mosquitto nor the names of its
   contributors may be used to endorse or promote products derived from
   this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/

#include <stdint.h>
#include <cstdlib>
#include <mosquitto.h>
#include <mosquittopp.h>

mosquittopp::mosquittopp()
{
}

mosquittopp::~mosquittopp()
{
}

int mosquittopp::connect(const char *host, int port)
{
	return mosquitto_connect(mosq, host, port);
}

int mosquittopp::disconnect()
{
	return mosquitto_disconnect(mosq);
}

int mosquittopp::publish(const char *topic, uint32_t payloadlen, const uint8_t *payload, int qos, bool retain)
{
	return mosquitto_publish(mosq, topic, payloadlen, payload, qos, retain);
}

int mosquittopp::subscribe(const char *sub, int qos)
{
	return mosquitto_subscribe(mosq, sub, qos);
}

int mosquittopp::unsubscribe(const char *sub)
{
	return mosquitto_unsubscribe(mosq, sub);
}

int mosquittopp::loop()
{
	return mosquitto_loop(mosq);
}

int mosquittopp::read()
{
	return mosquitto_read(mosq);
}

int mosquittopp::write()
{
	return mosquitto_write(mosq);
}

<|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/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/service/service_process_control.h"
#include "chrome/browser/service/service_process_control_manager.h"
#include "chrome/common/service_process_type.h"

class ServiceProcessControlBrowserTest
    : public InProcessBrowserTest,
      public ServiceProcessControl::MessageHandler {
 protected:
  void LaunchServiceProcessControl() {
    ServiceProcessControl* process =
        ServiceProcessControlManager::instance()->GetProcessControl(
            browser()->profile(), kServiceProcessCloudPrint);
    process_ = process;

    // Launch the process asynchronously.
    process->Launch(
        NewRunnableMethod(
            this,
            &ServiceProcessControlBrowserTest::ProcessControlLaunched));

    // Then run the message loop to keep things running.
    ui_test_utils::RunMessageLoop();
  }

  void SayHelloAndWait() {
   // Send a hello message to the service process and wait for a reply.
    process()->SendHello();
    ui_test_utils::RunMessageLoop();
  }

  void ProcessControlLaunched() {
    process()->SetMessageHandler(this);
    // Quit the current message.
    MessageLoop::current()->Quit();
  }

  // ServiceProcessControl::MessageHandler implementations.
  virtual void OnGoodDay() {
    MessageLoop::current()->Quit();
  }

  ServiceProcessControl* process() { return process_; }

 private:
  ServiceProcessControl* process_;
};

#if defined(OS_WIN)
// They way that the IPC is implemented only works on windows. This has to
// change when we implement a different scheme for IPC.
IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, LaunchAndIPC) {
  LaunchServiceProcessControl();

  // Make sure we are connected to the service process.
  EXPECT_TRUE(process()->is_connected());
  SayHelloAndWait();

  // And then shutdown the service process.
  EXPECT_TRUE(process()->Shutdown());
}

// This tests the case when a service process is launched when browser
// starts but we try to launch it again in the remoting setup dialog.
IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, DISABLED_LaunchTwice) {
  // Launch the service process the first time.
  LaunchServiceProcessControl();

  // Make sure we are connected to the service process.
  EXPECT_TRUE(process()->is_connected());
  SayHelloAndWait();

  // Launch the service process again.
  LaunchServiceProcessControl();
  EXPECT_TRUE(process()->is_connected());
  SayHelloAndWait();

  // And then shutdown the service process.
  EXPECT_TRUE(process()->Shutdown());
}
#endif

DISABLE_RUNNABLE_METHOD_REFCOUNT(ServiceProcessControlBrowserTest);
<commit_msg>Enable ServiceProcessControlTest.LaunchTwice<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/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/service/service_process_control.h"
#include "chrome/browser/service/service_process_control_manager.h"
#include "chrome/common/service_process_type.h"

class ServiceProcessControlBrowserTest
    : public InProcessBrowserTest,
      public ServiceProcessControl::MessageHandler {
 protected:
  void LaunchServiceProcessControl() {
    ServiceProcessControl* process =
        ServiceProcessControlManager::instance()->GetProcessControl(
            browser()->profile(), kServiceProcessCloudPrint);
    process_ = process;

    // Launch the process asynchronously.
    process->Launch(
        NewRunnableMethod(
            this,
            &ServiceProcessControlBrowserTest::ProcessControlLaunched));

    // Then run the message loop to keep things running.
    ui_test_utils::RunMessageLoop();
  }

  void SayHelloAndWait() {
   // Send a hello message to the service process and wait for a reply.
    process()->SendHello();
    ui_test_utils::RunMessageLoop();
  }

  void ProcessControlLaunched() {
    process()->SetMessageHandler(this);
    // Quit the current message.
    MessageLoop::current()->PostTask(FROM_HERE,
        new MessageLoop::QuitTask());
  }

  // ServiceProcessControl::MessageHandler implementations.
  virtual void OnGoodDay() {
    MessageLoop::current()->PostTask(FROM_HERE,
        new MessageLoop::QuitTask());
  }

  ServiceProcessControl* process() { return process_; }

 private:
  ServiceProcessControl* process_;
};

#if defined(OS_WIN)
// They way that the IPC is implemented only works on windows. This has to
// change when we implement a different scheme for IPC.
IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, LaunchAndIPC) {
  LaunchServiceProcessControl();

  // Make sure we are connected to the service process.
  EXPECT_TRUE(process()->is_connected());
  SayHelloAndWait();

  // And then shutdown the service process.
  EXPECT_TRUE(process()->Shutdown());
}

// This tests the case when a service process is launched when browser
// starts but we try to launch it again in the remoting setup dialog.
IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, LaunchTwice) {
  // Launch the service process the first time.
  LaunchServiceProcessControl();

  // Make sure we are connected to the service process.
  EXPECT_TRUE(process()->is_connected());
  SayHelloAndWait();

  // Launch the service process again.
  LaunchServiceProcessControl();
  EXPECT_TRUE(process()->is_connected());
  SayHelloAndWait();

  // And then shutdown the service process.
  EXPECT_TRUE(process()->Shutdown());
}
#endif

DISABLE_RUNNABLE_METHOD_REFCOUNT(ServiceProcessControlBrowserTest);
<|endoftext|>


<commit_before>#define SASS_COLOR_NAMES

namespace Sass {

  const char* color_names[] =
  {
    "aliceblue",
    "antiquewhite",
    "aqua",
    "aquamarine",
    "azure",
    "beige",
    "bisque",
    "black",
    "blanchedalmond",
    "blue",
    "blueviolet",
    "brown",
    "burlywood",
    "cadetblue",
    "chartreuse",
    "chocolate",
    "coral",
    "cornflowerblue",
    "cornsilk",
    "crimson",
    "cyan",
    "darkblue",
    "darkcyan",
    "darkgoldenrod",
    "darkgray",
    "darkgrey",
    "darkgreen",
    "darkkhaki",
    "darkmagenta",
    "darkolivegreen",
    "darkorange",
    "darkorchid",
    "darkred",
    "darksalmon",
    "darkseagreen",
    "darkslateblue",
    "darkslategray",
    "darkslategrey",
    "darkturquoise",
    "darkviolet",
    "deeppink",
    "deepskyblue",
    "dimgray",
    "dimgrey",
    "dodgerblue",
    "firebrick",
    "floralwhite",
    "forestgreen",
    "fuchsia",
    "gainsboro",
    "ghostwhite",
    "gold",
    "goldenrod",
    "gray",
    "grey",
    "green",
    "greenyellow",
    "honeydew",
    "hotpink",
    "indianred",
    "indigo",
    "ivory",
    "khaki",
    "lavender",
    "lavenderblush",
    "lawngreen",
    "lemonchiffon",
    "lightblue",
    "lightcoral",
    "lightcyan",
    "lightgoldenrodyellow",
    "lightgray",
    "lightgrey",
    "lightgreen",
    "lightpink",
    "lightsalmon",
    "lightseagreen",
    "lightskyblue",
    "lightslategray",
    "lightslategrey",
    "lightsteelblue",
    "lightyellow",
    "lime",
    "limegreen",
    "linen",
    "magenta",
    "maroon",
    "mediumaquamarine",
    "mediumblue",
    "mediumorchid",
    "mediumpurple",
    "mediumseagreen",
    "mediumslateblue",
    "mediumspringgreen",
    "mediumturquoise",
    "mediumvioletred",
    "midnightblue",
    "mintcream",
    "mistyrose",
    "moccasin",
    "navajowhite",
    "navy",
    "oldlace",
    "olive",
    "olivedrab",
    "orange",
    "orangered",
    "orchid",
    "palegoldenrod",
    "palegreen",
    "paleturquoise",
    "palevioletred",
    "papayawhip",
    "peachpuff",
    "peru",
    "pink",
    "plum",
    "powderblue",
    "purple",
    "red",
    "rosybrown",
    "royalblue",
    "saddlebrown",
    "salmon",
    "sandybrown",
    "seagreen",
    "seashell",
    "sienna",
    "silver",
    "skyblue",
    "slateblue",
    "slategray",
    "slategrey",
    "snow",
    "springgreen",
    "steelblue",
    "tan",
    "teal",
    "thistle",
    "tomato",
    "turquoise",
    "violet",
    "wheat",
    "white",
    "whitesmoke",
    "yellow",
    "yellowgreen",
    // sentinel value
    0
  };

  const double color_values[] =
  {
    0xf0, 0xf8, 0xff,
    0xfa, 0xeb, 0xd7,
    0x00, 0xff, 0xff,
    0x7f, 0xff, 0xd4,
    0xf0, 0xff, 0xff,
    0xf5, 0xf5, 0xdc,
    0xff, 0xe4, 0xc4,
    0x00, 0x00, 0x00,
    0xff, 0xeb, 0xcd,
    0x00, 0x00, 0xff,
    0x8a, 0x2b, 0xe2,
    0xa5, 0x2a, 0x2a,
    0xde, 0xb8, 0x87,
    0x5f, 0x9e, 0xa0,
    0x7f, 0xff, 0x00,
    0xd2, 0x69, 0x1e,
    0xff, 0x7f, 0x50,
    0x64, 0x95, 0xed,
    0xff, 0xf8, 0xdc,
    0xdc, 0x14, 0x3c,
    0x00, 0xff, 0xff,
    0x00, 0x00, 0x8b,
    0x00, 0x8b, 0x8b,
    0xb8, 0x86, 0x0b,
    0xa9, 0xa9, 0xa9,
    0xa9, 0xa9, 0xa9,
    0x00, 0x64, 0x00,
    0xbd, 0xb7, 0x6b,
    0x8b, 0x00, 0x8b,
    0x55, 0x6b, 0x2f,
    0xff, 0x8c, 0x00,
    0x99, 0x32, 0xcc,
    0x8b, 0x00, 0x00,
    0xe9, 0x96, 0x7a,
    0x8f, 0xbc, 0x8f,
    0x48, 0x3d, 0x8b,
    0x2f, 0x4f, 0x4f,
    0x2f, 0x4f, 0x4f,
    0x00, 0xce, 0xd1,
    0x94, 0x00, 0xd3,
    0xff, 0x14, 0x93,
    0x00, 0xbf, 0xff,
    0x69, 0x69, 0x69,
    0x69, 0x69, 0x69,
    0x1e, 0x90, 0xff,
    0xb2, 0x22, 0x22,
    0xff, 0xfa, 0xf0,
    0x22, 0x8b, 0x22,
    0xff, 0x00, 0xff,
    0xdc, 0xdc, 0xdc,
    0xf8, 0xf8, 0xff,
    0xff, 0xd7, 0x00,
    0xda, 0xa5, 0x20,
    0x80, 0x80, 0x80,
    0x80, 0x80, 0x80,
    0x00, 0x80, 0x00,
    0xad, 0xff, 0x2f,
    0xf0, 0xff, 0xf0,
    0xff, 0x69, 0xb4,
    0xcd, 0x5c, 0x5c,
    0x4b, 0x00, 0x82,
    0xff, 0xff, 0xf0,
    0xf0, 0xe6, 0x8c,
    0xe6, 0xe6, 0xfa,
    0xff, 0xf0, 0xf5,
    0x7c, 0xfc, 0x00,
    0xff, 0xfa, 0xcd,
    0xad, 0xd8, 0xe6,
    0xf0, 0x80, 0x80,
    0xe0, 0xff, 0xff,
    0xfa, 0xfa, 0xd2,
    0xd3, 0xd3, 0xd3,
    0xd3, 0xd3, 0xd3,
    0x90, 0xee, 0x90,
    0xff, 0xb6, 0xc1,
    0xff, 0xa0, 0x7a,
    0x20, 0xb2, 0xaa,
    0x87, 0xce, 0xfa,
    0x77, 0x88, 0x99,
    0x77, 0x88, 0x99,
    0xb0, 0xc4, 0xde,
    0xff, 0xff, 0xe0,
    0x00, 0xff, 0x00,
    0x32, 0xcd, 0x32,
    0xfa, 0xf0, 0xe6,
    0xff, 0x00, 0xff,
    0x80, 0x00, 0x00,
    0x66, 0xcd, 0xaa,
    0x00, 0x00, 0xcd,
    0xba, 0x55, 0xd3,
    0x93, 0x70, 0xd8,
    0x3c, 0xb3, 0x71,
    0x7b, 0x68, 0xee,
    0x00, 0xfa, 0x9a,
    0x48, 0xd1, 0xcc,
    0xc7, 0x15, 0x85,
    0x19, 0x19, 0x70,
    0xf5, 0xff, 0xfa,
    0xff, 0xe4, 0xe1,
    0xff, 0xe4, 0xb5,
    0xff, 0xde, 0xad,
    0x00, 0x00, 0x80,
    0xfd, 0xf5, 0xe6,
    0x80, 0x80, 0x00,
    0x6b, 0x8e, 0x23,
    0xff, 0xa5, 0x00,
    0xff, 0x45, 0x00,
    0xda, 0x70, 0xd6,
    0xee, 0xe8, 0xaa,
    0x98, 0xfb, 0x98,
    0xaf, 0xee, 0xee,
    0xd8, 0x70, 0x93,
    0xff, 0xef, 0xd5,
    0xff, 0xda, 0xb9,
    0xcd, 0x85, 0x3f,
    0xff, 0xc0, 0xcb,
    0xdd, 0xa0, 0xdd,
    0xb0, 0xe0, 0xe6,
    0x80, 0x00, 0x80,
    0xff, 0x00, 0x00,
    0xbc, 0x8f, 0x8f,
    0x41, 0x69, 0xe1,
    0x8b, 0x45, 0x13,
    0xfa, 0x80, 0x72,
    0xf4, 0xa4, 0x60,
    0x2e, 0x8b, 0x57,
    0xff, 0xf5, 0xee,
    0xa0, 0x52, 0x2d,
    0xc0, 0xc0, 0xc0,
    0x87, 0xce, 0xeb,
    0x6a, 0x5a, 0xcd,
    0x70, 0x80, 0x90,
    0x70, 0x80, 0x90,
    0xff, 0xfa, 0xfa,
    0x00, 0xff, 0x7f,
    0x46, 0x82, 0xb4,
    0xd2, 0xb4, 0x8c,
    0x00, 0x80, 0x80,
    0xd8, 0xbf, 0xd8,
    0xff, 0x63, 0x47,
    0x40, 0xe0, 0xd0,
    0xee, 0x82, 0xee,
    0xf5, 0xde, 0xb3,
    0xff, 0xff, 0xff,
    0xf5, 0xf5, 0xf5,
    0xff, 0xff, 0x00,
    0x9a, 0xcd, 0x32,
    // sentinel value
    0xfff
  };

}
<commit_msg>prefer "gray" to "grey" when converting colors to names<commit_after>#define SASS_COLOR_NAMES

namespace Sass {

  const char* color_names[] =
  {
    "aliceblue",
    "antiquewhite",
    "aqua",
    "aquamarine",
    "azure",
    "beige",
    "bisque",
    "black",
    "blanchedalmond",
    "blue",
    "blueviolet",
    "brown",
    "burlywood",
    "cadetblue",
    "chartreuse",
    "chocolate",
    "coral",
    "cornflowerblue",
    "cornsilk",
    "crimson",
    "cyan",
    "darkblue",
    "darkcyan",
    "darkgoldenrod",
    "darkgrey",
    "darkgray",
    "darkgreen",
    "darkkhaki",
    "darkmagenta",
    "darkolivegreen",
    "darkorange",
    "darkorchid",
    "darkred",
    "darksalmon",
    "darkseagreen",
    "darkslateblue",
    "darkslategrey",
    "darkslategray",
    "darkturquoise",
    "darkviolet",
    "deeppink",
    "deepskyblue",
    "dimgrey",
    "dimgray",
    "dodgerblue",
    "firebrick",
    "floralwhite",
    "forestgreen",
    "fuchsia",
    "gainsboro",
    "ghostwhite",
    "gold",
    "goldenrod",
    "grey",
    "gray",
    "green",
    "greenyellow",
    "honeydew",
    "hotpink",
    "indianred",
    "indigo",
    "ivory",
    "khaki",
    "lavender",
    "lavenderblush",
    "lawngreen",
    "lemonchiffon",
    "lightblue",
    "lightcoral",
    "lightcyan",
    "lightgoldenrodyellow",
    "lightgrey",
    "lightgray",
    "lightgreen",
    "lightpink",
    "lightsalmon",
    "lightseagreen",
    "lightskyblue",
    "lightslategrey",
    "lightslategray",
    "lightsteelblue",
    "lightyellow",
    "lime",
    "limegreen",
    "linen",
    "magenta",
    "maroon",
    "mediumaquamarine",
    "mediumblue",
    "mediumorchid",
    "mediumpurple",
    "mediumseagreen",
    "mediumslateblue",
    "mediumspringgreen",
    "mediumturquoise",
    "mediumvioletred",
    "midnightblue",
    "mintcream",
    "mistyrose",
    "moccasin",
    "navajowhite",
    "navy",
    "oldlace",
    "olive",
    "olivedrab",
    "orange",
    "orangered",
    "orchid",
    "palegoldenrod",
    "palegreen",
    "paleturquoise",
    "palevioletred",
    "papayawhip",
    "peachpuff",
    "peru",
    "pink",
    "plum",
    "powderblue",
    "purple",
    "red",
    "rosybrown",
    "royalblue",
    "saddlebrown",
    "salmon",
    "sandybrown",
    "seagreen",
    "seashell",
    "sienna",
    "silver",
    "skyblue",
    "slateblue",
    "slategrey",
    "slategray",
    "snow",
    "springgreen",
    "steelblue",
    "tan",
    "teal",
    "thistle",
    "tomato",
    "turquoise",
    "violet",
    "wheat",
    "white",
    "whitesmoke",
    "yellow",
    "yellowgreen",
    // sentinel value
    0
  };

  const double color_values[] =
  {
    0xf0, 0xf8, 0xff,
    0xfa, 0xeb, 0xd7,
    0x00, 0xff, 0xff,
    0x7f, 0xff, 0xd4,
    0xf0, 0xff, 0xff,
    0xf5, 0xf5, 0xdc,
    0xff, 0xe4, 0xc4,
    0x00, 0x00, 0x00,
    0xff, 0xeb, 0xcd,
    0x00, 0x00, 0xff,
    0x8a, 0x2b, 0xe2,
    0xa5, 0x2a, 0x2a,
    0xde, 0xb8, 0x87,
    0x5f, 0x9e, 0xa0,
    0x7f, 0xff, 0x00,
    0xd2, 0x69, 0x1e,
    0xff, 0x7f, 0x50,
    0x64, 0x95, 0xed,
    0xff, 0xf8, 0xdc,
    0xdc, 0x14, 0x3c,
    0x00, 0xff, 0xff,
    0x00, 0x00, 0x8b,
    0x00, 0x8b, 0x8b,
    0xb8, 0x86, 0x0b,
    0xa9, 0xa9, 0xa9,
    0xa9, 0xa9, 0xa9,
    0x00, 0x64, 0x00,
    0xbd, 0xb7, 0x6b,
    0x8b, 0x00, 0x8b,
    0x55, 0x6b, 0x2f,
    0xff, 0x8c, 0x00,
    0x99, 0x32, 0xcc,
    0x8b, 0x00, 0x00,
    0xe9, 0x96, 0x7a,
    0x8f, 0xbc, 0x8f,
    0x48, 0x3d, 0x8b,
    0x2f, 0x4f, 0x4f,
    0x2f, 0x4f, 0x4f,
    0x00, 0xce, 0xd1,
    0x94, 0x00, 0xd3,
    0xff, 0x14, 0x93,
    0x00, 0xbf, 0xff,
    0x69, 0x69, 0x69,
    0x69, 0x69, 0x69,
    0x1e, 0x90, 0xff,
    0xb2, 0x22, 0x22,
    0xff, 0xfa, 0xf0,
    0x22, 0x8b, 0x22,
    0xff, 0x00, 0xff,
    0xdc, 0xdc, 0xdc,
    0xf8, 0xf8, 0xff,
    0xff, 0xd7, 0x00,
    0xda, 0xa5, 0x20,
    0x80, 0x80, 0x80,
    0x80, 0x80, 0x80,
    0x00, 0x80, 0x00,
    0xad, 0xff, 0x2f,
    0xf0, 0xff, 0xf0,
    0xff, 0x69, 0xb4,
    0xcd, 0x5c, 0x5c,
    0x4b, 0x00, 0x82,
    0xff, 0xff, 0xf0,
    0xf0, 0xe6, 0x8c,
    0xe6, 0xe6, 0xfa,
    0xff, 0xf0, 0xf5,
    0x7c, 0xfc, 0x00,
    0xff, 0xfa, 0xcd,
    0xad, 0xd8, 0xe6,
    0xf0, 0x80, 0x80,
    0xe0, 0xff, 0xff,
    0xfa, 0xfa, 0xd2,
    0xd3, 0xd3, 0xd3,
    0xd3, 0xd3, 0xd3,
    0x90, 0xee, 0x90,
    0xff, 0xb6, 0xc1,
    0xff, 0xa0, 0x7a,
    0x20, 0xb2, 0xaa,
    0x87, 0xce, 0xfa,
    0x77, 0x88, 0x99,
    0x77, 0x88, 0x99,
    0xb0, 0xc4, 0xde,
    0xff, 0xff, 0xe0,
    0x00, 0xff, 0x00,
    0x32, 0xcd, 0x32,
    0xfa, 0xf0, 0xe6,
    0xff, 0x00, 0xff,
    0x80, 0x00, 0x00,
    0x66, 0xcd, 0xaa,
    0x00, 0x00, 0xcd,
    0xba, 0x55, 0xd3,
    0x93, 0x70, 0xd8,
    0x3c, 0xb3, 0x71,
    0x7b, 0x68, 0xee,
    0x00, 0xfa, 0x9a,
    0x48, 0xd1, 0xcc,
    0xc7, 0x15, 0x85,
    0x19, 0x19, 0x70,
    0xf5, 0xff, 0xfa,
    0xff, 0xe4, 0xe1,
    0xff, 0xe4, 0xb5,
    0xff, 0xde, 0xad,
    0x00, 0x00, 0x80,
    0xfd, 0xf5, 0xe6,
    0x80, 0x80, 0x00,
    0x6b, 0x8e, 0x23,
    0xff, 0xa5, 0x00,
    0xff, 0x45, 0x00,
    0xda, 0x70, 0xd6,
    0xee, 0xe8, 0xaa,
    0x98, 0xfb, 0x98,
    0xaf, 0xee, 0xee,
    0xd8, 0x70, 0x93,
    0xff, 0xef, 0xd5,
    0xff, 0xda, 0xb9,
    0xcd, 0x85, 0x3f,
    0xff, 0xc0, 0xcb,
    0xdd, 0xa0, 0xdd,
    0xb0, 0xe0, 0xe6,
    0x80, 0x00, 0x80,
    0xff, 0x00, 0x00,
    0xbc, 0x8f, 0x8f,
    0x41, 0x69, 0xe1,
    0x8b, 0x45, 0x13,
    0xfa, 0x80, 0x72,
    0xf4, 0xa4, 0x60,
    0x2e, 0x8b, 0x57,
    0xff, 0xf5, 0xee,
    0xa0, 0x52, 0x2d,
    0xc0, 0xc0, 0xc0,
    0x87, 0xce, 0xeb,
    0x6a, 0x5a, 0xcd,
    0x70, 0x80, 0x90,
    0x70, 0x80, 0x90,
    0xff, 0xfa, 0xfa,
    0x00, 0xff, 0x7f,
    0x46, 0x82, 0xb4,
    0xd2, 0xb4, 0x8c,
    0x00, 0x80, 0x80,
    0xd8, 0xbf, 0xd8,
    0xff, 0x63, 0x47,
    0x40, 0xe0, 0xd0,
    0xee, 0x82, 0xee,
    0xf5, 0xde, 0xb3,
    0xff, 0xff, 0xff,
    0xf5, 0xf5, 0xf5,
    0xff, 0xff, 0x00,
    0x9a, 0xcd, 0x32,
    // sentinel value
    0xfff
  };

}
<|endoftext|>


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

#include "chrome/browser/upgrade_detector_impl.h"

#include <string>

#include "base/bind.h"
#include "base/command_line.h"
#include "base/file_path.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/singleton.h"
#include "base/path_service.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "base/task.h"
#include "base/time.h"
#include "base/utf_string_conversions.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_version_info.h"
#include "chrome/installer/util/browser_distribution.h"
#include "content/public/browser/browser_thread.h"
#include "ui/base/resource/resource_bundle.h"

#if defined(OS_WIN)
#include "chrome/installer/util/install_util.h"
#elif defined(OS_MACOSX)
#include "chrome/browser/mac/keystone_glue.h"
#elif defined(OS_POSIX)
#include "base/process_util.h"
#include "base/version.h"
#endif

using content::BrowserThread;

namespace {

// How long (in milliseconds) to wait (each cycle) before checking whether
// Chrome's been upgraded behind our back.
const int kCheckForUpgradeMs = 2 * 60 * 60 * 1000;  // 2 hours.

// How long to wait (each cycle) before checking which severity level we should
// be at. Once we reach the highest severity, the timer will stop.
const int kNotifyCycleTimeMs = 20 * 60 * 1000;  // 20 minutes.

// Same as kNotifyCycleTimeMs but only used during testing.
const int kNotifyCycleTimeForTestingMs = 500;  // Half a second.

std::string CmdLineInterval() {
  const CommandLine& cmd_line = *CommandLine::ForCurrentProcess();
  return cmd_line.GetSwitchValueASCII(switches::kCheckForUpdateIntervalSec);
}

// How often to check for an upgrade.
int GetCheckForUpgradeEveryMs() {
  // Check for a value passed via the command line.
  int interval_ms;
  std::string interval = CmdLineInterval();
  if (!interval.empty() && base::StringToInt(interval, &interval_ms))
    return interval_ms * 1000;  // Command line value is in seconds.

  return kCheckForUpgradeMs;
}

// This task checks the currently running version of Chrome against the
// installed version. If the installed version is newer, it runs the passed
// callback task. Otherwise it just deletes the task.
class DetectUpgradeTask : public Task {
 public:
  DetectUpgradeTask(const base::Closure& upgrade_detected_task,
                    bool* is_unstable_channel,
                    bool* is_critical_upgrade)
      : upgrade_detected_task_(upgrade_detected_task),
        is_unstable_channel_(is_unstable_channel),
        is_critical_upgrade_(is_critical_upgrade) {
  }

  virtual ~DetectUpgradeTask() {
    if (!upgrade_detected_task_.is_null()) {
      // This has to get deleted on the same thread it was created.
      BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
                              upgrade_detected_task_);
    }
  }

  virtual void Run() {
    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));

    scoped_ptr<Version> installed_version;
    scoped_ptr<Version> critical_update;

#if defined(OS_WIN)
    // Get the version of the currently *installed* instance of Chrome,
    // which might be newer than the *running* instance if we have been
    // upgraded in the background.
    FilePath exe_path;
    if (!PathService::Get(base::DIR_EXE, &exe_path)) {
      NOTREACHED() << "Failed to find executable path";
      return;
    }

    bool system_install =
        !InstallUtil::IsPerUserInstall(exe_path.value().c_str());

    // TODO(tommi): Check if using the default distribution is always the right
    // thing to do.
    BrowserDistribution* dist = BrowserDistribution::GetDistribution();
    installed_version.reset(InstallUtil::GetChromeVersion(dist,
                                                          system_install));

    if (installed_version.get()) {
      critical_update.reset(
          InstallUtil::GetCriticalUpdateVersion(dist, system_install));
    }
#elif defined(OS_MACOSX)
    installed_version.reset(
        Version::GetVersionFromString(UTF16ToASCII(
            keystone_glue::CurrentlyInstalledVersion())));
#elif defined(OS_POSIX)
    // POSIX but not Mac OS X: Linux, etc.
    CommandLine command_line(*CommandLine::ForCurrentProcess());
    command_line.AppendSwitch(switches::kProductVersion);
    std::string reply;
    if (!base::GetAppOutput(command_line, &reply)) {
      DLOG(ERROR) << "Failed to get current file version";
      return;
    }

    installed_version.reset(Version::GetVersionFromString(reply));
#endif

    chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
    *is_unstable_channel_ = channel == chrome::VersionInfo::CHANNEL_DEV ||
                            channel == chrome::VersionInfo::CHANNEL_CANARY;

    // Get the version of the currently *running* instance of Chrome.
    chrome::VersionInfo version_info;
    if (!version_info.is_valid()) {
      NOTREACHED() << "Failed to get current file version";
      return;
    }
    scoped_ptr<Version> running_version(
        Version::GetVersionFromString(version_info.Version()));
    if (running_version.get() == NULL) {
      NOTREACHED() << "Failed to parse version info";
      return;
    }

    // |installed_version| may be NULL when the user downgrades on Linux (by
    // switching from dev to beta channel, for example). The user needs a
    // restart in this case as well. See http://crbug.com/46547
    if (!installed_version.get() ||
        (installed_version->CompareTo(*running_version) > 0)) {
      // If a more recent version is available, it might be that we are lacking
      // a critical update, such as a zero-day fix.
      *is_critical_upgrade_ =
          critical_update.get() &&
          (critical_update->CompareTo(*running_version) > 0);

      // Fire off the upgrade detected task.
      BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
                              upgrade_detected_task_);
      upgrade_detected_task_.Reset();
    }
  }

 private:
  base::Closure upgrade_detected_task_;
  bool* is_unstable_channel_;
  bool* is_critical_upgrade_;
};

}  // namespace

UpgradeDetectorImpl::UpgradeDetectorImpl()
    : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
      is_unstable_channel_(false) {
  CommandLine command_line(*CommandLine::ForCurrentProcess());
  if (command_line.HasSwitch(switches::kDisableBackgroundNetworking))
    return;
  // Windows: only enable upgrade notifications for official builds.
  // Mac: only enable them if the updater (Keystone) is present.
  // Linux (and other POSIX): always enable regardless of branding.
#if (defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD)) || defined(OS_POSIX)
#if defined(OS_MACOSX)
  if (keystone_glue::KeystoneEnabled())
#endif
  {
    detect_upgrade_timer_.Start(FROM_HERE,
        base::TimeDelta::FromMilliseconds(GetCheckForUpgradeEveryMs()),
        this, &UpgradeDetectorImpl::CheckForUpgrade);
  }
#endif
}

UpgradeDetectorImpl::~UpgradeDetectorImpl() {
}

void UpgradeDetectorImpl::CheckForUpgrade() {
  weak_factory_.InvalidateWeakPtrs();
  base::Closure callback_task =
      base::Bind(&UpgradeDetectorImpl::UpgradeDetected,
                 weak_factory_.GetWeakPtr());
  // We use FILE as the thread to run the upgrade detection code on all
  // platforms. For Linux, this is because we don't want to block the UI thread
  // while launching a background process and reading its output; on the Mac and
  // on Windows checking for an upgrade requires reading a file.
  BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
                          new DetectUpgradeTask(callback_task,
                                                &is_unstable_channel_,
                                                &is_critical_upgrade_));
}

void UpgradeDetectorImpl::UpgradeDetected() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  // Stop the recurring timer (that is checking for changes).
  detect_upgrade_timer_.Stop();

  NotifyUpgradeDetected();

  // Start the repeating timer for notifying the user after a certain period.
  // The called function will eventually figure out that enough time has passed
  // and stop the timer.
  int cycle_time = CmdLineInterval().empty() ? kNotifyCycleTimeMs :
                                               kNotifyCycleTimeForTestingMs;
  upgrade_notification_timer_.Start(FROM_HERE,
      base::TimeDelta::FromMilliseconds(cycle_time),
      this, &UpgradeDetectorImpl::NotifyOnUpgrade);
}

void UpgradeDetectorImpl::NotifyOnUpgrade() {
  base::TimeDelta delta = base::Time::Now() - upgrade_detected_time();
  std::string interval = CmdLineInterval();

  // A command line interval implies testing, which we'll make more convenient
  // by switching to seconds of waiting instead of days between flipping
  // severity. This works in conjunction with the similar interval.empty()
  // check below.
  int64 time_passed = interval.empty() ? delta.InHours() : delta.InSeconds();

  if (is_unstable_channel_) {
    // There's only one threat level for unstable channels like dev and
    // canary, and it hits after one hour. During testing, it hits after one
    // minute.
    const int kUnstableThreshold = 1;

    if (is_critical_upgrade_)
      set_upgrade_notification_stage(UPGRADE_ANNOYANCE_CRITICAL);
    else if (time_passed >= kUnstableThreshold) {
      set_upgrade_notification_stage(UPGRADE_ANNOYANCE_LOW);

      // That's as high as it goes.
      upgrade_notification_timer_.Stop();
    } else {
      return;  // Not ready to recommend upgrade.
    }
  } else {
    const int kMultiplier = interval.empty() ? 24 : 1;
    // 14 days when not testing, otherwise 14 seconds.
    const int kSevereThreshold = 14 * kMultiplier;
    const int kHighThreshold = 7 * kMultiplier;
    const int kElevatedThreshold = 4 * kMultiplier;
    const int kLowThreshold = 2 * kMultiplier;

    // These if statements must be sorted (highest interval first).
    if (time_passed >= kSevereThreshold || is_critical_upgrade_) {
      set_upgrade_notification_stage(
          is_critical_upgrade_ ? UPGRADE_ANNOYANCE_CRITICAL :
                                 UPGRADE_ANNOYANCE_SEVERE);

      // We can't get any higher, baby.
      upgrade_notification_timer_.Stop();
    } else if (time_passed >= kHighThreshold) {
      set_upgrade_notification_stage(UPGRADE_ANNOYANCE_HIGH);
    } else if (time_passed >= kElevatedThreshold) {
      set_upgrade_notification_stage(UPGRADE_ANNOYANCE_ELEVATED);
    } else if (time_passed >= kLowThreshold) {
      set_upgrade_notification_stage(UPGRADE_ANNOYANCE_LOW);
    } else {
      return;  // Not ready to recommend upgrade.
    }
  }

  NotifyUpgradeRecommended();
}

// static
UpgradeDetectorImpl* UpgradeDetectorImpl::GetInstance() {
  return Singleton<UpgradeDetectorImpl>::get();
}

// static
UpgradeDetector* UpgradeDetector::GetInstance() {
  return UpgradeDetectorImpl::GetInstance();
}
<commit_msg>Fix a bug that incorrectly kicked off the upgrade task.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/upgrade_detector_impl.h"

#include <string>

#include "base/bind.h"
#include "base/command_line.h"
#include "base/file_path.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/singleton.h"
#include "base/path_service.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "base/task.h"
#include "base/time.h"
#include "base/utf_string_conversions.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_version_info.h"
#include "chrome/installer/util/browser_distribution.h"
#include "content/public/browser/browser_thread.h"
#include "ui/base/resource/resource_bundle.h"

#if defined(OS_WIN)
#include "chrome/installer/util/install_util.h"
#elif defined(OS_MACOSX)
#include "chrome/browser/mac/keystone_glue.h"
#elif defined(OS_POSIX)
#include "base/process_util.h"
#include "base/version.h"
#endif

using content::BrowserThread;

namespace {

// How long (in milliseconds) to wait (each cycle) before checking whether
// Chrome's been upgraded behind our back.
const int kCheckForUpgradeMs = 2 * 60 * 60 * 1000;  // 2 hours.

// How long to wait (each cycle) before checking which severity level we should
// be at. Once we reach the highest severity, the timer will stop.
const int kNotifyCycleTimeMs = 20 * 60 * 1000;  // 20 minutes.

// Same as kNotifyCycleTimeMs but only used during testing.
const int kNotifyCycleTimeForTestingMs = 500;  // Half a second.

std::string CmdLineInterval() {
  const CommandLine& cmd_line = *CommandLine::ForCurrentProcess();
  return cmd_line.GetSwitchValueASCII(switches::kCheckForUpdateIntervalSec);
}

// How often to check for an upgrade.
int GetCheckForUpgradeEveryMs() {
  // Check for a value passed via the command line.
  int interval_ms;
  std::string interval = CmdLineInterval();
  if (!interval.empty() && base::StringToInt(interval, &interval_ms))
    return interval_ms * 1000;  // Command line value is in seconds.

  return kCheckForUpgradeMs;
}

// This task checks the currently running version of Chrome against the
// installed version. If the installed version is newer, it runs the passed
// callback task. Otherwise it just deletes the task.
class DetectUpgradeTask : public Task {
 public:
  DetectUpgradeTask(const base::Closure& upgrade_detected_task,
                    bool* is_unstable_channel,
                    bool* is_critical_upgrade)
      : upgrade_detected_task_(upgrade_detected_task),
        is_unstable_channel_(is_unstable_channel),
        is_critical_upgrade_(is_critical_upgrade) {
  }

  virtual void Run() {
    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));

    scoped_ptr<Version> installed_version;
    scoped_ptr<Version> critical_update;

#if defined(OS_WIN)
    // Get the version of the currently *installed* instance of Chrome,
    // which might be newer than the *running* instance if we have been
    // upgraded in the background.
    FilePath exe_path;
    if (!PathService::Get(base::DIR_EXE, &exe_path)) {
      NOTREACHED() << "Failed to find executable path";
      return;
    }

    bool system_install =
        !InstallUtil::IsPerUserInstall(exe_path.value().c_str());

    // TODO(tommi): Check if using the default distribution is always the right
    // thing to do.
    BrowserDistribution* dist = BrowserDistribution::GetDistribution();
    installed_version.reset(InstallUtil::GetChromeVersion(dist,
                                                          system_install));

    if (installed_version.get()) {
      critical_update.reset(
          InstallUtil::GetCriticalUpdateVersion(dist, system_install));
    }
#elif defined(OS_MACOSX)
    installed_version.reset(
        Version::GetVersionFromString(UTF16ToASCII(
            keystone_glue::CurrentlyInstalledVersion())));
#elif defined(OS_POSIX)
    // POSIX but not Mac OS X: Linux, etc.
    CommandLine command_line(*CommandLine::ForCurrentProcess());
    command_line.AppendSwitch(switches::kProductVersion);
    std::string reply;
    if (!base::GetAppOutput(command_line, &reply)) {
      DLOG(ERROR) << "Failed to get current file version";
      return;
    }

    installed_version.reset(Version::GetVersionFromString(reply));
#endif

    chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
    *is_unstable_channel_ = channel == chrome::VersionInfo::CHANNEL_DEV ||
                            channel == chrome::VersionInfo::CHANNEL_CANARY;

    // Get the version of the currently *running* instance of Chrome.
    chrome::VersionInfo version_info;
    if (!version_info.is_valid()) {
      NOTREACHED() << "Failed to get current file version";
      return;
    }
    scoped_ptr<Version> running_version(
        Version::GetVersionFromString(version_info.Version()));
    if (running_version.get() == NULL) {
      NOTREACHED() << "Failed to parse version info";
      return;
    }

    // |installed_version| may be NULL when the user downgrades on Linux (by
    // switching from dev to beta channel, for example). The user needs a
    // restart in this case as well. See http://crbug.com/46547
    if (!installed_version.get() ||
        (installed_version->CompareTo(*running_version) > 0)) {
      // If a more recent version is available, it might be that we are lacking
      // a critical update, such as a zero-day fix.
      *is_critical_upgrade_ =
          critical_update.get() &&
          (critical_update->CompareTo(*running_version) > 0);

      // Fire off the upgrade detected task.
      BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
                              upgrade_detected_task_);
      upgrade_detected_task_.Reset();
    }
  }

 private:
  base::Closure upgrade_detected_task_;
  bool* is_unstable_channel_;
  bool* is_critical_upgrade_;
};

}  // namespace

UpgradeDetectorImpl::UpgradeDetectorImpl()
    : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
      is_unstable_channel_(false) {
  CommandLine command_line(*CommandLine::ForCurrentProcess());
  if (command_line.HasSwitch(switches::kDisableBackgroundNetworking))
    return;
  // Windows: only enable upgrade notifications for official builds.
  // Mac: only enable them if the updater (Keystone) is present.
  // Linux (and other POSIX): always enable regardless of branding.
#if (defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD)) || defined(OS_POSIX)
#if defined(OS_MACOSX)
  if (keystone_glue::KeystoneEnabled())
#endif
  {
    detect_upgrade_timer_.Start(FROM_HERE,
        base::TimeDelta::FromMilliseconds(GetCheckForUpgradeEveryMs()),
        this, &UpgradeDetectorImpl::CheckForUpgrade);
  }
#endif
}

UpgradeDetectorImpl::~UpgradeDetectorImpl() {
}

void UpgradeDetectorImpl::CheckForUpgrade() {
  weak_factory_.InvalidateWeakPtrs();
  base::Closure callback_task =
      base::Bind(&UpgradeDetectorImpl::UpgradeDetected,
                 weak_factory_.GetWeakPtr());
  // We use FILE as the thread to run the upgrade detection code on all
  // platforms. For Linux, this is because we don't want to block the UI thread
  // while launching a background process and reading its output; on the Mac and
  // on Windows checking for an upgrade requires reading a file.
  BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
                          new DetectUpgradeTask(callback_task,
                                                &is_unstable_channel_,
                                                &is_critical_upgrade_));
}

void UpgradeDetectorImpl::UpgradeDetected() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  // Stop the recurring timer (that is checking for changes).
  detect_upgrade_timer_.Stop();

  NotifyUpgradeDetected();

  // Start the repeating timer for notifying the user after a certain period.
  // The called function will eventually figure out that enough time has passed
  // and stop the timer.
  int cycle_time = CmdLineInterval().empty() ? kNotifyCycleTimeMs :
                                               kNotifyCycleTimeForTestingMs;
  upgrade_notification_timer_.Start(FROM_HERE,
      base::TimeDelta::FromMilliseconds(cycle_time),
      this, &UpgradeDetectorImpl::NotifyOnUpgrade);
}

void UpgradeDetectorImpl::NotifyOnUpgrade() {
  base::TimeDelta delta = base::Time::Now() - upgrade_detected_time();
  std::string interval = CmdLineInterval();

  // A command line interval implies testing, which we'll make more convenient
  // by switching to seconds of waiting instead of days between flipping
  // severity. This works in conjunction with the similar interval.empty()
  // check below.
  int64 time_passed = interval.empty() ? delta.InHours() : delta.InSeconds();

  if (is_unstable_channel_) {
    // There's only one threat level for unstable channels like dev and
    // canary, and it hits after one hour. During testing, it hits after one
    // minute.
    const int kUnstableThreshold = 1;

    if (is_critical_upgrade_)
      set_upgrade_notification_stage(UPGRADE_ANNOYANCE_CRITICAL);
    else if (time_passed >= kUnstableThreshold) {
      set_upgrade_notification_stage(UPGRADE_ANNOYANCE_LOW);

      // That's as high as it goes.
      upgrade_notification_timer_.Stop();
    } else {
      return;  // Not ready to recommend upgrade.
    }
  } else {
    const int kMultiplier = interval.empty() ? 24 : 1;
    // 14 days when not testing, otherwise 14 seconds.
    const int kSevereThreshold = 14 * kMultiplier;
    const int kHighThreshold = 7 * kMultiplier;
    const int kElevatedThreshold = 4 * kMultiplier;
    const int kLowThreshold = 2 * kMultiplier;

    // These if statements must be sorted (highest interval first).
    if (time_passed >= kSevereThreshold || is_critical_upgrade_) {
      set_upgrade_notification_stage(
          is_critical_upgrade_ ? UPGRADE_ANNOYANCE_CRITICAL :
                                 UPGRADE_ANNOYANCE_SEVERE);

      // We can't get any higher, baby.
      upgrade_notification_timer_.Stop();
    } else if (time_passed >= kHighThreshold) {
      set_upgrade_notification_stage(UPGRADE_ANNOYANCE_HIGH);
    } else if (time_passed >= kElevatedThreshold) {
      set_upgrade_notification_stage(UPGRADE_ANNOYANCE_ELEVATED);
    } else if (time_passed >= kLowThreshold) {
      set_upgrade_notification_stage(UPGRADE_ANNOYANCE_LOW);
    } else {
      return;  // Not ready to recommend upgrade.
    }
  }

  NotifyUpgradeRecommended();
}

// static
UpgradeDetectorImpl* UpgradeDetectorImpl::GetInstance() {
  return Singleton<UpgradeDetectorImpl>::get();
}

// static
UpgradeDetector* UpgradeDetector::GetInstance() {
  return UpgradeDetectorImpl::GetInstance();
}
<|endoftext|>


<commit_before>/*
    Copyright (c) 2007 Volker Krause <vkrause@kde.org>

    This library is free software; you can redistribute it and/or modify it
    under the terms of the GNU Library General Public License as published by
    the Free Software Foundation; either version 2 of the License, or (at your
    option) any later version.

    This library is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
    License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to the
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
*/

#include "nntpcollectionattribute.h"

#include <QDataStream>

NntpCollectionAttribute::NntpCollectionAttribute()
  : CollectionAttribute(),
  mLastArticleId( 0 )
{
}

QByteArray NntpCollectionAttribute::type() const
{
  return "NNTP";
}

NntpCollectionAttribute * NntpCollectionAttribute::clone() const
{
  NntpCollectionAttribute *attr = new NntpCollectionAttribute();
  attr->mLastArticleId = mLastArticleId;
  return attr;
}

QByteArray NntpCollectionAttribute::toByteArray() const
{
  QByteArray data;
  QDataStream s( &data, QIODevice::Append );
  s << mLastArticleId;
  return data;
}

void NntpCollectionAttribute::setData(const QByteArray & data)
{
  QDataStream s( data );
  s >> mLastArticleId;
}

int NntpCollectionAttribute::lastArticle() const
{
  return mLastArticleId;
}

void NntpCollectionAttribute::setLastArticle(int last)
{
  mLastArticleId = last;
}
<commit_msg>No binary encoding, we don't handle newlines correctly yet.<commit_after>/*
    Copyright (c) 2007 Volker Krause <vkrause@kde.org>

    This library is free software; you can redistribute it and/or modify it
    under the terms of the GNU Library General Public License as published by
    the Free Software Foundation; either version 2 of the License, or (at your
    option) any later version.

    This library is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
    License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to the
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
*/

#include "nntpcollectionattribute.h"

#include <QDataStream>

NntpCollectionAttribute::NntpCollectionAttribute()
  : CollectionAttribute(),
  mLastArticleId( 0 )
{
}

QByteArray NntpCollectionAttribute::type() const
{
  return "NNTP";
}

NntpCollectionAttribute * NntpCollectionAttribute::clone() const
{
  NntpCollectionAttribute *attr = new NntpCollectionAttribute();
  attr->mLastArticleId = mLastArticleId;
  return attr;
}

QByteArray NntpCollectionAttribute::toByteArray() const
{
  QByteArray data = QByteArray::number( mLastArticleId );
  return data;
}

void NntpCollectionAttribute::setData(const QByteArray & data)
{
  mLastArticleId = data.toInt();
}

int NntpCollectionAttribute::lastArticle() const
{
  return mLastArticleId;
}

void NntpCollectionAttribute::setLastArticle(int last)
{
  mLastArticleId = last;
}
<|endoftext|>


<commit_before>// Copyright (c) 2017 Alexander Gallego. All rights reserved.
//

#include <chrono>
#include <iostream>

#include <core/app-template.hh>
#include <core/distributed.hh>
#include <net/api.hh>

#include "smf/histogram_seastar_utils.h"
#include "smf/log.h"
#include "smf/rpc_filter.h"
#include "smf/rpc_server.h"
#include "smf/unique_histogram_adder.h"
#include "smf/zstd_filter.h"

#include "demo_service.smf.fb.h"

class storage_service : public smf_gen::demo::SmfStorage {
  virtual seastar::future<smf::rpc_typed_envelope<smf_gen::demo::Response>>
  Get(smf::rpc_recv_typed_context<smf_gen::demo::Request> &&rec) final {
    smf::rpc_typed_envelope<smf_gen::demo::Response> data;

    // return the same payload
    if (rec) {
      LOG_INFO("Get called by {}", seastar::ipv4_addr(rec.ctx->remote_address));
      data.data->name = rec->name()->c_str();
    }

    data.envelope.set_status(200);
    return seastar::make_ready_future<
      smf::rpc_typed_envelope<smf_gen::demo::Response>>(std::move(data));
  }
};

void
cli_opts(boost::program_options::options_description_easy_init o) {
  namespace po = boost::program_options;
  o("ip", po::value<std::string>()->default_value("127.0.0.1"),
    "ip to connect to");
  o("port", po::value<uint16_t>()->default_value(20776), "port for service");
  o("httpport", po::value<uint16_t>()->default_value(20777),
    "port for http stats service");
}

int
main(int args, char **argv, char **env) {
  std::setvbuf(stdout, nullptr, _IOLBF, 1024);
  seastar::distributed<smf::rpc_server> rpc;
  seastar::app_template app;
  cli_opts(app.add_options());

  return app.run_deprecated(args, argv, [&] {
    seastar::engine().at_exit([&] {
      return rpc
        .map_reduce(
          smf::unique_histogram_adder(), &smf::rpc_server::copy_histogram)
        .then([](auto h) {
          LOG_INFO("Writing server histograms");
          return smf::histogram_seastar_utils::write(
            "server_latency.csv", std::move(h));
        })
        .then([&rpc] { return rpc.stop(); });
    });

    auto &cfg = app.configuration();

    smf::rpc_server_args args;
    args.ip = cfg["ip"].as<std::string>().c_str();
    args.rpc_port = cfg["port"].as<uint16_t>();
    args.http_port = cfg["httpport"].as<uint16_t>();

    // Normal services would either use the defaults or something smarter
    // This triggers the memory pressure
    args.basic_req_size = 60 /*payload size*/;
    args.bloat_mult = 1;  // no bloat
    args.memory_avail_per_core =
      static_cast<uint64_t>(0.9 * seastar::memory::stats().total_memory());

    return rpc.start(args)
      .then([&rpc] {
        LOG_INFO("Registering smf_gen::demo::storage_service");
        return rpc.invoke_on_all(
          &smf::rpc_server::register_service<storage_service>);
      })
      .then([&rpc] {
        LOG_INFO("Invoking rpc start on all cores");
        return rpc.invoke_on_all(&smf::rpc_server::start);
      });
  });
}
<commit_msg>cpp:demo: remove console logs<commit_after>// Copyright (c) 2017 Alexander Gallego. All rights reserved.
//

#include <chrono>
#include <iostream>

#include <core/app-template.hh>
#include <core/distributed.hh>
#include <net/api.hh>

#include "smf/histogram_seastar_utils.h"
#include "smf/log.h"
#include "smf/rpc_filter.h"
#include "smf/rpc_server.h"
#include "smf/unique_histogram_adder.h"
#include "smf/zstd_filter.h"

#include "demo_service.smf.fb.h"

class storage_service : public smf_gen::demo::SmfStorage {
  virtual seastar::future<smf::rpc_typed_envelope<smf_gen::demo::Response>>
  Get(smf::rpc_recv_typed_context<smf_gen::demo::Request> &&rec) final {
    smf::rpc_typed_envelope<smf_gen::demo::Response> data;
    // return the same payload
    if (rec) {
      data.data->name = rec->name()->c_str();
    }
    data.envelope.set_status(200);
    return seastar::make_ready_future<
      smf::rpc_typed_envelope<smf_gen::demo::Response>>(std::move(data));
  }
};

void
cli_opts(boost::program_options::options_description_easy_init o) {
  namespace po = boost::program_options;
  o("ip", po::value<std::string>()->default_value("127.0.0.1"),
    "ip to connect to");
  o("port", po::value<uint16_t>()->default_value(20776), "port for service");
  o("httpport", po::value<uint16_t>()->default_value(20777),
    "port for http stats service");
}

int
main(int args, char **argv, char **env) {
  std::setvbuf(stdout, nullptr, _IOLBF, 1024);
  seastar::distributed<smf::rpc_server> rpc;
  seastar::app_template app;
  cli_opts(app.add_options());

  return app.run_deprecated(args, argv, [&] {
    seastar::engine().at_exit([&] {
      return rpc
        .map_reduce(
          smf::unique_histogram_adder(), &smf::rpc_server::copy_histogram)
        .then([](auto h) {
          LOG_INFO("Writing server histograms");
          return smf::histogram_seastar_utils::write(
            "server_latency.csv", std::move(h));
        })
        .then([&rpc] { return rpc.stop(); });
    });

    auto &cfg = app.configuration();

    smf::rpc_server_args args;
    args.ip = cfg["ip"].as<std::string>().c_str();
    args.rpc_port = cfg["port"].as<uint16_t>();
    args.http_port = cfg["httpport"].as<uint16_t>();

    // Normal services would either use the defaults or something smarter
    // This triggers the memory pressure
    args.basic_req_size = 60 /*payload size*/;
    args.bloat_mult = 1;  // no bloat
    args.memory_avail_per_core =
      static_cast<uint64_t>(0.9 * seastar::memory::stats().total_memory());

    return rpc.start(args)
      .then([&rpc] {
        LOG_INFO("Registering smf_gen::demo::storage_service");
        return rpc.invoke_on_all(
          &smf::rpc_server::register_service<storage_service>);
      })
      .then([&rpc] {
        LOG_INFO("Invoking rpc start on all cores");
        return rpc.invoke_on_all(&smf::rpc_server::start);
      });
  });
}
<|endoftext|>