<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 "config.h"

#include <string>

#include "Document.h"
#include "DOMWindow.h"
#include "Frame.h"
#include "InspectorController.h"
#include "Node.h"
#include "Page.h"
#include "PlatformString.h"
#include "SecurityOrigin.h"
#include "V8Binding.h"
#include "V8CustomBinding.h"
#include "V8Proxy.h"
#include "V8Utilities.h"
#include <wtf/OwnPtr.h>
#include <wtf/Vector.h>
#undef LOG

#include "base/string_util.h"
#include "base/values.h"
#include "webkit/api/public/WebScriptSource.h"
#include "webkit/glue/devtools/bound_object.h"
#include "webkit/glue/devtools/debugger_agent.h"
#include "webkit/glue/devtools/devtools_rpc_js.h"
#include "webkit/glue/devtools/dom_agent.h"
#include "webkit/glue/devtools/tools_agent.h"
#include "webkit/glue/glue_util.h"
#include "webkit/glue/webdevtoolsclient_delegate.h"
#include "webkit/glue/webdevtoolsclient_impl.h"
#include "webkit/glue/webframe.h"
#include "webkit/glue/webview_impl.h"

using namespace WebCore;
using WebKit::WebScriptSource;
using WebKit::WebString;

DEFINE_RPC_JS_BOUND_OBJ(DebuggerAgent, DEBUGGER_AGENT_STRUCT,
    DebuggerAgentDelegate, DEBUGGER_AGENT_DELEGATE_STRUCT)
DEFINE_RPC_JS_BOUND_OBJ(DomAgent, DOM_AGENT_STRUCT,
    DomAgentDelegate, DOM_AGENT_DELEGATE_STRUCT)
DEFINE_RPC_JS_BOUND_OBJ(ToolsAgent, TOOLS_AGENT_STRUCT,
    ToolsAgentDelegate, TOOLS_AGENT_DELEGATE_STRUCT)

class ToolsAgentNativeDelegateImpl : public ToolsAgentNativeDelegate {
 public:
  struct ResourceContentRequestData {
    String mime_type;
    RefPtr<Node> frame;
  };

  ToolsAgentNativeDelegateImpl(WebFrameImpl* frame) : frame_(frame) {}
  virtual ~ToolsAgentNativeDelegateImpl() {}

  // ToolsAgentNativeDelegate implementation.
  virtual void DidGetResourceContent(int request_id, const String& content) {
    if (!resource_content_requests_.contains(request_id)) {
      NOTREACHED();
      return;
    }
    ResourceContentRequestData request =
        resource_content_requests_.take(request_id);

    InspectorController* ic = frame_->frame()->page()->inspectorController();
    if (request.frame && request.frame->attached()) {
      ic->addSourceToFrame(request.mime_type, content, request.frame.get());
    }
  }

  bool WaitingForResponse(int resource_id, Node* frame) {
    if (resource_content_requests_.contains(resource_id)) {
      DCHECK(resource_content_requests_.get(resource_id).frame.get() == frame)
          << "Only one frame is expected to display given resource";
      return true;
    }
    return false;
  }

  void RequestSent(int resource_id, String mime_type, Node* frame) {
    ResourceContentRequestData data;
    data.mime_type = mime_type;
    data.frame = frame;
    DCHECK(!resource_content_requests_.contains(resource_id));
    resource_content_requests_.set(resource_id, data);
  }

 private:
  WebFrameImpl* frame_;
  HashMap<int, ResourceContentRequestData> resource_content_requests_;
  DISALLOW_COPY_AND_ASSIGN(ToolsAgentNativeDelegateImpl);
};

namespace {

class RemoteDebuggerCommandExecutor : public CppBoundClass {
 public:
  RemoteDebuggerCommandExecutor(
      WebDevToolsClientDelegate* delegate,
      WebFrame* frame,
      const std::wstring& classname)
      : delegate_(delegate) {
    BindToJavascript(frame, classname);
    BindMethod("DebuggerCommand",
                &RemoteDebuggerCommandExecutor::DebuggerCommand);
  }
  virtual ~RemoteDebuggerCommandExecutor() {}

  // The DebuggerCommand() function provided to Javascript.
  void DebuggerCommand(const CppArgumentList& args, CppVariant* result) {
    std::string command = args[0].ToString();
    result->SetNull();
    delegate_->SendDebuggerCommandToAgent(command);
  }

 private:
  WebDevToolsClientDelegate* delegate_;
  DISALLOW_COPY_AND_ASSIGN(RemoteDebuggerCommandExecutor);
};

} //  namespace

// static
WebDevToolsClient* WebDevToolsClient::Create(
    WebView* view,
    WebDevToolsClientDelegate* delegate) {
  return new WebDevToolsClientImpl(static_cast<WebViewImpl*>(view), delegate);
}

WebDevToolsClientImpl::WebDevToolsClientImpl(
    WebViewImpl* web_view_impl,
    WebDevToolsClientDelegate* delegate)
    : web_view_impl_(web_view_impl),
      delegate_(delegate),
      loaded_(false) {
  WebFrameImpl* frame = web_view_impl_->main_frame();

  // Debugger commands should be sent using special method.
  debugger_command_executor_obj_.set(new RemoteDebuggerCommandExecutor(
      delegate, frame, L"RemoteDebuggerCommandExecutor"));
  debugger_agent_obj_.set(new JsDebuggerAgentBoundObj(
      this, frame, L"RemoteDebuggerAgent"));
  dom_agent_obj_.set(new JsDomAgentBoundObj(this, frame, L"RemoteDomAgent"));
  tools_agent_obj_.set(
      new JsToolsAgentBoundObj(this, frame, L"RemoteToolsAgent"));

  v8::HandleScope scope;
  v8::Handle<v8::Context> frame_context = V8Proxy::context(frame->frame());
  dev_tools_host_.set(new BoundObject(frame_context, this, "DevToolsHost"));
  dev_tools_host_->AddProtoFunction(
      "reset",
      WebDevToolsClientImpl::JsReset);
  dev_tools_host_->AddProtoFunction(
      "addSourceToFrame",
      WebDevToolsClientImpl::JsAddSourceToFrame);
  dev_tools_host_->AddProtoFunction(
      "addResourceSourceToFrame",
      WebDevToolsClientImpl::JsAddResourceSourceToFrame);
  dev_tools_host_->AddProtoFunction(
      "loaded",
      WebDevToolsClientImpl::JsLoaded);
  dev_tools_host_->AddProtoFunction(
      "search",
      WebCore::V8Custom::v8InspectorControllerSearchCallback);
  dev_tools_host_->AddProtoFunction(
      "getPlatform",
      WebDevToolsClientImpl::JsGetPlatform);
  dev_tools_host_->AddProtoFunction(
      "activateWindow",
      WebDevToolsClientImpl::JsActivateWindow);
  dev_tools_host_->AddProtoFunction(
      "closeWindow",
      WebDevToolsClientImpl::JsCloseWindow);
  dev_tools_host_->AddProtoFunction(
      "dockWindow",
      WebDevToolsClientImpl::JsDockWindow);
  dev_tools_host_->AddProtoFunction(
      "undockWindow",
      WebDevToolsClientImpl::JsUndockWindow);
  dev_tools_host_->AddProtoFunction(
      "toggleInspectElementMode",
      WebDevToolsClientImpl::JsToggleInspectElementMode);
  dev_tools_host_->Build();
}

WebDevToolsClientImpl::~WebDevToolsClientImpl() {
}

void WebDevToolsClientImpl::DispatchMessageFromAgent(
      const std::string& class_name,
      const std::string& method_name,
      const std::string& raw_msg) {
  if (ToolsAgentNativeDelegateDispatch::Dispatch(
          tools_agent_native_delegate_impl_.get(),
          class_name,
          method_name,
          raw_msg)) {
    return;
  }

  std::string expr = StringPrintf(
      "devtools.dispatch('%s','%s',%s)",
      class_name.c_str(),
      method_name.c_str(),
      raw_msg.c_str());
  if (!loaded_) {
    pending_incoming_messages_.append(expr);
    return;
  }
  ExecuteScript(expr);
}

void WebDevToolsClientImpl::AddResourceSourceToFrame(int resource_id,
                                                     String mime_type,
                                                     Node* frame) {
  if (tools_agent_native_delegate_impl_->WaitingForResponse(resource_id,
                                                            frame)) {
    return;
  }
  tools_agent_obj_->GetResourceContent(resource_id, resource_id);
  tools_agent_native_delegate_impl_->RequestSent(resource_id, mime_type, frame);
}

void WebDevToolsClientImpl::ExecuteScript(const std::string& expr) {
  web_view_impl_->GetMainFrame()->ExecuteScript(
      WebScriptSource(WebString::fromUTF8(expr)));
}

void WebDevToolsClientImpl::SendRpcMessage(const std::string& class_name,
                                           const std::string& method_name,
                                           const std::string& raw_msg) {
  delegate_->SendMessageToAgent(class_name, method_name, raw_msg);
}

// static
v8::Handle<v8::Value> WebDevToolsClientImpl::JsReset(
    const v8::Arguments& args) {
  WebDevToolsClientImpl* client = static_cast<WebDevToolsClientImpl*>(
      v8::External::Cast(*args.Data())->Value());
  WebFrameImpl* frame = client->web_view_impl_->main_frame();
  client->tools_agent_native_delegate_impl_.set(
      new ToolsAgentNativeDelegateImpl(frame));
  return v8::Undefined();
}

// static
v8::Handle<v8::Value> WebDevToolsClientImpl::JsAddSourceToFrame(
    const v8::Arguments& args) {
  if (args.Length() < 2) {
    return v8::Undefined();
  }

  v8::TryCatch exception_catcher;

  String mime_type = WebCore::toWebCoreStringWithNullCheck(args[0]);
  if (mime_type.isEmpty() || exception_catcher.HasCaught()) {
    return v8::Undefined();
  }
  String source_string = WebCore::toWebCoreStringWithNullCheck(args[1]);
  if (source_string.isEmpty() || exception_catcher.HasCaught()) {
    return v8::Undefined();
  }
  Node* node = V8DOMWrapper::convertDOMWrapperToNode<Node>(args[2]);
  if (!node || !node->attached()) {
    return v8::Undefined();
  }

  Page* page = V8Proxy::retrieveFrameForEnteredContext()->page();
  InspectorController* inspectorController = page->inspectorController();
  return WebCore::v8Boolean(inspectorController->
      addSourceToFrame(mime_type, source_string, node));
}

// static
v8::Handle<v8::Value> WebDevToolsClientImpl::JsAddResourceSourceToFrame(
    const v8::Arguments& args) {
  int resource_id = static_cast<int>(args[0]->NumberValue());
  String mime_type = WebCore::toWebCoreStringWithNullCheck(args[1]);
  if (mime_type.isEmpty()) {
    return v8::Undefined();
  }
  Node* node = V8DOMWrapper::convertDOMWrapperToNode<Node>(args[2]);
  WebDevToolsClientImpl* client = static_cast<WebDevToolsClientImpl*>(
      v8::External::Cast(*args.Data())->Value());
  client->AddResourceSourceToFrame(resource_id, mime_type, node);
  return v8::Undefined();
}

