<commit_before>/*
 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
 *
 * 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 <dali/dali.h>
#include <dali-toolkit/dali-toolkit.h>
#include <dali-toolkit/devel-api/image-atlas/image-atlas.h>
#include <dali/devel-api/images/atlas.h>

#include <assert.h>
#include <cstdlib>
#include <string.h>
#include <iostream>

#include "shared/view.h"
#include "shared/utility.h"

using namespace Dali;
using namespace Dali::Toolkit;

// LOCAL STUFF
namespace
{
const char* const CHANGE_IMAGE_ICON(DEMO_IMAGE_DIR "icon-change.png");
const char* const CHANGE_IMAGE_ICON_SELECTED( DEMO_IMAGE_DIR "icon-change-selected.png" );

// The content amount of one page between portrait and landscape view are different
// set a ratio to modify the current page number when the rotation is changed
const float PAGE_NUMBER_CORRESPONDING_RATIO(1.25f);

const char* BOOK_COVER_PORTRAIT( DEMO_IMAGE_DIR "book-portrait-cover.jpg" );
const char* BOOK_COVER_LANDSCAPE( DEMO_IMAGE_DIR "book-landscape-cover.jpg" );
const char* BOOK_COVER_BACK_LANDSCAPE( DEMO_IMAGE_DIR "book-landscape-cover-back.jpg" );

const char* PAGE_IMAGES_PORTRAIT[] =
{
  DEMO_IMAGE_DIR "book-portrait-p1.jpg",
  DEMO_IMAGE_DIR "book-portrait-p2.jpg",
  DEMO_IMAGE_DIR "book-portrait-p3.jpg",
  DEMO_IMAGE_DIR "book-portrait-p4.jpg",
  DEMO_IMAGE_DIR "book-portrait-p5.jpg"
};
const unsigned int NUMBER_OF_PORTRAIT_IMAGE( sizeof(PAGE_IMAGES_PORTRAIT) / sizeof(PAGE_IMAGES_PORTRAIT[0]) );

const char* PAGE_IMAGES_LANDSCAPE[] =
{
  DEMO_IMAGE_DIR "book-landscape-p1.jpg",
  DEMO_IMAGE_DIR "book-landscape-p2.jpg",
  DEMO_IMAGE_DIR "book-landscape-p3.jpg",
  DEMO_IMAGE_DIR "book-landscape-p4.jpg",
  DEMO_IMAGE_DIR "book-landscape-p5.jpg",
  DEMO_IMAGE_DIR "book-landscape-p6.jpg",
  DEMO_IMAGE_DIR "book-landscape-p7.jpg",
  DEMO_IMAGE_DIR "book-landscape-p8.jpg"
};
const unsigned int NUMBER_OF_LANDSCAPE_IMAGE( sizeof(PAGE_IMAGES_LANDSCAPE) / sizeof(PAGE_IMAGES_LANDSCAPE[0]) );

Atlas LoadImages( const char*imagePath1, const char* imagePath2 )
{
  PixelData pixelData1 = DemoHelper::LoadPixelData( imagePath1, ImageDimensions(), FittingMode::DEFAULT, SamplingMode::DEFAULT );
  PixelData pixelData2 = DemoHelper::LoadPixelData( imagePath2, ImageDimensions(), FittingMode::DEFAULT, SamplingMode::DEFAULT );

  unsigned int width = pixelData1.GetWidth()+pixelData2.GetWidth();
  unsigned int height = pixelData1.GetHeight() > pixelData2.GetHeight() ? pixelData1.GetHeight() : pixelData2.GetHeight();

  Atlas image  = Atlas::New( width, height );
  image.Upload( pixelData1, 0u, 0u );
  image.Upload( pixelData2, pixelData1.GetWidth(), 0u );

  return image;
}

}// end LOCAL STUFF

class PortraitPageFactory : public PageFactory
{
  /**
   * Query the number of pages available from the factory.
   * The maximum available page has an ID of GetNumberOfPages()-1.
   */
  virtual unsigned int GetNumberOfPages()
  {
    return 10*NUMBER_OF_PORTRAIT_IMAGE + 1;
  }
  /**
   * Create an image to represent a page.
   * @param[in] pageId The ID of the page to create.
   * @return An image, or an uninitialized pointer if the ID is out of range.
   */
  virtual Image NewPage( unsigned int pageId )
  {
    Atlas page;

    if( pageId == 0 )
    {
      page = DemoHelper::LoadImage( BOOK_COVER_PORTRAIT );
    }
    else
    {
      page = DemoHelper::LoadImage( PAGE_IMAGES_PORTRAIT[ (pageId-1) % NUMBER_OF_PORTRAIT_IMAGE ] );
    }

    return page;
  }
};

class LandscapePageFactory : public PageFactory
{

  /**
   * Query the number of pages available from the factory.
   * The maximum available page has an ID of GetNumberOfPages()-1.
   */
  virtual unsigned int GetNumberOfPages()
  {
    return 10*NUMBER_OF_LANDSCAPE_IMAGE / 2 + 1;
  }
  /**
   * Create an image to represent a page.
   * @param[in] pageId The ID of the page to create.
   * @return An image, or an uninitialized pointer if the ID is out of range.
   */
  virtual Image NewPage( unsigned int pageId )
  {

    Atlas page;
    if( pageId == 0 )
    {
      page = LoadImages( BOOK_COVER_LANDSCAPE, BOOK_COVER_BACK_LANDSCAPE );
    }
    else
    {
      unsigned int imageId = (pageId-1)*2;
      page = LoadImages( PAGE_IMAGES_LANDSCAPE[ imageId % NUMBER_OF_LANDSCAPE_IMAGE ], PAGE_IMAGES_LANDSCAPE[ (imageId+1) % NUMBER_OF_LANDSCAPE_IMAGE ] );
    }

    return page;
  }
};

/**
 * This example shows how to use the page turn UI control to implement the page-turn demo
 * The effect follows the pan gesture to animate the page
 * Pan the image inwards, the page will bent,
 * Depends on the distance of the panning, the image might turn over or slide back
 * Also, in portrait view, the pan gesture outwards from position near the spine could turn the previous page back
 * Allows to turn multiple pages one by one quickly towards the same direction, multiple animations are launched in this case
*/
class PageTurnController : public ConnectionTracker
{
public:
  PageTurnController( Application &app );
  ~PageTurnController();

  //This method gets called once the main loop of application is up and running
  void OnInit( Application& app );

private:

  /**
   * This method gets called when the button is clicked, switch between portrait and landscape views
   */
  bool OnButtonClicked(Toolkit::Button button);

  /**
   * Main key event handler
   */
  void OnKeyEvent(const KeyEvent& event);

  /**
   * Callback function of page turned signal
   * @param[in] pageTurnView The handle of the PageTurnPortraitView or PageTurnLandscapeView
   * @param[in] pageIndex The index of the page turned over
   * @param[in] isTurningForward The turning direction, forwards or backwards
   */
  void OnPageStartedTurn( PageTurnView pageTurnView, unsigned int pageIndex, bool isTurningForward );

  /**
   * Callback function of page turned signal
   * @param[in] pageTurnView The handle of the PageTurnPortraitView or PageTurnLandscapeView
   * @param[in] pageIndex The index of the page turned over
   * @param[in] isTurningForward The turning direction, forwards or backwards
   */
  void OnPageFinishedTurn( PageTurnView pageTurnView, unsigned int pageIndex, bool isTurningForward );

  /**
   * Callback function of page started pan signal
   *
   * @param[in] pageTurnView The calling page turn view
   */
  void OnPageStartedPan( PageTurnView pageTurnView );

  /**
   * Callback function of page finished pan signal
   *
   * @param[in] pageTurnView The calling page turn view
   */
  void OnPageFinishedPan( PageTurnView pageTurnView );

private:

  Application&                mApplication;
  Layer                       mButtonLayer;

  PageTurnView                mPageTurnPortraitView;
  PageTurnView                mPageTurnLandscapeView;
  PortraitPageFactory         mPortraitPageFactory;
  LandscapePageFactory        mLandscapePageFactory;

  bool                        mIsPortrait;
};

PageTurnController::PageTurnController( Application &app )
:mApplication( app ),
 mIsPortrait( true )
{
  // Connect to the Application's Init signal
  app.InitSignal().Connect( this, &PageTurnController::OnInit );
}

PageTurnController::~PageTurnController()
{
}

void PageTurnController::OnInit( Application& app )
{
  // The Init signal is received once ( only ) during the Application lifetime

  Stage::GetCurrent().KeyEventSignal().Connect(this, &PageTurnController::OnKeyEvent);

  // Hide the indicator bar
  app.GetWindow().ShowIndicator( Dali::Window::INVISIBLE );

  Stage stage = Stage::GetCurrent();
  Vector2 stageSize =  stage.GetSize();

  mButtonLayer = Layer::New();
  mButtonLayer.SetAnchorPoint( Dali::AnchorPoint::CENTER );
  mButtonLayer.SetParentOrigin( Dali::ParentOrigin::CENTER );
  mButtonLayer.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
  Toolkit::PushButton button = Toolkit::PushButton::New();
  button.SetAnchorPoint( AnchorPoint::TOP_RIGHT );
  button.SetParentOrigin( ParentOrigin::TOP_RIGHT );
  button.SetUnselectedImage( CHANGE_IMAGE_ICON  );
  button.SetSelectedImage( CHANGE_IMAGE_ICON_SELECTED );
  button.SetLeaveRequired( true );
  button.SetScale(1.5f);
  button.PressedSignal().Connect( this, &PageTurnController::OnButtonClicked );
  stage.Add( mButtonLayer );
  mButtonLayer.Add(button);

  Vector2 bookSize( stageSize.x > stageSize.y ? stageSize.y : stageSize.x,
                    stageSize.x > stageSize.y ? stageSize.x : stageSize.y );

  mPageTurnPortraitView = PageTurnPortraitView::New( mPortraitPageFactory, bookSize );
  mPageTurnPortraitView.SetParentOrigin( ParentOrigin::CENTER );
  mPageTurnPortraitView.SetAnchorPoint( AnchorPoint::CENTER );
  mPageTurnPortraitView.SetProperty( PageTurnView::Property::SPINE_SHADOW, Vector2(70.f, 30.f) );
  mPageTurnPortraitView.PageTurnStartedSignal().Connect( this, &PageTurnController::OnPageStartedTurn );
  mPageTurnPortraitView.PageTurnFinishedSignal().Connect( this, &PageTurnController::OnPageFinishedTurn );
  mPageTurnPortraitView.PagePanStartedSignal().Connect( this, &PageTurnController::OnPageStartedPan );
  mPageTurnPortraitView.PagePanFinishedSignal().Connect( this, &PageTurnController::OnPageFinishedPan );

  mPageTurnLandscapeView = PageTurnLandscapeView::New( mLandscapePageFactory, Vector2(bookSize.y*0.5f, bookSize.x) );
  mPageTurnLandscapeView.SetParentOrigin( ParentOrigin::CENTER );
  mPageTurnLandscapeView.SetAnchorPoint( AnchorPoint::CENTER );
  mPageTurnLandscapeView.PageTurnStartedSignal().Connect( this, &PageTurnController::OnPageStartedTurn );
  mPageTurnLandscapeView.PageTurnFinishedSignal().Connect( this, &PageTurnController::OnPageFinishedTurn );
  mPageTurnLandscapeView.PagePanStartedSignal().Connect( this, &PageTurnController::OnPageStartedPan );
  mPageTurnLandscapeView.PagePanFinishedSignal().Connect( this, &PageTurnController::OnPageFinishedPan );

  if( stageSize.x > stageSize.y )
  {
    stage.Add(mPageTurnLandscapeView);
    mPageTurnPortraitView.SetOrientation(Degree(90.f), Vector3::ZAXIS);
    mIsPortrait = false;
  }
  else
  {
    stage.Add(mPageTurnPortraitView);
    mPageTurnLandscapeView.SetOrientation(Degree(90.f), Vector3::ZAXIS);
    mIsPortrait = true;
  }

  mButtonLayer.RaiseToTop();
}

