<commit_before>/***********************************************************************
 ssx/genv2.cpp - Walks the SSQLS v2 parse result, writing back out
 	the equivalent SSQLS v2 DSL code.  This is useful for testing that
	our parser has correctly understood a given piece of code.  It is
	also something like the preprocessor mode of a C++ compiler,
	emitting a digested version of its input.

 Copyright (c) 2009 by Warren Young and (c) 2009-2010 by Educational
 Technology Resources, Inc.  Others may also hold copyrights on code
 in this file.  See the CREDITS.txt file in the top directory of the
 distribution for details.

 This file is part of MySQL++.

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

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

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "genv2.h"

#include "parsev2.h"

#include <iostream>
#include <fstream>
#include <typeinfo>

using namespace std;

//// generate_ssqls2 ///////////////////////////////////////////////////
// 2 versions: second checks its arguments and opens the named file,
// calling the second to actually generate the SSQLS v2 output from
// the parse result only if we were given sane parameters.

static bool
generate_ssqls2(ostream& os, const ParseV2* pparse)
{
	ParseV2::LineListIt it;
	for (it = pparse->begin(); it != pparse->end(); ++it) {
		os << **it << endl;
	}

	return true;
}

bool
generate_ssqls2(const char* file_name, const ParseV2* pparse)
{
	if (pparse) {
		if (strcmp(file_name, "-") == 0) {
			return generate_ssqls2(cout, pparse);
		}
		else {
			ofstream ofs(file_name);
			if (ofs) {
				cout << "TRACE: Generating SSQLS v2 file " << file_name <<
						" from " << (pparse->end() - pparse->begin()) <<
						" line parse result." << endl;
				return generate_ssqls2(ofs, pparse);
			}
			else {
				cerr << "Failed to open " << file_name << \
						" for writing for -o!" << endl;
				return false;
			}
		}
	}
	else {
		cerr << "No parse result given to -o handler!" << endl;
		return false;
	}
}
<commit_msg>ssqlsxlat -o now puts tabs before "field" directive so its output is legal -i input.<commit_after>/***********************************************************************
 ssx/genv2.cpp - Walks the SSQLS v2 parse result, writing back out
 	the equivalent SSQLS v2 DSL code.  This is useful for testing that
	our parser has correctly understood a given piece of code.  It is
	also something like the preprocessor mode of a C++ compiler,
	emitting a digested version of its input.

 Copyright (c) 2009 by Warren Young and (c) 2009-2010 by Educational
 Technology Resources, Inc.  Others may also hold copyrights on code
 in this file.  See the CREDITS.txt file in the top directory of the
 distribution for details.

 This file is part of MySQL++.

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

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

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "genv2.h"

#include "parsev2.h"

#include <iostream>
#include <fstream>
#include <typeinfo>

using namespace std;

//// generate_ssqls2 ///////////////////////////////////////////////////
// 2 versions: second checks its arguments and opens the named file,
// calling the second to actually generate the SSQLS v2 output from
// the parse result only if we were given sane parameters.

static bool
generate_ssqls2(ostream& os, const ParseV2* pparse)
{
	ParseV2::LineListIt it;
	for (it = pparse->begin(); it != pparse->end(); ++it) {
		if (dynamic_cast<ParseV2::Field*>(*it)) {
			// 'field' directives must be indented under the preceding
			// 'table'.  We don't want to hard-code this in
			// ParseV2::Field::print() in case we later start calling
			// those routines for other reasons, such as to construct
			// error messages.  It's really a special case of -o, not
			// really something that print() routine should know.
			os << '\t';
		}
		os << **it << endl;
	}

	return true;
}

bool
generate_ssqls2(const char* file_name, const ParseV2* pparse)
{
	if (pparse) {
		if (strcmp(file_name, "-") == 0) {
			return generate_ssqls2(cout, pparse);
		}
		else {
			ofstream ofs(file_name);
			if (ofs) {
				cout << "TRACE: Generating SSQLS v2 file " << file_name <<
						" from " << (pparse->end() - pparse->begin()) <<
						" line parse result." << endl;
				return generate_ssqls2(ofs, pparse);
			}
			else {
				cerr << "Failed to open " << file_name << \
						" for writing for -o!" << endl;
				return false;
			}
		}
	}
	else {
		cerr << "No parse result given to -o handler!" << endl;
		return false;
	}
}
<|endoftext|>


<commit_before>#include "openglwindow.h"
#include <QThread>

#include <iostream>

OpenGLWidget::OpenGLWidget(Scene *scene, QWidget *parent)
    : QOpenGLWidget(parent)
{
    m_scene = scene;
}

OpenGLWidget::~OpenGLWidget()
{

}

void OpenGLWidget::mousePressEvent(QMouseEvent *event)
{
    m_mousePressPosition = glm::vec2(event->localPos().x(),
                                     event->localPos().y());
    m_mouseButtons = event->buttons();
    m_mouseLastTime.start();
}

void OpenGLWidget::mouseMoveEvent(QMouseEvent *event)
{
    if (m_mouseButtons == Qt::NoButton) {
        event->ignore();
        return;
    }
    float time_delta = m_mouseLastTime.elapsed();
    if (time_delta < 25) {
        event->ignore();
        return;
    }

    time_delta /= 100;
    glm::vec2 cur = glm::vec2(event->localPos().x(),
                                     event->localPos().y());
    glm::vec2 last = m_mousePressPosition;

    m_mouseLastTime.start();
    m_mousePressPosition = cur;

    glm::vec2 delta = (cur - last) * time_delta;

    if (m_mouseButtons & Qt::LeftButton &&
            event->modifiers() & Qt::AltModifier &&
            event->modifiers() & Qt::ControlModifier) {
        m_scene->camera->pan(delta);
        update();

    } else if (m_mouseButtons & Qt::LeftButton &&
               event->modifiers() & Qt::AltModifier) {
         m_scene->camera->rotate(delta);
        update();

    } else if (m_mouseButtons & Qt::RightButton &&
               event->modifiers() & Qt::AltModifier) {
        m_scene->camera->dolly(delta);
        update();
    }
    event->accept();

}

void OpenGLWidget::mouseReleaseEvent(QMouseEvent *event)
{
    m_mouseButtons = Qt::NoButton;
}

void OpenGLWidget::set_imageplane_data(const FloatImage &data, int width, int height, int frame)
{
    makeCurrent();
    m_scene->set_imageplane_data(data, width, height, frame);
    doneCurrent();
    update();
    QSize s = size();
    s.setWidth(s.width() + 1);
    resize(s);
    s.setWidth(s.width() - 1);
    resize(s);
}

void OpenGLWidget::update_mesh()
{
    makeCurrent();
    m_scene->update();
    doneCurrent();
    update();
}

void OpenGLWidget::open_scene_file(QString path)
{
    makeCurrent();
    m_scene->open(path.toStdString());

    QSize s = size();
    m_scene->camera->setViewportSize(glm::vec2(s.width(),s.height()));
    doneCurrent();

    emit scene_loaded(path);
    emit frame_range_changed(m_scene->first(), m_scene->last());
    update();
}

void OpenGLWidget::set_template_texture(const FloatImage &data, int width, int height)
{
    makeCurrent();
    m_scene->set_template_texture(data, width, height);
    doneCurrent();
    QSize s = size();
    s.setWidth(s.width() + 1);
    resize(s);
    s.setWidth(s.width() - 1);
    resize(s);
}

void OpenGLWidget::render_template_data(FloatImageData &color_data,
                                        FloatImageData &alpha_data,
                                        FloatImageData &contour_data,
                                        int frame)
{
    makeCurrent();
    m_scene->render_template_data(color_data, alpha_data, contour_data, frame);
    doneCurrent();
}

void OpenGLWidget::clear()
{
    m_scene->clear();
    emit scene_loaded("");
    update();

    force_update();
}

void OpenGLWidget::force_update()
{
    update();

    QSize s = size();
    s.setWidth(s.width() + 1);
    resize(s);
    s.setWidth(s.width() - 1);
    resize(s);
}

void OpenGLWidget::initializeGL()
{
    glew_initialize();

    std::cerr << "using OpenGL " << format().majorVersion() << "." << format().minorVersion() << "\n";
    m_scene->create();
    //m_scene->update();

    emit opengl_initialized();
    emit scene_loaded("");
}

void OpenGLWidget::resizeGL(int w, int h)
{
    m_scene->camera->setViewportSize(glm::vec2(w,h));
    glViewport(0, 0, w, h);
}

void OpenGLWidget::paintGL()
{

    m_scene->draw(defaultFramebufferObject());

}
<commit_msg>added maya middle click behaviour<commit_after>#include "openglwindow.h"
#include <QThread>

#include <iostream>

OpenGLWidget::OpenGLWidget(Scene *scene, QWidget *parent)
    : QOpenGLWidget(parent)
{
    m_scene = scene;
}

OpenGLWidget::~OpenGLWidget()
{

}

void OpenGLWidget::mousePressEvent(QMouseEvent *event)
{
    m_mousePressPosition = glm::vec2(event->localPos().x(),
                                     event->localPos().y());
    m_mouseButtons = event->buttons();
    m_mouseLastTime.start();
}

void OpenGLWidget::mouseMoveEvent(QMouseEvent *event)
{
    if (m_mouseButtons == Qt::NoButton) {
        event->ignore();
        return;
    }
    float time_delta = m_mouseLastTime.elapsed();
    if (time_delta < 25) {
        event->ignore();
        return;
    }

    time_delta /= 100;
    glm::vec2 cur = glm::vec2(event->localPos().x(),
                                     event->localPos().y());
    glm::vec2 last = m_mousePressPosition;

    m_mouseLastTime.start();
    m_mousePressPosition = cur;

    glm::vec2 delta = (cur - last) * time_delta;

    if ((m_mouseButtons & Qt::RightButton &&
         event->modifiers() & Qt::AltModifier) ||
        (m_mouseButtons & Qt::LeftButton &&
         m_mouseButtons & Qt::MiddleButton &&
         event->modifiers() & Qt::AltModifier)) {

        m_scene->camera->dolly(delta);
        update();

    } else if ((m_mouseButtons & Qt::LeftButton &&
         event->modifiers() & Qt::AltModifier &&
         event->modifiers() & Qt::ControlModifier) ||
        (m_mouseButtons & Qt::MiddleButton && Qt::AltModifier)){

        m_scene->camera->pan(delta);
        update();

    } else if (m_mouseButtons & Qt::LeftButton &&
               event->modifiers() & Qt::AltModifier) {
         m_scene->camera->rotate(delta);
        update();

    }

    event->accept();

}

void OpenGLWidget::mouseReleaseEvent(QMouseEvent *event)
{
    m_mouseButtons = Qt::NoButton;
}

void OpenGLWidget::set_imageplane_data(const FloatImage &data, int width, int height, int frame)
{
    makeCurrent();
    m_scene->set_imageplane_data(data, width, height, frame);
    doneCurrent();
    update();
    QSize s = size();
    s.setWidth(s.width() + 1);
    resize(s);
    s.setWidth(s.width() - 1);
    resize(s);
}

void OpenGLWidget::update_mesh()
{
    makeCurrent();
    m_scene->update();
    doneCurrent();
    update();
}

void OpenGLWidget::open_scene_file(QString path)
{
    makeCurrent();
    m_scene->open(path.toStdString());

    QSize s = size();
    m_scene->camera->setViewportSize(glm::vec2(s.width(),s.height()));
    doneCurrent();

    emit scene_loaded(path);
    emit frame_range_changed(m_scene->first(), m_scene->last());
    update();
}

void OpenGLWidget::set_template_texture(const FloatImage &data, int width, int height)
{
    makeCurrent();
    m_scene->set_template_texture(data, width, height);
    doneCurrent();
    QSize s = size();
    s.setWidth(s.width() + 1);
    resize(s);
    s.setWidth(s.width() - 1);
    resize(s);
}

void OpenGLWidget::render_template_data(FloatImageData &color_data,
                                        FloatImageData &alpha_data,
                                        FloatImageData &contour_data,
                                        int frame)
{
    makeCurrent();
    m_scene->render_template_data(color_data, alpha_data, contour_data, frame);
    doneCurrent();
}

void OpenGLWidget::clear()
{
    m_scene->clear();
    emit scene_loaded("");
    update();

    force_update();
}

void OpenGLWidget::force_update()
{
    update();

    QSize s = size();
    s.setWidth(s.width() + 1);
    resize(s);
    s.setWidth(s.width() - 1);
    resize(s);
}

void OpenGLWidget::initializeGL()
{
    glew_initialize();

    std::cerr << "using OpenGL " << format().majorVersion() << "." << format().minorVersion() << "\n";
    m_scene->create();
    //m_scene->update();

    emit opengl_initialized();
    emit scene_loaded("");
}

void OpenGLWidget::resizeGL(int w, int h)
{
    m_scene->camera->setViewportSize(glm::vec2(w,h));
    glViewport(0, 0, w, h);
}

void OpenGLWidget::paintGL()
{

    m_scene->draw(defaultFramebufferObject());

}
<|endoftext|>


<commit_before><commit_msg>fix animation for GL3D chart<commit_after><|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 "base/bind.h"
#include "base/file_util.h"
#include "base/scoped_temp_dir.h"
#include "chrome/browser/character_encoding.h"
#include "chrome/browser/net/url_request_mock_util.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/web_contents.h"
#include "content/test/net/url_request_mock_http_job.h"
#include "content/test/test_navigation_observer.h"

using content::BrowserThread;

static const FilePath::CharType* kTestDir = FILE_PATH_LITERAL("encoding_tests");

class BrowserEncodingTest : public InProcessBrowserTest {
 protected:
  BrowserEncodingTest() {}

  // Saves the current page and verifies that the output matches the expected
  // result.
  void SaveAndCompare(const char* filename_to_write, const FilePath& expected) {
    // Dump the page, the content of dump page should be identical to the
    // expected result file.
    FilePath full_file_name = save_dir_.AppendASCII(filename_to_write);
    // We save the page as way of complete HTML file, which requires a directory
    // name to save sub resources in it. Although this test file does not have
    // sub resources, but the directory name is still required.
    ui_test_utils::WindowedNotificationObserver observer(
        content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED,
        content::NotificationService::AllSources());
    browser()->GetSelectedWebContents()->SavePage(
        full_file_name, temp_sub_resource_dir_,
        content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML);
    observer.Wait();

    FilePath expected_file_name = ui_test_utils::GetTestFilePath(
        FilePath(kTestDir), expected);

    EXPECT_TRUE(file_util::ContentsEqual(full_file_name, expected_file_name));
  }

  void SetUpOnMainThread() OVERRIDE {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    save_dir_ = temp_dir_.path();
    temp_sub_resource_dir_ = save_dir_.AppendASCII("sub_resource_files");

    BrowserThread::PostTask(
        BrowserThread::IO, FROM_HERE,
        base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true));
  }

  ScopedTempDir temp_dir_;
  FilePath save_dir_;
  FilePath temp_sub_resource_dir_;
};

// TODO(jnd): 1. Some encodings are missing here. It'll be added later. See
// http://crbug.com/13306.
// 2. Add more files with multiple encoding name variants for each canonical
// encoding name). Webkit layout tests cover some, but testing in the UI test is
// also necessary.

// This test fails frequently on the win_rel trybot. See http://crbug.com/122053
#if defined(OS_WIN)
#define MAYBE_TestEncodingAliasMapping DISABLED_TestEncodingAliasMapping
#else
#define MAYBE_TestEncodingAliasMapping TestEncodingAliasMapping
#endif
IN_PROC_BROWSER_TEST_F(BrowserEncodingTest, MAYBE_TestEncodingAliasMapping) {
  struct EncodingTestData {
    const char* file_name;
    const char* encoding_name;
  };

  const EncodingTestData kEncodingTestDatas[] = {
    { "Big5.html", "Big5" },
    { "EUC-JP.html", "EUC-JP" },
    { "gb18030.html", "gb18030" },
    { "iso-8859-1.html", "ISO-8859-1" },
    { "ISO-8859-2.html", "ISO-8859-2" },
    { "ISO-8859-4.html", "ISO-8859-4" },
    { "ISO-8859-5.html", "ISO-8859-5" },
    { "ISO-8859-6.html", "ISO-8859-6" },
    { "ISO-8859-7.html", "ISO-8859-7" },
    { "ISO-8859-8.html", "ISO-8859-8" },
    { "ISO-8859-13.html", "ISO-8859-13" },
    { "ISO-8859-15.html", "ISO-8859-15" },
    { "KOI8-R.html", "KOI8-R" },
    { "KOI8-U.html", "KOI8-U" },
    { "macintosh.html", "macintosh" },
    { "Shift-JIS.html", "Shift_JIS" },
    { "US-ASCII.html", "ISO-8859-1" },  // http://crbug.com/15801
    { "UTF-8.html", "UTF-8" },
    { "UTF-16LE.html", "UTF-16LE" },
    { "windows-874.html", "windows-874" },
    // http://crbug.com/95963
    // { "windows-949.html", "windows-949" },
    { "windows-1250.html", "windows-1250" },
    { "windows-1251.html", "windows-1251" },
    { "windows-1252.html", "windows-1252" },
    { "windows-1253.html", "windows-1253" },
    { "windows-1254.html", "windows-1254" },
    { "windows-1255.html", "windows-1255" },
    { "windows-1256.html", "windows-1256" },
    { "windows-1257.html", "windows-1257" },
    { "windows-1258.html", "windows-1258" }
  };
  const char* const kAliasTestDir = "alias_mapping";

  FilePath test_dir_path = FilePath(kTestDir).AppendASCII(kAliasTestDir);
  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kEncodingTestDatas); ++i) {
    FilePath test_file_path(test_dir_path);
    test_file_path = test_file_path.AppendASCII(
        kEncodingTestDatas[i].file_name);

    GURL url = URLRequestMockHTTPJob::GetMockUrl(test_file_path);
    ui_test_utils::NavigateToURL(browser(), url);

    EXPECT_EQ(kEncodingTestDatas[i].encoding_name,
              browser()->GetSelectedWebContents()->GetEncoding());
  }
}

// Marked as flaky: see  http://crbug.com/44668
IN_PROC_BROWSER_TEST_F(BrowserEncodingTest, TestOverrideEncoding) {
  const char* const kTestFileName = "gb18030_with_iso88591_meta.html";
  const char* const kExpectedFileName =
      "expected_gb18030_saved_from_iso88591_meta.html";
  const char* const kOverrideTestDir = "user_override";

  FilePath test_dir_path = FilePath(kTestDir).AppendASCII(kOverrideTestDir);
  test_dir_path = test_dir_path.AppendASCII(kTestFileName);
  GURL url = URLRequestMockHTTPJob::GetMockUrl(test_dir_path);
  ui_test_utils::NavigateToURL(browser(), url);
  content::WebContents* web_contents = browser()->GetSelectedWebContents();
  EXPECT_EQ("ISO-8859-1", web_contents->GetEncoding());

  // Override the encoding to "gb18030".
  const std::string selected_encoding =
      CharacterEncoding::GetCanonicalEncodingNameByAliasName("gb18030");
  TestNavigationObserver navigation_observer(
      content::Source<content::NavigationController>(
          &web_contents->GetController()));
  web_contents->SetOverrideEncoding(selected_encoding);
  navigation_observer.Wait();
  EXPECT_EQ("gb18030", web_contents->GetEncoding());

  FilePath expected_filename =
      FilePath().AppendASCII(kOverrideTestDir).AppendASCII(kExpectedFileName);
  SaveAndCompare(kTestFileName, expected_filename);
}

// The following encodings are excluded from the auto-detection test because
// it's a known issue that the current encoding detector does not detect them:
// ISO-8859-4
// ISO-8859-13
// KOI8-U
// macintosh
// windows-874
// windows-1252
// windows-1253
// windows-1257
// windows-1258

// For Hebrew, the expected encoding value is ISO-8859-8-I. See
// http://crbug.com/2927 for more details.
//
// This test fails frequently on the win_rel trybot. See http://crbug.com/122053
#if defined(OS_WIN)
#define MAYBE_TestEncodingAutoDetect DISABLED_TestEncodingAutoDetect
#else
#define MAYBE_TestEncodingAutoDetect TestEncodingAutoDetect
#endif
IN_PROC_BROWSER_TEST_F(BrowserEncodingTest, MAYBE_TestEncodingAutoDetect) {
  struct EncodingAutoDetectTestData {
    const char* test_file_name;   // File name of test data.
    const char* expected_result;  // File name of expected results.
    const char* expected_encoding;   // expected encoding.
  };
  const EncodingAutoDetectTestData kTestDatas[] = {
      { "Big5_with_no_encoding_specified.html",
        "expected_Big5_saved_from_no_encoding_specified.html",
        "Big5" },
      { "gb18030_with_no_encoding_specified.html",
        "expected_gb18030_saved_from_no_encoding_specified.html",
        "gb18030" },
      { "iso-8859-1_with_no_encoding_specified.html",
        "expected_iso-8859-1_saved_from_no_encoding_specified.html",
        "ISO-8859-1" },
      { "ISO-8859-5_with_no_encoding_specified.html",
        "expected_ISO-8859-5_saved_from_no_encoding_specified.html",
        "ISO-8859-5" },
      { "ISO-8859-6_with_no_encoding_specified.html",
        "expected_ISO-8859-6_saved_from_no_encoding_specified.html",
        "ISO-8859-6" },
      { "ISO-8859-7_with_no_encoding_specified.html",
        "expected_ISO-8859-7_saved_from_no_encoding_specified.html",
        "ISO-8859-7" },
      { "ISO-8859-8_with_no_encoding_specified.html",
        "expected_ISO-8859-8_saved_from_no_encoding_specified.html",
        "ISO-8859-8-I" },
      { "KOI8-R_with_no_encoding_specified.html",
        "expected_KOI8-R_saved_from_no_encoding_specified.html",
        "KOI8-R" },
      { "Shift-JIS_with_no_encoding_specified.html",
        "expected_Shift-JIS_saved_from_no_encoding_specified.html",
        "Shift_JIS" },
      { "UTF-8_with_no_encoding_specified.html",
        "expected_UTF-8_saved_from_no_encoding_specified.html",
        "UTF-8" },
      { "windows-949_with_no_encoding_specified.html",
        "expected_windows-949_saved_from_no_encoding_specified.html",
        "windows-949-2000" },
      { "windows-1251_with_no_encoding_specified.html",
        "expected_windows-1251_saved_from_no_encoding_specified.html",
        "windows-1251" },
      { "windows-1254_with_no_encoding_specified.html",
        "expected_windows-1254_saved_from_no_encoding_specified.html",
        "windows-1254" },
      { "windows-1255_with_no_encoding_specified.html",
        "expected_windows-1255_saved_from_no_encoding_specified.html",
        "windows-1255" },
      { "windows-1256_with_no_encoding_specified.html",
        "expected_windows-1256_saved_from_no_encoding_specified.html",
        "windows-1256" }
    };
  const char* const kAutoDetectDir = "auto_detect";
  // Directory of the files of expected results.
  const char* const kExpectedResultDir = "expected_results";

  FilePath test_dir_path = FilePath(kTestDir).AppendASCII(kAutoDetectDir);

  // Set the default charset to one of encodings not supported by the current
  // auto-detector (Please refer to the above comments) to make sure we
  // incorrectly decode the page. Now we use ISO-8859-4.
  browser()->profile()->GetPrefs()->SetString(
      prefs::kGlobalDefaultCharset, "ISO-8859-4");

  content::WebContents* web_contents = browser()->GetSelectedWebContents();
  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestDatas); ++i) {
    // Disable auto detect if it is on.
    browser()->profile()->GetPrefs()->SetBoolean(
        prefs::kWebKitUsesUniversalDetector, false);

    FilePath test_file_path(test_dir_path);
    test_file_path = test_file_path.AppendASCII(kTestDatas[i].test_file_name);
    GURL url = URLRequestMockHTTPJob::GetMockUrl(test_file_path);
    ui_test_utils::NavigateToURL(browser(), url);

    // Get the encoding used for the page, it must be the default charset we
    // just set.
    EXPECT_EQ("ISO-8859-4", web_contents->GetEncoding());

    // Enable the encoding auto detection.
    browser()->profile()->GetPrefs()->SetBoolean(
        prefs::kWebKitUsesUniversalDetector, true);

    TestNavigationObserver observer(
        content::Source<content::NavigationController>(
            &web_contents->GetController()));
    browser()->Reload(CURRENT_TAB);
    observer.Wait();

    // Re-get the encoding of page. It should return the real encoding now.
    EXPECT_EQ(kTestDatas[i].expected_encoding, web_contents->GetEncoding());

    // Dump the page, the content of dump page should be equal with our expect
    // result file.
    FilePath expected_result_file_name =
        FilePath().AppendASCII(kAutoDetectDir).AppendASCII(kExpectedResultDir).
        AppendASCII(kTestDatas[i].expected_result);
    SaveAndCompare(kTestDatas[i].test_file_name, expected_result_file_name);
  }
}
<commit_msg>Load every testcase of BrowserEncodingTest.TestEncodingAliasMapping in a new tab to avoid the race condition where the previous encoding is seen.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/bind.h"
#include "base/file_util.h"
#include "base/scoped_temp_dir.h"
#include "chrome/browser/character_encoding.h"
#include "chrome/browser/net/url_request_mock_util.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/web_contents.h"
#include "content/test/net/url_request_mock_http_job.h"
#include "content/test/test_navigation_observer.h"

using content::BrowserThread;

static const FilePath::CharType* kTestDir = FILE_PATH_LITERAL("encoding_tests");

class BrowserEncodingTest : public InProcessBrowserTest {
 protected:
  BrowserEncodingTest() {}

  // Saves the current page and verifies that the output matches the expected
  // result.
  void SaveAndCompare(const char* filename_to_write, const FilePath& expected) {
    // Dump the page, the content of dump page should be identical to the
    // expected result file.
    FilePath full_file_name = save_dir_.AppendASCII(filename_to_write);
    // We save the page as way of complete HTML file, which requires a directory
    // name to save sub resources in it. Although this test file does not have
    // sub resources, but the directory name is still required.
    ui_test_utils::WindowedNotificationObserver observer(
        content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED,
        content::NotificationService::AllSources());
    browser()->GetSelectedWebContents()->SavePage(
        full_file_name, temp_sub_resource_dir_,
        content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML);
    observer.Wait();

    FilePath expected_file_name = ui_test_utils::GetTestFilePath(
        FilePath(kTestDir), expected);

    EXPECT_TRUE(file_util::ContentsEqual(full_file_name, expected_file_name));
  }

  void SetUpOnMainThread() OVERRIDE {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    save_dir_ = temp_dir_.path();
    temp_sub_resource_dir_ = save_dir_.AppendASCII("sub_resource_files");

    BrowserThread::PostTask(
        BrowserThread::IO, FROM_HERE,
        base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true));
  }

  ScopedTempDir temp_dir_;
  FilePath save_dir_;
  FilePath temp_sub_resource_dir_;
};

// TODO(jnd): 1. Some encodings are missing here. It'll be added later. See
// http://crbug.com/13306.
// 2. Add more files with multiple encoding name variants for each canonical
// encoding name). Webkit layout tests cover some, but testing in the UI test is
// also necessary.
// SLOW_ is added for XP debug bots. These tests should really be unittests...
IN_PROC_BROWSER_TEST_F(BrowserEncodingTest, SLOW_TestEncodingAliasMapping) {
  struct EncodingTestData {
    const char* file_name;
    const char* encoding_name;
  };

  const EncodingTestData kEncodingTestDatas[] = {
    { "Big5.html", "Big5" },
    { "EUC-JP.html", "EUC-JP" },
    { "gb18030.html", "gb18030" },
    { "iso-8859-1.html", "ISO-8859-1" },
    { "ISO-8859-2.html", "ISO-8859-2" },
    { "ISO-8859-4.html", "ISO-8859-4" },
    { "ISO-8859-5.html", "ISO-8859-5" },
    { "ISO-8859-6.html", "ISO-8859-6" },
    { "ISO-8859-7.html", "ISO-8859-7" },
    { "ISO-8859-8.html", "ISO-8859-8" },
    { "ISO-8859-13.html", "ISO-8859-13" },
    { "ISO-8859-15.html", "ISO-8859-15" },
    { "KOI8-R.html", "KOI8-R" },
    { "KOI8-U.html", "KOI8-U" },
    { "macintosh.html", "macintosh" },
    { "Shift-JIS.html", "Shift_JIS" },
    { "US-ASCII.html", "ISO-8859-1" },  // http://crbug.com/15801
    { "UTF-8.html", "UTF-8" },
    { "UTF-16LE.html", "UTF-16LE" },
    { "windows-874.html", "windows-874" },
    // http://crbug.com/95963
    // { "windows-949.html", "windows-949" },
    { "windows-1250.html", "windows-1250" },
    { "windows-1251.html", "windows-1251" },
    { "windows-1252.html", "windows-1252" },
    { "windows-1253.html", "windows-1253" },
    { "windows-1254.html", "windows-1254" },
    { "windows-1255.html", "windows-1255" },
    { "windows-1256.html", "windows-1256" },
    { "windows-1257.html", "windows-1257" },
    { "windows-1258.html", "windows-1258" }
  };
  const char* const kAliasTestDir = "alias_mapping";

  FilePath test_dir_path = FilePath(kTestDir).AppendASCII(kAliasTestDir);
  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kEncodingTestDatas); ++i) {
    FilePath test_file_path(test_dir_path);
    test_file_path = test_file_path.AppendASCII(
        kEncodingTestDatas[i].file_name);

    GURL url = URLRequestMockHTTPJob::GetMockUrl(test_file_path);

    // When looping through all the above files in one WebContents, there's a
    // race condition on Windows trybots that causes the previous encoding to be
    // seen sometimes. Create a new tab for each one.  http://crbug.com/122053
    ui_test_utils::NavigateToURLWithDisposition(
        browser(), url, NEW_FOREGROUND_TAB,
        ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);

    EXPECT_EQ(kEncodingTestDatas[i].encoding_name,
              browser()->GetSelectedWebContents()->GetEncoding());
    browser()->CloseTab();
  }
}

// Marked as flaky: see  http://crbug.com/44668
IN_PROC_BROWSER_TEST_F(BrowserEncodingTest, TestOverrideEncoding) {
  const char* const kTestFileName = "gb18030_with_iso88591_meta.html";
  const char* const kExpectedFileName =
      "expected_gb18030_saved_from_iso88591_meta.html";
  const char* const kOverrideTestDir = "user_override";

  FilePath test_dir_path = FilePath(kTestDir).AppendASCII(kOverrideTestDir);
  test_dir_path = test_dir_path.AppendASCII(kTestFileName);
  GURL url = URLRequestMockHTTPJob::GetMockUrl(test_dir_path);
  ui_test_utils::NavigateToURL(browser(), url);
  content::WebContents* web_contents = browser()->GetSelectedWebContents();
  EXPECT_EQ("ISO-8859-1", web_contents->GetEncoding());

  // Override the encoding to "gb18030".
  const std::string selected_encoding =
      CharacterEncoding::GetCanonicalEncodingNameByAliasName("gb18030");
  TestNavigationObserver navigation_observer(
      content::Source<content::NavigationController>(
          &web_contents->GetController()));
  web_contents->SetOverrideEncoding(selected_encoding);
  navigation_observer.Wait();
  EXPECT_EQ("gb18030", web_contents->GetEncoding());

  FilePath expected_filename =
      FilePath().AppendASCII(kOverrideTestDir).AppendASCII(kExpectedFileName);
  SaveAndCompare(kTestFileName, expected_filename);
}

// The following encodings are excluded from the auto-detection test because
// it's a known issue that the current encoding detector does not detect them:
// ISO-8859-4
// ISO-8859-13
// KOI8-U
// macintosh
// windows-874
// windows-1252
// windows-1253
// windows-1257
// windows-1258

// For Hebrew, the expected encoding value is ISO-8859-8-I. See
// http://crbug.com/2927 for more details.
//
// This test fails frequently on the win_rel trybot. See http://crbug.com/122053
#if defined(OS_WIN)
#define MAYBE_TestEncodingAutoDetect DISABLED_TestEncodingAutoDetect
#else
#define MAYBE_TestEncodingAutoDetect TestEncodingAutoDetect
#endif
IN_PROC_BROWSER_TEST_F(BrowserEncodingTest, MAYBE_TestEncodingAutoDetect) {
  struct EncodingAutoDetectTestData {
    const char* test_file_name;   // File name of test data.
    const char* expected_result;  // File name of expected results.
    const char* expected_encoding;   // expected encoding.
  };
  const EncodingAutoDetectTestData kTestDatas[] = {
      { "Big5_with_no_encoding_specified.html",
        "expected_Big5_saved_from_no_encoding_specified.html",
        "Big5" },
      { "gb18030_with_no_encoding_specified.html",
        "expected_gb18030_saved_from_no_encoding_specified.html",
        "gb18030" },
      { "iso-8859-1_with_no_encoding_specified.html",
        "expected_iso-8859-1_saved_from_no_encoding_specified.html",
        "ISO-8859-1" },
      { "ISO-8859-5_with_no_encoding_specified.html",
        "expected_ISO-8859-5_saved_from_no_encoding_specified.html",
        "ISO-8859-5" },
      { "ISO-8859-6_with_no_encoding_specified.html",
        "expected_ISO-8859-6_saved_from_no_encoding_specified.html",
        "ISO-8859-6" },
      { "ISO-8859-7_with_no_encoding_specified.html",
        "expected_ISO-8859-7_saved_from_no_encoding_specified.html",
        "ISO-8859-7" },
      { "ISO-8859-8_with_no_encoding_specified.html",
        "expected_ISO-8859-8_saved_from_no_encoding_specified.html",
        "ISO-8859-8-I" },
      { "KOI8-R_with_no_encoding_specified.html",
        "expected_KOI8-R_saved_from_no_encoding_specified.html",
        "KOI8-R" },
      { "Shift-JIS_with_no_encoding_specified.html",
        "expected_Shift-JIS_saved_from_no_encoding_specified.html",
        "Shift_JIS" },
      { "UTF-8_with_no_encoding_specified.html",
        "expected_UTF-8_saved_from_no_encoding_specified.html",
        "UTF-8" },
      { "windows-949_with_no_encoding_specified.html",
        "expected_windows-949_saved_from_no_encoding_specified.html",
        "windows-949-2000" },
      { "windows-1251_with_no_encoding_specified.html",
        "expected_windows-1251_saved_from_no_encoding_specified.html",
        "windows-1251" },
      { "windows-1254_with_no_encoding_specified.html",
        "expected_windows-1254_saved_from_no_encoding_specified.html",
        "windows-1254" },
      { "windows-1255_with_no_encoding_specified.html",
        "expected_windows-1255_saved_from_no_encoding_specified.html",
        "windows-1255" },
      { "windows-1256_with_no_encoding_specified.html",
        "expected_windows-1256_saved_from_no_encoding_specified.html",
        "windows-1256" }
    };
  const char* const kAutoDetectDir = "auto_detect";
  // Directory of the files of expected results.
  const char* const kExpectedResultDir = "expected_results";

  FilePath test_dir_path = FilePath(kTestDir).AppendASCII(kAutoDetectDir);

  // Set the default charset to one of encodings not supported by the current
  // auto-detector (Please refer to the above comments) to make sure we
  // incorrectly decode the page. Now we use ISO-8859-4.
  browser()->profile()->GetPrefs()->SetString(
      prefs::kGlobalDefaultCharset, "ISO-8859-4");

  content::WebContents* web_contents = browser()->GetSelectedWebContents();
  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestDatas); ++i) {
    // Disable auto detect if it is on.
    browser()->profile()->GetPrefs()->SetBoolean(
        prefs::kWebKitUsesUniversalDetector, false);

    FilePath test_file_path(test_dir_path);
    test_file_path = test_file_path.AppendASCII(kTestDatas[i].test_file_name);
    GURL url = URLRequestMockHTTPJob::GetMockUrl(test_file_path);
    ui_test_utils::NavigateToURL(browser(), url);

    // Get the encoding used for the page, it must be the default charset we
    // just set.
    EXPECT_EQ("ISO-8859-4", web_contents->GetEncoding());

    // Enable the encoding auto detection.
    browser()->profile()->GetPrefs()->SetBoolean(
        prefs::kWebKitUsesUniversalDetector, true);

    TestNavigationObserver observer(
        content::Source<content::NavigationController>(
            &web_contents->GetController()));
    browser()->Reload(CURRENT_TAB);
    observer.Wait();

    // Re-get the encoding of page. It should return the real encoding now.
    EXPECT_EQ(kTestDatas[i].expected_encoding, web_contents->GetEncoding());

    // Dump the page, the content of dump page should be equal with our expect
    // result file.
    FilePath expected_result_file_name =
        FilePath().AppendASCII(kAutoDetectDir).AppendASCII(kExpectedResultDir).
        AppendASCII(kTestDatas[i].expected_result);
    SaveAndCompare(kTestDatas[i].test_file_name, expected_result_file_name);
  }
}
<|endoftext|>


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

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

#include "base/metrics/histogram.h"
#include "base/string_number_conversions.h"
#include "base/time.h"
#include "chrome/browser/prerender/prerender_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/common/view_messages.h"

namespace prerender {

namespace {

const int kMinHoverThresholdsMs[] = {
  50,
  75,
  100,
  150,
  200,
  250,
  300,
  400,
  500,
  750,
  1000
};

// Overview of hover-related histograms:
// -- count of hover start
// -- count of hover too short.
// difference between these is pages prerendered
// -- count of prerender used
// -- time from hover commence until click (subtract hover threshold
// from that value to figure out average savings).

enum HoverEvents {
  HOVER_EVENT_START = 0,
  HOVER_EVENT_TOO_SHORT = 1,
  HOVER_EVENT_REPLACED = 2,
  HOVER_EVENT_CLICK = 3,
  HOVER_EVENT_MAX
};

const int kNumHoverThresholds = arraysize(kMinHoverThresholdsMs);

class PerHoverThresholdHistograms {
 public:
  explicit PerHoverThresholdHistograms(int hover_threshold_ms) {
    std::string prefix = std::string("Prerender.HoverStats_") +
        base::IntToString(hover_threshold_ms) + std::string("_");
    count_hover_events_ = base::LinearHistogram::FactoryGet(
        prefix + std::string("Events"),
        1,
        HOVER_EVENT_MAX,
        HOVER_EVENT_MAX + 1,
        base::Histogram::kUmaTargetedHistogramFlag);
    time_hover_until_click_ = base::Histogram::FactoryTimeGet(
        prefix + std::string("TimeToClick"),
        base::TimeDelta::FromMilliseconds(1),
        base::TimeDelta::FromSeconds(60),
        100,
        base::Histogram::kUmaTargetedHistogramFlag);
  }
  base::Histogram* count_hover_events() { return count_hover_events_; }
  base::Histogram* time_hover_until_click() { return time_hover_until_click_; }

 private:
  base::Histogram* count_hover_events_;
  base::Histogram* time_hover_until_click_;
};

}  // namespace

class PrerenderObserver::HoverData {
 public:
  void SetHoverThreshold(int threshold_ms) {
    hover_threshold_ = base::TimeDelta::FromMilliseconds(threshold_ms);
    histograms_.reset(new PerHoverThresholdHistograms(threshold_ms));
  }

  void RecordHover(const GURL& url) {
    VerifyInitialized();

    MaybeStartedPrerendering();

    // Ignore duplicate hover messages.
    if (new_url_ == url)
      return;

    if (!new_url_.is_empty())
      histograms_->count_hover_events()->Add(HOVER_EVENT_TOO_SHORT);

    if (current_url_ == url) {
      // If we came back to URL currently being prerendered, we don't need
      // to "remember" to start prerendering, because we already have that
      // URL prerendered.
      new_url_ = GURL();
    } else {
      // Otherwise, we remember this new URL as something we might soon
      // start prerendering.
      new_url_ = url;
      new_time_ = base::TimeTicks::Now();
    }

    if (!new_url_.is_empty())
      histograms_->count_hover_events()->Add(HOVER_EVENT_START);
  }

  void RecordNavigation(const GURL& url) {
    VerifyInitialized();

    // Artifically call RecordHover with an empty URL to accomplish two things:
    // -- ensure we update what we are currently prerendering
    // -- record if there is a pending new hover, that we "exited" it,
    //    thereby recording an EVENT_TOO_SHORT for it.
    RecordHover(GURL());

    if (current_url_ == url) {
        // Match.  We would have started prerendering the new URL.
        histograms_->count_hover_events()->Add(HOVER_EVENT_CLICK);
        histograms_->time_hover_until_click()->AddTime(
            base::TimeTicks::Now() - current_time_);
        current_url_ = GURL();
    }
  }

 private:
  void VerifyInitialized() {
    DCHECK(histograms_.get() != NULL);
  }

  void MaybeStartedPrerendering() {
    if (!new_url_.is_empty() &&
        base::TimeTicks::Now() - new_time_ > hover_threshold_) {
      if (!current_url_.is_empty())
        histograms_->count_hover_events()->Add(HOVER_EVENT_REPLACED);
      current_url_ = new_url_;
      current_time_ = new_time_;
      new_url_ = GURL();
    }
  }

  scoped_ptr<PerHoverThresholdHistograms> histograms_;

  // The time & url of the hover that is currently being prerendered.
  base::TimeTicks current_time_;
  GURL current_url_;

  // The time & url of a new hover that does not meet the threshold for
  // prerendering and may replace the prerender currently being prerendered.
  base::TimeTicks new_time_;
  GURL new_url_;

  // The threshold for hovering.
  base::TimeDelta hover_threshold_;
};

PrerenderObserver::PrerenderObserver(TabContentsWrapper* tab)
    : TabContentsObserver(tab->tab_contents()),
      tab_(tab),
      pplt_load_start_(),
      last_hovers_(new HoverData[kNumHoverThresholds]) {
  for (int i = 0; i < kNumHoverThresholds; i++)
    last_hovers_[i].SetHoverThreshold(kMinHoverThresholdsMs[i]);
}

PrerenderObserver::~PrerenderObserver() {
}

void PrerenderObserver::ProvisionalChangeToMainFrameUrl(const GURL& url,
                                                        bool has_opener_set) {
  if (!tab_->delegate())
    return;  // PrerenderManager needs a delegate to handle the swap.
  PrerenderManager* prerender_manager = MaybeGetPrerenderManager();
  if (!prerender_manager)
    return;
  if (prerender_manager->IsTabContentsPrerendering(tab_contents()))
    return;
  prerender_manager->MarkTabContentsAsNotPrerendered(tab_contents());
  MaybeUsePrerenderedPage(url, has_opener_set);
}

bool PrerenderObserver::OnMessageReceived(const IPC::Message& message) {
  IPC_BEGIN_MESSAGE_MAP(PrerenderObserver, message)
    IPC_MESSAGE_HANDLER(ViewHostMsg_DidStartProvisionalLoadForFrame,
                        OnDidStartProvisionalLoadForFrame)
    IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateTargetURL, OnMsgUpdateTargetURL)
  IPC_END_MESSAGE_MAP()
  return false;
}

void PrerenderObserver::OnDidStartProvisionalLoadForFrame(int64 frame_id,
                                                          bool is_main_frame,
                                                          bool has_opener_set,
                                                          const GURL& url) {
  if (is_main_frame) {
    // Record the beginning of a new PPLT navigation.
    pplt_load_start_ = base::TimeTicks::Now();

    // Update hover stats.
    for (int i = 0; i < kNumHoverThresholds; i++)
      last_hovers_[i].RecordNavigation(url);

    MaybeLogCurrentHover(current_hover_url_ == url);
  }
}

void PrerenderObserver::OnMsgUpdateTargetURL(int32 page_id, const GURL& url) {
  for (int i = 0; i < kNumHoverThresholds; i++)
    last_hovers_[i].RecordHover(url);

  if (url != current_hover_url_) {
    MaybeLogCurrentHover(false);
    current_hover_url_ = url;
    current_hover_time_ = base::TimeTicks::Now();
  }
}

void PrerenderObserver::DidStopLoading() {
  // Don't include prerendered pages in the PPLT metric until after they are
  // swapped in.

  // Compute the PPLT metric and report it in a histogram, if needed.
  if (!pplt_load_start_.is_null() && !IsPrerendering()) {
    PrerenderManager::RecordPerceivedPageLoadTime(
        base::TimeTicks::Now() - pplt_load_start_, tab_contents());
  }

  // Reset the PPLT metric.
  pplt_load_start_ = base::TimeTicks();
}

PrerenderManager* PrerenderObserver::MaybeGetPrerenderManager() {
  Profile* profile =
      Profile::FromBrowserContext(tab_contents()->browser_context());
  return profile->GetPrerenderManager();
}

bool PrerenderObserver::MaybeUsePrerenderedPage(const GURL& url,
                                                bool has_opener_set) {
  PrerenderManager* prerender_manager = MaybeGetPrerenderManager();
  if (!prerender_manager)
    return false;
  DCHECK(!prerender_manager->IsTabContentsPrerendering(tab_contents()));
  return prerender_manager->MaybeUsePrerenderedPage(tab_contents(),
                                                    url,
                                                    has_opener_set);
}

bool PrerenderObserver::IsPrerendering() {
  PrerenderManager* prerender_manager = MaybeGetPrerenderManager();
  if (!prerender_manager)
    return false;
  return prerender_manager->IsTabContentsPrerendering(tab_contents());
}

void PrerenderObserver::PrerenderSwappedIn() {
  // Ensure we are not prerendering any more.
  DCHECK(!IsPrerendering());
  if (pplt_load_start_.is_null()) {
    // If we have already finished loading, report a 0 PPLT.
    PrerenderManager::RecordPerceivedPageLoadTime(base::TimeDelta(),
                                                  tab_contents());
  } else {
    // If we have not finished loading yet, rebase the start time to now.
    pplt_load_start_ = base::TimeTicks::Now();
  }
}

void PrerenderObserver::MaybeLogCurrentHover(bool was_used) {
  if (current_hover_url_.is_empty())
    return;

  static const int64 min_ms = 0;
  static const int64 max_ms = 2000;
  static const int num_buckets = 100;

  int64 elapsed_ms =
      (base::TimeTicks::Now() - current_hover_time_).InMilliseconds();

  elapsed_ms = std::min(std::max(elapsed_ms, min_ms), max_ms);
  elapsed_ms /= max_ms / num_buckets;

  if (was_used) {
    UMA_HISTOGRAM_ENUMERATION("Prerender.HoverStats_TimeUntilClicked",
                              elapsed_ms, num_buckets);
  } else {
    UMA_HISTOGRAM_ENUMERATION("Prerender.HoverStats_TimeUntilDiscarded",
                              elapsed_ms, num_buckets);
  }

  current_hover_url_ = GURL();
}

}  // namespace prerender
<commit_msg>Add Hover stats for 1.5s, 2s, and 3s hover thresholds. R=jabdelmalek@chromium.org Review URL: http://codereview.chromium.org/7621030<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

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

#include "base/metrics/histogram.h"
#include "base/string_number_conversions.h"
#include "base/time.h"
#include "chrome/browser/prerender/prerender_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/common/view_messages.h"

namespace prerender {

namespace {

const int kMinHoverThresholdsMs[] = {
  50,
  75,
  100,
  150,
  200,
  250,
  300,
  400,
  500,
  750,
  1000,
  1500,
  2000,
  3000,
  4000,
  5000
};

// Overview of hover-related histograms:
// -- count of hover start
// -- count of hover too short.
// difference between these is pages prerendered
// -- count of prerender used
// -- time from hover commence until click (subtract hover threshold
// from that value to figure out average savings).

enum HoverEvents {
  HOVER_EVENT_START = 0,
  HOVER_EVENT_TOO_SHORT = 1,
  HOVER_EVENT_REPLACED = 2,
  HOVER_EVENT_CLICK = 3,
  HOVER_EVENT_MAX
};

const int kNumHoverThresholds = arraysize(kMinHoverThresholdsMs);

class PerHoverThresholdHistograms {
 public:
  explicit PerHoverThresholdHistograms(int hover_threshold_ms) {
    std::string prefix = std::string("Prerender.HoverStats_") +
        base::IntToString(hover_threshold_ms) + std::string("_");
    count_hover_events_ = base::LinearHistogram::FactoryGet(
        prefix + std::string("Events"),
        1,
        HOVER_EVENT_MAX,
        HOVER_EVENT_MAX + 1,
        base::Histogram::kUmaTargetedHistogramFlag);
    time_hover_until_click_ = base::Histogram::FactoryTimeGet(
        prefix + std::string("TimeToClick"),
        base::TimeDelta::FromMilliseconds(1),
        base::TimeDelta::FromSeconds(60),
        100,
        base::Histogram::kUmaTargetedHistogramFlag);
  }
  base::Histogram* count_hover_events() { return count_hover_events_; }
  base::Histogram* time_hover_until_click() { return time_hover_until_click_; }

 private:
  base::Histogram* count_hover_events_;
  base::Histogram* time_hover_until_click_;
};

}  // namespace

class PrerenderObserver::HoverData {
 public:
  void SetHoverThreshold(int threshold_ms) {
    hover_threshold_ = base::TimeDelta::FromMilliseconds(threshold_ms);
    histograms_.reset(new PerHoverThresholdHistograms(threshold_ms));
  }

  void RecordHover(const GURL& url) {
    VerifyInitialized();

    MaybeStartedPrerendering();

    // Ignore duplicate hover messages.
    if (new_url_ == url)
      return;

    if (!new_url_.is_empty())
      histograms_->count_hover_events()->Add(HOVER_EVENT_TOO_SHORT);

    if (current_url_ == url) {
      // If we came back to URL currently being prerendered, we don't need
      // to "remember" to start prerendering, because we already have that
      // URL prerendered.
      new_url_ = GURL();
    } else {
      // Otherwise, we remember this new URL as something we might soon
      // start prerendering.
      new_url_ = url;
      new_time_ = base::TimeTicks::Now();
    }

    if (!new_url_.is_empty())
      histograms_->count_hover_events()->Add(HOVER_EVENT_START);
  }

  void RecordNavigation(const GURL& url) {
    VerifyInitialized();

    // Artifically call RecordHover with an empty URL to accomplish two things:
    // -- ensure we update what we are currently prerendering
    // -- record if there is a pending new hover, that we "exited" it,
    //    thereby recording an EVENT_TOO_SHORT for it.
    RecordHover(GURL());

    if (current_url_ == url) {
        // Match.  We would have started prerendering the new URL.
        histograms_->count_hover_events()->Add(HOVER_EVENT_CLICK);
        histograms_->time_hover_until_click()->AddTime(
            base::TimeTicks::Now() - current_time_);
        current_url_ = GURL();
    }
  }

 private:
  void VerifyInitialized() {
    DCHECK(histograms_.get() != NULL);
  }

  void MaybeStartedPrerendering() {
    if (!new_url_.is_empty() &&
        base::TimeTicks::Now() - new_time_ > hover_threshold_) {
      if (!current_url_.is_empty())
        histograms_->count_hover_events()->Add(HOVER_EVENT_REPLACED);
      current_url_ = new_url_;
      current_time_ = new_time_;
      new_url_ = GURL();
    }
  }

  scoped_ptr<PerHoverThresholdHistograms> histograms_;

  // The time & url of the hover that is currently being prerendered.
  base::TimeTicks current_time_;
  GURL current_url_;

  // The time & url of a new hover that does not meet the threshold for
  // prerendering and may replace the prerender currently being prerendered.
  base::TimeTicks new_time_;
  GURL new_url_;

  // The threshold for hovering.
  base::TimeDelta hover_threshold_;
};

PrerenderObserver::PrerenderObserver(TabContentsWrapper* tab)
    : TabContentsObserver(tab->tab_contents()),
      tab_(tab),
      pplt_load_start_(),
      last_hovers_(new HoverData[kNumHoverThresholds]) {
  for (int i = 0; i < kNumHoverThresholds; i++)
    last_hovers_[i].SetHoverThreshold(kMinHoverThresholdsMs[i]);
}

PrerenderObserver::~PrerenderObserver() {
}

void PrerenderObserver::ProvisionalChangeToMainFrameUrl(const GURL& url,
                                                        bool has_opener_set) {
  if (!tab_->delegate())
    return;  // PrerenderManager needs a delegate to handle the swap.
  PrerenderManager* prerender_manager = MaybeGetPrerenderManager();
  if (!prerender_manager)
    return;
  if (prerender_manager->IsTabContentsPrerendering(tab_contents()))
    return;
  prerender_manager->MarkTabContentsAsNotPrerendered(tab_contents());
  MaybeUsePrerenderedPage(url, has_opener_set);
}

bool PrerenderObserver::OnMessageReceived(const IPC::Message& message) {
  IPC_BEGIN_MESSAGE_MAP(PrerenderObserver, message)
    IPC_MESSAGE_HANDLER(ViewHostMsg_DidStartProvisionalLoadForFrame,
                        OnDidStartProvisionalLoadForFrame)
    IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateTargetURL, OnMsgUpdateTargetURL)
  IPC_END_MESSAGE_MAP()
  return false;
}

void PrerenderObserver::OnDidStartProvisionalLoadForFrame(int64 frame_id,
                                                          bool is_main_frame,
                                                          bool has_opener_set,
                                                          const GURL& url) {
  if (is_main_frame) {
    // Record the beginning of a new PPLT navigation.
    pplt_load_start_ = base::TimeTicks::Now();

    // Update hover stats.
    for (int i = 0; i < kNumHoverThresholds; i++)
      last_hovers_[i].RecordNavigation(url);

    MaybeLogCurrentHover(current_hover_url_ == url);
  }
}

void PrerenderObserver::OnMsgUpdateTargetURL(int32 page_id, const GURL& url) {
  for (int i = 0; i < kNumHoverThresholds; i++)
    last_hovers_[i].RecordHover(url);

  if (url != current_hover_url_) {
    MaybeLogCurrentHover(false);
    current_hover_url_ = url;
    current_hover_time_ = base::TimeTicks::Now();
  }
}

void PrerenderObserver::DidStopLoading() {
  // Don't include prerendered pages in the PPLT metric until after they are
  // swapped in.

  // Compute the PPLT metric and report it in a histogram, if needed.
  if (!pplt_load_start_.is_null() && !IsPrerendering()) {
    PrerenderManager::RecordPerceivedPageLoadTime(
        base::TimeTicks::Now() - pplt_load_start_, tab_contents());
  }

  // Reset the PPLT metric.
  pplt_load_start_ = base::TimeTicks();
}

PrerenderManager* PrerenderObserver::MaybeGetPrerenderManager() {
  Profile* profile =
      Profile::FromBrowserContext(tab_contents()->browser_context());
  return profile->GetPrerenderManager();
}

bool PrerenderObserver::MaybeUsePrerenderedPage(const GURL& url,
                                                bool has_opener_set) {
  PrerenderManager* prerender_manager = MaybeGetPrerenderManager();
  if (!prerender_manager)
    return false;
  DCHECK(!prerender_manager->IsTabContentsPrerendering(tab_contents()));
  return prerender_manager->MaybeUsePrerenderedPage(tab_contents(),
                                                    url,
                                                    has_opener_set);
}

bool PrerenderObserver::IsPrerendering() {
  PrerenderManager* prerender_manager = MaybeGetPrerenderManager();
  if (!prerender_manager)
    return false;
  return prerender_manager->IsTabContentsPrerendering(tab_contents());
}

void PrerenderObserver::PrerenderSwappedIn() {
  // Ensure we are not prerendering any more.
  DCHECK(!IsPrerendering());
  if (pplt_load_start_.is_null()) {
    // If we have already finished loading, report a 0 PPLT.
    PrerenderManager::RecordPerceivedPageLoadTime(base::TimeDelta(),
                                                  tab_contents());
  } else {
    // If we have not finished loading yet, rebase the start time to now.
    pplt_load_start_ = base::TimeTicks::Now();
  }
}

void PrerenderObserver::MaybeLogCurrentHover(bool was_used) {
  if (current_hover_url_.is_empty())
    return;

  static const int64 min_ms = 0;
  static const int64 max_ms = 2000;
  static const int num_buckets = 100;

  int64 elapsed_ms =
      (base::TimeTicks::Now() - current_hover_time_).InMilliseconds();

  elapsed_ms = std::min(std::max(elapsed_ms, min_ms), max_ms);
  elapsed_ms /= max_ms / num_buckets;

  if (was_used) {
    UMA_HISTOGRAM_ENUMERATION("Prerender.HoverStats_TimeUntilClicked",
                              elapsed_ms, num_buckets);
  } else {
    UMA_HISTOGRAM_ENUMERATION("Prerender.HoverStats_TimeUntilDiscarded",
                              elapsed_ms, num_buckets);
  }

  current_hover_url_ = GURL();
}

}  // namespace prerender
<|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/spellchecker/spellcheck_host.h"

#include "base/string_split.h"
#include "base/synchronization/waitable_event.h"
#include "chrome/browser/api/prefs/pref_member.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/spellchecker/spellcheck_host_impl.h"
#include "chrome/browser/spellchecker/spellcheck_platform_mac.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/spellcheck_common.h"

using content::BrowserThread;

namespace {

// An event used by browser tests to receive status events from this class and
// its derived classes.
base::WaitableEvent* g_status_event = NULL;
SpellCheckHost::EventType g_status_type = SpellCheckHost::BDICT_NOTINITIALIZED;

}  // namespace

// static
SpellCheckHost* SpellCheckHost::Create(
    SpellCheckProfileProvider* profile,
    const std::string& language,
    net::URLRequestContextGetter* request_context_getter,
    SpellCheckHostMetrics* metrics) {
  SpellCheckHostImpl* host =
      new SpellCheckHostImpl(profile, language, request_context_getter,
                             metrics);
  if (!host)
    return NULL;

  host->Initialize();
  return host;
}

// static
int SpellCheckHost::GetSpellCheckLanguages(
    Profile* profile,
    std::vector<std::string>* languages) {
  StringPrefMember accept_languages_pref;
  StringPrefMember dictionary_language_pref;
  accept_languages_pref.Init(prefs::kAcceptLanguages, profile->GetPrefs(),
                             NULL);
  dictionary_language_pref.Init(prefs::kSpellCheckDictionary,
                                profile->GetPrefs(), NULL);
  std::string dictionary_language = dictionary_language_pref.GetValue();

  // Now scan through the list of accept languages, and find possible mappings
  // from this list to the existing list of spell check languages.
  std::vector<std::string> accept_languages;

#if defined(OS_MACOSX)
  if (spellcheck_mac::SpellCheckerAvailable())
    spellcheck_mac::GetAvailableLanguages(&accept_languages);
  else
    base::SplitString(accept_languages_pref.GetValue(), ',', &accept_languages);
#else
  base::SplitString(accept_languages_pref.GetValue(), ',', &accept_languages);
#endif  // !OS_MACOSX

  GetSpellCheckLanguagesFromAcceptLanguages(
      accept_languages, dictionary_language, languages);

  for (size_t i = 0; i < languages->size(); ++i) {
    if ((*languages)[i] == dictionary_language)
      return i;
  }
  return -1;
}

// static
void SpellCheckHost::GetSpellCheckLanguagesFromAcceptLanguages(
    const std::vector<std::string>& accept_languages,
    const std::string& dictionary_language,
    std::vector<std::string>* languages) {
  // The current dictionary language should be there.
  languages->push_back(dictionary_language);

  for (std::vector<std::string>::const_iterator i = accept_languages.begin();
       i != accept_languages.end(); ++i) {
    std::string language =
        chrome::spellcheck_common::GetCorrespondingSpellCheckLanguage(*i);
    if (!language.empty() &&
        std::find(languages->begin(), languages->end(), language) ==
        languages->end()) {
      languages->push_back(language);
    }
  }
}

// static
bool SpellCheckHost::SignalStatusEvent(SpellCheckHost::EventType status_type) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));

  if (!g_status_event)
    return false;
  g_status_type = status_type;
  g_status_event->Signal();
  return true;
}

// static
void SpellCheckHost::AttachStatusEvent(base::WaitableEvent* status_event) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  g_status_event = status_event;
}

// static
SpellCheckHost::EventType SpellCheckHost::WaitStatusEvent() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  if (g_status_event)
    g_status_event->Wait();
  return g_status_type;
}
<commit_msg>[Spellcheck] remove dead file<commit_after><|endoftext|>


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

#include "chrome/browser/ui/views/file_manager_dialog.h"

#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "chrome/browser/extensions/extension_file_browser_private_api.h"
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/file_manager_util.h"
#include "chrome/browser/sessions/restore_tab_helper.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/browser/ui/views/extensions/extension_dialog.h"
#include "chrome/browser/ui/views/window.h"
#include "content/browser/browser_thread.h"
#include "content/browser/tab_contents/tab_contents.h"

namespace {
const int kFileManagerWidth = 720;  // pixels
const int kFileManagerHeight = 580;  // pixels

// Object to hold references to file manager dialogs that have callbacks
// pending to their listeners.
class PendingDialog {
 public:
  static void Add(int32 tab_id, FileManagerDialog* dialog);
  static void Remove(int32 tab_id);
  static FileManagerDialog* Find(int32 tab_id);

 private:
  explicit PendingDialog(FileManagerDialog* dialog)
      : dialog_(dialog) {
  }

  scoped_refptr<FileManagerDialog> dialog_;

  typedef std::map<int32, PendingDialog> Map;
  static Map map_;
};

// static
PendingDialog::Map PendingDialog::map_;

// static
void PendingDialog::Add(int32 tab_id, FileManagerDialog* dialog) {
  DCHECK(dialog);
  if (map_.find(tab_id) == map_.end())
    map_.insert(std::make_pair(tab_id, PendingDialog(dialog)));
  else
    LOG(WARNING) << "Duplicate pending dialog " << tab_id;
}

// static
void PendingDialog::Remove(int32 tab_id) {
  map_.erase(tab_id);
}

// static
FileManagerDialog* PendingDialog::Find(int32 tab_id) {
  Map::const_iterator it = map_.find(tab_id);
  if (it == map_.end()) {
    LOG(WARNING) << "Pending dialog not found " << tab_id;
    return NULL;
  }
  return it->second.dialog_.get();
}

}  // namespace

// Linking this implementation of SelectFileDialog::Create into the target
// selects FileManagerDialog as the dialog of choice.
// static
SelectFileDialog* SelectFileDialog::Create(Listener* listener) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  return new FileManagerDialog(listener);
}

/////////////////////////////////////////////////////////////////////////////

FileManagerDialog::FileManagerDialog(Listener* listener)
    : SelectFileDialog(listener),
      params_(NULL),
      tab_id_(0),
      owner_window_(0) {
}

FileManagerDialog::~FileManagerDialog() {
  if (extension_dialog_)
    extension_dialog_->ObserverDestroyed();
  PendingDialog::Remove(tab_id_);
}

bool FileManagerDialog::IsRunning(gfx::NativeWindow owner_window) const {
  return owner_window_ == owner_window;
}

void FileManagerDialog::ListenerDestroyed() {
  listener_ = NULL;
  params_ = NULL;
  PendingDialog::Remove(tab_id_);
}

void FileManagerDialog::ExtensionDialogIsClosing(ExtensionDialog* dialog) {
  owner_window_ = NULL;
  // Release our reference to the dialog to allow it to close.
  extension_dialog_ = NULL;
  PendingDialog::Remove(tab_id_);
}

void FileManagerDialog::Close() {
  if (extension_dialog_)
    extension_dialog_->Close();
  PendingDialog::Remove(tab_id_);
}

// static
void FileManagerDialog::OnFileSelected(
    int32 tab_id, const FilePath& path, int index) {
  FileManagerDialog* self = PendingDialog::Find(tab_id);
  if (self) {
    DCHECK(self->listener_);
    self->listener_->FileSelected(path, index, self->params_);
    self->Close();
  }
}

// static
void FileManagerDialog::OnMultiFilesSelected(
    int32 tab_id, const std::vector<FilePath>& files) {
  FileManagerDialog* self = PendingDialog::Find(tab_id);
  if (self) {
    DCHECK(self->listener_);
    self->listener_->MultiFilesSelected(files, self->params_);
    self->Close();
  }
}

// static
void FileManagerDialog::OnFileSelectionCanceled(int32 tab_id) {
  FileManagerDialog* self = PendingDialog::Find(tab_id);
  if (self) {
    DCHECK(self->listener_);
    self->listener_->FileSelectionCanceled(self->params_);
    self->Close();
  }
}

RenderViewHost* FileManagerDialog::GetRenderViewHost() {
  if (extension_dialog_)
    return extension_dialog_->host()->render_view_host();
  return NULL;
}

void FileManagerDialog::SelectFileImpl(
    Type type,
    const string16& title,
    const FilePath& default_path,
    const FileTypeInfo* file_types,
    int file_type_index,
    const FilePath::StringType& default_extension,
    gfx::NativeWindow owner_window,
    void* params) {
  LOG(INFO) << "FileBrowser: SelectFileImpl default_path "
      << default_path.value();
  if (owner_window_) {
    LOG(ERROR) << "File dialog already in use!";
    return;
  }
  Browser* owner_browser = BrowserList::FindBrowserWithWindow(owner_window);
  if (!owner_browser) {
    NOTREACHED() << "Can't find owning browser";
    return;
  }

  GURL file_browser_url = FileManagerUtil::GetFileBrowserUrlWithParams(
      type, title, default_path, file_types, file_type_index,
      default_extension);
  extension_dialog_ = ExtensionDialog::Show(file_browser_url,
      owner_browser, kFileManagerWidth, kFileManagerHeight,
      this /* ExtensionDialog::Observer */);

  // Connect our listener to FileDialogFunction's per-tab callbacks.
  TabContentsWrapper* tab = owner_browser->GetSelectedTabContentsWrapper();
  int32 tab_id = (tab ? tab->restore_tab_helper()->session_id().id() : 0);
  PendingDialog::Add(tab_id, this);

  params_ = params;
  tab_id_ = tab_id;
  owner_window_ = owner_window;
}
<commit_msg>CrOS - Fix file picker not appearing for Import Bookmarks<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/views/file_manager_dialog.h"

