<commit_before>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org

Copyright (c) 2000-2013 Torus Knot Software Ltd
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#include "SamplePlugin.h"
#include "VolumeCSG.h"

#include "OgreVolumeCSGSource.h"
#include "OgreVolumeCacheSource.h"
#include "OgreVolumeTextureSource.h"
#include "OgreVolumeMeshBuilder.h"
#include "OgreMath.h"

using namespace Ogre;
using namespace OgreBites;
using namespace Ogre::Volume;

void Sample_VolumeCSG::setupContent(void)
{
    setupControls();
    setupShaderGenerator();
    Real size = (Real)31.0;
    Vector3 to(size);

    // Light
    Light* directionalLight0 = mSceneMgr->createLight("directionalLight0");
    directionalLight0->setType(Light::LT_DIRECTIONAL);
    directionalLight0->setDirection(Vector3((Real)1, (Real)-1, (Real)1));
    directionalLight0->setDiffuseColour((Real)1, (Real)0.98, (Real)0.73);
    directionalLight0->setSpecularColour((Real)0.1, (Real)0.1, (Real)0.1);

    // Spheres
    CSGSphereSource sphere1((Real)5.0, Vector3((Real)5.5));
    CSGSphereSource sphere2((Real)5.0, Vector3((Real)25.5, (Real)5.5, (Real)5.5));
    CSGSphereSource sphere3((Real)5.0, Vector3((Real)25.5, (Real)5.5, (Real)25.5));
    CSGSphereSource sphere4((Real)5.0, Vector3((Real)5.5, (Real)5.5, (Real)25.5));

    // Cubes
    Real halfWidth = (Real)(2.5 / 2.0);
    CSGCubeSource cube1(Vector3((Real)5.5 - halfWidth), Vector3((Real)25.5 + halfWidth, (Real)5.5 + halfWidth, (Real)25.5 + halfWidth));
    CSGCubeSource cube2(Vector3((Real)5.5 + halfWidth, (Real)0.0, (Real)5.5 + halfWidth), Vector3((Real)25.5 - halfWidth, to.y, (Real)25.5 - halfWidth));
    CSGDifferenceSource difference1(&cube1, &cube2);

    // Inner rounded cube
    Real innerHalfWidth = (Real)(7.0 / 2.0);
    Vector3 center((Real)15.5, (Real)5.5, (Real)15.5);
    CSGCubeSource cube3(center - innerHalfWidth, center + innerHalfWidth);
    CSGSphereSource sphere5(innerHalfWidth + (Real)0.75, center);
    CSGIntersectionSource intersection1(&cube3, &sphere5);

    // A plane with noise
    CSGPlaneSource plane1((Real)1.0, Vector3::UNIT_Y);
    Real frequencies[] = {(Real)1.01, (Real)0.48};
    Real amplitudes[] = {(Real)0.25, (Real)0.5};
    CSGNoiseSource noise1(&plane1, frequencies, amplitudes, 2, 100);

    // Combine everything
    CSGUnionSource union1(&sphere1, &sphere2);
    CSGUnionSource union2(&union1, &sphere3);
    CSGUnionSource union3(&union2, &sphere4);
    CSGUnionSource union4(&union3, &difference1);
    CSGUnionSource union5(&union4, &intersection1);
    CSGUnionSource union6(&union5, &noise1);
    Source *src = &union6;

    mVolumeRoot = OGRE_NEW Chunk();
    SceneNode *volumeRootNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("VolumeParent");

    ChunkParameters parameters;
    parameters.sceneManager = mSceneMgr;
    parameters.src = src;
    parameters.baseError = (Real)0.25;

    mVolumeRoot->load(volumeRootNode, Vector3::ZERO, to, 1, &parameters);

    mVolumeRoot->setMaterial("Ogre/RTShader/TriplanarTexturing");

    // Camera
    mCamera->setPosition(to + (Real)7.5);
    mCamera->lookAt(center + (Real)11.0);
    mCamera->setNearClipDistance((Real)0.5);

    mRotation = (Real)0.0;

}

//-----------------------------------------------------------------------

void Sample_VolumeCSG::setupControls(void)
{
    mTrayMgr->showCursor();
#if OGRE_PLATFORM != OGRE_PLATFORM_APPLE_IOS
        setDragLook(true);
#endif
    mCameraMan->setStyle(OgreBites::CS_MANUAL);
    mCameraMan->setTopSpeed((Real)25.0);
    // make room for the volume
    mTrayMgr->showLogo(TL_TOPRIGHT);
    mTrayMgr->showFrameStats(TL_TOPRIGHT);
    mTrayMgr->toggleAdvancedFrameStats();
}

//-----------------------------------------------------------------------

void Sample_VolumeCSG::setupShaderGenerator()
{
    RTShader::ShaderGenerator* mGen = RTShader::ShaderGenerator::getSingletonPtr();

    RTShader::RenderState* pMainRenderState =
        mGen->createOrRetrieveRenderState(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME).first;
    pMainRenderState->reset();

    mGen->invalidateScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME);

    // Make this viewport work with shader generator scheme.
    mViewport->setMaterialScheme(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME);
}

//-----------------------------------------------------------------------

void Sample_VolumeCSG::cleanupContent(void)
{
    OGRE_DELETE mVolumeRoot;
    mVolumeRoot = 0;
}

//-----------------------------------------------------------------------

Sample_VolumeCSG::Sample_VolumeCSG(void) : mVolumeRoot(0), mHideAll(false)
{
    mInfo["Title"] = "Volume CSG and RTSS triplanar texturing";
    mInfo["Description"] = "Demonstrates a volumetric CSG scene, showing sphere, cube, plane, union, difference and intersection. The triplanar texturing is generated by the RTSS.";
    mInfo["Thumbnail"] = "thumb_volumecsg.png";
    mInfo["Category"] = "Geometry";
}

//-----------------------------------------------------------------------

bool Sample_VolumeCSG::keyPressed(const OIS::KeyEvent& evt)
{
    if (evt.key == OIS::KC_H)
    {
        if (mHideAll)
        {
            mTrayMgr->showAll();
        }
        else
        {
            mTrayMgr->hideAll();
        }
        mHideAll = !mHideAll;
    }
    return SdkSample::keyPressed(evt);
}

bool Sample_VolumeCSG::frameRenderingQueued(const Ogre::FrameEvent& evt)
{
    Vector3 center((Real)15.5, (Real)5.5, (Real)15.5);
    mRotation += Radian(evt.timeSinceLastFrame * (Real)0.5);
    Real r = (Real)35.0;
    mCamera->setPosition(
        Math::Sin(mRotation) * r + center.x,
        (Real)15.0 + center.y,
        Math::Cos(mRotation) * r + center.z
    );
    mCamera->lookAt(center);
    return SdkSample::frameRenderingQueued(evt);
}

//-----------------------------------------------------------------------

void Sample_VolumeCSG::_shutdown()
{
    RTShader::RenderState* pMainRenderState =
        RTShader::ShaderGenerator::getSingleton().createOrRetrieveRenderState(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME).first;
    pMainRenderState->reset();

    SdkSample::_shutdown();
}

//-----------------------------------------------------------------------

#ifndef OGRE_STATIC_LIB

SamplePlugin* sp;
Sample* s;

//-----------------------------------------------------------------------

extern "C" _OgreSampleExport void dllStartPlugin()
{
    s = new Sample_VolumeCSG();
    sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample");
    sp->addSample(s);
    Root::getSingleton().installPlugin(sp);
}

//-----------------------------------------------------------------------

extern "C" _OgreSampleExport void dllStopPlugin()
{
    Root::getSingleton().uninstallPlugin(sp);
    OGRE_DELETE sp;
    delete s;
}

#endif
<commit_msg>Re-merge to hopefully fix problems (back out original change set that was incorrectly merged)<commit_after>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org

Copyright (c) 2000-2013 Torus Knot Software Ltd
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#include "SamplePlugin.h"
#include "VolumeCSG.h"

#include "OgreVolumeCSGSource.h"
#include "OgreVolumeCacheSource.h"
#include "OgreVolumeTextureSource.h"
#include "OgreVolumeMeshBuilder.h"
#include "OgreMath.h"

using namespace Ogre;
using namespace OgreBites;
using namespace Ogre::Volume;

void Sample_VolumeCSG::setupContent(void)
{
    setupControls();
    setupShaderGenerator();
    Real size = (Real)31.0;
    Vector3 to(size);

    // Light
    Light* directionalLight0 = mSceneMgr->createLight("directionalLight0");
    directionalLight0->setType(Light::LT_DIRECTIONAL);
    directionalLight0->setDirection(Vector3((Real)1, (Real)-1, (Real)1));
    directionalLight0->setDiffuseColour((Real)1, (Real)0.98, (Real)0.73);
    directionalLight0->setSpecularColour((Real)0.1, (Real)0.1, (Real)0.1);

    // Spheres
    CSGSphereSource sphere1((Real)5.0, Vector3((Real)5.5));
    CSGSphereSource sphere2((Real)5.0, Vector3((Real)25.5, (Real)5.5, (Real)5.5));
    CSGSphereSource sphere3((Real)5.0, Vector3((Real)25.5, (Real)5.5, (Real)25.5));
    CSGSphereSource sphere4((Real)5.0, Vector3((Real)5.5, (Real)5.5, (Real)25.5));

    // Cubes
    Real halfWidth = (Real)(2.5 / 2.0);
    CSGCubeSource cube1(Vector3((Real)5.5 - halfWidth), Vector3((Real)25.5 + halfWidth, (Real)5.5 + halfWidth, (Real)25.5 + halfWidth));
    CSGCubeSource cube2(Vector3((Real)5.5 + halfWidth, (Real)0.0, (Real)5.5 + halfWidth), Vector3((Real)25.5 - halfWidth, to.y, (Real)25.5 - halfWidth));
    CSGDifferenceSource difference1(&cube1, &cube2);

    // Inner rounded cube
    Real innerHalfWidth = (Real)(7.0 / 2.0);
    Vector3 center((Real)15.5, (Real)5.5, (Real)15.5);
    CSGCubeSource cube3(center - innerHalfWidth, center + innerHalfWidth);
    CSGSphereSource sphere5(innerHalfWidth + (Real)0.75, center);
    CSGIntersectionSource intersection1(&cube3, &sphere5);

    // A plane with noise
    CSGPlaneSource plane1((Real)1.0, Vector3::UNIT_Y);
    Real frequencies[] = {(Real)1.01, (Real)0.48};
    Real amplitudes[] = {(Real)0.25, (Real)0.5};
    CSGNoiseSource noise1(&plane1, frequencies, amplitudes, 2, 100);

    // Combine everything
    CSGUnionSource union1(&sphere1, &sphere2);
    CSGUnionSource union2(&union1, &sphere3);
    CSGUnionSource union3(&union2, &sphere4);
    CSGUnionSource union4(&union3, &difference1);
    CSGUnionSource union5(&union4, &intersection1);
    CSGUnionSource union6(&union5, &noise1);
    Source *src = &union6;

    src->serialize(Vector3::ZERO, to, (Real)0.12109375, "volume.dat");

    mVolumeRoot = OGRE_NEW Chunk();
    SceneNode *volumeRootNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("VolumeParent");

    ChunkParameters parameters;
    parameters.sceneManager = mSceneMgr;
    parameters.src = src;
    parameters.baseError = (Real)0.25;

    mVolumeRoot->load(volumeRootNode, Vector3::ZERO, to, 1, &parameters);

    mVolumeRoot->setMaterial("Ogre/RTShader/TriplanarTexturing");

    // Camera
    mCamera->setPosition(to + (Real)7.5);
    mCamera->lookAt(center + (Real)11.0);
    mCamera->setNearClipDistance((Real)0.5);

    mRotation = (Real)0.0;

}