// static
v8::Handle<v8::Value> WebDevToolsClientImpl::JsLoaded(
    const v8::Arguments& args) {
  WebDevToolsClientImpl* client = static_cast<WebDevToolsClientImpl*>(
      v8::External::Cast(*args.Data())->Value());
  client->loaded_ = true;

  // Grant the devtools page the ability to have source view iframes.
  Page* page = V8Proxy::retrieveFrameForEnteredContext()->page();
  SecurityOrigin* origin = page->mainFrame()->domWindow()->securityOrigin();
  origin->grantUniversalAccess();

  for (Vector<std::string>::iterator it =
           client->pending_incoming_messages_.begin();
       it != client->pending_incoming_messages_.end();
       ++it) {
    client->ExecuteScript(*it);
  }
  client->pending_incoming_messages_.clear();
  return v8::Undefined();
}

// static
v8::Handle<v8::Value> WebDevToolsClientImpl::JsGetPlatform(
    const v8::Arguments& args) {
#if defined OS_MACOSX
  return v8String("mac-leopard");
#elif defined OS_LINUX
  return v8String("linux");
#else
  return v8String("windows");
#endif
}

// static
v8::Handle<v8::Value> WebDevToolsClientImpl::JsActivateWindow(
    const v8::Arguments& args) {
  WebDevToolsClientImpl* client = static_cast<WebDevToolsClientImpl*>(
      v8::External::Cast(*args.Data())->Value());
  client->delegate_->ActivateWindow();
  return v8::Undefined();
}

// static
v8::Handle<v8::Value> WebDevToolsClientImpl::JsCloseWindow(
    const v8::Arguments& args) {
  WebDevToolsClientImpl* client = static_cast<WebDevToolsClientImpl*>(
      v8::External::Cast(*args.Data())->Value());
  client->delegate_->CloseWindow();
  return v8::Undefined();
}

// static
v8::Handle<v8::Value> WebDevToolsClientImpl::JsDockWindow(
    const v8::Arguments& args) {
  WebDevToolsClientImpl* client = static_cast<WebDevToolsClientImpl*>(
      v8::External::Cast(*args.Data())->Value());
  client->delegate_->DockWindow();
  return v8::Undefined();
}

// static
v8::Handle<v8::Value> WebDevToolsClientImpl::JsUndockWindow(
    const v8::Arguments& args) {
  WebDevToolsClientImpl* client = static_cast<WebDevToolsClientImpl*>(
      v8::External::Cast(*args.Data())->Value());
  client->delegate_->UndockWindow();
  return v8::Undefined();
}

// static
v8::Handle<v8::Value> WebDevToolsClientImpl::JsToggleInspectElementMode(
    const v8::Arguments& args) {
  WebDevToolsClientImpl* client = static_cast<WebDevToolsClientImpl*>(
      v8::External::Cast(*args.Data())->Value());
  int enabled = static_cast<int>(args[0]->BooleanValue());
  client->delegate_->ToggleInspectElementMode(enabled);
  return v8::Undefined();
}
<commit_msg>Land Anton's change to cast from v8::Value to v8::Object before converting a wrapper to a native Node pointer in devtools.<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 "config.h"

#include <string>

#include "Document.h"
#include "DOMWindow.h"
#include "Frame.h"
#include "InspectorController.h"
#include "Node.h"
#include "Page.h"
#include "PlatformString.h"
#include "SecurityOrigin.h"
#include "V8Binding.h"
#include "V8CustomBinding.h"
#include "V8Proxy.h"
#include "V8Utilities.h"
#include <wtf/OwnPtr.h>
#include <wtf/Vector.h>
#undef LOG

#include "base/string_util.h"
#include "base/values.h"
#include "webkit/api/public/WebScriptSource.h"
#include "webkit/glue/devtools/bound_object.h"
#include "webkit/glue/devtools/debugger_agent.h"
#include "webkit/glue/devtools/devtools_rpc_js.h"
#include "webkit/glue/devtools/dom_agent.h"
#include "webkit/glue/devtools/tools_agent.h"
#include "webkit/glue/glue_util.h"
#include "webkit/glue/webdevtoolsclient_delegate.h"
#include "webkit/glue/webdevtoolsclient_impl.h"
#include "webkit/glue/webframe.h"
#include "webkit/glue/webview_impl.h"

using namespace WebCore;
using WebKit::WebScriptSource;
using WebKit::WebString;

DEFINE_RPC_JS_BOUND_OBJ(DebuggerAgent, DEBUGGER_AGENT_STRUCT,
    DebuggerAgentDelegate, DEBUGGER_AGENT_DELEGATE_STRUCT)
DEFINE_RPC_JS_BOUND_OBJ(DomAgent, DOM_AGENT_STRUCT,
    DomAgentDelegate, DOM_AGENT_DELEGATE_STRUCT)
DEFINE_RPC_JS_BOUND_OBJ(ToolsAgent, TOOLS_AGENT_STRUCT,
    ToolsAgentDelegate, TOOLS_AGENT_DELEGATE_STRUCT)

class ToolsAgentNativeDelegateImpl : public ToolsAgentNativeDelegate {
 public:
  struct ResourceContentRequestData {
    String mime_type;
    RefPtr<Node> frame;
  };

  ToolsAgentNativeDelegateImpl(WebFrameImpl* frame) : frame_(frame) {}
  virtual ~ToolsAgentNativeDelegateImpl() {}

  // ToolsAgentNativeDelegate implementation.
  virtual void DidGetResourceContent(int request_id, const String& content) {
    if (!resource_content_requests_.contains(request_id)) {
      NOTREACHED();
      return;
    }
    ResourceContentRequestData request =
        resource_content_requests_.take(request_id);

    InspectorController* ic = frame_->frame()->page()->inspectorController();
    if (request.frame && request.frame->attached()) {
      ic->addSourceToFrame(request.mime_type, content, request.frame.get());
    }
  }

  bool WaitingForResponse(int resource_id, Node* frame) {
    if (resource_content_requests_.contains(resource_id)) {
      DCHECK(resource_content_requests_.get(resource_id).frame.get() == frame)
          << "Only one frame is expected to display given resource";
      return true;
    }
    return false;
  }

  void RequestSent(int resource_id, String mime_type, Node* frame) {
    ResourceContentRequestData data;
    data.mime_type = mime_type;
    data.frame = frame;
    DCHECK(!resource_content_requests_.contains(resource_id));
    resource_content_requests_.set(resource_id, data);
  }

 private:
  WebFrameImpl* frame_;
  HashMap<int, ResourceContentRequestData> resource_content_requests_;
  DISALLOW_COPY_AND_ASSIGN(ToolsAgentNativeDelegateImpl);
};

namespace {

class RemoteDebuggerCommandExecutor : public CppBoundClass {
 public:
  RemoteDebuggerCommandExecutor(
      WebDevToolsClientDelegate* delegate,
      WebFrame* frame,
      const std::wstring& classname)
      : delegate_(delegate) {
    BindToJavascript(frame, classname);
    BindMethod("DebuggerCommand",
                &RemoteDebuggerCommandExecutor::DebuggerCommand);
  }
  virtual ~RemoteDebuggerCommandExecutor() {}

  // The DebuggerCommand() function provided to Javascript.
  void DebuggerCommand(const CppArgumentList& args, CppVariant* result) {
    std::string command = args[0].ToString();
    result->SetNull();
    delegate_->SendDebuggerCommandToAgent(command);
  }

 private:
  WebDevToolsClientDelegate* delegate_;
  DISALLOW_COPY_AND_ASSIGN(RemoteDebuggerCommandExecutor);
};

} //  namespace

// static
WebDevToolsClient* WebDevToolsClient::Create(
    WebView* view,
    WebDevToolsClientDelegate* delegate) {
  return new WebDevToolsClientImpl(static_cast<WebViewImpl*>(view), delegate);
}

WebDevToolsClientImpl::WebDevToolsClientImpl(
    WebViewImpl* web_view_impl,
    WebDevToolsClientDelegate* delegate)
    : web_view_impl_(web_view_impl),
      delegate_(delegate),
      loaded_(false) {
  WebFrameImpl* frame = web_view_impl_->main_frame();

  // Debugger commands should be sent using special method.
  debugger_command_executor_obj_.set(new RemoteDebuggerCommandExecutor(
      delegate, frame, L"RemoteDebuggerCommandExecutor"));
  debugger_agent_obj_.set(new JsDebuggerAgentBoundObj(
      this, frame, L"RemoteDebuggerAgent"));
  dom_agent_obj_.set(new JsDomAgentBoundObj(this, frame, L"RemoteDomAgent"));
  tools_agent_obj_.set(
      new JsToolsAgentBoundObj(this, frame, L"RemoteToolsAgent"));

  v8::HandleScope scope;
  v8::Handle<v8::Context> frame_context = V8Proxy::context(frame->frame());
  dev_tools_host_.set(new BoundObject(frame_context, this, "DevToolsHost"));
  dev_tools_host_->AddProtoFunction(
      "reset",
      WebDevToolsClientImpl::JsReset);
  dev_tools_host_->AddProtoFunction(
      "addSourceToFrame",
      WebDevToolsClientImpl::JsAddSourceToFrame);
  dev_tools_host_->AddProtoFunction(
      "addResourceSourceToFrame",
      WebDevToolsClientImpl::JsAddResourceSourceToFrame);
  dev_tools_host_->AddProtoFunction(
      "loaded",
      WebDevToolsClientImpl::JsLoaded);
  dev_tools_host_->AddProtoFunction(
      "search",
      WebCore::V8Custom::v8InspectorControllerSearchCallback);
  dev_tools_host_->AddProtoFunction(
      "getPlatform",
      WebDevToolsClientImpl::JsGetPlatform);
  dev_tools_host_->AddProtoFunction(
      "activateWindow",
      WebDevToolsClientImpl::JsActivateWindow);
  dev_tools_host_->AddProtoFunction(
      "closeWindow",
      WebDevToolsClientImpl::JsCloseWindow);
  dev_tools_host_->AddProtoFunction(
      "dockWindow",
      WebDevToolsClientImpl::JsDockWindow);
  dev_tools_host_->AddProtoFunction(
      "undockWindow",
      WebDevToolsClientImpl::JsUndockWindow);
  dev_tools_host_->AddProtoFunction(
      "toggleInspectElementMode",
      WebDevToolsClientImpl::JsToggleInspectElementMode);
  dev_tools_host_->Build();
}

WebDevToolsClientImpl::~WebDevToolsClientImpl() {
}

void WebDevToolsClientImpl::DispatchMessageFromAgent(
      const std::string& class_name,
      const std::string& method_name,
      const std::string& raw_msg) {
  if (ToolsAgentNativeDelegateDispatch::Dispatch(
          tools_agent_native_delegate_impl_.get(),
          class_name,
          method_name,
          raw_msg)) {
    return;
  }

  std::string expr = StringPrintf(
      "devtools.dispatch('%s','%s',%s)",
      class_name.c_str(),
      method_name.c_str(),
      raw_msg.c_str());
  if (!loaded_) {
    pending_incoming_messages_.append(expr);
    return;
  }
  ExecuteScript(expr);
}

void WebDevToolsClientImpl::AddResourceSourceToFrame(int resource_id,
                                                     String mime_type,
                                                     Node* frame) {
  if (tools_agent_native_delegate_impl_->WaitingForResponse(resource_id,
                                                            frame)) {
    return;
  }
  tools_agent_obj_->GetResourceContent(resource_id, resource_id);
  tools_agent_native_delegate_impl_->RequestSent(resource_id, mime_type, frame);
}

void WebDevToolsClientImpl::ExecuteScript(const std::string& expr) {
  web_view_impl_->GetMainFrame()->ExecuteScript(
      WebScriptSource(WebString::fromUTF8(expr)));
}

