<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 <com/sun/star/chart/ChartAxisLabelPosition.hpp>

#include "ChartErrorBarPanel.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 <comphelper/processfactory.hxx>

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

namespace chart { namespace sidebar {

namespace {

css::uno::Reference<css::beans::XPropertySet> getErrorBarPropSet(
        css::uno::Reference<css::frame::XModel> xModel, const OUString& rCID)
{
    return ObjectIdentifier::getObjectPropertySet(rCID, xModel);
}

bool showPositiveError(css::uno::Reference<css::frame::XModel> xModel,
        const OUString& rCID)
{
    css::uno::Reference<css::beans::XPropertySet> xPropSet =
        getErrorBarPropSet(xModel, rCID);

    if (!xPropSet.is())
        return false;

    css::uno::Any aAny = xPropSet->getPropertyValue("ShowPositiveError");

    if (!aAny.hasValue())
        return false;

    bool bShow = false;
    aAny >>= bShow;
    return bShow;
}

bool showNegativeError(css::uno::Reference<css::frame::XModel> xModel,
        const OUString& rCID)
{
    css::uno::Reference<css::beans::XPropertySet> xPropSet =
        getErrorBarPropSet(xModel, rCID);

    if (!xPropSet.is())
        return false;

    css::uno::Any aAny = xPropSet->getPropertyValue("ShowNegativeError");

    if (!aAny.hasValue())
        return false;

    bool bShow = false;
    aAny >>= bShow;
    return bShow;
}

void setShowPositiveError(css::uno::Reference<css::frame::XModel> xModel,
        const OUString& rCID, bool bShow)
{
    css::uno::Reference<css::beans::XPropertySet> xPropSet =
        getErrorBarPropSet(xModel, rCID);

    if (!xPropSet.is())
        return;

    xPropSet->setPropertyValue("ShowPositiveError", css::uno::makeAny(bShow));
}

void setShowNegativeError(css::uno::Reference<css::frame::XModel> xModel,
        const OUString& rCID, bool bShow)
{
    css::uno::Reference<css::beans::XPropertySet> xPropSet =
        getErrorBarPropSet(xModel, rCID);

    if (!xPropSet.is())
        return;

    xPropSet->setPropertyValue("ShowNegativeError", css::uno::makeAny(bShow));
}

OUString getCID(css::uno::Reference<css::frame::XModel> xModel)
{
    css::uno::Reference<css::frame::XController> xController(xModel->getCurrentController());
    css::uno::Reference<css::view::XSelectionSupplier> xSelectionSupplier(xController, css::uno::UNO_QUERY);
    if (!xSelectionSupplier.is())
        return OUString();

    uno::Any aAny = xSelectionSupplier->getSelection();
    assert(aAny.hasValue());
    OUString aCID;
    aAny >>= aCID;
#ifdef DBG_UTIL
    ObjectType eType = ObjectIdentifier::getObjectType(aCID);
    assert(eType == OBJECTTYPE_DATA_ERRORS_X ||
            eType == OBJECTTYPE_DATA_ERRORS_Y ||
            eType == OBJECTTYPE_DATA_ERRORS_Z);
#endif

    return aCID;
}

}

ChartErrorBarPanel::ChartErrorBarPanel(
    vcl::Window* pParent,
    const css::uno::Reference<css::frame::XFrame>& rxFrame,
    ChartController* pController)
  : PanelLayout(pParent, "ChartErrorBarPanel", "modules/schart/ui/sidebarerrorbar.ui", rxFrame),
    mxFrame(rxFrame),
    mxModel(pController->getModel()),
    mxListener(new ChartSidebarModifyListener(this))
{

    get(mpRBPosAndNeg, "radiobutton_positive_negative");
    get(mpRBPos, "radiobutton_positive");
    get(mpRBNeg, "radiobutton_negative");

    Initialize();
}

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

void ChartErrorBarPanel::dispose()
{
    css::uno::Reference<css::util::XModifyBroadcaster> xBroadcaster(mxModel, css::uno::UNO_QUERY_THROW);
    xBroadcaster->removeModifyListener(mxListener);

    mpRBPosAndNeg.clear();
    mpRBPos.clear();
    mpRBNeg.clear();

    PanelLayout::dispose();
}

void ChartErrorBarPanel::Initialize()
{
    css::uno::Reference<css::util::XModifyBroadcaster> xBroadcaster(mxModel, css::uno::UNO_QUERY_THROW);
    xBroadcaster->addModifyListener(mxListener);

    updateData();

    Link<> aLink = LINK(this, ChartErrorBarPanel, RadioBtnHdl);
    mpRBPosAndNeg->SetToggleHdl(aLink);
    mpRBPos->SetToggleHdl(aLink);
    mpRBNeg->SetToggleHdl(aLink);
}

void ChartErrorBarPanel::updateData()
{
    OUString aCID = getCID(mxModel);
    bool bPos = showPositiveError(mxModel, aCID);
    bool bNeg = showNegativeError(mxModel, aCID);

    SolarMutexGuard aGuard;

    if (bPos && bNeg)
        mpRBPosAndNeg->Check(true);
    else if (bPos)
        mpRBPos->Check(true);
    else if (bNeg)
        mpRBNeg->Check(true);
}

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

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

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

void ChartErrorBarPanel::HandleContextChange(
    const ::sfx2::sidebar::EnumContext& )
{
    updateData();
}

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

void ChartErrorBarPanel::modelInvalid()
{
}

IMPL_LINK_NOARG(ChartErrorBarPanel, RadioBtnHdl)
{
    OUString aCID = getCID(mxModel);
    bool bPos = mpRBPosAndNeg->IsChecked() || mpRBPos->IsChecked();
    bool bNeg = mpRBPosAndNeg->IsChecked() || mpRBNeg->IsChecked();

    setShowPositiveError(mxModel, aCID, bPos);
    setShowNegativeError(mxModel, aCID, bNeg);
}

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

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>fix build<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 <com/sun/star/chart/ChartAxisLabelPosition.hpp>

#include "ChartErrorBarPanel.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 <comphelper/processfactory.hxx>

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

namespace chart { namespace sidebar {

namespace {

css::uno::Reference<css::beans::XPropertySet> getErrorBarPropSet(
        css::uno::Reference<css::frame::XModel> xModel, const OUString& rCID)
{
    return ObjectIdentifier::getObjectPropertySet(rCID, xModel);
}

bool showPositiveError(css::uno::Reference<css::frame::XModel> xModel,
        const OUString& rCID)
{
    css::uno::Reference<css::beans::XPropertySet> xPropSet =
        getErrorBarPropSet(xModel, rCID);

    if (!xPropSet.is())
        return false;

    css::uno::Any aAny = xPropSet->getPropertyValue("ShowPositiveError");

    if (!aAny.hasValue())
        return false;

    bool bShow = false;
    aAny >>= bShow;
    return bShow;
}

bool showNegativeError(css::uno::Reference<css::frame::XModel> xModel,
        const OUString& rCID)
{
    css::uno::Reference<css::beans::XPropertySet> xPropSet =
        getErrorBarPropSet(xModel, rCID);

    if (!xPropSet.is())
        return false;

    css::uno::Any aAny = xPropSet->getPropertyValue("ShowNegativeError");

    if (!aAny.hasValue())
        return false;

    bool bShow = false;
    aAny >>= bShow;
    return bShow;
}

void setShowPositiveError(css::uno::Reference<css::frame::XModel> xModel,
        const OUString& rCID, bool bShow)
{
    css::uno::Reference<css::beans::XPropertySet> xPropSet =
        getErrorBarPropSet(xModel, rCID);

    if (!xPropSet.is())
        return;

    xPropSet->setPropertyValue("ShowPositiveError", css::uno::makeAny(bShow));
}

void setShowNegativeError(css::uno::Reference<css::frame::XModel> xModel,
        const OUString& rCID, bool bShow)
{
    css::uno::Reference<css::beans::XPropertySet> xPropSet =
        getErrorBarPropSet(xModel, rCID);

    if (!xPropSet.is())
        return;

    xPropSet->setPropertyValue("ShowNegativeError", css::uno::makeAny(bShow));
}

OUString getCID(css::uno::Reference<css::frame::XModel> xModel)
{
    css::uno::Reference<css::frame::XController> xController(xModel->getCurrentController());
    css::uno::Reference<css::view::XSelectionSupplier> xSelectionSupplier(xController, css::uno::UNO_QUERY);
    if (!xSelectionSupplier.is())
        return OUString();

    uno::Any aAny = xSelectionSupplier->getSelection();
    assert(aAny.hasValue());
    OUString aCID;
    aAny >>= aCID;
#ifdef DBG_UTIL
    ObjectType eType = ObjectIdentifier::getObjectType(aCID);
    assert(eType == OBJECTTYPE_DATA_ERRORS_X ||
            eType == OBJECTTYPE_DATA_ERRORS_Y ||
            eType == OBJECTTYPE_DATA_ERRORS_Z);
#endif

    return aCID;
}

}

ChartErrorBarPanel::ChartErrorBarPanel(
    vcl::Window* pParent,
    const css::uno::Reference<css::frame::XFrame>& rxFrame,
    ChartController* pController)
  : PanelLayout(pParent, "ChartErrorBarPanel", "modules/schart/ui/sidebarerrorbar.ui", rxFrame),
    mxFrame(rxFrame),
    mxModel(pController->getModel()),
    mxListener(new ChartSidebarModifyListener(this))
{

    get(mpRBPosAndNeg, "radiobutton_positive_negative");
    get(mpRBPos, "radiobutton_positive");
    get(mpRBNeg, "radiobutton_negative");

    Initialize();
}

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

void ChartErrorBarPanel::dispose()
{
    css::uno::Reference<css::util::XModifyBroadcaster> xBroadcaster(mxModel, css::uno::UNO_QUERY_THROW);
    xBroadcaster->removeModifyListener(mxListener);

    mpRBPosAndNeg.clear();
    mpRBPos.clear();
    mpRBNeg.clear();

    PanelLayout::dispose();
}

void ChartErrorBarPanel::Initialize()
{
    css::uno::Reference<css::util::XModifyBroadcaster> xBroadcaster(mxModel, css::uno::UNO_QUERY_THROW);
    xBroadcaster->addModifyListener(mxListener);

    updateData();

    Link<> aLink = LINK(this, ChartErrorBarPanel, RadioBtnHdl);
    mpRBPosAndNeg->SetToggleHdl(aLink);
    mpRBPos->SetToggleHdl(aLink);
    mpRBNeg->SetToggleHdl(aLink);
}

void ChartErrorBarPanel::updateData()
{
    OUString aCID = getCID(mxModel);
    bool bPos = showPositiveError(mxModel, aCID);
    bool bNeg = showNegativeError(mxModel, aCID);

    SolarMutexGuard aGuard;

    if (bPos && bNeg)
        mpRBPosAndNeg->Check(true);
    else if (bPos)
        mpRBPos->Check(true);
    else if (bNeg)
        mpRBNeg->Check(true);
}

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

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

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

void ChartErrorBarPanel::HandleContextChange(
    const ::sfx2::sidebar::EnumContext& )
{
    updateData();
}

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

void ChartErrorBarPanel::modelInvalid()
{
}

IMPL_LINK_NOARG(ChartErrorBarPanel, RadioBtnHdl)
{
    OUString aCID = getCID(mxModel);
    bool bPos = mpRBPosAndNeg->IsChecked() || mpRBPos->IsChecked();
    bool bNeg = mpRBPosAndNeg->IsChecked() || mpRBNeg->IsChecked();

    setShowPositiveError(mxModel, aCID, bPos);
    setShowNegativeError(mxModel, aCID, bNeg);

    return 0;
}

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

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


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

#include "base/format_macros.h"
#include "base/stringprintf.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/autocomplete/autocomplete.h"
#include "chrome/browser/autocomplete/autocomplete_edit.h"
#include "chrome/browser/autocomplete/autocomplete_match.h"
#include "chrome/browser/autocomplete/autocomplete_popup_model.h"
#include "chrome/browser/history/history.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/omnibox/location_bar.h"
#include "chrome/browser/ui/omnibox/omnibox_view.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/common/notification_type.h"
#include "testing/gtest/include/gtest/gtest.h"

// Autocomplete test is flaky on ChromeOS.
// http://crbug.com/52928
#if defined(OS_CHROMEOS)
#define MAYBE_Autocomplete FLAKY_Autocomplete
#else
#define MAYBE_Autocomplete Autocomplete
#endif

namespace {

string16 AutocompleteResultAsString(const AutocompleteResult& result) {
  std::string output(base::StringPrintf("{%" PRIuS "} ", result.size()));
  for (size_t i = 0; i < result.size(); ++i) {
    AutocompleteMatch match = result.match_at(i);
    std::string provider_name = match.provider->name();
    output.append(base::StringPrintf("[\"%s\" by \"%s\"] ",
                                     UTF16ToUTF8(match.contents).c_str(),
                                     provider_name.c_str()));
  }
  return UTF8ToUTF16(output);
}

}  // namespace

class AutocompleteBrowserTest : public InProcessBrowserTest {
 protected:
  LocationBar* GetLocationBar() const {
    return browser()->window()->GetLocationBar();
  }