#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "chrome/browser/extensions/extension_file_browser_private_api.h"
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/file_manager_util.h"
#include "chrome/browser/sessions/restore_tab_helper.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/browser/ui/views/extensions/extension_dialog.h"
#include "chrome/browser/ui/views/window.h"
#include "content/browser/browser_thread.h"
#include "content/browser/tab_contents/tab_contents.h"

namespace {
const int kFileManagerWidth = 720;  // pixels
const int kFileManagerHeight = 580;  // pixels

// Object to hold references to file manager dialogs that have callbacks
// pending to their listeners.
class PendingDialog {
 public:
  static void Add(int32 tab_id, FileManagerDialog* dialog);
  static void Remove(int32 tab_id);
  static FileManagerDialog* Find(int32 tab_id);

 private:
  explicit PendingDialog(FileManagerDialog* dialog)
      : dialog_(dialog) {
  }

  scoped_refptr<FileManagerDialog> dialog_;

  typedef std::map<int32, PendingDialog> Map;
  static Map map_;
};

// static
PendingDialog::Map PendingDialog::map_;

// static
void PendingDialog::Add(int32 tab_id, FileManagerDialog* dialog) {
  DCHECK(dialog);
  if (map_.find(tab_id) == map_.end())
    map_.insert(std::make_pair(tab_id, PendingDialog(dialog)));
  else
    LOG(WARNING) << "Duplicate pending dialog " << tab_id;
}

// static
void PendingDialog::Remove(int32 tab_id) {
  map_.erase(tab_id);
}

// static
FileManagerDialog* PendingDialog::Find(int32 tab_id) {
  Map::const_iterator it = map_.find(tab_id);
  if (it == map_.end()) {
    LOG(WARNING) << "Pending dialog not found " << tab_id;
    return NULL;
  }
  return it->second.dialog_.get();
}

}  // namespace