//-----------------------------------------------------------------------

void Sample_VolumeCSG::setupControls(void)
{
    mTrayMgr->showCursor();
#if OGRE_PLATFORM != OGRE_PLATFORM_APPLE_IOS
        setDragLook(true);
#endif
    mCameraMan->setStyle(OgreBites::CS_MANUAL);
    mCameraMan->setTopSpeed((Real)25.0);
    // make room for the volume
    mTrayMgr->showLogo(TL_TOPRIGHT);
    mTrayMgr->showFrameStats(TL_TOPRIGHT);
    mTrayMgr->toggleAdvancedFrameStats();
}

//-----------------------------------------------------------------------

void Sample_VolumeCSG::setupShaderGenerator()
{
    RTShader::ShaderGenerator* mGen = RTShader::ShaderGenerator::getSingletonPtr();

    RTShader::RenderState* pMainRenderState =
        mGen->createOrRetrieveRenderState(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME).first;
    pMainRenderState->reset();

    mGen->invalidateScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME);

    // Make this viewport work with shader generator scheme.
    mViewport->setMaterialScheme(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME);
}

//-----------------------------------------------------------------------

void Sample_VolumeCSG::cleanupContent(void)
{
    OGRE_DELETE mVolumeRoot;
    mVolumeRoot = 0;
}

//-----------------------------------------------------------------------

Sample_VolumeCSG::Sample_VolumeCSG(void) : mVolumeRoot(0), mHideAll(false)
{
    mInfo["Title"] = "Volume CSG and RTSS triplanar texturing";
    mInfo["Description"] = "Demonstrates a volumetric CSG scene, showing sphere, cube, plane, union, difference and intersection. The triplanar texturing is generated by the RTSS.";
    mInfo["Thumbnail"] = "thumb_volumecsg.png";
    mInfo["Category"] = "Geometry";
}

//-----------------------------------------------------------------------

bool Sample_VolumeCSG::keyPressed(const OIS::KeyEvent& evt)
{
    if (evt.key == OIS::KC_H)
    {
        if (mHideAll)
        {
            mTrayMgr->showAll();
        }
        else
        {
            mTrayMgr->hideAll();
        }
        mHideAll = !mHideAll;
    }
    return SdkSample::keyPressed(evt);
}

bool Sample_VolumeCSG::frameRenderingQueued(const Ogre::FrameEvent& evt)
{
    Vector3 center((Real)15.5, (Real)5.5, (Real)15.5);
    mRotation += Radian(evt.timeSinceLastFrame * (Real)0.5);
    Real r = (Real)35.0;
    mCamera->setPosition(
        Math::Sin(mRotation) * r + center.x,
        (Real)15.0 + center.y,
        Math::Cos(mRotation) * r + center.z
    );
    mCamera->lookAt(center);
    return SdkSample::frameRenderingQueued(evt);
}

//-----------------------------------------------------------------------

void Sample_VolumeCSG::_shutdown()
{
    RTShader::RenderState* pMainRenderState =
        RTShader::ShaderGenerator::getSingleton().createOrRetrieveRenderState(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME).first;
    pMainRenderState->reset();

    SdkSample::_shutdown();
}

//-----------------------------------------------------------------------

#ifndef OGRE_STATIC_LIB

SamplePlugin* sp;
Sample* s;

//-----------------------------------------------------------------------

extern "C" _OgreSampleExport void dllStartPlugin()
{
    s = new Sample_VolumeCSG();
    sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample");
    sp->addSample(s);
    Root::getSingleton().installPlugin(sp);
}

//-----------------------------------------------------------------------

extern "C" _OgreSampleExport void dllStopPlugin()
{
    Root::getSingleton().uninstallPlugin(sp);
    OGRE_DELETE sp;
    delete s;
}

#endif
<|endoftext|>


<commit_before><commit_msg>loading in training data<commit_after><|endoftext|>


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

#include "base/bind.h"
#include "base/command_line.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/memory/ref_counted.h"
#include "base/scoped_temp_dir.h"
#include "base/test/thread_test_helper.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/browser/in_process_webkit/indexed_db_context.h"
#include "content/browser/in_process_webkit/webkit_context.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/public/common/content_switches.h"
#include "webkit/database/database_util.h"
#include "webkit/quota/mock_special_storage_policy.h"
#include "webkit/quota/quota_manager.h"
#include "webkit/quota/special_storage_policy.h"

using content::BrowserContext;
using content::BrowserThread;
using quota::QuotaManager;
using webkit_database::DatabaseUtil;

// This browser test is aimed towards exercising the IndexedDB bindings and
// the actual implementation that lives in the browser side (in_process_webkit).
class IndexedDBBrowserTest : public InProcessBrowserTest {
 public:
  IndexedDBBrowserTest() {
    EnableDOMAutomation();
  }

  GURL testUrl(const FilePath& file_path) {
    const FilePath kTestDir(FILE_PATH_LITERAL("indexeddb"));
    return ui_test_utils::GetTestUrl(kTestDir, file_path);
  }

  void SimpleTest(const GURL& test_url, bool incognito = false) {
    // The test page will perform tests on IndexedDB, then navigate to either
    // a #pass or #fail ref.
    Browser* the_browser = incognito ? CreateIncognitoBrowser() : browser();

    LOG(INFO) << "Navigating to URL and blocking.";
    ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
        the_browser, test_url, 2);
    LOG(INFO) << "Navigation done.";
    std::string result = the_browser->GetSelectedWebContents()->GetURL().ref();
    if (result != "pass") {
      std::string js_result;
      ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
          the_browser->GetSelectedWebContents()->GetRenderViewHost(), L"",
          L"window.domAutomationController.send(getLog())", &js_result));
      FAIL() << "Failed: " << js_result;
    }
  }
};

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CursorTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("cursor_test.html"))));
}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CursorTestIncognito) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("cursor_test.html"))),
             true /* incognito */);
}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CursorPrefetch) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("cursor_prefetch.html"))));
}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, IndexTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("index_test.html"))));
}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, KeyPathTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("key_path_test.html"))));
}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, TransactionGetTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("transaction_get_test.html"))));
}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, KeyTypesTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("key_types_test.html"))));
}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, ObjectStoreTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("object_store_test.html"))));
}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DatabaseTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("database_test.html"))));
}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, TransactionTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("transaction_test.html"))));
}

// Flaky: http://crbug.com/70773
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DISABLED_DoesntHangTest) {
  SimpleTest(testUrl(FilePath(
      FILE_PATH_LITERAL("transaction_run_forever.html"))));
  ui_test_utils::CrashTab(browser()->GetSelectedWebContents());
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("transaction_test.html"))));
}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, Bug84933Test) {
  const GURL url = testUrl(FilePath(FILE_PATH_LITERAL("bug_84933.html")));

  // Just navigate to the URL. Test will crash if it fails.
  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(browser(), url, 1);
}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, Bug106883Test) {
  const GURL url = testUrl(FilePath(FILE_PATH_LITERAL("bug_106883.html")));

  // Just navigate to the URL. Test will crash if it fails.
  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(browser(), url, 1);
}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, Bug109187Test) {
  const GURL url = testUrl(FilePath(FILE_PATH_LITERAL("bug_109187.html")));

  // Just navigate to the URL. Test will crash if it fails.
  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(browser(), url, 1);
}

// In proc browser test is needed here because ClearLocalState indirectly calls
// WebKit's isMainThread through WebSecurityOrigin->SecurityOrigin.
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, ClearLocalState) {
  ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

  FilePath protected_path;
  FilePath unprotected_path;

  // Create the scope which will ensure we run the destructor of the webkit
  // context which should trigger the clean up.
  {
    TestingProfile profile;

    // Test our assumptions about what is protected and what is not.
    const GURL kProtectedOrigin("chrome-extension://foo/");
    const GURL kUnprotectedOrigin("http://foo/");
    quota::SpecialStoragePolicy* policy = profile.GetSpecialStoragePolicy();
    ASSERT_TRUE(policy->IsStorageProtected(kProtectedOrigin));
    ASSERT_FALSE(policy->IsStorageProtected(kUnprotectedOrigin));

    // Create some indexedDB paths.
    // With the levelDB backend, these are directories.
    WebKitContext* webkit_context = BrowserContext::GetWebKitContext(&profile);
    IndexedDBContext* idb_context = webkit_context->indexed_db_context();
    idb_context->set_data_path_for_testing(temp_dir.path());
    protected_path = idb_context->GetIndexedDBFilePath(
        DatabaseUtil::GetOriginIdentifier(kProtectedOrigin));
    unprotected_path = idb_context->GetIndexedDBFilePath(
        DatabaseUtil::GetOriginIdentifier(kUnprotectedOrigin));
    ASSERT_TRUE(file_util::CreateDirectory(protected_path));
    ASSERT_TRUE(file_util::CreateDirectory(unprotected_path));

    // Setup to clear all unprotected origins on exit.
    webkit_context->set_clear_local_state_on_exit(true);
  }

  // Make sure we wait until the destructor has run.
  scoped_refptr<base::ThreadTestHelper> helper_io(
      new base::ThreadTestHelper(
          BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)));
  ASSERT_TRUE(helper_io->Run());
  scoped_refptr<base::ThreadTestHelper> helper_webkit(
      new base::ThreadTestHelper(
          BrowserThread::GetMessageLoopProxyForThread(
              BrowserThread::WEBKIT_DEPRECATED)));
  ASSERT_TRUE(helper_webkit->Run());

  ASSERT_TRUE(file_util::DirectoryExists(protected_path));
  ASSERT_FALSE(file_util::DirectoryExists(unprotected_path));
}

