<commit_before>// Copyright 2013 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 "ash/accelerators/exit_warning_handler.h"

#include "ash/shell.h"
#include "ash/shell_delegate.h"
#include "ash/shell_window_ids.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "grit/ash_strings.h"
#include "ui/aura/root_window.h"
#include "ui/base/accessibility/accessible_view_state.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/font.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"

namespace ash {
namespace {

const int64 kTimeOutMilliseconds = 2000;
const SkColor kForegroundColor = 0xFFFFFFFF;
const SkColor kBackgroundColor = 0xE0808080;
const int kHorizontalMarginAroundText = 100;
const int kVerticalMarginAroundText = 100;

class ExitWarningLabel : public views::Label {
 public:
  ExitWarningLabel() {}

  virtual ~ExitWarningLabel() {}

 private:
  virtual void PaintText(gfx::Canvas* canvas,
                         const string16& text,
                         const gfx::Rect& text_bounds,
                         int flags) OVERRIDE {
    // Turn off subpixel rendering.
    views::Label::PaintText(canvas,
                            text,
                            text_bounds,
                            flags | gfx::Canvas::NO_SUBPIXEL_RENDERING);
  }

  DISALLOW_COPY_AND_ASSIGN(ExitWarningLabel);
};

class ExitWarningWidgetDelegateView : public views::WidgetDelegateView {
 public:
  ExitWarningWidgetDelegateView() : text_width_(0), width_(0), height_(0) {
    text_ = l10n_util::GetStringUTF16(IDS_ASH_EXIT_WARNING_POPUP_TEXT);
    accessible_name_ =
        l10n_util::GetStringUTF16(IDS_ASH_EXIT_WARNING_POPUP_TEXT_ACCESSIBLE);
    ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
    font_ = rb.GetFont(ui::ResourceBundle::LargeFont);
    text_width_ = font_.GetStringWidth(text_);
    width_ = text_width_ + kHorizontalMarginAroundText;
    height_ = font_.GetHeight() + kVerticalMarginAroundText;
    views::Label* label = new ExitWarningLabel;
    label->SetText(text_);
    label->SetHorizontalAlignment(gfx::ALIGN_CENTER);
    label->SetFont(font_);
    label->SetEnabledColor(kForegroundColor);
    label->SetDisabledColor(kForegroundColor);
    label->SetAutoColorReadabilityEnabled(false);
    AddChildView(label);
    SetLayoutManager(new views::FillLayout);
  }

  virtual gfx::Size GetPreferredSize() OVERRIDE {
    return gfx::Size(width_, height_);
  }

  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
    canvas->FillRect(GetLocalBounds(), kBackgroundColor);
    views::WidgetDelegateView::OnPaint(canvas);
  }

  virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE {
    state->name = accessible_name_;
    state->role = ui::AccessibilityTypes::ROLE_ALERT;
  }

 private:
  base::string16 text_;
  base::string16 accessible_name_;
  gfx::Font font_;
  int text_width_;
  int width_;
  int height_;

  DISALLOW_COPY_AND_ASSIGN(ExitWarningWidgetDelegateView);
};

}  // namespace

ExitWarningHandler::ExitWarningHandler()
    : state_(IDLE),
      stub_timer_for_test_(false) {
}

ExitWarningHandler::~ExitWarningHandler() {
  // Note: If a timer is outstanding, it is stopped in its destructor.
  Hide();
}

void ExitWarningHandler::HandleAccelerator() {
  ShellDelegate* shell_delegate = Shell::GetInstance()->delegate();
  switch (state_) {
    case IDLE:
      state_ = WAIT_FOR_DOUBLE_PRESS;
      Show();
      StartTimer();
      shell_delegate->RecordUserMetricsAction(UMA_ACCEL_EXIT_FIRST_Q);
      break;
    case WAIT_FOR_DOUBLE_PRESS:
      state_ = EXITING;
      CancelTimer();
      Hide();
      shell_delegate->RecordUserMetricsAction(UMA_ACCEL_EXIT_SECOND_Q);
      shell_delegate->Exit();
      break;
    case EXITING:
      break;
    default:
      NOTREACHED();
      break;
  }
}

void ExitWarningHandler::TimerAction() {
  Hide();
  if (state_ == WAIT_FOR_DOUBLE_PRESS)
    state_ = IDLE;
}

void ExitWarningHandler::StartTimer() {
  if (stub_timer_for_test_)
    return;
  timer_.Start(FROM_HERE,
               base::TimeDelta::FromMilliseconds(kTimeOutMilliseconds),
               this,
               &ExitWarningHandler::TimerAction);
}

void ExitWarningHandler::CancelTimer() {
  timer_.Stop();
}

void ExitWarningHandler::Show() {
  if (widget_)
    return;
  aura::RootWindow* root_window = Shell::GetActiveRootWindow();
  ExitWarningWidgetDelegateView* delegate = new ExitWarningWidgetDelegateView;
  gfx::Size rs = root_window->bounds().size();
  gfx::Size ps = delegate->GetPreferredSize();
  gfx::Rect bounds((rs.width() - ps.width()) / 2,
                   (rs.height() - ps.height()) / 3,
                   ps.width(), ps.height());
  views::Widget::InitParams params;
  params.type = views::Widget::InitParams::TYPE_POPUP;
  params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
  params.accept_events = false;
  params.can_activate = false;
  params.keep_on_top = true;
  params.remove_standard_frame = true;
  params.delegate = delegate;
  params.bounds = bounds;
  params.parent = Shell::GetContainer(
      root_window,
      internal::kShellWindowId_SettingBubbleContainer);
  widget_.reset(new views::Widget);
  widget_->Init(params);
  widget_->SetContentsView(delegate);
  widget_->GetNativeView()->SetName("ExitWarningWindow");
  widget_->Show();

  delegate->NotifyAccessibilityEvent(ui::AccessibilityTypes::EVENT_ALERT, true);
}

void ExitWarningHandler::Hide() {
  widget_.reset();
}

}  // namespace ash
<commit_msg>ash: Make exit warning dialog transparent black<commit_after>// Copyright 2013 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 "ash/accelerators/exit_warning_handler.h"

#include "ash/shell.h"
#include "ash/shell_delegate.h"
#include "ash/shell_window_ids.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "grit/ash_strings.h"
#include "ui/aura/root_window.h"
#include "ui/base/accessibility/accessible_view_state.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/font.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"

namespace ash {
namespace {

const int64 kTimeOutMilliseconds = 2000;
// Color of the text of the warning message.
const SkColor kTextColor = SK_ColorWHITE;
// Color of the window background.
const SkColor kWindowBackgroundColor = SkColorSetARGB(0xC0, 0x0, 0x0, 0x0);
// Radius of the rounded corners of the window.
const int kWindowCornerRadius = 2;
const int kHorizontalMarginAroundText = 100;
const int kVerticalMarginAroundText = 100;

class ExitWarningLabel : public views::Label {
 public:
  ExitWarningLabel() {}

  virtual ~ExitWarningLabel() {}

 private:
  virtual void PaintText(gfx::Canvas* canvas,
                         const string16& text,
                         const gfx::Rect& text_bounds,
                         int flags) OVERRIDE {
    // Turn off subpixel rendering.
    views::Label::PaintText(canvas,
                            text,
                            text_bounds,
                            flags | gfx::Canvas::NO_SUBPIXEL_RENDERING);
  }

  DISALLOW_COPY_AND_ASSIGN(ExitWarningLabel);
};

class ExitWarningWidgetDelegateView : public views::WidgetDelegateView {
 public:
  ExitWarningWidgetDelegateView() : text_width_(0), width_(0), height_(0) {
    text_ = l10n_util::GetStringUTF16(IDS_ASH_EXIT_WARNING_POPUP_TEXT);
    accessible_name_ =
        l10n_util::GetStringUTF16(IDS_ASH_EXIT_WARNING_POPUP_TEXT_ACCESSIBLE);
    ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
    font_ = rb.GetFont(ui::ResourceBundle::LargeFont);
    text_width_ = font_.GetStringWidth(text_);
    width_ = text_width_ + kHorizontalMarginAroundText;
    height_ = font_.GetHeight() + kVerticalMarginAroundText;
    views::Label* label = new ExitWarningLabel;
    label->SetText(text_);
    label->SetHorizontalAlignment(gfx::ALIGN_CENTER);
    label->SetFont(font_);
    label->SetEnabledColor(kTextColor);
    label->SetDisabledColor(kTextColor);
    label->SetAutoColorReadabilityEnabled(false);
    AddChildView(label);
    SetLayoutManager(new views::FillLayout);
  }

  virtual gfx::Size GetPreferredSize() OVERRIDE {
    return gfx::Size(width_, height_);
  }

  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
    SkPaint paint;
    paint.setStyle(SkPaint::kFill_Style);
    paint.setColor(kWindowBackgroundColor);
    canvas->DrawRoundRect(GetLocalBounds(), kWindowCornerRadius, paint);
    views::WidgetDelegateView::OnPaint(canvas);
  }

  virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE {
    state->name = accessible_name_;
    state->role = ui::AccessibilityTypes::ROLE_ALERT;
  }

 private:
  base::string16 text_;
  base::string16 accessible_name_;
  gfx::Font font_;
  int text_width_;
  int width_;
  int height_;

  DISALLOW_COPY_AND_ASSIGN(ExitWarningWidgetDelegateView);
};

}  // namespace

ExitWarningHandler::ExitWarningHandler()
    : state_(IDLE),
      stub_timer_for_test_(false) {
}

ExitWarningHandler::~ExitWarningHandler() {
  // Note: If a timer is outstanding, it is stopped in its destructor.
  Hide();
}

void ExitWarningHandler::HandleAccelerator() {
  ShellDelegate* shell_delegate = Shell::GetInstance()->delegate();
  switch (state_) {
    case IDLE:
      state_ = WAIT_FOR_DOUBLE_PRESS;
      Show();
      StartTimer();
      shell_delegate->RecordUserMetricsAction(UMA_ACCEL_EXIT_FIRST_Q);
      break;
    case WAIT_FOR_DOUBLE_PRESS:
      state_ = EXITING;
      CancelTimer();
      Hide();
      shell_delegate->RecordUserMetricsAction(UMA_ACCEL_EXIT_SECOND_Q);
      shell_delegate->Exit();
      break;
    case EXITING:
      break;
    default:
      NOTREACHED();
      break;
  }
}

void ExitWarningHandler::TimerAction() {
  Hide();
  if (state_ == WAIT_FOR_DOUBLE_PRESS)
    state_ = IDLE;
}

void ExitWarningHandler::StartTimer() {
  if (stub_timer_for_test_)
    return;
  timer_.Start(FROM_HERE,
               base::TimeDelta::FromMilliseconds(kTimeOutMilliseconds),
               this,
               &ExitWarningHandler::TimerAction);
}

void ExitWarningHandler::CancelTimer() {
  timer_.Stop();
}

void ExitWarningHandler::Show() {
  if (widget_)
    return;
  aura::RootWindow* root_window = Shell::GetActiveRootWindow();
  ExitWarningWidgetDelegateView* delegate = new ExitWarningWidgetDelegateView;
  gfx::Size rs = root_window->bounds().size();
  gfx::Size ps = delegate->GetPreferredSize();
  gfx::Rect bounds((rs.width() - ps.width()) / 2,
                   (rs.height() - ps.height()) / 3,
                   ps.width(), ps.height());
  views::Widget::InitParams params;
  params.type = views::Widget::InitParams::TYPE_POPUP;
  params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
  params.accept_events = false;
  params.can_activate = false;
  params.keep_on_top = true;
  params.remove_standard_frame = true;
  params.delegate = delegate;
  params.bounds = bounds;
  params.parent = Shell::GetContainer(
      root_window,
      internal::kShellWindowId_SettingBubbleContainer);
  widget_.reset(new views::Widget);
  widget_->Init(params);
  widget_->SetContentsView(delegate);
  widget_->GetNativeView()->SetName("ExitWarningWindow");
  widget_->Show();

  delegate->NotifyAccessibilityEvent(ui::AccessibilityTypes::EVENT_ALERT, true);
}

void ExitWarningHandler::Hide() {
  widget_.reset();
}

}  // namespace ash
<|endoftext|>


<commit_before>#include <iostream>

#include "occa.hpp"

