<commit_before>#include "net/RawSocket.h"
#include "common/RhodesApp.h"

#include <algorithm>

#if !defined(OS_WINDOWS) && !defined(OS_WINCE)
#include <arpa/inet.h>
#endif

#if !defined(OS_WINCE)
#include <common/stat.h>

#ifdef EAGAIN
#undef EAGAIN
#endif
#define EAGAIN EWOULDBLOCK

#else

#include "CompatWince.h"

#if defined(OS_WINDOWS) || defined(OS_WINCE)
typedef unsigned __int16 uint16_t;

#  ifndef S_ISDIR
#    define S_ISDIR(m) ((_S_IFDIR & m) == _S_IFDIR)
#  endif

#  ifndef S_ISREG
#    define S_ISREG(m) ((_S_IFREG & m) == _S_IFREG)
#  endif

#  ifndef EAGAIN
#    define EAGAIN WSAEWOULDBLOCK
#  endif
#endif

#undef DEFAULT_LOGCATEGORY
#define DEFAULT_LOGCATEGORY "RawSocket"

namespace rho
{
namespace net
{

bool RawSocket::init()
{
    RAWTRACE("Init raw socket");
    m_isInit = create();
    return m_isInit;
}

bool RawSocket::create()
{
    RAWTRACE("Start create raw socket");
    cleanup();

    int iResult;
    addrinfo *addrInfo = NULL, hints;

    memset( &hints, 0, sizeof(hints) );
    hints.ai_family   = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    RAWTRACE("Get host adress");

    // Resolve the server address and port
    iResult = getaddrinfo(m_hostName.c_str(), m_hostPort.c_str(), &hints, &addrInfo);

    if (iResult != 0) {
        RAWTRACE2("Unable to get addres info for host %s, port %s", m_hostName.c_str(), m_hostPort.c_str());
        return false;
    }

    RAWTRACE("Create socket");
    // Create a SOCKET for connecting to server
    m_clientSocket = socket(addrInfo->ai_family, addrInfo->ai_socktype, addrInfo->ai_protocol);

    if (m_clientSocket == INVALID_SOCKET) {
        RAWTRACE2("Socket can`t create for host %s, port %s", m_hostName.c_str(), m_hostPort.c_str());
        freeaddrinfo(addrInfo);
        return false;
    }

    // Connect to server.
    RAWTRACE("Connect to server");
    iResult = connect(m_clientSocket, addrInfo->ai_addr, (int)addrInfo->ai_addrlen);

    if (iResult == SOCKET_ERROR) {
        RAWTRACE2("Can`t connect to host %s, port %s ", m_hostName.c_str(), m_hostPort.c_str());
        cleanup();
        return false;
    }

    freeaddrinfo(addrInfo);

    RAWTRACE("End of socket creating");

    return true;
}

bool RawSocket::send(const String& sendData)
{
    int iResult = 0;

    // Send an initial buffer
    iResult = ::send(m_clientSocket, sendData.c_str(), (int) sendData.size(), 0);

    if (iResult == SOCKET_ERROR)
    {
        RAWTRACE2("Data not send for host %s, port %s", m_hostName.c_str(), m_hostPort.c_str());
        cleanup();
        return false;
    }

    return true;
}

void RawSocket::cleanup()
{
    m_isInit = false;
    closesocket(m_clientSocket);
    m_clientSocket = INVALID_SOCKET;
}

} // namespace net
} // namespace rho

#endif<commit_msg>fix raw socket<commit_after>#include "net/RawSocket.h"
#include "common/RhodesApp.h"

#include <algorithm>

#if !defined(OS_WINDOWS) && !defined(OS_WINCE)
#include <arpa/inet.h>
#endif

#if !defined(OS_WINCE)
#include <common/stat.h>

#ifdef EAGAIN
#undef EAGAIN
#endif
#define EAGAIN EWOULDBLOCK

#else

#include "CompatWince.h"

#if defined(OS_WINDOWS) || defined(OS_WINCE)
typedef unsigned __int16 uint16_t;

#  ifndef S_ISDIR
#    define S_ISDIR(m) ((_S_IFDIR & m) == _S_IFDIR)
#  endif

#  ifndef S_ISREG
#    define S_ISREG(m) ((_S_IFREG & m) == _S_IFREG)
#  endif

#  ifndef EAGAIN
#    define EAGAIN WSAEWOULDBLOCK
#  endif
#endif

#undef DEFAULT_LOGCATEGORY
#define DEFAULT_LOGCATEGORY "RawSocket"

namespace rho
{
namespace net
{

bool RawSocket::init()
{
    //RAWTRACE("Init raw socket");
    m_isInit = create();
    return m_isInit;
}

bool RawSocket::create()
{
    //RAWTRACE("Start create raw socket");
    cleanup();

    int iResult;
    addrinfo *addrInfo = NULL, hints;

    memset( &hints, 0, sizeof(hints) );
    hints.ai_family   = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    //RAWTRACE("Get host adress");

    // Resolve the server address and port
    iResult = getaddrinfo(m_hostName.c_str(), m_hostPort.c_str(), &hints, &addrInfo);

    if (iResult != 0) {
        //RAWTRACE2("Unable to get addres info for host %s, port %s", m_hostName.c_str(), m_hostPort.c_str());
        return false;
    }

    //RAWTRACE("Create socket");
    // Create a SOCKET for connecting to server
    m_clientSocket = socket(addrInfo->ai_family, addrInfo->ai_socktype, addrInfo->ai_protocol);

    if (m_clientSocket == INVALID_SOCKET) {
        //RAWTRACE2("Socket can`t create for host %s, port %s", m_hostName.c_str(), m_hostPort.c_str());
        freeaddrinfo(addrInfo);
        return false;
    }

    // Connect to server.
    //RAWTRACE("Connect to server");
    iResult = connect(m_clientSocket, addrInfo->ai_addr, (int)addrInfo->ai_addrlen);

    if (iResult == SOCKET_ERROR) {
        //RAWTRACE2("Can`t connect to host %s, port %s ", m_hostName.c_str(), m_hostPort.c_str());
        cleanup();
        return false;
    }

    freeaddrinfo(addrInfo);

    //RAWTRACE("End of socket creating");

    return true;
}

bool RawSocket::send(const String& sendData)
{
    int iResult = 0;

    // Send an initial buffer
    iResult = ::send(m_clientSocket, sendData.c_str(), (int) sendData.size(), 0);

    if (iResult == SOCKET_ERROR)
    {
        //RAWTRACE2("Data not send for host %s, port %s", m_hostName.c_str(), m_hostPort.c_str());
        cleanup();
        return false;
    }

    return true;
}

void RawSocket::cleanup()
{
    m_isInit = false;
    closesocket(m_clientSocket);
    m_clientSocket = INVALID_SOCKET;
}

} // namespace net
} // namespace rho

#endif<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// File: oapicimpl.hpp
//
// Desc: OpenCVR API - OpenCVR API.
//
// Copyright (c) 2014-2018 opencvr.com. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __VSC_OAPIC_IMPL_H_
#define __VSC_OAPIC_IMPL_H_

OAPIClient::OAPIClient(XRef<XSocket> pSocket)
:m_pSocket(pSocket)
{

}
OAPIClient::~OAPIClient()
{

}

BOOL OAPIClient::DeviceListRequest(oapi::DeviceList &list)
{
	OAPIHeader header;
	header.cmd = htonl(OAPI_CMD_GET_DEVICE_REQ);
	header.length = 0;

	m_pSocket->Send((void *)&header, sizeof(header));

	s32 nRet = m_pSocket->Recv((void *)&header, sizeof(header));
	if (nRet == sizeof(header))
	{
		header.length = ntohl(header.length);
		char *pRecv = new char[header.length + 1];
		s32 nRetBody = m_pSocket->Recv((void *)pRecv, header.length);
		if (nRetBody == header.length)
		{
			std::cerr << pRecv << '\n';
			autojsoncxx::ParsingResult result;
			if (!autojsoncxx::from_json_string(pRecv, list, result))
			{
			    //std::cerr << result << '\n';
			    //return FALSE;
			}
			delete pRecv;

		}else
		{
			delete pRecv;
			return FALSE;
		}
	}else
	{
		return FALSE;
	}
}

#endif<commit_msg>add parse<commit_after>//------------------------------------------------------------------------------
// File: oapicimpl.hpp
//
// Desc: OpenCVR API - OpenCVR API.
//
// Copyright (c) 2014-2018 opencvr.com. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __VSC_OAPIC_IMPL_H_
#define __VSC_OAPIC_IMPL_H_

OAPIClient::OAPIClient(XRef<XSocket> pSocket)
:m_pSocket(pSocket)
{

}
OAPIClient::~OAPIClient()
{

}

/* Setup connect with server */
BOOL OAPIClient::Setup(std::string strUser, std::string strPasswd)
{
	//TODO
	return TRUE;
}

BOOL OAPIClient::SendDeviceListRequest()
{
	OAPIHeader header;
	header.cmd = htonl(OAPI_CMD_DEVICE_LIST_REQ);
	header.length = 0;

	m_pSocket->Send((void *)&header, sizeof(header));

	return TRUE;

}

BOOL OAPIClient::StartLiveview(int nId)
{
	OAPIHeader header;

	oapi::LiveView liveview;
	liveview.nId = nId;

	std::string strJson = autojsoncxx::to_pretty_json_string(liveview);
	s32 nJsonLen = strJson.length();
	if (nJsonLen <= 0)
	{
		return FALSE;
	}
	header.cmd = htonl(OAPI_CMD_START_LIVE);
	header.length = htonl(nJsonLen + 1);;

	m_pSocket->Send((void *)&header, sizeof(header));
	m_pSocket->Send((void *)strJson.c_str(), nJsonLen + 1);
	return TRUE;

}

BOOL OAPIClient::StopLiveview(int nId)
{
	OAPIHeader header;

	oapi::LiveView liveview;
	liveview.nId = nId;

	std::string strJson = autojsoncxx::to_pretty_json_string(liveview);
	s32 nJsonLen = strJson.length();
	if (nJsonLen <= 0)
	{
		return FALSE;
	}
	header.cmd = htonl(OAPI_CMD_STOP_LIVE);
	header.length = htonl(nJsonLen + 1);

	m_pSocket->Send((void *)&header, sizeof(header));
	m_pSocket->Send((void *)strJson.c_str(), nJsonLen + 1);
	return TRUE;

}
BOOL OAPIClient::ParseDeviceList(char *pRecv, int len, oapi::DeviceList &list)
{
	autojsoncxx::ParsingResult result;
	if (!autojsoncxx::from_json_string(pRecv, list, result))
	{
	    std::cerr << result << '\n';
	    return FALSE;
	}
	return TRUE;
}
#endif<|endoftext|>


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

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

#include <algorithm>

#include "app/resource_bundle.h"
#include "base/file_path.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "build/build_config.h"
#include "chrome/browser/net/chrome_url_request_context.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host_request_info.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_file_util.h"
#include "chrome/common/extensions/extension_resource.h"
#include "chrome/common/url_constants.h"
#include "googleurl/src/url_util.h"
#include "grit/bookmark_manager_resources_map.h"
#include "net/base/mime_util.h"
#include "net/base/net_errors.h"
#include "net/url_request/url_request_error_job.h"
#include "net/url_request/url_request_file_job.h"
#include "net/url_request/url_request_simple_job.h"

namespace {

class URLRequestResourceBundleJob : public URLRequestSimpleJob {
 public:
  explicit URLRequestResourceBundleJob(URLRequest* request,
      const FilePath& filename, int resource_id)
          : URLRequestSimpleJob(request),
            filename_(filename),
            resource_id_(resource_id) { }

  // URLRequestSimpleJob method.
  virtual bool GetData(std::string* mime_type,
                       std::string* charset,
                       std::string* data) const {
    const ResourceBundle& rb = ResourceBundle::GetSharedInstance();
    *data = rb.GetRawDataResource(resource_id_).as_string();
    bool result = net::GetMimeTypeFromFile(filename_, mime_type);
    if (StartsWithASCII(*mime_type, "text/", false)) {
      // All of our HTML files should be UTF-8 and for other resource types
      // (like images), charset doesn't matter.
      DCHECK(IsStringUTF8(*data));
      *charset = "utf-8";
    }
    return result;
  }

 private:
  virtual ~URLRequestResourceBundleJob() { }

  // We need the filename of the resource to determine the mime type.
  FilePath filename_;