bool PageTurnController::OnButtonClicked(Toolkit::Button button)
{
  if( mIsPortrait )
  {
    mPageTurnPortraitView.Unparent();
    Stage::GetCurrent().Add( mPageTurnLandscapeView );
    int pageId = mPageTurnPortraitView.GetProperty( PageTurnView::Property::CURRENT_PAGE_ID ).Get<int>();
    int currentPage = ceil( static_cast<float>(pageId) / PAGE_NUMBER_CORRESPONDING_RATIO );
    mPageTurnLandscapeView.SetProperty(PageTurnView::Property::CURRENT_PAGE_ID, currentPage );
  }
  else
  {
    mPageTurnLandscapeView.Unparent();
    Stage::GetCurrent().Add( mPageTurnPortraitView );
    int pageId = mPageTurnLandscapeView.GetProperty( PageTurnView::Property::CURRENT_PAGE_ID ).Get<int>();
    int currentPage = floor(pageId * PAGE_NUMBER_CORRESPONDING_RATIO );
    mPageTurnPortraitView.SetProperty(PageTurnView::Property::CURRENT_PAGE_ID, currentPage );
  }

  mIsPortrait = !mIsPortrait;
  mButtonLayer.RaiseToTop();
  return true;
}

/**
 * Main key event handler
 */
void PageTurnController::OnKeyEvent(const KeyEvent& event)
{
  if(event.state == KeyEvent::Down)
  {
    if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
    {
      mApplication.Quit();
    }
  }
}

void PageTurnController::OnPageStartedTurn( PageTurnView pageTurnView, unsigned int pageIndex, bool isTurningForward )
{
  std::cout<< ( ( pageTurnView == mPageTurnPortraitView ) ? " portrait: " : " Landscape: " )
           << " page " << pageIndex
           << ( isTurningForward ? " is starting to turn forward" : " is starting to turn backward" )
           << std::endl;
}

void PageTurnController::OnPageFinishedTurn( PageTurnView pageTurnView, unsigned int pageIndex, bool isTurningForward )
{
  std::cout<< ( ( pageTurnView == mPageTurnPortraitView ) ? " portrait: " : " Landscape: " )
           << " page " << pageIndex
           << ( isTurningForward ? " has finished turning forward" : " has finished turning backward" )
           << std::endl;
}

void PageTurnController::OnPageStartedPan( PageTurnView pageTurnView )
{
  std::cout<< "Starting to pan" << std::endl;
}

void PageTurnController::OnPageFinishedPan( PageTurnView pageTurnView )
{
  std::cout<< "Finished panning" << std::endl;
}

// Entry point for applications
int DALI_EXPORT_API main( int argc, char **argv )
{
  Application app = Application::New(&argc, &argv, DEMO_THEME_PATH);
  PageTurnController test ( app );

  app.MainLoop();

  return 0;
}
<commit_msg>Changes after PageTurnView moved to Devel API<commit_after>/*
 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
 *
 * 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 <dali/dali.h>
#include <dali-toolkit/dali-toolkit.h>
#include <dali-toolkit/devel-api/image-atlas/image-atlas.h>
#include <dali-toolkit/devel-api/controls/page-turn-view/page-factory.h>
#include <dali-toolkit/devel-api/controls/page-turn-view/page-turn-landscape-view.h>
#include <dali-toolkit/devel-api/controls/page-turn-view/page-turn-portrait-view.h>
#include <dali-toolkit/devel-api/controls/page-turn-view/page-turn-view.h>
#include <dali/devel-api/images/atlas.h>

#include <assert.h>
#include <cstdlib>
#include <string.h>
#include <iostream>

#include "shared/view.h"
#include "shared/utility.h"

using namespace Dali;
using namespace Dali::Toolkit;

// LOCAL STUFF
namespace
{
const char* const CHANGE_IMAGE_ICON(DEMO_IMAGE_DIR "icon-change.png");
const char* const CHANGE_IMAGE_ICON_SELECTED( DEMO_IMAGE_DIR "icon-change-selected.png" );

// The content amount of one page between portrait and landscape view are different
// set a ratio to modify the current page number when the rotation is changed
const float PAGE_NUMBER_CORRESPONDING_RATIO(1.25f);

const char* BOOK_COVER_PORTRAIT( DEMO_IMAGE_DIR "book-portrait-cover.jpg" );
const char* BOOK_COVER_LANDSCAPE( DEMO_IMAGE_DIR "book-landscape-cover.jpg" );
const char* BOOK_COVER_BACK_LANDSCAPE( DEMO_IMAGE_DIR "book-landscape-cover-back.jpg" );

const char* PAGE_IMAGES_PORTRAIT[] =
{
  DEMO_IMAGE_DIR "book-portrait-p1.jpg",
  DEMO_IMAGE_DIR "book-portrait-p2.jpg",
  DEMO_IMAGE_DIR "book-portrait-p3.jpg",
  DEMO_IMAGE_DIR "book-portrait-p4.jpg",
  DEMO_IMAGE_DIR "book-portrait-p5.jpg"
};
const unsigned int NUMBER_OF_PORTRAIT_IMAGE( sizeof(PAGE_IMAGES_PORTRAIT) / sizeof(PAGE_IMAGES_PORTRAIT[0]) );

const char* PAGE_IMAGES_LANDSCAPE[] =
{
  DEMO_IMAGE_DIR "book-landscape-p1.jpg",
  DEMO_IMAGE_DIR "book-landscape-p2.jpg",
  DEMO_IMAGE_DIR "book-landscape-p3.jpg",
  DEMO_IMAGE_DIR "book-landscape-p4.jpg",
  DEMO_IMAGE_DIR "book-landscape-p5.jpg",
  DEMO_IMAGE_DIR "book-landscape-p6.jpg",
  DEMO_IMAGE_DIR "book-landscape-p7.jpg",
  DEMO_IMAGE_DIR "book-landscape-p8.jpg"
};
const unsigned int NUMBER_OF_LANDSCAPE_IMAGE( sizeof(PAGE_IMAGES_LANDSCAPE) / sizeof(PAGE_IMAGES_LANDSCAPE[0]) );

Atlas LoadImages( const char*imagePath1, const char* imagePath2 )
{
  PixelData pixelData1 = DemoHelper::LoadPixelData( imagePath1, ImageDimensions(), FittingMode::DEFAULT, SamplingMode::DEFAULT );
  PixelData pixelData2 = DemoHelper::LoadPixelData( imagePath2, ImageDimensions(), FittingMode::DEFAULT, SamplingMode::DEFAULT );

  unsigned int width = pixelData1.GetWidth()+pixelData2.GetWidth();
  unsigned int height = pixelData1.GetHeight() > pixelData2.GetHeight() ? pixelData1.GetHeight() : pixelData2.GetHeight();

  Atlas image  = Atlas::New( width, height );
  image.Upload( pixelData1, 0u, 0u );
  image.Upload( pixelData2, pixelData1.GetWidth(), 0u );

  return image;
}

}// end LOCAL STUFF

class PortraitPageFactory : public PageFactory
{
  /**
   * Query the number of pages available from the factory.
   * The maximum available page has an ID of GetNumberOfPages()-1.
   */
  virtual unsigned int GetNumberOfPages()
  {
    return 10*NUMBER_OF_PORTRAIT_IMAGE + 1;
  }
  /**
   * Create an image to represent a page.
   * @param[in] pageId The ID of the page to create.
   * @return An image, or an uninitialized pointer if the ID is out of range.
   */
  virtual Image NewPage( unsigned int pageId )
  {
    Atlas page;

    if( pageId == 0 )
    {
      page = DemoHelper::LoadImage( BOOK_COVER_PORTRAIT );
    }
    else
    {
      page = DemoHelper::LoadImage( PAGE_IMAGES_PORTRAIT[ (pageId-1) % NUMBER_OF_PORTRAIT_IMAGE ] );
    }

    return page;
  }
};

class LandscapePageFactory : public PageFactory
{

  /**
   * Query the number of pages available from the factory.
   * The maximum available page has an ID of GetNumberOfPages()-1.
   */
  virtual unsigned int GetNumberOfPages()
  {
    return 10*NUMBER_OF_LANDSCAPE_IMAGE / 2 + 1;
  }
  /**
   * Create an image to represent a page.
   * @param[in] pageId The ID of the page to create.
   * @return An image, or an uninitialized pointer if the ID is out of range.
   */
  virtual Image NewPage( unsigned int pageId )
  {

    Atlas page;
    if( pageId == 0 )
    {
      page = LoadImages( BOOK_COVER_LANDSCAPE, BOOK_COVER_BACK_LANDSCAPE );
    }
    else
    {
      unsigned int imageId = (pageId-1)*2;
      page = LoadImages( PAGE_IMAGES_LANDSCAPE[ imageId % NUMBER_OF_LANDSCAPE_IMAGE ], PAGE_IMAGES_LANDSCAPE[ (imageId+1) % NUMBER_OF_LANDSCAPE_IMAGE ] );
    }

    return page;
  }
};

/**
 * This example shows how to use the page turn UI control to implement the page-turn demo
 * The effect follows the pan gesture to animate the page
 * Pan the image inwards, the page will bent,
 * Depends on the distance of the panning, the image might turn over or slide back
 * Also, in portrait view, the pan gesture outwards from position near the spine could turn the previous page back
 * Allows to turn multiple pages one by one quickly towards the same direction, multiple animations are launched in this case
*/
class PageTurnController : public ConnectionTracker
{
public:
  PageTurnController( Application &app );
  ~PageTurnController();

  //This method gets called once the main loop of application is up and running
  void OnInit( Application& app );

private:

  /**
   * This method gets called when the button is clicked, switch between portrait and landscape views
   */
  bool OnButtonClicked(Toolkit::Button button);

  /**
   * Main key event handler
   */
  void OnKeyEvent(const KeyEvent& event);

  /**
   * Callback function of page turned signal
   * @param[in] pageTurnView The handle of the PageTurnPortraitView or PageTurnLandscapeView
   * @param[in] pageIndex The index of the page turned over
   * @param[in] isTurningForward The turning direction, forwards or backwards
   */
  void OnPageStartedTurn( PageTurnView pageTurnView, unsigned int pageIndex, bool isTurningForward );

  /**
   * Callback function of page turned signal
   * @param[in] pageTurnView The handle of the PageTurnPortraitView or PageTurnLandscapeView
   * @param[in] pageIndex The index of the page turned over
   * @param[in] isTurningForward The turning direction, forwards or backwards
   */
  void OnPageFinishedTurn( PageTurnView pageTurnView, unsigned int pageIndex, bool isTurningForward );

  /**
   * Callback function of page started pan signal
   *
   * @param[in] pageTurnView The calling page turn view
   */
  void OnPageStartedPan( PageTurnView pageTurnView );

  /**
   * Callback function of page finished pan signal
   *
   * @param[in] pageTurnView The calling page turn view
   */
  void OnPageFinishedPan( PageTurnView pageTurnView );

private:

  Application&                mApplication;
  Layer                       mButtonLayer;

  PageTurnView                mPageTurnPortraitView;
  PageTurnView                mPageTurnLandscapeView;
  PortraitPageFactory         mPortraitPageFactory;
  LandscapePageFactory        mLandscapePageFactory;

  bool                        mIsPortrait;
};

PageTurnController::PageTurnController( Application &app )
:mApplication( app ),
 mIsPortrait( true )
{
  // Connect to the Application's Init signal
  app.InitSignal().Connect( this, &PageTurnController::OnInit );
}

PageTurnController::~PageTurnController()
{
}