  AutocompleteController* GetAutocompleteController() const {
    return GetLocationBar()->location_entry()->model()->popup_model()->
        autocomplete_controller();
  }
};

IN_PROC_BROWSER_TEST_F(AutocompleteBrowserTest, Basic) {
  LocationBar* location_bar = GetLocationBar();

  EXPECT_TRUE(location_bar->GetInputString().empty());
  EXPECT_EQ(UTF8ToUTF16(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  // TODO(phajdan.jr): check state of IsSelectAll when it's consistent across
  // platforms.

  location_bar->FocusLocation(true);

  EXPECT_TRUE(location_bar->GetInputString().empty());
  EXPECT_EQ(UTF8ToUTF16(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  EXPECT_TRUE(location_bar->location_entry()->IsSelectAll());

  location_bar->location_entry()->SetUserText(ASCIIToUTF16("chrome"));

  EXPECT_TRUE(location_bar->GetInputString().empty());
  EXPECT_EQ(ASCIIToUTF16("chrome"), location_bar->location_entry()->GetText());
  EXPECT_FALSE(location_bar->location_entry()->IsSelectAll());

  location_bar->location_entry()->RevertAll();

  EXPECT_TRUE(location_bar->GetInputString().empty());
  EXPECT_EQ(UTF8ToUTF16(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  EXPECT_FALSE(location_bar->location_entry()->IsSelectAll());

  location_bar->location_entry()->SetUserText(ASCIIToUTF16("chrome"));
  location_bar->Revert();

  EXPECT_TRUE(location_bar->GetInputString().empty());
  EXPECT_EQ(UTF8ToUTF16(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  EXPECT_FALSE(location_bar->location_entry()->IsSelectAll());
}

IN_PROC_BROWSER_TEST_F(AutocompleteBrowserTest, MAYBE_Autocomplete) {
  // The results depend on the history backend being loaded. Make sure it is
  // loaded so that the autocomplete results are consistent.
  ui_test_utils::WaitForHistoryToLoad(browser());

  LocationBar* location_bar = GetLocationBar();
  AutocompleteController* autocomplete_controller = GetAutocompleteController();

  {
    autocomplete_controller->Start(
        ASCIIToUTF16("chrome"), string16(), true, false, true,
        AutocompleteInput::SYNCHRONOUS_MATCHES);

    EXPECT_TRUE(autocomplete_controller->done());
    EXPECT_TRUE(location_bar->GetInputString().empty());
    EXPECT_TRUE(location_bar->location_entry()->GetText().empty());
    EXPECT_TRUE(location_bar->location_entry()->IsSelectAll());
    const AutocompleteResult& result = autocomplete_controller->result();
    // We get two matches because we have a provider for extension apps and the
    // Chrome Web Store is a built-in Extension app. For this test, we only care
    // about the other match existing.
    ASSERT_GE(result.size(), 1U) << AutocompleteResultAsString(result);
    AutocompleteMatch match = result.match_at(0);
    EXPECT_EQ(AutocompleteMatch::SEARCH_WHAT_YOU_TYPED, match.type);
    EXPECT_FALSE(match.deletable);
  }

  {
    location_bar->Revert();

    EXPECT_TRUE(location_bar->GetInputString().empty());
    EXPECT_EQ(UTF8ToUTF16(chrome::kAboutBlankURL),
              location_bar->location_entry()->GetText());
    EXPECT_FALSE(location_bar->location_entry()->IsSelectAll());
    const AutocompleteResult& result = autocomplete_controller->result();
    EXPECT_TRUE(result.empty()) << AutocompleteResultAsString(result);
  }
}

IN_PROC_BROWSER_TEST_F(AutocompleteBrowserTest, TabAwayRevertSelect) {
  // http://code.google.com/p/chromium/issues/detail?id=38385
  // Make sure that tabbing away from an empty omnibar causes a revert
  // and select all.
  LocationBar* location_bar = GetLocationBar();
  EXPECT_EQ(UTF8ToUTF16(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  location_bar->location_entry()->SetUserText(string16());
  browser()->AddSelectedTabWithURL(GURL(chrome::kAboutBlankURL),
                                   PageTransition::START_PAGE);
  ui_test_utils::WaitForNavigation(
      &browser()->GetSelectedTabContents()->controller());
  EXPECT_EQ(UTF8ToUTF16(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  browser()->CloseTab();
  EXPECT_EQ(UTF8ToUTF16(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  EXPECT_TRUE(location_bar->location_entry()->IsSelectAll());
}

IN_PROC_BROWSER_TEST_F(AutocompleteBrowserTest, FocusSearch) {
  LocationBar* location_bar = GetLocationBar();

  // Focus search when omnibox is blank
  {
    EXPECT_TRUE(location_bar->GetInputString().empty());
    EXPECT_EQ(UTF8ToUTF16(chrome::kAboutBlankURL),
              location_bar->location_entry()->GetText());

    location_bar->FocusSearch();
    EXPECT_TRUE(location_bar->GetInputString().empty());
    EXPECT_EQ(ASCIIToUTF16("?"), location_bar->location_entry()->GetText());

    size_t selection_start, selection_end;
    location_bar->location_entry()->GetSelectionBounds(&selection_start,
                                                       &selection_end);
    EXPECT_EQ(1U, selection_start);
    EXPECT_EQ(1U, selection_end);
  }

  // Focus search when omnibox is _not_ alread in forced query mode.
  {
    location_bar->location_entry()->SetUserText(ASCIIToUTF16("foo"));
    EXPECT_TRUE(location_bar->GetInputString().empty());
    EXPECT_EQ(ASCIIToUTF16("foo"), location_bar->location_entry()->GetText());

    location_bar->FocusSearch();
    EXPECT_TRUE(location_bar->GetInputString().empty());
    EXPECT_EQ(ASCIIToUTF16("?"), location_bar->location_entry()->GetText());

    size_t selection_start, selection_end;
    location_bar->location_entry()->GetSelectionBounds(&selection_start,
                                                       &selection_end);
    EXPECT_EQ(1U, selection_start);
    EXPECT_EQ(1U, selection_end);
  }

  // Focus search when omnibox _is_ already in forced query mode, but no query
  // has been typed.
  {
    location_bar->location_entry()->SetUserText(ASCIIToUTF16("?"));
    EXPECT_TRUE(location_bar->GetInputString().empty());
    EXPECT_EQ(ASCIIToUTF16("?"), location_bar->location_entry()->GetText());

    location_bar->FocusSearch();
    EXPECT_TRUE(location_bar->GetInputString().empty());
    EXPECT_EQ(ASCIIToUTF16("?"), location_bar->location_entry()->GetText());

    size_t selection_start, selection_end;
    location_bar->location_entry()->GetSelectionBounds(&selection_start,
                                                       &selection_end);
    EXPECT_EQ(1U, selection_start);
    EXPECT_EQ(1U, selection_end);
  }

  // Focus search when omnibox _is_ already in forced query mode, and some query
  // has been typed.
  {
    location_bar->location_entry()->SetUserText(ASCIIToUTF16("?foo"));
    EXPECT_TRUE(location_bar->GetInputString().empty());
    EXPECT_EQ(ASCIIToUTF16("?foo"), location_bar->location_entry()->GetText());

    location_bar->FocusSearch();
    EXPECT_TRUE(location_bar->GetInputString().empty());
    EXPECT_EQ(ASCIIToUTF16("?foo"), location_bar->location_entry()->GetText());

    size_t selection_start, selection_end;
    location_bar->location_entry()->GetSelectionBounds(&selection_start,
                                                       &selection_end);
    EXPECT_EQ(1U, std::min(selection_start, selection_end));
    EXPECT_EQ(4U, std::max(selection_start, selection_end));
  }

  // Focus search when omnibox is in forced query mode with leading whitespace.
  {
    location_bar->location_entry()->SetUserText(ASCIIToUTF16("   ?foo"));
    EXPECT_TRUE(location_bar->GetInputString().empty());
    EXPECT_EQ(ASCIIToUTF16("   ?foo"),
              location_bar->location_entry()->GetText());

    location_bar->FocusSearch();
    EXPECT_TRUE(location_bar->GetInputString().empty());
    EXPECT_EQ(ASCIIToUTF16("   ?foo"),
              location_bar->location_entry()->GetText());

    size_t selection_start, selection_end;
    location_bar->location_entry()->GetSelectionBounds(&selection_start,
                                                       &selection_end);
    EXPECT_EQ(4U, std::min(selection_start, selection_end));
    EXPECT_EQ(7U, std::max(selection_start, selection_end));
  }
}
<commit_msg><commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/format_macros.h"
#include "base/path_service.h"
#include "base/stringprintf.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/autocomplete/autocomplete.h"
#include "chrome/browser/autocomplete/autocomplete_edit.h"
#include "chrome/browser/autocomplete/autocomplete_match.h"
#include "chrome/browser/autocomplete/autocomplete_popup_model.h"
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/history/history.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/omnibox/location_bar.h"
#include "chrome/browser/ui/omnibox/omnibox_view.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/common/notification_type.h"
#include "testing/gtest/include/gtest/gtest.h"

// Autocomplete test is flaky on ChromeOS.
// http://crbug.com/52928
#if defined(OS_CHROMEOS)
#define MAYBE_Autocomplete FLAKY_Autocomplete
#else
#define MAYBE_Autocomplete Autocomplete
#endif

namespace {

string16 AutocompleteResultAsString(const AutocompleteResult& result) {
  std::string output(base::StringPrintf("{%" PRIuS "} ", result.size()));
  for (size_t i = 0; i < result.size(); ++i) {
    AutocompleteMatch match = result.match_at(i);
    std::string provider_name = match.provider->name();
    output.append(base::StringPrintf("[\"%s\" by \"%s\"] ",
                                     UTF16ToUTF8(match.contents).c_str(),
                                     provider_name.c_str()));
  }
  return UTF8ToUTF16(output);
}

}  // namespace

class AutocompleteBrowserTest : public ExtensionBrowserTest {
 protected:
  LocationBar* GetLocationBar() const {
    return browser()->window()->GetLocationBar();
  }

  AutocompleteController* GetAutocompleteController() const {
    return GetLocationBar()->location_entry()->model()->popup_model()->
        autocomplete_controller();
  }
};

IN_PROC_BROWSER_TEST_F(AutocompleteBrowserTest, Basic) {
  LocationBar* location_bar = GetLocationBar();

  EXPECT_TRUE(location_bar->GetInputString().empty());
  EXPECT_EQ(UTF8ToUTF16(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  // TODO(phajdan.jr): check state of IsSelectAll when it's consistent across
  // platforms.

  location_bar->FocusLocation(true);

  EXPECT_TRUE(location_bar->GetInputString().empty());
  EXPECT_EQ(UTF8ToUTF16(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  EXPECT_TRUE(location_bar->location_entry()->IsSelectAll());

  location_bar->location_entry()->SetUserText(ASCIIToUTF16("chrome"));

  EXPECT_TRUE(location_bar->GetInputString().empty());
  EXPECT_EQ(ASCIIToUTF16("chrome"), location_bar->location_entry()->GetText());
  EXPECT_FALSE(location_bar->location_entry()->IsSelectAll());

  location_bar->location_entry()->RevertAll();

  EXPECT_TRUE(location_bar->GetInputString().empty());
  EXPECT_EQ(UTF8ToUTF16(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  EXPECT_FALSE(location_bar->location_entry()->IsSelectAll());

  location_bar->location_entry()->SetUserText(ASCIIToUTF16("chrome"));
  location_bar->Revert();

  EXPECT_TRUE(location_bar->GetInputString().empty());
  EXPECT_EQ(UTF8ToUTF16(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  EXPECT_FALSE(location_bar->location_entry()->IsSelectAll());
}

IN_PROC_BROWSER_TEST_F(AutocompleteBrowserTest, MAYBE_Autocomplete) {
  // The results depend on the history backend being loaded. Make sure it is
  // loaded so that the autocomplete results are consistent.
  ui_test_utils::WaitForHistoryToLoad(browser());

  LocationBar* location_bar = GetLocationBar();
  AutocompleteController* autocomplete_controller = GetAutocompleteController();

  {
    autocomplete_controller->Start(
        ASCIIToUTF16("chrome"), string16(), true, false, true,
        AutocompleteInput::SYNCHRONOUS_MATCHES);

    EXPECT_TRUE(autocomplete_controller->done());
    EXPECT_TRUE(location_bar->GetInputString().empty());
    EXPECT_TRUE(location_bar->location_entry()->GetText().empty());
    EXPECT_TRUE(location_bar->location_entry()->IsSelectAll());
    const AutocompleteResult& result = autocomplete_controller->result();
    // We get two matches because we have a provider for extension apps and the
    // Chrome Web Store is a built-in Extension app. For this test, we only care
    // about the other match existing.
    ASSERT_GE(result.size(), 1U) << AutocompleteResultAsString(result);
    AutocompleteMatch match = result.match_at(0);
    EXPECT_EQ(AutocompleteMatch::SEARCH_WHAT_YOU_TYPED, match.type);
    EXPECT_FALSE(match.deletable);
  }

  {
    location_bar->Revert();

    EXPECT_TRUE(location_bar->GetInputString().empty());
    EXPECT_EQ(UTF8ToUTF16(chrome::kAboutBlankURL),
              location_bar->location_entry()->GetText());
    EXPECT_FALSE(location_bar->location_entry()->IsSelectAll());
    const AutocompleteResult& result = autocomplete_controller->result();
    EXPECT_TRUE(result.empty()) << AutocompleteResultAsString(result);
  }
}

IN_PROC_BROWSER_TEST_F(AutocompleteBrowserTest, TabAwayRevertSelect) {
  // http://code.google.com/p/chromium/issues/detail?id=38385
  // Make sure that tabbing away from an empty omnibar causes a revert
  // and select all.
  LocationBar* location_bar = GetLocationBar();
  EXPECT_EQ(UTF8ToUTF16(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  location_bar->location_entry()->SetUserText(string16());
  browser()->AddSelectedTabWithURL(GURL(chrome::kAboutBlankURL),
                                   PageTransition::START_PAGE);
  ui_test_utils::WaitForNavigation(
      &browser()->GetSelectedTabContents()->controller());
  EXPECT_EQ(UTF8ToUTF16(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  browser()->CloseTab();
  EXPECT_EQ(UTF8ToUTF16(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  EXPECT_TRUE(location_bar->location_entry()->IsSelectAll());
}

IN_PROC_BROWSER_TEST_F(AutocompleteBrowserTest, FocusSearch) {
  LocationBar* location_bar = GetLocationBar();

  // Focus search when omnibox is blank
  {
    EXPECT_TRUE(location_bar->GetInputString().empty());
    EXPECT_EQ(UTF8ToUTF16(chrome::kAboutBlankURL),
              location_bar->location_entry()->GetText());

    location_bar->FocusSearch();
    EXPECT_TRUE(location_bar->GetInputString().empty());
    EXPECT_EQ(ASCIIToUTF16("?"), location_bar->location_entry()->GetText());

    size_t selection_start, selection_end;
    location_bar->location_entry()->GetSelectionBounds(&selection_start,
                                                       &selection_end);
    EXPECT_EQ(1U, selection_start);
    EXPECT_EQ(1U, selection_end);
  }

  // Focus search when omnibox is _not_ alread in forced query mode.
  {
    location_bar->location_entry()->SetUserText(ASCIIToUTF16("foo"));
    EXPECT_TRUE(location_bar->GetInputString().empty());
    EXPECT_EQ(ASCIIToUTF16("foo"), location_bar->location_entry()->GetText());

    location_bar->FocusSearch();
    EXPECT_TRUE(location_bar->GetInputString().empty());
    EXPECT_EQ(ASCIIToUTF16("?"), location_bar->location_entry()->GetText());

    size_t selection_start, selection_end;
    location_bar->location_entry()->GetSelectionBounds(&selection_start,
                                                       &selection_end);
    EXPECT_EQ(1U, selection_start);
    EXPECT_EQ(1U, selection_end);
  }

  // Focus search when omnibox _is_ already in forced query mode, but no query
  // has been typed.
  {
    location_bar->location_entry()->SetUserText(ASCIIToUTF16("?"));
    EXPECT_TRUE(location_bar->GetInputString().empty());
    EXPECT_EQ(ASCIIToUTF16("?"), location_bar->location_entry()->GetText());

    location_bar->FocusSearch();
    EXPECT_TRUE(location_bar->GetInputString().empty());
    EXPECT_EQ(ASCIIToUTF16("?"), location_bar->location_entry()->GetText());

    size_t selection_start, selection_end;
    location_bar->location_entry()->GetSelectionBounds(&selection_start,
                                                       &selection_end);
    EXPECT_EQ(1U, selection_start);
    EXPECT_EQ(1U, selection_end);
  }

  // Focus search when omnibox _is_ already in forced query mode, and some query
  // has been typed.
  {
    location_bar->location_entry()->SetUserText(ASCIIToUTF16("?foo"));
    EXPECT_TRUE(location_bar->GetInputString().empty());
    EXPECT_EQ(ASCIIToUTF16("?foo"), location_bar->location_entry()->GetText());

    location_bar->FocusSearch();
    EXPECT_TRUE(location_bar->GetInputString().empty());
    EXPECT_EQ(ASCIIToUTF16("?foo"), location_bar->location_entry()->GetText());

    size_t selection_start, selection_end;
    location_bar->location_entry()->GetSelectionBounds(&selection_start,
                                                       &selection_end);
    EXPECT_EQ(1U, std::min(selection_start, selection_end));
    EXPECT_EQ(4U, std::max(selection_start, selection_end));
  }

  // Focus search when omnibox is in forced query mode with leading whitespace.
  {
    location_bar->location_entry()->SetUserText(ASCIIToUTF16("   ?foo"));
    EXPECT_TRUE(location_bar->GetInputString().empty());
    EXPECT_EQ(ASCIIToUTF16("   ?foo"),
              location_bar->location_entry()->GetText());

    location_bar->FocusSearch();
    EXPECT_TRUE(location_bar->GetInputString().empty());
    EXPECT_EQ(ASCIIToUTF16("   ?foo"),
              location_bar->location_entry()->GetText());

    size_t selection_start, selection_end;
    location_bar->location_entry()->GetSelectionBounds(&selection_start,
                                                       &selection_end);
    EXPECT_EQ(4U, std::min(selection_start, selection_end));
    EXPECT_EQ(7U, std::max(selection_start, selection_end));
  }
}

IN_PROC_BROWSER_TEST_F(AutocompleteBrowserTest, ExtensionAppProvider) {
  ExtensionService* service = browser()->profile()->GetExtensionService();
  size_t extension_count = service->extensions()->size();

  FilePath test_dir;
  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_dir));
  // Load a packaged app.
  service->LoadExtension(test_dir.AppendASCII("extensions")
                                 .AppendASCII("packaged_app"));
  WaitForExtensionLoad();
  // Load a hosted app.
  service->LoadExtension(test_dir.AppendASCII("extensions")
                                 .AppendASCII("app"));
  WaitForExtensionLoad();
  ASSERT_EQ(extension_count + 2U, service->extensions()->size());

  // The results depend on the history backend being loaded. Make sure it is
  // loaded so that the autocomplete results are consistent.
  ui_test_utils::WaitForHistoryToLoad(browser());

  LocationBar* location_bar = GetLocationBar();
  AutocompleteController* autocomplete_controller = GetAutocompleteController();

  // Try out the packaged app.
  {
    autocomplete_controller->Start(
        ASCIIToUTF16("Packaged App Test"), string16(), true, false, true,
        AutocompleteInput::SYNCHRONOUS_MATCHES);

    EXPECT_TRUE(autocomplete_controller->done());
    EXPECT_TRUE(location_bar->GetInputString().empty());
    EXPECT_TRUE(location_bar->location_entry()->GetText().empty());
    EXPECT_TRUE(location_bar->location_entry()->IsSelectAll());
    const AutocompleteResult& result = autocomplete_controller->result();
    EXPECT_GT(result.size(), 1U) << AutocompleteResultAsString(result);
    AutocompleteMatch match = result.match_at(0);
    EXPECT_EQ(ASCIIToUTF16("Packaged App Test"), match.contents);
    EXPECT_EQ(AutocompleteMatch::EXTENSION_APP, match.type);
    EXPECT_FALSE(match.deletable);
    location_bar->AcceptInput();
  }

  browser()->NewTab();

  // Try out the hosted app.
  {
    autocomplete_controller->Start(
        ASCIIToUTF16("App Test"), string16(), true, false, true,
        AutocompleteInput::SYNCHRONOUS_MATCHES);

    EXPECT_TRUE(autocomplete_controller->done());
    EXPECT_TRUE(location_bar->GetInputString().empty());
    EXPECT_TRUE(location_bar->location_entry()->GetText().empty());
    EXPECT_TRUE(location_bar->location_entry()->IsSelectAll());
    const AutocompleteResult& result = autocomplete_controller->result();
    // 'App test' is also a substring of extension 'Packaged App Test'.
    EXPECT_GT(result.size(), 2U) << AutocompleteResultAsString(result);
    AutocompleteMatch match = result.match_at(0);
    EXPECT_EQ(ASCIIToUTF16("App Test"), match.contents);
    EXPECT_EQ(AutocompleteMatch::EXTENSION_APP, match.type);
    EXPECT_FALSE(match.deletable);
    location_bar->AcceptInput();
  }
}
<|endoftext|>


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

#include <vector>

#include "base/command_line.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/extensions/user_script_master.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/notification_details.h"
#include "chrome/common/notification_observer.h"
#include "chrome/common/notification_registrar.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/notification_type.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "net/base/net_util.h"

// This file contains high-level startup tests for the extensions system. We've
// had many silly bugs where command line flags did not get propagated correctly
// into the services, so we didn't start correctly.

class ExtensionStartupTestBase : public InProcessBrowserTest {
 public:
  ExtensionStartupTestBase() : enable_extensions_(false) {
  }

 protected:
  // InProcessBrowserTest
  virtual void SetUpCommandLine(CommandLine* command_line) {
    EnableDOMAutomation();

    FilePath profile_dir;
    PathService::Get(chrome::DIR_USER_DATA, &profile_dir);
    profile_dir = profile_dir.AppendASCII("Default");
    file_util::CreateDirectory(profile_dir);

    preferences_file_ = profile_dir.AppendASCII("Preferences");
    user_scripts_dir_ = profile_dir.AppendASCII("User Scripts");
    extensions_dir_ = profile_dir.AppendASCII("Extensions");

    if (enable_extensions_) {
      FilePath src_dir;
      PathService::Get(chrome::DIR_TEST_DATA, &src_dir);
      src_dir = src_dir.AppendASCII("extensions").AppendASCII("good");

      file_util::CopyFile(src_dir.AppendASCII("Preferences"),
                          preferences_file_);
      file_util::CopyDirectory(src_dir.AppendASCII("Extensions"),
                               profile_dir, true);  // recursive
    } else {
      command_line->AppendSwitch(switches::kDisableExtensions);
    }

    if (!load_extension_.value().empty()) {
      command_line->AppendSwitchWithValue(switches::kLoadExtension,
                                          load_extension_.ToWStringHack());
    }
  }

  virtual void TearDown() {
    EXPECT_TRUE(file_util::Delete(preferences_file_, false));
    EXPECT_TRUE(file_util::Delete(user_scripts_dir_, true));
    EXPECT_TRUE(file_util::Delete(extensions_dir_, true));
  }

  void WaitForServicesToStart(int num_expected_extensions,
                              bool expect_extensions_enabled) {
    ExtensionsService* service = browser()->profile()->GetExtensionsService();
    if (!service->is_ready())
      ui_test_utils::WaitForNotification(NotificationType::EXTENSIONS_READY);
    ASSERT_TRUE(service->is_ready());

    ASSERT_EQ(static_cast<uint32>(num_expected_extensions),
              service->extensions()->size());
    ASSERT_EQ(expect_extensions_enabled, service->extensions_enabled());

    UserScriptMaster* master = browser()->profile()->GetUserScriptMaster();
    if (!master->ScriptsReady()) {
      ui_test_utils::WaitForNotification(
          NotificationType::USER_SCRIPTS_UPDATED);
    }
    ASSERT_TRUE(master->ScriptsReady());
  }

  void TestInjection(bool expect_css, bool expect_script) {
    // Load a page affected by the content script and test to see the effect.
    FilePath test_file;
    PathService::Get(chrome::DIR_TEST_DATA, &test_file);
    test_file = test_file.AppendASCII("extensions")
                         .AppendASCII("test_file.html");

    ui_test_utils::NavigateToURL(browser(), net::FilePathToFileURL(test_file));

    bool result = false;
    ui_test_utils::ExecuteJavaScriptAndExtractBool(
        browser()->GetSelectedTabContents()->render_view_host(), L"",
        L"window.domAutomationController.send("
        L"document.defaultView.getComputedStyle(document.body, null)."
        L"getPropertyValue('background-color') == 'rgb(245, 245, 220)')",
        &result);
    EXPECT_EQ(expect_css, result);

    result = false;
    ui_test_utils::ExecuteJavaScriptAndExtractBool(
        browser()->GetSelectedTabContents()->render_view_host(), L"",
        L"window.domAutomationController.send(document.title == 'Modified')",
        &result);
    EXPECT_EQ(expect_script, result);
  }

  FilePath preferences_file_;
  FilePath extensions_dir_;
  FilePath user_scripts_dir_;
  bool enable_extensions_;
  FilePath load_extension_;
};

// ExtensionsStartupTest
// Ensures that we can startup the browser with --enable-extensions and some
// extensions installed and see them run and do basic things.

class ExtensionsStartupTest : public ExtensionStartupTestBase {
 public:
  ExtensionsStartupTest() {
    enable_extensions_ = true;
  }
};

IN_PROC_BROWSER_TEST_F(ExtensionsStartupTest, Test) {
  WaitForServicesToStart(4, true);  // 1 component extension and 3 others.
  TestInjection(true, true);
}

// ExtensionsLoadTest
// Ensures that we can startup the browser with --load-extension and see them
// run.

class ExtensionsLoadTest : public ExtensionStartupTestBase {
 public:
  ExtensionsLoadTest() {
    PathService::Get(chrome::DIR_TEST_DATA, &load_extension_);
    load_extension_ = load_extension_
        .AppendASCII("extensions")
        .AppendASCII("good")
        .AppendASCII("Extensions")
        .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
        .AppendASCII("1.0.0.0");
  }
};

IN_PROC_BROWSER_TEST_F(ExtensionsLoadTest, Test) {
  WaitForServicesToStart(1, false);
  TestInjection(true, true);
}
<commit_msg>Do not make the tests fail on failed file deletes.<commit_after>// Copyright (c) 2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <vector>

#include "base/command_line.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/extensions/user_script_master.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/notification_details.h"
#include "chrome/common/notification_observer.h"
#include "chrome/common/notification_registrar.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/notification_type.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "net/base/net_util.h"

// This file contains high-level startup tests for the extensions system. We've
// had many silly bugs where command line flags did not get propagated correctly
// into the services, so we didn't start correctly.

class ExtensionStartupTestBase : public InProcessBrowserTest {
 public:
  ExtensionStartupTestBase() : enable_extensions_(false) {
  }

 protected:
  // InProcessBrowserTest
  virtual void SetUpCommandLine(CommandLine* command_line) {
    EnableDOMAutomation();

    FilePath profile_dir;
    PathService::Get(chrome::DIR_USER_DATA, &profile_dir);
    profile_dir = profile_dir.AppendASCII("Default");
    file_util::CreateDirectory(profile_dir);

    preferences_file_ = profile_dir.AppendASCII("Preferences");
    user_scripts_dir_ = profile_dir.AppendASCII("User Scripts");
    extensions_dir_ = profile_dir.AppendASCII("Extensions");

    if (enable_extensions_) {
      FilePath src_dir;
      PathService::Get(chrome::DIR_TEST_DATA, &src_dir);
      src_dir = src_dir.AppendASCII("extensions").AppendASCII("good");

      file_util::CopyFile(src_dir.AppendASCII("Preferences"),
                          preferences_file_);
      file_util::CopyDirectory(src_dir.AppendASCII("Extensions"),
                               profile_dir, true);  // recursive
    } else {
      command_line->AppendSwitch(switches::kDisableExtensions);
    }

    if (!load_extension_.value().empty()) {
      command_line->AppendSwitchWithValue(switches::kLoadExtension,
                                          load_extension_.ToWStringHack());
    }
  }

  virtual void TearDown() {
    EXPECT_TRUE(file_util::Delete(preferences_file_, false));

    // TODO(phajdan.jr): Check return values of the functions below, carefully.
    file_util::Delete(user_scripts_dir_, true);
    file_util::Delete(extensions_dir_, true));
  }

  void WaitForServicesToStart(int num_expected_extensions,
                              bool expect_extensions_enabled) {
    ExtensionsService* service = browser()->profile()->GetExtensionsService();
    if (!service->is_ready())
      ui_test_utils::WaitForNotification(NotificationType::EXTENSIONS_READY);
    ASSERT_TRUE(service->is_ready());

    ASSERT_EQ(static_cast<uint32>(num_expected_extensions),
              service->extensions()->size());
    ASSERT_EQ(expect_extensions_enabled, service->extensions_enabled());

    UserScriptMaster* master = browser()->profile()->GetUserScriptMaster();
    if (!master->ScriptsReady()) {
      ui_test_utils::WaitForNotification(
          NotificationType::USER_SCRIPTS_UPDATED);
    }
    ASSERT_TRUE(master->ScriptsReady());
  }

  void TestInjection(bool expect_css, bool expect_script) {
    // Load a page affected by the content script and test to see the effect.
    FilePath test_file;
    PathService::Get(chrome::DIR_TEST_DATA, &test_file);
    test_file = test_file.AppendASCII("extensions")
                         .AppendASCII("test_file.html");

    ui_test_utils::NavigateToURL(browser(), net::FilePathToFileURL(test_file));

    bool result = false;
    ui_test_utils::ExecuteJavaScriptAndExtractBool(
        browser()->GetSelectedTabContents()->render_view_host(), L"",
        L"window.domAutomationController.send("
        L"document.defaultView.getComputedStyle(document.body, null)."
        L"getPropertyValue('background-color') == 'rgb(245, 245, 220)')",
        &result);
    EXPECT_EQ(expect_css, result);

    result = false;
    ui_test_utils::ExecuteJavaScriptAndExtractBool(
        browser()->GetSelectedTabContents()->render_view_host(), L"",
        L"window.domAutomationController.send(document.title == 'Modified')",
        &result);
    EXPECT_EQ(expect_script, result);
  }

  FilePath preferences_file_;
  FilePath extensions_dir_;
  FilePath user_scripts_dir_;
  bool enable_extensions_;
  FilePath load_extension_;
};

// ExtensionsStartupTest
// Ensures that we can startup the browser with --enable-extensions and some
// extensions installed and see them run and do basic things.

class ExtensionsStartupTest : public ExtensionStartupTestBase {
 public:
  ExtensionsStartupTest() {
    enable_extensions_ = true;
  }
};

IN_PROC_BROWSER_TEST_F(ExtensionsStartupTest, Test) {
  WaitForServicesToStart(4, true);  // 1 component extension and 3 others.
  TestInjection(true, true);
}

// ExtensionsLoadTest
// Ensures that we can startup the browser with --load-extension and see them
// run.

class ExtensionsLoadTest : public ExtensionStartupTestBase {
 public:
  ExtensionsLoadTest() {
    PathService::Get(chrome::DIR_TEST_DATA, &load_extension_);
    load_extension_ = load_extension_
        .AppendASCII("extensions")
        .AppendASCII("good")
        .AppendASCII("Extensions")
        .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
        .AppendASCII("1.0.0.0");
  }
};

IN_PROC_BROWSER_TEST_F(ExtensionsLoadTest, Test) {
  WaitForServicesToStart(1, false);
  TestInjection(true, true);
}
<|endoftext|>


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

#include "chrome/browser/in_process_webkit/dom_storage_context.h"

#include <algorithm>

#include "base/file_path.h"
#include "base/file_util.h"
#include "base/string_util.h"
#include "chrome/browser/browser_thread.h"
#include "chrome/browser/in_process_webkit/dom_storage_area.h"
#include "chrome/browser/in_process_webkit/dom_storage_namespace.h"
#include "chrome/browser/in_process_webkit/webkit_context.h"
#include "chrome/common/dom_storage_common.h"
#include "third_party/WebKit/WebKit/chromium/public/WebSecurityOrigin.h"
#include "third_party/WebKit/WebKit/chromium/public/WebString.h"
#include "webkit/glue/webkit_glue.h"

const FilePath::CharType DOMStorageContext::kLocalStorageDirectory[] =
    FILE_PATH_LITERAL("Local Storage");

const FilePath::CharType DOMStorageContext::kLocalStorageExtension[] =
    FILE_PATH_LITERAL(".localstorage");

static const FilePath::CharType kLocalStorageOldPath[] =
    FILE_PATH_LITERAL("localStorage");

// TODO(jorlow): Remove after Chrome 4 ships.
static void MigrateLocalStorageDirectory(const FilePath& data_path) {
  FilePath new_path = data_path.Append(
      DOMStorageContext::kLocalStorageDirectory);
  FilePath old_path = data_path.Append(kLocalStorageOldPath);
  if (!file_util::DirectoryExists(new_path) &&
      file_util::DirectoryExists(old_path)) {
    file_util::Move(old_path, new_path);
  }
}

DOMStorageContext::DOMStorageContext(WebKitContext* webkit_context)
    : last_storage_area_id_(0),
      last_session_storage_namespace_id_on_ui_thread_(kLocalStorageNamespaceId),
      last_session_storage_namespace_id_on_io_thread_(kLocalStorageNamespaceId),
      webkit_context_(webkit_context) {
}

DOMStorageContext::~DOMStorageContext() {
  // This should not go away until all DOM Storage Dispatcher hosts have gone
  // away.  And they remove themselves from this list.
  DCHECK(dispatcher_host_set_.empty());

  for (StorageNamespaceMap::iterator iter(storage_namespace_map_.begin());
       iter != storage_namespace_map_.end(); ++iter) {
    delete iter->second;
  }
}

int64 DOMStorageContext::AllocateStorageAreaId() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  return ++last_storage_area_id_;
}

int64 DOMStorageContext::AllocateSessionStorageNamespaceId() {
  if (BrowserThread::CurrentlyOn(BrowserThread::UI))
    return ++last_session_storage_namespace_id_on_ui_thread_;
  return --last_session_storage_namespace_id_on_io_thread_;
}

int64 DOMStorageContext::CloneSessionStorage(int64 original_id) {
  DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  int64 clone_id = AllocateSessionStorageNamespaceId();
  BrowserThread::PostTask(
      BrowserThread::WEBKIT, FROM_HERE, NewRunnableFunction(
          &DOMStorageContext::CompleteCloningSessionStorage,
          this, original_id, clone_id));
  return clone_id;
}

void DOMStorageContext::RegisterStorageArea(DOMStorageArea* storage_area) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  int64 id = storage_area->id();
  DCHECK(!GetStorageArea(id));
  storage_area_map_[id] = storage_area;
}

void DOMStorageContext::UnregisterStorageArea(DOMStorageArea* storage_area) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  int64 id = storage_area->id();
  DCHECK(GetStorageArea(id));
  storage_area_map_.erase(id);
}

DOMStorageArea* DOMStorageContext::GetStorageArea(int64 id) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  StorageAreaMap::iterator iter = storage_area_map_.find(id);
  if (iter == storage_area_map_.end())
    return NULL;
  return iter->second;
}

void DOMStorageContext::DeleteSessionStorageNamespace(int64 namespace_id) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  StorageNamespaceMap::iterator iter =
      storage_namespace_map_.find(namespace_id);
  if (iter == storage_namespace_map_.end())
    return;
  DCHECK(iter->second->dom_storage_type() == DOM_STORAGE_SESSION);
  delete iter->second;
  storage_namespace_map_.erase(iter);
}

DOMStorageNamespace* DOMStorageContext::GetStorageNamespace(
    int64 id, bool allocation_allowed) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  StorageNamespaceMap::iterator iter = storage_namespace_map_.find(id);
  if (iter != storage_namespace_map_.end())
    return iter->second;
  if (!allocation_allowed)
    return NULL;
  if (id == kLocalStorageNamespaceId)
    return CreateLocalStorage();
  return CreateSessionStorage(id);
}

void DOMStorageContext::RegisterDispatcherHost(
    DOMStorageDispatcherHost* dispatcher_host) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
  DCHECK(dispatcher_host_set_.find(dispatcher_host) ==
         dispatcher_host_set_.end());
  dispatcher_host_set_.insert(dispatcher_host);
}

void DOMStorageContext::UnregisterDispatcherHost(
    DOMStorageDispatcherHost* dispatcher_host) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
  DCHECK(dispatcher_host_set_.find(dispatcher_host) !=
         dispatcher_host_set_.end());
  dispatcher_host_set_.erase(dispatcher_host);
}

const DOMStorageContext::DispatcherHostSet*
DOMStorageContext::GetDispatcherHostSet() const {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
  return &dispatcher_host_set_;
}

void DOMStorageContext::PurgeMemory() {
  // It is only safe to purge the memory from the LocalStorage namespace,
  // because it is backed by disk and can be reloaded later.  If we purge a
  // SessionStorage namespace, its data will be gone forever, because it isn't
  // currently backed by disk.
  DOMStorageNamespace* local_storage =
      GetStorageNamespace(kLocalStorageNamespaceId, false);
  if (local_storage)
    local_storage->PurgeMemory();
}

void DOMStorageContext::DeleteDataModifiedSince(
    const base::Time& cutoff,
    const char* url_scheme_to_be_skipped,
    const std::vector<string16>& protected_origins) {
  // Make sure that we don't delete a database that's currently being accessed
  // by unloading all of the databases temporarily.
  PurgeMemory();

  file_util::FileEnumerator file_enumerator(
      webkit_context_->data_path().Append(kLocalStorageDirectory), false,
      file_util::FileEnumerator::FILES);
  for (FilePath path = file_enumerator.Next(); !path.value().empty();
       path = file_enumerator.Next()) {
    WebKit::WebSecurityOrigin web_security_origin =
        WebKit::WebSecurityOrigin::createFromDatabaseIdentifier(
            webkit_glue::FilePathToWebString(path.BaseName()));
    if (EqualsASCII(web_security_origin.protocol(), url_scheme_to_be_skipped))
      continue;

    std::vector<string16>::const_iterator find_iter =
        std::find(protected_origins.begin(), protected_origins.end(),
            web_security_origin.databaseIdentifier());
    if (find_iter != protected_origins.end())
      continue;

    file_util::FileEnumerator::FindInfo find_info;
    file_enumerator.GetFindInfo(&find_info);
    if (file_util::HasFileBeenModifiedSince(find_info, cutoff))
      file_util::Delete(path, false);
  }
}

void DOMStorageContext::DeleteLocalStorageFile(const FilePath& file_path) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));

  // Make sure that we don't delete a database that's currently being accessed
  // by unloading all of the databases temporarily.
  // TODO(bulach): both this method and DeleteDataModifiedSince could purge
  // only the memory used by the specific file instead of all memory at once.
  // See http://crbug.com/32000
  PurgeMemory();
  file_util::Delete(file_path, false);
}

void DOMStorageContext::DeleteLocalStorageForOrigin(const string16& origin_id) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  DeleteLocalStorageFile(GetLocalStorageFilePath(origin_id));
}

void DOMStorageContext::DeleteAllLocalStorageFiles() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));

  // Make sure that we don't delete a database that's currently being accessed
  // by unloading all of the databases temporarily.
  PurgeMemory();

  file_util::FileEnumerator file_enumerator(
      webkit_context_->data_path().Append(kLocalStorageDirectory), false,
      file_util::FileEnumerator::FILES);
  for (FilePath file_path = file_enumerator.Next(); !file_path.empty();
       file_path = file_enumerator.Next()) {
    if (file_path.Extension() == kLocalStorageExtension)
      file_util::Delete(file_path, false);
  }
}

DOMStorageNamespace* DOMStorageContext::CreateLocalStorage() {
  FilePath data_path = webkit_context_->data_path();
  FilePath dir_path;
  if (!data_path.empty()) {
    MigrateLocalStorageDirectory(data_path);
    dir_path = data_path.Append(kLocalStorageDirectory);
  }
  DOMStorageNamespace* new_namespace =
      DOMStorageNamespace::CreateLocalStorageNamespace(this, dir_path);
  RegisterStorageNamespace(new_namespace);
  return new_namespace;
}

DOMStorageNamespace* DOMStorageContext::CreateSessionStorage(
    int64 namespace_id) {
  DOMStorageNamespace* new_namespace =
      DOMStorageNamespace::CreateSessionStorageNamespace(this, namespace_id);
  RegisterStorageNamespace(new_namespace);
  return new_namespace;
}

void DOMStorageContext::RegisterStorageNamespace(
    DOMStorageNamespace* storage_namespace) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  int64 id = storage_namespace->id();
  DCHECK(!GetStorageNamespace(id, false));
  storage_namespace_map_[id] = storage_namespace;
}

/* static */
void DOMStorageContext::CompleteCloningSessionStorage(
    DOMStorageContext* context, int64 existing_id, int64 clone_id) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  DOMStorageNamespace* existing_namespace =
      context->GetStorageNamespace(existing_id, false);
  // If nothing exists, then there's nothing to clone.
  if (existing_namespace)
    context->RegisterStorageNamespace(existing_namespace->Copy(clone_id));
}

// static
void DOMStorageContext::ClearLocalState(const FilePath& profile_path,
                                        const char* url_scheme_to_be_skipped) {
  file_util::FileEnumerator file_enumerator(profile_path.Append(
      kLocalStorageDirectory), false, file_util::FileEnumerator::FILES);
  for (FilePath file_path = file_enumerator.Next(); !file_path.empty();
       file_path = file_enumerator.Next()) {
    if (file_path.Extension() == kLocalStorageExtension) {
      WebKit::WebSecurityOrigin web_security_origin =
          WebKit::WebSecurityOrigin::createFromDatabaseIdentifier(
              webkit_glue::FilePathToWebString(file_path.BaseName()));
      if (!EqualsASCII(web_security_origin.protocol(),
                       url_scheme_to_be_skipped))
        file_util::Delete(file_path, false);
    }
  }
}

FilePath DOMStorageContext::GetLocalStorageFilePath(
    const string16& origin_id) const {
  FilePath storageDir = webkit_context_->data_path().Append(
      DOMStorageContext::kLocalStorageDirectory);
  FilePath::StringType id =
      webkit_glue::WebStringToFilePathString(origin_id);
  return storageDir.Append(id.append(kLocalStorageExtension));
}
<commit_msg>Coding style clean up of DomStorageContext.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/in_process_webkit/dom_storage_context.h"

#include <algorithm>

#include "base/file_path.h"
#include "base/file_util.h"
#include "base/string_util.h"
#include "chrome/browser/browser_thread.h"
#include "chrome/browser/in_process_webkit/dom_storage_area.h"
#include "chrome/browser/in_process_webkit/dom_storage_namespace.h"
#include "chrome/browser/in_process_webkit/webkit_context.h"
#include "chrome/common/dom_storage_common.h"
#include "third_party/WebKit/WebKit/chromium/public/WebSecurityOrigin.h"
#include "third_party/WebKit/WebKit/chromium/public/WebString.h"
#include "webkit/glue/webkit_glue.h"

using WebKit::WebSecurityOrigin;

const FilePath::CharType DOMStorageContext::kLocalStorageDirectory[] =
    FILE_PATH_LITERAL("Local Storage");

const FilePath::CharType DOMStorageContext::kLocalStorageExtension[] =
    FILE_PATH_LITERAL(".localstorage");

static const FilePath::CharType kLocalStorageOldPath[] =
    FILE_PATH_LITERAL("localStorage");

// TODO(jorlow): Remove after Chrome 4 ships.
static void MigrateLocalStorageDirectory(const FilePath& data_path) {
  FilePath new_path = data_path.Append(
      DOMStorageContext::kLocalStorageDirectory);
  FilePath old_path = data_path.Append(kLocalStorageOldPath);
  if (!file_util::DirectoryExists(new_path) &&
      file_util::DirectoryExists(old_path)) {
    file_util::Move(old_path, new_path);
  }
}

DOMStorageContext::DOMStorageContext(WebKitContext* webkit_context)
    : last_storage_area_id_(0),
      last_session_storage_namespace_id_on_ui_thread_(kLocalStorageNamespaceId),
      last_session_storage_namespace_id_on_io_thread_(kLocalStorageNamespaceId),
      webkit_context_(webkit_context) {
}

DOMStorageContext::~DOMStorageContext() {
  // This should not go away until all DOM Storage Dispatcher hosts have gone
  // away.  And they remove themselves from this list.
  DCHECK(dispatcher_host_set_.empty());

  for (StorageNamespaceMap::iterator iter(storage_namespace_map_.begin());
       iter != storage_namespace_map_.end(); ++iter) {
    delete iter->second;
  }
}

int64 DOMStorageContext::AllocateStorageAreaId() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  return ++last_storage_area_id_;
}

int64 DOMStorageContext::AllocateSessionStorageNamespaceId() {
  if (BrowserThread::CurrentlyOn(BrowserThread::UI))
    return ++last_session_storage_namespace_id_on_ui_thread_;
  return --last_session_storage_namespace_id_on_io_thread_;
}

int64 DOMStorageContext::CloneSessionStorage(int64 original_id) {
  DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  int64 clone_id = AllocateSessionStorageNamespaceId();
  BrowserThread::PostTask(
      BrowserThread::WEBKIT, FROM_HERE, NewRunnableFunction(
          &DOMStorageContext::CompleteCloningSessionStorage,
          this, original_id, clone_id));
  return clone_id;
}

void DOMStorageContext::RegisterStorageArea(DOMStorageArea* storage_area) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  int64 id = storage_area->id();
  DCHECK(!GetStorageArea(id));
  storage_area_map_[id] = storage_area;
}

void DOMStorageContext::UnregisterStorageArea(DOMStorageArea* storage_area) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  int64 id = storage_area->id();
  DCHECK(GetStorageArea(id));
  storage_area_map_.erase(id);
}

DOMStorageArea* DOMStorageContext::GetStorageArea(int64 id) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  StorageAreaMap::iterator iter = storage_area_map_.find(id);
  if (iter == storage_area_map_.end())
    return NULL;
  return iter->second;
}

void DOMStorageContext::DeleteSessionStorageNamespace(int64 namespace_id) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  StorageNamespaceMap::iterator iter =
      storage_namespace_map_.find(namespace_id);
  if (iter == storage_namespace_map_.end())
    return;
  DCHECK(iter->second->dom_storage_type() == DOM_STORAGE_SESSION);
  delete iter->second;
  storage_namespace_map_.erase(iter);
}

DOMStorageNamespace* DOMStorageContext::GetStorageNamespace(
    int64 id, bool allocation_allowed) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  StorageNamespaceMap::iterator iter = storage_namespace_map_.find(id);
  if (iter != storage_namespace_map_.end())
    return iter->second;
  if (!allocation_allowed)
    return NULL;
  if (id == kLocalStorageNamespaceId)
    return CreateLocalStorage();
  return CreateSessionStorage(id);
}

void DOMStorageContext::RegisterDispatcherHost(
    DOMStorageDispatcherHost* dispatcher_host) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
  DCHECK(dispatcher_host_set_.find(dispatcher_host) ==
         dispatcher_host_set_.end());
  dispatcher_host_set_.insert(dispatcher_host);
}

void DOMStorageContext::UnregisterDispatcherHost(
    DOMStorageDispatcherHost* dispatcher_host) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
  DCHECK(dispatcher_host_set_.find(dispatcher_host) !=
         dispatcher_host_set_.end());
  dispatcher_host_set_.erase(dispatcher_host);
}

const DOMStorageContext::DispatcherHostSet*
DOMStorageContext::GetDispatcherHostSet() const {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
  return &dispatcher_host_set_;
}

void DOMStorageContext::PurgeMemory() {
  // It is only safe to purge the memory from the LocalStorage namespace,
  // because it is backed by disk and can be reloaded later.  If we purge a
  // SessionStorage namespace, its data will be gone forever, because it isn't
  // currently backed by disk.
  DOMStorageNamespace* local_storage =
      GetStorageNamespace(kLocalStorageNamespaceId, false);
  if (local_storage)
    local_storage->PurgeMemory();
}

void DOMStorageContext::DeleteDataModifiedSince(
    const base::Time& cutoff,
    const char* url_scheme_to_be_skipped,
    const std::vector<string16>& protected_origins) {
  // Make sure that we don't delete a database that's currently being accessed
  // by unloading all of the databases temporarily.
  PurgeMemory();

  file_util::FileEnumerator file_enumerator(
      webkit_context_->data_path().Append(kLocalStorageDirectory), false,
      file_util::FileEnumerator::FILES);
  for (FilePath path = file_enumerator.Next(); !path.value().empty();
       path = file_enumerator.Next()) {
    WebSecurityOrigin web_security_origin =
        WebSecurityOrigin::createFromDatabaseIdentifier(
            webkit_glue::FilePathToWebString(path.BaseName()));
    if (EqualsASCII(web_security_origin.protocol(), url_scheme_to_be_skipped))
      continue;

    std::vector<string16>::const_iterator find_iter =
        std::find(protected_origins.begin(), protected_origins.end(),
            web_security_origin.databaseIdentifier());
    if (find_iter != protected_origins.end())
      continue;

    file_util::FileEnumerator::FindInfo find_info;
    file_enumerator.GetFindInfo(&find_info);
    if (file_util::HasFileBeenModifiedSince(find_info, cutoff))
      file_util::Delete(path, false);
  }
}

void DOMStorageContext::DeleteLocalStorageFile(const FilePath& file_path) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));