int main(int argc, char **argv){
  int entries = 5;

  float *a  = new float[entries];
  float *b  = new float[entries];
  float *ab = new float[entries];

  for(int i = 0; i < entries; ++i){
    a[i]  = i;
    b[i]  = 1 - i;
    ab[i] = 0;
  }

  // occa::availableDevices<occa::OpenCL>();

  occa::device device;
  occa::kernel addVectors;
  occa::memory o_a, o_b, o_ab;

  device.setup("mode = OpenMP  , schedule = compact, chunk = 10");
  // device.setup("mode = OpenCL  , platformID = 0, deviceID = 0");
  // device.setup("mode = CUDA    , deviceID = 0");
  // device.setup("mode = Pthreads, threadCount = 1, schedule = compact");
  // device.setup("mode = COI     , deviceID = 0");

  o_a  = device.malloc(entries*sizeof(float));
  o_b  = device.malloc(entries*sizeof(float));
  o_ab = device.malloc(entries*sizeof(float));

  addVectors = device.buildKernelFromSource("addVectors.okl",
                                            "addVectors");

  //---[ Don't need to set these up when using OKL ]--------
  // int dims = 1;
  // int itemsPerGroup(16);
  // int groups((entries + itemsPerGroup - 1)/itemsPerGroup);
  //========================================================

  // addVectors.setWorkingDims(dims, itemsPerGroup, groups);

  o_a.copyFrom(a);
  o_b.copyFrom(b);

  occa::initTimer(device);

  occa::tic("addVectors");

  addVectors(entries, o_a, o_b, o_ab);

  double elapsedTime = occa::toc("addVectors", addVectors);

  o_ab.copyTo(ab);

  std::cout << "Elapsed time = " << elapsedTime << " s" << std::endl;

  occa::printTimer();

  for(int i = 0; i < 5; ++i)
    std::cout << i << ": " << ab[i] << '\n';

  for(int i = 0; i < entries; ++i){
    if(ab[i] != (a[i] + b[i]))
      throw 1;
  }

  delete [] a;
  delete [] b;
  delete [] ab;

  addVectors.free();
  o_a.free();
  o_b.free();
  o_ab.free();
  device.free();

  return 0;
}
<commit_msg>[Example] Updated device setup on addVectors example<commit_after>#include <iostream>

#include "occa.hpp"