void PageTurnController::OnInit( Application& app )
{
  // The Init signal is received once ( only ) during the Application lifetime

  Stage::GetCurrent().KeyEventSignal().Connect(this, &PageTurnController::OnKeyEvent);

  // Hide the indicator bar
  app.GetWindow().ShowIndicator( Dali::Window::INVISIBLE );

  Stage stage = Stage::GetCurrent();
  Vector2 stageSize =  stage.GetSize();

  mButtonLayer = Layer::New();
  mButtonLayer.SetAnchorPoint( Dali::AnchorPoint::CENTER );
  mButtonLayer.SetParentOrigin( Dali::ParentOrigin::CENTER );
  mButtonLayer.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
  Toolkit::PushButton button = Toolkit::PushButton::New();
  button.SetAnchorPoint( AnchorPoint::TOP_RIGHT );
  button.SetParentOrigin( ParentOrigin::TOP_RIGHT );
  button.SetUnselectedImage( CHANGE_IMAGE_ICON  );
  button.SetSelectedImage( CHANGE_IMAGE_ICON_SELECTED );
  button.SetLeaveRequired( true );
  button.SetScale(1.5f);
  button.PressedSignal().Connect( this, &PageTurnController::OnButtonClicked );
  stage.Add( mButtonLayer );
  mButtonLayer.Add(button);

  Vector2 bookSize( stageSize.x > stageSize.y ? stageSize.y : stageSize.x,
                    stageSize.x > stageSize.y ? stageSize.x : stageSize.y );

  mPageTurnPortraitView = PageTurnPortraitView::New( mPortraitPageFactory, bookSize );
  mPageTurnPortraitView.SetParentOrigin( ParentOrigin::CENTER );
  mPageTurnPortraitView.SetAnchorPoint( AnchorPoint::CENTER );
  mPageTurnPortraitView.SetProperty( PageTurnView::Property::SPINE_SHADOW, Vector2(70.f, 30.f) );
  mPageTurnPortraitView.PageTurnStartedSignal().Connect( this, &PageTurnController::OnPageStartedTurn );
  mPageTurnPortraitView.PageTurnFinishedSignal().Connect( this, &PageTurnController::OnPageFinishedTurn );
  mPageTurnPortraitView.PagePanStartedSignal().Connect( this, &PageTurnController::OnPageStartedPan );
  mPageTurnPortraitView.PagePanFinishedSignal().Connect( this, &PageTurnController::OnPageFinishedPan );

  mPageTurnLandscapeView = PageTurnLandscapeView::New( mLandscapePageFactory, Vector2(bookSize.y*0.5f, bookSize.x) );
  mPageTurnLandscapeView.SetParentOrigin( ParentOrigin::CENTER );
  mPageTurnLandscapeView.SetAnchorPoint( AnchorPoint::CENTER );
  mPageTurnLandscapeView.PageTurnStartedSignal().Connect( this, &PageTurnController::OnPageStartedTurn );
  mPageTurnLandscapeView.PageTurnFinishedSignal().Connect( this, &PageTurnController::OnPageFinishedTurn );
  mPageTurnLandscapeView.PagePanStartedSignal().Connect( this, &PageTurnController::OnPageStartedPan );
  mPageTurnLandscapeView.PagePanFinishedSignal().Connect( this, &PageTurnController::OnPageFinishedPan );

  if( stageSize.x > stageSize.y )
  {
    stage.Add(mPageTurnLandscapeView);
    mPageTurnPortraitView.SetOrientation(Degree(90.f), Vector3::ZAXIS);
    mIsPortrait = false;
  }
  else
  {
    stage.Add(mPageTurnPortraitView);
    mPageTurnLandscapeView.SetOrientation(Degree(90.f), Vector3::ZAXIS);
    mIsPortrait = true;
  }

  mButtonLayer.RaiseToTop();
}

bool PageTurnController::OnButtonClicked(Toolkit::Button button)
{
  if( mIsPortrait )
  {
    mPageTurnPortraitView.Unparent();
    Stage::GetCurrent().Add( mPageTurnLandscapeView );
    int pageId = mPageTurnPortraitView.GetProperty( PageTurnView::Property::CURRENT_PAGE_ID ).Get<int>();
    int currentPage = ceil( static_cast<float>(pageId) / PAGE_NUMBER_CORRESPONDING_RATIO );
    mPageTurnLandscapeView.SetProperty(PageTurnView::Property::CURRENT_PAGE_ID, currentPage );
  }
  else
  {
    mPageTurnLandscapeView.Unparent();
    Stage::GetCurrent().Add( mPageTurnPortraitView );
    int pageId = mPageTurnLandscapeView.GetProperty( PageTurnView::Property::CURRENT_PAGE_ID ).Get<int>();
    int currentPage = floor(pageId * PAGE_NUMBER_CORRESPONDING_RATIO );
    mPageTurnPortraitView.SetProperty(PageTurnView::Property::CURRENT_PAGE_ID, currentPage );
  }

  mIsPortrait = !mIsPortrait;
  mButtonLayer.RaiseToTop();
  return true;
}

/**
 * Main key event handler
 */
void PageTurnController::OnKeyEvent(const KeyEvent& event)
{
  if(event.state == KeyEvent::Down)
  {
    if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
    {
      mApplication.Quit();
    }
  }
}

void PageTurnController::OnPageStartedTurn( PageTurnView pageTurnView, unsigned int pageIndex, bool isTurningForward )
{
  std::cout<< ( ( pageTurnView == mPageTurnPortraitView ) ? " portrait: " : " Landscape: " )
           << " page " << pageIndex
           << ( isTurningForward ? " is starting to turn forward" : " is starting to turn backward" )
           << std::endl;
}

void PageTurnController::OnPageFinishedTurn( PageTurnView pageTurnView, unsigned int pageIndex, bool isTurningForward )
{
  std::cout<< ( ( pageTurnView == mPageTurnPortraitView ) ? " portrait: " : " Landscape: " )
           << " page " << pageIndex
           << ( isTurningForward ? " has finished turning forward" : " has finished turning backward" )
           << std::endl;
}

void PageTurnController::OnPageStartedPan( PageTurnView pageTurnView )
{
  std::cout<< "Starting to pan" << std::endl;
}

void PageTurnController::OnPageFinishedPan( PageTurnView pageTurnView )
{
  std::cout<< "Finished panning" << std::endl;
}

// Entry point for applications
int DALI_EXPORT_API main( int argc, char **argv )
{
  Application app = Application::New(&argc, &argv, DEMO_THEME_PATH);
  PageTurnController test ( app );

  app.MainLoop();

  return 0;
}
<|endoftext|>


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

#include "chrome/browser/gtk/status_bubble_gtk.h"

#include <gtk/gtk.h>

#include "app/gfx/text_elider.h"
#include "app/l10n_util.h"
#include "base/gfx/gtk_util.h"
#include "base/message_loop.h"
#include "base/string_util.h"
#include "chrome/browser/gtk/gtk_theme_provider.h"
#include "chrome/browser/gtk/slide_animator_gtk.h"
#include "chrome/common/gtk_util.h"
#include "chrome/common/notification_service.h"
#include "googleurl/src/gurl.h"

namespace {

const GdkColor kFrameBorderColor = GDK_COLOR_RGB(0xbe, 0xc8, 0xd4);

// Inner padding between the border and the text label.
const int kInternalTopBottomPadding = 1;
const int kInternalLeftRightPadding = 2;

// The radius of the edges of our bubble.
const int kCornerSize = 4;

// Milliseconds before we hide the status bubble widget when you mouseout.
const int kHideDelay = 250;

enum FrameType {
  FRAME_MASK,
  FRAME_STROKE,
};

// Returns a list of points that either form the outline of the status bubble
// (|type| == FRAME_MASK) or form the inner border around the inner edge
// (|type| == FRAME_STROKE).
std::vector<GdkPoint> MakeFramePolygonPoints(int width,
                                             int height,
                                             FrameType type) {
  using gtk_util::MakeBidiGdkPoint;
  std::vector<GdkPoint> points;

  bool ltr = l10n_util::GetTextDirection() == l10n_util::LEFT_TO_RIGHT;
  // If we have a stroke, we have to offset some of our points by 1 pixel.
  // We have to inset by 1 pixel when we draw horizontal lines that are on the
  // bottom or when we draw vertical lines that are closer to the end (end is
  // right for ltr).
  int y_off = (type == FRAME_MASK) ? 0 : -1;
  // We use this one for LTR.
  int x_off_l = ltr ? y_off : 0;

  // Top left corner.
  points.push_back(MakeBidiGdkPoint(0, 0, width, ltr));

  // Top right (rounded) corner.
  points.push_back(MakeBidiGdkPoint(
      width - kCornerSize + 1 + x_off_l, 0, width, ltr));
  points.push_back(MakeBidiGdkPoint(
      width + x_off_l, kCornerSize - 1, width, ltr));

  // Bottom right corner.
  points.push_back(MakeBidiGdkPoint(
      width + x_off_l, height + y_off, width, ltr));

  if (type == FRAME_MASK) {
    // Bottom left corner.
    points.push_back(MakeBidiGdkPoint(0, height + y_off, width, ltr));
  }

  return points;
}

}  // namespace

StatusBubbleGtk::StatusBubbleGtk(Profile* profile)
    : theme_provider_(GtkThemeProvider::GetFrom(profile)),
      bubble_width_(-1),
      bubble_height_(-1),
      timer_factory_(this) {
  InitWidgets();

  registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED,
                 NotificationService::AllSources());
}

StatusBubbleGtk::~StatusBubbleGtk() {
  container_.Destroy();
}

void StatusBubbleGtk::SetStatus(const std::wstring& status_text_wide) {
  std::string status_text = WideToUTF8(status_text_wide);
  if (status_text_ == status_text)
    return;

  status_text_ = status_text;
  if (!status_text_.empty()) {
    SetStatusTextTo(status_text_);
  } else if (!url_text_.empty()) {
    SetStatusTextTo(url_text_);
  } else {
    SetStatusTextTo(std::string());
  }
}

void StatusBubbleGtk::SetURL(const GURL& url, const std::wstring& languages) {
  // If we want to clear a displayed URL but there is a status still to
  // display, display that status instead.
  if (url.is_empty() && !status_text_.empty()) {
    url_text_ = std::string();
    SetStatusTextTo(status_text_);
    return;
  }

  // Set Elided Text corresponding to the GURL object.  We limit the width of
  // the URL to a third of the width of the browser window (matching the width
  // on Windows).
  GtkWidget* parent = gtk_widget_get_parent(container_.get());
  int window_width = parent->allocation.width;
  // TODO(tc): We don't actually use gfx::Font as the font in the status
  // bubble.  We should extend gfx::ElideUrl to take some sort of pango font.
  url_text_ = WideToUTF8(gfx::ElideUrl(url, gfx::Font(), window_width / 3,
                                       languages));
  SetStatusTextTo(url_text_);
}

void StatusBubbleGtk::Show() {
  // If we were going to hide, stop.
  timer_factory_.RevokeAll();

  gtk_widget_show_all(container_.get());

  if (container_->window)
    gdk_window_raise(container_->window);
}

void StatusBubbleGtk::Hide() {
  gtk_widget_hide_all(container_.get());
}

void StatusBubbleGtk::SetStatusTextTo(const std::string& status_utf8) {
  if (status_utf8.empty()) {
    HideInASecond();
  } else {
    gtk_label_set_text(GTK_LABEL(label_), status_utf8.c_str());
    Show();
  }
}

void StatusBubbleGtk::HideInASecond() {
  if (!timer_factory_.empty())
    timer_factory_.RevokeAll();

  MessageLoop::current()->PostDelayedTask(FROM_HERE,
      timer_factory_.NewRunnableMethod(&StatusBubbleGtk::Hide),
      kHideDelay);
}

void StatusBubbleGtk::MouseMoved() {
  // We can't do that fancy sliding behaviour where the status bubble slides
  // out of the window because the window manager gets in the way. So totally
  // ignore this message for now.
  //
  // TODO(erg): At least get some sliding behaviour so that it slides out of
  // the way to hide the status bubble on mouseover.
}

void StatusBubbleGtk::Observe(NotificationType type,
                              const NotificationSource& source,
                              const NotificationDetails& details) {
  if (type == NotificationType::BROWSER_THEME_CHANGED) {
    UserChangedTheme();
  }
}

void StatusBubbleGtk::InitWidgets() {
  label_ = gtk_label_new(NULL);

  GtkWidget* padding = gtk_alignment_new(0, 0, 1, 1);
  gtk_alignment_set_padding(GTK_ALIGNMENT(padding),
      kInternalTopBottomPadding, kInternalTopBottomPadding,
      kInternalLeftRightPadding,
      kInternalLeftRightPadding + kCornerSize);
  gtk_container_add(GTK_CONTAINER(padding), label_);

  container_.Own(gtk_event_box_new());
  gtk_widget_set_name(container_.get(), "status-bubble");
  gtk_container_add(GTK_CONTAINER(container_.get()), padding);
  gtk_widget_set_app_paintable(container_.get(), TRUE);
  g_signal_connect(G_OBJECT(container_.get()), "expose-event",
                   G_CALLBACK(OnExpose), this);

  UserChangedTheme();
}