  // Make sure that we don't delete a database that's currently being accessed
  // by unloading all of the databases temporarily.
  // TODO(bulach): both this method and DeleteDataModifiedSince could purge
  // only the memory used by the specific file instead of all memory at once.
  // See http://crbug.com/32000
  PurgeMemory();
  file_util::Delete(file_path, false);
}

void DOMStorageContext::DeleteLocalStorageForOrigin(const string16& origin_id) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  DeleteLocalStorageFile(GetLocalStorageFilePath(origin_id));
}

void DOMStorageContext::DeleteAllLocalStorageFiles() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));

  // Make sure that we don't delete a database that's currently being accessed
  // by unloading all of the databases temporarily.
  PurgeMemory();

  file_util::FileEnumerator file_enumerator(
      webkit_context_->data_path().Append(kLocalStorageDirectory), false,
      file_util::FileEnumerator::FILES);
  for (FilePath file_path = file_enumerator.Next(); !file_path.empty();
       file_path = file_enumerator.Next()) {
    if (file_path.Extension() == kLocalStorageExtension)
      file_util::Delete(file_path, false);
  }
}

DOMStorageNamespace* DOMStorageContext::CreateLocalStorage() {
  FilePath data_path = webkit_context_->data_path();
  FilePath dir_path;
  if (!data_path.empty()) {
    MigrateLocalStorageDirectory(data_path);
    dir_path = data_path.Append(kLocalStorageDirectory);
  }
  DOMStorageNamespace* new_namespace =
      DOMStorageNamespace::CreateLocalStorageNamespace(this, dir_path);
  RegisterStorageNamespace(new_namespace);
  return new_namespace;
}