  // The resource bundle id to load.
  int resource_id_;
};

// Returns true if an chrome-extension:// resource should be allowed to load.
bool AllowExtensionResourceLoad(URLRequest* request,
                                ChromeURLRequestContext* context,
                                const std::string& scheme) {
  const ResourceDispatcherHostRequestInfo* info =
      ResourceDispatcherHost::InfoForRequest(request);

  GURL origin_url(info->frame_origin());

  // chrome:// URLs are always allowed to load chrome-extension:// resources.
  // The app launcher in the NTP uses this feature, as does dev tools.
  if (origin_url.SchemeIs(chrome::kChromeUIScheme))
    return true;

  // Disallow loading of packaged resources for hosted apps. We don't allow
  // hybrid hosted/packaged apps.
  if (context->ExtensionHasWebExtent(request->url().host()))
    return false;

  // chrome-extension:// pages can load resources from extensions and packaged
  // apps. This is allowed for legacy reasons.
  if (origin_url.SchemeIs(chrome::kExtensionScheme))
    return true;

  // Extension resources should only be loadable from web pages which the
  // extension has host permissions to (and therefore could be running script
  // in, which might need access to the extension resources).
  ExtensionExtent host_permissions =
      context->GetEffectiveHostPermissionsForExtension(request->url().host());
  if (!origin_url.is_empty() && !host_permissions.ContainsURL(origin_url))
    return false;

  // Don't allow toplevel navigations to extension resources in incognito mode.
  // This is because an extension must run in a single process, and an
  // incognito tab prevents that.
  if (context->is_off_the_record() &&
      info->resource_type() == ResourceType::MAIN_FRAME) {
    return false;
  }

  // Otherwise, the resource load is allowed.
  return true;
}

}  // namespace

// Factory registered with URLRequest to create URLRequestJobs for extension://
// URLs.
static URLRequestJob* CreateExtensionURLRequestJob(URLRequest* request,
                                                   const std::string& scheme) {
  ChromeURLRequestContext* context =
      static_cast<ChromeURLRequestContext*>(request->context());

  // TODO(mpcomplete): better error code.
  if (!AllowExtensionResourceLoad(request, context, scheme))
    return new URLRequestErrorJob(request, net::ERR_ADDRESS_UNREACHABLE);

  // chrome-extension://extension-id/resource/path.js
  const std::string& extension_id = request->url().host();
  FilePath directory_path = context->GetPathForExtension(extension_id);
  if (directory_path.value().empty()) {
    LOG(WARNING) << "Failed to GetPathForExtension: " << extension_id;
    return NULL;
  }

  FilePath resources_path;
  if (PathService::Get(chrome::DIR_RESOURCES, &resources_path) &&
      directory_path.DirName() == resources_path) {
    FilePath relative_path = directory_path.BaseName().Append(
        extension_file_util::ExtensionURLToRelativeFilePath(request->url()));
#if defined(OS_WIN)
    relative_path = relative_path.NormalizeWindowsPathSeparators();
#endif

    // TODO(tc): Make a map of FilePath -> resource ids so we don't have to
    // covert to FilePaths all the time.  This will be more useful as we add
    // more resources.
    for (size_t i = 0; i < kBookmarkManagerResourcesSize; ++i) {
      FilePath bm_resource_path =
          FilePath().AppendASCII(kBookmarkManagerResources[i].name);
#if defined(OS_WIN)
      bm_resource_path = bm_resource_path.NormalizeWindowsPathSeparators();
#endif
      if (relative_path == bm_resource_path) {
        return new URLRequestResourceBundleJob(request, relative_path,
            kBookmarkManagerResources[i].value);
      }
    }
  }
  // TODO(tc): Move all of these files into resources.pak so we don't break
  // when updating on Linux.
  ExtensionResource resource(extension_id, directory_path,
      extension_file_util::ExtensionURLToRelativeFilePath(request->url()));

  return new URLRequestFileJob(request,
                               resource.GetFilePathOnAnyThreadHack());
}

// Factory registered with URLRequest to create URLRequestJobs for
// chrome-user-script:/ URLs.
static URLRequestJob* CreateUserScriptURLRequestJob(URLRequest* request,
                                                    const std::string& scheme) {
  ChromeURLRequestContext* context =
      static_cast<ChromeURLRequestContext*>(request->context());

  // chrome-user-script:/user-script-name.user.js
  FilePath directory_path = context->user_script_dir_path();

  ExtensionResource resource(request->url().host(), directory_path,
      extension_file_util::ExtensionURLToRelativeFilePath(request->url()));

  return new URLRequestFileJob(request, resource.GetFilePath());
}

void RegisterExtensionProtocols() {
  URLRequest::RegisterProtocolFactory(chrome::kExtensionScheme,
                                      &CreateExtensionURLRequestJob);
  URLRequest::RegisterProtocolFactory(chrome::kUserScriptScheme,
                                      &CreateUserScriptURLRequestJob);
}
<commit_msg>Fixes a bug in revision 55103 that prevents extensions from loading their own resources in some rare cases when the origin is "null". <commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

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

#include <algorithm>

#include "app/resource_bundle.h"
#include "base/file_path.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "build/build_config.h"
#include "chrome/browser/net/chrome_url_request_context.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host_request_info.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_file_util.h"
#include "chrome/common/extensions/extension_resource.h"
#include "chrome/common/url_constants.h"
#include "googleurl/src/url_util.h"
#include "grit/bookmark_manager_resources_map.h"
#include "net/base/mime_util.h"
#include "net/base/net_errors.h"
#include "net/url_request/url_request_error_job.h"
#include "net/url_request/url_request_file_job.h"
#include "net/url_request/url_request_simple_job.h"

namespace {

class URLRequestResourceBundleJob : public URLRequestSimpleJob {
 public:
  explicit URLRequestResourceBundleJob(URLRequest* request,
      const FilePath& filename, int resource_id)
          : URLRequestSimpleJob(request),
            filename_(filename),
            resource_id_(resource_id) { }

  // URLRequestSimpleJob method.
  virtual bool GetData(std::string* mime_type,
                       std::string* charset,
                       std::string* data) const {
    const ResourceBundle& rb = ResourceBundle::GetSharedInstance();
    *data = rb.GetRawDataResource(resource_id_).as_string();
    bool result = net::GetMimeTypeFromFile(filename_, mime_type);
    if (StartsWithASCII(*mime_type, "text/", false)) {
      // All of our HTML files should be UTF-8 and for other resource types
      // (like images), charset doesn't matter.
      DCHECK(IsStringUTF8(*data));
      *charset = "utf-8";
    }
    return result;
  }

 private:
  virtual ~URLRequestResourceBundleJob() { }

  // We need the filename of the resource to determine the mime type.
  FilePath filename_;

  // The resource bundle id to load.
  int resource_id_;
};

// Returns true if an chrome-extension:// resource should be allowed to load.
bool AllowExtensionResourceLoad(URLRequest* request,
                                ChromeURLRequestContext* context,
                                const std::string& scheme) {
  const ResourceDispatcherHostRequestInfo* info =
      ResourceDispatcherHost::InfoForRequest(request);

  GURL origin_url(info->frame_origin());

  // chrome:// URLs are always allowed to load chrome-extension:// resources.
  // The app launcher in the NTP uses this feature, as does dev tools.
  if (origin_url.SchemeIs(chrome::kChromeUIScheme))
    return true;

  // Disallow loading of packaged resources for hosted apps. We don't allow
  // hybrid hosted/packaged apps.
  if (context->ExtensionHasWebExtent(request->url().host()))
    return false;

  // chrome-extension:// pages can load resources from extensions and packaged
  // apps. This is allowed for legacy reasons.
  if (origin_url.SchemeIs(chrome::kExtensionScheme))
    return true;

  // Allow extenion's options pages to access resources media resources.
  // This will have an origin of "null".
  if (LowerCaseEqualsASCII(info->frame_origin(), "null"))
    return true;

  // Extension resources should only be loadable from web pages which the
  // extension has host permissions to (and therefore could be running script
  // in, which might need access to the extension resources).
  ExtensionExtent host_permissions =
      context->GetEffectiveHostPermissionsForExtension(request->url().host());
  if (!origin_url.is_empty() && !host_permissions.ContainsURL(origin_url))
    return false;

  // Don't allow toplevel navigations to extension resources in incognito mode.
  // This is because an extension must run in a single process, and an
  // incognito tab prevents that.
  if (context->is_off_the_record() &&
      info->resource_type() == ResourceType::MAIN_FRAME) {
    return false;
  }

  // Otherwise, the resource load is allowed.
  return true;
}

}  // namespace

// Factory registered with URLRequest to create URLRequestJobs for extension://
// URLs.
static URLRequestJob* CreateExtensionURLRequestJob(URLRequest* request,
                                                   const std::string& scheme) {
  ChromeURLRequestContext* context =
      static_cast<ChromeURLRequestContext*>(request->context());

  // TODO(mpcomplete): better error code.
  if (!AllowExtensionResourceLoad(request, context, scheme))
    return new URLRequestErrorJob(request, net::ERR_ADDRESS_UNREACHABLE);

  // chrome-extension://extension-id/resource/path.js
  const std::string& extension_id = request->url().host();
  FilePath directory_path = context->GetPathForExtension(extension_id);
  if (directory_path.value().empty()) {
    LOG(WARNING) << "Failed to GetPathForExtension: " << extension_id;
    return NULL;
  }

  FilePath resources_path;
  if (PathService::Get(chrome::DIR_RESOURCES, &resources_path) &&
      directory_path.DirName() == resources_path) {
    FilePath relative_path = directory_path.BaseName().Append(
        extension_file_util::ExtensionURLToRelativeFilePath(request->url()));
#if defined(OS_WIN)
    relative_path = relative_path.NormalizeWindowsPathSeparators();
#endif

    // TODO(tc): Make a map of FilePath -> resource ids so we don't have to
    // covert to FilePaths all the time.  This will be more useful as we add
    // more resources.
    for (size_t i = 0; i < kBookmarkManagerResourcesSize; ++i) {
      FilePath bm_resource_path =
          FilePath().AppendASCII(kBookmarkManagerResources[i].name);
#if defined(OS_WIN)
      bm_resource_path = bm_resource_path.NormalizeWindowsPathSeparators();
#endif
      if (relative_path == bm_resource_path) {
        return new URLRequestResourceBundleJob(request, relative_path,
            kBookmarkManagerResources[i].value);
      }
    }
  }
  // TODO(tc): Move all of these files into resources.pak so we don't break
  // when updating on Linux.
  ExtensionResource resource(extension_id, directory_path,
      extension_file_util::ExtensionURLToRelativeFilePath(request->url()));

  return new URLRequestFileJob(request,
                               resource.GetFilePathOnAnyThreadHack());
}

// Factory registered with URLRequest to create URLRequestJobs for
// chrome-user-script:/ URLs.
static URLRequestJob* CreateUserScriptURLRequestJob(URLRequest* request,
                                                    const std::string& scheme) {
  ChromeURLRequestContext* context =
      static_cast<ChromeURLRequestContext*>(request->context());

  // chrome-user-script:/user-script-name.user.js
  FilePath directory_path = context->user_script_dir_path();

  ExtensionResource resource(request->url().host(), directory_path,
      extension_file_util::ExtensionURLToRelativeFilePath(request->url()));

  return new URLRequestFileJob(request, resource.GetFilePath());
}

void RegisterExtensionProtocols() {
  URLRequest::RegisterProtocolFactory(chrome::kExtensionScheme,
                                      &CreateExtensionURLRequestJob);
  URLRequest::RegisterProtocolFactory(chrome::kUserScriptScheme,
                                      &CreateUserScriptURLRequestJob);
}
<|endoftext|>


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

#include "base/gfx/png_encoder.h"
#include "chrome/browser/browser_theme_provider.h"
#include "chrome/browser/dom_ui/dom_ui_theme_source.h"
#include "chrome/browser/profile.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/testing_profile.h"
#include "grit/theme_resources.h"
#include "testing/gtest/include/gtest/gtest.h"

// A mock ThemeSource (so we can override SendResponse to get at its data).
class MockThemeSource : public DOMUIThemeSource {
 public:
  explicit MockThemeSource(Profile* profile) : DOMUIThemeSource(profile) { }

  virtual void SendResponse(int request_id, RefCountedBytes* data) {
    result_data_size_ = data ? data->data.size() : 0;
    result_request_id_ = request_id;
  }

  int result_request_id_;
  int result_data_size_;
};

// A mock profile
class MockProfile : public TestingProfile {
 public:
  ThemeProvider* GetThemeProvider() { return new BrowserThemeProvider(); }
};

TEST(DOMUISources, ThemeSourceMimeTypes) {
  MockProfile* profile = new MockProfile();
  DOMUIThemeSource* theme_source = new DOMUIThemeSource(profile);

  EXPECT_EQ(theme_source->GetMimeType("css/newtab.css"), "text/css");
  EXPECT_EQ(theme_source->GetMimeType("css/newtab.css?foo"), "text/css");
  EXPECT_EQ(theme_source->GetMimeType("WRONGURL"), "image/png");
}