// Linking this implementation of SelectFileDialog::Create into the target
// selects FileManagerDialog as the dialog of choice.
// static
SelectFileDialog* SelectFileDialog::Create(Listener* listener) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  return new FileManagerDialog(listener);
}

/////////////////////////////////////////////////////////////////////////////

FileManagerDialog::FileManagerDialog(Listener* listener)
    : SelectFileDialog(listener),
      params_(NULL),
      tab_id_(0),
      owner_window_(0) {
}

FileManagerDialog::~FileManagerDialog() {
  if (extension_dialog_)
    extension_dialog_->ObserverDestroyed();
  PendingDialog::Remove(tab_id_);
}

bool FileManagerDialog::IsRunning(gfx::NativeWindow owner_window) const {
  return owner_window_ == owner_window;
}

void FileManagerDialog::ListenerDestroyed() {
  listener_ = NULL;
  params_ = NULL;
  PendingDialog::Remove(tab_id_);
}

void FileManagerDialog::ExtensionDialogIsClosing(ExtensionDialog* dialog) {
  owner_window_ = NULL;
  // Release our reference to the dialog to allow it to close.
  extension_dialog_ = NULL;
  PendingDialog::Remove(tab_id_);
}

void FileManagerDialog::Close() {
  if (extension_dialog_)
    extension_dialog_->Close();
  PendingDialog::Remove(tab_id_);
}