void WebDevToolsClientImpl::SendRpcMessage(const std::string& class_name,
                                           const std::string& method_name,
                                           const std::string& raw_msg) {
  delegate_->SendMessageToAgent(class_name, method_name, raw_msg);
}

// static
v8::Handle<v8::Value> WebDevToolsClientImpl::JsReset(
    const v8::Arguments& args) {
  WebDevToolsClientImpl* client = static_cast<WebDevToolsClientImpl*>(
      v8::External::Cast(*args.Data())->Value());
  WebFrameImpl* frame = client->web_view_impl_->main_frame();
  client->tools_agent_native_delegate_impl_.set(
      new ToolsAgentNativeDelegateImpl(frame));
  return v8::Undefined();
}

// static
v8::Handle<v8::Value> WebDevToolsClientImpl::JsAddSourceToFrame(
    const v8::Arguments& args) {
  if (args.Length() < 2) {
    return v8::Undefined();
  }

  v8::TryCatch exception_catcher;

  String mime_type = WebCore::toWebCoreStringWithNullCheck(args[0]);
  if (mime_type.isEmpty() || exception_catcher.HasCaught()) {
    return v8::Undefined();
  }
  String source_string = WebCore::toWebCoreStringWithNullCheck(args[1]);
  if (source_string.isEmpty() || exception_catcher.HasCaught()) {
    return v8::Undefined();
  }
  v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(args[2]);
  Node* node = V8DOMWrapper::convertDOMWrapperToNode<Node>(wrapper);
  if (!node || !node->attached()) {
    return v8::Undefined();
  }

  Page* page = V8Proxy::retrieveFrameForEnteredContext()->page();
  InspectorController* inspectorController = page->inspectorController();
  return WebCore::v8Boolean(inspectorController->
      addSourceToFrame(mime_type, source_string, node));
}

// static
v8::Handle<v8::Value> WebDevToolsClientImpl::JsAddResourceSourceToFrame(
    const v8::Arguments& args) {
  int resource_id = static_cast<int>(args[0]->NumberValue());
  String mime_type = WebCore::toWebCoreStringWithNullCheck(args[1]);
  if (mime_type.isEmpty()) {
    return v8::Undefined();
  }
  v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(args[2]);
  Node* node = V8DOMWrapper::convertDOMWrapperToNode<Node>(wrapper);
  WebDevToolsClientImpl* client = static_cast<WebDevToolsClientImpl*>(
      v8::External::Cast(*args.Data())->Value());
  client->AddResourceSourceToFrame(resource_id, mime_type, node);
  return v8::Undefined();
}

// static
v8::Handle<v8::Value> WebDevToolsClientImpl::JsLoaded(
    const v8::Arguments& args) {
  WebDevToolsClientImpl* client = static_cast<WebDevToolsClientImpl*>(
      v8::External::Cast(*args.Data())->Value());
  client->loaded_ = true;

  // Grant the devtools page the ability to have source view iframes.
  Page* page = V8Proxy::retrieveFrameForEnteredContext()->page();
  SecurityOrigin* origin = page->mainFrame()->domWindow()->securityOrigin();
  origin->grantUniversalAccess();

  for (Vector<std::string>::iterator it =
           client->pending_incoming_messages_.begin();
       it != client->pending_incoming_messages_.end();
       ++it) {
    client->ExecuteScript(*it);
  }
  client->pending_incoming_messages_.clear();
  return v8::Undefined();
}

// static
v8::Handle<v8::Value> WebDevToolsClientImpl::JsGetPlatform(
    const v8::Arguments& args) {
#if defined OS_MACOSX
  return v8String("mac-leopard");
#elif defined OS_LINUX
  return v8String("linux");
#else
  return v8String("windows");
#endif
}

// static
v8::Handle<v8::Value> WebDevToolsClientImpl::JsActivateWindow(
    const v8::Arguments& args) {
  WebDevToolsClientImpl* client = static_cast<WebDevToolsClientImpl*>(
      v8::External::Cast(*args.Data())->Value());
  client->delegate_->ActivateWindow();
  return v8::Undefined();
}

// static
v8::Handle<v8::Value> WebDevToolsClientImpl::JsCloseWindow(
    const v8::Arguments& args) {
  WebDevToolsClientImpl* client = static_cast<WebDevToolsClientImpl*>(
      v8::External::Cast(*args.Data())->Value());
  client->delegate_->CloseWindow();
  return v8::Undefined();
}

// static
v8::Handle<v8::Value> WebDevToolsClientImpl::JsDockWindow(
    const v8::Arguments& args) {
  WebDevToolsClientImpl* client = static_cast<WebDevToolsClientImpl*>(
      v8::External::Cast(*args.Data())->Value());
  client->delegate_->DockWindow();
  return v8::Undefined();
}

// static
v8::Handle<v8::Value> WebDevToolsClientImpl::JsUndockWindow(
    const v8::Arguments& args) {
  WebDevToolsClientImpl* client = static_cast<WebDevToolsClientImpl*>(
      v8::External::Cast(*args.Data())->Value());
  client->delegate_->UndockWindow();
  return v8::Undefined();
}

// static
v8::Handle<v8::Value> WebDevToolsClientImpl::JsToggleInspectElementMode(
    const v8::Arguments& args) {
  WebDevToolsClientImpl* client = static_cast<WebDevToolsClientImpl*>(
      v8::External::Cast(*args.Data())->Value());
  int enabled = static_cast<int>(args[0]->BooleanValue());
  client->delegate_->ToggleInspectElementMode(enabled);
  return v8::Undefined();
}
<|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/browser_window_gtk.h"

#include "base/logging.h"
#include "chrome/browser/browser.h"

namespace {

gboolean MainWindowDestroyed(GtkWindow* window, BrowserWindowGtk* browser_win) {
  delete browser_win;
  return FALSE;  // Don't stop this message.
}

gboolean MainWindowConfigured(GtkWindow* window, GdkEventConfigure* event,
                              BrowserWindowGtk* browser_win) {
  gfx::Rect bounds = gfx::Rect(event->x, event->y, event->width, event->height);
  browser_win->OnBoundsChanged(bounds);
  return FALSE;
}

gboolean MainWindowStateChanged(GtkWindow* window, GdkEventWindowState* event,
                                BrowserWindowGtk* browser_win) {
  browser_win->OnStateChanged(event->new_window_state);
  return FALSE;
}

// Using gtk_window_get_position/size creates a race condition, so only use
// this to get the initial bounds.  After window creation, we pick up the
// normal bounds by connecting to the configure-event signal.
gfx::Rect GetInitialWindowBounds(GtkWindow* window) {
  gint x, y, width, height;
  gtk_window_get_position(window, &x, &y);
  gtk_window_get_size(window, &width, &height);
  return gfx::Rect(x, y, width, height);
}

}  // namespace

BrowserWindowGtk::BrowserWindowGtk(Browser* browser) : browser_(browser) {
  Init();
}

BrowserWindowGtk::~BrowserWindowGtk() {
  Close();
}

void BrowserWindowGtk::Init() {
  window_ = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
  gtk_window_set_title(window_, "Chromium");
  gtk_window_set_default_size(window_, 640, 480);
  g_signal_connect(G_OBJECT(window_), "destroy",
                   G_CALLBACK(MainWindowDestroyed), this);
  g_signal_connect(G_OBJECT(window_), "configure-event",
                   G_CALLBACK(MainWindowConfigured), this);
  g_signal_connect(G_OBJECT(window_), "window-state-event",
                   G_CALLBACK(MainWindowStateChanged), this);
  bounds_ = GetInitialWindowBounds(window_);
}

void BrowserWindowGtk::Show() {
  gtk_widget_show_all(GTK_WIDGET(window_));
}

void BrowserWindowGtk::SetBounds(const gfx::Rect& bounds) {
  gint x = static_cast<gint>(bounds.x());
  gint y = static_cast<gint>(bounds.y());
  gint width = static_cast<gint>(bounds.width());
  gint height = static_cast<gint>(bounds.height());

  gtk_window_move(window_, x, y);
  gtk_window_resize(window_, width, height);
}

void BrowserWindowGtk::Close() {
  if (!window_)
    return;

  gtk_widget_destroy(GTK_WIDGET(window_));
  window_ = NULL;
}

void BrowserWindowGtk::Activate() {
  gtk_window_present(window_);
}

void BrowserWindowGtk::FlashFrame() {
  // May not be respected by all window managers.
  gtk_window_set_urgency_hint(window_, TRUE);
}

void* BrowserWindowGtk::GetNativeHandle() {
  return window_;
}

BrowserWindowTesting* BrowserWindowGtk::GetBrowserWindowTesting() {
  NOTIMPLEMENTED();
  return NULL;
}

StatusBubble* BrowserWindowGtk::GetStatusBubble() {
  NOTIMPLEMENTED();
  return NULL;
}

void BrowserWindowGtk::SelectedTabToolbarSizeChanged(bool is_animating) {
  NOTIMPLEMENTED();
}

void BrowserWindowGtk::UpdateTitleBar() {
  NOTIMPLEMENTED();
}

void BrowserWindowGtk::UpdateLoadingAnimations(bool should_animate) {
  NOTIMPLEMENTED();
}

void BrowserWindowGtk::SetStarredState(bool is_starred) {
  NOTIMPLEMENTED();
}

gfx::Rect BrowserWindowGtk::GetNormalBounds() const {
  return bounds_;
}

bool BrowserWindowGtk::IsMaximized() const {
  return (state_ & GDK_WINDOW_STATE_MAXIMIZED);
}

LocationBar* BrowserWindowGtk::GetLocationBar() const {
  NOTIMPLEMENTED();
  return NULL;
}

void BrowserWindowGtk::UpdateStopGoState(bool is_loading) {
  NOTIMPLEMENTED();
}

void BrowserWindowGtk::UpdateToolbar(TabContents* contents,
                                     bool should_restore_state) {
  NOTIMPLEMENTED();
}

void BrowserWindowGtk::FocusToolbar() {
  NOTIMPLEMENTED();
}

bool BrowserWindowGtk::IsBookmarkBarVisible() const {
  NOTIMPLEMENTED();
  return false;
}

gfx::Rect BrowserWindowGtk::GetRootWindowResizerRect() const {
  NOTIMPLEMENTED();
  return gfx::Rect();
}

void BrowserWindowGtk::ToggleBookmarkBar() {
  NOTIMPLEMENTED();
}

void BrowserWindowGtk::ShowAboutChromeDialog() {
  NOTIMPLEMENTED();
}

void BrowserWindowGtk::ShowBookmarkManager() {
  NOTIMPLEMENTED();
}

bool BrowserWindowGtk::IsBookmarkBubbleVisible() const {
  NOTIMPLEMENTED();
  return false;
}

void BrowserWindowGtk::ShowBookmarkBubble(const GURL& url,
                                          bool already_bookmarked) {
  NOTIMPLEMENTED();
}

void BrowserWindowGtk::ShowReportBugDialog() {
  NOTIMPLEMENTED();
}

void BrowserWindowGtk::ShowClearBrowsingDataDialog() {
  NOTIMPLEMENTED();
}

void BrowserWindowGtk::ShowImportDialog() {
  NOTIMPLEMENTED();
}

void BrowserWindowGtk::ShowSearchEnginesDialog() {
  NOTIMPLEMENTED();
}

void BrowserWindowGtk::ShowPasswordManager() {
  NOTIMPLEMENTED();
}

void BrowserWindowGtk::ShowSelectProfileDialog() {
  NOTIMPLEMENTED();
}