int main(int argc, char **argv){
  int entries = 5;

  float *a  = new float[entries];
  float *b  = new float[entries];
  float *ab = new float[entries];

  for(int i = 0; i < entries; ++i){
    a[i]  = i;
    b[i]  = 1 - i;
    ab[i] = 0;
  }

  // occa::availableDevices<occa::OpenCL>();

  occa::device device;
  occa::kernel addVectors;
  occa::memory o_a, o_b, o_ab;

  device.setup("mode = OpenMP  , schedule = compact, chunk = 10");

  //---[ Device setup with string flags ]-------------------
  //    device.setup("mode = OpenMP  , schedule = compact, chunk = 10");
  //    device.setup("mode = OpenCL  , platformID = 0, deviceID = 0");
  //    device.setup("mode = CUDA    , deviceID = 0");
  //    device.setup("mode = Pthreads, threadCount = 4, schedule = compact, pinnedCores = [0, 0, 1, 1]");
  //    device.setup("mode = COI     , deviceID = 0");
  //========================================================

  //---[ Device setup with Python-like arguments ]----------
  //    device.setup("OpenMP",
  //                 occa::schedule = "compact",
  //                 occa::chunk    = 10);
  //
  //    device.setup("OpenCL",
  //                 occa::platformID = 0,
  //                 occa::deviceID   = 0);
  //
  //    device.setup("CUDA",
  //                 occa::deviceID = 0);
  //
  //    device.setup("Pthreads",
  //                 occa::threadCount = 4,
  //                 occa::schedule    = "compact",
  //                 occa::pinnedCores = "[0, 0, 1, 1]");
  //
  //    device.setup("COI",
  //                 occa::deviceID = 0);
  //========================================================

  o_a  = device.malloc(entries*sizeof(float));
  o_b  = device.malloc(entries*sizeof(float));
  o_ab = device.malloc(entries*sizeof(float));

  addVectors = device.buildKernelFromSource("addVectors.okl",
                                            "addVectors");

  //---[ Don't need to set these up when using OKL ]--------
  // int dims = 1;
  // int itemsPerGroup(16);
  // int groups((entries + itemsPerGroup - 1)/itemsPerGroup);
  //========================================================

  // addVectors.setWorkingDims(dims, itemsPerGroup, groups);

  o_a.copyFrom(a);
  o_b.copyFrom(b);

  occa::initTimer(device);

  occa::tic("addVectors");

  addVectors(entries, o_a, o_b, o_ab);

  double elapsedTime = occa::toc("addVectors", addVectors);

  o_ab.copyTo(ab);

  std::cout << "Elapsed time = " << elapsedTime << " s" << std::endl;

  occa::printTimer();

  for(int i = 0; i < 5; ++i)
    std::cout << i << ": " << ab[i] << '\n';

  for(int i = 0; i < entries; ++i){
    if(ab[i] != (a[i] + b[i]))
      throw 1;
  }

  delete [] a;
  delete [] b;
  delete [] ab;

  addVectors.free();
  o_a.free();
  o_b.free();
  o_ab.free();
  device.free();

  return 0;
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <sfx2/sidebar/ResourceDefinitions.hrc>
#include <sfx2/sidebar/Theme.hxx>
#include <sfx2/sidebar/ControlFactory.hxx>
#include "ChartElementsPanel.hxx"
#include "ChartController.hxx"
#include <sfx2/bindings.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/imagemgr.hxx>
#include <vcl/fixed.hxx>
#include <vcl/lstbox.hxx>
#include <vcl/field.hxx>
#include <vcl/toolbox.hxx>
#include <svl/intitem.hxx>
#include <svl/stritem.hxx>

#include "LegendHelper.hxx"
#include "TitleHelper.hxx"

#include "ChartModel.hxx"

using namespace css;
using namespace css::uno;
using ::sfx2::sidebar::Theme;

namespace chart { namespace sidebar {

namespace {

ChartModel* getChartModel(css::uno::Reference<css::frame::XModel> xModel)
{
    ChartModel* pModel = dynamic_cast<ChartModel*>(xModel.get());

    return pModel;
}

bool isLegendVisible(css::uno::Reference<css::frame::XModel> xModel)
{
    ChartModel* pModel = getChartModel(xModel);
    if (!pModel)
        return false;

    Reference< beans::XPropertySet > xLegendProp( LegendHelper::getLegend(*pModel), uno::UNO_QUERY );
    if( xLegendProp.is())
    {
        try
        {
            bool bShow = false;
            if( xLegendProp->getPropertyValue( "Show") >>= bShow )
            {
                return bShow;
            }
        }
        catch(const uno::Exception &)
        {
        }
    }

    return false;
}

bool isTitleVisisble(css::uno::Reference<css::frame::XModel> xModel, TitleHelper::eTitleType eTitle)
{
    return TitleHelper::getTitle(eTitle, xModel).is();
}

}

ChartElementsPanel::ChartElementsPanel(
    vcl::Window* pParent,
    const css::uno::Reference<css::frame::XFrame>& rxFrame,
    SfxBindings* pBindings,
    ChartController* pController)
  : PanelLayout(pParent, "ChartElementsPanel", "modules/schart/ui/sidebarelements.ui", rxFrame),
    mxFrame(rxFrame),
    maContext(),
    mpBindings(pBindings),
    mxModel(pController->getModel())
{
    get(mpCBTitle,  "checkbutton_title");
    get(mpCBSubtitle,  "checkbutton_subtitle");
    get(mpCBXAxis,  "checkbutton_x_axis");
    get(mpCBXAxisTitle,  "checkbutton_x_axis_title");
    get(mpCBYAxis,  "checkbutton_y_axis");
    get(mpCBYAxisTitle,  "checkbutton_y_axis_title");
    get(mpCBZAxis,  "checkbutton_z_axis");
    get(mpCBZAxisTitle,  "checkbutton_z_axis_title");
    get(mpCB2ndXAxis,  "checkbutton_2nd_x_axis");
    get(mpCB2ndXAxisTitle,  "checkbutton_2nd_x_axis_title");
    get(mpCB2ndYAxis,  "checkbutton_2nd_y_axis");
    get(mpCB2ndYAxisTitle,  "checkbutton_2nd_y_axis_title");
    get(mpCBLegend,  "checkbutton_legend");
    get(mpCBGridVertical,  "checkbutton_gridline_vertical");
    get(mpCBGridHorizontal,  "checkbutton_gridline_horizontal");
    get(mpCBShowLabel,  "checkbutton_label");
    get(mpCBTrendline,  "checkbutton_trendline");
}

ChartElementsPanel::~ChartElementsPanel()
{
    disposeOnce();
}

void ChartElementsPanel::dispose()
{
    mpCBTitle.clear();
    mpCBSubtitle.clear();
    mpCBXAxis.clear();
    mpCBXAxisTitle.clear();
    mpCBYAxis.clear();
    mpCBYAxisTitle.clear();
    mpCBZAxis.clear();
    mpCBZAxisTitle.clear();
    mpCB2ndXAxis.clear();
    mpCB2ndXAxisTitle.clear();
    mpCB2ndYAxis.clear();
    mpCB2ndYAxisTitle.clear();
    mpCBLegend.clear();
    mpCBGridVertical.clear();
    mpCBGridHorizontal.clear();
    mpCBShowLabel.clear();
    mpCBTrendline.clear();

    PanelLayout::dispose();
}

void ChartElementsPanel::Initialize()
{
    updateData();
}

void ChartElementsPanel::updateData()
{
    mpCBLegend->Check(isLegendVisible(mxModel));
    mpCBTitle->Check(isTitleVisisble(mxModel, TitleHelper::MAIN_TITLE));
    mpCBSubtitle->Check(isTitleVisisble(mxModel, TitleHelper::SUB_TITLE));
    mpCBXAxisTitle->Check(isTitleVisisble(mxModel, TitleHelper::X_AXIS_TITLE));
    mpCBYAxisTitle->Check(isTitleVisisble(mxModel, TitleHelper::Y_AXIS_TITLE));
    mpCBZAxisTitle->Check(isTitleVisisble(mxModel, TitleHelper::Z_AXIS_TITLE));
    mpCB2ndXAxisTitle->Check(isTitleVisisble(mxModel, TitleHelper::SECONDARY_X_AXIS_TITLE));
    mpCB2ndYAxisTitle->Check(isTitleVisisble(mxModel, TitleHelper::SECONDARY_Y_AXIS_TITLE));
}

VclPtr<vcl::Window> ChartElementsPanel::Create (
    vcl::Window* pParent,
    const css::uno::Reference<css::frame::XFrame>& rxFrame,
    SfxBindings* pBindings, ChartController* pController)
{
    if (pParent == NULL)
        throw lang::IllegalArgumentException("no parent Window given to ChartElementsPanel::Create", NULL, 0);
    if ( ! rxFrame.is())
        throw lang::IllegalArgumentException("no XFrame given to ChartElementsPanel::Create", NULL, 1);
    if (pBindings == NULL)
        throw lang::IllegalArgumentException("no SfxBindings given to ChartElementsPanel::Create", NULL, 2);

    return  VclPtr<ChartElementsPanel>::Create(
                        pParent, rxFrame, pBindings, pController);
}

void ChartElementsPanel::DataChanged(
    const DataChangedEvent& )
{
    updateData();
}

void ChartElementsPanel::HandleContextChange(
    const ::sfx2::sidebar::EnumContext& rContext)
{
    if(maContext == rContext)
    {
        // Nothing to do.
        return;
    }

    maContext = rContext;
    updateData();
}

void ChartElementsPanel::NotifyItemUpdate(
    sal_uInt16 /*nSID*/,
    SfxItemState /*eState*/,
    const SfxPoolItem* /*pState*/,
    const bool )
{
}

}} // end of namespace ::chart::sidebar

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>wire gridlines in chart elements panel<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <sfx2/sidebar/ResourceDefinitions.hrc>
#include <sfx2/sidebar/Theme.hxx>
#include <sfx2/sidebar/ControlFactory.hxx>
#include "ChartElementsPanel.hxx"
#include "ChartController.hxx"
#include <sfx2/bindings.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/imagemgr.hxx>
#include <vcl/fixed.hxx>
#include <vcl/lstbox.hxx>
#include <vcl/field.hxx>
#include <vcl/toolbox.hxx>
#include <svl/intitem.hxx>
#include <svl/stritem.hxx>

#include "LegendHelper.hxx"
#include "TitleHelper.hxx"
#include "ChartModelHelper.hxx"
#include "AxisHelper.hxx"

#include "ChartModel.hxx"

using namespace css;
using namespace css::uno;
using ::sfx2::sidebar::Theme;

namespace chart { namespace sidebar {

namespace {

enum class GridType
{
    VERT_MAJOR,
    VERT_MINOR,
    HOR_MAJOR,
    HOR_MINOR
};

ChartModel* getChartModel(css::uno::Reference<css::frame::XModel> xModel)
{
    ChartModel* pModel = dynamic_cast<ChartModel*>(xModel.get());

    return pModel;
}

bool isLegendVisible(css::uno::Reference<css::frame::XModel> xModel)
{
    ChartModel* pModel = getChartModel(xModel);
    if (!pModel)
        return false;

    Reference< beans::XPropertySet > xLegendProp( LegendHelper::getLegend(*pModel), uno::UNO_QUERY );
    if( xLegendProp.is())
    {
        try
        {
            bool bShow = false;
            if( xLegendProp->getPropertyValue( "Show") >>= bShow )
            {
                return bShow;
            }
        }
        catch(const uno::Exception &)
        {
        }
    }

    return false;
}

bool isTitleVisisble(css::uno::Reference<css::frame::XModel> xModel, TitleHelper::eTitleType eTitle)
{
    return TitleHelper::getTitle(eTitle, xModel).is();
}

bool isGridVisible(css::uno::Reference<css::frame::XModel> xModel, GridType eType)
{
    Reference< chart2::XDiagram > xDiagram(ChartModelHelper::findDiagram(xModel));
    if(xDiagram.is())
    {
        sal_Int32 nDimensionIndex = 0;
        if (eType == GridType::HOR_MAJOR || eType == GridType::HOR_MINOR)
            nDimensionIndex = 1;
        sal_Int32 nCooSysIndex = 0;

        bool bMajor = (eType == GridType::HOR_MAJOR || eType == GridType::VERT_MAJOR);

        bool bHasGrid = AxisHelper::isGridShown(nDimensionIndex, nCooSysIndex, bMajor, xDiagram);
        return bHasGrid;
    }
    return false;
}

}

ChartElementsPanel::ChartElementsPanel(
    vcl::Window* pParent,
    const css::uno::Reference<css::frame::XFrame>& rxFrame,
    SfxBindings* pBindings,
    ChartController* pController)
  : PanelLayout(pParent, "ChartElementsPanel", "modules/schart/ui/sidebarelements.ui", rxFrame),
    mxFrame(rxFrame),
    maContext(),
    mpBindings(pBindings),
    mxModel(pController->getModel())
{
    get(mpCBTitle,  "checkbutton_title");
    get(mpCBSubtitle,  "checkbutton_subtitle");
    get(mpCBXAxis,  "checkbutton_x_axis");
    get(mpCBXAxisTitle,  "checkbutton_x_axis_title");
    get(mpCBYAxis,  "checkbutton_y_axis");
    get(mpCBYAxisTitle,  "checkbutton_y_axis_title");
    get(mpCBZAxis,  "checkbutton_z_axis");
    get(mpCBZAxisTitle,  "checkbutton_z_axis_title");
    get(mpCB2ndXAxis,  "checkbutton_2nd_x_axis");
    get(mpCB2ndXAxisTitle,  "checkbutton_2nd_x_axis_title");
    get(mpCB2ndYAxis,  "checkbutton_2nd_y_axis");
    get(mpCB2ndYAxisTitle,  "checkbutton_2nd_y_axis_title");
    get(mpCBLegend,  "checkbutton_legend");
    get(mpCBGridVertical,  "checkbutton_gridline_vertical");
    get(mpCBGridHorizontal,  "checkbutton_gridline_horizontal");
    get(mpCBShowLabel,  "checkbutton_label");
    get(mpCBTrendline,  "checkbutton_trendline");
}

ChartElementsPanel::~ChartElementsPanel()
{
    disposeOnce();
}

void ChartElementsPanel::dispose()
{
    mpCBTitle.clear();
    mpCBSubtitle.clear();
    mpCBXAxis.clear();
    mpCBXAxisTitle.clear();
    mpCBYAxis.clear();
    mpCBYAxisTitle.clear();
    mpCBZAxis.clear();
    mpCBZAxisTitle.clear();
    mpCB2ndXAxis.clear();
    mpCB2ndXAxisTitle.clear();
    mpCB2ndYAxis.clear();
    mpCB2ndYAxisTitle.clear();
    mpCBLegend.clear();
    mpCBGridVertical.clear();
    mpCBGridHorizontal.clear();
    mpCBShowLabel.clear();
    mpCBTrendline.clear();

    PanelLayout::dispose();
}

void ChartElementsPanel::Initialize()
{
    updateData();
}

void ChartElementsPanel::updateData()
{
    mpCBLegend->Check(isLegendVisible(mxModel));
    mpCBTitle->Check(isTitleVisisble(mxModel, TitleHelper::MAIN_TITLE));
    mpCBSubtitle->Check(isTitleVisisble(mxModel, TitleHelper::SUB_TITLE));
    mpCBXAxisTitle->Check(isTitleVisisble(mxModel, TitleHelper::X_AXIS_TITLE));
    mpCBYAxisTitle->Check(isTitleVisisble(mxModel, TitleHelper::Y_AXIS_TITLE));
    mpCBZAxisTitle->Check(isTitleVisisble(mxModel, TitleHelper::Z_AXIS_TITLE));
    mpCB2ndXAxisTitle->Check(isTitleVisisble(mxModel, TitleHelper::SECONDARY_X_AXIS_TITLE));
    mpCB2ndYAxisTitle->Check(isTitleVisisble(mxModel, TitleHelper::SECONDARY_Y_AXIS_TITLE));
    mpCBGridVertical->Check(isGridVisible(mxModel, GridType::VERT_MAJOR));
    mpCBGridHorizontal->Check(isGridVisible(mxModel, GridType::HOR_MAJOR));
}

VclPtr<vcl::Window> ChartElementsPanel::Create (
    vcl::Window* pParent,
    const css::uno::Reference<css::frame::XFrame>& rxFrame,
    SfxBindings* pBindings, ChartController* pController)
{
    if (pParent == NULL)
        throw lang::IllegalArgumentException("no parent Window given to ChartElementsPanel::Create", NULL, 0);
    if ( ! rxFrame.is())
        throw lang::IllegalArgumentException("no XFrame given to ChartElementsPanel::Create", NULL, 1);
    if (pBindings == NULL)
        throw lang::IllegalArgumentException("no SfxBindings given to ChartElementsPanel::Create", NULL, 2);

    return  VclPtr<ChartElementsPanel>::Create(
                        pParent, rxFrame, pBindings, pController);
}

void ChartElementsPanel::DataChanged(
    const DataChangedEvent& )
{
    updateData();
}

void ChartElementsPanel::HandleContextChange(
    const ::sfx2::sidebar::EnumContext& rContext)
{
    if(maContext == rContext)
    {
        // Nothing to do.
        return;
    }

    maContext = rContext;
    updateData();
}

void ChartElementsPanel::NotifyItemUpdate(
    sal_uInt16 /*nSID*/,
    SfxItemState /*eState*/,
    const SfxPoolItem* /*pState*/,
    const bool )
{
}

}} // end of namespace ::chart::sidebar

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>#include "input/Input.hpp"
#include "input/ControllableCamera.hpp"
#include "resources/ResourcesManager.hpp"
#include "graphics/GPU.hpp"
#include "graphics/Framebuffer.hpp"
#include "system/Config.hpp"
#include "system/System.hpp"
#include "system/Window.hpp"
#include "generation/Random.hpp"
#include "Common.hpp"

/**
 \defgroup Playground Playground
 \brief A basic playground for testing ideas.
 \ingroup Applications
 */

/**
 The main function of the playground.
 \param argc the number of input arguments.
 \param argv a pointer to the raw input arguments.
 \return a general error code.
 \ingroup Playground
 */
int main(int argc, char ** argv) {

	// First, init/parse/load configuration.
	RenderingConfig config(std::vector<std::string>(argv, argv + argc));
	if(config.showHelp()) {
		return 0;
	}

	Window window("Playground", config, false);

	if(!config.resourcesPath.empty()){
		Resources::manager().addResources(config.resourcesPath);
	}

	// Seed random generator.
	Random::seed();
	// Query the renderer identifier, and the supported GPU API version.
	std::string vendor, renderer, version, shaderVersion;
	GPU::deviceInfos(vendor, renderer, version, shaderVersion);
	Log::Info() << Log::GPU << "Vendor: " << vendor << "." << std::endl;
	Log::Info() << Log::GPU << "Internal renderer: " << renderer << "." << std::endl;
	Log::Info() << Log::GPU << "Versions: Driver: " << version << ", API: " << shaderVersion << "." << std::endl;

	// Query the extensions.
	const std::vector<std::string> extensions = GPU::supportedExtensions();
	// Log extensions.
	size_t extensionCount = extensions.size();
	for(const auto& ext : extensions){
		if(ext[0] == '-'){
			--extensionCount;
		}
	}

	if(!extensions.empty()) {
		Log::Info() << Log::GPU << "Extensions detected (" << extensionCount << "): " << std::endl;
		for(size_t i = 0; i < extensions.size(); ++i) {
			const bool isHeader = extensions[i][0] == '-';
			Log::Info() << (isHeader ? "\n" : "") << extensions[i] << (isHeader ? "\n" : ", ") << std::flush;
		}
		Log::Info() << std::endl;
	}
	const std::string titleHeader = "Extensions (" + std::to_string(extensionCount) + ")";

	GPU::setDepthState(true, TestFunction::LESS, true);
	GPU::setCullState(true, Faces::BACK);
	GPU::setBlendState(false);

	// Setup the timer.
	double timer		 = System::time();
	double fullTime		 = 0.0;
	double remainingTime = 0.0;
	const double dt		 = 1.0 / 120.0; // Small physics timestep.

	Program * program = Resources::manager().getProgram("object", "object_basic", "object_basic_random");
	const Mesh * mesh		= Resources::manager().getMesh("light_sphere", Storage::GPU);

	Program * program2 = Resources::manager().getProgram("object_basic_color");
	Mesh mesh2("Plane");
	mesh2.positions = {glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec3(0.5f, -0.5f, 0.5f), glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(-0.5f, 0.5f, 0.5f)};
	mesh2.colors = {glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, 0.0f, 0.0f)};
	mesh2.indices = {0, 1, 2, 0, 2, 3};
	mesh2.upload();

	Mesh mesh3("Triangle");
	mesh3.positions = {glm::vec3(-0.5f, -0.5f, 0.1f), glm::vec3(0.5f, -0.5f, 0.1f), glm::vec3(0.0f, 1.0f, 0.1f)};
	mesh3.colors = {glm::vec3(1.0f, 1.0f, 0.0f), glm::vec3(0.0f, 1.0f, 1.0f), glm::vec3(1.0f, 0.0f, 1.0f)};
	mesh3.indices = {0, 2, 1};
	mesh3.upload();

	ControllableCamera camera;

	camera.pose(glm::vec3(0.0f,0.0f,3.0f), glm::vec3(0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
	camera.projection(config.screenResolution[0] / config.screenResolution[1], 1.34f, 0.1f, 100.0f);
	bool showImGuiDemo = false;

	const Texture* tex = Resources::manager().getTexture("debug-grid", {Layout::RGBA16F, Filter::LINEAR_LINEAR, Wrap::CLAMP}, Storage::GPU);

	Texture tex2("textest");
	tex2.width = tex2.height = 8;
	tex2.depth = tex2.levels = 1;
	tex2.shape = TextureShape::D2;
	tex2.images.emplace_back(tex2.width, tex2.height, 4);
	auto& texData = tex2.images.back();

	uint count = 0;
	Descriptor desc = {Layout::RGBA8, Filter::LINEAR, Wrap::CLAMP};
	Framebuffer fb(400, 300, desc , true, "testfb");

	// Start the display/interaction loop.
	while(window.nextFrame()) {

		// Reload resources.
		if(Input::manager().triggered(Input::Key::P)) {
			Resources::manager().reload();
		}

		// Compute the time elapsed since last frame
		const double currentTime = System::time();
		double frameTime		 = currentTime - timer;
		timer					 = currentTime;

		camera.update();

		// Physics simulation
		// First avoid super high frametime by clamping.
		if(frameTime > 0.2) {
			frameTime = 0.2;
		}
		// Accumulate new frame time.
		remainingTime += frameTime;
		// Instead of bounding at dt, we lower our requirement (1 order of magnitude).
		while(remainingTime > 0.2 * dt) {
			double deltaTime = fmin(remainingTime, dt);
			// Update physics and camera.
			camera.physics(deltaTime);
			// Update timers.
			fullTime += deltaTime;
			remainingTime -= deltaTime;
		}

		if(Input::manager().resized()){
			fb.resize(Input::manager().size());
		}

		// Render.
		const glm::ivec2 screenSize = Input::manager().size();
		const glm::mat4 MVP		   = camera.projection() * camera.view();
		fb.bind(glm::vec4(0.2f, 0.3f, 0.25f, 1.0f), 1.0f);
		GPU::setViewport(0, 0, screenSize[0], screenSize[1]);
		program->use();
		program->uniform("mvp", MVP);
		//GPU::drawMesh(*mesh);
		//GPU::setBlendState(true, BlendEquation::ADD, BlendFunction::SRC_ALPHA, BlendFunction::ONE_MINUS_SRC_ALPHA);

		for(uint dy = 0; dy < tex2.height; ++dy){
			for(uint dx = 0; dx < tex2.width; ++dx){
				float r = 0.0f; float g = 0.0f; float b = 0.0f;
				uint x = (dx + count)%8;
				uint y = (dy + count)%8;
				if(x < 2){
					r = 1.0f;
				} else if (x < 4){
					g = 1.0f;
				} else if(x < 6){
					b = 1.0f;
				}
				if(y < 2){
					b = 0.5f;
				} else if (y < 4){
					r = 0.5f;
				} else if(y < 6){
					g = 0.5f;
				}
				r = float(count % 60)/60.0f;
				texData.rgba(x,y) = glm::vec4(r,g,b,0.5f);
			}
		}
		++count;
		tex2.upload({Layout::RGBA32F, Filter::NEAREST_LINEAR, Wrap::CLAMP}, true);

		program2->use();
		program2->uniform("mvp", MVP);
		program2->uniform("color", glm::vec3(1.0f, 0.5f, 0.0f));
		program2->texture(tex, 0);
		GPU::drawMesh(mesh2);
		//GPU::setCullState(true, Faces::BACK);
		//GPU::setBlendState(false);
		float angle = float(count % 360)/360.0 * glm::two_pi<float>();
		glm::mat3 rot = glm::mat3(glm::rotate(glm::mat4(1.0f), angle, glm::vec3(0.0f, 0.0f, 1.0f)));

		mesh3.positions.clear();
		mesh3.positions = {rot * glm::vec3(-0.5f, -0.5f, 0.1f), rot * glm::vec3(0.5f, -0.5f, 0.1f), rot * glm::vec3(0.0f, 1.0f, 0.1f)};
		mesh3.upload();

		program2->texture(tex2, 0);
		program2->uniform("color", glm::vec3(0.0f, 0.5f, 1.0f));
		GPU::drawMesh(mesh3);

		//GPU::setViewport(screenSize[0]/2, 0, screenSize[0]/2, screenSize[1]);
		//GPU::drawMesh(mesh2);
		//GPU::drawMesh(mesh3);

		//Framebuffer::backbuffer()->bind();

		ImGui::Text("ImGui is functional!");
		ImGui::SameLine();
		ImGui::Checkbox("Show demo", &showImGuiDemo);
		ImGui::Text("%.1f ms, %.1f fps", frameTime * 1000.0f, 1.0f/frameTime);
		ImGui::Separator();

		ImGui::Text("OpengGL vendor: %s", vendor.c_str());
		ImGui::Text("Internal renderer: %s", renderer.c_str());
		ImGui::Text("Versions: Driver: %s, GLSL: %s", version.c_str(), shaderVersion.c_str());
		if(ImGui::CollapsingHeader(titleHeader.c_str())) {
			for(const auto & ext : extensions) {
				ImGui::Text("%s", ext.c_str());
			}
		}

		if(showImGuiDemo) {
			ImGui::ShowDemoWindow();
		}

	}

	return 0;
}
<commit_msg>Playground: update test loop.<commit_after>#include "input/Input.hpp"
#include "input/ControllableCamera.hpp"
#include "resources/ResourcesManager.hpp"
#include "graphics/GPU.hpp"
#include "graphics/Framebuffer.hpp"
#include "system/Config.hpp"
#include "system/System.hpp"
#include "system/Window.hpp"
#include "generation/Random.hpp"
#include "Common.hpp"

/**
 \defgroup Playground Playground
 \brief A basic playground for testing ideas.
 \ingroup Applications
 */

/**
 The main function of the playground.
 \param argc the number of input arguments.
 \param argv a pointer to the raw input arguments.
 \return a general error code.
 \ingroup Playground
 */
int main(int argc, char ** argv) {

	// First, init/parse/load configuration.
	RenderingConfig config(std::vector<std::string>(argv, argv + argc));
	if(config.showHelp()) {
		return 0;
	}

	Window window("Playground", config, false);

	if(!config.resourcesPath.empty()){
		Resources::manager().addResources(config.resourcesPath);
	}

	// Seed random generator.
	Random::seed();
	// Query the renderer identifier, and the supported GPU API version.
	std::string vendor, renderer, version, shaderVersion;
	GPU::deviceInfos(vendor, renderer, version, shaderVersion);
	Log::Info() << Log::GPU << "Vendor: " << vendor << "." << std::endl;
	Log::Info() << Log::GPU << "Internal renderer: " << renderer << "." << std::endl;
	Log::Info() << Log::GPU << "Versions: Driver: " << version << ", API: " << shaderVersion << "." << std::endl;

	// Query the extensions.
	const std::vector<std::string> extensions = GPU::supportedExtensions();
	// Log extensions.
	size_t extensionCount = extensions.size();
	for(const auto& ext : extensions){
		if(ext[0] == '-'){
			--extensionCount;
		}
	}

	if(!extensions.empty()) {
		Log::Info() << Log::GPU << "Extensions detected (" << extensionCount << "): " << std::endl;
		for(size_t i = 0; i < extensions.size(); ++i) {
			const bool isHeader = extensions[i][0] == '-';
			Log::Info() << (isHeader ? "\n" : "") << extensions[i] << (isHeader ? "\n" : ", ") << std::flush;
		}
		Log::Info() << std::endl;
	}
	const std::string titleHeader = "Extensions (" + std::to_string(extensionCount) + ")";

	GPU::setDepthState(true, TestFunction::LESS, true);
	GPU::setCullState(true, Faces::BACK);
	GPU::setBlendState(false);

	// Setup the timer.
	double timer		 = System::time();
	double fullTime		 = 0.0;
	double remainingTime = 0.0;
	const double dt		 = 1.0 / 120.0; // Small physics timestep.

	Program * program = Resources::manager().getProgram("object", "object_basic", "object_basic_random");
	const Mesh * mesh		= Resources::manager().getMesh("light_sphere", Storage::GPU);

	Program * program2 = Resources::manager().getProgram("object_basic_color");
	Mesh mesh2("Plane");
	mesh2.positions = {glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec3(0.5f, -0.5f, 0.5f), glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(-0.5f, 0.5f, 0.5f)};
	mesh2.colors = {glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, 0.0f, 0.0f)};
	mesh2.indices = {0, 1, 2, 0, 2, 3};
	mesh2.upload();

	Mesh mesh3("Triangle");
	mesh3.positions = {glm::vec3(-0.5f, -0.5f, 0.1f), glm::vec3(0.5f, -0.5f, 0.1f), glm::vec3(0.0f, 1.0f, 0.1f)};
	mesh3.colors = {glm::vec3(1.0f, 1.0f, 0.0f), glm::vec3(0.0f, 1.0f, 1.0f), glm::vec3(1.0f, 0.0f, 1.0f)};
	mesh3.indices = {0, 2, 1};
	mesh3.upload();

	ControllableCamera camera;

	camera.pose(glm::vec3(0.0f,0.0f,3.0f), glm::vec3(0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
	camera.projection(config.screenResolution[0] / config.screenResolution[1], 1.34f, 0.1f, 100.0f);
	bool showImGuiDemo = false;

	const Texture* tex = Resources::manager().getTexture("debug-grid", {Layout::RGBA16F, Filter::LINEAR_LINEAR, Wrap::CLAMP}, Storage::GPU);

	Texture tex2("textest");
	tex2.width = tex2.height = 8;
	tex2.depth = tex2.levels = 1;
	tex2.shape = TextureShape::D2;
	tex2.images.emplace_back(tex2.width, tex2.height, 4);
	auto& texData = tex2.images.back();

	uint count = 0;
	Descriptor desc = {Layout::RGBA8, Filter::LINEAR, Wrap::CLAMP};
	Framebuffer fb(400, 300, desc , true, "testfb");

	// Start the display/interaction loop.
	while(window.nextFrame()) {

		// Reload resources.
		if(Input::manager().triggered(Input::Key::P)) {
			Resources::manager().reload();
		}

		// Compute the time elapsed since last frame
		const double currentTime = System::time();
		double frameTime		 = currentTime - timer;
		timer					 = currentTime;

		camera.update();

		// Physics simulation
		// First avoid super high frametime by clamping.
		if(frameTime > 0.2) {
			frameTime = 0.2;
		}
		// Accumulate new frame time.
		remainingTime += frameTime;
		// Instead of bounding at dt, we lower our requirement (1 order of magnitude).
		while(remainingTime > 0.2 * dt) {
			double deltaTime = fmin(remainingTime, dt);
			// Update physics and camera.
			camera.physics(deltaTime);
			// Update timers.
			fullTime += deltaTime;
			remainingTime -= deltaTime;
		}

		if(Input::manager().resized()){
			fb.resize(Input::manager().size());
		}

		// Render.
		const glm::ivec2 screenSize = Input::manager().size();
		const glm::mat4 MVP		   = camera.projection() * camera.view();
		fb.bind(glm::vec4(0.2f, 0.3f, 0.25f, 1.0f), 1.0f, Framebuffer::Operation::DONTCARE);

		fb.setViewport();

		program->use();
		program->uniform("mvp", MVP);
		//GPU::drawMesh(*mesh);
		//GPU::setBlendState(true, BlendEquation::ADD, BlendFunction::SRC_ALPHA, BlendFunction::ONE_MINUS_SRC_ALPHA);

		for(uint dy = 0; dy < tex2.height; ++dy){
			for(uint dx = 0; dx < tex2.width; ++dx){
				float r = 0.0f; float g = 0.0f; float b = 0.0f;
				uint x = (dx + count)%8;
				uint y = (dy + count)%8;
				if(x < 2){
					r = 1.0f;
				} else if (x < 4){
					g = 1.0f;
				} else if(x < 6){
					b = 1.0f;
				}
				if(y < 2){
					b = 0.5f;
				} else if (y < 4){
					r = 0.5f;
				} else if(y < 6){
					g = 0.5f;
				}
				r = float(count % 60)/60.0f;
				texData.rgba(x,y) = glm::vec4(r,g,b,0.5f);
			}
		}
		++count;
		tex2.upload({Layout::RGBA32F, Filter::NEAREST_LINEAR, Wrap::CLAMP}, true);

		program2->use();
		program2->uniform("mvp", MVP);
		program2->uniform("color", glm::vec3(1.0f, 0.5f, 0.0f));
		program2->texture(tex, 0);
		GPU::drawMesh(mesh2);
		//GPU::setCullState(true, Faces::BACK);
		//GPU::setBlendState(false);
		float angle = float(count % 360)/360.0 * glm::two_pi<float>();
		glm::mat3 rot = glm::mat3(glm::rotate(glm::mat4(1.0f), angle, glm::vec3(0.0f, 0.0f, 1.0f)));

		mesh3.positions.clear();
		mesh3.positions = {rot * glm::vec3(-0.5f, -0.5f, 0.1f), rot * glm::vec3(0.5f, -0.5f, 0.1f), rot * glm::vec3(0.0f, 1.0f, 0.1f)};
		mesh3.upload();

		program2->texture(tex2, 0);
		program2->uniform("color", glm::vec3(0.0f, 0.5f, 1.0f));
		GPU::drawMesh(mesh3);

		//GPU::setViewport(screenSize[0]/2, 0, screenSize[0]/2, screenSize[1]);
		//GPU::drawMesh(mesh2);
		//GPU::drawMesh(mesh3);

		//Framebuffer::backbuffer()->bind(glm::vec4(1.0f, 0.5f, 0.2f, 1.0f), 1.0f, Framebuffer::Operation::DONTCARE);
		//Framebuffer::backbuffer()->setViewport();
		GPU::blit(fb, *Framebuffer::backbuffer(), Filter::LINEAR);

		ImGui::Text("ImGui is functional!");
		ImGui::SameLine();
		ImGui::Checkbox("Show demo", &showImGuiDemo);
		ImGui::Text("%.1f ms, %.1f fps", frameTime * 1000.0f, 1.0f/frameTime);
		ImGui::Separator();

		ImGui::Text("OpengGL vendor: %s", vendor.c_str());
		ImGui::Text("Internal renderer: %s", renderer.c_str());
		ImGui::Text("Versions: Driver: %s, GLSL: %s", version.c_str(), shaderVersion.c_str());
		if(ImGui::CollapsingHeader(titleHeader.c_str())) {
			for(const auto & ext : extensions) {
				ImGui::Text("%s", ext.c_str());
			}
		}

		if(showImGuiDemo) {
			ImGui::ShowDemoWindow();
		}

	}

	return 0;
}
<|endoftext|>


<commit_before><commit_msg>handle all kinds of condition entries correctly in the dialog<commit_after><|endoftext|>


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

#include "chrome/browser/automation/url_request_automation_job.h"

#include "base/message_loop.h"
#include "base/time.h"
#include "chrome/browser/automation/automation_resource_message_filter.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host_request_info.h"
#include "chrome/test/automation/automation_messages.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/http/http_util.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"

using base::Time;
using base::TimeDelta;

// The list of filtered headers that are removed from requests sent via
// StartAsync(). These must be lower case.
static const char* kFilteredHeaderStrings[] = {
  "accept",
  "authorization",
  "cache-control",
  "connection",
  "cookie",
  "expect",
  "if-match",
  "if-modified-since",
  "if-none-match",
  "if-range",
  "if-unmodified-since",
  "max-forwards",
  "proxy-authorization",
  "te",
  "upgrade",
  "via"
};

// This class manages the interception of network requests for automation.
// It looks at the request, and creates an intercept job if it indicates
// that it should use automation channel.
// NOTE: All methods must be called on the IO thread.
class AutomationRequestInterceptor : public URLRequest::Interceptor {
 public:
  AutomationRequestInterceptor() {
    URLRequest::RegisterRequestInterceptor(this);
  }

  virtual ~AutomationRequestInterceptor() {
    URLRequest::UnregisterRequestInterceptor(this);
  }

  // URLRequest::Interceptor
  virtual URLRequestJob* MaybeIntercept(URLRequest* request);

 private:
  DISALLOW_COPY_AND_ASSIGN(AutomationRequestInterceptor);
};

URLRequestJob* AutomationRequestInterceptor::MaybeIntercept(
    URLRequest* request) {
  if (request->url().SchemeIs("http") || request->url().SchemeIs("https")) {
    ResourceDispatcherHostRequestInfo* request_info =
        ResourceDispatcherHost::InfoForRequest(request);
    if (request_info) {
      AutomationResourceMessageFilter::AutomationDetails details;
      if (AutomationResourceMessageFilter::LookupRegisteredRenderView(
              request_info->child_id(), request_info->route_id(), &details)) {
        URLRequestAutomationJob* job = new URLRequestAutomationJob(request,
            details.tab_handle, details.filter);
        return job;
      }
    }
  }

  return NULL;
}

static URLRequest::Interceptor* GetAutomationRequestInterceptor() {
  return Singleton<AutomationRequestInterceptor>::get();
}

int URLRequestAutomationJob::instance_count_ = 0;

URLRequestAutomationJob::URLRequestAutomationJob(
    URLRequest* request, int tab, AutomationResourceMessageFilter* filter)
    : URLRequestJob(request), id_(0), tab_(tab), message_filter_(filter),
      pending_buf_size_(0), redirect_status_(0) {
  DLOG(INFO) << "URLRequestAutomationJob create. Count: " << ++instance_count_;
  if (message_filter_) {
    id_ = message_filter_->NewRequestId();
    DCHECK(id_);
  } else {
    NOTREACHED();
  }
}

URLRequestAutomationJob::~URLRequestAutomationJob() {
  DLOG(INFO) << "URLRequestAutomationJob delete. Count: " << --instance_count_;
  Cleanup();
}

bool URLRequestAutomationJob::InitializeInterceptor() {
  // AutomationRequestInterceptor will register itself when it
  // is first created.
  URLRequest::Interceptor* interceptor = GetAutomationRequestInterceptor();
  return (interceptor != NULL);
}

// URLRequestJob Implementation.
void URLRequestAutomationJob::Start() {
  // Start reading asynchronously so that all error reporting and data
  // callbacks happen as they would for network requests.
  MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
      this, &URLRequestAutomationJob::StartAsync));
}

void URLRequestAutomationJob::Kill() {
  if (message_filter_.get()) {
    message_filter_->Send(new AutomationMsg_RequestEnd(0, tab_, id_,
        URLRequestStatus(URLRequestStatus::CANCELED, 0)));
  }
  DisconnectFromMessageFilter();
  URLRequestJob::Kill();
}

bool URLRequestAutomationJob::ReadRawData(
    net::IOBuffer* buf, int buf_size, int* bytes_read) {
  DLOG(INFO) << "URLRequestAutomationJob: " <<
      request_->url().spec() << " - read pending: " << buf_size;
  pending_buf_ = buf;
  pending_buf_size_ = buf_size;

  message_filter_->Send(new AutomationMsg_RequestRead(0, tab_, id_,
      buf_size));
  SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0));
  return false;
}