// In proc browser test is needed here because ClearLocalState indirectly calls
// WebKit's isMainThread through WebSecurityOrigin->SecurityOrigin.
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, ClearSessionOnlyDatabases) {
  ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

  FilePath normal_path;
  FilePath session_only_path;

  // Create the scope which will ensure we run the destructor of the webkit
  // context which should trigger the clean up.
  {
    TestingProfile profile;

    const GURL kNormalOrigin("http://normal/");
    const GURL kSessionOnlyOrigin("http://session-only/");
    scoped_refptr<quota::MockSpecialStoragePolicy> special_storage_policy =
        new quota::MockSpecialStoragePolicy;
    special_storage_policy->AddSessionOnly(kSessionOnlyOrigin);

    // Create some indexedDB paths.
    // With the levelDB backend, these are directories.
    WebKitContext* webkit_context = BrowserContext::GetWebKitContext(&profile);
    IndexedDBContext* idb_context = webkit_context->indexed_db_context();

    // Override the storage policy with our own.
    idb_context->special_storage_policy_ = special_storage_policy;
    idb_context->set_data_path_for_testing(temp_dir.path());

    normal_path = idb_context->GetIndexedDBFilePath(
        DatabaseUtil::GetOriginIdentifier(kNormalOrigin));
    session_only_path = idb_context->GetIndexedDBFilePath(
        DatabaseUtil::GetOriginIdentifier(kSessionOnlyOrigin));
    ASSERT_TRUE(file_util::CreateDirectory(normal_path));
    ASSERT_TRUE(file_util::CreateDirectory(session_only_path));
  }

  scoped_refptr<base::ThreadTestHelper> helper_io(
      new base::ThreadTestHelper(
          BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)));
  ASSERT_TRUE(helper_io->Run());
  scoped_refptr<base::ThreadTestHelper> helper_webkit(
      new base::ThreadTestHelper(
          BrowserThread::GetMessageLoopProxyForThread(
              BrowserThread::WEBKIT_DEPRECATED)));
  ASSERT_TRUE(helper_webkit->Run());

  EXPECT_TRUE(file_util::DirectoryExists(normal_path));
  EXPECT_FALSE(file_util::DirectoryExists(session_only_path));
}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, SaveSessionState) {
  ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

  FilePath normal_path;
  FilePath session_only_path;

  // Create the scope which will ensure we run the destructor of the webkit
  // context.
  {
    TestingProfile profile;

    const GURL kNormalOrigin("http://normal/");
    const GURL kSessionOnlyOrigin("http://session-only/");
    scoped_refptr<quota::MockSpecialStoragePolicy> special_storage_policy =
        new quota::MockSpecialStoragePolicy;
    special_storage_policy->AddSessionOnly(kSessionOnlyOrigin);

    // Create some indexedDB paths.
    // With the levelDB backend, these are directories.
    WebKitContext* webkit_context = BrowserContext::GetWebKitContext(&profile);
    IndexedDBContext* idb_context = webkit_context->indexed_db_context();

    // Override the storage policy with our own.
    idb_context->special_storage_policy_ = special_storage_policy;
    idb_context->set_clear_local_state_on_exit(true);
    idb_context->set_data_path_for_testing(temp_dir.path());

    // Save session state. This should bypass the destruction-time deletion.
    idb_context->SaveSessionState();

    normal_path = idb_context->GetIndexedDBFilePath(
        DatabaseUtil::GetOriginIdentifier(kNormalOrigin));
    session_only_path = idb_context->GetIndexedDBFilePath(
        DatabaseUtil::GetOriginIdentifier(kSessionOnlyOrigin));
    ASSERT_TRUE(file_util::CreateDirectory(normal_path));
    ASSERT_TRUE(file_util::CreateDirectory(session_only_path));
  }

  // Make sure we wait until the destructor has run.
  scoped_refptr<base::ThreadTestHelper> helper(
      new base::ThreadTestHelper(
          BrowserThread::GetMessageLoopProxyForThread(
              BrowserThread::WEBKIT_DEPRECATED)));
  ASSERT_TRUE(helper->Run());

  // No data was cleared because of SaveSessionState.
  EXPECT_TRUE(file_util::DirectoryExists(normal_path));
  EXPECT_TRUE(file_util::DirectoryExists(session_only_path));
}

class IndexedDBBrowserTestWithLowQuota : public IndexedDBBrowserTest {
 public:
  virtual void SetUpOnMainThread() {
    const int kInitialQuotaKilobytes = 5000;
    const int kTemporaryStorageQuotaMaxSize = kInitialQuotaKilobytes
        * 1024 * QuotaManager::kPerHostTemporaryPortion;
    SetTempQuota(
        kTemporaryStorageQuotaMaxSize,
        content::BrowserContext::GetQuotaManager(browser()->profile()));
  }

  static void SetTempQuota(int64 bytes, scoped_refptr<QuotaManager> qm) {
    if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
      BrowserThread::PostTask(
          BrowserThread::IO, FROM_HERE,
          base::Bind(&IndexedDBBrowserTestWithLowQuota::SetTempQuota, bytes,
                     qm));
      return;
    }
    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
    qm->SetTemporaryGlobalOverrideQuota(bytes, quota::QuotaCallback());
    // Don't return until the quota has been set.
    scoped_refptr<base::ThreadTestHelper> helper(
        new base::ThreadTestHelper(
            BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB)));
    ASSERT_TRUE(helper->Run());
  }

};

// No longer testable with file: URL: http://crbug.com/104748
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithLowQuota, DISABLED_QuotaTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("quota_test.html"))));
}

class IndexedDBBrowserTestWithGCExposed : public IndexedDBBrowserTest {
 public:
  virtual void SetUpCommandLine(CommandLine* command_line) {
    command_line->AppendSwitchASCII(switches::kJavaScriptFlags, "--expose-gc");
  }
};

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithGCExposed,
                       DatabaseCallbacksTest) {
  SimpleTest(
      testUrl(FilePath(FILE_PATH_LITERAL("database_callbacks_first.html"))));
}
<commit_msg>Mark IndexedDBBrowserTest.ClearLocalState and IndexedDBBrowserTest.SaveSessionState as flaky.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/bind.h"
#include "base/command_line.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/memory/ref_counted.h"
#include "base/scoped_temp_dir.h"
#include "base/test/thread_test_helper.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/browser/in_process_webkit/indexed_db_context.h"
#include "content/browser/in_process_webkit/webkit_context.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/public/common/content_switches.h"
#include "webkit/database/database_util.h"
#include "webkit/quota/mock_special_storage_policy.h"
#include "webkit/quota/quota_manager.h"
#include "webkit/quota/special_storage_policy.h"

using content::BrowserContext;
using content::BrowserThread;
using quota::QuotaManager;
using webkit_database::DatabaseUtil;

// This browser test is aimed towards exercising the IndexedDB bindings and
// the actual implementation that lives in the browser side (in_process_webkit).
class IndexedDBBrowserTest : public InProcessBrowserTest {
 public:
  IndexedDBBrowserTest() {
    EnableDOMAutomation();
  }

  GURL testUrl(const FilePath& file_path) {
    const FilePath kTestDir(FILE_PATH_LITERAL("indexeddb"));
    return ui_test_utils::GetTestUrl(kTestDir, file_path);
  }

  void SimpleTest(const GURL& test_url, bool incognito = false) {
    // The test page will perform tests on IndexedDB, then navigate to either
    // a #pass or #fail ref.
    Browser* the_browser = incognito ? CreateIncognitoBrowser() : browser();

    LOG(INFO) << "Navigating to URL and blocking.";
    ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
        the_browser, test_url, 2);
    LOG(INFO) << "Navigation done.";
    std::string result = the_browser->GetSelectedWebContents()->GetURL().ref();
    if (result != "pass") {
      std::string js_result;
      ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
          the_browser->GetSelectedWebContents()->GetRenderViewHost(), L"",
          L"window.domAutomationController.send(getLog())", &js_result));
      FAIL() << "Failed: " << js_result;
    }
  }
};

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CursorTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("cursor_test.html"))));
}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CursorTestIncognito) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("cursor_test.html"))),
             true /* incognito */);
}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CursorPrefetch) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("cursor_prefetch.html"))));
}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, IndexTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("index_test.html"))));
}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, KeyPathTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("key_path_test.html"))));
}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, TransactionGetTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("transaction_get_test.html"))));
}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, KeyTypesTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("key_types_test.html"))));
}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, ObjectStoreTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("object_store_test.html"))));
}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DatabaseTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("database_test.html"))));
}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, TransactionTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("transaction_test.html"))));
}

// Flaky: http://crbug.com/70773
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DISABLED_DoesntHangTest) {
  SimpleTest(testUrl(FilePath(
      FILE_PATH_LITERAL("transaction_run_forever.html"))));
  ui_test_utils::CrashTab(browser()->GetSelectedWebContents());
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("transaction_test.html"))));
}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, Bug84933Test) {
  const GURL url = testUrl(FilePath(FILE_PATH_LITERAL("bug_84933.html")));

  // Just navigate to the URL. Test will crash if it fails.
  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(browser(), url, 1);
}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, Bug106883Test) {
  const GURL url = testUrl(FilePath(FILE_PATH_LITERAL("bug_106883.html")));

  // Just navigate to the URL. Test will crash if it fails.
  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(browser(), url, 1);
}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, Bug109187Test) {
  const GURL url = testUrl(FilePath(FILE_PATH_LITERAL("bug_109187.html")));

  // Just navigate to the URL. Test will crash if it fails.
  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(browser(), url, 1);
}

#if defined(OS_MACOSX)
// http://crbug.com/115188. On Mac, failure rate is about 18% currently.
#define MAYBE_ClearLocalState DISABLED_ClearLocalState
#else
#define MAYBE_ClearLocalState ClearLocalState
#endif

// In proc browser test is needed here because ClearLocalState indirectly calls
// WebKit's isMainThread through WebSecurityOrigin->SecurityOrigin.
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, MAYBE_ClearLocalState) {
  ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

  FilePath protected_path;
  FilePath unprotected_path;

  // Create the scope which will ensure we run the destructor of the webkit
  // context which should trigger the clean up.
  {
    TestingProfile profile;

    // Test our assumptions about what is protected and what is not.
    const GURL kProtectedOrigin("chrome-extension://foo/");
    const GURL kUnprotectedOrigin("http://foo/");
    quota::SpecialStoragePolicy* policy = profile.GetSpecialStoragePolicy();
    ASSERT_TRUE(policy->IsStorageProtected(kProtectedOrigin));
    ASSERT_FALSE(policy->IsStorageProtected(kUnprotectedOrigin));

    // Create some indexedDB paths.
    // With the levelDB backend, these are directories.
    WebKitContext* webkit_context = BrowserContext::GetWebKitContext(&profile);
    IndexedDBContext* idb_context = webkit_context->indexed_db_context();
    idb_context->set_data_path_for_testing(temp_dir.path());
    protected_path = idb_context->GetIndexedDBFilePath(
        DatabaseUtil::GetOriginIdentifier(kProtectedOrigin));
    unprotected_path = idb_context->GetIndexedDBFilePath(
        DatabaseUtil::GetOriginIdentifier(kUnprotectedOrigin));
    ASSERT_TRUE(file_util::CreateDirectory(protected_path));
    ASSERT_TRUE(file_util::CreateDirectory(unprotected_path));

    // Setup to clear all unprotected origins on exit.
    webkit_context->set_clear_local_state_on_exit(true);
  }

  // Make sure we wait until the destructor has run.
  scoped_refptr<base::ThreadTestHelper> helper_io(
      new base::ThreadTestHelper(
          BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)));
  ASSERT_TRUE(helper_io->Run());
  scoped_refptr<base::ThreadTestHelper> helper_webkit(
      new base::ThreadTestHelper(
          BrowserThread::GetMessageLoopProxyForThread(
              BrowserThread::WEBKIT_DEPRECATED)));
  ASSERT_TRUE(helper_webkit->Run());

  ASSERT_TRUE(file_util::DirectoryExists(protected_path));
  ASSERT_FALSE(file_util::DirectoryExists(unprotected_path));
}