void BrowserWindowGtk::ShowNewProfileDialog() {
  NOTIMPLEMENTED();
}

void BrowserWindowGtk::ShowHTMLDialog(HtmlDialogContentsDelegate* delegate,
                                      void* parent_window) {
  NOTIMPLEMENTED();
}

void BrowserWindowGtk::DestroyBrowser() {
  browser_.reset();
}

void BrowserWindowGtk::OnBoundsChanged(const gfx::Rect& bounds) {
  bounds_ = bounds;
}

void BrowserWindowGtk::OnStateChanged(GdkWindowState state) {
  state_ = state;
}
<commit_msg>Revert "Linux build fix" This reverts commit r9411.<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/browser_window_gtk.h"

#include "base/logging.h"
#include "chrome/browser/browser.h"

namespace {

gboolean MainWindowDestroyed(GtkWindow* window, BrowserWindowGtk* browser_win) {
  delete browser_win;
  return FALSE;  // Don't stop this message.
}

gboolean MainWindowConfigured(GtkWindow* window, GdkEventConfigure* event,
                              BrowserWindowGtk* browser_win) {
  gfx::Rect bounds = gfx::Rect(event->x, event->y, event->width, event->height);
  browser_win->OnBoundsChanged(bounds);
  return FALSE;
}

gboolean MainWindowStateChanged(GtkWindow* window, GdkEventWindowState* event,
                                BrowserWindowGtk* browser_win) {
  browser_win->OnStateChanged(event->new_window_state);
  return FALSE;
}

// Using gtk_window_get_position/size creates a race condition, so only use
// this to get the initial bounds.  After window creation, we pick up the
// normal bounds by connecting to the configure-event signal.
gfx::Rect GetInitialWindowBounds(GtkWindow* window) {
  gint x, y, width, height;
  gtk_window_get_position(window, &x, &y);
  gtk_window_get_size(window, &width, &height);
  return gfx::Rect(x, y, width, height);
}

}  // namespace

BrowserWindowGtk::BrowserWindowGtk(Browser* browser) : browser_(browser) {
  Init();
}

BrowserWindowGtk::~BrowserWindowGtk() {
  Close();
}

void BrowserWindowGtk::Init() {
  window_ = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
  gtk_window_set_title(window_, "Chromium");
  gtk_window_set_default_size(window_, 640, 480);
  g_signal_connect(G_OBJECT(window_), "destroy",
                   G_CALLBACK(MainWindowDestroyed), this);
  g_signal_connect(G_OBJECT(window_), "configure-event",
                   G_CALLBACK(MainWindowConfigured), this);
  g_signal_connect(G_OBJECT(window_), "window-state-event",
                   G_CALLBACK(MainWindowStateChanged), this);
  bounds_ = GetInitialWindowBounds(window_);
}

void BrowserWindowGtk::Show() {
  gtk_widget_show_all(GTK_WIDGET(window_));
}

void BrowserWindowGtk::SetBounds(const gfx::Rect& bounds) {
  gint x = static_cast<gint>(bounds.x());
  gint y = static_cast<gint>(bounds.y());
  gint width = static_cast<gint>(bounds.width());
  gint height = static_cast<gint>(bounds.height());

  gtk_window_move(window_, x, y);
  gtk_window_resize(window_, width, height);
}

void BrowserWindowGtk::Close() {
  if (!window_)
    return;

  gtk_widget_destroy(GTK_WIDGET(window_));
  window_ = NULL;
}

void BrowserWindowGtk::Activate() {
  gtk_window_present(window_);
}

void BrowserWindowGtk::FlashFrame() {
  // May not be respected by all window managers.
  gtk_window_set_urgency_hint(window_, TRUE);
}

void* BrowserWindowGtk::GetNativeHandle() {
  return window_;
}

BrowserWindowTesting* BrowserWindowGtk::GetBrowserWindowTesting() {
  NOTIMPLEMENTED();
  return NULL;
}

StatusBubble* BrowserWindowGtk::GetStatusBubble() {
  NOTIMPLEMENTED();
  return NULL;
}

void BrowserWindowGtk::SelectedTabToolbarSizeChanged(bool is_animating) {
  NOTIMPLEMENTED();
}

void BrowserWindowGtk::UpdateTitleBar() {
  NOTIMPLEMENTED();
}

void BrowserWindowGtk::UpdateLoadingAnimations(bool should_animate) {
  NOTIMPLEMENTED();
}

void BrowserWindowGtk::SetStarredState(bool is_starred) {
  NOTIMPLEMENTED();
}

gfx::Rect BrowserWindowGtk::GetNormalBounds() const {
  return bounds_;
}

bool BrowserWindowGtk::IsMaximized() {
  return (state_ & GDK_WINDOW_STATE_MAXIMIZED);
}

LocationBar* BrowserWindowGtk::GetLocationBar() const {
  NOTIMPLEMENTED();
  return NULL;
}

void BrowserWindowGtk::UpdateStopGoState(bool is_loading) {
  NOTIMPLEMENTED();
}

void BrowserWindowGtk::UpdateToolbar(TabContents* contents,
                                     bool should_restore_state) {
  NOTIMPLEMENTED();
}

void BrowserWindowGtk::FocusToolbar() {
  NOTIMPLEMENTED();
}

bool BrowserWindowGtk::IsBookmarkBarVisible() const {
  NOTIMPLEMENTED();
  return false;
}

void BrowserWindowGtk::ToggleBookmarkBar() {
  NOTIMPLEMENTED();
}

void BrowserWindowGtk::ShowAboutChromeDialog() {
  NOTIMPLEMENTED();
}

void BrowserWindowGtk::ShowBookmarkManager() {
  NOTIMPLEMENTED();
}

bool BrowserWindowGtk::IsBookmarkBubbleVisible() const {
  NOTIMPLEMENTED();
  return false;
}

void BrowserWindowGtk::ShowBookmarkBubble(const GURL& url,
                                          bool already_bookmarked) {
  NOTIMPLEMENTED();
}

void BrowserWindowGtk::ShowReportBugDialog() {
  NOTIMPLEMENTED();
}

void BrowserWindowGtk::ShowClearBrowsingDataDialog() {
  NOTIMPLEMENTED();
}

void BrowserWindowGtk::ShowImportDialog() {
  NOTIMPLEMENTED();
}

void BrowserWindowGtk::ShowSearchEnginesDialog() {
  NOTIMPLEMENTED();
}

void BrowserWindowGtk::ShowPasswordManager() {
  NOTIMPLEMENTED();
}

void BrowserWindowGtk::ShowSelectProfileDialog() {
  NOTIMPLEMENTED();
}

void BrowserWindowGtk::ShowNewProfileDialog() {
  NOTIMPLEMENTED();
}

void BrowserWindowGtk::ShowHTMLDialog(HtmlDialogContentsDelegate* delegate,
                                      void* parent_window) {
  NOTIMPLEMENTED();
}

void BrowserWindowGtk::DestroyBrowser() {
  browser_.reset();
}

void BrowserWindowGtk::OnBoundsChanged(const gfx::Rect& bounds) {
  bounds_ = bounds;
}

void BrowserWindowGtk::OnStateChanged(GdkWindowState state) {
  state_ = state;
}
<|endoftext|>


<commit_before>#include "DatabaseServer.h"

#include "core/global.h"
#include <fstream>

ConfigVariable<channel_t> control_channel("control", 0);
ConfigVariable<unsigned int> id_start("generate/min", 1000);
ConfigVariable<unsigned int> id_end("generate/max", 2000);
ConfigVariable<std::string> storage_type("storage/type", "yaml");
LogCategory db_log("db", "Database");

DatabaseServer::DatabaseServer(RoleConfig roleconfig) : Role(roleconfig)
{
	m_log = &db_log;
	m_channel = control_channel.get_rval(roleconfig);
	m_db = DatabaseFactory::singleton.instantiate_db(storage_type.get_rval(roleconfig), roleconfig["storage"]);
	if(!m_db) {
		m_log->fatal() << "Database has no storage backend of type: " << storage_type.get_rval(roleconfig) << std::endl;
		exit(1);
	}
	m_start_id = m_free_id = id_start.get_rval(roleconfig);
	m_end_id = id_end.get_rval(roleconfig);

	subscribe_channel(m_channel);
}

DatabaseServer::~DatabaseServer() {}

void DatabaseServer::handle_datagram(Datagram &in_dg, DatagramIterator &dgi)
{
	channel_t sender = dgi.read_uint64();
	unsigned short msg_type = dgi.read_uint16();
	switch(msg_type)
	{
		case DBSERVER_CREATE_STORED_OBJECT:
		{
			unsigned int context = dgi.read_uint32();
			unsigned short dc_id = dgi.read_uint16();
			DCClass *dcc = gDCF->get_class(dc_id);
			unsigned short field_count = dgi.read_uint16();
			unsigned int do_id = m_free_id;
			if(do_id > m_end_id)
			{
				m_log->error() << "Database ran out of DistributedObject ids" << std::endl;
				Datagram resp;
				resp.add_server_header(sender, m_channel, DBSERVER_CREATE_STORED_OBJECT_RESP);
				resp.add_uint32(context);
				resp.add_uint32(0);
				send(resp);
				return;
			}
			m_free_id++;

			FieldList fields;
			for(unsigned short  i = 0; i < field_count; ++i)
			{
				unsigned short field_id = dgi.read_uint16();
				DCField *field = dcc->get_field(field_id);
				if(field && field->is_db())
				{
					fields.emplace(fields.end(), field, "");
					dgi.unpack_field(field, fields.back().second);
				}
			}

			m_db->create_object(do_id, fields);

			Datagram resp;
			resp.add_server_header(sender, m_channel, DBSERVER_CREATE_STORED_OBJECT_RESP);
			resp.add_uint32(context);
			resp.add_uint32(do_id);
			send(resp);
		}
		break;
		default:
			db_log.error() << "DB recv'd unknown MsgType: " << msg_type
				<< std::endl;
	};
}

RoleFactoryItem<DatabaseServer> dbserver_fact("database");
<commit_msg>DBServer: Clean debug messages (note, all messages prefixed with Database: already)<commit_after>#include "DatabaseServer.h"

#include "core/global.h"
#include <fstream>

ConfigVariable<channel_t> control_channel("control", 0);
ConfigVariable<unsigned int> id_start("generate/min", 1000);
ConfigVariable<unsigned int> id_end("generate/max", 2000);
ConfigVariable<std::string> storage_type("storage/type", "yaml");
LogCategory db_log("db", "Database");

DatabaseServer::DatabaseServer(RoleConfig roleconfig) : Role(roleconfig)
{
	m_log = &db_log;
	m_channel = control_channel.get_rval(roleconfig);
	m_db = DatabaseFactory::singleton.instantiate_db(storage_type.get_rval(roleconfig), roleconfig["storage"]);
	if(!m_db) {
		m_log->fatal() << "No storage backend of type '" << storage_type.get_rval(roleconfig) << "' exists." << std::endl;
		exit(1);
	}
	m_start_id = m_free_id = id_start.get_rval(roleconfig);
	m_end_id = id_end.get_rval(roleconfig);

	subscribe_channel(m_channel);
}

DatabaseServer::~DatabaseServer() {}