// static
void FileManagerDialog::OnFileSelected(
    int32 tab_id, const FilePath& path, int index) {
  FileManagerDialog* self = PendingDialog::Find(tab_id);
  if (self) {
    DCHECK(self->listener_);
    self->listener_->FileSelected(path, index, self->params_);
    self->Close();
  }
}

// static
void FileManagerDialog::OnMultiFilesSelected(
    int32 tab_id, const std::vector<FilePath>& files) {
  FileManagerDialog* self = PendingDialog::Find(tab_id);
  if (self) {
    DCHECK(self->listener_);
    self->listener_->MultiFilesSelected(files, self->params_);
    self->Close();
  }
}

// static
void FileManagerDialog::OnFileSelectionCanceled(int32 tab_id) {
  FileManagerDialog* self = PendingDialog::Find(tab_id);
  if (self) {
    DCHECK(self->listener_);
    self->listener_->FileSelectionCanceled(self->params_);
    self->Close();
  }
}

RenderViewHost* FileManagerDialog::GetRenderViewHost() {
  if (extension_dialog_)
    return extension_dialog_->host()->render_view_host();
  return NULL;
}

void FileManagerDialog::SelectFileImpl(
    Type type,
    const string16& title,
    const FilePath& default_path,
    const FileTypeInfo* file_types,
    int file_type_index,
    const FilePath::StringType& default_extension,
    gfx::NativeWindow owner_window,
    void* params) {
  if (owner_window_) {
    LOG(ERROR) << "File dialog already in use!";
    return;
  }
  // Extension background pages may not supply an owner_window.
  Browser* owner_browser = (owner_window ?
      BrowserList::FindBrowserWithWindow(owner_window) :
      BrowserList::GetLastActive());
  if (!owner_browser) {
    NOTREACHED() << "Can't find owning browser";
    return;
  }

  GURL file_browser_url = FileManagerUtil::GetFileBrowserUrlWithParams(
      type, title, default_path, file_types, file_type_index,
      default_extension);
  extension_dialog_ = ExtensionDialog::Show(file_browser_url,
      owner_browser, kFileManagerWidth, kFileManagerHeight,
      this /* ExtensionDialog::Observer */);

  // Connect our listener to FileDialogFunction's per-tab callbacks.
  TabContentsWrapper* tab = owner_browser->GetSelectedTabContentsWrapper();
  int32 tab_id = (tab ? tab->restore_tab_helper()->session_id().id() : 0);
  PendingDialog::Add(tab_id, this);

  params_ = params;
  tab_id_ = tab_id;
  owner_window_ = owner_window;
}
<|endoftext|>