void StatusBubbleGtk::UserChangedTheme() {
  if (theme_provider_->UseGtkTheme()) {
    gtk_widget_modify_fg(label_, GTK_STATE_NORMAL, NULL);
    gtk_widget_modify_bg(container_.get(), GTK_STATE_NORMAL, NULL);

    border_color_ = theme_provider_->GetBorderColor();
  } else {
    // TODO(erg): This is the closest to "text that will look good on a
    // toolbar" that I can find. Maybe in later iterations of the theme system,
    // there will be a better color to pick.
    GdkColor bookmark_text =
        theme_provider_->GetGdkColor(BrowserThemeProvider::COLOR_BOOKMARK_TEXT);
    gtk_widget_modify_fg(label_, GTK_STATE_NORMAL, &bookmark_text);

    GdkColor toolbar_color =
        theme_provider_->GetGdkColor(BrowserThemeProvider::COLOR_TOOLBAR);
    gtk_widget_modify_bg(container_.get(), GTK_STATE_NORMAL, &toolbar_color);

    border_color_ = kFrameBorderColor;
  }
}

// static
gboolean StatusBubbleGtk::OnExpose(GtkWidget* widget,
                                   GdkEventExpose* event,
                                   StatusBubbleGtk* bubble) {
  if (bubble->bubble_width_ != widget->allocation.width ||
      bubble->bubble_height_ != widget->allocation.height) {
    // We need to update the shape of the status bubble whenever our GDK
    // window changes shape.
    std::vector<GdkPoint> mask_points = MakeFramePolygonPoints(
        widget->allocation.width, widget->allocation.height, FRAME_MASK);
    GdkRegion* mask_region = gdk_region_polygon(&mask_points[0],
                                                mask_points.size(),
                                                GDK_EVEN_ODD_RULE);
    gdk_window_shape_combine_region(widget->window, mask_region, 0, 0);
    gdk_region_destroy(mask_region);

    bubble->bubble_width_ = widget->allocation.width;
    bubble->bubble_height_ = widget->allocation.height;
  }

  GdkDrawable* drawable = GDK_DRAWABLE(event->window);
  GdkGC* gc = gdk_gc_new(drawable);
  gdk_gc_set_rgb_fg_color(gc, &bubble->border_color_);

  // Stroke the frame border.
  std::vector<GdkPoint> points = MakeFramePolygonPoints(
      widget->allocation.width, widget->allocation.height, FRAME_STROKE);
  gdk_draw_lines(drawable, gc, &points[0], points.size());

  g_object_unref(gc);
  return FALSE;  // Propagate so our children paint, etc.
}
<commit_msg>Reduce the status bubble rounding by a pixel.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/gtk/status_bubble_gtk.h"

#include <gtk/gtk.h>

#include "app/gfx/text_elider.h"
#include "app/l10n_util.h"
#include "base/gfx/gtk_util.h"
#include "base/message_loop.h"
#include "base/string_util.h"
#include "chrome/browser/gtk/gtk_theme_provider.h"
#include "chrome/browser/gtk/slide_animator_gtk.h"
#include "chrome/common/gtk_util.h"
#include "chrome/common/notification_service.h"
#include "googleurl/src/gurl.h"

namespace {

const GdkColor kFrameBorderColor = GDK_COLOR_RGB(0xbe, 0xc8, 0xd4);

// Inner padding between the border and the text label.
const int kInternalTopBottomPadding = 1;
const int kInternalLeftRightPadding = 2;

// The radius of the edges of our bubble.
const int kCornerSize = 3;

// Milliseconds before we hide the status bubble widget when you mouseout.
const int kHideDelay = 250;

enum FrameType {
  FRAME_MASK,
  FRAME_STROKE,
};

// Returns a list of points that either form the outline of the status bubble
// (|type| == FRAME_MASK) or form the inner border around the inner edge
// (|type| == FRAME_STROKE).
std::vector<GdkPoint> MakeFramePolygonPoints(int width,
                                             int height,
                                             FrameType type) {
  using gtk_util::MakeBidiGdkPoint;
  std::vector<GdkPoint> points;

  bool ltr = l10n_util::GetTextDirection() == l10n_util::LEFT_TO_RIGHT;
  // If we have a stroke, we have to offset some of our points by 1 pixel.
  // We have to inset by 1 pixel when we draw horizontal lines that are on the
  // bottom or when we draw vertical lines that are closer to the end (end is
  // right for ltr).
  int y_off = (type == FRAME_MASK) ? 0 : -1;
  // We use this one for LTR.
  int x_off_l = ltr ? y_off : 0;

  // Top left corner.
  points.push_back(MakeBidiGdkPoint(0, 0, width, ltr));

  // Top right (rounded) corner.
  points.push_back(MakeBidiGdkPoint(
      width - kCornerSize + 1 + x_off_l, 0, width, ltr));
  points.push_back(MakeBidiGdkPoint(
      width + x_off_l, kCornerSize - 1, width, ltr));

  // Bottom right corner.
  points.push_back(MakeBidiGdkPoint(
      width + x_off_l, height + y_off, width, ltr));

  if (type == FRAME_MASK) {
    // Bottom left corner.
    points.push_back(MakeBidiGdkPoint(0, height + y_off, width, ltr));
  }

  return points;
}

}  // namespace

StatusBubbleGtk::StatusBubbleGtk(Profile* profile)
    : theme_provider_(GtkThemeProvider::GetFrom(profile)),
      bubble_width_(-1),
      bubble_height_(-1),
      timer_factory_(this) {
  InitWidgets();

  registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED,
                 NotificationService::AllSources());
}

StatusBubbleGtk::~StatusBubbleGtk() {
  container_.Destroy();
}

void StatusBubbleGtk::SetStatus(const std::wstring& status_text_wide) {
  std::string status_text = WideToUTF8(status_text_wide);
  if (status_text_ == status_text)
    return;

  status_text_ = status_text;
  if (!status_text_.empty()) {
    SetStatusTextTo(status_text_);
  } else if (!url_text_.empty()) {
    SetStatusTextTo(url_text_);
  } else {
    SetStatusTextTo(std::string());
  }
}

void StatusBubbleGtk::SetURL(const GURL& url, const std::wstring& languages) {
  // If we want to clear a displayed URL but there is a status still to
  // display, display that status instead.
  if (url.is_empty() && !status_text_.empty()) {
    url_text_ = std::string();
    SetStatusTextTo(status_text_);
    return;
  }

  // Set Elided Text corresponding to the GURL object.  We limit the width of
  // the URL to a third of the width of the browser window (matching the width
  // on Windows).
  GtkWidget* parent = gtk_widget_get_parent(container_.get());
  int window_width = parent->allocation.width;
  // TODO(tc): We don't actually use gfx::Font as the font in the status
  // bubble.  We should extend gfx::ElideUrl to take some sort of pango font.
  url_text_ = WideToUTF8(gfx::ElideUrl(url, gfx::Font(), window_width / 3,
                                       languages));
  SetStatusTextTo(url_text_);
}

void StatusBubbleGtk::Show() {
  // If we were going to hide, stop.
  timer_factory_.RevokeAll();

  gtk_widget_show_all(container_.get());

  if (container_->window)
    gdk_window_raise(container_->window);
}

void StatusBubbleGtk::Hide() {
  gtk_widget_hide_all(container_.get());
}

void StatusBubbleGtk::SetStatusTextTo(const std::string& status_utf8) {
  if (status_utf8.empty()) {
    HideInASecond();
  } else {
    gtk_label_set_text(GTK_LABEL(label_), status_utf8.c_str());
    Show();
  }
}

void StatusBubbleGtk::HideInASecond() {
  if (!timer_factory_.empty())
    timer_factory_.RevokeAll();

  MessageLoop::current()->PostDelayedTask(FROM_HERE,
      timer_factory_.NewRunnableMethod(&StatusBubbleGtk::Hide),
      kHideDelay);
}

void StatusBubbleGtk::MouseMoved() {
  // We can't do that fancy sliding behaviour where the status bubble slides
  // out of the window because the window manager gets in the way. So totally
  // ignore this message for now.
  //
  // TODO(erg): At least get some sliding behaviour so that it slides out of
  // the way to hide the status bubble on mouseover.
}

void StatusBubbleGtk::Observe(NotificationType type,
                              const NotificationSource& source,
                              const NotificationDetails& details) {
  if (type == NotificationType::BROWSER_THEME_CHANGED) {
    UserChangedTheme();
  }
}

void StatusBubbleGtk::InitWidgets() {
  label_ = gtk_label_new(NULL);

  GtkWidget* padding = gtk_alignment_new(0, 0, 1, 1);
  gtk_alignment_set_padding(GTK_ALIGNMENT(padding),
      kInternalTopBottomPadding, kInternalTopBottomPadding,
      kInternalLeftRightPadding,
      kInternalLeftRightPadding + kCornerSize);
  gtk_container_add(GTK_CONTAINER(padding), label_);

  container_.Own(gtk_event_box_new());
  gtk_widget_set_name(container_.get(), "status-bubble");
  gtk_container_add(GTK_CONTAINER(container_.get()), padding);
  gtk_widget_set_app_paintable(container_.get(), TRUE);
  g_signal_connect(G_OBJECT(container_.get()), "expose-event",
                   G_CALLBACK(OnExpose), this);

  UserChangedTheme();
}

void StatusBubbleGtk::UserChangedTheme() {
  if (theme_provider_->UseGtkTheme()) {
    gtk_widget_modify_fg(label_, GTK_STATE_NORMAL, NULL);
    gtk_widget_modify_bg(container_.get(), GTK_STATE_NORMAL, NULL);

    border_color_ = theme_provider_->GetBorderColor();
  } else {
    // TODO(erg): This is the closest to "text that will look good on a
    // toolbar" that I can find. Maybe in later iterations of the theme system,
    // there will be a better color to pick.
    GdkColor bookmark_text =
        theme_provider_->GetGdkColor(BrowserThemeProvider::COLOR_BOOKMARK_TEXT);
    gtk_widget_modify_fg(label_, GTK_STATE_NORMAL, &bookmark_text);

    GdkColor toolbar_color =
        theme_provider_->GetGdkColor(BrowserThemeProvider::COLOR_TOOLBAR);
    gtk_widget_modify_bg(container_.get(), GTK_STATE_NORMAL, &toolbar_color);

    border_color_ = kFrameBorderColor;
  }
}

// static
gboolean StatusBubbleGtk::OnExpose(GtkWidget* widget,
                                   GdkEventExpose* event,
                                   StatusBubbleGtk* bubble) {
  if (bubble->bubble_width_ != widget->allocation.width ||
      bubble->bubble_height_ != widget->allocation.height) {
    // We need to update the shape of the status bubble whenever our GDK
    // window changes shape.
    std::vector<GdkPoint> mask_points = MakeFramePolygonPoints(
        widget->allocation.width, widget->allocation.height, FRAME_MASK);
    GdkRegion* mask_region = gdk_region_polygon(&mask_points[0],
                                                mask_points.size(),
                                                GDK_EVEN_ODD_RULE);
    gdk_window_shape_combine_region(widget->window, mask_region, 0, 0);
    gdk_region_destroy(mask_region);

    bubble->bubble_width_ = widget->allocation.width;
    bubble->bubble_height_ = widget->allocation.height;
  }

  GdkDrawable* drawable = GDK_DRAWABLE(event->window);
  GdkGC* gc = gdk_gc_new(drawable);
  gdk_gc_set_rgb_fg_color(gc, &bubble->border_color_);

  // Stroke the frame border.
  std::vector<GdkPoint> points = MakeFramePolygonPoints(
      widget->allocation.width, widget->allocation.height, FRAME_STROKE);
  gdk_draw_lines(drawable, gc, &points[0], points.size());

  g_object_unref(gc);
  return FALSE;  // Propagate so our children paint, etc.
}
<|endoftext|>


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