void DatabaseServer::handle_datagram(Datagram &in_dg, DatagramIterator &dgi)
{
	channel_t sender = dgi.read_uint64();
	unsigned short msg_type = dgi.read_uint16();
	switch(msg_type)
	{
		case DBSERVER_CREATE_STORED_OBJECT:
		{
			unsigned int context = dgi.read_uint32();
			unsigned short dc_id = dgi.read_uint16();
			DCClass *dcc = gDCF->get_class(dc_id);
			unsigned short field_count = dgi.read_uint16();
			unsigned int do_id = m_free_id;
			if(do_id > m_end_id)
			{
				m_log->error() << "Ran out of DistributedObject ids while creating new object." << std::endl;
				Datagram resp;
				resp.add_server_header(sender, m_channel, DBSERVER_CREATE_STORED_OBJECT_RESP);
				resp.add_uint32(context);
				resp.add_uint32(0);
				send(resp);
				return;
			}
			m_free_id++;

			m_log->spam() << "Created stored object with ID: " << do_id << std::endl;

			FieldList fields;
			for(unsigned short  i = 0; i < field_count; ++i)
			{
				unsigned short field_id = dgi.read_uint16();
				DCField *field = dcc->get_field(field_id);
				if(field && field->is_db())
				{
					fields.emplace(fields.end(), field, "");
					dgi.unpack_field(field, fields.back().second);
				}
			}

			m_db->create_object(do_id, fields);

			Datagram resp;
			resp.add_server_header(sender, m_channel, DBSERVER_CREATE_STORED_OBJECT_RESP);
			resp.add_uint32(context);
			resp.add_uint32(do_id);
			send(resp);
		}
		break;
		default:
			db_log.error() << "Recieved unknown MsgType: " << msg_type
				<< std::endl;
	};
}

RoleFactoryItem<DatabaseServer> dbserver_fact("database");
<|endoftext|>


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

#include "chrome/browser/views/app_launcher.h"

#include <string>
#include <vector>

#include "base/command_line.h"
#include "base/message_loop.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/view_ids.h"
#include "chrome/browser/views/dom_view.h"
#include "chrome/browser/views/info_bubble.h"
#include "chrome/browser/views/frame/browser_view.h"
#include "chrome/browser/views/location_bar/location_bar_view.h"
#include "chrome/common/url_constants.h"
#include "views/widget/root_view.h"

#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/status/status_area_view.h"
#endif

namespace {

// Padding between the navigation bar and the render view contents.
const int kNavigationBarBottomPadding = 3;

// NavigationBar constants.
const int kNavigationBarBorderThickness = 1;

// The speed in pixels per milli-second at which the animation should progress.
// It is easier to use a speed than a duration as the contents may report
// several changes in size over-time.
const double kAnimationSpeedPxPerMS = 1.5;

const SkColor kBorderColor = SkColorSetRGB(205, 201, 201);

// Command line switch for specifying url of the page.
// TODO: nuke when we convert to the real app page. Also nuke code in
// AddNewContents
const char kURLSwitch[] = "main-menu-url";

// Returns the URL of the menu.
static GURL GetMenuURL() {
  std::string url_string =
      CommandLine::ForCurrentProcess()->GetSwitchValueASCII(kURLSwitch);
  if (!url_string.empty())
    return GURL(url_string);
  return GURL(chrome::kChromeUIAppLauncherURL);
}

// Returns the location bar view of |browser|.
static views::View* GetBrowserLocationBar(Browser* browser) {
  BrowserView* browser_view = static_cast<BrowserView*>(browser->window());
  views::RootView* root_view = views::Widget::GetWidgetFromNativeWindow(
      browser_view->GetNativeHandle())->GetRootView();
  return root_view->GetViewByID(VIEW_ID_LOCATION_BAR);
}

}  // namespace

// InfoBubbleContentsView
//
// The view that contains the navigation bar and DOMUI.
// It is displayed in an info-bubble.

class InfoBubbleContentsView : public views::View,
                               public LocationBarView::Delegate,
                               public CommandUpdater::CommandUpdaterDelegate {
 public:
  explicit InfoBubbleContentsView(AppLauncher* app_launcher);
  ~InfoBubbleContentsView();

  // Computes and sets the preferred size for the InfoBubbleContentsView based
  // on the preferred size of the DOMUI contents specified.
  void ComputePreferredSize(const gfx::Size& dom_view_preferred_size);

  // Sets the initial focus.
  // Should be called when the bubble that contains us is shown.
  void BubbleShown();

  // Returns the TabContents displaying the contents for this bubble.
  TabContents* GetBubbleTabContents();

  // views::View override:
  virtual gfx::Size GetPreferredSize();
  virtual void Layout();
  virtual void ViewHierarchyChanged(bool is_add,
                                    views::View* parent,
                                    views::View* child);

  // LocationBarView::Delegate implementation:

  // WARNING: this is not the TabContents of the bubble!  Use
  // GetBubbleTabContents() to get the bubble's TabContents.
  virtual TabContents* GetTabContents();
  virtual void OnInputInProgress(bool in_progress) {}

  // CommandUpdater::CommandUpdaterDelegate implementation:
  virtual void ExecuteCommand(int id);

 private:
  // The application launcher displaying this info bubble.
  AppLauncher* app_launcher_;

  // The location bar.
  LocationBarView* location_bar_;

  // The view containing the renderer view.
  DOMView* dom_view_;

  // The preferred size for this view (at which it fits its contents).
  gfx::Size preferred_size_;

  // CommandUpdater the location bar sends commands to.
  CommandUpdater command_updater_;

  // The width of the browser's location bar.
  int browser_location_bar_width_;

  DISALLOW_COPY_AND_ASSIGN(InfoBubbleContentsView);
};

InfoBubbleContentsView::InfoBubbleContentsView(AppLauncher* app_launcher)
    : app_launcher_(app_launcher),
      location_bar_(NULL),
      dom_view_(NULL),
      ALLOW_THIS_IN_INITIALIZER_LIST(command_updater_(this)) {
  // Allow the location bar to open URLs.
  command_updater_.UpdateCommandEnabled(IDC_OPEN_CURRENT_URL, true);
  DCHECK(app_launcher);

  browser_location_bar_width_ =
      GetBrowserLocationBar(app_launcher->browser())->width();
}

InfoBubbleContentsView::~InfoBubbleContentsView() {
}

void InfoBubbleContentsView::ComputePreferredSize(
    const gfx::Size& dom_view_preferred_size) {
  preferred_size_ = dom_view_preferred_size;

  // Add the padding and location bar height.
  preferred_size_.Enlarge(
      0, location_bar_->height() + kNavigationBarBottomPadding);

  // Make sure the width is at least the browser location bar width.
  if (preferred_size_.width() < browser_location_bar_width_)
    preferred_size_.set_width(browser_location_bar_width_);
}

void InfoBubbleContentsView::BubbleShown() {
  location_bar_->RequestFocus();
}

TabContents* InfoBubbleContentsView::GetBubbleTabContents() {
  return dom_view_->tab_contents();
}

void InfoBubbleContentsView::ViewHierarchyChanged(
    bool is_add, views::View* parent, views::View* child) {
  if (!is_add || child != this)
    return;

  DCHECK(!dom_view_);
  dom_view_ = new DOMView();
  AddChildView(dom_view_);
  // We pass NULL for site instance so the renderer uses its own process.
  dom_view_->Init(app_launcher_->browser()->profile(), NULL);
  // We make the AppLauncher the TabContents delegate so we get notifications
  // from the page to open links.
  dom_view_->tab_contents()->set_delegate(app_launcher_);
  GURL url = GetMenuURL();
  std::string ref = url.ref();
  if (!app_launcher_->hash_params().empty()) {
    if (!ref.empty())
      ref += "&";
    ref += app_launcher_->hash_params();

    url_canon::Replacements<char> replacements;
    replacements.SetRef(ref.c_str(), url_parse::Component(0, ref.size()));
    url = url.ReplaceComponents(replacements);
  }
  dom_view_->LoadURL(url);

  Browser* browser = app_launcher_->browser();
  location_bar_ =  new LocationBarView(browser->profile(),
                                       &command_updater_,
                                       browser->toolbar_model(),
                                       this,
                                       LocationBarView::APP_LAUNCHER);

  location_bar_->set_border(
      views::Border::CreateSolidBorder(kNavigationBarBorderThickness,
                                       kBorderColor));
  AddChildView(location_bar_);
  location_bar_->Init();
  // Size the location to its preferred size so ComputePreferredSize() computes
  // the right size.
  location_bar_->SizeToPreferredSize();
  ComputePreferredSize(gfx::Size(browser_location_bar_width_, 0));
  Layout();
}

TabContents* InfoBubbleContentsView::GetTabContents() {
  return app_launcher_->browser()->GetSelectedTabContents();
}

gfx::Size InfoBubbleContentsView::GetPreferredSize() {
  return preferred_size_;
}

void InfoBubbleContentsView::Layout() {
  if (bounds().IsEmpty() || GetChildViewCount() == 0)
    return;

  gfx::Rect bounds = GetLocalBounds(false);
  // The browser's location bar uses vertical padding that we need to take into
  // account to match its height.
  int location_bar_height = location_bar_->GetPreferredSize().height() -
      LocationBarView::kVerticalEdgeThickness;
  location_bar_->SetBounds(bounds.x(), bounds.y(), bounds.width(),
                           location_bar_height);
  int render_y = location_bar_->bounds().bottom() + kNavigationBarBottomPadding;
  dom_view_->SetBounds(0, render_y,
                       width(), app_launcher_->contents_pref_size_.height());
}

void InfoBubbleContentsView::ExecuteCommand(int id) {
  // The user navigated by typing or selecting an entry in the location bar.
  DCHECK_EQ(IDC_OPEN_CURRENT_URL, id);
  GURL url(WideToUTF8(location_bar_->GetInputString()));
  app_launcher_->AddTabWithURL(url, location_bar_->GetPageTransition());
  app_launcher_->Hide();
}

////////////////////////////////////////////////////////////////////////////////
// AppLauncher

AppLauncher::AppLauncher(Browser* browser)
    : browser_(browser),
      info_bubble_(NULL) {
  DCHECK(browser);
  info_bubble_content_ = new InfoBubbleContentsView(this);
#if defined(OS_WIN)
  animate_ = true;
  animation_.reset(new SlideAnimation(this));
  animation_->SetTweenType(Tween::LINEAR);
#else
  animate_ = false;
#endif
}

AppLauncher::~AppLauncher() {
}

// static
AppLauncher* AppLauncher::Show(Browser* browser,
                               const gfx::Rect& bounds,
                               const gfx::Point& bubble_anchor,
                               const std::string& hash_params) {
  AppLauncher* app_launcher = new AppLauncher(browser);
  BrowserView* browser_view = static_cast<BrowserView*>(browser->window());
  app_launcher->hash_params_ = hash_params;
  app_launcher->info_bubble_ =
      PinnedContentsInfoBubble::Show(browser_view->GetWidget(),
          bounds, BubbleBorder::TOP_LEFT, bubble_anchor,
          app_launcher->info_bubble_content_, app_launcher);
  app_launcher->info_bubble_content_->BubbleShown();

  // TODO(finnur): Change this so that we only fade out when the user launches
  // something from the bubble. This will fade out on dismiss as well.
  app_launcher->info_bubble_->set_fade_away_on_close(true);
  return app_launcher;
}