<commit_before>
#ifndef _WIN32
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <libgen.h>
#include <dlfcn.h>
#else
#include <windows.h>
#endif
#include <chrono>
#include <iostream>
#include <thread>
#include <stdexcept>
#include <tclap/CmdLine.h>

#include <mapredo/settings.h>
#include <mapredo/engine.h>
#include <mapredo/base.h>
#ifndef _WIN32
#include <mapredo/plugin_loader.h>
#include <mapredo/directory.h>
#else
#include <mapredo/plugin_loader_win32.h>
#include <mapredo/directory_win32.h>
typedef DWORD ssize_t;
#endif

static double time_since (const std::chrono::high_resolution_clock::time_point& time)
{
    auto duration = std::chrono::duration_cast<std::chrono::duration<double>>
	(std::chrono::high_resolution_clock::now() - time);
    return duration.count();
}

static void reduce (const std::string& plugin_file,
		    const std::string& work_dir,
		    const std::string& subdir,
		    const bool verbose,
		    const int parallel,
		    const int max_files)
{
    if (verbose)
    {
	std::cerr << "Using working directory " << work_dir << "\n";
	std::cerr << "Using " << parallel << " threads,"
		  << " with HW concurrency at "
		  << std::thread::hardware_concurrency()
		  << "\n";
    }

    plugin_loader plugin (plugin_file);
    auto& mapreducer (plugin.get());
    engine mapred_engine (work_dir, subdir, parallel, 0, max_files);
    auto start_time = std::chrono::high_resolution_clock::now();

    mapred_engine.reduce (mapreducer, plugin);

    if (verbose)
    {
	std::cerr << "Merging finished in " << std::fixed
		  << time_since (start_time) << "s\n";
    }
}