TEST(DOMUISources, ThemeSourceImages) {
  MockProfile* profile = new MockProfile();
  MockThemeSource* theme_source = new MockThemeSource(profile);

  // Our test data. Rather than comparing the data itself, we just compare
  // its size.
  ThemeProvider* tp = profile->GetThemeProvider();
  SkBitmap* image = tp->GetBitmapNamed(IDR_THEME_FRAME);
  std::vector<unsigned char> png_bytes;
  PNGEncoder::EncodeBGRASkBitmap(*image, false, &png_bytes);

  theme_source->StartDataRequest("theme_frame", 1);
  EXPECT_EQ(theme_source->result_request_id_, 1);
  EXPECT_EQ(theme_source->result_data_size_, png_bytes.size());

  theme_source->StartDataRequest("theme_toolbar", 2);
  EXPECT_EQ(theme_source->result_request_id_, 2);
  EXPECT_NE(theme_source->result_data_size_, png_bytes.size());
}

TEST(DOMUISources, ThemeSourceCSS) {
  MockProfile* profile = new MockProfile();
  MockThemeSource* theme_source = new MockThemeSource(profile);

  // Generating the test data for the NTP CSS would just involve copying the
  // method, or being super brittle and hard-coding the result (requiring
  // an update to the unittest every time the CSS template changes), so we
  // just check for a successful request and data that is non-null.
  theme_source->StartDataRequest("css/newtab.css", 1);
  EXPECT_EQ(theme_source->result_request_id_, 1);
  EXPECT_NE(theme_source->result_data_size_, 0);

  theme_source->StartDataRequest("css/newtab.css?pie", 3);
  EXPECT_EQ(theme_source->result_request_id_, 3);
  EXPECT_NE(theme_source->result_data_size_, 0);

  // Check that we send NULL back when we can't find what we're looking for.
  theme_source->StartDataRequest("css/WRONGURL", 7);
  EXPECT_EQ(theme_source->result_request_id_, 7);
  EXPECT_EQ(theme_source->result_data_size_, 0);
}
<commit_msg>Fix mac builder. int comparison.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/gfx/png_encoder.h"
#include "chrome/browser/browser_theme_provider.h"
#include "chrome/browser/dom_ui/dom_ui_theme_source.h"
#include "chrome/browser/profile.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/testing_profile.h"
#include "grit/theme_resources.h"
#include "testing/gtest/include/gtest/gtest.h"

// A mock ThemeSource (so we can override SendResponse to get at its data).
class MockThemeSource : public DOMUIThemeSource {
 public:
  explicit MockThemeSource(Profile* profile) : DOMUIThemeSource(profile) { }

  virtual void SendResponse(int request_id, RefCountedBytes* data) {
    result_data_size_ = data ? data->data.size() : 0;
    result_request_id_ = request_id;
  }

  int result_request_id_;
  unsigned int result_data_size_;
};

// A mock profile
class MockProfile : public TestingProfile {
 public:
  ThemeProvider* GetThemeProvider() { return new BrowserThemeProvider(); }
};

TEST(DOMUISources, ThemeSourceMimeTypes) {
  MockProfile* profile = new MockProfile();
  DOMUIThemeSource* theme_source = new DOMUIThemeSource(profile);

  EXPECT_EQ(theme_source->GetMimeType("css/newtab.css"), "text/css");
  EXPECT_EQ(theme_source->GetMimeType("css/newtab.css?foo"), "text/css");
  EXPECT_EQ(theme_source->GetMimeType("WRONGURL"), "image/png");
}

TEST(DOMUISources, ThemeSourceImages) {
  MockProfile* profile = new MockProfile();
  MockThemeSource* theme_source = new MockThemeSource(profile);

  // Our test data. Rather than comparing the data itself, we just compare
  // its size.
  ThemeProvider* tp = profile->GetThemeProvider();
  SkBitmap* image = tp->GetBitmapNamed(IDR_THEME_FRAME);
  std::vector<unsigned char> png_bytes;
  PNGEncoder::EncodeBGRASkBitmap(*image, false, &png_bytes);

  theme_source->StartDataRequest("theme_frame", 1);
  EXPECT_EQ(theme_source->result_request_id_, 1);
  EXPECT_EQ(theme_source->result_data_size_, png_bytes.size());

  theme_source->StartDataRequest("theme_toolbar", 2);
  EXPECT_EQ(theme_source->result_request_id_, 2);
  EXPECT_NE(theme_source->result_data_size_, png_bytes.size());
}

TEST(DOMUISources, ThemeSourceCSS) {
  MockProfile* profile = new MockProfile();
  MockThemeSource* theme_source = new MockThemeSource(profile);

  // Generating the test data for the NTP CSS would just involve copying the
  // method, or being super brittle and hard-coding the result (requiring
  // an update to the unittest every time the CSS template changes), so we
  // just check for a successful request and data that is non-null.
  theme_source->StartDataRequest("css/newtab.css", 1);
  EXPECT_EQ(theme_source->result_request_id_, 1);
  EXPECT_NE(theme_source->result_data_size_, 0);

  theme_source->StartDataRequest("css/newtab.css?pie", 3);
  EXPECT_EQ(theme_source->result_request_id_, 3);
  EXPECT_NE(theme_source->result_data_size_, 0);

  // Check that we send NULL back when we can't find what we're looking for.
  theme_source->StartDataRequest("css/WRONGURL", 7);
  EXPECT_EQ(theme_source->result_request_id_, 7);
  EXPECT_EQ(theme_source->result_data_size_, 0);
}
<|endoftext|>


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

#include "base/command_line.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/ui_test_utils.h"
#include "net/base/mock_host_resolver.h"

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, FLAKY_WindowOpen) {
  CommandLine::ForCurrentProcess()->AppendSwitch(
      switches::kEnableExperimentalExtensionApis);

  ResultCatcher catcher;
  ASSERT_TRUE(LoadExtensionIncognito(test_data_dir_
      .AppendASCII("window_open").AppendASCII("spanning")));
  EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
}

void WaitForTabsAndPopups(Browser* browser, int num_tabs, int num_popups) {
  // We start with one tab and one browser already open.
  ++num_tabs;
  size_t num_browsers = static_cast<size_t>(num_popups) + 1;

  while (true) {
    if (BrowserList::GetBrowserCount(browser->profile()) < num_browsers ||
        browser->tab_count() < num_tabs) {
      MessageLoopForUI::current()->RunAllPending();
      continue;
    }

    ASSERT_EQ(num_browsers, BrowserList::GetBrowserCount(browser->profile()));
    ASSERT_EQ(num_tabs, browser->tab_count());

    for (BrowserList::const_iterator iter = BrowserList::begin();
         iter != BrowserList::end(); ++iter) {
      if (*iter == browser)
        continue;

      // Check for TYPE_POPUP or TYPE_APP_POPUP/PANEL.
      ASSERT_TRUE((*iter)->type() & Browser::TYPE_POPUP);
    }

    break;
  }
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, PopupBlockingExtension) {
  host_resolver()->AddRule("*", "127.0.0.1");
  ASSERT_TRUE(StartTestServer());

  ASSERT_TRUE(LoadExtension(
      test_data_dir_.AppendASCII("window_open").AppendASCII("popup_blocking")
      .AppendASCII("extension")));

  WaitForTabsAndPopups(browser(), 5, 3);
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, PopupBlockingHostedApp) {
  host_resolver()->AddRule("*", "127.0.0.1");
  ASSERT_TRUE(test_server()->Start());

  ASSERT_TRUE(LoadExtension(
      test_data_dir_.AppendASCII("window_open").AppendASCII("popup_blocking")
      .AppendASCII("hosted_app")));

  // The app being tested owns the domain a.com .  The test URLs we navigate
  // to below must be within that domain, so that they fall within the app's
  // web extent.
  GURL::Replacements replace_host;
  std::string a_dot_com = "a.com";
  replace_host.SetHostStr(a_dot_com);

  const std::string popup_app_contents_path(
    "files/extensions/api_test/window_open/popup_blocking/hosted_app/");

  GURL open_tab =
      test_server()->GetURL(popup_app_contents_path + "open_tab.html")
          .ReplaceComponents(replace_host);
  GURL open_popup =
      test_server()->GetURL(popup_app_contents_path + "open_popup.html")
          .ReplaceComponents(replace_host);

  browser()->OpenURL(open_tab, GURL(), NEW_FOREGROUND_TAB,
                     PageTransition::TYPED);
  browser()->OpenURL(open_popup, GURL(), NEW_FOREGROUND_TAB,
                     PageTransition::TYPED);

  WaitForTabsAndPopups(browser(), 3, 1);
}
<commit_msg>Disable ExtensionApiTest.WindowOpen on mac because it never works.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/command_line.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/ui_test_utils.h"
#include "net/base/mock_host_resolver.h"

// crbug.com/60156
#if defined(OS_MACOSX)
// On mac, this test basically never succeeds.
#define FLAKY_WindowOpen DISABLED_WindowOpen
#endif

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, FLAKY_WindowOpen) {
  CommandLine::ForCurrentProcess()->AppendSwitch(
      switches::kEnableExperimentalExtensionApis);

  ResultCatcher catcher;
  ASSERT_TRUE(LoadExtensionIncognito(test_data_dir_
      .AppendASCII("window_open").AppendASCII("spanning")));
  EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
}

void WaitForTabsAndPopups(Browser* browser, int num_tabs, int num_popups) {
  // We start with one tab and one browser already open.
  ++num_tabs;
  size_t num_browsers = static_cast<size_t>(num_popups) + 1;

  while (true) {
    if (BrowserList::GetBrowserCount(browser->profile()) < num_browsers ||
        browser->tab_count() < num_tabs) {
      MessageLoopForUI::current()->RunAllPending();
      continue;
    }

    ASSERT_EQ(num_browsers, BrowserList::GetBrowserCount(browser->profile()));
    ASSERT_EQ(num_tabs, browser->tab_count());

    for (BrowserList::const_iterator iter = BrowserList::begin();
         iter != BrowserList::end(); ++iter) {
      if (*iter == browser)
        continue;

      // Check for TYPE_POPUP or TYPE_APP_POPUP/PANEL.
      ASSERT_TRUE((*iter)->type() & Browser::TYPE_POPUP);
    }

    break;
  }
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, PopupBlockingExtension) {
  host_resolver()->AddRule("*", "127.0.0.1");
  ASSERT_TRUE(StartTestServer());

  ASSERT_TRUE(LoadExtension(
      test_data_dir_.AppendASCII("window_open").AppendASCII("popup_blocking")
      .AppendASCII("extension")));

  WaitForTabsAndPopups(browser(), 5, 3);
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, PopupBlockingHostedApp) {
  host_resolver()->AddRule("*", "127.0.0.1");
  ASSERT_TRUE(test_server()->Start());

  ASSERT_TRUE(LoadExtension(
      test_data_dir_.AppendASCII("window_open").AppendASCII("popup_blocking")
      .AppendASCII("hosted_app")));

  // The app being tested owns the domain a.com .  The test URLs we navigate
  // to below must be within that domain, so that they fall within the app's
  // web extent.
  GURL::Replacements replace_host;
  std::string a_dot_com = "a.com";
  replace_host.SetHostStr(a_dot_com);

  const std::string popup_app_contents_path(
    "files/extensions/api_test/window_open/popup_blocking/hosted_app/");

  GURL open_tab =
      test_server()->GetURL(popup_app_contents_path + "open_tab.html")
          .ReplaceComponents(replace_host);
  GURL open_popup =
      test_server()->GetURL(popup_app_contents_path + "open_popup.html")
          .ReplaceComponents(replace_host);

  browser()->OpenURL(open_tab, GURL(), NEW_FOREGROUND_TAB,
                     PageTransition::TYPED);
  browser()->OpenURL(open_popup, GURL(), NEW_FOREGROUND_TAB,
                     PageTransition::TYPED);

  WaitForTabsAndPopups(browser(), 3, 1);
}
<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 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/app/chrome_dll_resource.h"
#include "chrome/browser/find_in_page_controller.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/window_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "net/url_request/url_request_unittest.h"

class FindInPageControllerTest : public UITest {
 public:
  FindInPageControllerTest() {
    show_window_ = true;
  }
};

const std::wstring kFramePage = L"files/find_in_page/frames.html";
const std::wstring kUserSelectPage = L"files/find_in_page/user-select.html";
const std::wstring kCrashPage = L"files/find_in_page/crash_1341577.html";
const std::wstring kTooFewMatchesPage = L"files/find_in_page/bug_1155639.html";