// static
AppLauncher* AppLauncher::ShowForNewTab(Browser* browser,
                                        const std::string& hash_params) {
  BrowserView* browser_view = static_cast<BrowserView*>(browser->window());
  TabStrip* tabstrip = browser_view->tabstrip()->AsTabStrip();
  if (!tabstrip)
    return NULL;
  gfx::Rect bounds = tabstrip->GetNewTabButtonBounds();
  gfx::Point origin = bounds.origin();
  views::RootView::ConvertPointToScreen(tabstrip, &origin);
  bounds.set_origin(origin);

  // Figure out where the location bar is, so we can pin the bubble to
  // make our url bar appear exactly over it.
  views::View* location_bar = GetBrowserLocationBar(browser);
  gfx::Point location_bar_origin = location_bar->bounds().origin();
  views::RootView::ConvertPointToScreen(location_bar->GetParent(),
                                        &location_bar_origin);

  return Show(browser, bounds, location_bar_origin, hash_params);
}

void AppLauncher::Hide() {
  info_bubble_->Close();
}

void AppLauncher::OpenURLFromTab(TabContents* source,
                                 const GURL& url, const GURL& referrer,
                                 WindowOpenDisposition disposition,
                                 PageTransition::Type transition) {
  // TODO(jcivelli): we should call Browser::OpenApplicationTab(), we would need
  //                 to access the app for this URL.
  // The user clicked an item in the app launcher contents.
  AddTabWithURL(url, PageTransition::AUTO_BOOKMARK);
  Hide();
}

void AppLauncher::AddNewContents(TabContents* source,
                                 TabContents* new_contents,
                                 WindowOpenDisposition disposition,
                                 const gfx::Rect& initial_pos,
                                 bool user_gesture) {
#if defined(OS_CHROMEOS)
  // ChromeOS uses the kURLSwitch to specify a page that opens popups. We need
  // to do this so the popups are opened when the user clicks on the page.
  // TODO: nuke when convert to the real app page.
  new_contents->set_delegate(NULL);
  browser_->GetSelectedTabContents()->AddNewContents(
      new_contents, disposition, initial_pos, user_gesture);
  Hide();
#endif
}

void AppLauncher::UpdatePreferredSize(const gfx::Size& pref_size) {
  if (pref_size.width() == 0 || pref_size.height() == 0)
    return;

  previous_contents_pref_size_ = contents_pref_size_;
  contents_pref_size_ = pref_size;

  if (!animate_) {
    info_bubble_content_->ComputePreferredSize(pref_size);
    info_bubble_->SizeToContents();
    return;
  }

  int original_height = previous_contents_pref_size_.height();
  int new_height = contents_pref_size_.height();
  int new_duration;
  if (animation_->is_animating()) {
    // Modify the animation duration so that the current running animation does
    // not appear janky.
    new_duration = static_cast<int>(new_height / kAnimationSpeedPxPerMS);
  } else {
    // The animation is not running.
    animation_->Reset();  // It may have already been run.
    new_duration = static_cast<int>(abs(new_height - original_height) /
                                    kAnimationSpeedPxPerMS);
  }
  animation_->SetSlideDuration(new_duration);
  animation_->Show();  // No-op if already showing.
}

void AppLauncher::AnimationProgressed(const Animation* animation) {
  gfx::Size contents_size(contents_pref_size_.width(),
      animation->CurrentValueBetween(previous_contents_pref_size_.height(),
                                     contents_pref_size_.height()));
  info_bubble_content_->ComputePreferredSize(contents_size);
  info_bubble_->SizeToContents();
}

void AppLauncher::InfoBubbleClosing(InfoBubble* info_bubble,
                                    bool closed_by_escape) {
  // Delay deleting to be safe (we, and our tabcontents may be on the stack).
  // Remove ourself as a delegate as on GTK the Widget destruction is
  // asynchronous and will happen after the AppLauncher has been deleted (and it
  // might notify us after we have been deleted).
  info_bubble_content_->GetBubbleTabContents()->set_delegate(NULL);
  MessageLoop::current()->PostTask(FROM_HERE,
                                   new DeleteTask<AppLauncher>(this));
}

void AppLauncher::AddTabWithURL(const GURL& url,
                                PageTransition::Type transition) {
  browser_->AddTabWithURL(
      url, GURL(), transition, -1,
      TabStripModel::ADD_SELECTED | TabStripModel::ADD_FORCE_INDEX, NULL,
      std::string(), NULL);
}

void AppLauncher::Resize(const gfx::Size& contents_size) {
  info_bubble_content_->ComputePreferredSize(contents_size);
  info_bubble_->SizeToContents();
}
<commit_msg>Nukes --main-menu-url as it's not used anymore.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/views/app_launcher.h"

#include <string>
#include <vector>

#include "base/message_loop.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/view_ids.h"
#include "chrome/browser/views/dom_view.h"
#include "chrome/browser/views/info_bubble.h"
#include "chrome/browser/views/frame/browser_view.h"
#include "chrome/browser/views/location_bar/location_bar_view.h"
#include "chrome/common/url_constants.h"
#include "views/widget/root_view.h"

#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/status/status_area_view.h"
#endif

namespace {

// Padding between the navigation bar and the render view contents.
const int kNavigationBarBottomPadding = 3;

// NavigationBar constants.
const int kNavigationBarBorderThickness = 1;

// The speed in pixels per milli-second at which the animation should progress.
// It is easier to use a speed than a duration as the contents may report
// several changes in size over-time.
const double kAnimationSpeedPxPerMS = 1.5;

const SkColor kBorderColor = SkColorSetRGB(205, 201, 201);

// Returns the location bar view of |browser|.
static views::View* GetBrowserLocationBar(Browser* browser) {
  BrowserView* browser_view = static_cast<BrowserView*>(browser->window());
  views::RootView* root_view = views::Widget::GetWidgetFromNativeWindow(
      browser_view->GetNativeHandle())->GetRootView();
  return root_view->GetViewByID(VIEW_ID_LOCATION_BAR);
}

}  // namespace

// InfoBubbleContentsView
//
// The view that contains the navigation bar and DOMUI.
// It is displayed in an info-bubble.

class InfoBubbleContentsView : public views::View,
                               public LocationBarView::Delegate,
                               public CommandUpdater::CommandUpdaterDelegate {
 public:
  explicit InfoBubbleContentsView(AppLauncher* app_launcher);
  ~InfoBubbleContentsView();

  // Computes and sets the preferred size for the InfoBubbleContentsView based
  // on the preferred size of the DOMUI contents specified.
  void ComputePreferredSize(const gfx::Size& dom_view_preferred_size);

  // Sets the initial focus.
  // Should be called when the bubble that contains us is shown.
  void BubbleShown();

  // Returns the TabContents displaying the contents for this bubble.
  TabContents* GetBubbleTabContents();

  // views::View override:
  virtual gfx::Size GetPreferredSize();
  virtual void Layout();
  virtual void ViewHierarchyChanged(bool is_add,
                                    views::View* parent,
                                    views::View* child);

  // LocationBarView::Delegate implementation:

  // WARNING: this is not the TabContents of the bubble!  Use
  // GetBubbleTabContents() to get the bubble's TabContents.
  virtual TabContents* GetTabContents();
  virtual void OnInputInProgress(bool in_progress) {}

  // CommandUpdater::CommandUpdaterDelegate implementation:
  virtual void ExecuteCommand(int id);

 private:
  // The application launcher displaying this info bubble.
  AppLauncher* app_launcher_;

  // The location bar.
  LocationBarView* location_bar_;

  // The view containing the renderer view.
  DOMView* dom_view_;

  // The preferred size for this view (at which it fits its contents).
  gfx::Size preferred_size_;

  // CommandUpdater the location bar sends commands to.
  CommandUpdater command_updater_;

  // The width of the browser's location bar.
  int browser_location_bar_width_;

  DISALLOW_COPY_AND_ASSIGN(InfoBubbleContentsView);
};

InfoBubbleContentsView::InfoBubbleContentsView(AppLauncher* app_launcher)
    : app_launcher_(app_launcher),
      location_bar_(NULL),
      dom_view_(NULL),
      ALLOW_THIS_IN_INITIALIZER_LIST(command_updater_(this)) {
  // Allow the location bar to open URLs.
  command_updater_.UpdateCommandEnabled(IDC_OPEN_CURRENT_URL, true);
  DCHECK(app_launcher);

  browser_location_bar_width_ =
      GetBrowserLocationBar(app_launcher->browser())->width();
}

InfoBubbleContentsView::~InfoBubbleContentsView() {
}

void InfoBubbleContentsView::ComputePreferredSize(
    const gfx::Size& dom_view_preferred_size) {
  preferred_size_ = dom_view_preferred_size;

  // Add the padding and location bar height.
  preferred_size_.Enlarge(
      0, location_bar_->height() + kNavigationBarBottomPadding);

  // Make sure the width is at least the browser location bar width.
  if (preferred_size_.width() < browser_location_bar_width_)
    preferred_size_.set_width(browser_location_bar_width_);
}

void InfoBubbleContentsView::BubbleShown() {
  location_bar_->RequestFocus();
}

TabContents* InfoBubbleContentsView::GetBubbleTabContents() {
  return dom_view_->tab_contents();
}

void InfoBubbleContentsView::ViewHierarchyChanged(
    bool is_add, views::View* parent, views::View* child) {
  if (!is_add || child != this)
    return;

  DCHECK(!dom_view_);
  dom_view_ = new DOMView();
  AddChildView(dom_view_);
  // We pass NULL for site instance so the renderer uses its own process.
  dom_view_->Init(app_launcher_->browser()->profile(), NULL);
  // We make the AppLauncher the TabContents delegate so we get notifications
  // from the page to open links.
  dom_view_->tab_contents()->set_delegate(app_launcher_);
  GURL url(chrome::kChromeUIAppLauncherURL);
  std::string ref = url.ref();
  if (!app_launcher_->hash_params().empty()) {
    if (!ref.empty())
      ref += "&";
    ref += app_launcher_->hash_params();

    url_canon::Replacements<char> replacements;
    replacements.SetRef(ref.c_str(), url_parse::Component(0, ref.size()));
    url = url.ReplaceComponents(replacements);
  }
  dom_view_->LoadURL(url);

  Browser* browser = app_launcher_->browser();
  location_bar_ =  new LocationBarView(browser->profile(),
                                       &command_updater_,
                                       browser->toolbar_model(),
                                       this,
                                       LocationBarView::APP_LAUNCHER);

  location_bar_->set_border(
      views::Border::CreateSolidBorder(kNavigationBarBorderThickness,
                                       kBorderColor));
  AddChildView(location_bar_);
  location_bar_->Init();
  // Size the location to its preferred size so ComputePreferredSize() computes
  // the right size.
  location_bar_->SizeToPreferredSize();
  ComputePreferredSize(gfx::Size(browser_location_bar_width_, 0));
  Layout();
}

TabContents* InfoBubbleContentsView::GetTabContents() {
  return app_launcher_->browser()->GetSelectedTabContents();
}

gfx::Size InfoBubbleContentsView::GetPreferredSize() {
  return preferred_size_;
}

void InfoBubbleContentsView::Layout() {
  if (bounds().IsEmpty() || GetChildViewCount() == 0)
    return;

  gfx::Rect bounds = GetLocalBounds(false);
  // The browser's location bar uses vertical padding that we need to take into
  // account to match its height.
  int location_bar_height = location_bar_->GetPreferredSize().height() -
      LocationBarView::kVerticalEdgeThickness;
  location_bar_->SetBounds(bounds.x(), bounds.y(), bounds.width(),
                           location_bar_height);
  int render_y = location_bar_->bounds().bottom() + kNavigationBarBottomPadding;
  dom_view_->SetBounds(0, render_y,
                       width(), app_launcher_->contents_pref_size_.height());
}