static void run (const std::string& plugin_file,
		 const std::string& work_dir,
		 const std::string& subdir,
		 const bool verbose,
		 const size_t buffer_size,
		 const int parallel,
		 const int max_files,
		 const bool map_only)
{
    plugin_loader plugin (plugin_file);
    auto& mapreducer (plugin.get());
    engine mapred_engine (work_dir, subdir, parallel, buffer_size, max_files);
    size_t buf_size = 0x2000;
    std::unique_ptr<char[]> buf (new char[buf_size]);
    size_t start = 0, end = 0;
    size_t i;
    ssize_t bytes;
    std::string line;
    bool first = true;
    std::chrono::high_resolution_clock::time_point start_time;

#ifdef _WIN32
    auto STDIN_FILENO = GetStdHandle (STD_INPUT_HANDLE);
    while ((ReadFile (STDIN_FILENO, buf.get() + end,
	    buf_size - end, &bytes, NULL) && bytes > 0))
#else
    while ((bytes = read(STDIN_FILENO, buf.get() + end, buf_size - end)) > 0)
#endif
    {
	end += bytes;
	if (first)
	{
	    first = false;

	    // Skip any Windows style UTF-8 header
	    unsigned char u8header[] = {0xef, 0xbb, 0xbf};
	    if (end - start >= 3 && memcmp(buf.get() + start, u8header, 3) == 0)
	    {
		start += 3;
	    }
	    start_time = std::chrono::high_resolution_clock::now();
	    mapred_engine.enable_sorters (mapreducer.type(),
					  false);
	    if (verbose)
	    {
		std::cerr << "Using working directory " << work_dir << "\n";
		std::cerr << "Maximum buffer size is " << buffer_size
			  << " bytes.\nUsing " << parallel << " threads,"
			  << " with HW concurrency at "
			  << std::thread::hardware_concurrency()
			  << "\n";
	    }
	}
	for (i = start; i < end; i++)
	{
	    if (buf[i] == '\n')
	    {
		if (i == start || buf[i-1] != '\r')
		{
		    buf[i] = '\0';
		    mapreducer.map(buf.get() + start, i - start, mapred_engine);
		}
		else
		{
		    buf[i-1] = '\0';
		    mapreducer.map (buf.get() + start, i - start - 1,
				    mapred_engine);
		}
		start = i + 1;
	    }
	}
	if (start < i)
	{
	    if (start == 0)
	    {
		buf_size *= 2; // double line buffer
		char* nbuf = new char[buf_size];
		memcpy (nbuf, buf.get(), end);
		buf.reset (nbuf);
	    }
	    memmove (buf.get(), buf.get() + start, end - start);
	    end -= start;
	    start = 0;
	}
	else start = end = 0;
    }
    if (first) return; // no input

    if (verbose)
    {
	std::cerr << "Sorting finished in " << std::fixed
		  << time_since (start_time) << "s\n";
    }

    if (!map_only)
    {
	mapred_engine.flush (mapreducer, plugin);
	if (verbose)
	{
	    std::cerr << "Merging finished in " << std::fixed
		      << time_since (start_time) << "s\n";
	}
    }
    else mapred_engine.flush();
}