// In proc browser test is needed here because ClearLocalState indirectly calls
// WebKit's isMainThread through WebSecurityOrigin->SecurityOrigin.
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, ClearSessionOnlyDatabases) {
  ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

  FilePath normal_path;
  FilePath session_only_path;

  // Create the scope which will ensure we run the destructor of the webkit
  // context which should trigger the clean up.
  {
    TestingProfile profile;

    const GURL kNormalOrigin("http://normal/");
    const GURL kSessionOnlyOrigin("http://session-only/");
    scoped_refptr<quota::MockSpecialStoragePolicy> special_storage_policy =
        new quota::MockSpecialStoragePolicy;
    special_storage_policy->AddSessionOnly(kSessionOnlyOrigin);

    // Create some indexedDB paths.
    // With the levelDB backend, these are directories.
    WebKitContext* webkit_context = BrowserContext::GetWebKitContext(&profile);
    IndexedDBContext* idb_context = webkit_context->indexed_db_context();

    // Override the storage policy with our own.
    idb_context->special_storage_policy_ = special_storage_policy;
    idb_context->set_data_path_for_testing(temp_dir.path());

    normal_path = idb_context->GetIndexedDBFilePath(
        DatabaseUtil::GetOriginIdentifier(kNormalOrigin));
    session_only_path = idb_context->GetIndexedDBFilePath(
        DatabaseUtil::GetOriginIdentifier(kSessionOnlyOrigin));
    ASSERT_TRUE(file_util::CreateDirectory(normal_path));
    ASSERT_TRUE(file_util::CreateDirectory(session_only_path));
  }

  scoped_refptr<base::ThreadTestHelper> helper_io(
      new base::ThreadTestHelper(
          BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)));
  ASSERT_TRUE(helper_io->Run());
  scoped_refptr<base::ThreadTestHelper> helper_webkit(
      new base::ThreadTestHelper(
          BrowserThread::GetMessageLoopProxyForThread(
              BrowserThread::WEBKIT_DEPRECATED)));
  ASSERT_TRUE(helper_webkit->Run());

  EXPECT_TRUE(file_util::DirectoryExists(normal_path));
  EXPECT_FALSE(file_util::DirectoryExists(session_only_path));
}

#if defined(OS_MACOSX)
// http://crbug.com/115188. On Mac, failure rate is about 18% currently.
#define MAYBE_SaveSessionState DISABLED_SaveSessionState
#else
#define MAYBE_SaveSessionState SaveSessionState
#endif

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, MAYBE_SaveSessionState) {
  ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

  FilePath normal_path;
  FilePath session_only_path;

  // Create the scope which will ensure we run the destructor of the webkit
  // context.
  {
    TestingProfile profile;

    const GURL kNormalOrigin("http://normal/");
    const GURL kSessionOnlyOrigin("http://session-only/");
    scoped_refptr<quota::MockSpecialStoragePolicy> special_storage_policy =
        new quota::MockSpecialStoragePolicy;
    special_storage_policy->AddSessionOnly(kSessionOnlyOrigin);

    // Create some indexedDB paths.
    // With the levelDB backend, these are directories.
    WebKitContext* webkit_context = BrowserContext::GetWebKitContext(&profile);
    IndexedDBContext* idb_context = webkit_context->indexed_db_context();

    // Override the storage policy with our own.
    idb_context->special_storage_policy_ = special_storage_policy;
    idb_context->set_clear_local_state_on_exit(true);
    idb_context->set_data_path_for_testing(temp_dir.path());

    // Save session state. This should bypass the destruction-time deletion.
    idb_context->SaveSessionState();

    normal_path = idb_context->GetIndexedDBFilePath(
        DatabaseUtil::GetOriginIdentifier(kNormalOrigin));
    session_only_path = idb_context->GetIndexedDBFilePath(
        DatabaseUtil::GetOriginIdentifier(kSessionOnlyOrigin));
    ASSERT_TRUE(file_util::CreateDirectory(normal_path));
    ASSERT_TRUE(file_util::CreateDirectory(session_only_path));
  }

  // Make sure we wait until the destructor has run.
  scoped_refptr<base::ThreadTestHelper> helper(
      new base::ThreadTestHelper(
          BrowserThread::GetMessageLoopProxyForThread(
              BrowserThread::WEBKIT_DEPRECATED)));
  ASSERT_TRUE(helper->Run());

  // No data was cleared because of SaveSessionState.
  EXPECT_TRUE(file_util::DirectoryExists(normal_path));
  EXPECT_TRUE(file_util::DirectoryExists(session_only_path));
}

class IndexedDBBrowserTestWithLowQuota : public IndexedDBBrowserTest {
 public:
  virtual void SetUpOnMainThread() {
    const int kInitialQuotaKilobytes = 5000;
    const int kTemporaryStorageQuotaMaxSize = kInitialQuotaKilobytes
        * 1024 * QuotaManager::kPerHostTemporaryPortion;
    SetTempQuota(
        kTemporaryStorageQuotaMaxSize,
        content::BrowserContext::GetQuotaManager(browser()->profile()));
  }

  static void SetTempQuota(int64 bytes, scoped_refptr<QuotaManager> qm) {
    if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
      BrowserThread::PostTask(
          BrowserThread::IO, FROM_HERE,
          base::Bind(&IndexedDBBrowserTestWithLowQuota::SetTempQuota, bytes,
                     qm));
      return;
    }
    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
    qm->SetTemporaryGlobalOverrideQuota(bytes, quota::QuotaCallback());
    // Don't return until the quota has been set.
    scoped_refptr<base::ThreadTestHelper> helper(
        new base::ThreadTestHelper(
            BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB)));
    ASSERT_TRUE(helper->Run());
  }

};

// No longer testable with file: URL: http://crbug.com/104748
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithLowQuota, DISABLED_QuotaTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("quota_test.html"))));
}