bool URLRequestAutomationJob::GetMimeType(std::string* mime_type) const {
  if (!mime_type_.empty()) {
    *mime_type = mime_type_;
  } else if (headers_) {
    headers_->GetMimeType(mime_type);
  }

  return (!mime_type->empty());
}

bool URLRequestAutomationJob::GetCharset(std::string* charset) {
  if (headers_)
    return headers_->GetCharset(charset);
  return false;
}

void URLRequestAutomationJob::GetResponseInfo(net::HttpResponseInfo* info) {
  if (headers_)
    info->headers = headers_;
  if (request_->url().SchemeIsSecure()) {
    // Make up a fake certificate for this response since we don't have
    // access to the real SSL info.
    const char* kCertIssuer = "Chrome Internal";
    const int kLifetimeDays = 100;

    info->ssl_info.cert =
        new net::X509Certificate(request_->url().GetWithEmptyPath().spec(),
                                 kCertIssuer,
                                 Time::Now(),
                                 Time::Now() +
                                     TimeDelta::FromDays(kLifetimeDays));
    info->ssl_info.cert_status = 0;
    info->ssl_info.security_bits = 0;
  }
}

int URLRequestAutomationJob::GetResponseCode() const {
  if (headers_)
    return headers_->response_code();

  static const int kDefaultResponseCode = 200;
  return kDefaultResponseCode;
}