static std::string get_default_workdir()
{
    return TMPDIR;
}

int
main (int argc, char* argv[])
{
    int64_t buffer_size = 10 * 1024 * 1024;
    int parallel = std::thread::hardware_concurrency();
    int max_files = 20 * parallel;
    bool verbose = false;
    bool compression = true;
    std::string subdir;
    std::string work_dir = get_default_workdir();
    bool map_only = false;
    bool reduce_only = false;
    bool keep_tmpfiles = false;
    std::string plugin_path;

    settings& config (settings::instance());

    try
    {
	TCLAP::CmdLine cmd ("mapredo: Map-reduce engine for small/medium data",
			    ' ', PACKAGE_VERSION);
	TCLAP::ValueArg<std::string> subdirArg
	    ("s", "subdir", "Subdirectory to use",
	     false, "", "string", cmd);
	TCLAP::ValueArg<std::string> workdirArg
	    ("d", "work-dir", "Working directory to use",
	     false, work_dir, "string", cmd);
	TCLAP::ValueArg<std::string> bufferSizeArg
	    ("b", "buffer-size", "Buffer size to use",
	     false, "10M", "size", cmd);
	TCLAP::ValueArg<int> maxFilesArg
	    ("f", "max-open-files", "Maximum number of open files",
	     false, max_files, "number", cmd);
	TCLAP::ValueArg<int> threadsArg
	    ("j", "threads", "Number of threads to use",
	     false, parallel, "threads", cmd);
	TCLAP::SwitchArg verboseArg
	    ("", "verbose", "Verbose output", cmd, false);
	TCLAP::SwitchArg noCompressionArg
	    ("", "no-compression", "Disable compression", cmd, false);
	TCLAP::SwitchArg keepFilesArg
	    ("", "keep-tmpfiles", "Keep the temporary files after completion",
	     cmd, false);
	TCLAP::SwitchArg mapOnlyArg
	    ("", "map-only", "Only perform the mapping stage", cmd, false);
	TCLAP::SwitchArg reduceOnlyArg
	    ("", "reduce-only", "Only perform the reduce stage", cmd, false);
	TCLAP::UnlabeledValueArg<std::string> pluginArg
	    ("plugin", "Plugin file to use", true, "", "plugin file", cmd);

	cmd.parse (argc, argv);
	subdir = subdirArg.getValue();
	work_dir = workdirArg.getValue();
	buffer_size = config.parse_size (bufferSizeArg.getValue());
	max_files = maxFilesArg.getValue();
	parallel = threadsArg.getValue();
	verbose = verboseArg.getValue();
	keep_tmpfiles = keepFilesArg.getValue();
	map_only = mapOnlyArg.getValue();
	reduce_only = reduceOnlyArg.getValue();
	plugin_path = pluginArg.getValue();

	if (!directory::exists(work_dir))
	{
	    throw TCLAP::ArgException
		("The working directory '" + work_dir + "' does not exist",
		 "work-dir");
	}
	if (max_files < 3)
	{
	    throw TCLAP::ArgException
		("Can not work with less than 3 files", "max-open-files");
	}

	if (reduce_only && map_only)
	{
	    throw TCLAP::ArgException
		("Options --map-only and --reduce-only are mutually exclusive",
		 "map_only");
	}
	if (map_only && subdir.empty())
	{
	    throw TCLAP::ArgException
		("Option --map-only cannot be used without --subdir",
		 "map-only");
	}
	if (reduce_only && subdir.empty())
	{
	    throw TCLAP::ArgException
		("Option --reduce-only cannot be used without --subdir",
		 "reduce-only");
	}
    }
    catch (const TCLAP::ArgException& e)
    {
	std::cerr << "error: " << e.error() << " for " << e.argId()
		  << std::endl;
	return (1);
    }

    if (verbose) config.set_verbose();
    if (compression) config.set_compressed();
    if (keep_tmpfiles) config.set_keep_tmpfiles();

    try
    {
	if (reduce_only)
	{
	    reduce (plugin_path, work_dir, subdir, verbose, parallel,
		    max_files);
	}
	else
	{
	    run (plugin_path, work_dir, subdir, verbose, buffer_size,
		 parallel, max_files, map_only);
	}
    }
    catch (const std::exception& e)
    {
	std::cerr << e.what() << std::endl;
	return 1;
    }

    return 0;
}
<commit_msg>Changed duration check to measure time since last call.<commit_after>
#ifndef _WIN32
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <libgen.h>
#include <dlfcn.h>
#else
#include <windows.h>
#endif
#include <chrono>
#include <iostream>
#include <thread>
#include <stdexcept>
#include <tclap/CmdLine.h>