void InfoBubbleContentsView::ExecuteCommand(int id) {
  // The user navigated by typing or selecting an entry in the location bar.
  DCHECK_EQ(IDC_OPEN_CURRENT_URL, id);
  GURL url(WideToUTF8(location_bar_->GetInputString()));
  app_launcher_->AddTabWithURL(url, location_bar_->GetPageTransition());
  app_launcher_->Hide();
}

////////////////////////////////////////////////////////////////////////////////
// AppLauncher

AppLauncher::AppLauncher(Browser* browser)
    : browser_(browser),
      info_bubble_(NULL) {
  DCHECK(browser);
  info_bubble_content_ = new InfoBubbleContentsView(this);
#if defined(OS_WIN)
  animate_ = true;
  animation_.reset(new SlideAnimation(this));
  animation_->SetTweenType(Tween::LINEAR);
#else
  animate_ = false;
#endif
}

AppLauncher::~AppLauncher() {
}

// static
AppLauncher* AppLauncher::Show(Browser* browser,
                               const gfx::Rect& bounds,
                               const gfx::Point& bubble_anchor,
                               const std::string& hash_params) {
  AppLauncher* app_launcher = new AppLauncher(browser);
  BrowserView* browser_view = static_cast<BrowserView*>(browser->window());
  app_launcher->hash_params_ = hash_params;
  app_launcher->info_bubble_ =
      PinnedContentsInfoBubble::Show(browser_view->GetWidget(),
          bounds, BubbleBorder::TOP_LEFT, bubble_anchor,
          app_launcher->info_bubble_content_, app_launcher);
  app_launcher->info_bubble_content_->BubbleShown();

  // TODO(finnur): Change this so that we only fade out when the user launches
  // something from the bubble. This will fade out on dismiss as well.
  app_launcher->info_bubble_->set_fade_away_on_close(true);
  return app_launcher;
}

// static
AppLauncher* AppLauncher::ShowForNewTab(Browser* browser,
                                        const std::string& hash_params) {
  BrowserView* browser_view = static_cast<BrowserView*>(browser->window());
  TabStrip* tabstrip = browser_view->tabstrip()->AsTabStrip();
  if (!tabstrip)
    return NULL;
  gfx::Rect bounds = tabstrip->GetNewTabButtonBounds();
  gfx::Point origin = bounds.origin();
  views::RootView::ConvertPointToScreen(tabstrip, &origin);
  bounds.set_origin(origin);

  // Figure out where the location bar is, so we can pin the bubble to
  // make our url bar appear exactly over it.
  views::View* location_bar = GetBrowserLocationBar(browser);
  gfx::Point location_bar_origin = location_bar->bounds().origin();
  views::RootView::ConvertPointToScreen(location_bar->GetParent(),
                                        &location_bar_origin);

  return Show(browser, bounds, location_bar_origin, hash_params);
}

void AppLauncher::Hide() {
  info_bubble_->Close();
}

void AppLauncher::OpenURLFromTab(TabContents* source,
                                 const GURL& url, const GURL& referrer,
                                 WindowOpenDisposition disposition,
                                 PageTransition::Type transition) {
  // TODO(jcivelli): we should call Browser::OpenApplicationTab(), we would need
  //                 to access the app for this URL.
  // The user clicked an item in the app launcher contents.
  AddTabWithURL(url, PageTransition::AUTO_BOOKMARK);
  Hide();
}

void AppLauncher::AddNewContents(TabContents* source,
                                 TabContents* new_contents,
                                 WindowOpenDisposition disposition,
                                 const gfx::Rect& initial_pos,
                                 bool user_gesture) {
}

void AppLauncher::UpdatePreferredSize(const gfx::Size& pref_size) {
  if (pref_size.width() == 0 || pref_size.height() == 0)
    return;

  previous_contents_pref_size_ = contents_pref_size_;
  contents_pref_size_ = pref_size;

  if (!animate_) {
    info_bubble_content_->ComputePreferredSize(pref_size);
    info_bubble_->SizeToContents();
    return;
  }

  int original_height = previous_contents_pref_size_.height();
  int new_height = contents_pref_size_.height();
  int new_duration;
  if (animation_->is_animating()) {
    // Modify the animation duration so that the current running animation does
    // not appear janky.
    new_duration = static_cast<int>(new_height / kAnimationSpeedPxPerMS);
  } else {
    // The animation is not running.
    animation_->Reset();  // It may have already been run.
    new_duration = static_cast<int>(abs(new_height - original_height) /
                                    kAnimationSpeedPxPerMS);
  }
  animation_->SetSlideDuration(new_duration);
  animation_->Show();  // No-op if already showing.
}

void AppLauncher::AnimationProgressed(const Animation* animation) {
  gfx::Size contents_size(contents_pref_size_.width(),
      animation->CurrentValueBetween(previous_contents_pref_size_.height(),
                                     contents_pref_size_.height()));
  info_bubble_content_->ComputePreferredSize(contents_size);
  info_bubble_->SizeToContents();
}

void AppLauncher::InfoBubbleClosing(InfoBubble* info_bubble,
                                    bool closed_by_escape) {
  // Delay deleting to be safe (we, and our tabcontents may be on the stack).
  // Remove ourself as a delegate as on GTK the Widget destruction is
  // asynchronous and will happen after the AppLauncher has been deleted (and it
  // might notify us after we have been deleted).
  info_bubble_content_->GetBubbleTabContents()->set_delegate(NULL);
  MessageLoop::current()->PostTask(FROM_HERE,
                                   new DeleteTask<AppLauncher>(this));
}

void AppLauncher::AddTabWithURL(const GURL& url,
                                PageTransition::Type transition) {
  browser_->AddTabWithURL(
      url, GURL(), transition, -1,
      TabStripModel::ADD_SELECTED | TabStripModel::ADD_FORCE_INDEX, NULL,
      std::string(), NULL);
}

void AppLauncher::Resize(const gfx::Size& contents_size) {
  info_bubble_content_->ComputePreferredSize(contents_size);
  info_bubble_->SizeToContents();
}
<|endoftext|>


<commit_before><commit_msg>Modifies the over-install behavior of setup to launch Chrome itself instead of letting Omaha do it.<commit_after><|endoftext|>


<commit_before><commit_msg>Style issues: - Fix indentation. - Reorder typedefs according to style guide. - Add DISALLOW_COPY_AND_ASSIGN. Review URL: http://codereview.chromium.org/42322<commit_after><|endoftext|>


<commit_before>
#ifndef CHROMOSOME_HPP_
#define CHROMOSOME_HPP_

#include <vector>	  // vector
#include <algorithm>  // swap_ranges
#include <random>     // mt19937, uniform_int_distribution, random_device

#define MINIMUM_NUMBER 0

template <class T>
class Chromosome {

protected:
    std::vector<T > chromosome;

    // random number generator values.
    static std::mt19937 random_engine;
    static std::uniform_int_distribution<int > rand_chrom_elem;
    // This only works with integer values
    static std::uniform_int_distribution<int > rand_value;

public:

    /**
     * Default contructor to allow for easier creation.
     */
    Chromosome() {

    }

    /**
     * Create a chromosome of the given size
     * @param chromosome_size The size of the chromosome.
     */
    Chromosome(unsigned int chromosome_size) : chromosome(chromosome_size){
    }

    ~Chromosome() {

    }

    /**
     * Create a chromosome of the given size
     * @param chromosome_size The size of the chromosome.
     */
    Chromosome(std::vector<T > chromosome) {
    	this->chromosome = chromosome;
    }

    /**
     * Initialize the population to random values. This only needs to be called on
     * the first generation during setup.
     * @param population The output population, note this will be cleared of any
     * existing values.
     * @param population_size The size of the population.
     * @param chromosome_size The size of the chromosomes within the population.
     */
    static void initPopulation(std::vector<Chromosome<T > > &population,
    		unsigned int population_size, unsigned int chromosome_size) {
    	population.clear();
    	for(unsigned int i = 0; i < population_size; i++) {
    		Chromosome<T > chrom (chromosome_size);
    		chrom.randChromosome();
    		population.push_back(chrom);
    	}
    }

    /**
     * Set up the random number generator engines to allow within the defined ranges.
     * @param chromosome_size The size of the chromosome.
     * @param min_chromosome_value The minimum value of a chromosome element.
     * @param max_chromosome_value The maximum value of a chromosome element.
     */
    static void initialize(unsigned int chromosome_size, T min_chromosome_value, T max_chromosome_value) {

		// Set up the random number generator engines.
		std::random_device rd;
		random_engine = std::mt19937 (rd());
		rand_chrom_elem = std::uniform_int_distribution<int> (MINIMUM_NUMBER, chromosome_size - 1);
		rand_value = std::uniform_int_distribution<int > (min_chromosome_value, max_chromosome_value);
    }

    /**
     * Apply the mutation operation to the chromosome and put it into the next generation.
     * @param children The next generation of chromosomes (the next population) that is currently being bread.
     */
    void mutate() {
    	//clonning(children);

    	// Identify element that will be changed
    	unsigned int mutated_index = getRandomElement();

        // Mutate the element
    	mutateElement(mutated_index);
    }

    /**
     * Apply the crossover operation to the chromosome and the other chromosome provided.
     * This will produce two offspring that are placed in the next generation.
     * *Note, Assumed that the two chromosomes (this and other) are of the same length.
     * @param other The second chromosome involved in the crossover operation
     * @param children The next generation of the population.
     *
     * Note that there are two possible methods to apply this crossover: index inclusive and index exclusive.
     * Currently index inclusive is used, this is where the site where the chromosomes are crossed over is
     * included in the crossover. Exclusive is the opposite where the index where the chromosomes are
     * crossed over is not included in the crossover.
     *
     * The crossover will work as:
     * chromosome1 = l1 + r1
     * chromosome2 = l2 + r2
     * after the crossover:
     * chromosome1 = l1 + r2
     * chromosome2 = l2 + r1
     * Where l1 and l2 are subsets of the chromosome = chromosome[0..crossover_site-1] for each respective chromosome
     * and r1 and r2 are subsets of the chromosome = chromosome[crossover_site..chromosome.size()-1] for each respective chromosome.
     */
    void crossover(Chromosome<T > &other, std::vector<Chromosome<T > > &children) {
    	// Copy value to the next population
    	clonning(children);
    	// Copy other to the next population
    	other.clonning(children);

    	// Randomly pick one point (where the cross over starts)
    	int crossover_index = getRandomElement(7);

    	// Using the index inclusive approach
    	// First gets l1 + r2 and second gets l2 + r1
    	// Note this approach does not work if crossover_index == 0
    	std::swap_ranges((*(children.end()-2)).chromosome.begin()+crossover_index, (*(children.end()-2)).chromosome.end(), (*(children.end()-1)).chromosome.begin()+crossover_index);

    	// Alternative exclusive index approach
    	// Note this approach does not work if crossover_index == 7, also this has been adjusted to hopefully work but has not been tested.
    	//std::swap_ranges((*(children.end()-2)).begin(), (*(children.end()-2)).begin()+(chromosome.size()-1-crossover_index)+1, (*(children.end()-1)).rbegin()+(chromosome.size()-1-crossover_index));

    }

    /**
     * Copy the chromosome to the next generation.
     * @param children The next generation.
     */
    void clonning(std::vector<Chromosome<T > > &children) {
    	// Copy value to the next population
    	children.push_back(*this);
    }

    /**
     * Overload the array operator.
     * @param n The index to retrieve the value at.
     * @return The value.
     */
    T operator[](unsigned int n) const {
    	return *this->chromosome[n];
    }