DOMStorageNamespace* DOMStorageContext::CreateSessionStorage(
    int64 namespace_id) {
  DOMStorageNamespace* new_namespace =
      DOMStorageNamespace::CreateSessionStorageNamespace(this, namespace_id);
  RegisterStorageNamespace(new_namespace);
  return new_namespace;
}

void DOMStorageContext::RegisterStorageNamespace(
    DOMStorageNamespace* storage_namespace) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  int64 id = storage_namespace->id();
  DCHECK(!GetStorageNamespace(id, false));
  storage_namespace_map_[id] = storage_namespace;
}

/* static */
void DOMStorageContext::CompleteCloningSessionStorage(
    DOMStorageContext* context, int64 existing_id, int64 clone_id) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  DOMStorageNamespace* existing_namespace =
      context->GetStorageNamespace(existing_id, false);
  // If nothing exists, then there's nothing to clone.
  if (existing_namespace)
    context->RegisterStorageNamespace(existing_namespace->Copy(clone_id));
}

// static
void DOMStorageContext::ClearLocalState(const FilePath& profile_path,
                                        const char* url_scheme_to_be_skipped) {
  file_util::FileEnumerator file_enumerator(profile_path.Append(
      kLocalStorageDirectory), false, file_util::FileEnumerator::FILES);
  for (FilePath file_path = file_enumerator.Next(); !file_path.empty();
       file_path = file_enumerator.Next()) {
    if (file_path.Extension() == kLocalStorageExtension) {
      WebSecurityOrigin web_security_origin =
          WebSecurityOrigin::createFromDatabaseIdentifier(
              webkit_glue::FilePathToWebString(file_path.BaseName()));
      if (!EqualsASCII(web_security_origin.protocol(),
                       url_scheme_to_be_skipped)) {
        file_util::Delete(file_path, false);
      }
    }
  }
}