#include <mapredo/settings.h>
#include <mapredo/engine.h>
#include <mapredo/base.h>
#ifndef _WIN32
#include <mapredo/plugin_loader.h>
#include <mapredo/directory.h>
#else
#include <mapredo/plugin_loader_win32.h>
#include <mapredo/directory_win32.h>
typedef DWORD ssize_t;
#endif

static double duration (std::chrono::high_resolution_clock::time_point& time)
{
    auto now (std::chrono::high_resolution_clock::now());
    auto duration = std::chrono::duration_cast<std::chrono::duration<double>>
	(now - time);
    time = now;
    return duration.count();
}

static void reduce (const std::string& plugin_file,
		    const std::string& work_dir,
		    const std::string& subdir,
		    const bool verbose,
		    const int parallel,
		    const int max_files)
{
    if (verbose)
    {
	std::cerr << "Using working directory " << work_dir << "\n";
	std::cerr << "Using " << parallel << " threads,"
		  << " with HW concurrency at "
		  << std::thread::hardware_concurrency()
		  << "\n";
    }

    plugin_loader plugin (plugin_file);
    auto& mapreducer (plugin.get());
    engine mapred_engine (work_dir, subdir, parallel, 0, max_files);
    auto start_time (std::chrono::high_resolution_clock::now());

    mapred_engine.reduce (mapreducer, plugin);

    if (verbose)
    {
	std::cerr << "Merging finished in " << std::fixed
		  << duration (start_time) << "s\n";
    }
}

static void run (const std::string& plugin_file,
		 const std::string& work_dir,
		 const std::string& subdir,
		 const bool verbose,
		 const size_t buffer_size,
		 const int parallel,
		 const int max_files,
		 const bool map_only)
{
    plugin_loader plugin (plugin_file);
    auto& mapreducer (plugin.get());
    engine mapred_engine (work_dir, subdir, parallel, buffer_size, max_files);
    size_t buf_size = 0x2000;
    std::unique_ptr<char[]> buf (new char[buf_size]);
    size_t start = 0, end = 0;
    size_t i;
    ssize_t bytes;
    std::string line;
    bool first = true;
    std::chrono::high_resolution_clock::time_point start_time;

#ifdef _WIN32
    auto STDIN_FILENO = GetStdHandle (STD_INPUT_HANDLE);
    while ((ReadFile (STDIN_FILENO, buf.get() + end,
	    buf_size - end, &bytes, NULL) && bytes > 0))
#else
    while ((bytes = read(STDIN_FILENO, buf.get() + end, buf_size - end)) > 0)
#endif
    {
	end += bytes;
	if (first)
	{
	    first = false;

	    // Skip any Windows style UTF-8 header
	    unsigned char u8header[] = {0xef, 0xbb, 0xbf};
	    if (end - start >= 3 && memcmp(buf.get() + start, u8header, 3) == 0)
	    {
		start += 3;
	    }
	    start_time = std::chrono::high_resolution_clock::now();
	    mapred_engine.enable_sorters (mapreducer.type(),
					  false);
	    if (verbose)
	    {
		std::cerr << "Using working directory " << work_dir << "\n";
		std::cerr << "Maximum buffer size is " << buffer_size
			  << " bytes.\nUsing " << parallel << " threads,"
			  << " with HW concurrency at "
			  << std::thread::hardware_concurrency()
			  << "\n";
	    }
	}
	for (i = start; i < end; i++)
	{
	    if (buf[i] == '\n')
	    {
		if (i == start || buf[i-1] != '\r')
		{
		    buf[i] = '\0';
		    mapreducer.map(buf.get() + start, i - start, mapred_engine);
		}
		else
		{
		    buf[i-1] = '\0';
		    mapreducer.map (buf.get() + start, i - start - 1,
				    mapred_engine);
		}
		start = i + 1;
	    }
	}
	if (start < i)
	{
	    if (start == 0)
	    {
		buf_size *= 2; // double line buffer
		char* nbuf = new char[buf_size];
		memcpy (nbuf, buf.get(), end);
		buf.reset (nbuf);
	    }
	    memmove (buf.get(), buf.get() + start, end - start);
	    end -= start;
	    start = 0;
	}
	else start = end = 0;
    }
    if (first) return; // no input

    if (verbose)
    {
	std::cerr << "Sorting finished in " << std::fixed
		  << duration (start_time) << "s\n";
    }

    if (!map_only)
    {
	mapred_engine.flush (mapreducer, plugin);
	if (verbose)
	{
	    std::cerr << "Merging finished in " << std::fixed
		      << duration (start_time) << "s\n";
	}
    }
    else mapred_engine.flush();
}

static std::string get_default_workdir()
{
    return TMPDIR;
}

int
main (int argc, char* argv[])
{
    int64_t buffer_size = 10 * 1024 * 1024;
    int parallel = std::thread::hardware_concurrency();
    int max_files = 20 * parallel;
    bool verbose = false;
    bool compression = true;
    std::string subdir;
    std::string work_dir = get_default_workdir();
    bool map_only = false;
    bool reduce_only = false;
    bool keep_tmpfiles = false;
    std::string plugin_path;

    settings& config (settings::instance());

    try
    {
	TCLAP::CmdLine cmd ("mapredo: Map-reduce engine for small/medium data",
			    ' ', PACKAGE_VERSION);
	TCLAP::ValueArg<std::string> subdirArg
	    ("s", "subdir", "Subdirectory to use",
	     false, "", "string", cmd);
	TCLAP::ValueArg<std::string> workdirArg
	    ("d", "work-dir", "Working directory to use",
	     false, work_dir, "string", cmd);
	TCLAP::ValueArg<std::string> bufferSizeArg
	    ("b", "buffer-size", "Buffer size to use",
	     false, "10M", "size", cmd);
	TCLAP::ValueArg<int> maxFilesArg
	    ("f", "max-open-files", "Maximum number of open files",
	     false, max_files, "number", cmd);
	TCLAP::ValueArg<int> threadsArg
	    ("j", "threads", "Number of threads to use",
	     false, parallel, "threads", cmd);
	TCLAP::SwitchArg verboseArg
	    ("", "verbose", "Verbose output", cmd, false);
	TCLAP::SwitchArg noCompressionArg
	    ("", "no-compression", "Disable compression", cmd, false);
	TCLAP::SwitchArg keepFilesArg
	    ("", "keep-tmpfiles", "Keep the temporary files after completion",
	     cmd, false);
	TCLAP::SwitchArg mapOnlyArg
	    ("", "map-only", "Only perform the mapping stage", cmd, false);
	TCLAP::SwitchArg reduceOnlyArg
	    ("", "reduce-only", "Only perform the reduce stage", cmd, false);
	TCLAP::UnlabeledValueArg<std::string> pluginArg
	    ("plugin", "Plugin file to use", true, "", "plugin file", cmd);

	cmd.parse (argc, argv);
	subdir = subdirArg.getValue();
	work_dir = workdirArg.getValue();
	buffer_size = config.parse_size (bufferSizeArg.getValue());
	max_files = maxFilesArg.getValue();
	parallel = threadsArg.getValue();
	verbose = verboseArg.getValue();
	keep_tmpfiles = keepFilesArg.getValue();
	map_only = mapOnlyArg.getValue();
	reduce_only = reduceOnlyArg.getValue();
	plugin_path = pluginArg.getValue();

	if (!directory::exists(work_dir))
	{
	    throw TCLAP::ArgException
		("The working directory '" + work_dir + "' does not exist",
		 "work-dir");
	}
	if (max_files < 3)
	{
	    throw TCLAP::ArgException
		("Can not work with less than 3 files", "max-open-files");
	}

	if (reduce_only && map_only)
	{
	    throw TCLAP::ArgException
		("Options --map-only and --reduce-only are mutually exclusive",
		 "map_only");
	}
	if (map_only && subdir.empty())
	{
	    throw TCLAP::ArgException
		("Option --map-only cannot be used without --subdir",
		 "map-only");
	}
	if (reduce_only && subdir.empty())
	{
	    throw TCLAP::ArgException
		("Option --reduce-only cannot be used without --subdir",
		 "reduce-only");
	}
    }
    catch (const TCLAP::ArgException& e)
    {
	std::cerr << "error: " << e.error() << " for " << e.argId()
		  << std::endl;
	return (1);
    }

    if (verbose) config.set_verbose();
    if (compression) config.set_compressed();
    if (keep_tmpfiles) config.set_keep_tmpfiles();

    try
    {
	if (reduce_only)
	{
	    reduce (plugin_path, work_dir, subdir, verbose, parallel,
		    max_files);
	}
	else
	{
	    run (plugin_path, work_dir, subdir, verbose, buffer_size,
		 parallel, max_files, map_only);
	}
    }
    catch (const std::exception& e)
    {
	std::cerr << e.what() << std::endl;
	return 1;
    }

    return 0;
}
<|endoftext|>