#include "chrome/browser/net/dns_probe_service.h"

#include "base/metrics/histogram.h"
#include "chrome/browser/net/dns_probe_job.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_util.h"
#include "net/base/network_change_notifier.h"
#include "net/dns/dns_client.h"
#include "net/dns/dns_config_service.h"
#include "net/dns/dns_protocol.h"

using net::DnsClient;
using net::DnsConfig;
using net::IPAddressNumber;
using net::IPEndPoint;
using net::ParseIPLiteralToNumber;
using net::NetworkChangeNotifier;

namespace chrome_browser_net {

namespace {

const char kPublicDnsPrimary[]   = "8.8.8.8";
const char kPublicDnsSecondary[] = "8.8.4.4";

IPEndPoint MakeDnsEndPoint(const std::string& dns_ip_literal) {
  IPAddressNumber dns_ip_number;
  bool rv = ParseIPLiteralToNumber(dns_ip_literal, &dns_ip_number);
  DCHECK(rv);
  return IPEndPoint(dns_ip_number, net::dns_protocol::kDefaultPort);
}

const int kMaxResultAgeMs = 5000;

}  // namespace

DnsProbeService::DnsProbeService()
    : system_result_(DnsProbeJob::SERVERS_UNKNOWN),
      public_result_(DnsProbeJob::SERVERS_UNKNOWN),
      state_(STATE_NO_RESULTS),
      result_(PROBE_UNKNOWN) {
}

DnsProbeService::~DnsProbeService() {
}

void DnsProbeService::ProbeDns(const DnsProbeService::CallbackType& callback) {
  callbacks_.push_back(callback);

  if (state_ == STATE_RESULTS_CACHED && ResultsExpired())
    ExpireResults();

  switch (state_) {
  case STATE_NO_RESULTS:
    StartProbes();
    break;
  case STATE_RESULTS_CACHED:
    CallCallbacks();
    break;
  case STATE_PROBE_RUNNING:
    // do nothing; probe is already running, and will call the callback
    break;
  }
}

scoped_ptr<DnsProbeJob> DnsProbeService::CreateSystemProbeJob(
    const DnsProbeJob::CallbackType& job_callback) {
  DnsConfig system_config;
  GetSystemDnsConfig(&system_config);
  return CreateProbeJob(system_config, job_callback);
}

scoped_ptr<DnsProbeJob> DnsProbeService::CreatePublicProbeJob(
    const DnsProbeJob::CallbackType& job_callback) {
  DnsConfig public_config;
  GetPublicDnsConfig(&public_config);
  return CreateProbeJob(public_config, job_callback);
}

void DnsProbeService::ExpireResults() {
  DCHECK_EQ(STATE_RESULTS_CACHED, state_);

  state_ = STATE_NO_RESULTS;
  result_ = PROBE_UNKNOWN;
}

void DnsProbeService::StartProbes() {
  DCHECK_NE(STATE_PROBE_RUNNING, state_);
  DCHECK(!system_job_.get());
  DCHECK(!public_job_.get());

  DnsProbeJob::CallbackType job_callback =
      base::Bind(&DnsProbeService::OnProbeJobComplete,
                 base::Unretained(this));

  // TODO(ttuttle): Do we want to keep explicit flags for "job done"?
  //                Or maybe DnsProbeJob should have a "finished" flag?
  system_result_ = DnsProbeJob::SERVERS_UNKNOWN;
  public_result_ = DnsProbeJob::SERVERS_UNKNOWN;

  system_job_ = CreateSystemProbeJob(job_callback);
  public_job_ = CreatePublicProbeJob(job_callback);

  // If we can't create one or both jobs, fail the probe immediately.
  if (!system_job_.get() || !public_job_.get()) {
    system_job_.reset();
    public_job_.reset();
    state_ = STATE_RESULTS_CACHED;
    result_ = PROBE_UNKNOWN;
    CallCallbacks();
    return;
  }

  state_ = STATE_PROBE_RUNNING;
  probe_start_time_ = base::Time::Now();
}

void DnsProbeService::OnProbesComplete() {
  DCHECK_EQ(STATE_PROBE_RUNNING, state_);

  base::TimeDelta probe_elapsed = base::Time::Now() - probe_start_time_;
  UMA_HISTOGRAM_ENUMERATION("DnsProbe.Probe.Result", result_, MAX_RESULT);
  UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Probe.Elapsed", probe_elapsed);

  state_ = STATE_RESULTS_CACHED;
  result_ = EvaluateResults();

  CallCallbacks();
}

DnsProbeService::Result DnsProbeService::EvaluateResults() {
  DCHECK_NE(DnsProbeJob::SERVERS_UNKNOWN, system_result_);
  DCHECK_NE(DnsProbeJob::SERVERS_UNKNOWN, public_result_);

  // If the system DNS is working, assume the domain doesn't exist.
  if (system_result_ == DnsProbeJob::SERVERS_CORRECT)
    return PROBE_NXDOMAIN;

  // If the system DNS is not working but another public server is, assume the
  // DNS config is bad (or perhaps the DNS servers are down or broken).
  if (public_result_ == DnsProbeJob::SERVERS_CORRECT)
    return PROBE_BAD_CONFIG;

  // If the system DNS is not working and another public server is unreachable,
  // assume the internet connection is down (note that system DNS may be a
  // router on the LAN, so it may be reachable but returning errors.)
  if (public_result_ == DnsProbeJob::SERVERS_UNREACHABLE)
    return PROBE_NO_INTERNET;

  // Otherwise: the system DNS is not working and another public server is
  // responding but with errors or incorrect results.  This is an awkward case;
  // an invasive captive portal or a restrictive firewall may be intercepting
  // or rewriting DNS traffic, or the public server may itself be failing or
  // down.
  return PROBE_UNKNOWN;
}

void DnsProbeService::CallCallbacks() {
  DCHECK_EQ(STATE_RESULTS_CACHED, state_);
  DCHECK(!callbacks_.empty());

  std::vector<CallbackType> callbacks = callbacks_;
  callbacks_.clear();

  for (std::vector<CallbackType>::const_iterator i = callbacks.begin();
       i != callbacks.end(); ++i) {
    i->Run(result_);
  }
}

scoped_ptr<DnsProbeJob> DnsProbeService::CreateProbeJob(
    const DnsConfig& dns_config,
    const DnsProbeJob::CallbackType& job_callback) {
  if (!dns_config.IsValid())
    return scoped_ptr<DnsProbeJob>(NULL);

  scoped_ptr<DnsClient> dns_client(DnsClient::CreateClient(NULL));
  dns_client->SetConfig(dns_config);
  return DnsProbeJob::CreateJob(dns_client.Pass(), job_callback, NULL);
}

void DnsProbeService::OnProbeJobComplete(DnsProbeJob* job,
                                         DnsProbeJob::Result result) {
  DCHECK_EQ(STATE_PROBE_RUNNING, state_);

  if (job == system_job_.get()) {
    system_result_ = result;
    system_job_.reset();
  } else if (job == public_job_.get()) {
    public_result_ = result;
    public_job_.reset();
  } else {
    NOTREACHED();
    return;
  }

  if (system_result_ != DnsProbeJob::SERVERS_UNKNOWN &&
      public_result_ != DnsProbeJob::SERVERS_UNKNOWN) {
    OnProbesComplete();
  }
}

void DnsProbeService::GetSystemDnsConfig(DnsConfig* config) {
  NetworkChangeNotifier::GetDnsConfig(config);
}

void DnsProbeService::GetPublicDnsConfig(DnsConfig* config) {
  *config = DnsConfig();
  config->nameservers.push_back(MakeDnsEndPoint(kPublicDnsPrimary));
  config->nameservers.push_back(MakeDnsEndPoint(kPublicDnsSecondary));
}

bool DnsProbeService::ResultsExpired() {
  const base::TimeDelta kMaxResultAge =
      base::TimeDelta::FromMilliseconds(kMaxResultAgeMs);
  return base::Time::Now() - probe_start_time_ > kMaxResultAge;
}

} // namespace chrome_browser_net
<commit_msg>Fix crash in dns_probe_service.cc on Android.<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 "chrome/browser/net/dns_probe_service.h"

#include "base/metrics/histogram.h"
#include "chrome/browser/net/dns_probe_job.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_util.h"
#include "net/base/network_change_notifier.h"
#include "net/dns/dns_client.h"
#include "net/dns/dns_config_service.h"
#include "net/dns/dns_protocol.h"

using net::DnsClient;
using net::DnsConfig;
using net::IPAddressNumber;
using net::IPEndPoint;
using net::ParseIPLiteralToNumber;
using net::NetworkChangeNotifier;