class IndexedDBBrowserTestWithGCExposed : public IndexedDBBrowserTest {
 public:
  virtual void SetUpCommandLine(CommandLine* command_line) {
    command_line->AppendSwitchASCII(switches::kJavaScriptFlags, "--expose-gc");
  }
};

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithGCExposed,
                       DatabaseCallbacksTest) {
  SimpleTest(
      testUrl(FilePath(FILE_PATH_LITERAL("database_callbacks_first.html"))));
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed 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
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "src/trace_processor/raw_table.h"

#include <inttypes.h>

#include "src/trace_processor/ftrace_descriptors.h"
#include "src/trace_processor/sqlite_utils.h"
#include "src/trace_processor/variadic.h"

#include "perfetto/trace/ftrace/binder.pbzero.h"
#include "perfetto/trace/ftrace/clk.pbzero.h"
#include "perfetto/trace/ftrace/ftrace.pbzero.h"
#include "perfetto/trace/ftrace/ftrace_event.pbzero.h"
#include "perfetto/trace/ftrace/sched.pbzero.h"

namespace perfetto {
namespace trace_processor {

RawTable::RawTable(sqlite3* db, const TraceStorage* storage)
    : storage_(storage) {
  auto fn = [](sqlite3_context* ctx, int argc, sqlite3_value** argv) {
    auto* thiz = static_cast<RawTable*>(sqlite3_user_data(ctx));
    thiz->ToSystrace(ctx, argc, argv);
  };
  sqlite3_create_function(db, "to_ftrace", 1,
                          SQLITE_UTF8 | SQLITE_DETERMINISTIC, this, fn, nullptr,
                          nullptr);
}

void RawTable::RegisterTable(sqlite3* db, const TraceStorage* storage) {
  Table::Register<RawTable>(db, storage, "raw");
}

StorageSchema RawTable::CreateStorageSchema() {
  const auto& raw = storage_->raw_events();
  return StorageSchema::Builder()
      .AddGenericNumericColumn("id", RowIdAccessor(TableId::kRawEvents))
      .AddOrderedNumericColumn("ts", &raw.timestamps())
      .AddStringColumn("name", &raw.name_ids(), &storage_->string_pool())
      .AddNumericColumn("cpu", &raw.cpus())
      .AddNumericColumn("utid", &raw.utids())
      .AddNumericColumn("arg_set_id", &raw.arg_set_ids())
      .Build({"name", "ts"});
}

uint32_t RawTable::RowCount() {
  return static_cast<uint32_t>(storage_->raw_events().raw_event_count());
}

int RawTable::BestIndex(const QueryConstraints& qc, BestIndexInfo* info) {
  info->estimated_cost = RowCount();

  // Only the string columns are handled by SQLite
  info->order_by_consumed = true;
  size_t name_index = schema().ColumnIndexFromName("name");
  for (size_t i = 0; i < qc.constraints().size(); i++) {
    info->omit[i] = qc.constraints()[i].iColumn != static_cast<int>(name_index);
  }

  return SQLITE_OK;
}

void RawTable::FormatSystraceArgs(NullTermStringView event_name,
                                  ArgSetId arg_set_id,
                                  base::StringWriter* writer) {
  const auto& set_ids = storage_->args().set_ids();
  auto lb = std::lower_bound(set_ids.begin(), set_ids.end(), arg_set_id);
  auto ub = std::find(lb, set_ids.end(), arg_set_id + 1);

  auto start_row = static_cast<uint32_t>(std::distance(set_ids.begin(), lb));

  using ValueWriter = std::function<void(const Variadic&)>;
  auto write_value = [this, writer](const Variadic& value) {
    switch (value.type) {
      case Variadic::kInt:
        writer->AppendInt(value.int_value);
        break;
      case Variadic::kUint:
        writer->AppendUnsignedInt(value.uint_value);
        break;
      case Variadic::kString: {
        const auto& str = storage_->GetString(value.string_value);
        writer->AppendString(str.c_str(), str.size());
        break;
      }
      case Variadic::kReal:
        writer->AppendDouble(value.real_value);
        break;
      case Variadic::kPointer:
        writer->AppendUnsignedInt(value.pointer_value);
        break;
      case Variadic::kBool:
        writer->AppendBool(value.bool_value);
        break;
      case Variadic::kJson: {
        const auto& str = storage_->GetString(value.json_value);
        writer->AppendString(str.c_str(), str.size());
        break;
      }
    }
  };
  auto write_value_at_index = [this, start_row](uint32_t arg_idx,
                                                ValueWriter value_fn) {
    value_fn(storage_->args().arg_values()[start_row + arg_idx]);
  };
  auto write_arg = [this, writer, start_row](uint32_t arg_idx,
                                             ValueWriter value_fn) {
    uint32_t arg_row = start_row + arg_idx;
    const auto& args = storage_->args();
    const auto& key = storage_->GetString(args.keys()[arg_row]);
    const auto& value = args.arg_values()[arg_row];

    writer->AppendChar(' ');
    writer->AppendString(key.c_str(), key.size());
    writer->AppendChar('=');
    value_fn(value);
  };

  if (event_name == "sched_switch") {
    using SS = protos::pbzero::SchedSwitchFtraceEvent;
    write_arg(SS::kPrevCommFieldNumber - 1, write_value);
    write_arg(SS::kPrevPidFieldNumber - 1, write_value);
    write_arg(SS::kPrevPrioFieldNumber - 1, write_value);
    write_arg(SS::kPrevStateFieldNumber - 1, [writer](const Variadic& value) {
      auto state = static_cast<uint16_t>(value.int_value);
      writer->AppendString(ftrace_utils::TaskState(state).ToString().data());
    });
    writer->AppendLiteral(" ==>");
    write_arg(SS::kNextCommFieldNumber - 1, write_value);
    write_arg(SS::kNextPidFieldNumber - 1, write_value);
    write_arg(SS::kNextPrioFieldNumber - 1, write_value);
    return;
  } else if (event_name == "sched_wakeup") {
    using SW = protos::pbzero::SchedWakeupFtraceEvent;
    write_arg(SW::kCommFieldNumber - 1, write_value);
    write_arg(SW::kPidFieldNumber - 1, write_value);
    write_arg(SW::kPrioFieldNumber - 1, write_value);
    write_arg(SW::kTargetCpuFieldNumber - 1, [writer](const Variadic& value) {
      writer->AppendPaddedInt<'0', 3>(value.int_value);
    });
    return;
  } else if (event_name == "clock_set_rate") {
    // TODO(lalitm): this is a big hack but the best way to do this now.
    // Doing this requires overhauling how we deal with args by pushing them all
    // to an array and then reading back from that array.

    // We use the string "todo" as the name to stay consistent with old
    // trace_to_text print code.
    writer->AppendString(" todo");
    write_arg(0 /* state */, write_value);
    write_arg(1 /* cpu_id */, write_value);
    return;
  } else if (event_name == "clk_set_rate") {
    using CSR = protos::pbzero::ClkSetRateFtraceEvent;
    writer->AppendLiteral(" ");
    write_value_at_index(CSR::kNameFieldNumber - 1, write_value);
    writer->AppendLiteral(" ");
    write_value_at_index(CSR::kRateFieldNumber - 1, write_value);
    return;
  } else if (event_name == "binder_transaction") {
    using BT = protos::pbzero::BinderTransactionFtraceEvent;
    writer->AppendString(" transaction=");
    write_value_at_index(BT::kDebugIdFieldNumber - 1, write_value);
    writer->AppendString(" dest_node=");
    write_value_at_index(BT::kTargetNodeFieldNumber - 1, write_value);
    writer->AppendString(" dest_proc=");
    write_value_at_index(BT::kToProcFieldNumber - 1, write_value);
    writer->AppendString(" dest_thread=");
    write_value_at_index(BT::kToThreadFieldNumber - 1, write_value);
    write_arg(BT::kReplyFieldNumber - 1, write_value);
    writer->AppendString(" flags=0x");
    write_value_at_index(
        BT::kFlagsFieldNumber - 1, [writer](const Variadic& value) {
          writer->AppendHexInt(static_cast<uint32_t>(value.int_value));
        });
    writer->AppendString(" code=0x");
    write_value_at_index(
        BT::kCodeFieldNumber - 1, [writer](const Variadic& value) {
          writer->AppendHexInt(static_cast<uint32_t>(value.int_value));
        });
    return;
  } else if (event_name == "binder_transaction_alloc_buf") {
    using BTAB = protos::pbzero::BinderTransactionAllocBufFtraceEvent;
    writer->AppendString(" transaction=");
    write_value_at_index(BTAB::kDebugIdFieldNumber - 1, write_value);
    write_arg(BTAB::kDataSizeFieldNumber - 1, write_value);
    write_arg(BTAB::kOffsetsSizeFieldNumber - 1, write_value);
    return;
  } else if (event_name == "binder_transaction_received") {
    using BTR = protos::pbzero::BinderTransactionReceivedFtraceEvent;
    writer->AppendString(" transaction=");
    write_value_at_index(BTR::kDebugIdFieldNumber - 1, write_value);
    return;
  } else if (event_name == "print") {
    using P = protos::pbzero::PrintFtraceEvent;

    uint32_t arg_row = start_row + P::kBufFieldNumber - 1;
    const auto& args = storage_->args();
    const auto& value = args.arg_values()[arg_row];
    const auto& str = storage_->GetString(value.string_value);
    // If the last character is a newline in a print, just drop it.
    auto chars_to_print = !str.empty() && str.c_str()[str.size() - 1] == '\n'
                              ? str.size() - 1
                              : str.size();
    writer->AppendChar(' ');
    writer->AppendString(str.c_str(), chars_to_print);
    return;
  }

  uint32_t arg = 0;
  for (auto it = lb; it != ub; it++) {
    write_arg(arg++, write_value);
  }
}

void RawTable::ToSystrace(sqlite3_context* ctx,
                          int argc,
                          sqlite3_value** argv) {
  if (argc != 1 || sqlite3_value_type(argv[0]) != SQLITE_INTEGER) {
    sqlite3_result_error(ctx, "Usage: to_ftrace(id)", -1);
    return;
  }
  RowId row_id = sqlite3_value_int64(argv[0]);
  auto pair = TraceStorage::ParseRowId(row_id);
  PERFETTO_DCHECK(pair.first == TableId::kRawEvents);
  auto row = pair.second;

  const auto& raw_evts = storage_->raw_events();

  UniqueTid utid = raw_evts.utids()[row];
  const auto& thread = storage_->GetThread(utid);
  uint32_t tgid = 0;
  if (thread.upid.has_value()) {
    tgid = storage_->GetProcess(thread.upid.value()).pid;
  }
  const auto& name = storage_->GetString(thread.name_id);

  char line[4096];
  base::StringWriter writer(line, sizeof(line));

  ftrace_utils::FormatSystracePrefix(raw_evts.timestamps()[row],
                                     raw_evts.cpus()[row], thread.tid, tgid,
                                     base::StringView(name), &writer);

  const auto& event_name = storage_->GetString(raw_evts.name_ids()[row]);
  writer.AppendChar(' ');
  if (event_name == "print") {
    writer.AppendString("tracing_mark_write");
  } else {
    writer.AppendString(event_name.c_str(), event_name.size());
  }
  writer.AppendChar(':');

  FormatSystraceArgs(event_name, raw_evts.arg_set_ids()[row], &writer);
  sqlite3_result_text(ctx, writer.CreateStringCopy(), -1, free);
}

}  // namespace trace_processor
}  // namespace perfetto
<commit_msg>Update trace_to_text for mm_filemap event am: 59bfc2a1ff am: 05cc0a7b44 am: ebd7104159<commit_after>/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed 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
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "src/trace_processor/raw_table.h"

#include <inttypes.h>

#include "src/trace_processor/ftrace_descriptors.h"
#include "src/trace_processor/sqlite_utils.h"
#include "src/trace_processor/variadic.h"

#include "perfetto/trace/ftrace/binder.pbzero.h"
#include "perfetto/trace/ftrace/clk.pbzero.h"
#include "perfetto/trace/ftrace/filemap.pbzero.h"
#include "perfetto/trace/ftrace/ftrace.pbzero.h"
#include "perfetto/trace/ftrace/ftrace_event.pbzero.h"
#include "perfetto/trace/ftrace/sched.pbzero.h"

namespace perfetto {
namespace trace_processor {

RawTable::RawTable(sqlite3* db, const TraceStorage* storage)
    : storage_(storage) {
  auto fn = [](sqlite3_context* ctx, int argc, sqlite3_value** argv) {
    auto* thiz = static_cast<RawTable*>(sqlite3_user_data(ctx));
    thiz->ToSystrace(ctx, argc, argv);
  };
  sqlite3_create_function(db, "to_ftrace", 1,
                          SQLITE_UTF8 | SQLITE_DETERMINISTIC, this, fn, nullptr,
                          nullptr);
}

void RawTable::RegisterTable(sqlite3* db, const TraceStorage* storage) {
  Table::Register<RawTable>(db, storage, "raw");
}

StorageSchema RawTable::CreateStorageSchema() {
  const auto& raw = storage_->raw_events();
  return StorageSchema::Builder()
      .AddGenericNumericColumn("id", RowIdAccessor(TableId::kRawEvents))
      .AddOrderedNumericColumn("ts", &raw.timestamps())
      .AddStringColumn("name", &raw.name_ids(), &storage_->string_pool())
      .AddNumericColumn("cpu", &raw.cpus())
      .AddNumericColumn("utid", &raw.utids())
      .AddNumericColumn("arg_set_id", &raw.arg_set_ids())
      .Build({"name", "ts"});
}

uint32_t RawTable::RowCount() {
  return static_cast<uint32_t>(storage_->raw_events().raw_event_count());
}

int RawTable::BestIndex(const QueryConstraints& qc, BestIndexInfo* info) {
  info->estimated_cost = RowCount();

  // Only the string columns are handled by SQLite
  info->order_by_consumed = true;
  size_t name_index = schema().ColumnIndexFromName("name");
  for (size_t i = 0; i < qc.constraints().size(); i++) {
    info->omit[i] = qc.constraints()[i].iColumn != static_cast<int>(name_index);
  }

  return SQLITE_OK;
}

void RawTable::FormatSystraceArgs(NullTermStringView event_name,
                                  ArgSetId arg_set_id,
                                  base::StringWriter* writer) {
  const auto& set_ids = storage_->args().set_ids();
  auto lb = std::lower_bound(set_ids.begin(), set_ids.end(), arg_set_id);
  auto ub = std::find(lb, set_ids.end(), arg_set_id + 1);

  auto start_row = static_cast<uint32_t>(std::distance(set_ids.begin(), lb));

  using ValueWriter = std::function<void(const Variadic&)>;
  auto write_value = [this, writer](const Variadic& value) {
    switch (value.type) {
      case Variadic::kInt:
        writer->AppendInt(value.int_value);
        break;
      case Variadic::kUint:
        writer->AppendUnsignedInt(value.uint_value);
        break;
      case Variadic::kString: {
        const auto& str = storage_->GetString(value.string_value);
        writer->AppendString(str.c_str(), str.size());
        break;
      }
      case Variadic::kReal:
        writer->AppendDouble(value.real_value);
        break;
      case Variadic::kPointer:
        writer->AppendUnsignedInt(value.pointer_value);
        break;
      case Variadic::kBool:
        writer->AppendBool(value.bool_value);
        break;
      case Variadic::kJson: {
        const auto& str = storage_->GetString(value.json_value);
        writer->AppendString(str.c_str(), str.size());
        break;
      }
    }
  };
  auto write_value_at_index = [this, start_row](uint32_t arg_idx,
                                                ValueWriter value_fn) {
    value_fn(storage_->args().arg_values()[start_row + arg_idx]);
  };
  auto write_arg = [this, writer, start_row](uint32_t arg_idx,
                                             ValueWriter value_fn) {
    uint32_t arg_row = start_row + arg_idx;
    const auto& args = storage_->args();
    const auto& key = storage_->GetString(args.keys()[arg_row]);
    const auto& value = args.arg_values()[arg_row];

    writer->AppendChar(' ');
    writer->AppendString(key.c_str(), key.size());
    writer->AppendChar('=');
    value_fn(value);
  };

  if (event_name == "sched_switch") {
    using SS = protos::pbzero::SchedSwitchFtraceEvent;
    write_arg(SS::kPrevCommFieldNumber - 1, write_value);
    write_arg(SS::kPrevPidFieldNumber - 1, write_value);
    write_arg(SS::kPrevPrioFieldNumber - 1, write_value);
    write_arg(SS::kPrevStateFieldNumber - 1, [writer](const Variadic& value) {
      auto state = static_cast<uint16_t>(value.int_value);
      writer->AppendString(ftrace_utils::TaskState(state).ToString().data());
    });
    writer->AppendLiteral(" ==>");
    write_arg(SS::kNextCommFieldNumber - 1, write_value);
    write_arg(SS::kNextPidFieldNumber - 1, write_value);
    write_arg(SS::kNextPrioFieldNumber - 1, write_value);
    return;
  } else if (event_name == "sched_wakeup") {
    using SW = protos::pbzero::SchedWakeupFtraceEvent;
    write_arg(SW::kCommFieldNumber - 1, write_value);
    write_arg(SW::kPidFieldNumber - 1, write_value);
    write_arg(SW::kPrioFieldNumber - 1, write_value);
    write_arg(SW::kTargetCpuFieldNumber - 1, [writer](const Variadic& value) {
      writer->AppendPaddedInt<'0', 3>(value.int_value);
    });
    return;
  } else if (event_name == "clock_set_rate") {
    // TODO(lalitm): this is a big hack but the best way to do this now.
    // Doing this requires overhauling how we deal with args by pushing them all
    // to an array and then reading back from that array.

    // We use the string "todo" as the name to stay consistent with old
    // trace_to_text print code.
    writer->AppendString(" todo");
    write_arg(0 /* state */, write_value);
    write_arg(1 /* cpu_id */, write_value);
    return;
  } else if (event_name == "clk_set_rate") {
    using CSR = protos::pbzero::ClkSetRateFtraceEvent;
    writer->AppendLiteral(" ");
    write_value_at_index(CSR::kNameFieldNumber - 1, write_value);
    writer->AppendLiteral(" ");
    write_value_at_index(CSR::kRateFieldNumber - 1, write_value);
    return;
  } else if (event_name == "binder_transaction") {
    using BT = protos::pbzero::BinderTransactionFtraceEvent;
    writer->AppendString(" transaction=");
    write_value_at_index(BT::kDebugIdFieldNumber - 1, write_value);
    writer->AppendString(" dest_node=");
    write_value_at_index(BT::kTargetNodeFieldNumber - 1, write_value);
    writer->AppendString(" dest_proc=");
    write_value_at_index(BT::kToProcFieldNumber - 1, write_value);
    writer->AppendString(" dest_thread=");
    write_value_at_index(BT::kToThreadFieldNumber - 1, write_value);
    write_arg(BT::kReplyFieldNumber - 1, write_value);
    writer->AppendString(" flags=0x");
    write_value_at_index(
        BT::kFlagsFieldNumber - 1, [writer](const Variadic& value) {
          writer->AppendHexInt(static_cast<uint32_t>(value.int_value));
        });
    writer->AppendString(" code=0x");
    write_value_at_index(
        BT::kCodeFieldNumber - 1, [writer](const Variadic& value) {
          writer->AppendHexInt(static_cast<uint32_t>(value.int_value));
        });
    return;
  } else if (event_name == "binder_transaction_alloc_buf") {
    using BTAB = protos::pbzero::BinderTransactionAllocBufFtraceEvent;
    writer->AppendString(" transaction=");
    write_value_at_index(BTAB::kDebugIdFieldNumber - 1, write_value);
    write_arg(BTAB::kDataSizeFieldNumber - 1, write_value);
    write_arg(BTAB::kOffsetsSizeFieldNumber - 1, write_value);
    return;
  } else if (event_name == "binder_transaction_received") {
    using BTR = protos::pbzero::BinderTransactionReceivedFtraceEvent;
    writer->AppendString(" transaction=");
    write_value_at_index(BTR::kDebugIdFieldNumber - 1, write_value);
    return;
  } else if (event_name == "mm_filemap_add_to_page_cache") {
    using MFA = protos::pbzero::MmFilemapAddToPageCacheFtraceEvent;
    writer->AppendString(" dev ");
    write_value_at_index(MFA::kSDevFieldNumber - 1,
                         [writer](const Variadic& value) {
                           writer->AppendInt(value.int_value >> 20);
                         });
    writer->AppendString(":");
    write_value_at_index(MFA::kSDevFieldNumber - 1,
                         [writer](const Variadic& value) {
                           writer->AppendInt(value.int_value & ((1 << 20) - 1));
                         });
    writer->AppendString(" ino ");
    write_value_at_index(MFA::kIInoFieldNumber - 1, write_value);
    writer->AppendString(" page=0000000000000000");
    writer->AppendString(" pfn=");
    write_value_at_index(MFA::kPfnFieldNumber - 1, write_value);
    writer->AppendString(" ofs=");
    write_value_at_index(MFA::kIndexFieldNumber - 1,
                         [writer](const Variadic& value) {
                           writer->AppendInt(value.int_value << 12);
                         });
    return;
  } else if (event_name == "print") {
    using P = protos::pbzero::PrintFtraceEvent;

    uint32_t arg_row = start_row + P::kBufFieldNumber - 1;
    const auto& args = storage_->args();
    const auto& value = args.arg_values()[arg_row];
    const auto& str = storage_->GetString(value.string_value);
    // If the last character is a newline in a print, just drop it.
    auto chars_to_print = !str.empty() && str.c_str()[str.size() - 1] == '\n'
                              ? str.size() - 1
                              : str.size();
    writer->AppendChar(' ');
    writer->AppendString(str.c_str(), chars_to_print);
    return;
  }

  uint32_t arg = 0;
  for (auto it = lb; it != ub; it++) {
    write_arg(arg++, write_value);
  }
}

void RawTable::ToSystrace(sqlite3_context* ctx,
                          int argc,
                          sqlite3_value** argv) {
  if (argc != 1 || sqlite3_value_type(argv[0]) != SQLITE_INTEGER) {
    sqlite3_result_error(ctx, "Usage: to_ftrace(id)", -1);
    return;
  }
  RowId row_id = sqlite3_value_int64(argv[0]);
  auto pair = TraceStorage::ParseRowId(row_id);
  PERFETTO_DCHECK(pair.first == TableId::kRawEvents);
  auto row = pair.second;

  const auto& raw_evts = storage_->raw_events();

  UniqueTid utid = raw_evts.utids()[row];
  const auto& thread = storage_->GetThread(utid);
  uint32_t tgid = 0;
  if (thread.upid.has_value()) {
    tgid = storage_->GetProcess(thread.upid.value()).pid;
  }
  const auto& name = storage_->GetString(thread.name_id);

  char line[4096];
  base::StringWriter writer(line, sizeof(line));

  ftrace_utils::FormatSystracePrefix(raw_evts.timestamps()[row],
                                     raw_evts.cpus()[row], thread.tid, tgid,
                                     base::StringView(name), &writer);

  const auto& event_name = storage_->GetString(raw_evts.name_ids()[row]);
  writer.AppendChar(' ');
  if (event_name == "print") {
    writer.AppendString("tracing_mark_write");
  } else {
    writer.AppendString(event_name.c_str(), event_name.size());
  }
  writer.AppendChar(':');

  FormatSystraceArgs(event_name, raw_evts.arg_set_ids()[row], &writer);
  sqlite3_result_text(ctx, writer.CreateStringCopy(), -1, free);
}

}  // namespace trace_processor
}  // namespace perfetto
<|endoftext|>


<commit_before>// Copyright 2016 Lachlan Gunn

#include <algorithm>
#include <list>

#include "verify.h"
#include "packet.h"
#include "keys/key.h"
#include "parser.h"
#include "exceptions.h"

namespace parse4880 {

namespace {

void UpdateContextWithKey(VerificationContext& ctx, const PublicKeyPacket& key) {
  ctx.Update("\x99");
  ctx.Update(WriteInteger(key.contents().length(), 2));
  ctx.Update(key.contents());
}

}  // namespace

int verify_subkey_binding(const PublicKeyPacket&    key_packet,
                           const PublicSubkeyPacket& subkey_packet,
                           const SignaturePacket&    signature) {
  // First we need to get the primary key out of the packet.
  std::unique_ptr<Key> key = Key::ParseKey(key_packet);

  const std::list<std::shared_ptr<PGPPacket>>& subpackets = signature.subpackets();

  std::unique_ptr<VerificationContext> ctx =
      key->GetVerificationContext(signature);

  UpdateContextWithKey(*ctx, key_packet);
  UpdateContextWithKey(*ctx, subkey_packet);

  bool verifies = ctx->Verify();

  auto subsignature_iterator =
      std::find_if(subpackets.begin(), subpackets.end(),
                   [](const std::shared_ptr<PGPPacket>& x) -> bool {
                     return (x->tag() == 32);
                   });

  if (subsignature_iterator != subpackets.end()) {
    try {
      std::unique_ptr<Key> subkey = Key::ParseKey(subkey_packet);
      SignaturePacket subsignature_packet((**subsignature_iterator).contents());
      std::unique_ptr<VerificationContext> ctx_subsignature =
          subkey->GetVerificationContext(subsignature_packet);
      UpdateContextWithKey(*ctx_subsignature, key_packet);
      UpdateContextWithKey(*ctx_subsignature, subkey_packet);

      verifies &= ctx_subsignature->Verify();
    } catch(parse4880::parse4880_error e) {
      return verifies;
    }
  }

  return verifies;
}

}  // namespace parse4880
<commit_msg>Added proper subkey verification return value.<commit_after>// Copyright 2016 Lachlan Gunn

#include <algorithm>
#include <list>

#include "verify.h"
#include "packet.h"
#include "keys/key.h"
#include "parser.h"
#include "exceptions.h"

namespace parse4880 {

namespace {

void UpdateContextWithKey(VerificationContext& ctx, const PublicKeyPacket& key) {
  ctx.Update("\x99");
  ctx.Update(WriteInteger(key.contents().length(), 2));
  ctx.Update(key.contents());
}

}  // namespace

int verify_subkey_binding(const PublicKeyPacket&    key_packet,
                           const PublicSubkeyPacket& subkey_packet,
                           const SignaturePacket&    signature) {
  // First we need to get the primary key out of the packet.
  std::unique_ptr<Key> key = Key::ParseKey(key_packet);

  // Next, we validate the top-level signature.
  std::unique_ptr<VerificationContext> ctx =
      key->GetVerificationContext(signature);

  UpdateContextWithKey(*ctx, key_packet);
  UpdateContextWithKey(*ctx, subkey_packet);

  int verifies = ctx->Verify();

  // The first signature having been validated, we need to check for and
  // validate the second binding signature.
  const std::list<std::shared_ptr<PGPPacket>>& subpackets = signature.subpackets();
  auto subsignature_iterator =
      std::find_if(subpackets.begin(), subpackets.end(),
                   [](const std::shared_ptr<PGPPacket>& x) -> bool {
                     return (x->tag() == 32);
                   });

  if (subsignature_iterator != subpackets.end()) {
    try {
      std::unique_ptr<Key> subkey = Key::ParseKey(subkey_packet);
      SignaturePacket subsignature_packet((**subsignature_iterator).contents());
      std::unique_ptr<VerificationContext> ctx_subsignature =
          subkey->GetVerificationContext(subsignature_packet);
      UpdateContextWithKey(*ctx_subsignature, key_packet);
      UpdateContextWithKey(*ctx_subsignature, subkey_packet);

      // We should signal somehow a verification failure.
      verifies += ctx_subsignature->Verify();
    } catch(parse4880::parse4880_error e) {
      return verifies;
    }
  }

  return verifies;
}

}  // namespace parse4880
<|endoftext|>


<commit_before>#ifndef BOP_MATRIX_HPP
#define BOP_MATRIX_HPP

#include <memory>
#include <initializer_list>
#include <string>
#include <sstream>
#include <new>
#include "Vector.hpp"

/*
	bop::maths::Matrix class file
*/

namespace bop {
	namespace maths{
		template<class T>
		class Matrix {
			protected:
				unsigned int width;
				unsigned int height;
			public:
				Vector<T>* data;

				//Constructors
				Matrix(unsigned int size, T fill = 0) {
					/*
						Square matrix constructor, sets all values as
						the given fill value.
					*/
					this->data = new Vector<T>[size];
					for (int i = 0; i < size; i++) {
						this->data[i] = Vector<T>(size, fill);
					}
					this->width = size;
					this->height = size;
				}

				Matrix(unsigned int width, unsigned int height, T fill = 0) {
					/*
						Non-square matrix constructor, sets all values as
						the given fill value.
					*/
					this->data = new Vector<T>[height];
					for (int i = 0; i < height; i++) {
						this->data[i] = Vector<T>(width, fill);
					}
					this->height = height;
					this->width = width;
				}

				Matrix(std::initializer_list< std::initializer_list<T> > list) {
					/*
						Creates a matrix from a 2-dimensional initializer_list.
					*/
					this->height = list.size();
					this->data = new Vector<T>[this->height];
					unsigned int min_w = list.begin()->size();
					int i = 0;
					for (auto elem : list) {
						if (elem.size() < min_w) min_w = elem.size();
						this->data[i] = elem;
						i++;
					}
					this->width = min_w;
				}

				Matrix(Matrix<T>& mat) {
					/*
						Copy constructor.
					*/
					this->width = mat.width;
					this->height = mat.height;
					this->data = new Vector<T>[this->height];
					for (unsigned int i = 0; i < this->width; i++) {
						this->data[i] = mat.data[i];
					}
				}

				Matrix(Matrix<T>&& mat) {
					/*
						Move constructor.
					*/
					this->width = mat.width;
					this->height = mat.height;
					this->data = mat.data;
				}

				Matrix() {
					/*
						Empty constructor.
					*/
				}

				//Destructor
				~Matrix() {
					delete[] this->data;
				}

				//Operator overloads
				inline Vector<T>& operator[] (const unsigned int index) {}
				Matrix<T>& operator= (const Matrix<T> &mat) {}

				//Arithmetic overloads
				Matrix<T>& operator*= (const T scalar) {
					/*
						Scalar multiplication member operator, multiplies all
						elements by the given scalar.
					*/
					for (int i = 0; i < this->height; i++) {
						this->data[i] *= scalar;
					}
					return *this;
				}

				Matrix<T>& operator*= (Matrix<T> &mat) {
					/*
						Matrix multiplication member operator.
					*/
					Vector<T>* temp = new Vector<T>[this->height];
					for (int i = 0; i < this->height; i++) {
						temp[i] = Vector<T>(mat.width);
					}
					for (int r = 0; r < this->height; r++) {
						for (int c = 0; c < mat.width; c++) {
							T product = 0;
							for (int i = 0; i < mat.width; i++) {
								product += (this->data[r][i] * mat.data[i][c]);
							}
							temp[r][c] = product;
						}
					}
					delete[] this->data;
					this->data = temp;
					this->width = mat.width;
					return *this;
				}

				Matrix<T>& operator/= (const T scalar) {
					/*
						Scalar division member operator, divides all elements
						by the given scalar.
					*/
					for (int i = 0; i < this->height; i++) {
						this->data[i] /= scalar;
					}
					return *this;
				}

				Matrix<T>& operator+= (Matrix<T> &mat) {
					/*
						Addition member operator, adds all the elements of a
						given matrix to the matrix.
					*/
					for (int i = 0; i < this->height; i++) {
						this->data[i] += mat[i];
					}
					return *this;
				}

				Matrix<T>& operator-= (Matrix<T> &mat) {
					/*
						Subtraction member operator, subtracts the value of
						each element in a given matrix from the matrix.
					*/
					for (int i = 0; i < this->height; i++) {
						this->data[i] -= mat[i];
					}
					return *this;
				}

				//Information functions
				inline unsigned int w() {
					/*
						Returns the width of the Matrix.
					*/
					return this->width;
				}

				inline unsigned int h() {
					/*
						Returns the height of the Matrix.
					*/
					return this->height;
				}

				inline bool square() {
					/*
						Determines if the Matrix is a square Matrix.
					*/
					return (this->width == this->height);
				}

				std::string string(bool newlines = true) {
					/*
						Similar to the maths::Vector::string function, returns
						a human-readable representation of the Matrix.
					*/
					std::ostringstream mat_str;
					for (int i = 0; i < this->height; i++) {
						mat_str << '[' << this->data[i].string(false) << ']';
						if (newlines) mat_str << '\n';
					}
					return mat_str.str();
				}

		};

		//External arithmetic overloads

		template<class T>
		Matrix<T> operator* (Matrix<T> mat, const T scalar) {
			mat *= scalar;
			return mat;
		}

		template<class T>
		Matrix<T> operator* (Matrix<T> mat1, Matrix<T>& mat2) {
			mat1 *= mat2;
			return mat1;
		}

		template<class T>
		Matrix<T> operator/ (Matrix<T> mat, const T scalar) {
			mat /= scalar;
			return mat;
		}

		template<class T>
		Matrix<T> operator+ (Matrix<T> mat1, Matrix<T>& mat2) {
			mat1 += mat2;
			return mat1;
		}

		template<class T>
		Matrix<T> operator- (Matrix<T> mat1, Matrix<T>& mat2) {
			mat1 -= mat2;
		}

		//Matrix related functions
		template<class T>
		T determinant(Matrix<T>& mat, Vector<bool>& allowed_cols, unsigned int& size) {
			/*
				Recursive matrix determinant function.
			*/
			if (size == 2) {
				//the  base case, finding the 2 by 2 matrix determinant
				int c1 = -1, c2 = -1;
				for (int i = 0; i < mat.w(); i++) {
					if (allowed_cols[i]) {
						if (c1 < 0) {
							c1 = i;
						}
						else if (c2 < 0) {
							c2 = i;
						}
						else {
							break;
						}
					}
				}

				return (mat[mat.h() - 2][c1] * mat[mat.h() - 1][c2]) - (mat[mat.h() - 2][c2] * mat[mat.h() - 1][c1]);

			}
			else {
				size--;
				T product = 0;
				T multi = 1;

				for (int i = 0; i < mat.w(); i++) {
					if (!allowed_cols[i]) continue;
					else {
						allowed_cols[i] = false;
						product += (multi * (mat[mat.h() - size][i] * determinant(mat, allowed_cols, size)));
						multi *= -1;
						allowed_cols[i] = true;

					}
				}

				size++;
				return product;
			}
		}

		template<class T>
		T determinant(Matrix<T>& mat) {
			/*
				Matrix determinant init function.
			*/
			if (mat.w() != mat.h()) return static_cast<T>(0);
			else {
				if (mat.w() == 2) {
					//shortcut to determinant of a 2 by 2 matrix
					return (mat[0][0] * mat[1][1]) - (mat[0][1] * mat[1][0]);
				}
				else {
					Vector<bool> allowed_cols(mat.w(), true);
					T product = 0;
					T multi = 1;
					int size = mat.h() - 1;
					for (int i = 0; i < mat.w(); i++) {
						allowed_cols[i] = false;
						product += (multi * (mat[0][i] * determinant(mat, allowed_cols, size)));
						multi *= -1;
						allowed_cols[i] = true;
					}
					return product;
				}
			}
		}

		template<class T>
		Matrix<T> identityMatrix(unsigned int size) {
			/*
				Returns an Identity Matrix.
			*/
			Matrix<T> unit_m(size);
			for (int i = 0; i < size; i++) {
				unit_m[i] = 1;
			}
			return unit_m;
		}

		template<class T>
		Matrix<T> inverseMatrix(Matrix<T> &mat) {
			//Todo
		}

		template<class T>
		Matrix<T> transposeMatrix(Matrix<T> &mat) {
			/*
				Returns a transposed matrix.
			*/
			Matrix<T> trans(mat.h(), mat.w(), 0);
			for (unsigned int y = 0; y < mat.h(); y++) {
				for (unsigned int x = 0; x < mat.w(); x++) {
					trans[x][y] = mat[y][x];
				}
			}
			return trans;
		}

	}
}

#endif<commit_msg>Added various maths::Matrix methods<commit_after>#ifndef BOP_MATRIX_HPP
#define BOP_MATRIX_HPP

#include <memory>
#include <initializer_list>
#include <string>
#include <sstream>
#include <new>
#include "Vector.hpp"

/*
	bop::maths::Matrix class file
*/

namespace bop {
	namespace maths{
		template<class T>
		class Matrix {
			protected:
				unsigned int width;
				unsigned int height;
			public:
				Vector<T>* data;

				//Constructors
				Matrix(unsigned int size, T fill = 0) {
					/*
						Square matrix constructor, sets all values as
						the given fill value.
					*/
					this->data = new Vector<T>[size];
					for (unsigned int i = 0; i < size; i++) {
						this->data[i] = Vector<T>(size, fill);
					}
					this->width = size;
					this->height = size;
				}

				Matrix(unsigned int width, unsigned int height, T fill = 0) {
					/*
						Non-square matrix constructor, sets all values as
						the given fill value.
					*/
					this->data = new Vector<T>[height];
					for (int i = 0; i < height; i++) {
						this->data[i] = Vector<T>(width, fill);
					}
					this->height = height;
					this->width = width;
				}

				Matrix(std::initializer_list< std::initializer_list<T> > list) {
					/*
						Creates a matrix from a 2-dimensional initializer_list.
					*/
					this->height = list.size();
					this->data = new Vector<T>[this->height];
					unsigned int min_w = list.begin()->size();
					int i = 0;
					for (auto elem : list) {
						if (elem.size() < min_w) min_w = elem.size();
						this->data[i] = elem;
						i++;
					}
					this->width = min_w;
				}

				Matrix(Matrix<T>& mat) {
					/*
						Copy constructor.
					*/
					this->width = mat.width;
					this->height = mat.height;
					this->data = new Vector<T>[this->height];
					for (unsigned int i = 0; i < this->width; i++) {
						this->data[i] = mat.data[i];
					}
				}

				Matrix(Matrix<T>&& mat) {
					/*
						Move constructor.
					*/
					this->width = mat.width;
					this->height = mat.height;
					this->data = mat.data;
				}

				Matrix() {

					/*
						Empty constructor.
					*/
				}

				//Destructor
				~Matrix() {
					delete[] this->data;
				}

				//Operator overloads
				inline Vector<T>& operator[] (const unsigned int index) {
					return this->data[index];
				}

				Matrix<T>& operator= (const Matrix<T> &mat) {
					this->width = mat.width;
					this->height = mat.height;
					delete[] this->data;
					this->data = new Vector<T>[this->height];
					for (unsigned int i = 0; i < this->height; i++) {
						this->data[i] = mat.data[i];
					}
				}

				//Boolean logic overloads
				bool operator== (const Matrix<T>& mat) {
					if (this->width == mat.width && this->height == mat.height) {
						bool same = true;
						for (unsigned int i = 0; i < this->height && same; i++) {
							same = (this->data[i] == mat.data[i]);
						}
						return same;
					}
					else return false;
				}

				bool operator!= (const Matrix<T>& mat) {
					return !(this->operator==(mat));
				}

				//Arithmetic overloads
				Matrix<T>& operator*= (const T scalar) {
					/*
						Scalar multiplication member operator, multiplies all
						elements by the given scalar.
					*/
					for (int i = 0; i < this->height; i++) {
						this->data[i] *= scalar;
					}
					return *this;
				}

				Matrix<T>& operator*= (Matrix<T> &mat) {
					/*
						Matrix multiplication member operator.
					*/
					Vector<T>* temp = new Vector<T>[this->height];
					for (int i = 0; i < this->height; i++) {
						temp[i] = Vector<T>(mat.width);
					}
					for (int r = 0; r < this->height; r++) {
						for (int c = 0; c < mat.width; c++) {
							T product = 0;
							for (int i = 0; i < mat.width; i++) {
								product += (this->data[r][i] * mat.data[i][c]);
							}
							temp[r][c] = product;
						}
					}
					delete[] this->data;
					this->data = temp;
					this->width = mat.width;
					return *this;
				}

				Matrix<T>& operator/= (const T scalar) {
					/*
						Scalar division member operator, divides all elements
						by the given scalar.
					*/
					for (int i = 0; i < this->height; i++) {
						this->data[i] /= scalar;
					}
					return *this;
				}

				Matrix<T>& operator+= (Matrix<T> &mat) {
					/*
						Addition member operator, adds all the elements of a
						given matrix to the matrix.
					*/
					for (int i = 0; i < this->height; i++) {
						this->data[i] += mat[i];
					}
					return *this;
				}

				Matrix<T>& operator-= (Matrix<T> &mat) {
					/*
						Subtraction member operator, subtracts the value of
						each element in a given matrix from the matrix.
					*/
					for (int i = 0; i < this->height; i++) {
						this->data[i] -= mat[i];
					}
					return *this;
				}

				//Information functions
				inline unsigned int w() {
					/*
						Returns the width of the Matrix.
					*/
					return this->width;
				}

				inline unsigned int h() {
					/*
						Returns the height of the Matrix.
					*/
					return this->height;
				}

				inline bool square() {
					/*
						Tests if the Matrix is a square Matrix.
					*/
					return (this->width == this->height);
				}

				bool identity() {
					/*
						Tests if the matrix is an identity matrix.
					*/
					if (this->width == this->height) {
						bool identity = true;
						for (unsigned int y = 0; y < this->height && identity; y++) {
							for (unsigned int x = 0; x < this->width && identity; x++) {
								if (x == y) identity = (this->data[y][x] == 1);
								else identity = (this->data[y][x] == 0);
							}
						}
						return identity;
					}
					else return false;
				}

				std::string string(bool newlines = true) {
					/*
						Similar to the maths::Vector::string function, returns
						a human-readable representation of the Matrix.
					*/
					std::ostringstream mat_str;
					for (unsigned int i = 0; i < this->height; i++) {
						mat_str << '[' << this->data[i].string(false) << ']';
						if (newlines) mat_str << '\n';
					}
					return mat_str.str();
				}

				//Matrix manipulation functions.

				inline void swapRows(unsigned int index_a, unsigned int index_b) {
					/*
						Row swap function, for use in such algorithms as Gauss-Jordan
						elimination.
					*/
					this->data[index_a].swap(this->data[index_b]);
				}

				void swap(Matrix<T>& mat) {
					/*
						Matrix object swap function.
					*/
					Vector<T>* temp_arr = mat.data;
					unsigned int temp_w = mat.width;
					unsigned int temp_h = mat.height;
					mat.data = this->data;
					mat.width = this->width;
					mat.height = this->height;
					this->data = temp_arr;
					this->width = temp_w;
					this->height = temp_h;
				}
		};

		//External arithmetic overloads

		template<class T>
		Matrix<T> operator* (Matrix<T> mat, const T scalar) {
			mat *= scalar;
			return mat;
		}

		template<class T>
		Matrix<T> operator* (Matrix<T> mat1, Matrix<T>& mat2) {
			mat1 *= mat2;
			return mat1;
		}

		template<class T>
		Matrix<T> operator/ (Matrix<T> mat, const T scalar) {
			mat /= scalar;
			return mat;
		}

		template<class T>
		Matrix<T> operator+ (Matrix<T> mat1, Matrix<T>& mat2) {
			mat1 += mat2;
			return mat1;
		}

		template<class T>
		Matrix<T> operator- (Matrix<T> mat1, Matrix<T>& mat2) {
			mat1 -= mat2;
			return mat1;
		}

		//Matrix related functions
		template<class T>
		T determinant(Matrix<T>& mat, Vector<bool>& allowed_cols, unsigned int& size) {
			/*
				Recursive matrix determinant function.
			*/
			if (size == 2) {
				//the  base case, finding the 2 by 2 matrix determinant
				int c1 = -1, c2 = -1;
				for (unsigned int i = 0; i < mat.w(); i++) {
					if (allowed_cols[i]) {
						if (c1 < 0) {
							c1 = i;
						}
						else if (c2 < 0) {
							c2 = i;
						}
						else {
							break;
						}
					}
				}
				return (mat[mat.h() - 2][c1] * mat[mat.h() - 1][c2]) - (mat[mat.h() - 2][c2] * mat[mat.h() - 1][c1]);
			}
			else {
				size--;
				T product = 0;
				T multi = 1;
				for (int i = 0; i < mat.w(); i++) {
					if (!allowed_cols[i]) continue;
					else {
						allowed_cols[i] = false;
						product += (multi * (mat[mat.h() - size][i] * determinant(mat, allowed_cols, size)));
						multi *= -1;
						allowed_cols[i] = true;

					}
				}
				size++;
				return product;
			}
		}

		template<class T>
		T determinant(Matrix<T>& mat) {
			/*
				Matrix determinant init function.
			*/
			if (!mat.square()) return static_cast<T>(0);
			else {
				if (mat.w() == 2) {
					//shortcut to determinant of a 2 by 2 matrix
					return (mat[0][0] * mat[1][1]) - (mat[0][1] * mat[1][0]);
				}
				else {
					Vector<bool> allowed_cols(mat.w(), true);
					T product = 0;
					T multi = 1;
					int size = mat.h() - 1;
					for (int i = 0; i < mat.w(); i++) {
						allowed_cols[i] = false;
						product += (multi * (mat[0][i] * determinant(mat, allowed_cols, size)));
						multi *= -1;
						allowed_cols[i] = true;
					}
					return product;
				}
			}
		}

		template<class T>
		Matrix<T> identityMatrix(unsigned int size) {
			/*
				Returns an Identity Matrix.
			*/
			Matrix<T> unit_m(size);
			for (int i = 0; i < size; i++) {
				unit_m[i] = 1;
			}
			return unit_m;
		}

		template<class T>
		bool invertable(Matrix<T> &mat) {
			return (mat.square() && determinant(mat) != 0);
		}

		template<class T>
		Matrix<T> inverseMatrix(Matrix<T> mat, bool tested = true) {
			/*
				Matrix inverse by Gauss-Jordan method. Assumes that the
				matrix has already been tested as invertible. takes a
				COPY of a matrix, as this method requires the manipulation
				of the rows of the matrix.
			*/
			if (!tested && invertable(mat) == 0) {
				/*
					In the case that the matrix is not invertible, the function will
					return an identity matrix with the height of the given matrix.
				*/
				return identityMatrix(mat.h());
			}
			else {
				//todo
			}
		}

		template<class T>
		Matrix<T> transposeMatrix(Matrix<T> &mat) {
			/*
				Creates & returns a transposed version of the given matrix.
			*/
			Matrix<T> trans(mat.h(), mat.w(), 0);
			for (unsigned int y = 0; y < mat.h(); y++) {
				for (unsigned int x = 0; x < mat.w(); x++) {
					trans[x][y] = mat[y][x];
				}
			}
			return trans;
		}

	}
}

#endif<|endoftext|>