FilePath DOMStorageContext::GetLocalStorageFilePath(
    const string16& origin_id) const {
  FilePath storageDir = webkit_context_->data_path().Append(
      DOMStorageContext::kLocalStorageDirectory);
  FilePath::StringType id =
      webkit_glue::WebStringToFilePathString(origin_id);
  return storageDir.Append(id.append(kLocalStorageExtension));
}
<|endoftext|>


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

#include "chrome/browser/password_manager/login_database.h"

#include "base/utf_string_conversions.h"

// TODO: Actually encrypt passwords on Linux.

std::string LoginDatabase::EncryptedString(const string16& plain_text)
    const {
  return UTF16ToUTF8(plain_text);
}

string16 LoginDatabase::DecryptedString(const std::string& cipher_text)
    const {
  return ASCIIToUTF16(cipher_text);
}
<commit_msg>Linux: fix retrieving passwords with non-ASCII characters from the default password store. TEST=save a password containing a non-ASCII character, it should autofill correctly BUG=54065 Review URL: http://codereview.chromium.org/3316014<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/password_manager/login_database.h"

#include "base/utf_string_conversions.h"

// TODO: Actually encrypt passwords on Linux.

std::string LoginDatabase::EncryptedString(const string16& plain_text)
    const {
  return UTF16ToUTF8(plain_text);
}