namespace chrome_browser_net {

namespace {

const char kPublicDnsPrimary[]   = "8.8.8.8";
const char kPublicDnsSecondary[] = "8.8.4.4";

IPEndPoint MakeDnsEndPoint(const std::string& dns_ip_literal) {
  IPAddressNumber dns_ip_number;
  bool rv = ParseIPLiteralToNumber(dns_ip_literal, &dns_ip_number);
  DCHECK(rv);
  return IPEndPoint(dns_ip_number, net::dns_protocol::kDefaultPort);
}

const int kMaxResultAgeMs = 5000;

}  // namespace

DnsProbeService::DnsProbeService()
    : system_result_(DnsProbeJob::SERVERS_UNKNOWN),
      public_result_(DnsProbeJob::SERVERS_UNKNOWN),
      state_(STATE_NO_RESULTS),
      result_(PROBE_UNKNOWN) {
}

DnsProbeService::~DnsProbeService() {
}

void DnsProbeService::ProbeDns(const DnsProbeService::CallbackType& callback) {
  callbacks_.push_back(callback);

  if (state_ == STATE_RESULTS_CACHED && ResultsExpired())
    ExpireResults();

  switch (state_) {
  case STATE_NO_RESULTS:
    StartProbes();
    break;
  case STATE_RESULTS_CACHED:
    CallCallbacks();
    break;
  case STATE_PROBE_RUNNING:
    // do nothing; probe is already running, and will call the callback
    break;
  }
}

scoped_ptr<DnsProbeJob> DnsProbeService::CreateSystemProbeJob(
    const DnsProbeJob::CallbackType& job_callback) {
  DnsConfig system_config;
  GetSystemDnsConfig(&system_config);
  return CreateProbeJob(system_config, job_callback);
}

scoped_ptr<DnsProbeJob> DnsProbeService::CreatePublicProbeJob(
    const DnsProbeJob::CallbackType& job_callback) {
  DnsConfig public_config;
  GetPublicDnsConfig(&public_config);
  return CreateProbeJob(public_config, job_callback);
}

void DnsProbeService::ExpireResults() {
  DCHECK_EQ(STATE_RESULTS_CACHED, state_);

  state_ = STATE_NO_RESULTS;
  result_ = PROBE_UNKNOWN;
}

void DnsProbeService::StartProbes() {
  DCHECK_NE(STATE_PROBE_RUNNING, state_);
  DCHECK(!system_job_.get());
  DCHECK(!public_job_.get());

  DnsProbeJob::CallbackType job_callback =
      base::Bind(&DnsProbeService::OnProbeJobComplete,
                 base::Unretained(this));

  // TODO(ttuttle): Do we want to keep explicit flags for "job done"?
  //                Or maybe DnsProbeJob should have a "finished" flag?
  system_result_ = DnsProbeJob::SERVERS_UNKNOWN;
  public_result_ = DnsProbeJob::SERVERS_UNKNOWN;

  system_job_ = CreateSystemProbeJob(job_callback);
  if (system_job_.get())
    public_job_ = CreatePublicProbeJob(job_callback);

  // If we can't create one or both jobs, fail the probe immediately.
  if (!system_job_.get() || !public_job_.get()) {
    system_job_.reset();
    public_job_.reset();
    state_ = STATE_RESULTS_CACHED;
    result_ = PROBE_UNKNOWN;
    CallCallbacks();
    return;
  }

  state_ = STATE_PROBE_RUNNING;
  probe_start_time_ = base::Time::Now();
}

void DnsProbeService::OnProbesComplete() {
  DCHECK_EQ(STATE_PROBE_RUNNING, state_);

  base::TimeDelta probe_elapsed = base::Time::Now() - probe_start_time_;
  UMA_HISTOGRAM_ENUMERATION("DnsProbe.Probe.Result", result_, MAX_RESULT);
  UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Probe.Elapsed", probe_elapsed);

  state_ = STATE_RESULTS_CACHED;
  result_ = EvaluateResults();

  CallCallbacks();
}

DnsProbeService::Result DnsProbeService::EvaluateResults() {
  DCHECK_NE(DnsProbeJob::SERVERS_UNKNOWN, system_result_);
  DCHECK_NE(DnsProbeJob::SERVERS_UNKNOWN, public_result_);

  // If the system DNS is working, assume the domain doesn't exist.
  if (system_result_ == DnsProbeJob::SERVERS_CORRECT)
    return PROBE_NXDOMAIN;

  // If the system DNS is not working but another public server is, assume the
  // DNS config is bad (or perhaps the DNS servers are down or broken).
  if (public_result_ == DnsProbeJob::SERVERS_CORRECT)
    return PROBE_BAD_CONFIG;

  // If the system DNS is not working and another public server is unreachable,
  // assume the internet connection is down (note that system DNS may be a
  // router on the LAN, so it may be reachable but returning errors.)
  if (public_result_ == DnsProbeJob::SERVERS_UNREACHABLE)
    return PROBE_NO_INTERNET;

  // Otherwise: the system DNS is not working and another public server is
  // responding but with errors or incorrect results.  This is an awkward case;
  // an invasive captive portal or a restrictive firewall may be intercepting
  // or rewriting DNS traffic, or the public server may itself be failing or
  // down.
  return PROBE_UNKNOWN;
}

void DnsProbeService::CallCallbacks() {
  DCHECK_EQ(STATE_RESULTS_CACHED, state_);
  DCHECK(!callbacks_.empty());

  std::vector<CallbackType> callbacks = callbacks_;
  callbacks_.clear();

  for (std::vector<CallbackType>::const_iterator i = callbacks.begin();
       i != callbacks.end(); ++i) {
    i->Run(result_);
  }
}

scoped_ptr<DnsProbeJob> DnsProbeService::CreateProbeJob(
    const DnsConfig& dns_config,
    const DnsProbeJob::CallbackType& job_callback) {
  if (!dns_config.IsValid())
    return scoped_ptr<DnsProbeJob>(NULL);

  scoped_ptr<DnsClient> dns_client(DnsClient::CreateClient(NULL));
  dns_client->SetConfig(dns_config);
  return DnsProbeJob::CreateJob(dns_client.Pass(), job_callback, NULL);
}

void DnsProbeService::OnProbeJobComplete(DnsProbeJob* job,
                                         DnsProbeJob::Result result) {
  DCHECK_EQ(STATE_PROBE_RUNNING, state_);

  if (job == system_job_.get()) {
    system_result_ = result;
    system_job_.reset();
  } else if (job == public_job_.get()) {
    public_result_ = result;
    public_job_.reset();
  } else {
    NOTREACHED();
    return;
  }

  if (system_result_ != DnsProbeJob::SERVERS_UNKNOWN &&
      public_result_ != DnsProbeJob::SERVERS_UNKNOWN) {
    OnProbesComplete();
  }
}

void DnsProbeService::GetSystemDnsConfig(DnsConfig* config) {
  NetworkChangeNotifier::GetDnsConfig(config);
}

void DnsProbeService::GetPublicDnsConfig(DnsConfig* config) {
  *config = DnsConfig();
  config->nameservers.push_back(MakeDnsEndPoint(kPublicDnsPrimary));
  config->nameservers.push_back(MakeDnsEndPoint(kPublicDnsSecondary));
}

bool DnsProbeService::ResultsExpired() {
  const base::TimeDelta kMaxResultAge =
      base::TimeDelta::FromMilliseconds(kMaxResultAgeMs);
  return base::Time::Now() - probe_start_time_ > kMaxResultAge;
}

} // namespace chrome_browser_net
<|endoftext|>


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

#include "chrome/common/notification_registrar.h"

#include <algorithm>

#include "base/logging.h"
#include "chrome/common/notification_service.h"

struct NotificationRegistrar::Record {
  bool operator==(const Record& other) const;

  NotificationObserver* observer;
  NotificationType type;
  NotificationSource source;
};

bool NotificationRegistrar::Record::operator==(const Record& other) const {
  return observer == other.observer &&
         type == other.type &&
         source == other.source;
}

NotificationRegistrar::NotificationRegistrar() {
}

NotificationRegistrar::~NotificationRegistrar() {
  RemoveAll();
}

void NotificationRegistrar::Add(NotificationObserver* observer,
                                NotificationType type,
                                const NotificationSource& source) {
  Record record = { observer, type, source };
  DCHECK(std::find(registered_.begin(), registered_.end(), record) ==
         registered_.end()) << "Duplicate registration.";
  registered_.push_back(record);

  NotificationService::current()->AddObserver(observer, type, source);
}

void NotificationRegistrar::Remove(NotificationObserver* observer,
                                   NotificationType type,
                                   const NotificationSource& source) {
  Record record = { observer, type, source };
  RecordVector::iterator found = std::find(
      registered_.begin(), registered_.end(), record);
  if (found != registered_.end()) {
    registered_.erase(found);
  } else {
    // Fall through to passing the removal through to the notification service.
    // If it really isn't registered, it will also assert and do nothing, but
    // we might as well catch the case where the class is trying to unregister
    // for something they registered without going through us.
    NOTREACHED();
  }

  // This can be NULL if our owner outlives the NotificationService, e.g. if our
  // owner is a Singleton.
  NotificationService* service = NotificationService::current();
  if (service)
    service->RemoveObserver(observer, type, source);
}

void NotificationRegistrar::RemoveAll() {
  // This can be NULL if our owner outlives the NotificationService, e.g. if our
  // owner is a Singleton.
  NotificationService* service = NotificationService::current();
  if (service) {
    for (size_t i = 0; i < registered_.size(); i++) {
      service->RemoveObserver(registered_[i].observer,
                              registered_[i].type,
                              registered_[i].source);
    }
  }
  registered_.clear();
}

bool NotificationRegistrar::IsEmpty() const {
  return registered_.empty();
}
<commit_msg>Avoid calling NotificationService::current() unless we have to, to prevent problems during shutdown in atypical cases.We can now be more stringent with the Remove() check that was already in place, since now users _must_ go through NotificationRegistrar to register an observer.<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/common/notification_registrar.h"

#include <algorithm>

#include "base/logging.h"
#include "chrome/common/notification_service.h"

struct NotificationRegistrar::Record {
  bool operator==(const Record& other) const;

  NotificationObserver* observer;
  NotificationType type;
  NotificationSource source;
};

bool NotificationRegistrar::Record::operator==(const Record& other) const {
  return observer == other.observer &&
         type == other.type &&
         source == other.source;
}

NotificationRegistrar::NotificationRegistrar() {
}

NotificationRegistrar::~NotificationRegistrar() {
  RemoveAll();
}

void NotificationRegistrar::Add(NotificationObserver* observer,
                                NotificationType type,
                                const NotificationSource& source) {
  Record record = { observer, type, source };
  DCHECK(std::find(registered_.begin(), registered_.end(), record) ==
         registered_.end()) << "Duplicate registration.";
  registered_.push_back(record);

  NotificationService::current()->AddObserver(observer, type, source);
}

void NotificationRegistrar::Remove(NotificationObserver* observer,
                                   NotificationType type,
                                   const NotificationSource& source) {
  Record record = { observer, type, source };
  RecordVector::iterator found = std::find(
      registered_.begin(), registered_.end(), record);
  if (found == registered_.end()) {
    NOTREACHED();
    return;
  }
  registered_.erase(found);

  // This can be NULL if our owner outlives the NotificationService, e.g. if our
  // owner is a Singleton.
  NotificationService* service = NotificationService::current();
  if (service)
    service->RemoveObserver(observer, type, source);
}

void NotificationRegistrar::RemoveAll() {
  // Early-exit if no registrations, to avoid calling
  // NotificationService::current.  If we've constructed an object with a
  // NotificationRegistrar member, but haven't actually used the notification
  // service, and we reach prgram exit, then calling current() below could try
  // to initialize the service's lazy TLS pointer during exit, which throws
  // wrenches at things.
  if (registered_.empty())
    return;

  // This can be NULL if our owner outlives the NotificationService, e.g. if our
  // owner is a Singleton.
  NotificationService* service = NotificationService::current();
  if (service) {
    for (size_t i = 0; i < registered_.size(); i++) {
      service->RemoveObserver(registered_[i].observer,
                              registered_[i].type,
                              registered_[i].source);
    }
  }
  registered_.clear();
}

bool NotificationRegistrar::IsEmpty() const {
  return registered_.empty();
}
<|endoftext|>


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

#include "temp_scaffolding_stubs.h"

#include "build/build_config.h"

#include <vector>

#include "base/file_util.h"
#include "base/logging.h"
#include "base/thread.h"
#include "base/path_service.h"
#include "base/string_piece.h"
#include "base/singleton.h"
#include "base/task.h"
#include "chrome/browser/autocomplete/history_url_provider.h"
#include "chrome/browser/automation/automation_provider.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_shutdown.h"
#include "chrome/browser/cache_manager_host.h"
#include "chrome/browser/debugger/debugger_shell.h"
#include "chrome/browser/dom_ui/dom_ui.h"
#include "chrome/browser/download/download_request_dialog_delegate.h"
#include "chrome/browser/download/download_request_manager.h"
#include "chrome/browser/first_run.h"
#include "chrome/browser/history/in_memory_history_backend.h"
#include "chrome/browser/memory_details.h"
#include "chrome/browser/profile_manager.h"
#include "chrome/browser/renderer_host/render_widget_helper.h"
#include "chrome/browser/renderer_host/resource_message_filter.h"
#include "chrome/browser/rlz/rlz.h"
#include "chrome/browser/search_engines/template_url_prepopulate_data.h"
#include "chrome/browser/shell_integration.h"
#include "chrome/browser/tab_contents/web_contents.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_plugin_util.h"
#include "chrome/common/gfx/chrome_font.h"
#include "chrome/common/gfx/text_elider.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_service.h"
#include "chrome/common/process_watcher.h"
#include "net/url_request/url_request_context.h"
#include "webkit/glue/webcursor.h"
#include "webkit/glue/webkit_glue.h"

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

WebContents* AutomationProvider::GetWebContentsForHandle(
    int handle, NavigationController** tab) {
  NOTIMPLEMENTED();
  return NULL;
}

void AutomationProvider::GetActiveWindow(int* handle) { NOTIMPLEMENTED(); }

void AutomationProvider::IsWindowActive(int handle, bool* success,
                                        bool* is_active) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::ActivateWindow(int handle) { NOTIMPLEMENTED(); }

void AutomationProvider::SetWindowVisible(int handle, bool visible,
                                          bool* result) { NOTIMPLEMENTED(); }

void AutomationProvider::GetFocusedViewID(int handle, int* view_id) {
  NOTIMPLEMENTED();
}

void AutomationProvider::OpenNewBrowserWindow(int show_command) {
  NOTIMPLEMENTED();
}

void AutomationProvider::GetWindowForBrowser(int browser_handle,
                                             bool* success,
                                             int* handle) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::GetAutocompleteEditForBrowser(
    int browser_handle,
    bool* success,
    int* autocomplete_edit_handle) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::GetBrowserForWindow(int window_handle,
                                             bool* success,
                                             int* browser_handle) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::GetSecurityState(int handle, bool* success,
                                          SecurityStyle* security_style,
                                          int* ssl_cert_status,
                                          int* mixed_content_status) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::GetPageType(int handle, bool* success,
                                     NavigationEntry::PageType* page_type) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::ActionOnSSLBlockingPage(int handle, bool proceed,
                                                 IPC::Message* reply_message) {
  NOTIMPLEMENTED();
}

void AutomationProvider::PrintNow(int tab_handle,
                                  IPC::Message* reply_message) {
  NOTIMPLEMENTED();
}