// This test loads a page with frames and starts FindInPage requests
TEST_F(FindInPageControllerTest, FindInPageFrames) {
  TestServer server(L"chrome/test/data");

  // First we navigate to our frames page.
  GURL url = server.TestServerPageW(kFramePage);
  scoped_ptr<TabProxy> tab(GetActiveTab());
  ASSERT_TRUE(tab->NavigateToURL(url));
  WaitUntilTabCount(1);

  // Try incremental search (mimicking user typing in).
  EXPECT_EQ(18, tab->FindInPage(L"g",       FWD, IGNORE_CASE, false));
  EXPECT_EQ(11, tab->FindInPage(L"go",      FWD, IGNORE_CASE, false));
  EXPECT_EQ(04, tab->FindInPage(L"goo",     FWD, IGNORE_CASE, false));
  EXPECT_EQ(03, tab->FindInPage(L"goog",    FWD, IGNORE_CASE, false));
  EXPECT_EQ(02, tab->FindInPage(L"googl",   FWD, IGNORE_CASE, false));
  EXPECT_EQ(01, tab->FindInPage(L"google",  FWD, IGNORE_CASE, false));
  EXPECT_EQ(00, tab->FindInPage(L"google!", FWD, IGNORE_CASE, false));

  // Negative test (no matches should be found).
  EXPECT_EQ(0, tab->FindInPage(L"Non-existing string", FWD, IGNORE_CASE,
                               false));

  // 'horse' only exists in the three right frames.
  EXPECT_EQ(3, tab->FindInPage(L"horse", FWD, IGNORE_CASE, false));

  // 'cat' only exists in the first frame.
  EXPECT_EQ(1, tab->FindInPage(L"cat", FWD, IGNORE_CASE, false));

  // Try searching again, should still come up with 1 match.
  EXPECT_EQ(1, tab->FindInPage(L"cat", FWD, IGNORE_CASE, false));

  // Try searching backwards, ignoring case, should still come up with 1 match.
  EXPECT_EQ(1, tab->FindInPage(L"CAT", BACK, IGNORE_CASE, false));

  // Try case sensitive, should NOT find it.
  EXPECT_EQ(0, tab->FindInPage(L"CAT", FWD, CASE_SENSITIVE, false));

  // Try again case sensitive, but this time with right case.
  EXPECT_EQ(1, tab->FindInPage(L"dog", FWD, CASE_SENSITIVE, false));

  // Try non-Latin characters ('Hreggvidur' with 'eth' for 'd' in left frame).
  EXPECT_EQ(1, tab->FindInPage(L"Hreggvi\u00F0ur", FWD, IGNORE_CASE, false));
  EXPECT_EQ(1, tab->FindInPage(L"Hreggvi\u00F0ur", FWD, CASE_SENSITIVE, false));
  EXPECT_EQ(0, tab->FindInPage(L"hreggvi\u00F0ur", FWD, CASE_SENSITIVE, false));
}

// Load a page with no selectable text and make sure we don't crash.
TEST_F(FindInPageControllerTest, FindUnSelectableText) {
  TestServer server(L"chrome/test/data");

  GURL url = server.TestServerPageW(kUserSelectPage);
  scoped_ptr<TabProxy> tab(GetActiveTab());
  ASSERT_TRUE(tab->NavigateToURL(url));
  WaitUntilTabCount(1);

  EXPECT_EQ(0, tab->FindInPage(L"text", FWD, IGNORE_CASE, false));
  EXPECT_EQ(0, tab->FindInPage(L"Non-existing string", FWD, IGNORE_CASE,
                               false));
}

// Try to reproduce the crash seen in issue 1341577.
TEST_F(FindInPageControllerTest, FindCrash_Issue1341577) {
  TestServer server(L"chrome/test/data");

  GURL url = server.TestServerPageW(kCrashPage);
  scoped_ptr<TabProxy> tab(GetActiveTab());
  ASSERT_TRUE(tab->NavigateToURL(url));
  WaitUntilTabCount(1);

  // This would crash the tab. These must be the first two find requests issued
  // against the frame, otherwise an active frame pointer is set and it wont
  // produce the crash.
  EXPECT_EQ(1, tab->FindInPage(L"\u0D4C", FWD, IGNORE_CASE, false));
  // FindNext returns -1 for match count because it doesn't bother with
  // recounting the number of matches. We don't care about the match count
  // anyway in this case, we just want to make sure it doesn't crash.
  EXPECT_EQ(-1, tab->FindInPage(L"\u0D4C", FWD, IGNORE_CASE, true));

  // This should work fine.
  EXPECT_EQ(1, tab->FindInPage(L"\u0D24\u0D46", FWD, IGNORE_CASE, false));
  EXPECT_EQ(0, tab->FindInPage(L"nostring", FWD, IGNORE_CASE, false));
}

// Test to make sure Find does the right thing when restarting from a timeout.
// We used to have a problem where we'd stop finding matches when all of the
// following conditions were true:
// 1) The page has a lot of text to search.
// 2) The page contains more than one match.
// 3) It takes longer than the time-slice given to each Find operation (100
//    ms) to find one or more of those matches (so Find times out and has to try
//    again from where it left off).
TEST_F(FindInPageControllerTest, FindEnoughMatches_Issue1155639) {
  TestServer server(L"chrome/test/data");

  GURL url = server.TestServerPageW(kTooFewMatchesPage);
  scoped_ptr<TabProxy> tab(GetActiveTab());
  ASSERT_TRUE(tab->NavigateToURL(url));
  WaitUntilTabCount(1);

  // This string appears 5 times at the bottom of a long page. If Find restarts
  // properly after a timeout, it will find 5 matches, not just 1.
  EXPECT_EQ(5, tab->FindInPage(L"008.xml", FWD, IGNORE_CASE, false));
}

// The find window should not change its location just because we open and close
// a new tab.
TEST_F(FindInPageControllerTest, FindMovesOnTabClose_Issue1343052) {
  TestServer server(L"chrome/test/data");

  GURL url = server.TestServerPageW(kFramePage);
  scoped_ptr<TabProxy> tabA(GetActiveTab());
  ASSERT_TRUE(tabA->NavigateToURL(url));
  WaitUntilTabCount(1);

  scoped_ptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get() != NULL);

  // Toggle the bookmark bar state.
  browser->ApplyAccelerator(IDC_SHOW_BOOKMARKS_BAR);
  EXPECT_TRUE(WaitForBookmarkBarVisibilityChange(browser.get(), true));

  // Open the Find window and wait for it to animate.
  EXPECT_TRUE(tabA->OpenFindInPage());
  EXPECT_TRUE(WaitForFindWindowFullyVisible(tabA.get()));

  // Find its location.
  int x = -1, y = -1;
  EXPECT_TRUE(tabA->GetFindWindowLocation(&x, &y));

  // Open another tab (tab B).
  EXPECT_TRUE(browser->AppendTab(url));
  scoped_ptr<TabProxy> tabB(GetActiveTab());

  // Close tab B.
  EXPECT_TRUE(tabB->Close(true));

  // See if the Find window has moved.
  int new_x = -1, new_y = -1;
  EXPECT_TRUE(tabA->GetFindWindowLocation(&new_x, &new_y));

  EXPECT_EQ(x, new_x);
  EXPECT_EQ(y, new_y);

  // Now reset the bookmarks bar state and try the same again.
  browser->ApplyAccelerator(IDC_SHOW_BOOKMARKS_BAR);
  EXPECT_TRUE(WaitForBookmarkBarVisibilityChange(browser.get(), false));

  // Bookmark bar has moved, reset our coordinates.
  EXPECT_TRUE(tabA->GetFindWindowLocation(&x, &y));

  // Open another tab (tab C).
  EXPECT_TRUE(browser->AppendTab(url));
  scoped_ptr<TabProxy> tabC(GetActiveTab());

  // Close it.
  EXPECT_TRUE(tabC->Close(true));

  // See if the Find window has moved.
  EXPECT_TRUE(tabA->GetFindWindowLocation(&new_x, &new_y));

  EXPECT_EQ(x, new_x);
  EXPECT_EQ(y, new_y);
}
<commit_msg>Add some trace statements in an attempt to find the reason why a Find test is flaky. This will be removed once I get a run that hangs again.<commit_after>// Copyright (c) 2006-2008 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/app/chrome_dll_resource.h"
#include "chrome/browser/find_in_page_controller.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/window_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "net/url_request/url_request_unittest.h"

class FindInPageControllerTest : public UITest {
 public:
  FindInPageControllerTest() {
    show_window_ = true;
  }
};

const std::wstring kFramePage = L"files/find_in_page/frames.html";
const std::wstring kUserSelectPage = L"files/find_in_page/user-select.html";
const std::wstring kCrashPage = L"files/find_in_page/crash_1341577.html";
const std::wstring kTooFewMatchesPage = L"files/find_in_page/bug_1155639.html";

// This test loads a page with frames and starts FindInPage requests
TEST_F(FindInPageControllerTest, FindInPageFrames) {
  TestServer server(L"chrome/test/data");

  // First we navigate to our frames page.
  GURL url = server.TestServerPageW(kFramePage);
  scoped_ptr<TabProxy> tab(GetActiveTab());
  ASSERT_TRUE(tab->NavigateToURL(url));
  WaitUntilTabCount(1);

  // Try incremental search (mimicking user typing in).
  EXPECT_EQ(18, tab->FindInPage(L"g",       FWD, IGNORE_CASE, false));
  EXPECT_EQ(11, tab->FindInPage(L"go",      FWD, IGNORE_CASE, false));
  EXPECT_EQ(04, tab->FindInPage(L"goo",     FWD, IGNORE_CASE, false));
  EXPECT_EQ(03, tab->FindInPage(L"goog",    FWD, IGNORE_CASE, false));
  EXPECT_EQ(02, tab->FindInPage(L"googl",   FWD, IGNORE_CASE, false));
  EXPECT_EQ(01, tab->FindInPage(L"google",  FWD, IGNORE_CASE, false));
  EXPECT_EQ(00, tab->FindInPage(L"google!", FWD, IGNORE_CASE, false));

  // Negative test (no matches should be found).
  EXPECT_EQ(0, tab->FindInPage(L"Non-existing string", FWD, IGNORE_CASE,
                               false));

  // 'horse' only exists in the three right frames.
  EXPECT_EQ(3, tab->FindInPage(L"horse", FWD, IGNORE_CASE, false));

  // 'cat' only exists in the first frame.
  EXPECT_EQ(1, tab->FindInPage(L"cat", FWD, IGNORE_CASE, false));

  // Try searching again, should still come up with 1 match.
  EXPECT_EQ(1, tab->FindInPage(L"cat", FWD, IGNORE_CASE, false));

  // Try searching backwards, ignoring case, should still come up with 1 match.
  EXPECT_EQ(1, tab->FindInPage(L"CAT", BACK, IGNORE_CASE, false));

  // Try case sensitive, should NOT find it.
  EXPECT_EQ(0, tab->FindInPage(L"CAT", FWD, CASE_SENSITIVE, false));

  // Try again case sensitive, but this time with right case.
  EXPECT_EQ(1, tab->FindInPage(L"dog", FWD, CASE_SENSITIVE, false));

  // Try non-Latin characters ('Hreggvidur' with 'eth' for 'd' in left frame).
  EXPECT_EQ(1, tab->FindInPage(L"Hreggvi\u00F0ur", FWD, IGNORE_CASE, false));
  EXPECT_EQ(1, tab->FindInPage(L"Hreggvi\u00F0ur", FWD, CASE_SENSITIVE, false));
  EXPECT_EQ(0, tab->FindInPage(L"hreggvi\u00F0ur", FWD, CASE_SENSITIVE, false));
}

// Load a page with no selectable text and make sure we don't crash.
TEST_F(FindInPageControllerTest, FindUnSelectableText) {
  TestServer server(L"chrome/test/data");

  GURL url = server.TestServerPageW(kUserSelectPage);
  scoped_ptr<TabProxy> tab(GetActiveTab());
  ASSERT_TRUE(tab->NavigateToURL(url));
  WaitUntilTabCount(1);

  EXPECT_EQ(0, tab->FindInPage(L"text", FWD, IGNORE_CASE, false));
  EXPECT_EQ(0, tab->FindInPage(L"Non-existing string", FWD, IGNORE_CASE,
                               false));
}

// Try to reproduce the crash seen in issue 1341577.
TEST_F(FindInPageControllerTest, FindCrash_Issue1341577) {
  TestServer server(L"chrome/test/data");

  GURL url = server.TestServerPageW(kCrashPage);
  scoped_ptr<TabProxy> tab(GetActiveTab());
  ASSERT_TRUE(tab->NavigateToURL(url));
  WaitUntilTabCount(1);

  // This would crash the tab. These must be the first two find requests issued
  // against the frame, otherwise an active frame pointer is set and it wont
  // produce the crash.
  EXPECT_EQ(1, tab->FindInPage(L"\u0D4C", FWD, IGNORE_CASE, false));
  // FindNext returns -1 for match count because it doesn't bother with
  // recounting the number of matches. We don't care about the match count
  // anyway in this case, we just want to make sure it doesn't crash.
  EXPECT_EQ(-1, tab->FindInPage(L"\u0D4C", FWD, IGNORE_CASE, true));

  // This should work fine.
  EXPECT_EQ(1, tab->FindInPage(L"\u0D24\u0D46", FWD, IGNORE_CASE, false));
  EXPECT_EQ(0, tab->FindInPage(L"nostring", FWD, IGNORE_CASE, false));
}