string16 LoginDatabase::DecryptedString(const std::string& cipher_text)
    const {
  return UTF8ToUTF16(cipher_text);
}
<|endoftext|>


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

#ifndef ORGANIZED_COMPRESSION_HPP
#define ORGANIZED_COMPRESSION_HPP

#include <pcl/compression/organized_pointcloud_compression.h>

#include <pcl/pcl_macros.h>
#include <pcl/point_cloud.h>

#include <pcl/common/boost.h>
#include <pcl/common/eigen.h>
#include <pcl/common/common.h>
#include <pcl/common/io.h>

#include <pcl/compression/libpng_wrapper.h>
#include <pcl/compression/organized_pointcloud_conversion.h>

#include <string>
#include <vector>
#include <limits>
#include <assert.h>

namespace pcl
{
  namespace io
  {
    //////////////////////////////////////////////////////////////////////////////////////////////
    template<typename PointT> void
    OrganizedPointCloudCompression<PointT>::encodePointCloud (const PointCloudConstPtr &cloud_arg,
                                                              std::ostream& compressedDataOut_arg,
                                                              bool doColorEncoding,
                                                              bool bShowStatistics_arg,
                                                              int pngLevel_arg,
                                                              float depthQuantization_arg)
    {
      uint32_t cloud_width = cloud_arg->width;
      uint32_t cloud_height = cloud_arg->height;

      float maxDepth, vocalLength;

      analyzeOrganizedCloud (cloud_arg, maxDepth, vocalLength);

      // encode header identifier
      compressedDataOut_arg.write (reinterpret_cast<const char*> (frameHeaderIdentifier_), strlen (frameHeaderIdentifier_));
      // encode point cloud width
      compressedDataOut_arg.write (reinterpret_cast<const char*> (&cloud_width), sizeof (cloud_width));
      // encode frame type height
      compressedDataOut_arg.write (reinterpret_cast<const char*> (&cloud_height), sizeof (cloud_height));
      // encode frame max depth
      compressedDataOut_arg.write (reinterpret_cast<const char*> (&maxDepth), sizeof (maxDepth));
      // encode frame focal lenght
      compressedDataOut_arg.write (reinterpret_cast<const char*> (&vocalLength), sizeof (vocalLength));
      // encode frame depth quantization
      compressedDataOut_arg.write (reinterpret_cast<const char*> (&depthQuantization_arg), sizeof (depthQuantization_arg));

      // disparity and rgb image data
      std::vector<uint16_t> disparityData;
      std::vector<uint8_t> rgbData;

      // compressed disparity and rgb image data
      std::vector<uint8_t> compressedDisparity;
      std::vector<uint8_t> compressedRGB;

      uint32_t compressedDisparitySize = 0;
      uint32_t compressedRGBSize = 0;

      // Convert point cloud to disparity and rgb image
      OrganizedConversion<PointT>::convert (*cloud_arg, maxDepth,  depthQuantization_arg, disparityData, rgbData);

      // Compress disparity information
      encodeMonoImageToPNG (disparityData, cloud_width, cloud_height, compressedDisparity, pngLevel_arg);

      compressedDisparitySize = static_cast<uint32_t>(compressedDisparity.size());
      // Encode size of compressed disparity image data
      compressedDataOut_arg.write (reinterpret_cast<const char*> (&compressedDisparitySize), sizeof (compressedDisparitySize));
      // Output compressed disparity to ostream
      compressedDataOut_arg.write (reinterpret_cast<const char*> (&compressedDisparity[0]), compressedDisparity.size () * sizeof(uint8_t));

      // Compress color information
      if (CompressionPointTraits<PointT>::hasColor && doColorEncoding)
        encodeRGBImageToPNG (rgbData, cloud_width, cloud_height, compressedRGB, 1 /*Z_BEST_SPEED*/);

      compressedRGBSize = static_cast<uint32_t>(compressedRGB.size ());
      // Encode size of compressed RGB image data
      compressedDataOut_arg.write (reinterpret_cast<const char*> (&compressedRGBSize), sizeof (compressedRGBSize));
      // Output compressed disparity to ostream
      compressedDataOut_arg.write (reinterpret_cast<const char*> (&compressedRGB[0]), compressedRGB.size () * sizeof(uint8_t));

      if (bShowStatistics_arg)
      {
        uint64_t pointCount = cloud_width * cloud_height;
        float bytesPerPoint = static_cast<float> (compressedDisparitySize+compressedRGBSize) / static_cast<float> (pointCount);

        PCL_INFO("*** POINTCLOUD ENCODING ***\n");
        PCL_INFO("Number of encoded points: %ld\n", pointCount);
        PCL_INFO("Size of uncompressed point cloud: %.2f kBytes\n", (static_cast<float> (pointCount) * CompressionPointTraits<PointT>::bytesPerPoint) / 1024.0f);
        PCL_INFO("Size of compressed point cloud: %.2f kBytes\n", static_cast<float> (compressedDisparitySize+compressedRGBSize) / 1024.0f);
        PCL_INFO("Total bytes per point: %.4f bytes\n", static_cast<float> (bytesPerPoint));
        PCL_INFO("Total compression percentage: %.4f%%\n", (bytesPerPoint) / (CompressionPointTraits<PointT>::bytesPerPoint) * 100.0f);
        PCL_INFO("Compression ratio: %.2f\n\n", static_cast<float> (CompressionPointTraits<PointT>::bytesPerPoint) / bytesPerPoint);
      }
    }