    /**
     * Overload the array operator
     * @param n The index to retrieve the value at.
     * @return The reference to the value.
     */
    T& operator[](unsigned int n) {
		return this->chromosome[n];
	}

    /**
     * Overload the == operation.
     * @param other The Chromosome to compare too.
     * @return Whether the two chromosomes are the same.
     */
    inline bool operator==(const Chromosome<T >& other){ return this->chromosome == other.chromosome; }

    /**
     * Overload the != operation, makes use of == operator overload
     * @param other The chromosome to check equality.
     * @return Whether the two chromosomes are different.
     */
    inline bool operator!=(const Chromosome<T >& other){ return !(*this == other); }

private:

    /**
     * Get a random index to allow for the retrieval a random element within the chromosome.
     * @return The random index.
     */
    unsigned int getRandomElement() {
    	return rand_chrom_elem(random_engine);
    }

	/**
	 * Get a random number between 0 and chromosome.size()-1 that is not index
	 * @param index The only value within the range that the return cannot be.
	 * @return A number within the defined range that is not index.
	 */
	unsigned int getRandomElement(unsigned int index) {
		unsigned int val = getRandomElement();

		while(val == index) {
			val = getRandomElement();
		}
		return val;
	}

	/**
	 * Mutate the given element within the chromosome
	 * @param mutated_index The index of the element within the chromosome that will be mutated.
	 */
    void mutateElement(unsigned int mutated_index) {

	// Could check if it is none primitive and call an expected function
	// Aka all 'data' types that are passed (that are not bool or int) are a child of a abstract class Gene
	// This will define a abstract accessor methods static method Gene::randomElement(Gene)
	// And potential other types of data members.
    	// Apply mutation operation to the chromosome
    	if(std::is_same<T, bool>::value) {
    		// Flip the bit
    		this->chromosome[mutated_index] = !this->chromosome[mutated_index];
    	} else {
    		// This will really only works for 'primitive types'
    		// Choose a random number within the range
    		this->chromosome[mutated_index] = getRandomValue(this->chromosome[mutated_index]);
    	}
    }

    /**
     * Generate a random chromosome.
     */
    void randChromosome() {
		for(unsigned int i = 0; i < chromosome.size(); i++) {
			chromosome[i] = getRandomValue();
		}
    }

    /**
     * Generate a random value for a chromosome element.
     * @return
     */
    T getRandomValue() {
    	return rand_value(random_engine);
    }

    /**
     * Generate a random value for the chromosome element that is not
     * equal to the one provided.
     * @param prev The value for which the return will not be equal to.
     * @return The random value for the chromosome element that is not
     * equal to prev.
     */
    T getRandomValue(T prev) {
        T val = getRandomValue();

        while(val == prev) {
            val = getRandomValue();
        }
        return val;
    }

};

template<class T>
std::mt19937 Chromosome<T >::random_engine;
template<class T>
std::uniform_int_distribution<int > Chromosome<T >::rand_chrom_elem;
template<class T>
std::uniform_int_distribution<int > Chromosome<T >::rand_value;

#endif /* CHROMOSOME_HPP_ */
<commit_msg>FIXED: crossover, 0 is not a valid index<commit_after>
#ifndef CHROMOSOME_HPP_
#define CHROMOSOME_HPP_

#include <vector>	  // vector
#include <algorithm>  // swap_ranges
#include <random>     // mt19937, uniform_int_distribution, random_device

#define MINIMUM_NUMBER 0

template <class T>
class Chromosome {

protected:
    std::vector<T > chromosome;

    // random number generator values.
    static std::mt19937 random_engine;
    static std::uniform_int_distribution<int > rand_chrom_elem;
    // This only works with integer values
    static std::uniform_int_distribution<int > rand_value;

public:

    /**
     * Default contructor to allow for easier creation.
     */
    Chromosome() {

    }

    /**
     * Create a chromosome of the given size
     * @param chromosome_size The size of the chromosome.
     */
    Chromosome(unsigned int chromosome_size) : chromosome(chromosome_size){
    }

    ~Chromosome() {

    }

    /**
     * Create a chromosome of the given size
     * @param chromosome_size The size of the chromosome.
     */
    Chromosome(std::vector<T > chromosome) {
    	this->chromosome = chromosome;
    }

    /**
     * Initialize the population to random values. This only needs to be called on
     * the first generation during setup.
     * @param population The output population, note this will be cleared of any
     * existing values.
     * @param population_size The size of the population.
     * @param chromosome_size The size of the chromosomes within the population.
     */
    static void initPopulation(std::vector<Chromosome<T > > &population,
    		unsigned int population_size, unsigned int chromosome_size) {
    	population.clear();
    	for(unsigned int i = 0; i < population_size; i++) {
    		Chromosome<T > chrom (chromosome_size);
    		chrom.randChromosome();
    		population.push_back(chrom);
    	}
    }

    /**
     * Set up the random number generator engines to allow within the defined ranges.
     * @param chromosome_size The size of the chromosome.
     * @param min_chromosome_value The minimum value of a chromosome element.
     * @param max_chromosome_value The maximum value of a chromosome element.
     */
    static void initialize(unsigned int chromosome_size, T min_chromosome_value, T max_chromosome_value) {

		// Set up the random number generator engines.
		std::random_device rd;
		random_engine = std::mt19937 (rd());
		rand_chrom_elem = std::uniform_int_distribution<int> (MINIMUM_NUMBER, chromosome_size - 1);
		rand_value = std::uniform_int_distribution<int > (min_chromosome_value, max_chromosome_value);
    }

    /**
     * Apply the mutation operation to the chromosome and put it into the next generation.
     * @param children The next generation of chromosomes (the next population) that is currently being bread.
     */
    void mutate() {
    	//clonning(children);

    	// Identify element that will be changed
    	unsigned int mutated_index = getRandomElement();

        // Mutate the element
    	mutateElement(mutated_index);
    }

    /**
     * Apply the crossover operation to the chromosome and the other chromosome provided.
     * This will produce two offspring that are placed in the next generation.
     * *Note, Assumed that the two chromosomes (this and other) are of the same length.
     * @param other The second chromosome involved in the crossover operation
     * @param children The next generation of the population.
     *
     * Note that there are two possible methods to apply this crossover: index inclusive and index exclusive.
     * Currently index inclusive is used, this is where the site where the chromosomes are crossed over is
     * included in the crossover. Exclusive is the opposite where the index where the chromosomes are
     * crossed over is not included in the crossover.
     *
     * The crossover will work as:
     * chromosome1 = l1 + r1
     * chromosome2 = l2 + r2
     * after the crossover:
     * chromosome1 = l1 + r2
     * chromosome2 = l2 + r1
     * Where l1 and l2 are subsets of the chromosome = chromosome[0..crossover_site-1] for each respective chromosome
     * and r1 and r2 are subsets of the chromosome = chromosome[crossover_site..chromosome.size()-1] for each respective chromosome.
     */
    void crossover(Chromosome<T > &other, std::vector<Chromosome<T > > &children) {
    	// Copy value to the next population
    	clonning(children);
    	// Copy other to the next population
    	other.clonning(children);

    	// Randomly pick one point (where the cross over starts)
    	int crossover_index = getRandomElement(0);

    	// Using the index inclusive approach
    	// First gets l1 + r2 and second gets l2 + r1
    	// Note this approach does not work if crossover_index == 0
    	std::swap_ranges((*(children.end()-2)).chromosome.begin()+crossover_index, (*(children.end()-2)).chromosome.end(), (*(children.end()-1)).chromosome.begin()+crossover_index);

    	// Alternative exclusive index approach
    	// Note this approach does not work if crossover_index == 7, also this has been adjusted to hopefully work but has not been tested.
    	//std::swap_ranges((*(children.end()-2)).begin(), (*(children.end()-2)).begin()+(chromosome.size()-1-crossover_index)+1, (*(children.end()-1)).rbegin()+(chromosome.size()-1-crossover_index));

    }

    /**
     * Copy the chromosome to the next generation.
     * @param children The next generation.
     */
    void clonning(std::vector<Chromosome<T > > &children) {
    	// Copy value to the next population
    	children.push_back(*this);
    }

    /**
     * Overload the array operator.
     * @param n The index to retrieve the value at.
     * @return The value.
     */
    T operator[](unsigned int n) const {
    	return *this->chromosome[n];
    }

    /**
     * Get the size of the chromosome
     * @return
     */
	unsigned int size() {
		return this->chromosome.size();
	}

    /**
     * Overload the array operator
     * @param n The index to retrieve the value at.
     * @return The reference to the value.
     */
    T& operator[](unsigned int n) {
		return this->chromosome[n];
	}

    /**
     * Overload the == operation.
     * @param other The Chromosome to compare too.
     * @return Whether the two chromosomes are the same.
     */
    inline bool operator==(const Chromosome<T >& other){ return this->chromosome == other.chromosome; }

    /**
     * Overload the != operation, makes use of == operator overload
     * @param other The chromosome to check equality.
     * @return Whether the two chromosomes are different.
     */
    inline bool operator!=(const Chromosome<T >& other){ return !(*this == other); }

private:

    /**
     * Get a random index to allow for the retrieval a random element within the chromosome.
     * @return The random index.
     */
    unsigned int getRandomElement() {
    	return rand_chrom_elem(random_engine);
    }

	/**
	 * Get a random number between 0 and chromosome.size()-1 that is not index
	 * @param index The only value within the range that the return cannot be.
	 * @return A number within the defined range that is not index.
	 */
	unsigned int getRandomElement(unsigned int index) {
		unsigned int val = getRandomElement();

		while(val == index) {
			val = getRandomElement();
		}
		return val;
	}

	/**
	 * Mutate the given element within the chromosome
	 * @param mutated_index The index of the element within the chromosome that will be mutated.
	 */
    void mutateElement(unsigned int mutated_index) {

	// Could check if it is none primitive and call an expected function
	// Aka all 'data' types that are passed (that are not bool or int) are a child of a abstract class Gene
	// This will define a abstract accessor methods static method Gene::randomElement(Gene)
	// And potential other types of data members.
    	// Apply mutation operation to the chromosome
    	if(std::is_same<T, bool>::value) {
    		// Flip the bit
    		this->chromosome[mutated_index] = !this->chromosome[mutated_index];
    	} else {
    		// This will really only works for 'primitive types'
    		// Choose a random number within the range
    		this->chromosome[mutated_index] = getRandomValue(this->chromosome[mutated_index]);
    	}
    }

    /**
     * Generate a random chromosome.
     */
    void randChromosome() {
		for(unsigned int i = 0; i < chromosome.size(); i++) {
			chromosome[i] = getRandomValue();
		}
    }

    /**
     * Generate a random value for a chromosome element.
     * @return
     */
    T getRandomValue() {
    	return rand_value(random_engine);
    }

    /**
     * Generate a random value for the chromosome element that is not
     * equal to the one provided.
     * @param prev The value for which the return will not be equal to.
     * @return The random value for the chromosome element that is not
     * equal to prev.
     */
    T getRandomValue(T prev) {
        T val = getRandomValue();

        while(val == prev) {
            val = getRandomValue();
        }
        return val;
    }

};

template<class T>
std::mt19937 Chromosome<T >::random_engine;
template<class T>
std::uniform_int_distribution<int > Chromosome<T >::rand_chrom_elem;
template<class T>
std::uniform_int_distribution<int > Chromosome<T >::rand_value;

#endif /* CHROMOSOME_HPP_ */
<|endoftext|>