// Test to make sure Find does the right thing when restarting from a timeout.
// We used to have a problem where we'd stop finding matches when all of the
// following conditions were true:
// 1) The page has a lot of text to search.
// 2) The page contains more than one match.
// 3) It takes longer than the time-slice given to each Find operation (100
//    ms) to find one or more of those matches (so Find times out and has to try
//    again from where it left off).
TEST_F(FindInPageControllerTest, FindEnoughMatches_Issue1155639) {
  TestServer server(L"chrome/test/data");

  GURL url = server.TestServerPageW(kTooFewMatchesPage);
  scoped_ptr<TabProxy> tab(GetActiveTab());
  ASSERT_TRUE(tab->NavigateToURL(url));
  WaitUntilTabCount(1);

  // This string appears 5 times at the bottom of a long page. If Find restarts
  // properly after a timeout, it will find 5 matches, not just 1.
  EXPECT_EQ(5, tab->FindInPage(L"008.xml", FWD, IGNORE_CASE, false));
}

// The find window should not change its location just because we open and close
// a new tab.
TEST_F(FindInPageControllerTest, FindMovesOnTabClose_Issue1343052) {
  fprintf(stderr, "Starting FindMovesOnTabClose_Issue1343052\n");
  TestServer server(L"chrome/test/data");

  fprintf(stderr, "TestServerPageW\n");
  GURL url = server.TestServerPageW(kFramePage);
  fprintf(stderr, "GetActiveTab A\n");
  scoped_ptr<TabProxy> tabA(GetActiveTab());
  fprintf(stderr, "Navigate A\n");
  ASSERT_TRUE(tabA->NavigateToURL(url));
  fprintf(stderr, "WaitUntilTabCount(1) for A\n");
  WaitUntilTabCount(1);

  fprintf(stderr, "GetBrowserWindow(0)\n");
  scoped_ptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get() != NULL);

  // Toggle the bookmark bar state.
  fprintf(stderr, "ApplyAccelerator bookmark bar\n");
  browser->ApplyAccelerator(IDC_SHOW_BOOKMARKS_BAR);
  fprintf(stderr, "WaitForBookmarkVisibility\n");
  EXPECT_TRUE(WaitForBookmarkBarVisibilityChange(browser.get(), true));

  // Open the Find window and wait for it to animate.
  fprintf(stderr, "OpenFindInPage in A\n");
  EXPECT_TRUE(tabA->OpenFindInPage());
  fprintf(stderr, "WaitForWindowFullyVisible in A\n");
  EXPECT_TRUE(WaitForFindWindowFullyVisible(tabA.get()));

  // Find its location.
  int x = -1, y = -1;
  fprintf(stderr, "GetFindWindowLocation in A\n");
  EXPECT_TRUE(tabA->GetFindWindowLocation(&x, &y));

  // Open another tab (tab B).
  fprintf(stderr, "AppendTab B\n");
  EXPECT_TRUE(browser->AppendTab(url));
  fprintf(stderr, "GetActiveTab B\n");
  scoped_ptr<TabProxy> tabB(GetActiveTab());

  // Close tab B.
  fprintf(stderr, "Tab Close B\n");
  EXPECT_TRUE(tabB->Close(true));

  // See if the Find window has moved.
  int new_x = -1, new_y = -1;
  fprintf(stderr, "GetFindWindowLocation in A\n");
  EXPECT_TRUE(tabA->GetFindWindowLocation(&new_x, &new_y));

  EXPECT_EQ(x, new_x);
  EXPECT_EQ(y, new_y);

  // Now reset the bookmarks bar state and try the same again.
  fprintf(stderr, "ApplyAccelerator BookmarksBar\n");
  browser->ApplyAccelerator(IDC_SHOW_BOOKMARKS_BAR);
  fprintf(stderr, "WaitForBookmarkBarVisibilityChange\n");
  EXPECT_TRUE(WaitForBookmarkBarVisibilityChange(browser.get(), false));

  // Bookmark bar has moved, reset our coordinates.
  fprintf(stderr, "GetFindWindowLocation again\n");
  EXPECT_TRUE(tabA->GetFindWindowLocation(&x, &y));

  // Open another tab (tab C).
  fprintf(stderr, "Append tab C\n");
  EXPECT_TRUE(browser->AppendTab(url));
  fprintf(stderr, "GetActiveTab C\n");
  scoped_ptr<TabProxy> tabC(GetActiveTab());

  // Close it.
  fprintf(stderr, "Close tab C\n");
  EXPECT_TRUE(tabC->Close(true));

  // See if the Find window has moved.
  fprintf(stderr, "GetFindWindowLocation yet again\n");
  EXPECT_TRUE(tabA->GetFindWindowLocation(&new_x, &new_y));

  EXPECT_EQ(x, new_x);
  EXPECT_EQ(y, new_y);
  fprintf(stderr, "Done!\n");
}
<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 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.

// Tests the MetricsService stat recording to make sure that the numbers are
// what we expect.

#include <string>

#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/platform_thread.h"
#include "base/process_util.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/pref_service.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "net/base/net_util.h"

class MetricsServiceTest : public UITest {
 public:
   MetricsServiceTest() : UITest() {
     // We need to show the window so web content type tabs load.
     show_window_ = true;
   }

  // Open a few tabs of random content
  void OpenTabs() {
    scoped_refptr<BrowserProxy> window = automation()->GetBrowserWindow(0);
    ASSERT_TRUE(window.get());

    FilePath page1_path;
    ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &page1_path));
    page1_path = page1_path.AppendASCII("title2.html");
    ASSERT_TRUE(window->AppendTab(net::FilePathToFileURL(page1_path)));

    FilePath page2_path;
    ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &page2_path));
    page2_path = page2_path.AppendASCII("iframe.html");
    ASSERT_TRUE(window->AppendTab(net::FilePathToFileURL(page2_path)));
  }

  // Get a PrefService whose contents correspond to the Local State file
  // that was saved by the app as it closed.  The caller takes ownership of the
  // returned PrefService object.
  PrefService* GetLocalState() {
    FilePath local_state_path = user_data_dir()
        .Append(chrome::kLocalStateFilename);

    return new PrefService(local_state_path);
  }
};

TEST_F(MetricsServiceTest, CloseRenderersNormally) {
  OpenTabs();
  QuitBrowser();

  scoped_ptr<PrefService> local_state(GetLocalState());
  local_state->RegisterBooleanPref(prefs::kStabilityExitedCleanly, true);
  local_state->RegisterIntegerPref(prefs::kStabilityLaunchCount, 0);
  local_state->RegisterIntegerPref(prefs::kStabilityPageLoadCount, 0);
  local_state->RegisterIntegerPref(prefs::kStabilityRendererCrashCount, 0);
  EXPECT_TRUE(local_state->GetBoolean(prefs::kStabilityExitedCleanly));
  EXPECT_EQ(1, local_state->GetInteger(prefs::kStabilityLaunchCount));
  EXPECT_EQ(3, local_state->GetInteger(prefs::kStabilityPageLoadCount));
  EXPECT_EQ(0, local_state->GetInteger(prefs::kStabilityRendererCrashCount));
}

#if defined(OS_WIN)
// http://crbug.com/32048
#define CrashRenderers FLAKY_CrashRenders
#endif
TEST_F(MetricsServiceTest, CrashRenderers) {
  // This doesn't make sense to test in single process mode.
  if (in_process_renderer_)
    return;

  OpenTabs();

  {
    // Limit the lifetime of various automation proxies used here. We must
    // destroy them before calling QuitBrowser.

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

    // Kill the process for one of the tabs.
    scoped_refptr<TabProxy> tab(window->GetTab(1));
    ASSERT_TRUE(tab.get());

// Only windows implements the crash service for now.
#if defined(OS_WIN)
    expected_crashes_ = 1;
#endif
    ASSERT_TRUE(tab->NavigateToURLAsync(GURL("about:crash")));
  }

  // Give the browser a chance to notice the crashed tab.
  PlatformThread::Sleep(1000);

  QuitBrowser();

  scoped_ptr<PrefService> local_state(GetLocalState());
  local_state->RegisterBooleanPref(prefs::kStabilityExitedCleanly, true);
  local_state->RegisterIntegerPref(prefs::kStabilityLaunchCount, 0);
  local_state->RegisterIntegerPref(prefs::kStabilityPageLoadCount, 0);
  local_state->RegisterIntegerPref(prefs::kStabilityRendererCrashCount, 0);
  EXPECT_TRUE(local_state->GetBoolean(prefs::kStabilityExitedCleanly));
  EXPECT_EQ(1, local_state->GetInteger(prefs::kStabilityLaunchCount));
  EXPECT_EQ(4, local_state->GetInteger(prefs::kStabilityPageLoadCount));
  EXPECT_EQ(1, local_state->GetInteger(prefs::kStabilityRendererCrashCount));
}
<commit_msg>Linux: Fix test crash expectations for MetricsServiceTest.CrashRenderers.<commit_after>// Copyright (c) 2006-2008 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.

// Tests the MetricsService stat recording to make sure that the numbers are
// what we expect.

#include <string>

#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/platform_thread.h"
#include "base/process_util.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/pref_service.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "net/base/net_util.h"

class MetricsServiceTest : public UITest {
 public:
   MetricsServiceTest() : UITest() {
     // We need to show the window so web content type tabs load.
     show_window_ = true;
   }

  // Open a few tabs of random content
  void OpenTabs() {
    scoped_refptr<BrowserProxy> window = automation()->GetBrowserWindow(0);
    ASSERT_TRUE(window.get());

    FilePath page1_path;
    ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &page1_path));
    page1_path = page1_path.AppendASCII("title2.html");
    ASSERT_TRUE(window->AppendTab(net::FilePathToFileURL(page1_path)));

    FilePath page2_path;
    ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &page2_path));
    page2_path = page2_path.AppendASCII("iframe.html");
    ASSERT_TRUE(window->AppendTab(net::FilePathToFileURL(page2_path)));
  }

  // Get a PrefService whose contents correspond to the Local State file
  // that was saved by the app as it closed.  The caller takes ownership of the
  // returned PrefService object.
  PrefService* GetLocalState() {
    FilePath local_state_path = user_data_dir()
        .Append(chrome::kLocalStateFilename);

    return new PrefService(local_state_path);
  }
};

TEST_F(MetricsServiceTest, CloseRenderersNormally) {
  OpenTabs();
  QuitBrowser();

  scoped_ptr<PrefService> local_state(GetLocalState());
  local_state->RegisterBooleanPref(prefs::kStabilityExitedCleanly, true);
  local_state->RegisterIntegerPref(prefs::kStabilityLaunchCount, 0);
  local_state->RegisterIntegerPref(prefs::kStabilityPageLoadCount, 0);
  local_state->RegisterIntegerPref(prefs::kStabilityRendererCrashCount, 0);
  EXPECT_TRUE(local_state->GetBoolean(prefs::kStabilityExitedCleanly));
  EXPECT_EQ(1, local_state->GetInteger(prefs::kStabilityLaunchCount));
  EXPECT_EQ(3, local_state->GetInteger(prefs::kStabilityPageLoadCount));
  EXPECT_EQ(0, local_state->GetInteger(prefs::kStabilityRendererCrashCount));
}

#if defined(OS_WIN)
// http://crbug.com/32048
#define CrashRenderers FLAKY_CrashRenders
#endif
TEST_F(MetricsServiceTest, CrashRenderers) {
  // This doesn't make sense to test in single process mode.
  if (in_process_renderer_)
    return;

  OpenTabs();

  {
    // Limit the lifetime of various automation proxies used here. We must
    // destroy them before calling QuitBrowser.

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

    // Kill the process for one of the tabs.
    scoped_refptr<TabProxy> tab(window->GetTab(1));
    ASSERT_TRUE(tab.get());

// We should get a crash dump on Windows.
// Also on Linux with Breakpad enabled.
#if defined(OS_WIN) || defined(USE_LINUX_BREAKPAD)
    expected_crashes_ = 1;
#endif
    ASSERT_TRUE(tab->NavigateToURLAsync(GURL("about:crash")));
  }

  // Give the browser a chance to notice the crashed tab.
  PlatformThread::Sleep(1000);

  QuitBrowser();

  scoped_ptr<PrefService> local_state(GetLocalState());
  local_state->RegisterBooleanPref(prefs::kStabilityExitedCleanly, true);
  local_state->RegisterIntegerPref(prefs::kStabilityLaunchCount, 0);
  local_state->RegisterIntegerPref(prefs::kStabilityPageLoadCount, 0);
  local_state->RegisterIntegerPref(prefs::kStabilityRendererCrashCount, 0);
  EXPECT_TRUE(local_state->GetBoolean(prefs::kStabilityExitedCleanly));
  EXPECT_EQ(1, local_state->GetInteger(prefs::kStabilityLaunchCount));
  EXPECT_EQ(4, local_state->GetInteger(prefs::kStabilityPageLoadCount));
  EXPECT_EQ(1, local_state->GetInteger(prefs::kStabilityRendererCrashCount));
}
<|endoftext|>


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