void AutomationProvider::SavePage(int tab_handle,
                                  const std::wstring& file_name,
                                  const std::wstring& dir_path,
                                  int type,
                                  bool* success) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::GetAutocompleteEditText(int autocomplete_edit_handle,
                                                 bool* success,
                                                 std::wstring* text) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::SetAutocompleteEditText(int autocomplete_edit_handle,
                                                 const std::wstring& text,
                                                 bool* success) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::AutocompleteEditGetMatches(
    int autocomplete_edit_handle,
    bool* success,
    std::vector<AutocompleteMatchData>* matches) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::AutocompleteEditIsQueryInProgress(
    int autocomplete_edit_handle,
    bool* success,
    bool* query_in_progress) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::OnMessageFromExternalHost(
    int handle, const std::string& target, const std::string& message) {
  NOTIMPLEMENTED();
}

void AutomationProvider::GetShowingAppModalDialog(bool* showing_dialog,
                                                  int* dialog_button) {
  NOTIMPLEMENTED();
}

void AutomationProvider::ClickAppModalDialogButton(int button, bool* success) {
  *success = false;
  NOTIMPLEMENTED();
}

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

bool ShellIntegration::SetAsDefaultBrowser() {
  NOTIMPLEMENTED();
  return true;
}

bool ShellIntegration::IsDefaultBrowser() {
  NOTIMPLEMENTED();
  return true;
}

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

// static
bool FirstRun::IsChromeFirstRun() {
  NOTIMPLEMENTED();
  return false;
}

// static
bool FirstRun::ProcessMasterPreferences(const FilePath& user_data_dir,
                                        const FilePath& master_prefs_path,
                                        int* preference_details) {
  NOTIMPLEMENTED();
  return false;
}

// static
int FirstRun::ImportNow(Profile* profile, const CommandLine& cmdline) {
  NOTIMPLEMENTED();
  return 0;
}

// static
bool Upgrade::IsBrowserAlreadyRunning() {
  NOTIMPLEMENTED();
  return false;
}

// static
bool Upgrade::RelaunchChromeBrowser(const CommandLine& command_line) {
  NOTIMPLEMENTED();
  return true;
}

// static
bool Upgrade::SwapNewChromeExeIfPresent() {
  NOTIMPLEMENTED();
  return true;
}

void OpenFirstRunDialog(Profile* profile) { NOTIMPLEMENTED(); }

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

void InstallJankometer(const CommandLine&) {
  // http://code.google.com/p/chromium/issues/detail?id=8077
}

void UninstallJankometer() {
  // http://code.google.com/p/chromium/issues/detail?id=8077
}

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

void TabContents::SetupController(Profile* profile) {
  DCHECK(!controller_);
  controller_ = new NavigationController(this, profile);
}

Profile* TabContents::profile() const {
  return controller_ ? controller_->profile() : NULL;
}

void TabContents::CloseContents() {
  // Destroy our NavigationController, which will Destroy all tabs it owns.
  controller_->Destroy();
  // Note that the controller may have deleted us at this point,
  // so don't touch any member variables here.
}

void TabContents::Destroy() {
  // TODO(pinkerton): this isn't the real version of Destroy(), just enough to
  // get the scaffolding working.

  is_being_destroyed_ = true;

  // Notify any observer that have a reference on this tab contents.
  NotificationService::current()->Notify(
      NotificationType::TAB_CONTENTS_DESTROYED,
      Source<TabContents>(this),
      NotificationService::NoDetails());

  // Notify our NavigationController.  Make sure we are deleted first, so
  // that the controller is the last to die.
  NavigationController* controller = controller_;
  TabContentsType type = this->type();

  delete this;

  controller->TabContentsWasDestroyed(type);
}

const GURL& TabContents::GetURL() const {
  // We may not have a navigation entry yet
  NavigationEntry* entry = controller_->GetActiveEntry();
  return entry ? entry->display_url() : GURL::EmptyGURL();
}

const std::wstring& TabContents::GetTitle() const {
  // We use the title for the last committed entry rather than a pending
  // navigation entry. For example, when the user types in a URL, we want to
  // keep the old page's title until the new load has committed and we get a new
  // title.
  // The exception is with transient pages, for which we really want to use
  // their title, as they are not committed.
  NavigationEntry* entry = controller_->GetTransientEntry();
  if (entry)
    return entry->GetTitleForDisplay();

  entry = controller_->GetLastCommittedEntry();
  if (entry)
    return entry->GetTitleForDisplay();
  else if (controller_->LoadingURLLazily())
    return controller_->GetLazyTitle();
  return EmptyWString();
}

void TabContents::NotifyNavigationStateChanged(unsigned changed_flags) {
  if (delegate_)
    delegate_->NavigationStateChanged(this, changed_flags);
}

void TabContents::OpenURL(const GURL& url, const GURL& referrer,
                          WindowOpenDisposition disposition,
                          PageTransition::Type transition) {
  if (delegate_)
    delegate_->OpenURLFromTab(this, url, referrer, disposition, transition);
}

void TabContents::SetIsLoading(bool is_loading,
                               LoadNotificationDetails* details) {
  if (is_loading == is_loading_)
    return;

  is_loading_ = is_loading;
  waiting_for_response_ = is_loading;

  // Suppress notifications for this TabContents if we are not active.
  if (!is_active_)
    return;

  if (delegate_)
    delegate_->LoadingStateChanged(this);

  NotificationType type = is_loading ? NotificationType::LOAD_START :
      NotificationType::LOAD_STOP;
  NotificationDetails det = NotificationService::NoDetails();;
  if (details)
      det = Details<LoadNotificationDetails>(details);
  NotificationService::current()->Notify(type,
      Source<NavigationController>(this->controller()),
      det);
}

bool TabContents::SupportsURL(GURL* url) {
  GURL u(*url);
  if (TabContents::TypeForURL(&u) == type()) {
    *url = u;
    return true;
  }
  return false;
}

int32 TabContents::GetMaxPageID() {
  if (GetSiteInstance())
    return GetSiteInstance()->max_page_id();
  else
    return max_page_id_;
}

void TabContents::UpdateMaxPageID(int32 page_id) {
  // Ensure both the SiteInstance and RenderProcessHost update their max page
  // IDs in sync. Only WebContents will also have site instances, except during
  // testing.
  if (GetSiteInstance())
    GetSiteInstance()->UpdateMaxPageID(page_id);

  if (AsWebContents())
    AsWebContents()->process()->UpdateMaxPageID(page_id);
  else
    max_page_id_ = std::max(max_page_id_, page_id);
}

void TabContents::SetIsCrashed(bool state) {
  if (state == is_crashed_)
    return;

  is_crashed_ = state;
  if (delegate_)
    delegate_->ContentsStateChanged(this);
}

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

void RLZTracker::CleanupRlz() {
  // http://code.google.com/p/chromium/issues/detail?id=8152
}

bool RLZTracker::GetAccessPointRlz(AccessPoint point, std::wstring* rlz) {
  // http://code.google.com/p/chromium/issues/detail?id=8152
  return false;
}

bool RLZTracker::RecordProductEvent(Product product, AccessPoint point,
                                    Event event) {
  // http://code.google.com/p/chromium/issues/detail?id=8152
  return false;
}

// This depends on porting all the plugin IPC messages.
bool IsPluginProcess() {
  return false;
}

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

void RunJavascriptMessageBox(WebContents* web_contents,
                             int dialog_flags,
                             const std::wstring& message_text,
                             const std::wstring& default_prompt_text,
                             bool display_suppress_checkbox,
                             IPC::Message* reply_msg) {
  NOTIMPLEMENTED();
}

void RunBeforeUnloadDialog(WebContents* web_contents,
                           const std::wstring& message_text,
                           IPC::Message* reply_msg) {
  NOTIMPLEMENTED();
}

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

void RunRepostFormWarningDialog(NavigationController*) {
}

LoginHandler* CreateLoginPrompt(net::AuthChallengeInfo* auth_info,
                                URLRequest* request,
                                MessageLoop* ui_loop) {
  NOTIMPLEMENTED();
  return NULL;
}

void ProcessWatcher::EnsureProcessTerminated(int) {
  NOTIMPLEMENTED();
}

//--------------------------------------------------------------------------
namespace webkit_glue {

bool IsDefaultPluginEnabled() {
  NOTIMPLEMENTED();
  return false;
}

#if defined(OS_MACOSX)
bool ClipboardIsFormatAvailable(Clipboard::FormatType format) {
  NOTIMPLEMENTED();
  return false;
}
#endif

}  // webkit_glue

#ifndef CHROME_DEBUGGER_DISABLED
DebuggerShell::DebuggerShell(DebuggerInputOutput *io) { }
DebuggerShell::~DebuggerShell() { }
void DebuggerShell::Start() { NOTIMPLEMENTED(); }
void DebuggerShell::Debug(TabContents* tab) { NOTIMPLEMENTED(); }
void DebuggerShell::DebugMessage(const std::wstring& msg) { NOTIMPLEMENTED(); }
void DebuggerShell::OnDebugAttach() { NOTIMPLEMENTED(); }
void DebuggerShell::OnDebugDisconnect() { NOTIMPLEMENTED(); }
void DebuggerShell::DidConnect() { NOTIMPLEMENTED(); }
void DebuggerShell::DidDisconnect() { NOTIMPLEMENTED(); }
void DebuggerShell::ProcessCommand(const std::wstring& data) {
  NOTIMPLEMENTED();
}
#endif  // !CHROME_DEBUGGER_DISABLED

MemoryDetails::MemoryDetails() {
  NOTIMPLEMENTED();
}

void MemoryDetails::StartFetch() {
  NOTIMPLEMENTED();
}

InfoBar* ConfirmInfoBarDelegate::CreateInfoBar() {
  NOTIMPLEMENTED();
  return NULL;
}

InfoBar* AlertInfoBarDelegate::CreateInfoBar() {
  NOTIMPLEMENTED();
  return NULL;
}

InfoBar* LinkInfoBarDelegate::CreateInfoBar() {
  NOTIMPLEMENTED();
  return NULL;
}

bool CanImportURL(const GURL& url) {
  NOTIMPLEMENTED();
  return false;
}

DownloadRequestDialogDelegate* DownloadRequestDialogDelegate::Create(
    TabContents* tab,
    DownloadRequestManager::TabDownloadState* host) {
  NOTIMPLEMENTED();
  return NULL;
}

views::Window* CreateInputWindow(gfx::NativeWindow parent_hwnd,
                                 InputWindowDelegate* delegate) {
  NOTIMPLEMENTED();
  return new views::Window();
}

<commit_msg>Fix build error caused due to the AutomationProvider::OnMessageFromExternalHost signature change.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "temp_scaffolding_stubs.h"

#include "build/build_config.h"

#include <vector>

#include "base/file_util.h"
#include "base/logging.h"
#include "base/thread.h"
#include "base/path_service.h"
#include "base/string_piece.h"
#include "base/singleton.h"
#include "base/task.h"
#include "chrome/browser/autocomplete/history_url_provider.h"
#include "chrome/browser/automation/automation_provider.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_shutdown.h"
#include "chrome/browser/cache_manager_host.h"
#include "chrome/browser/debugger/debugger_shell.h"
#include "chrome/browser/dom_ui/dom_ui.h"
#include "chrome/browser/download/download_request_dialog_delegate.h"
#include "chrome/browser/download/download_request_manager.h"
#include "chrome/browser/first_run.h"
#include "chrome/browser/history/in_memory_history_backend.h"
#include "chrome/browser/memory_details.h"
#include "chrome/browser/profile_manager.h"
#include "chrome/browser/renderer_host/render_widget_helper.h"
#include "chrome/browser/renderer_host/resource_message_filter.h"
#include "chrome/browser/rlz/rlz.h"
#include "chrome/browser/search_engines/template_url_prepopulate_data.h"
#include "chrome/browser/shell_integration.h"
#include "chrome/browser/tab_contents/web_contents.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_plugin_util.h"
#include "chrome/common/gfx/chrome_font.h"
#include "chrome/common/gfx/text_elider.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_service.h"
#include "chrome/common/process_watcher.h"
#include "net/url_request/url_request_context.h"
#include "webkit/glue/webcursor.h"
#include "webkit/glue/webkit_glue.h"

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