bool URLRequestAutomationJob::IsRedirectResponse(
    GURL* location, int* http_status_code) {
  static const int kDefaultHttpRedirectResponseCode = 301;

  if (!redirect_url_.empty()) {
    DLOG_IF(ERROR, redirect_status_ == 0) << "Missing redirect status?";
    *http_status_code = redirect_status_ ? redirect_status_ :
                                           kDefaultHttpRedirectResponseCode;
    *location = GURL(redirect_url_);
    return true;
  } else {
    DCHECK(redirect_status_ == 0)
        << "Unexpectedly have redirect status but no URL";
  }

  return false;
}

int URLRequestAutomationJob::MayFilterMessage(const IPC::Message& message) {
  switch (message.type()) {
    case AutomationMsg_RequestStarted::ID:
    case AutomationMsg_RequestData::ID:
    case AutomationMsg_RequestEnd::ID: {
      void* iter = NULL;
      int tab = 0;
      int id = 0;
      if (message.ReadInt(&iter, &tab) && message.ReadInt(&iter, &id)) {
        DCHECK(id);
        return id;
      }
      break;
    }
  }

  return 0;
}

void URLRequestAutomationJob::OnMessage(const IPC::Message& message) {
  IPC_BEGIN_MESSAGE_MAP(URLRequestAutomationJob, message)
    IPC_MESSAGE_HANDLER(AutomationMsg_RequestStarted, OnRequestStarted)
    IPC_MESSAGE_HANDLER(AutomationMsg_RequestData, OnDataAvailable)
    IPC_MESSAGE_HANDLER(AutomationMsg_RequestEnd, OnRequestEnd)
  IPC_END_MESSAGE_MAP()
}

void URLRequestAutomationJob::OnRequestStarted(
    int tab, int id, const IPC::AutomationURLResponse& response) {
  DLOG(INFO) << "URLRequestAutomationJob: " <<
      request_->url().spec() << " - response started.";
  set_expected_content_size(response.content_length);
  mime_type_ = response.mime_type;

  redirect_url_ = response.redirect_url;
  redirect_status_ = response.redirect_status;
  DCHECK(redirect_status_ == 0 || redirect_status_ == 200 ||
         (redirect_status_ >= 300 && redirect_status_ < 400));

  GURL url_for_cookies =
      GURL(redirect_url_.empty() ? request_->url().spec().c_str() :
          redirect_url_.c_str());

  URLRequestContext* ctx = request_->context();

  if (!response.headers.empty()) {
    headers_ = new net::HttpResponseHeaders(
        net::HttpUtil::AssembleRawHeaders(response.headers.data(),
                                          response.headers.size()));
    // Parse and set HTTP cookies.
    const std::string name = "Set-Cookie";
    std::string value;
    std::vector<std::string> response_cookies;

    void* iter = NULL;
    while (headers_->EnumerateHeader(&iter, name, &value)) {
      if (request_->context()->InterceptCookie(request_, &value))
        response_cookies.push_back(value);
    }

    if (response_cookies.size()) {
      if (ctx && ctx->cookie_store() &&
          ctx->cookie_policy()->CanSetCookie(
              url_for_cookies, request_->first_party_for_cookies())) {
        net::CookieOptions options;
        options.set_include_httponly();
        ctx->cookie_store()->SetCookiesWithOptions(url_for_cookies,
                                                   response_cookies,
                                                   options);
      }
    }
  }

  if (ctx && ctx->cookie_store() && !response.persistent_cookies.empty() &&
      ctx->cookie_policy()->CanSetCookie(
          url_for_cookies, request_->first_party_for_cookies())) {
    StringTokenizer cookie_parser(response.persistent_cookies, ";");

    while (cookie_parser.GetNext()) {
      net::CookieOptions options;
      ctx->cookie_store()->SetCookieWithOptions(url_for_cookies,
                                                cookie_parser.token(),
                                                options);
    }
  }

  NotifyHeadersComplete();
}

void URLRequestAutomationJob::OnDataAvailable(
    int tab, int id, const std::string& bytes) {
  DLOG(INFO) << "URLRequestAutomationJob: " <<
      request_->url().spec() << " - data available, Size: " << bytes.size();
  DCHECK(!bytes.empty());

  // The request completed, and we have all the data.
  // Clear any IO pending status.
  SetStatus(URLRequestStatus());

  if (pending_buf_ && pending_buf_->data()) {
    DCHECK_GE(pending_buf_size_, bytes.size());
    const int bytes_to_copy = std::min(bytes.size(), pending_buf_size_);
    memcpy(pending_buf_->data(), &bytes[0], bytes_to_copy);

    pending_buf_ = NULL;
    pending_buf_size_ = 0;

    NotifyReadComplete(bytes_to_copy);
  }
}