#include "chrome/browser/ssl_client_certificate_selector.h"

#include <gtk/gtk.h>

#include <string>
#include <vector>

#include "app/gtk_signal.h"
#include "app/l10n_util.h"
#include "base/i18n/time_formatting.h"
#include "base/logging.h"
#include "base/nss_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/certificate_viewer.h"
#include "chrome/browser/gtk/constrained_window_gtk.h"
#include "chrome/browser/gtk/gtk_util.h"
#include "chrome/browser/gtk/owned_widget_gtk.h"
#include "chrome/browser/ssl/ssl_client_auth_handler.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/net/x509_certificate_model.h"
#include "gfx/native_widget_types.h"
#include "grit/generated_resources.h"
#include "net/base/x509_certificate.h"

namespace {

enum {
  RESPONSE_SHOW_CERT_INFO = 1,
};

///////////////////////////////////////////////////////////////////////////////
// SSLClientCertificateSelector

class SSLClientCertificateSelector : public ConstrainedDialogDelegate {
 public:
  explicit SSLClientCertificateSelector(
      TabContents* parent,
      net::SSLCertRequestInfo* cert_request_info,
      SSLClientAuthHandler* delegate);
  ~SSLClientCertificateSelector();

  void Show();

  // ConstrainedDialogDelegate implementation:
  virtual GtkWidget* GetWidgetRoot() { return root_widget_.get(); }
  virtual void DeleteDelegate() { delete this; }

 private:
  void PopulateCerts();

  net::X509Certificate* GetSelectedCert();

  static std::string FormatComboBoxText(
      net::X509Certificate::OSCertHandle cert,
      const std::string& nickname);
  static std::string FormatDetailsText(
      net::X509Certificate::OSCertHandle cert);

  CHROMEGTK_CALLBACK_0(SSLClientCertificateSelector, void, OnComboBoxChanged);
  CHROMEGTK_CALLBACK_0(SSLClientCertificateSelector, void, OnViewClicked);
  CHROMEGTK_CALLBACK_0(SSLClientCertificateSelector, void, OnCancelClicked);
  CHROMEGTK_CALLBACK_0(SSLClientCertificateSelector, void, OnOkClicked);
  CHROMEGTK_CALLBACK_1(SSLClientCertificateSelector, void, OnPromptShown,
                       GtkWidget*);

  scoped_refptr<net::SSLCertRequestInfo> cert_request_info_;

  std::vector<std::string> details_strings_;

  GtkWidget* cert_combo_box_;
  GtkTextBuffer* cert_details_buffer_;

  scoped_refptr<SSLClientAuthHandler> delegate_;

  OwnedWidgetGtk root_widget_;
  // Hold on to the select button to focus it.
  GtkWidget* select_button_;

  TabContents* parent_;
  ConstrainedWindow* window_;

  DISALLOW_COPY_AND_ASSIGN(SSLClientCertificateSelector);
};

SSLClientCertificateSelector::SSLClientCertificateSelector(
    TabContents* parent,
    net::SSLCertRequestInfo* cert_request_info,
    SSLClientAuthHandler* delegate)
    : cert_request_info_(cert_request_info),
      delegate_(delegate),
      parent_(parent),
      window_(NULL) {
  root_widget_.Own(gtk_vbox_new(FALSE, gtk_util::kControlSpacing));

  GtkWidget* site_vbox = gtk_vbox_new(FALSE, gtk_util::kControlSpacing);
  gtk_box_pack_start(GTK_BOX(root_widget_.get()), site_vbox,
                     FALSE, FALSE, 0);

  GtkWidget* site_description_label = gtk_util::CreateBoldLabel(
      l10n_util::GetStringUTF8(IDS_CERT_SELECTOR_SITE_DESCRIPTION_LABEL));
  gtk_box_pack_start(GTK_BOX(site_vbox), site_description_label,
                     FALSE, FALSE, 0);

  GtkWidget* site_label = gtk_label_new(
      cert_request_info->host_and_port.c_str());
  gtk_util::LeftAlignMisc(site_label);
  gtk_box_pack_start(GTK_BOX(site_vbox), site_label, FALSE, FALSE, 0);

  GtkWidget* selector_vbox = gtk_vbox_new(FALSE, gtk_util::kControlSpacing);
  gtk_box_pack_start(GTK_BOX(root_widget_.get()), selector_vbox,
                     TRUE, TRUE, 0);

  GtkWidget* choose_description_label = gtk_util::CreateBoldLabel(
      l10n_util::GetStringUTF8(IDS_CERT_SELECTOR_CHOOSE_DESCRIPTION_LABEL));
  gtk_box_pack_start(GTK_BOX(selector_vbox), choose_description_label,
                     FALSE, FALSE, 0);

  cert_combo_box_ = gtk_combo_box_new_text();
  g_signal_connect(cert_combo_box_, "changed",
                   G_CALLBACK(OnComboBoxChangedThunk), this);
  gtk_box_pack_start(GTK_BOX(selector_vbox), cert_combo_box_,
                     FALSE, FALSE, 0);

  GtkWidget* details_label = gtk_label_new(l10n_util::GetStringUTF8(
      IDS_CERT_SELECTOR_DETAILS_DESCRIPTION_LABEL).c_str());
  gtk_util::LeftAlignMisc(details_label);
  gtk_box_pack_start(GTK_BOX(selector_vbox), details_label, FALSE, FALSE, 0);

  // TODO(mattm): fix text view coloring (should have grey background).
  GtkWidget* cert_details_view = gtk_text_view_new();
  gtk_text_view_set_editable(GTK_TEXT_VIEW(cert_details_view), FALSE);
  gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(cert_details_view), GTK_WRAP_WORD);
  cert_details_buffer_ = gtk_text_view_get_buffer(
      GTK_TEXT_VIEW(cert_details_view));
  // We put the details in a frame instead of a scrolled window so that the
  // entirety will be visible without requiring scrolling or expanding the
  // dialog.  This does however mean the dialog will grow itself if you switch
  // to different cert that has longer details text.
  GtkWidget* details_frame = gtk_frame_new(NULL);
  gtk_frame_set_shadow_type(GTK_FRAME(details_frame), GTK_SHADOW_ETCHED_IN);
  gtk_container_add(GTK_CONTAINER(details_frame), cert_details_view);
  gtk_box_pack_start(GTK_BOX(selector_vbox), details_frame, TRUE, TRUE, 0);

  // And then create a set of buttons like a GtkDialog would.
  GtkWidget* button_box = gtk_hbutton_box_new();
  gtk_button_box_set_layout(GTK_BUTTON_BOX(button_box), GTK_BUTTONBOX_END);
  gtk_box_set_spacing(GTK_BOX(button_box), gtk_util::kControlSpacing);
  gtk_box_pack_end(GTK_BOX(root_widget_.get()), button_box, FALSE, FALSE, 0);

  GtkWidget* view_button = gtk_button_new_with_mnemonic(
      l10n_util::GetStringUTF8(IDS_PAGEINFO_CERT_INFO_BUTTON).c_str());
  gtk_box_pack_start(GTK_BOX(button_box), view_button, FALSE, FALSE, 0);
  g_signal_connect(view_button, "clicked",
                   G_CALLBACK(OnViewClickedThunk), this);

  GtkWidget* cancel_button = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
  gtk_box_pack_end(GTK_BOX(button_box), cancel_button, FALSE, FALSE, 0);
  g_signal_connect(cancel_button, "clicked",
                   G_CALLBACK(OnCancelClickedThunk), this);

  GtkWidget* select_button = gtk_button_new_from_stock(GTK_STOCK_OK);
  gtk_box_pack_end(GTK_BOX(button_box), select_button, FALSE, FALSE, 0);
  g_signal_connect(select_button, "clicked",
                   G_CALLBACK(OnOkClickedThunk), this);

  // When we are attached to a window, focus the select button.
  select_button_ = select_button;
  g_signal_connect(root_widget_.get(), "hierarchy-changed",
                   G_CALLBACK(OnPromptShownThunk), this);
  PopulateCerts();

  gtk_widget_show_all(root_widget_.get());
}

SSLClientCertificateSelector::~SSLClientCertificateSelector() {
  root_widget_.Destroy();
}

void SSLClientCertificateSelector::Show() {
  DCHECK(!window_);
  window_ = parent_->CreateConstrainedDialog(this);
}

void SSLClientCertificateSelector::PopulateCerts() {
  std::vector<std::string> nicknames;
  x509_certificate_model::GetNicknameStringsFromCertList(
      cert_request_info_->client_certs,
      l10n_util::GetStringUTF8(IDS_CERT_SELECTOR_CERT_EXPIRED),
      l10n_util::GetStringUTF8(IDS_CERT_SELECTOR_CERT_NOT_YET_VALID),
      &nicknames);

  DCHECK_EQ(nicknames.size(),
            cert_request_info_->client_certs.size());

  for (size_t i = 0; i < cert_request_info_->client_certs.size(); ++i) {
    net::X509Certificate::OSCertHandle cert =
        cert_request_info_->client_certs[i]->os_cert_handle();

    details_strings_.push_back(FormatDetailsText(cert));

    gtk_combo_box_append_text(
        GTK_COMBO_BOX(cert_combo_box_),
        FormatComboBoxText(cert, nicknames[i]).c_str());
  }

  // Auto-select the first cert.
  gtk_combo_box_set_active(GTK_COMBO_BOX(cert_combo_box_), 0);
}

net::X509Certificate* SSLClientCertificateSelector::GetSelectedCert() {
  int selected = gtk_combo_box_get_active(GTK_COMBO_BOX(cert_combo_box_));
  if (selected >= 0 &&
      selected < static_cast<int>(
          cert_request_info_->client_certs.size()))
    return cert_request_info_->client_certs[selected];
  return NULL;
}

// static
std::string SSLClientCertificateSelector::FormatComboBoxText(
    net::X509Certificate::OSCertHandle cert, const std::string& nickname) {
  std::string rv(nickname);
  rv += " [";
  rv += x509_certificate_model::GetSerialNumberHexified(cert, "");
  rv += ']';
  return rv;
}

// static
std::string SSLClientCertificateSelector::FormatDetailsText(
    net::X509Certificate::OSCertHandle cert) {
  std::string rv;

  rv += l10n_util::GetStringFUTF8(
      IDS_CERT_SUBJECTNAME_FORMAT,
      UTF8ToUTF16(x509_certificate_model::GetSubjectName(cert)));;

  rv += "\n  ";
  rv += l10n_util::GetStringFUTF8(
      IDS_CERT_SERIAL_NUMBER_FORMAT,
      UTF8ToUTF16(
          x509_certificate_model::GetSerialNumberHexified(cert, "")));

  base::Time issued, expires;
  if (x509_certificate_model::GetTimes(cert, &issued, &expires)) {
    string16 issued_str = WideToUTF16(
        base::TimeFormatShortDateAndTime(issued));
    string16 expires_str = WideToUTF16(
        base::TimeFormatShortDateAndTime(expires));
    rv += "\n  ";
    rv += l10n_util::GetStringFUTF8(IDS_CERT_VALIDITY_RANGE_FORMAT,
                                    issued_str, expires_str);
  }

  std::vector<std::string> usages;
  x509_certificate_model::GetUsageStrings(cert, &usages);
  if (usages.size()) {
    rv += "\n  ";
    rv += l10n_util::GetStringFUTF8(IDS_CERT_X509_EXTENDED_KEY_USAGE_FORMAT,
                                    UTF8ToUTF16(JoinString(usages, ',')));
  }

  std::string key_usage_str = x509_certificate_model::GetKeyUsageString(cert);
  if (!key_usage_str.empty()) {
    rv += "\n  ";
    rv += l10n_util::GetStringFUTF8(IDS_CERT_X509_KEY_USAGE_FORMAT,
                                    UTF8ToUTF16(key_usage_str));
  }

  std::vector<std::string> email_addresses;
  x509_certificate_model::GetEmailAddresses(cert, &email_addresses);
  if (email_addresses.size()) {
    rv += "\n  ";
    rv += l10n_util::GetStringFUTF8(
        IDS_CERT_EMAIL_ADDRESSES_FORMAT,
        UTF8ToUTF16(JoinString(email_addresses, ',')));
  }

  rv += '\n';
  rv += l10n_util::GetStringFUTF8(
      IDS_CERT_ISSUERNAME_FORMAT,
      UTF8ToUTF16(x509_certificate_model::GetIssuerName(cert)));

  string16 token(UTF8ToUTF16(x509_certificate_model::GetTokenName(cert)));
  if (!token.empty()) {
    rv += '\n';
    rv += l10n_util::GetStringFUTF8(IDS_CERT_TOKEN_FORMAT, token);
  }

  return rv;
}