WebContents* AutomationProvider::GetWebContentsForHandle(
    int handle, NavigationController** tab) {
  NOTIMPLEMENTED();
  return NULL;
}

void AutomationProvider::GetActiveWindow(int* handle) { NOTIMPLEMENTED(); }

void AutomationProvider::IsWindowActive(int handle, bool* success,
                                        bool* is_active) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::ActivateWindow(int handle) { NOTIMPLEMENTED(); }

void AutomationProvider::SetWindowVisible(int handle, bool visible,
                                          bool* result) { NOTIMPLEMENTED(); }

void AutomationProvider::GetFocusedViewID(int handle, int* view_id) {
  NOTIMPLEMENTED();
}

void AutomationProvider::OpenNewBrowserWindow(int show_command) {
  NOTIMPLEMENTED();
}

void AutomationProvider::GetWindowForBrowser(int browser_handle,
                                             bool* success,
                                             int* handle) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::GetAutocompleteEditForBrowser(
    int browser_handle,
    bool* success,
    int* autocomplete_edit_handle) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::GetBrowserForWindow(int window_handle,
                                             bool* success,
                                             int* browser_handle) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::GetSecurityState(int handle, bool* success,
                                          SecurityStyle* security_style,
                                          int* ssl_cert_status,
                                          int* mixed_content_status) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::GetPageType(int handle, bool* success,
                                     NavigationEntry::PageType* page_type) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::ActionOnSSLBlockingPage(int handle, bool proceed,
                                                 IPC::Message* reply_message) {
  NOTIMPLEMENTED();
}

void AutomationProvider::PrintNow(int tab_handle,
                                  IPC::Message* reply_message) {
  NOTIMPLEMENTED();
}

void AutomationProvider::SavePage(int tab_handle,
                                  const std::wstring& file_name,
                                  const std::wstring& dir_path,
                                  int type,
                                  bool* success) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::GetAutocompleteEditText(int autocomplete_edit_handle,
                                                 bool* success,
                                                 std::wstring* text) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::SetAutocompleteEditText(int autocomplete_edit_handle,
                                                 const std::wstring& text,
                                                 bool* success) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::AutocompleteEditGetMatches(
    int autocomplete_edit_handle,
    bool* success,
    std::vector<AutocompleteMatchData>* matches) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::AutocompleteEditIsQueryInProgress(
    int autocomplete_edit_handle,
    bool* success,
    bool* query_in_progress) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::OnMessageFromExternalHost(
    int handle, const std::string& message) {
  NOTIMPLEMENTED();
}

void AutomationProvider::GetShowingAppModalDialog(bool* showing_dialog,
                                                  int* dialog_button) {
  NOTIMPLEMENTED();
}

void AutomationProvider::ClickAppModalDialogButton(int button, bool* success) {
  *success = false;
  NOTIMPLEMENTED();
}

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

bool ShellIntegration::SetAsDefaultBrowser() {
  NOTIMPLEMENTED();
  return true;
}

bool ShellIntegration::IsDefaultBrowser() {
  NOTIMPLEMENTED();
  return true;
}

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

// static
bool FirstRun::IsChromeFirstRun() {
  NOTIMPLEMENTED();
  return false;
}

// static
bool FirstRun::ProcessMasterPreferences(const FilePath& user_data_dir,
                                        const FilePath& master_prefs_path,
                                        int* preference_details) {
  NOTIMPLEMENTED();
  return false;
}

// static
int FirstRun::ImportNow(Profile* profile, const CommandLine& cmdline) {
  NOTIMPLEMENTED();
  return 0;
}

// static
bool Upgrade::IsBrowserAlreadyRunning() {
  NOTIMPLEMENTED();
  return false;
}

// static
bool Upgrade::RelaunchChromeBrowser(const CommandLine& command_line) {
  NOTIMPLEMENTED();
  return true;
}

// static
bool Upgrade::SwapNewChromeExeIfPresent() {
  NOTIMPLEMENTED();
  return true;
}

void OpenFirstRunDialog(Profile* profile) { NOTIMPLEMENTED(); }

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

void InstallJankometer(const CommandLine&) {
  // http://code.google.com/p/chromium/issues/detail?id=8077
}

void UninstallJankometer() {
  // http://code.google.com/p/chromium/issues/detail?id=8077
}

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

void TabContents::SetupController(Profile* profile) {
  DCHECK(!controller_);
  controller_ = new NavigationController(this, profile);
}

Profile* TabContents::profile() const {
  return controller_ ? controller_->profile() : NULL;
}

void TabContents::CloseContents() {
  // Destroy our NavigationController, which will Destroy all tabs it owns.
  controller_->Destroy();
  // Note that the controller may have deleted us at this point,
  // so don't touch any member variables here.
}

void TabContents::Destroy() {
  // TODO(pinkerton): this isn't the real version of Destroy(), just enough to
  // get the scaffolding working.

  is_being_destroyed_ = true;

  // Notify any observer that have a reference on this tab contents.
  NotificationService::current()->Notify(
      NotificationType::TAB_CONTENTS_DESTROYED,
      Source<TabContents>(this),
      NotificationService::NoDetails());

  // Notify our NavigationController.  Make sure we are deleted first, so
  // that the controller is the last to die.
  NavigationController* controller = controller_;
  TabContentsType type = this->type();

  delete this;

  controller->TabContentsWasDestroyed(type);
}

const GURL& TabContents::GetURL() const {
  // We may not have a navigation entry yet
  NavigationEntry* entry = controller_->GetActiveEntry();
  return entry ? entry->display_url() : GURL::EmptyGURL();
}

const std::wstring& TabContents::GetTitle() const {
  // We use the title for the last committed entry rather than a pending
  // navigation entry. For example, when the user types in a URL, we want to
  // keep the old page's title until the new load has committed and we get a new
  // title.
  // The exception is with transient pages, for which we really want to use
  // their title, as they are not committed.
  NavigationEntry* entry = controller_->GetTransientEntry();
  if (entry)
    return entry->GetTitleForDisplay();

  entry = controller_->GetLastCommittedEntry();
  if (entry)
    return entry->GetTitleForDisplay();
  else if (controller_->LoadingURLLazily())
    return controller_->GetLazyTitle();
  return EmptyWString();
}

void TabContents::NotifyNavigationStateChanged(unsigned changed_flags) {
  if (delegate_)
    delegate_->NavigationStateChanged(this, changed_flags);
}

void TabContents::OpenURL(const GURL& url, const GURL& referrer,
                          WindowOpenDisposition disposition,
                          PageTransition::Type transition) {
  if (delegate_)
    delegate_->OpenURLFromTab(this, url, referrer, disposition, transition);
}

void TabContents::SetIsLoading(bool is_loading,
                               LoadNotificationDetails* details) {
  if (is_loading == is_loading_)
    return;

  is_loading_ = is_loading;
  waiting_for_response_ = is_loading;

  // Suppress notifications for this TabContents if we are not active.
  if (!is_active_)
    return;

  if (delegate_)
    delegate_->LoadingStateChanged(this);

  NotificationType type = is_loading ? NotificationType::LOAD_START :
      NotificationType::LOAD_STOP;
  NotificationDetails det = NotificationService::NoDetails();;
  if (details)
      det = Details<LoadNotificationDetails>(details);
  NotificationService::current()->Notify(type,
      Source<NavigationController>(this->controller()),
      det);
}

bool TabContents::SupportsURL(GURL* url) {
  GURL u(*url);
  if (TabContents::TypeForURL(&u) == type()) {
    *url = u;
    return true;
  }
  return false;
}

int32 TabContents::GetMaxPageID() {
  if (GetSiteInstance())
    return GetSiteInstance()->max_page_id();
  else
    return max_page_id_;
}

void TabContents::UpdateMaxPageID(int32 page_id) {
  // Ensure both the SiteInstance and RenderProcessHost update their max page
  // IDs in sync. Only WebContents will also have site instances, except during
  // testing.
  if (GetSiteInstance())
    GetSiteInstance()->UpdateMaxPageID(page_id);

  if (AsWebContents())
    AsWebContents()->process()->UpdateMaxPageID(page_id);
  else
    max_page_id_ = std::max(max_page_id_, page_id);
}

void TabContents::SetIsCrashed(bool state) {
  if (state == is_crashed_)
    return;

  is_crashed_ = state;
  if (delegate_)
    delegate_->ContentsStateChanged(this);
}

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

void RLZTracker::CleanupRlz() {
  // http://code.google.com/p/chromium/issues/detail?id=8152
}

bool RLZTracker::GetAccessPointRlz(AccessPoint point, std::wstring* rlz) {
  // http://code.google.com/p/chromium/issues/detail?id=8152
  return false;
}

bool RLZTracker::RecordProductEvent(Product product, AccessPoint point,
                                    Event event) {
  // http://code.google.com/p/chromium/issues/detail?id=8152
  return false;
}

// This depends on porting all the plugin IPC messages.
bool IsPluginProcess() {
  return false;
}

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

void RunJavascriptMessageBox(WebContents* web_contents,
                             int dialog_flags,
                             const std::wstring& message_text,
                             const std::wstring& default_prompt_text,
                             bool display_suppress_checkbox,
                             IPC::Message* reply_msg) {
  NOTIMPLEMENTED();
}

void RunBeforeUnloadDialog(WebContents* web_contents,
                           const std::wstring& message_text,
                           IPC::Message* reply_msg) {
  NOTIMPLEMENTED();
}

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

void RunRepostFormWarningDialog(NavigationController*) {
}

LoginHandler* CreateLoginPrompt(net::AuthChallengeInfo* auth_info,
                                URLRequest* request,
                                MessageLoop* ui_loop) {
  NOTIMPLEMENTED();
  return NULL;
}

void ProcessWatcher::EnsureProcessTerminated(int) {
  NOTIMPLEMENTED();
}

//--------------------------------------------------------------------------
namespace webkit_glue {

bool IsDefaultPluginEnabled() {
  NOTIMPLEMENTED();
  return false;
}

#if defined(OS_MACOSX)
bool ClipboardIsFormatAvailable(Clipboard::FormatType format) {
  NOTIMPLEMENTED();
  return false;
}
#endif

}  // webkit_glue

#ifndef CHROME_DEBUGGER_DISABLED
DebuggerShell::DebuggerShell(DebuggerInputOutput *io) { }
DebuggerShell::~DebuggerShell() { }
void DebuggerShell::Start() { NOTIMPLEMENTED(); }
void DebuggerShell::Debug(TabContents* tab) { NOTIMPLEMENTED(); }
void DebuggerShell::DebugMessage(const std::wstring& msg) { NOTIMPLEMENTED(); }
void DebuggerShell::OnDebugAttach() { NOTIMPLEMENTED(); }
void DebuggerShell::OnDebugDisconnect() { NOTIMPLEMENTED(); }
void DebuggerShell::DidConnect() { NOTIMPLEMENTED(); }
void DebuggerShell::DidDisconnect() { NOTIMPLEMENTED(); }
void DebuggerShell::ProcessCommand(const std::wstring& data) {
  NOTIMPLEMENTED();
}
#endif  // !CHROME_DEBUGGER_DISABLED

MemoryDetails::MemoryDetails() {
  NOTIMPLEMENTED();
}

void MemoryDetails::StartFetch() {
  NOTIMPLEMENTED();
}

InfoBar* ConfirmInfoBarDelegate::CreateInfoBar() {
  NOTIMPLEMENTED();
  return NULL;
}

InfoBar* AlertInfoBarDelegate::CreateInfoBar() {
  NOTIMPLEMENTED();
  return NULL;
}

InfoBar* LinkInfoBarDelegate::CreateInfoBar() {
  NOTIMPLEMENTED();
  return NULL;
}

bool CanImportURL(const GURL& url) {
  NOTIMPLEMENTED();
  return false;
}

DownloadRequestDialogDelegate* DownloadRequestDialogDelegate::Create(
    TabContents* tab,
    DownloadRequestManager::TabDownloadState* host) {
  NOTIMPLEMENTED();
  return NULL;
}

views::Window* CreateInputWindow(gfx::NativeWindow parent_hwnd,
                                 InputWindowDelegate* delegate) {
  NOTIMPLEMENTED();
  return new views::Window();
}

<|endoftext|>