void URLRequestAutomationJob::OnRequestEnd(
    int tab, int id, const URLRequestStatus& status) {
  DLOG(INFO) << "URLRequestAutomationJob: " <<
      request_->url().spec() << " - request end. Status: " << status.status();

  // TODO(tommi): When we hit certificate errors, notify the delegate via
  // OnSSLCertificateError().  Right now we don't have the certificate
  // so we don't.  We could possibly call OnSSLCertificateError with a NULL
  // certificate, but I'm not sure if all implementations expect it.
  // if (status.status() == URLRequestStatus::FAILED &&
  //    net::IsCertificateError(status.os_error()) && request_->delegate()) {
  //  request_->delegate()->OnSSLCertificateError(request_, status.os_error(),
  //                                              NULL);
  // }

  DisconnectFromMessageFilter();
  NotifyDone(status);

  // Reset any pending reads.
  if (pending_buf_) {
    pending_buf_ = NULL;
    pending_buf_size_ = 0;
    NotifyReadComplete(0);
  }
}

void URLRequestAutomationJob::Cleanup() {
  headers_ = NULL;
  mime_type_.erase();

  id_ = 0;
  tab_ = 0;

  DCHECK(message_filter_ == NULL);
  DisconnectFromMessageFilter();

  pending_buf_ = NULL;
  pending_buf_size_ = 0;
}

void URLRequestAutomationJob::StartAsync() {
  DLOG(INFO) << "URLRequestAutomationJob: start request: " <<
      (request_ ? request_->url().spec() : "NULL request");

  // If the job is cancelled before we got a chance to start it
  // we have nothing much to do here.
  if (is_done())
    return;

  if (!request_) {
    NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED,
        net::ERR_FAILED));
    return;
  }

  // Register this request with automation message filter.
  message_filter_->RegisterRequest(this);

  // Strip unwanted headers.
  std::string new_request_headers(
      net::HttpUtil::StripHeaders(request_->extra_request_headers(),
                                  kFilteredHeaderStrings,
                                  arraysize(kFilteredHeaderStrings)));

  // Ensure that we do not send username and password fields in the referrer.
  GURL referrer(request_->GetSanitizedReferrer());

  // The referrer header must be suppressed if the preceding URL was
  // a secure one and the new one is not.
  if (referrer.SchemeIsSecure() && !request_->url().SchemeIsSecure()) {
    DLOG(INFO) <<
        "Suppressing referrer header since going from secure to non-secure";
    referrer = GURL();
  }

  // Ask automation to start this request.
  IPC::AutomationURLRequest automation_request = {
    request_->url().spec(),
    request_->method(),
    referrer.spec(),
    new_request_headers,
    request_->get_upload()
  };

  DCHECK(message_filter_);
  message_filter_->Send(new AutomationMsg_RequestStart(0, tab_, id_,
      automation_request));
}

void URLRequestAutomationJob::DisconnectFromMessageFilter() {
  if (message_filter_) {
    message_filter_->UnRegisterRequest(this);
    message_filter_ = NULL;
  }
}
<commit_msg>Fix a dlog that could dereference a null pointer.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/automation/url_request_automation_job.h"

#include "base/message_loop.h"
#include "base/time.h"
#include "chrome/browser/automation/automation_resource_message_filter.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host_request_info.h"
#include "chrome/test/automation/automation_messages.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/http/http_util.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"

using base::Time;
using base::TimeDelta;

// The list of filtered headers that are removed from requests sent via
// StartAsync(). These must be lower case.
static const char* kFilteredHeaderStrings[] = {
  "accept",
  "authorization",
  "cache-control",
  "connection",
  "cookie",
  "expect",
  "if-match",
  "if-modified-since",
  "if-none-match",
  "if-range",
  "if-unmodified-since",
  "max-forwards",
  "proxy-authorization",
  "te",
  "upgrade",
  "via"
};

// This class manages the interception of network requests for automation.
// It looks at the request, and creates an intercept job if it indicates
// that it should use automation channel.
// NOTE: All methods must be called on the IO thread.
class AutomationRequestInterceptor : public URLRequest::Interceptor {
 public:
  AutomationRequestInterceptor() {
    URLRequest::RegisterRequestInterceptor(this);
  }

  virtual ~AutomationRequestInterceptor() {
    URLRequest::UnregisterRequestInterceptor(this);
  }

  // URLRequest::Interceptor
  virtual URLRequestJob* MaybeIntercept(URLRequest* request);

 private:
  DISALLOW_COPY_AND_ASSIGN(AutomationRequestInterceptor);
};

URLRequestJob* AutomationRequestInterceptor::MaybeIntercept(
    URLRequest* request) {
  if (request->url().SchemeIs("http") || request->url().SchemeIs("https")) {
    ResourceDispatcherHostRequestInfo* request_info =
        ResourceDispatcherHost::InfoForRequest(request);
    if (request_info) {
      AutomationResourceMessageFilter::AutomationDetails details;
      if (AutomationResourceMessageFilter::LookupRegisteredRenderView(
              request_info->child_id(), request_info->route_id(), &details)) {
        URLRequestAutomationJob* job = new URLRequestAutomationJob(request,
            details.tab_handle, details.filter);
        return job;
      }
    }
  }

  return NULL;
}

static URLRequest::Interceptor* GetAutomationRequestInterceptor() {
  return Singleton<AutomationRequestInterceptor>::get();
}

int URLRequestAutomationJob::instance_count_ = 0;

URLRequestAutomationJob::URLRequestAutomationJob(
    URLRequest* request, int tab, AutomationResourceMessageFilter* filter)
    : URLRequestJob(request), id_(0), tab_(tab), message_filter_(filter),
      pending_buf_size_(0), redirect_status_(0) {
  DLOG(INFO) << "URLRequestAutomationJob create. Count: " << ++instance_count_;
  if (message_filter_) {
    id_ = message_filter_->NewRequestId();
    DCHECK(id_);
  } else {
    NOTREACHED();
  }
}

URLRequestAutomationJob::~URLRequestAutomationJob() {
  DLOG(INFO) << "URLRequestAutomationJob delete. Count: " << --instance_count_;
  Cleanup();
}

bool URLRequestAutomationJob::InitializeInterceptor() {
  // AutomationRequestInterceptor will register itself when it
  // is first created.
  URLRequest::Interceptor* interceptor = GetAutomationRequestInterceptor();
  return (interceptor != NULL);
}

// URLRequestJob Implementation.
void URLRequestAutomationJob::Start() {
  // Start reading asynchronously so that all error reporting and data
  // callbacks happen as they would for network requests.
  MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
      this, &URLRequestAutomationJob::StartAsync));
}

void URLRequestAutomationJob::Kill() {
  if (message_filter_.get()) {
    message_filter_->Send(new AutomationMsg_RequestEnd(0, tab_, id_,
        URLRequestStatus(URLRequestStatus::CANCELED, 0)));
  }
  DisconnectFromMessageFilter();
  URLRequestJob::Kill();
}

bool URLRequestAutomationJob::ReadRawData(
    net::IOBuffer* buf, int buf_size, int* bytes_read) {
  DLOG(INFO) << "URLRequestAutomationJob: " <<
      request_->url().spec() << " - read pending: " << buf_size;
  pending_buf_ = buf;
  pending_buf_size_ = buf_size;

  message_filter_->Send(new AutomationMsg_RequestRead(0, tab_, id_,
      buf_size));
  SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0));
  return false;
}

bool URLRequestAutomationJob::GetMimeType(std::string* mime_type) const {
  if (!mime_type_.empty()) {
    *mime_type = mime_type_;
  } else if (headers_) {
    headers_->GetMimeType(mime_type);
  }

  return (!mime_type->empty());
}

bool URLRequestAutomationJob::GetCharset(std::string* charset) {
  if (headers_)
    return headers_->GetCharset(charset);
  return false;
}

void URLRequestAutomationJob::GetResponseInfo(net::HttpResponseInfo* info) {
  if (headers_)
    info->headers = headers_;
  if (request_->url().SchemeIsSecure()) {
    // Make up a fake certificate for this response since we don't have
    // access to the real SSL info.
    const char* kCertIssuer = "Chrome Internal";
    const int kLifetimeDays = 100;

    info->ssl_info.cert =
        new net::X509Certificate(request_->url().GetWithEmptyPath().spec(),
                                 kCertIssuer,
                                 Time::Now(),
                                 Time::Now() +
                                     TimeDelta::FromDays(kLifetimeDays));
    info->ssl_info.cert_status = 0;
    info->ssl_info.security_bits = 0;
  }
}

int URLRequestAutomationJob::GetResponseCode() const {
  if (headers_)
    return headers_->response_code();

  static const int kDefaultResponseCode = 200;
  return kDefaultResponseCode;
}

bool URLRequestAutomationJob::IsRedirectResponse(
    GURL* location, int* http_status_code) {
  static const int kDefaultHttpRedirectResponseCode = 301;

  if (!redirect_url_.empty()) {
    DLOG_IF(ERROR, redirect_status_ == 0) << "Missing redirect status?";
    *http_status_code = redirect_status_ ? redirect_status_ :
                                           kDefaultHttpRedirectResponseCode;
    *location = GURL(redirect_url_);
    return true;
  } else {
    DCHECK(redirect_status_ == 0)
        << "Unexpectedly have redirect status but no URL";
  }

  return false;
}

int URLRequestAutomationJob::MayFilterMessage(const IPC::Message& message) {
  switch (message.type()) {
    case AutomationMsg_RequestStarted::ID:
    case AutomationMsg_RequestData::ID:
    case AutomationMsg_RequestEnd::ID: {
      void* iter = NULL;
      int tab = 0;
      int id = 0;
      if (message.ReadInt(&iter, &tab) && message.ReadInt(&iter, &id)) {
        DCHECK(id);
        return id;
      }
      break;
    }
  }

  return 0;
}

void URLRequestAutomationJob::OnMessage(const IPC::Message& message) {
  IPC_BEGIN_MESSAGE_MAP(URLRequestAutomationJob, message)
    IPC_MESSAGE_HANDLER(AutomationMsg_RequestStarted, OnRequestStarted)
    IPC_MESSAGE_HANDLER(AutomationMsg_RequestData, OnDataAvailable)
    IPC_MESSAGE_HANDLER(AutomationMsg_RequestEnd, OnRequestEnd)
  IPC_END_MESSAGE_MAP()
}

void URLRequestAutomationJob::OnRequestStarted(
    int tab, int id, const IPC::AutomationURLResponse& response) {
  DLOG(INFO) << "URLRequestAutomationJob: " <<
      request_->url().spec() << " - response started.";
  set_expected_content_size(response.content_length);
  mime_type_ = response.mime_type;

  redirect_url_ = response.redirect_url;
  redirect_status_ = response.redirect_status;
  DCHECK(redirect_status_ == 0 || redirect_status_ == 200 ||
         (redirect_status_ >= 300 && redirect_status_ < 400));

  GURL url_for_cookies =
      GURL(redirect_url_.empty() ? request_->url().spec().c_str() :
          redirect_url_.c_str());

  URLRequestContext* ctx = request_->context();

  if (!response.headers.empty()) {
    headers_ = new net::HttpResponseHeaders(
        net::HttpUtil::AssembleRawHeaders(response.headers.data(),
                                          response.headers.size()));
    // Parse and set HTTP cookies.
    const std::string name = "Set-Cookie";
    std::string value;
    std::vector<std::string> response_cookies;

    void* iter = NULL;
    while (headers_->EnumerateHeader(&iter, name, &value)) {
      if (request_->context()->InterceptCookie(request_, &value))
        response_cookies.push_back(value);
    }

    if (response_cookies.size()) {
      if (ctx && ctx->cookie_store() &&
          ctx->cookie_policy()->CanSetCookie(
              url_for_cookies, request_->first_party_for_cookies())) {
        net::CookieOptions options;
        options.set_include_httponly();
        ctx->cookie_store()->SetCookiesWithOptions(url_for_cookies,
                                                   response_cookies,
                                                   options);
      }
    }
  }

  if (ctx && ctx->cookie_store() && !response.persistent_cookies.empty() &&
      ctx->cookie_policy()->CanSetCookie(
          url_for_cookies, request_->first_party_for_cookies())) {
    StringTokenizer cookie_parser(response.persistent_cookies, ";");

    while (cookie_parser.GetNext()) {
      net::CookieOptions options;
      ctx->cookie_store()->SetCookieWithOptions(url_for_cookies,
                                                cookie_parser.token(),
                                                options);
    }
  }

  NotifyHeadersComplete();
}