void SSLClientCertificateSelector::OnComboBoxChanged(GtkWidget* combo_box) {
  int selected = gtk_combo_box_get_active(
      GTK_COMBO_BOX(cert_combo_box_));
  if (selected < 0)
    return;
  gtk_text_buffer_set_text(cert_details_buffer_,
                           details_strings_[selected].c_str(),
                           details_strings_[selected].size());
}

void SSLClientCertificateSelector::OnViewClicked(GtkWidget* button) {
  net::X509Certificate* cert = GetSelectedCert();
  if (cert) {
    GtkWidget* toplevel = gtk_widget_get_toplevel(root_widget_.get());
    ShowCertificateViewer(GTK_WINDOW(toplevel), cert);
  }
}

void SSLClientCertificateSelector::OnCancelClicked(GtkWidget* button) {
  delegate_->CertificateSelected(NULL);
  DCHECK(window_);
  window_->CloseConstrainedWindow();
}

void SSLClientCertificateSelector::OnOkClicked(GtkWidget* button) {
  net::X509Certificate* cert = GetSelectedCert();
  delegate_->CertificateSelected(cert);
  DCHECK(window_);
  window_->CloseConstrainedWindow();
}

void SSLClientCertificateSelector::OnPromptShown(GtkWidget* widget,
                                                 GtkWidget* previous_toplevel) {
  if (!root_widget_.get() ||
      !GTK_WIDGET_TOPLEVEL(gtk_widget_get_toplevel(root_widget_.get())))
    return;
  GTK_WIDGET_SET_FLAGS(select_button_, GTK_CAN_DEFAULT);
  gtk_widget_grab_default(select_button_);
  gtk_widget_grab_focus(select_button_);
}

}  // namespace

///////////////////////////////////////////////////////////////////////////////
// SSLClientAuthHandler platform specific implementation:

namespace browser {

void ShowSSLClientCertificateSelector(
    TabContents* parent,
    net::SSLCertRequestInfo* cert_request_info,
    SSLClientAuthHandler* delegate) {
  (new SSLClientCertificateSelector(parent,
                                    cert_request_info,
                                    delegate))->Show();
}

}  // namespace browser
<commit_msg>Linux: Fix client certificate selection dialog handling of esc key.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ssl_client_certificate_selector.h"

#include <gtk/gtk.h>

#include <string>
#include <vector>

#include "app/gtk_signal.h"
#include "app/l10n_util.h"
#include "base/i18n/time_formatting.h"
#include "base/logging.h"
#include "base/nss_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/certificate_viewer.h"
#include "chrome/browser/gtk/constrained_window_gtk.h"
#include "chrome/browser/gtk/gtk_util.h"
#include "chrome/browser/gtk/owned_widget_gtk.h"
#include "chrome/browser/ssl/ssl_client_auth_handler.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/net/x509_certificate_model.h"
#include "gfx/native_widget_types.h"
#include "grit/generated_resources.h"
#include "net/base/x509_certificate.h"

namespace {

enum {
  RESPONSE_SHOW_CERT_INFO = 1,
};

///////////////////////////////////////////////////////////////////////////////
// SSLClientCertificateSelector

class SSLClientCertificateSelector : public ConstrainedDialogDelegate {
 public:
  explicit SSLClientCertificateSelector(
      TabContents* parent,
      net::SSLCertRequestInfo* cert_request_info,
      SSLClientAuthHandler* delegate);
  ~SSLClientCertificateSelector();

  void Show();

  // ConstrainedDialogDelegate implementation:
  virtual GtkWidget* GetWidgetRoot() { return root_widget_.get(); }
  virtual void DeleteDelegate();

 private:
  void PopulateCerts();

  net::X509Certificate* GetSelectedCert();

  static std::string FormatComboBoxText(
      net::X509Certificate::OSCertHandle cert,
      const std::string& nickname);
  static std::string FormatDetailsText(
      net::X509Certificate::OSCertHandle cert);

  CHROMEGTK_CALLBACK_0(SSLClientCertificateSelector, void, OnComboBoxChanged);
  CHROMEGTK_CALLBACK_0(SSLClientCertificateSelector, void, OnViewClicked);
  CHROMEGTK_CALLBACK_0(SSLClientCertificateSelector, void, OnCancelClicked);
  CHROMEGTK_CALLBACK_0(SSLClientCertificateSelector, void, OnOkClicked);
  CHROMEGTK_CALLBACK_1(SSLClientCertificateSelector, void, OnPromptShown,
                       GtkWidget*);

  scoped_refptr<net::SSLCertRequestInfo> cert_request_info_;

  std::vector<std::string> details_strings_;

  GtkWidget* cert_combo_box_;
  GtkTextBuffer* cert_details_buffer_;

  scoped_refptr<SSLClientAuthHandler> delegate_;

  OwnedWidgetGtk root_widget_;
  // Hold on to the select button to focus it.
  GtkWidget* select_button_;

  TabContents* parent_;
  ConstrainedWindow* window_;

  DISALLOW_COPY_AND_ASSIGN(SSLClientCertificateSelector);
};

SSLClientCertificateSelector::SSLClientCertificateSelector(
    TabContents* parent,
    net::SSLCertRequestInfo* cert_request_info,
    SSLClientAuthHandler* delegate)
    : cert_request_info_(cert_request_info),
      delegate_(delegate),
      parent_(parent),
      window_(NULL) {
  root_widget_.Own(gtk_vbox_new(FALSE, gtk_util::kControlSpacing));

  GtkWidget* site_vbox = gtk_vbox_new(FALSE, gtk_util::kControlSpacing);
  gtk_box_pack_start(GTK_BOX(root_widget_.get()), site_vbox,
                     FALSE, FALSE, 0);

  GtkWidget* site_description_label = gtk_util::CreateBoldLabel(
      l10n_util::GetStringUTF8(IDS_CERT_SELECTOR_SITE_DESCRIPTION_LABEL));
  gtk_box_pack_start(GTK_BOX(site_vbox), site_description_label,
                     FALSE, FALSE, 0);

  GtkWidget* site_label = gtk_label_new(
      cert_request_info->host_and_port.c_str());
  gtk_util::LeftAlignMisc(site_label);
  gtk_box_pack_start(GTK_BOX(site_vbox), site_label, FALSE, FALSE, 0);

  GtkWidget* selector_vbox = gtk_vbox_new(FALSE, gtk_util::kControlSpacing);
  gtk_box_pack_start(GTK_BOX(root_widget_.get()), selector_vbox,
                     TRUE, TRUE, 0);

  GtkWidget* choose_description_label = gtk_util::CreateBoldLabel(
      l10n_util::GetStringUTF8(IDS_CERT_SELECTOR_CHOOSE_DESCRIPTION_LABEL));
  gtk_box_pack_start(GTK_BOX(selector_vbox), choose_description_label,
                     FALSE, FALSE, 0);

  cert_combo_box_ = gtk_combo_box_new_text();
  g_signal_connect(cert_combo_box_, "changed",
                   G_CALLBACK(OnComboBoxChangedThunk), this);
  gtk_box_pack_start(GTK_BOX(selector_vbox), cert_combo_box_,
                     FALSE, FALSE, 0);

  GtkWidget* details_label = gtk_label_new(l10n_util::GetStringUTF8(
      IDS_CERT_SELECTOR_DETAILS_DESCRIPTION_LABEL).c_str());
  gtk_util::LeftAlignMisc(details_label);
  gtk_box_pack_start(GTK_BOX(selector_vbox), details_label, FALSE, FALSE, 0);

  // TODO(mattm): fix text view coloring (should have grey background).
  GtkWidget* cert_details_view = gtk_text_view_new();
  gtk_text_view_set_editable(GTK_TEXT_VIEW(cert_details_view), FALSE);
  gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(cert_details_view), GTK_WRAP_WORD);
  cert_details_buffer_ = gtk_text_view_get_buffer(
      GTK_TEXT_VIEW(cert_details_view));
  // We put the details in a frame instead of a scrolled window so that the
  // entirety will be visible without requiring scrolling or expanding the
  // dialog.  This does however mean the dialog will grow itself if you switch
  // to different cert that has longer details text.
  GtkWidget* details_frame = gtk_frame_new(NULL);
  gtk_frame_set_shadow_type(GTK_FRAME(details_frame), GTK_SHADOW_ETCHED_IN);
  gtk_container_add(GTK_CONTAINER(details_frame), cert_details_view);
  gtk_box_pack_start(GTK_BOX(selector_vbox), details_frame, TRUE, TRUE, 0);

  // And then create a set of buttons like a GtkDialog would.
  GtkWidget* button_box = gtk_hbutton_box_new();
  gtk_button_box_set_layout(GTK_BUTTON_BOX(button_box), GTK_BUTTONBOX_END);
  gtk_box_set_spacing(GTK_BOX(button_box), gtk_util::kControlSpacing);
  gtk_box_pack_end(GTK_BOX(root_widget_.get()), button_box, FALSE, FALSE, 0);

  GtkWidget* view_button = gtk_button_new_with_mnemonic(
      l10n_util::GetStringUTF8(IDS_PAGEINFO_CERT_INFO_BUTTON).c_str());
  gtk_box_pack_start(GTK_BOX(button_box), view_button, FALSE, FALSE, 0);
  g_signal_connect(view_button, "clicked",
                   G_CALLBACK(OnViewClickedThunk), this);

  GtkWidget* cancel_button = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
  gtk_box_pack_end(GTK_BOX(button_box), cancel_button, FALSE, FALSE, 0);
  g_signal_connect(cancel_button, "clicked",
                   G_CALLBACK(OnCancelClickedThunk), this);

  GtkWidget* select_button = gtk_button_new_from_stock(GTK_STOCK_OK);
  gtk_box_pack_end(GTK_BOX(button_box), select_button, FALSE, FALSE, 0);
  g_signal_connect(select_button, "clicked",
                   G_CALLBACK(OnOkClickedThunk), this);

  // When we are attached to a window, focus the select button.
  select_button_ = select_button;
  g_signal_connect(root_widget_.get(), "hierarchy-changed",
                   G_CALLBACK(OnPromptShownThunk), this);
  PopulateCerts();

  gtk_widget_show_all(root_widget_.get());
}

SSLClientCertificateSelector::~SSLClientCertificateSelector() {
  root_widget_.Destroy();
}

void SSLClientCertificateSelector::Show() {
  DCHECK(!window_);
  window_ = parent_->CreateConstrainedDialog(this);
}

void SSLClientCertificateSelector::DeleteDelegate() {
  if (delegate_) {
    // The dialog was closed by escape key.
    delegate_->CertificateSelected(NULL);
  }
  delete this;
}

void SSLClientCertificateSelector::PopulateCerts() {
  std::vector<std::string> nicknames;
  x509_certificate_model::GetNicknameStringsFromCertList(
      cert_request_info_->client_certs,
      l10n_util::GetStringUTF8(IDS_CERT_SELECTOR_CERT_EXPIRED),
      l10n_util::GetStringUTF8(IDS_CERT_SELECTOR_CERT_NOT_YET_VALID),
      &nicknames);

  DCHECK_EQ(nicknames.size(),
            cert_request_info_->client_certs.size());

  for (size_t i = 0; i < cert_request_info_->client_certs.size(); ++i) {
    net::X509Certificate::OSCertHandle cert =
        cert_request_info_->client_certs[i]->os_cert_handle();

    details_strings_.push_back(FormatDetailsText(cert));

    gtk_combo_box_append_text(
        GTK_COMBO_BOX(cert_combo_box_),
        FormatComboBoxText(cert, nicknames[i]).c_str());
  }

  // Auto-select the first cert.
  gtk_combo_box_set_active(GTK_COMBO_BOX(cert_combo_box_), 0);
}

net::X509Certificate* SSLClientCertificateSelector::GetSelectedCert() {
  int selected = gtk_combo_box_get_active(GTK_COMBO_BOX(cert_combo_box_));
  if (selected >= 0 &&
      selected < static_cast<int>(
          cert_request_info_->client_certs.size()))
    return cert_request_info_->client_certs[selected];
  return NULL;
}