    //////////////////////////////////////////////////////////////////////////////////////////////
    template<typename PointT> void
    OrganizedPointCloudCompression<PointT>::decodePointCloud (std::istream& compressedDataIn_arg,
                                                              PointCloudPtr &cloud_arg,
                                                              bool bShowStatistics_arg)
    {
      // sync to frame header
      unsigned int headerIdPos = 0;
      while (headerIdPos < strlen (frameHeaderIdentifier_))
      {
        char readChar;
        compressedDataIn_arg.read (static_cast<char*> (&readChar), sizeof (readChar));
        if (readChar != frameHeaderIdentifier_[headerIdPos++])
          headerIdPos = (frameHeaderIdentifier_[0] == readChar) ? 1 : 0;
      }

      uint32_t cloud_width;
      uint32_t cloud_height;
      float maxDepth, vocalLength;
      float depthQuantization;

      // reading frame header
      compressedDataIn_arg.read (reinterpret_cast<char*> (&cloud_width), sizeof (cloud_width));
      compressedDataIn_arg.read (reinterpret_cast<char*> (&cloud_height), sizeof (cloud_height));
      compressedDataIn_arg.read (reinterpret_cast<char*> (&maxDepth), sizeof (maxDepth));
      compressedDataIn_arg.read (reinterpret_cast<char*> (&vocalLength), sizeof (vocalLength));
      compressedDataIn_arg.read (reinterpret_cast<char*> (&depthQuantization), sizeof (depthQuantization));

      // disparity and rgb image data
      std::vector<uint16_t> disparityData;
      std::vector<uint8_t> rgbData;

      // compressed disparity and rgb image data
      std::vector<uint8_t> compressedDisparity;
      std::vector<uint8_t> compressedRGB;

      uint32_t compressedDisparitySize;
      uint32_t compressedRGBSize;

      // reading compressed disparity data
      compressedDataIn_arg.read (reinterpret_cast<char*> (&compressedDisparitySize), sizeof (compressedDisparitySize));
      compressedDisparity.resize (compressedDisparitySize);
      compressedDataIn_arg.read (reinterpret_cast<char*> (&compressedDisparity[0]), compressedDisparitySize * sizeof(uint8_t));

      // reading compressed rgb data
      compressedDataIn_arg.read (reinterpret_cast<char*> (&compressedRGBSize), sizeof (compressedRGBSize));
      compressedRGB.resize (compressedRGBSize);
      compressedDataIn_arg.read (reinterpret_cast<char*> (&compressedRGB[0]), compressedRGBSize * sizeof(uint8_t));

      // PNG decoded parameters
      size_t png_width;
      size_t png_height;
      unsigned int png_channels;

      // decode PNG compressed disparity data
      decodePNGToImage (compressedDisparity, disparityData, png_width, png_height, png_channels);

      // decode PNG compressed rgb data
      decodePNGToImage (compressedRGB, rgbData, png_width, png_height, png_channels);

      // reconstruct point cloud
      OrganizedConversion<PointT>::convert (disparityData, rgbData, cloud_width, cloud_height, maxDepth, depthQuantization, vocalLength, *cloud_arg);

      if (bShowStatistics_arg)
      {
        uint64_t pointCount = cloud_width * cloud_height;
        float bytesPerPoint = static_cast<float> (compressedDisparitySize+compressedRGBSize) / static_cast<float> (pointCount);

        PCL_INFO("*** POINTCLOUD DECODING ***\n");
        PCL_INFO("Number of encoded points: %ld\n", pointCount);
        PCL_INFO("Size of uncompressed point cloud: %.2f kBytes\n", (static_cast<float> (pointCount) * CompressionPointTraits<PointT>::bytesPerPoint) / 1024.0f);
        PCL_INFO("Size of compressed point cloud: %.2f kBytes\n", static_cast<float> (compressedDisparitySize+compressedRGBSize) / 1024.0f);
        PCL_INFO("Total bytes per point: %.4f bytes\n", static_cast<float> (bytesPerPoint));
        PCL_INFO("Total compression percentage: %.4f%%\n", (bytesPerPoint) / (CompressionPointTraits<PointT>::bytesPerPoint) * 100.0f);
        PCL_INFO("Compression ratio: %.2f\n\n", static_cast<float> (CompressionPointTraits<PointT>::bytesPerPoint) / bytesPerPoint);
      }
    }

    //////////////////////////////////////////////////////////////////////////////////////////////
    template<typename PointT> void
    OrganizedPointCloudCompression<PointT>::analyzeOrganizedCloud (PointCloudConstPtr cloud_arg,
                                                                   float& maxDepth_arg,
                                                                   float& vocalLength_arg) const
    {
      size_t width, height, it;
      int centerX, centerY;
      int x, y;
      float maxDepth;
      float focalLength;

      width = cloud_arg->width;
      height = cloud_arg->height;

      // Center of organized point cloud
      centerX = static_cast<int> (width / 2);
      centerY = static_cast<int> (height / 2);

      // Ensure we have an organized point cloud
      assert((width>1) && (height>1));
      assert(width*height == cloud_arg->points.size());

      maxDepth = 0;
      focalLength = 0;

      it = 0;
      for (y = -centerY; y < +centerY; ++y)
        for (x = -centerX; x < +centerX; ++x)
        {
          const PointT& point = cloud_arg->points[it++];

          if (pcl::isFinite (point))
          {
            if (maxDepth < point.z)
            {
              // Update maximum depth
              maxDepth = point.z;

              // Calculate focal length
              focalLength = 2.0f / (point.x / (static_cast<float> (x) * point.z) + point.y / (static_cast<float> (y) * point.z));
            }
          }
        }

      // Update return values
      maxDepth_arg = maxDepth;
      vocalLength_arg = focalLength;
    }

  }
}