void URLRequestAutomationJob::OnDataAvailable(
    int tab, int id, const std::string& bytes) {
  DLOG(INFO) << "URLRequestAutomationJob: " <<
      request_->url().spec() << " - data available, Size: " << bytes.size();
  DCHECK(!bytes.empty());

  // The request completed, and we have all the data.
  // Clear any IO pending status.
  SetStatus(URLRequestStatus());

  if (pending_buf_ && pending_buf_->data()) {
    DCHECK_GE(pending_buf_size_, bytes.size());
    const int bytes_to_copy = std::min(bytes.size(), pending_buf_size_);
    memcpy(pending_buf_->data(), &bytes[0], bytes_to_copy);

    pending_buf_ = NULL;
    pending_buf_size_ = 0;

    NotifyReadComplete(bytes_to_copy);
  }
}

void URLRequestAutomationJob::OnRequestEnd(
    int tab, int id, const URLRequestStatus& status) {
  DLOG(INFO) << "URLRequestAutomationJob: "
      << request_ ? request_->url().spec().c_str() : "(null)"
      << " - request end. Status: " << status.status();

  // TODO(tommi): When we hit certificate errors, notify the delegate via
  // OnSSLCertificateError().  Right now we don't have the certificate
  // so we don't.  We could possibly call OnSSLCertificateError with a NULL
  // certificate, but I'm not sure if all implementations expect it.
  // if (status.status() == URLRequestStatus::FAILED &&
  //    net::IsCertificateError(status.os_error()) && request_->delegate()) {
  //  request_->delegate()->OnSSLCertificateError(request_, status.os_error(),
  //                                              NULL);
  // }

  DisconnectFromMessageFilter();
  NotifyDone(status);

  // Reset any pending reads.
  if (pending_buf_) {
    pending_buf_ = NULL;
    pending_buf_size_ = 0;
    NotifyReadComplete(0);
  }
}

void URLRequestAutomationJob::Cleanup() {
  headers_ = NULL;
  mime_type_.erase();

  id_ = 0;
  tab_ = 0;

  DCHECK(message_filter_ == NULL);
  DisconnectFromMessageFilter();

  pending_buf_ = NULL;
  pending_buf_size_ = 0;
}

void URLRequestAutomationJob::StartAsync() {
  DLOG(INFO) << "URLRequestAutomationJob: start request: " <<
      (request_ ? request_->url().spec() : "NULL request");

  // If the job is cancelled before we got a chance to start it
  // we have nothing much to do here.
  if (is_done())
    return;

  if (!request_) {
    NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED,
        net::ERR_FAILED));
    return;
  }

  // Register this request with automation message filter.
  message_filter_->RegisterRequest(this);

  // Strip unwanted headers.
  std::string new_request_headers(
      net::HttpUtil::StripHeaders(request_->extra_request_headers(),
                                  kFilteredHeaderStrings,
                                  arraysize(kFilteredHeaderStrings)));

  // Ensure that we do not send username and password fields in the referrer.
  GURL referrer(request_->GetSanitizedReferrer());

  // The referrer header must be suppressed if the preceding URL was
  // a secure one and the new one is not.
  if (referrer.SchemeIsSecure() && !request_->url().SchemeIsSecure()) {
    DLOG(INFO) <<
        "Suppressing referrer header since going from secure to non-secure";
    referrer = GURL();
  }

  // Ask automation to start this request.
  IPC::AutomationURLRequest automation_request = {
    request_->url().spec(),
    request_->method(),
    referrer.spec(),
    new_request_headers,
    request_->get_upload()
  };

  DCHECK(message_filter_);
  message_filter_->Send(new AutomationMsg_RequestStart(0, tab_, id_,
      automation_request));
}

void URLRequestAutomationJob::DisconnectFromMessageFilter() {
  if (message_filter_) {
    message_filter_->UnRegisterRequest(this);
    message_filter_ = NULL;
  }
}
<|endoftext|>


<commit_before><commit_msg>cairo_restore without matching cairo_save<commit_after><|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/ref_counted.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/extensions/autoupdate_interceptor.h"
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/extensions/extension_updater.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/ui_test_utils.h"

class ExtensionManagementTest : public ExtensionBrowserTest {
 protected:
  // Helper method that returns whether the extension is at the given version.
  // This calls version(), which must be defined in the extension's bg page,
  // as well as asking the extension itself.
  bool IsExtensionAtVersion(Extension* extension,
                            const std::string& expected_version) {
    // Test that the extension's version from the manifest and reported by the
    // background page is correct.  This is to ensure that the processes are in
    // sync with the Extension.
    ExtensionProcessManager* manager = browser()->profile()->
        GetExtensionProcessManager();
    ExtensionHost* ext_host = manager->GetBackgroundHostForExtension(extension);
    EXPECT_TRUE(ext_host);
    if (!ext_host)
      return false;

    std::string version_from_bg;
    bool exec = ui_test_utils::ExecuteJavaScriptAndExtractString(
        ext_host->render_view_host(), L"", L"version()", &version_from_bg);
    EXPECT_TRUE(exec);
    if (!exec)
      return false;

    if (version_from_bg != expected_version ||
        extension->VersionString() != expected_version)
      return false;
    return true;
  }

  // Helper method that installs a low permission extension then updates
  // to the second version requiring increased permissions. Returns whether
  // the operation was completed successfully.
  bool InstallAndUpdateIncreasingPermissionsExtension() {
    ExtensionsService* service = browser()->profile()->GetExtensionsService();
    TabContents* contents = browser()->GetSelectedTabContents();
    if (service->HasInstalledExtensions() || !contents)
      return false;

    // Install the initial version, which should happen just fine.
    if (!InstallExtension(
        test_data_dir_.AppendASCII("permissions-low-v1.crx"), 1))
      return false;
    EXPECT_EQ(0, contents->infobar_delegate_count());

    // Upgrade to a version that wants more permissions. We should disable the
    // extension and prompt the user to reenable.
    if (service->extensions()->size() != 1u)
      return false;
    if (!UpdateExtension(
        service->extensions()->at(0)->id(),
        test_data_dir_.AppendASCII("permissions-high-v2.crx"), -1))
      return false;
    EXPECT_EQ(1, contents->infobar_delegate_count());
    EXPECT_EQ(0u, service->extensions()->size());
    if (service->disabled_extensions()->size() != 1u)
      return false;
    return true;
  }
};

// Tests that installing the same version does not overwrite.
IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, InstallSameVersion) {
  ExtensionsService* service = browser()->profile()->GetExtensionsService();
  ASSERT_FALSE(service->HasInstalledExtensions());
  ASSERT_TRUE(InstallExtension(
      test_data_dir_.AppendASCII("install/install.crx"), 1));

  // Install an extension with the same version. The previous install should
  // be kept.
  ASSERT_TRUE(InstallExtension(
      test_data_dir_.AppendASCII("install/install_same_version.crx"), 0));
  EXPECT_TRUE(IsExtensionAtVersion(service->extensions()->at(0), "1.0"));
}

IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, InstallOlderVersion) {
  ExtensionsService* service = browser()->profile()->GetExtensionsService();
  ASSERT_FALSE(service->HasInstalledExtensions());
  ASSERT_TRUE(InstallExtension(
      test_data_dir_.AppendASCII("install/install.crx"), 1));
  ASSERT_TRUE(InstallExtension(
      test_data_dir_.AppendASCII("install/install_older_version.crx"), 0));
  EXPECT_TRUE(IsExtensionAtVersion(service->extensions()->at(0), "1.0"));
}

IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, InstallThenCancel) {
  ExtensionsService* service = browser()->profile()->GetExtensionsService();
  ASSERT_FALSE(service->HasInstalledExtensions());
  ASSERT_TRUE(InstallExtension(
      test_data_dir_.AppendASCII("install/install.crx"), 1));

  // Cancel this install.
  StartInstallButCancel(test_data_dir_.AppendASCII("install/install_v2.crx"));
  EXPECT_TRUE(IsExtensionAtVersion(service->extensions()->at(0), "1.0"));
}

// Tests that installing and uninstalling extensions don't crash with an
// incognito window open.
IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, Incognito) {
  // Open an incognito window to the extensions management page.  We just
  // want to make sure that we don't crash while playing with extensions when
  // this guy is around.
  ui_test_utils::OpenURLOffTheRecord(browser()->profile(),
                                     GURL(chrome::kChromeUIExtensionsURL));

  ASSERT_TRUE(InstallExtension(test_data_dir_.AppendASCII("good.crx"), 1));
  UninstallExtension("ldnnhddmnhbkjipkidpdiheffobcpfmf");
}

// Tests the process of updating an extension to one that requires higher
// permissions.
IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, UpdatePermissions) {
  ExtensionsService* service = browser()->profile()->GetExtensionsService();
  ASSERT_TRUE(InstallAndUpdateIncreasingPermissionsExtension());

  // Now try reenabling it, which should also dismiss the infobar.
  service->EnableExtension(service->disabled_extensions()->at(0)->id());
  TabContents* contents = browser()->GetSelectedTabContents();
  ASSERT_TRUE(contents);
  EXPECT_EQ(0, contents->infobar_delegate_count());
  EXPECT_EQ(1u, service->extensions()->size());
  EXPECT_EQ(0u, service->disabled_extensions()->size());
}

// Tests that we can uninstall a disabled extension.
IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, UninstallDisabled) {
  ExtensionsService* service = browser()->profile()->GetExtensionsService();
  ASSERT_TRUE(InstallAndUpdateIncreasingPermissionsExtension());

  // Now try uninstalling it.
  UninstallExtension(service->disabled_extensions()->at(0)->id());
  EXPECT_EQ(0u, service->extensions()->size());
  EXPECT_EQ(0u, service->disabled_extensions()->size());
  ASSERT_FALSE(service->HasInstalledExtensions());
}

// Tests that disabling and re-enabling an extension works.
IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, DisableEnable) {
  ExtensionProcessManager* manager = browser()->profile()->
      GetExtensionProcessManager();
  ExtensionsService* service = browser()->profile()->GetExtensionsService();

  // Load an extension, expect the background page to be available.
  ASSERT_FALSE(service->HasInstalledExtensions());
  ASSERT_TRUE(LoadExtension(
      test_data_dir_.AppendASCII("good").AppendASCII("Extensions")
                    .AppendASCII("bjafgdebaacbbbecmhlhpofkepfkgcpa")
                    .AppendASCII("1.0")));
  ASSERT_EQ(1u, service->extensions()->size());
  EXPECT_EQ(0u, service->disabled_extensions()->size());
  Extension* extension = service->extensions()->at(0);
  EXPECT_TRUE(manager->GetBackgroundHostForExtension(extension));
  ASSERT_TRUE(service->HasInstalledExtensions());

  // After disabling, the background page should go away.
  service->DisableExtension("bjafgdebaacbbbecmhlhpofkepfkgcpa");
  EXPECT_EQ(0u, service->extensions()->size());
  EXPECT_EQ(1u, service->disabled_extensions()->size());
  EXPECT_FALSE(manager->GetBackgroundHostForExtension(extension));
  ASSERT_TRUE(service->HasInstalledExtensions());

  // And bring it back.
  service->EnableExtension("bjafgdebaacbbbecmhlhpofkepfkgcpa");
  EXPECT_EQ(1u, service->extensions()->size());
  EXPECT_EQ(0u, service->disabled_extensions()->size());
  EXPECT_TRUE(manager->GetBackgroundHostForExtension(extension));
  ASSERT_TRUE(service->HasInstalledExtensions());
}