// static
std::string SSLClientCertificateSelector::FormatComboBoxText(
    net::X509Certificate::OSCertHandle cert, const std::string& nickname) {
  std::string rv(nickname);
  rv += " [";
  rv += x509_certificate_model::GetSerialNumberHexified(cert, "");
  rv += ']';
  return rv;
}

// static
std::string SSLClientCertificateSelector::FormatDetailsText(
    net::X509Certificate::OSCertHandle cert) {
  std::string rv;

  rv += l10n_util::GetStringFUTF8(
      IDS_CERT_SUBJECTNAME_FORMAT,
      UTF8ToUTF16(x509_certificate_model::GetSubjectName(cert)));;

  rv += "\n  ";
  rv += l10n_util::GetStringFUTF8(
      IDS_CERT_SERIAL_NUMBER_FORMAT,
      UTF8ToUTF16(
          x509_certificate_model::GetSerialNumberHexified(cert, "")));

  base::Time issued, expires;
  if (x509_certificate_model::GetTimes(cert, &issued, &expires)) {
    string16 issued_str = WideToUTF16(
        base::TimeFormatShortDateAndTime(issued));
    string16 expires_str = WideToUTF16(
        base::TimeFormatShortDateAndTime(expires));
    rv += "\n  ";
    rv += l10n_util::GetStringFUTF8(IDS_CERT_VALIDITY_RANGE_FORMAT,
                                    issued_str, expires_str);
  }

  std::vector<std::string> usages;
  x509_certificate_model::GetUsageStrings(cert, &usages);
  if (usages.size()) {
    rv += "\n  ";
    rv += l10n_util::GetStringFUTF8(IDS_CERT_X509_EXTENDED_KEY_USAGE_FORMAT,
                                    UTF8ToUTF16(JoinString(usages, ',')));
  }

  std::string key_usage_str = x509_certificate_model::GetKeyUsageString(cert);
  if (!key_usage_str.empty()) {
    rv += "\n  ";
    rv += l10n_util::GetStringFUTF8(IDS_CERT_X509_KEY_USAGE_FORMAT,
                                    UTF8ToUTF16(key_usage_str));
  }

  std::vector<std::string> email_addresses;
  x509_certificate_model::GetEmailAddresses(cert, &email_addresses);
  if (email_addresses.size()) {
    rv += "\n  ";
    rv += l10n_util::GetStringFUTF8(
        IDS_CERT_EMAIL_ADDRESSES_FORMAT,
        UTF8ToUTF16(JoinString(email_addresses, ',')));
  }

  rv += '\n';
  rv += l10n_util::GetStringFUTF8(
      IDS_CERT_ISSUERNAME_FORMAT,
      UTF8ToUTF16(x509_certificate_model::GetIssuerName(cert)));

  string16 token(UTF8ToUTF16(x509_certificate_model::GetTokenName(cert)));
  if (!token.empty()) {
    rv += '\n';
    rv += l10n_util::GetStringFUTF8(IDS_CERT_TOKEN_FORMAT, token);
  }

  return rv;
}

void SSLClientCertificateSelector::OnComboBoxChanged(GtkWidget* combo_box) {
  int selected = gtk_combo_box_get_active(
      GTK_COMBO_BOX(cert_combo_box_));
  if (selected < 0)
    return;
  gtk_text_buffer_set_text(cert_details_buffer_,
                           details_strings_[selected].c_str(),
                           details_strings_[selected].size());
}

void SSLClientCertificateSelector::OnViewClicked(GtkWidget* button) {
  net::X509Certificate* cert = GetSelectedCert();
  if (cert) {
    GtkWidget* toplevel = gtk_widget_get_toplevel(root_widget_.get());
    ShowCertificateViewer(GTK_WINDOW(toplevel), cert);
  }
}

void SSLClientCertificateSelector::OnCancelClicked(GtkWidget* button) {
  delegate_->CertificateSelected(NULL);
  delegate_ = NULL;
  DCHECK(window_);
  window_->CloseConstrainedWindow();
}

void SSLClientCertificateSelector::OnOkClicked(GtkWidget* button) {
  net::X509Certificate* cert = GetSelectedCert();
  delegate_->CertificateSelected(cert);
  delegate_ = NULL;
  DCHECK(window_);
  window_->CloseConstrainedWindow();
}

void SSLClientCertificateSelector::OnPromptShown(GtkWidget* widget,
                                                 GtkWidget* previous_toplevel) {
  if (!root_widget_.get() ||
      !GTK_WIDGET_TOPLEVEL(gtk_widget_get_toplevel(root_widget_.get())))
    return;
  GTK_WIDGET_SET_FLAGS(select_button_, GTK_CAN_DEFAULT);
  gtk_widget_grab_default(select_button_);
  gtk_widget_grab_focus(select_button_);
}

}  // namespace

///////////////////////////////////////////////////////////////////////////////
// SSLClientAuthHandler platform specific implementation:

namespace browser {

void ShowSSLClientCertificateSelector(
    TabContents* parent,
    net::SSLCertRequestInfo* cert_request_info,
    SSLClientAuthHandler* delegate) {
  (new SSLClientCertificateSelector(parent,
                                    cert_request_info,
                                    delegate))->Show();
}

}  // namespace browser
<|endoftext|>


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

#include "chrome/browser/metrics/proto/study.pb.h"
#include "chrome/browser/metrics/variations_service.h"
#include "chrome/common/chrome_version_info.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

// Converts |time| to chrome_variations::Study proto format.
int64 TimeToProtoTime(const base::Time& time) {
  return (time - base::Time::UnixEpoch()).InSeconds();
}

}  // namespace

TEST(VariationsServiceTest, CheckStudyChannel) {
  const chrome::VersionInfo::Channel channels[] = {
    chrome::VersionInfo::CHANNEL_CANARY,
    chrome::VersionInfo::CHANNEL_DEV,
    chrome::VersionInfo::CHANNEL_BETA,
    chrome::VersionInfo::CHANNEL_STABLE,
  };
  const chrome_variations::Study_Channel study_channels[] = {
    chrome_variations::Study_Channel_CANARY,
    chrome_variations::Study_Channel_DEV,
    chrome_variations::Study_Channel_BETA,
    chrome_variations::Study_Channel_STABLE,
  };
  ASSERT_EQ(arraysize(channels), arraysize(study_channels));
  bool channel_added[arraysize(channels)] = { 0 };

  chrome_variations::Study study;

  // Check in the forwarded order. The loop cond is <= arraysize(study_channels)
  // instead of < so that the result of adding the last channel gets checked.
  for (size_t i = 0; i <= arraysize(study_channels); ++i) {
    for (size_t j = 0; j < arraysize(channels); ++j) {
      const bool expected = channel_added[j] || study.channel_size() == 0;
      const bool result = VariationsService::CheckStudyChannel(study,
                                                               channels[j]);
      EXPECT_EQ(expected, result) << "Case " << i << "," << j << " failed!";
    }

    if (i < arraysize(study_channels))
    {
      study.add_channel(study_channels[i]);
      channel_added[i] = true;
    }
  }

  // Do the same check in the reverse order.
  study.clear_channel();
  memset(&channel_added, 0, sizeof(channel_added));
  for (size_t i = 0; i <= arraysize(study_channels); ++i) {
    for (size_t j = 0; j < arraysize(channels); ++j) {
      const bool expected = channel_added[j] || study.channel_size() == 0;
      const bool result = VariationsService::CheckStudyChannel(study,
                                                               channels[j]);
      EXPECT_EQ(expected, result) << "Case " << i << "," << j << " failed!";
    }

    if (i < arraysize(study_channels))
    {
      const int index = arraysize(study_channels) - i - 1;
      study.add_channel(study_channels[index]);
      channel_added[index] = true;
    }
  }
}

TEST(VariationsServiceTest, CheckStudyVersion) {
  const struct {
    const char* min_version;
    const char* version;
    bool expected_result;
  } min_test_cases[] = {
    { "1.2.2", "1.2.3", true },
    { "1.2.3", "1.2.3", true },
    { "1.2.4", "1.2.3", false },
    { "1.3.2", "1.2.3", false },
    { "2.1.2", "1.2.3", false },
    { "0.3.4", "1.2.3", true },
  };

  const struct {
    const char* max_version;
    const char* version;
    bool expected_result;
  } max_test_cases[] = {
    { "1.2.2", "1.2.3", false },
    { "1.2.3", "1.2.3", true },
    { "1.2.4", "1.2.3", true },
    { "2.1.1", "1.2.3", true },
    { "2.1.1", "2.3.4", false },
  };

  chrome_variations::Study study;

  // Min/max version not set should result in true.
  EXPECT_TRUE(VariationsService::CheckStudyVersion(study, "1.2.3"));

  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(min_test_cases); ++i) {
    study.set_min_version(min_test_cases[i].min_version);
    const bool result =
        VariationsService::CheckStudyVersion(study, min_test_cases[i].version);
    EXPECT_EQ(min_test_cases[i].expected_result, result) <<
        "Case " << i << " failed!";
  }
  study.clear_min_version();

  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(max_test_cases); ++i) {
    study.set_max_version(max_test_cases[i].max_version);
    const bool result =
        VariationsService::CheckStudyVersion(study, max_test_cases[i].version);
    EXPECT_EQ(max_test_cases[i].expected_result, result) <<
        "Case " << i << " failed!";
  }

  // Check intersection semantics.
  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(min_test_cases); ++i) {
    for (size_t j = 0; j < ARRAYSIZE_UNSAFE(max_test_cases); ++j) {
      study.set_min_version(min_test_cases[i].min_version);
      study.set_max_version(max_test_cases[j].max_version);

      if (!min_test_cases[i].expected_result) {
        const bool result =
            VariationsService::CheckStudyVersion(study,
                                                 min_test_cases[i].version);
        EXPECT_FALSE(result) << "Case " << i << "," << j << " failed!";
      }

      if (!max_test_cases[j].expected_result) {
        const bool result =
            VariationsService::CheckStudyVersion(study,
                                                 max_test_cases[j].version);
        EXPECT_FALSE(result) << "Case " << i << "," << j << " failed!";
      }
    }
  }
}

// The current client logic does not handle version number strings containing
// wildcards. Check that any such values received from the server result in the
// study being disqualified.
TEST(VariationsServiceTest, CheckStudyVersionWildcards) {
  chrome_variations::Study study;

  study.set_min_version("1.0.*");
  EXPECT_FALSE(VariationsService::CheckStudyVersion(study, "1.2.3"));

  study.clear_min_version();
  study.set_max_version("2.0.*");
  EXPECT_FALSE(VariationsService::CheckStudyVersion(study, "1.2.3"));
}

TEST(VariationsServiceTest, CheckStudyDate) {
  const base::Time now = base::Time::Now();
  const base::TimeDelta delta = base::TimeDelta::FromHours(1);
  const struct {
    const base::Time start_date;
    bool expected_result;
  } start_test_cases[] = {
    { now - delta, true },
    { now, true },
    { now + delta, false },
  };
  const struct {
    const base::Time expiry_date;
    bool expected_result;
  } expiry_test_cases[] = {
    { now - delta, false },
    { now, false },
    { now + delta, true },
  };

  chrome_variations::Study study;

  // Start/expiry date not set should result in true.
  EXPECT_TRUE(VariationsService::CheckStudyDate(study, now));

  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(start_test_cases); ++i) {
    study.set_start_date(TimeToProtoTime(start_test_cases[i].start_date));
    const bool result = VariationsService::CheckStudyDate(study, now);
    EXPECT_EQ(start_test_cases[i].expected_result, result)
        << "Case " << i << " failed!";
  }
  study.clear_start_date();

  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(expiry_test_cases); ++i) {
    study.set_expiry_date(TimeToProtoTime(expiry_test_cases[i].expiry_date));
    const bool result = VariationsService::CheckStudyDate(study, now);
    EXPECT_EQ(expiry_test_cases[i].expected_result, result)
        << "Case " << i << " failed!";
  }

  // Check intersection semantics.
  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(start_test_cases); ++i) {
    for (size_t j = 0; j < ARRAYSIZE_UNSAFE(expiry_test_cases); ++j) {
      study.set_start_date(TimeToProtoTime(start_test_cases[i].start_date));
      study.set_expiry_date(TimeToProtoTime(expiry_test_cases[j].expiry_date));
      const bool expected = start_test_cases[i].expected_result &&
                            expiry_test_cases[j].expected_result;
      const bool result = VariationsService::CheckStudyDate(study, now);
      EXPECT_EQ(expected, result) << "Case " << i << "," << j << " failed!";
    }
  }
}
<commit_msg>revert 135858: This depends on the previous revet<commit_after><|endoftext|>