#endif

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

#ifndef ORGANIZED_COMPRESSION_HPP
#define ORGANIZED_COMPRESSION_HPP

#include <pcl/compression/organized_pointcloud_compression.h>

#include <pcl/pcl_macros.h>
#include <pcl/point_cloud.h>

#include <pcl/common/boost.h>
#include <pcl/common/eigen.h>
#include <pcl/common/common.h>
#include <pcl/common/io.h>

#include <pcl/compression/libpng_wrapper.h>
#include <pcl/compression/organized_pointcloud_conversion.h>

#include <string>
#include <vector>
#include <limits>
#include <assert.h>

namespace pcl
{
  namespace io
  {
    //////////////////////////////////////////////////////////////////////////////////////////////
    template<typename PointT> void
    OrganizedPointCloudCompression<PointT>::encodePointCloud (const PointCloudConstPtr &cloud_arg,
                                                              std::ostream& compressedDataOut_arg,
                                                              bool doColorEncoding,
                                                              bool bShowStatistics_arg,
                                                              int pngLevel_arg,
                                                              float depthQuantization_arg)
    {
      uint32_t cloud_width = cloud_arg->width;
      uint32_t cloud_height = cloud_arg->height;

      float maxDepth, vocalLength;

      analyzeOrganizedCloud (cloud_arg, maxDepth, vocalLength);

      // encode header identifier
      compressedDataOut_arg.write (reinterpret_cast<const char*> (frameHeaderIdentifier_), strlen (frameHeaderIdentifier_));
      // encode point cloud width
      compressedDataOut_arg.write (reinterpret_cast<const char*> (&cloud_width), sizeof (cloud_width));
      // encode frame type height
      compressedDataOut_arg.write (reinterpret_cast<const char*> (&cloud_height), sizeof (cloud_height));
      // encode frame max depth
      compressedDataOut_arg.write (reinterpret_cast<const char*> (&maxDepth), sizeof (maxDepth));
      // encode frame focal lenght
      compressedDataOut_arg.write (reinterpret_cast<const char*> (&vocalLength), sizeof (vocalLength));
      // encode frame depth quantization
      compressedDataOut_arg.write (reinterpret_cast<const char*> (&depthQuantization_arg), sizeof (depthQuantization_arg));

      // disparity and rgb image data
      std::vector<uint16_t> disparityData;
      std::vector<uint8_t> rgbData;

      // compressed disparity and rgb image data
      std::vector<uint8_t> compressedDisparity;
      std::vector<uint8_t> compressedRGB;

      uint32_t compressedDisparitySize = 0;
      uint32_t compressedRGBSize = 0;

      // Convert point cloud to disparity and rgb image
      OrganizedConversion<PointT>::convert (*cloud_arg, maxDepth,  depthQuantization_arg, disparityData, rgbData);

      // Compress disparity information
      encodeMonoImageToPNG (disparityData, cloud_width, cloud_height, compressedDisparity, pngLevel_arg);

      compressedDisparitySize = static_cast<uint32_t>(compressedDisparity.size());
      // Encode size of compressed disparity image data
      compressedDataOut_arg.write (reinterpret_cast<const char*> (&compressedDisparitySize), sizeof (compressedDisparitySize));
      // Output compressed disparity to ostream
      compressedDataOut_arg.write (reinterpret_cast<const char*> (&compressedDisparity[0]), compressedDisparity.size () * sizeof(uint8_t));

      // Compress color information
      if (CompressionPointTraits<PointT>::hasColor && doColorEncoding)
        encodeRGBImageToPNG (rgbData, cloud_width, cloud_height, compressedRGB, 1 /*Z_BEST_SPEED*/);

      compressedRGBSize = static_cast<uint32_t>(compressedRGB.size ());
      // Encode size of compressed RGB image data
      compressedDataOut_arg.write (reinterpret_cast<const char*> (&compressedRGBSize), sizeof (compressedRGBSize));
      // Output compressed disparity to ostream
      compressedDataOut_arg.write (reinterpret_cast<const char*> (&compressedRGB[0]), compressedRGB.size () * sizeof(uint8_t));

      if (bShowStatistics_arg)
      {
        uint64_t pointCount = cloud_width * cloud_height;
        float bytesPerPoint = static_cast<float> (compressedDisparitySize+compressedRGBSize) / static_cast<float> (pointCount);

        PCL_INFO("*** POINTCLOUD ENCODING ***\n");
        PCL_INFO("Number of encoded points: %ld\n", pointCount);
        PCL_INFO("Size of uncompressed point cloud: %.2f kBytes\n", (static_cast<float> (pointCount) * CompressionPointTraits<PointT>::bytesPerPoint) / 1024.0f);
        PCL_INFO("Size of compressed point cloud: %.2f kBytes\n", static_cast<float> (compressedDisparitySize+compressedRGBSize) / 1024.0f);
        PCL_INFO("Total bytes per point: %.4f bytes\n", static_cast<float> (bytesPerPoint));
        PCL_INFO("Total compression percentage: %.4f%%\n", (bytesPerPoint) / (CompressionPointTraits<PointT>::bytesPerPoint) * 100.0f);
        PCL_INFO("Compression ratio: %.2f\n\n", static_cast<float> (CompressionPointTraits<PointT>::bytesPerPoint) / bytesPerPoint);
      }
    }

    //////////////////////////////////////////////////////////////////////////////////////////////
    template<typename PointT> void
    OrganizedPointCloudCompression<PointT>::decodePointCloud (std::istream& compressedDataIn_arg,
                                                              PointCloudPtr &cloud_arg,
                                                              bool bShowStatistics_arg)
    {
      uint32_t cloud_width;
      uint32_t cloud_height;
      float maxDepth, vocalLength;
      float depthQuantization;

      // disparity and rgb image data
      std::vector<uint16_t> disparityData;
      std::vector<uint8_t> rgbData;

      // compressed disparity and rgb image data
      std::vector<uint8_t> compressedDisparity;
      std::vector<uint8_t> compressedRGB;

      uint32_t compressedDisparitySize;
      uint32_t compressedRGBSize;

      // PNG decoded parameters
      size_t png_width = 0;
      size_t png_height = 0;
      unsigned int png_channels = 1;

      // sync to frame header
      unsigned int headerIdPos = 0;
      bool valid_stream = true;
      while (valid_stream && (headerIdPos < strlen (frameHeaderIdentifier_)))
      {
        char readChar;
        compressedDataIn_arg.read (static_cast<char*> (&readChar), sizeof (readChar));
        if (readChar != frameHeaderIdentifier_[headerIdPos++])
          headerIdPos = (frameHeaderIdentifier_[0] == readChar) ? 1 : 0;

        valid_stream=compressedDataIn_arg.good ();
      }

      if (valid_stream) {

        // reading frame header
        compressedDataIn_arg.read (reinterpret_cast<char*> (&cloud_width), sizeof (cloud_width));
        compressedDataIn_arg.read (reinterpret_cast<char*> (&cloud_height), sizeof (cloud_height));
        compressedDataIn_arg.read (reinterpret_cast<char*> (&maxDepth), sizeof (maxDepth));
        compressedDataIn_arg.read (reinterpret_cast<char*> (&vocalLength), sizeof (vocalLength));
        compressedDataIn_arg.read (reinterpret_cast<char*> (&depthQuantization), sizeof (depthQuantization));

        // reading compressed disparity data
        compressedDataIn_arg.read (reinterpret_cast<char*> (&compressedDisparitySize), sizeof (compressedDisparitySize));
        compressedDisparity.resize (compressedDisparitySize);
        compressedDataIn_arg.read (reinterpret_cast<char*> (&compressedDisparity[0]), compressedDisparitySize * sizeof(uint8_t));

        // reading compressed rgb data
        compressedDataIn_arg.read (reinterpret_cast<char*> (&compressedRGBSize), sizeof (compressedRGBSize));
        compressedRGB.resize (compressedRGBSize);
        compressedDataIn_arg.read (reinterpret_cast<char*> (&compressedRGB[0]), compressedRGBSize * sizeof(uint8_t));

        // decode PNG compressed disparity data
        decodePNGToImage (compressedDisparity, disparityData, png_width, png_height, png_channels);

        // decode PNG compressed rgb data
        decodePNGToImage (compressedRGB, rgbData, png_width, png_height, png_channels);
      }

      // reconstruct point cloud
      OrganizedConversion<PointT>::convert (disparityData, rgbData, cloud_width, cloud_height, maxDepth, depthQuantization, vocalLength, *cloud_arg);

      if (bShowStatistics_arg)
      {
        uint64_t pointCount = cloud_width * cloud_height;
        float bytesPerPoint = static_cast<float> (compressedDisparitySize+compressedRGBSize) / static_cast<float> (pointCount);

        PCL_INFO("*** POINTCLOUD DECODING ***\n");
        PCL_INFO("Number of encoded points: %ld\n", pointCount);
        PCL_INFO("Size of uncompressed point cloud: %.2f kBytes\n", (static_cast<float> (pointCount) * CompressionPointTraits<PointT>::bytesPerPoint) / 1024.0f);
        PCL_INFO("Size of compressed point cloud: %.2f kBytes\n", static_cast<float> (compressedDisparitySize+compressedRGBSize) / 1024.0f);
        PCL_INFO("Total bytes per point: %.4f bytes\n", static_cast<float> (bytesPerPoint));
        PCL_INFO("Total compression percentage: %.4f%%\n", (bytesPerPoint) / (CompressionPointTraits<PointT>::bytesPerPoint) * 100.0f);
        PCL_INFO("Compression ratio: %.2f\n\n", static_cast<float> (CompressionPointTraits<PointT>::bytesPerPoint) / bytesPerPoint);
      }
    }

    //////////////////////////////////////////////////////////////////////////////////////////////
    template<typename PointT> void
    OrganizedPointCloudCompression<PointT>::analyzeOrganizedCloud (PointCloudConstPtr cloud_arg,
                                                                   float& maxDepth_arg,
                                                                   float& vocalLength_arg) const
    {
      size_t width, height, it;
      int centerX, centerY;
      int x, y;
      float maxDepth;
      float focalLength;

      width = cloud_arg->width;
      height = cloud_arg->height;

      // Center of organized point cloud
      centerX = static_cast<int> (width / 2);
      centerY = static_cast<int> (height / 2);

      // Ensure we have an organized point cloud
      assert((width>1) && (height>1));
      assert(width*height == cloud_arg->points.size());

      maxDepth = 0;
      focalLength = 0;

      it = 0;
      for (y = -centerY; y < +centerY; ++y)
        for (x = -centerX; x < +centerX; ++x)
        {
          const PointT& point = cloud_arg->points[it++];

          if (pcl::isFinite (point))
          {
            if (maxDepth < point.z)
            {
              // Update maximum depth
              maxDepth = point.z;

              // Calculate focal length
              focalLength = 2.0f / (point.x / (static_cast<float> (x) * point.z) + point.y / (static_cast<float> (y) * point.z));
            }
          }
        }

      // Update return values
      maxDepth_arg = maxDepth;
      vocalLength_arg = focalLength;
    }

  }
}

#endif

<|endoftext|>