// TODO(asargent): This test seems to crash on linux buildbots.
// (http://crbug.com/31737)
#if !defined(OS_LINUX)
// Tests extension autoupdate.
IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, AutoUpdate) {
  FilePath basedir = test_data_dir_.AppendASCII("autoupdate");
  // Note: This interceptor gets requests on the IO thread.
  scoped_refptr<AutoUpdateInterceptor> interceptor(new AutoUpdateInterceptor());
  URLFetcher::enable_interception_for_tests(true);

  interceptor->SetResponseOnIOThread("http://localhost/autoupdate/manifest",
                                     basedir.AppendASCII("manifest_v2.xml"));
  interceptor->SetResponseOnIOThread("http://localhost/autoupdate/v2.crx",
                                     basedir.AppendASCII("v2.crx"));

  // Install version 1 of the extension.
  ExtensionsService* service = browser()->profile()->GetExtensionsService();
  ASSERT_FALSE(service->HasInstalledExtensions());
  ASSERT_TRUE(InstallExtension(basedir.AppendASCII("v1.crx"), 1));
  const ExtensionList* extensions = service->extensions();
  ASSERT_TRUE(service->HasInstalledExtensions());
  ASSERT_EQ(1u, extensions->size());
  ASSERT_EQ("ogjcoiohnmldgjemafoockdghcjciccf", extensions->at(0)->id());
  ASSERT_EQ("1.0", extensions->at(0)->VersionString());

  // We don't want autoupdate blacklist checks.
  service->updater()->set_blacklist_checks_enabled(false);

  // Run autoupdate and make sure version 2 of the extension was installed.
  service->updater()->CheckNow();
  ASSERT_TRUE(WaitForExtensionInstall());
  extensions = service->extensions();
  ASSERT_EQ(1u, extensions->size());
  ASSERT_EQ("ogjcoiohnmldgjemafoockdghcjciccf", extensions->at(0)->id());
  ASSERT_EQ("2.0", extensions->at(0)->VersionString());

  // Now try doing an update to version 3, which has been incorrectly
  // signed. This should fail.
  interceptor->SetResponseOnIOThread("http://localhost/autoupdate/manifest",
                                     basedir.AppendASCII("manifest_v3.xml"));
  interceptor->SetResponseOnIOThread("http://localhost/autoupdate/v3.crx",
                                     basedir.AppendASCII("v3.crx"));

  service->updater()->CheckNow();
  ASSERT_TRUE(WaitForExtensionInstallError());

  // Make sure the extension state is the same as before.
  extensions = service->extensions();
  ASSERT_EQ(1u, extensions->size());
  ASSERT_EQ("ogjcoiohnmldgjemafoockdghcjciccf", extensions->at(0)->id());
  ASSERT_EQ("2.0", extensions->at(0)->VersionString());
}
#endif  // !defined(OS_LINUX)
<commit_msg>Disable UninstallDisabled and UpdatePermissions temporarily. BUG=none TEST=none TBR=asargent Review URL: http://codereview.chromium.org/552077<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/ref_counted.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/extensions/autoupdate_interceptor.h"
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/extensions/extension_updater.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/ui_test_utils.h"

class ExtensionManagementTest : public ExtensionBrowserTest {
 protected:
  // Helper method that returns whether the extension is at the given version.
  // This calls version(), which must be defined in the extension's bg page,
  // as well as asking the extension itself.
  bool IsExtensionAtVersion(Extension* extension,
                            const std::string& expected_version) {
    // Test that the extension's version from the manifest and reported by the
    // background page is correct.  This is to ensure that the processes are in
    // sync with the Extension.
    ExtensionProcessManager* manager = browser()->profile()->
        GetExtensionProcessManager();
    ExtensionHost* ext_host = manager->GetBackgroundHostForExtension(extension);
    EXPECT_TRUE(ext_host);
    if (!ext_host)
      return false;

    std::string version_from_bg;
    bool exec = ui_test_utils::ExecuteJavaScriptAndExtractString(
        ext_host->render_view_host(), L"", L"version()", &version_from_bg);
    EXPECT_TRUE(exec);
    if (!exec)
      return false;

    if (version_from_bg != expected_version ||
        extension->VersionString() != expected_version)
      return false;
    return true;
  }

  // Helper method that installs a low permission extension then updates
  // to the second version requiring increased permissions. Returns whether
  // the operation was completed successfully.
  bool InstallAndUpdateIncreasingPermissionsExtension() {
    ExtensionsService* service = browser()->profile()->GetExtensionsService();
    TabContents* contents = browser()->GetSelectedTabContents();
    if (service->HasInstalledExtensions() || !contents)
      return false;

    // Install the initial version, which should happen just fine.
    if (!InstallExtension(
        test_data_dir_.AppendASCII("permissions-low-v1.crx"), 1))
      return false;
    EXPECT_EQ(0, contents->infobar_delegate_count());

    // Upgrade to a version that wants more permissions. We should disable the
    // extension and prompt the user to reenable.
    if (service->extensions()->size() != 1u)
      return false;
    if (!UpdateExtension(
        service->extensions()->at(0)->id(),
        test_data_dir_.AppendASCII("permissions-high-v2.crx"), -1))
      return false;
    EXPECT_EQ(1, contents->infobar_delegate_count());
    EXPECT_EQ(0u, service->extensions()->size());
    if (service->disabled_extensions()->size() != 1u)
      return false;
    return true;
  }
};

// Tests that installing the same version does not overwrite.
IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, InstallSameVersion) {
  ExtensionsService* service = browser()->profile()->GetExtensionsService();
  ASSERT_FALSE(service->HasInstalledExtensions());
  ASSERT_TRUE(InstallExtension(
      test_data_dir_.AppendASCII("install/install.crx"), 1));

  // Install an extension with the same version. The previous install should
  // be kept.
  ASSERT_TRUE(InstallExtension(
      test_data_dir_.AppendASCII("install/install_same_version.crx"), 0));
  EXPECT_TRUE(IsExtensionAtVersion(service->extensions()->at(0), "1.0"));
}

IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, InstallOlderVersion) {
  ExtensionsService* service = browser()->profile()->GetExtensionsService();
  ASSERT_FALSE(service->HasInstalledExtensions());
  ASSERT_TRUE(InstallExtension(
      test_data_dir_.AppendASCII("install/install.crx"), 1));
  ASSERT_TRUE(InstallExtension(
      test_data_dir_.AppendASCII("install/install_older_version.crx"), 0));
  EXPECT_TRUE(IsExtensionAtVersion(service->extensions()->at(0), "1.0"));
}

IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, InstallThenCancel) {
  ExtensionsService* service = browser()->profile()->GetExtensionsService();
  ASSERT_FALSE(service->HasInstalledExtensions());
  ASSERT_TRUE(InstallExtension(
      test_data_dir_.AppendASCII("install/install.crx"), 1));

  // Cancel this install.
  StartInstallButCancel(test_data_dir_.AppendASCII("install/install_v2.crx"));
  EXPECT_TRUE(IsExtensionAtVersion(service->extensions()->at(0), "1.0"));
}

// Tests that installing and uninstalling extensions don't crash with an
// incognito window open.
IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, Incognito) {
  // Open an incognito window to the extensions management page.  We just
  // want to make sure that we don't crash while playing with extensions when
  // this guy is around.
  ui_test_utils::OpenURLOffTheRecord(browser()->profile(),
                                     GURL(chrome::kChromeUIExtensionsURL));

  ASSERT_TRUE(InstallExtension(test_data_dir_.AppendASCII("good.crx"), 1));
  UninstallExtension("ldnnhddmnhbkjipkidpdiheffobcpfmf");
}

// Tests the process of updating an extension to one that requires higher
// permissions.
IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, DISABLED_UpdatePermissions) {
  ExtensionsService* service = browser()->profile()->GetExtensionsService();
  ASSERT_TRUE(InstallAndUpdateIncreasingPermissionsExtension());

  // Now try reenabling it, which should also dismiss the infobar.
  service->EnableExtension(service->disabled_extensions()->at(0)->id());
  TabContents* contents = browser()->GetSelectedTabContents();
  ASSERT_TRUE(contents);
  EXPECT_EQ(0, contents->infobar_delegate_count());
  EXPECT_EQ(1u, service->extensions()->size());
  EXPECT_EQ(0u, service->disabled_extensions()->size());
}

// Tests that we can uninstall a disabled extension.
IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, DISABLED_UninstallDisabled) {
  ExtensionsService* service = browser()->profile()->GetExtensionsService();
  ASSERT_TRUE(InstallAndUpdateIncreasingPermissionsExtension());

  // Now try uninstalling it.
  UninstallExtension(service->disabled_extensions()->at(0)->id());
  EXPECT_EQ(0u, service->extensions()->size());
  EXPECT_EQ(0u, service->disabled_extensions()->size());
  ASSERT_FALSE(service->HasInstalledExtensions());
}

// Tests that disabling and re-enabling an extension works.
IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, DisableEnable) {
  ExtensionProcessManager* manager = browser()->profile()->
      GetExtensionProcessManager();
  ExtensionsService* service = browser()->profile()->GetExtensionsService();

  // Load an extension, expect the background page to be available.
  ASSERT_FALSE(service->HasInstalledExtensions());
  ASSERT_TRUE(LoadExtension(
      test_data_dir_.AppendASCII("good").AppendASCII("Extensions")
                    .AppendASCII("bjafgdebaacbbbecmhlhpofkepfkgcpa")
                    .AppendASCII("1.0")));
  ASSERT_EQ(1u, service->extensions()->size());
  EXPECT_EQ(0u, service->disabled_extensions()->size());
  Extension* extension = service->extensions()->at(0);
  EXPECT_TRUE(manager->GetBackgroundHostForExtension(extension));
  ASSERT_TRUE(service->HasInstalledExtensions());

  // After disabling, the background page should go away.
  service->DisableExtension("bjafgdebaacbbbecmhlhpofkepfkgcpa");
  EXPECT_EQ(0u, service->extensions()->size());
  EXPECT_EQ(1u, service->disabled_extensions()->size());
  EXPECT_FALSE(manager->GetBackgroundHostForExtension(extension));
  ASSERT_TRUE(service->HasInstalledExtensions());

  // And bring it back.
  service->EnableExtension("bjafgdebaacbbbecmhlhpofkepfkgcpa");
  EXPECT_EQ(1u, service->extensions()->size());
  EXPECT_EQ(0u, service->disabled_extensions()->size());
  EXPECT_TRUE(manager->GetBackgroundHostForExtension(extension));
  ASSERT_TRUE(service->HasInstalledExtensions());
}

// TODO(asargent): This test seems to crash on linux buildbots.
// (http://crbug.com/31737)
#if !defined(OS_LINUX)
// Tests extension autoupdate.
IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, AutoUpdate) {
  FilePath basedir = test_data_dir_.AppendASCII("autoupdate");
  // Note: This interceptor gets requests on the IO thread.
  scoped_refptr<AutoUpdateInterceptor> interceptor(new AutoUpdateInterceptor());
  URLFetcher::enable_interception_for_tests(true);

  interceptor->SetResponseOnIOThread("http://localhost/autoupdate/manifest",
                                     basedir.AppendASCII("manifest_v2.xml"));
  interceptor->SetResponseOnIOThread("http://localhost/autoupdate/v2.crx",
                                     basedir.AppendASCII("v2.crx"));

  // Install version 1 of the extension.
  ExtensionsService* service = browser()->profile()->GetExtensionsService();
  ASSERT_FALSE(service->HasInstalledExtensions());
  ASSERT_TRUE(InstallExtension(basedir.AppendASCII("v1.crx"), 1));
  const ExtensionList* extensions = service->extensions();
  ASSERT_TRUE(service->HasInstalledExtensions());
  ASSERT_EQ(1u, extensions->size());
  ASSERT_EQ("ogjcoiohnmldgjemafoockdghcjciccf", extensions->at(0)->id());
  ASSERT_EQ("1.0", extensions->at(0)->VersionString());

  // We don't want autoupdate blacklist checks.
  service->updater()->set_blacklist_checks_enabled(false);

  // Run autoupdate and make sure version 2 of the extension was installed.
  service->updater()->CheckNow();
  ASSERT_TRUE(WaitForExtensionInstall());
  extensions = service->extensions();
  ASSERT_EQ(1u, extensions->size());
  ASSERT_EQ("ogjcoiohnmldgjemafoockdghcjciccf", extensions->at(0)->id());
  ASSERT_EQ("2.0", extensions->at(0)->VersionString());

  // Now try doing an update to version 3, which has been incorrectly
  // signed. This should fail.
  interceptor->SetResponseOnIOThread("http://localhost/autoupdate/manifest",
                                     basedir.AppendASCII("manifest_v3.xml"));
  interceptor->SetResponseOnIOThread("http://localhost/autoupdate/v3.crx",
                                     basedir.AppendASCII("v3.crx"));

  service->updater()->CheckNow();
  ASSERT_TRUE(WaitForExtensionInstallError());

  // Make sure the extension state is the same as before.
  extensions = service->extensions();
  ASSERT_EQ(1u, extensions->size());
  ASSERT_EQ("ogjcoiohnmldgjemafoockdghcjciccf", extensions->at(0)->id());
  ASSERT_EQ("2.0", extensions->at(0)->VersionString());
}
#endif  // !defined(OS_LINUX)
<|endoftext|>