diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..cfba0fe --- /dev/null +++ b/LICENSE @@ -0,0 +1,29 @@ +// Copyright (c) 2015 University of Szeged. +// Copyright (c) 2015 The Chromium Authors. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/browser/browser_context.cc b/browser/browser_context.cc new file mode 100644 index 0000000..51d8fa4 --- /dev/null +++ b/browser/browser_context.cc @@ -0,0 +1,160 @@ +// Copyright (c) 2015 University of Szeged. +// Copyright (c) 2015 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 "minibrowser/browser/browser_context.h" + +#include "base/command_line.h" +#include "base/environment.h" +#include "base/files/file_util.h" +#include "base/path_service.h" +#include "base/nix/xdg_util.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/storage_partition.h" +#include "content/public/common/content_switches.h" + +MiniBrowserBrowserContext::MiniBrowserResourceContext::MiniBrowserResourceContext() + : getter_(NULL) { +} + +MiniBrowserBrowserContext::MiniBrowserResourceContext::~MiniBrowserResourceContext() { +} + +net::HostResolver* +MiniBrowserBrowserContext::MiniBrowserResourceContext::GetHostResolver() { + CHECK(getter_); + return getter_->host_resolver(); +} + +net::URLRequestContext* +MiniBrowserBrowserContext::MiniBrowserResourceContext::GetRequestContext() { + CHECK(getter_); + return getter_->GetURLRequestContext(); +} + +MiniBrowserBrowserContext::MiniBrowserBrowserContext(bool off_the_record) + : resource_context_(new MiniBrowserResourceContext), + ignore_certificate_errors_(false), + off_the_record_(off_the_record) { + InitWhileIOAllowed(); +} + +MiniBrowserBrowserContext::~MiniBrowserBrowserContext() { + if (resource_context_) { + content::BrowserThread::DeleteSoon( + content::BrowserThread::IO, FROM_HERE, resource_context_.release()); + } +} + +void MiniBrowserBrowserContext::InitWhileIOAllowed() { + base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); + if (cmd_line->HasSwitch(switches::kIgnoreCertificateErrors)) + ignore_certificate_errors_ = true; + + scoped_ptr env(base::Environment::Create()); + base::FilePath config_dir( + base::nix::GetXDGDirectory(env.get(), + base::nix::kXdgConfigHomeEnvVar, + base::nix::kDotConfigDir)); + path_ = config_dir.Append("minibrowser"); + if (!base::PathExists(path_)) + base::CreateDirectory(path_); +} + +base::FilePath MiniBrowserBrowserContext::GetPath() const { + return path_; +} + +scoped_ptr +MiniBrowserBrowserContext::CreateZoomLevelDelegate( + const base::FilePath& partition_path) { + return scoped_ptr(); +} + +bool MiniBrowserBrowserContext::IsOffTheRecord() const { + return off_the_record_; +} + +net::URLRequestContextGetter* +MiniBrowserBrowserContext::GetRequestContext() { + return GetDefaultStoragePartition(this)->GetURLRequestContext(); +} + +net::URLRequestContextGetter* +MiniBrowserBrowserContext::GetRequestContextForRenderProcess( + int renderer_child_id) { + return GetRequestContext(); +} + +net::URLRequestContextGetter* +MiniBrowserBrowserContext::GetMediaRequestContext() { + return GetRequestContext(); +} + +net::URLRequestContextGetter* +MiniBrowserBrowserContext::GetMediaRequestContextForRenderProcess( + int renderer_child_id) { + return GetRequestContext(); +} + +net::URLRequestContextGetter* +MiniBrowserBrowserContext::GetMediaRequestContextForStoragePartition( + const base::FilePath& partition_path, + bool in_memory) { + return GetRequestContext(); +} + +content::ResourceContext* +MiniBrowserBrowserContext::GetResourceContext() { + return resource_context_.get(); +} + +content::DownloadManagerDelegate* +MiniBrowserBrowserContext::GetDownloadManagerDelegate() { + return NULL; +} + +content::BrowserPluginGuestManager* +MiniBrowserBrowserContext::GetGuestManager() { + return NULL; +} + +storage::SpecialStoragePolicy* +MiniBrowserBrowserContext::GetSpecialStoragePolicy() { + return NULL; +} + +content::PushMessagingService* +MiniBrowserBrowserContext::GetPushMessagingService() { + return NULL; +} + +content::SSLHostStateDelegate* +MiniBrowserBrowserContext::GetSSLHostStateDelegate() { + return NULL; +} + +MiniBrowserURLRequestContextGetter* +MiniBrowserBrowserContext::CreateURLRequestContextGetter( + content::ProtocolHandlerMap* protocol_handlers, + content::URLRequestInterceptorScopedVector request_interceptors) { + return new MiniBrowserURLRequestContextGetter( + ignore_certificate_errors_, + GetPath(), + content::BrowserThread::UnsafeGetMessageLoopForThread(content::BrowserThread::IO), + content::BrowserThread::UnsafeGetMessageLoopForThread(content::BrowserThread::FILE), + protocol_handlers, + request_interceptors.Pass()); +} + +net::URLRequestContextGetter* +MiniBrowserBrowserContext::CreateRequestContext( + content::ProtocolHandlerMap* protocol_handlers, + content::URLRequestInterceptorScopedVector request_interceptors) { + url_request_getter_ = CreateURLRequestContextGetter( + protocol_handlers, request_interceptors.Pass()); + resource_context_->set_url_request_context_getter(url_request_getter_.get()); + return url_request_getter_.get(); +} diff --git a/browser/browser_context.h b/browser/browser_context.h new file mode 100644 index 0000000..8a00835 --- /dev/null +++ b/browser/browser_context.h @@ -0,0 +1,95 @@ +// Copyright (c) 2015 University of Szeged. +// Copyright (c) 2015 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. + +#ifndef MINI_BROWSER_BROWSER_BROWSER_CONTEXT_H_ +#define MINI_BROWSER_BROWSER_BROWSER_CONTEXT_H_ + +#include "base/files/file_path.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/content_browser_client.h" +#include "content/public/browser/resource_context.h" +#include "minibrowser/browser/net/url_request_context_getter.h" + +class MiniBrowserBrowserContext : public content::BrowserContext { +public: + MiniBrowserBrowserContext(bool off_the_record); + ~MiniBrowserBrowserContext() override; + + // BrowserContext implementation. + base::FilePath GetPath() const override; + scoped_ptr CreateZoomLevelDelegate( + const base::FilePath& partition_path) override; + bool IsOffTheRecord() const override; + net::URLRequestContextGetter* GetRequestContext() override; + net::URLRequestContextGetter* GetRequestContextForRenderProcess( + int renderer_child_id) override; + net::URLRequestContextGetter* GetMediaRequestContext() override; + net::URLRequestContextGetter* GetMediaRequestContextForRenderProcess( + int renderer_child_id) override; + net::URLRequestContextGetter* GetMediaRequestContextForStoragePartition( + const base::FilePath& partition_path, + bool in_memory) override; + content::ResourceContext* GetResourceContext() override; + content::DownloadManagerDelegate* GetDownloadManagerDelegate() override; + content::BrowserPluginGuestManager* GetGuestManager() override; + storage::SpecialStoragePolicy* GetSpecialStoragePolicy() override; + content::PushMessagingService* GetPushMessagingService() override; + content::SSLHostStateDelegate* GetSSLHostStateDelegate() override; + net::URLRequestContextGetter* CreateRequestContext( + content::ProtocolHandlerMap* protocol_handlers, + content::URLRequestInterceptorScopedVector request_interceptors); + +protected: + // Contains URLRequestContextGetter required for resource loading. + class MiniBrowserResourceContext : public content::ResourceContext { + public: + MiniBrowserResourceContext(); + ~MiniBrowserResourceContext() override; + + // ResourceContext implementation: + net::HostResolver* GetHostResolver() override; + net::URLRequestContext* GetRequestContext() override; + + void set_url_request_context_getter(MiniBrowserURLRequestContextGetter* getter) { + getter_ = getter; + } + + private: + MiniBrowserURLRequestContextGetter* getter_; + + DISALLOW_COPY_AND_ASSIGN(MiniBrowserResourceContext); + }; + + MiniBrowserURLRequestContextGetter* url_request_context_getter() { + return url_request_getter_.get(); + } + + // Used by MiniBrowserBrowserContext to initiate and set different types of + // URLRequestContextGetter. + virtual MiniBrowserURLRequestContextGetter* CreateURLRequestContextGetter( + content::ProtocolHandlerMap* protocol_handlers, + content::URLRequestInterceptorScopedVector request_interceptors); + void set_url_request_context_getter(MiniBrowserURLRequestContextGetter* getter) { + url_request_getter_ = getter; + } + + bool ignore_certificate_errors() const { return ignore_certificate_errors_; } + + scoped_ptr resource_context_; + bool ignore_certificate_errors_; + +private: + void InitWhileIOAllowed(); + + bool off_the_record_; + base::FilePath path_; + scoped_refptr url_request_getter_; + + DISALLOW_COPY_AND_ASSIGN(MiniBrowserBrowserContext); +}; + + +#endif // MINI_BROWSER_BROWSER_BROWSER_CONTEXT_H_ \ No newline at end of file diff --git a/browser/browser_main.cc b/browser/browser_main.cc new file mode 100644 index 0000000..d274761 --- /dev/null +++ b/browser/browser_main.cc @@ -0,0 +1,26 @@ +// Copyright (c) 2015 University of Szeged. +// Copyright (c) 2015 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 "minibrowser/browser/browser_main.h" + +#include "base/memory/scoped_ptr.h" +#include "content/public/browser/browser_main_runner.h" + +// Main routine for running as the Browser process. +int BrowserMain( + const content::MainFunctionParams& parameters, + const scoped_ptr& main_runner) { + int exit_code = main_runner->Initialize(parameters); + + if (exit_code >= 0) + return exit_code; + + exit_code = main_runner->Run(); + + main_runner->Shutdown(); + + return exit_code; +} \ No newline at end of file diff --git a/browser/browser_main.h b/browser/browser_main.h new file mode 100644 index 0000000..92dbb33 --- /dev/null +++ b/browser/browser_main.h @@ -0,0 +1,21 @@ +// Copyright (c) 2015 University of Szeged. +// Copyright (c) 2015 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. + +#ifndef MINI_BROWSER_BROWSER_BROWSER_MAIN_H_ +#define MINI_BROWSER_BROWSER_BROWSER_MAIN_H_ + +#include "base/memory/scoped_ptr.h" + +namespace content { +class BrowserMainRunner; +struct MainFunctionParams; +} + +int BrowserMain( + const content::MainFunctionParams& parameters, + const scoped_ptr& main_runner); + +#endif // MINI_BROWSER_BROWSER_BROWSER_MAIN_H_ \ No newline at end of file diff --git a/browser/browser_main_parts.cc b/browser/browser_main_parts.cc new file mode 100644 index 0000000..8ffba35 --- /dev/null +++ b/browser/browser_main_parts.cc @@ -0,0 +1,103 @@ +// Copyright (c) 2015 University of Szeged. +// Copyright (c) 2015 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 "minibrowser/browser/browser_main_parts.h" + +#include "base/base_switches.h" +#include "base/bind.h" +#include "base/command_line.h" +#include "base/files/file_path.h" +#include "base/message_loop/message_loop.h" +#include "content/public/common/main_function_params.h" +#include "content/public/common/url_constants.h" +#include "minibrowser/browser/ui/minibrowser.h" +#include "minibrowser/browser/browser_context.h" +#include "net/base/filename_util.h" +#include "net/base/net_module.h" +#include "net/grit/net_resources.h" +#include "ui/base/ime/input_method_initializer.h" +#include "ui/base/resource/resource_bundle.h" +#include "url/gurl.h" + +namespace { + +GURL GetStartupURL() { + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + const base::CommandLine::StringVector& args = command_line->GetArgs(); + + if (args.empty()) + return GURL("https://www.google.com/"); + + GURL url(args[0]); + if (url.is_valid() && url.has_scheme()) + return url; + + return net::FilePathToFileURL(base::FilePath(args[0])); +} + +base::StringPiece NetResourceProvider(int key) { + if (key == IDR_DIR_HEADER_HTML) { + base::StringPiece html_data = + ui::ResourceBundle::GetSharedInstance().GetRawDataResource( + IDR_DIR_HEADER_HTML); + return html_data; + } + return base::StringPiece(); +} + +} // namespace + + +MiniBrowserBrowserMainParts::MiniBrowserBrowserMainParts( + const content::MainFunctionParams& parameters) + : parameters_(parameters), + run_message_loop_(true) { +} + +MiniBrowserBrowserMainParts::~MiniBrowserBrowserMainParts() { +} + +void MiniBrowserBrowserMainParts::PreMainMessageLoopStart() { +} + +void MiniBrowserBrowserMainParts::PostMainMessageLoopStart() { +} + +void MiniBrowserBrowserMainParts::PreEarlyInitialization() { + ui::InitializeInputMethodForTesting(); +} + +void MiniBrowserBrowserMainParts::InitializeBrowserContexts() { + set_browser_context(new MiniBrowserBrowserContext(false)); + set_off_the_record_browser_context( + new MiniBrowserBrowserContext(true)); +} + +void MiniBrowserBrowserMainParts::InitializeMessageLoopContext() { + MiniBrowser::CreateNewWindow(browser_context_.get(), + GetStartupURL(), + NULL, + gfx::Size()); +} + +void MiniBrowserBrowserMainParts::PreMainMessageLoopRun() { + InitializeBrowserContexts(); + + MiniBrowser::Initialize(); + + net::NetModule::SetResourceProvider(NetResourceProvider); + + InitializeMessageLoopContext(); +} + +bool MiniBrowserBrowserMainParts::MainMessageLoopRun(int* result_code) { + return !run_message_loop_; +} + +void MiniBrowserBrowserMainParts::PostMainMessageLoopRun() { + browser_context_.reset(); + off_the_record_browser_context_.reset(); +} \ No newline at end of file diff --git a/browser/browser_main_parts.h b/browser/browser_main_parts.h new file mode 100644 index 0000000..e713591 --- /dev/null +++ b/browser/browser_main_parts.h @@ -0,0 +1,58 @@ +// Copyright (c) 2015 University of Szeged. +// Copyright (c) 2015 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. + +#ifndef MINI_BROWSER_BROWSER_BROWSER_MAIN_PARTS_H_ +#define MINI_BROWSER_BROWSER_BROWSER_MAIN_PARTS_H_ + +#include "base/basictypes.h" +#include "base/memory/scoped_ptr.h" +#include "content/public/browser/browser_main_parts.h" +#include "content/public/common/main_function_params.h" +#include "minibrowser/browser/browser_context.h" + +class MiniBrowserBrowserMainParts : public content::BrowserMainParts { +public: + explicit MiniBrowserBrowserMainParts( + const content::MainFunctionParams& parameters); + ~MiniBrowserBrowserMainParts() override; + + MiniBrowserBrowserContext* browser_context() { + return browser_context_.get(); + } + MiniBrowserBrowserContext* off_the_record_browser_context() { + return off_the_record_browser_context_.get(); + } + + // content::BrowserMainParts overrides. + void PreEarlyInitialization() override; + void PreMainMessageLoopStart() override; + void PostMainMessageLoopStart() override; + void PreMainMessageLoopRun() override; + bool MainMessageLoopRun(int* result_code) override; + void PostMainMessageLoopRun() override; + +protected: + virtual void InitializeBrowserContexts(); + virtual void InitializeMessageLoopContext(); + + void set_browser_context(MiniBrowserBrowserContext* context) { + browser_context_.reset(context); + } + void set_off_the_record_browser_context(MiniBrowserBrowserContext* context) { + off_the_record_browser_context_.reset(context); + } + +private: + scoped_ptr browser_context_; + scoped_ptr off_the_record_browser_context_; + + const content::MainFunctionParams parameters_; + bool run_message_loop_; + + DISALLOW_COPY_AND_ASSIGN(MiniBrowserBrowserMainParts); +}; + +#endif // MINI_BROWSER_BROWSER_BROWSER_MAIN_PARTS_H_ \ No newline at end of file diff --git a/browser/content_browser_client.cc b/browser/content_browser_client.cc new file mode 100644 index 0000000..8ab2057 --- /dev/null +++ b/browser/content_browser_client.cc @@ -0,0 +1,114 @@ +// Copyright (c) 2015 University of Szeged. +// Copyright (c) 2015 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 "minibrowser/browser/content_browser_client.h" + +#include "base/base_switches.h" +#include "base/command_line.h" +#include "base/path_service.h" +#include "content/public/browser/resource_dispatcher_host.h" +#include "content/public/common/content_descriptors.h" +#include "content/public/common/url_constants.h" +#include "minibrowser/browser/browser_context.h" +#include "minibrowser/browser/browser_main_parts.h" +#include "gin/public/isolate_holder.h" +#include "net/url_request/url_request_context_getter.h" +#include "url/gurl.h" + + +MiniBrowserContentBrowserClient::MiniBrowserContentBrowserClient() + : v8_natives_fd_(-1), + v8_snapshot_fd_(-1), + browser_main_parts_(NULL) { +} + +MiniBrowserContentBrowserClient::~MiniBrowserContentBrowserClient() { +} + +content::BrowserMainParts* +MiniBrowserContentBrowserClient::CreateBrowserMainParts( + const content::MainFunctionParams& parameters) { + browser_main_parts_ = new MiniBrowserBrowserMainParts(parameters); + return browser_main_parts_; +} + +net::URLRequestContextGetter* +MiniBrowserContentBrowserClient::CreateRequestContext( + content::BrowserContext* browser_context, + content::ProtocolHandlerMap* protocol_handlers, + content::URLRequestInterceptorScopedVector request_interceptors) { + MiniBrowserBrowserContext* minibrowser_browser_context = + MiniBrowserBrowserContextForBrowserContext(browser_context); + return minibrowser_browser_context->CreateRequestContext( + protocol_handlers, request_interceptors.Pass()); +} + +bool MiniBrowserContentBrowserClient::IsHandledURL(const GURL& url) { + if (!url.is_valid()) { + return false; + } + + static const char* const kProtocolList[] = { + url::kBlobScheme, + url::kFileSystemScheme, + content::kChromeUIScheme, + url::kDataScheme, + url::kFileScheme, + }; + for (size_t i = 0; i < arraysize(kProtocolList); ++i) { + if (url.scheme() == kProtocolList[i]) + return true; + } + return false; +} + +std::string MiniBrowserContentBrowserClient::GetDefaultDownloadName() { + return "download"; +} + +void MiniBrowserContentBrowserClient::GetAdditionalMappedFilesForChildProcess( + const base::CommandLine& command_line, + int child_process_id, + content::FileDescriptorInfo* mappings) { + if (v8_snapshot_fd_.get() == -1 && v8_natives_fd_.get() == -1) { + base::FilePath v8_data_path; + PathService::Get(gin::IsolateHolder::kV8SnapshotBasePathKey, &v8_data_path); + DCHECK(!v8_data_path.empty()); + + int file_flags = base::File::FLAG_OPEN | base::File::FLAG_READ; + base::FilePath v8_natives_data_path = + v8_data_path.AppendASCII(gin::IsolateHolder::kNativesFileName); + base::FilePath v8_snapshot_data_path = + v8_data_path.AppendASCII(gin::IsolateHolder::kSnapshotFileName); + base::File v8_natives_data_file(v8_natives_data_path, file_flags); + base::File v8_snapshot_data_file(v8_snapshot_data_path, file_flags); + DCHECK(v8_natives_data_file.IsValid()); + DCHECK(v8_snapshot_data_file.IsValid()); + v8_natives_fd_.reset(v8_natives_data_file.TakePlatformFile()); + v8_snapshot_fd_.reset(v8_snapshot_data_file.TakePlatformFile()); + } + mappings->Share(kV8NativesDataDescriptor, v8_natives_fd_.get()); + mappings->Share(kV8SnapshotDataDescriptor, v8_snapshot_fd_.get()); +} + +MiniBrowserBrowserContext* +MiniBrowserContentBrowserClient::browser_context() { + return browser_main_parts_->browser_context(); +} + +MiniBrowserBrowserContext* +MiniBrowserContentBrowserClient::off_the_record_browser_context() { + return browser_main_parts_->off_the_record_browser_context(); +} + +MiniBrowserBrowserContext* +MiniBrowserContentBrowserClient::MiniBrowserBrowserContextForBrowserContext( + content::BrowserContext* content_browser_context) { + if (content_browser_context == browser_context()) + return browser_context(); + DCHECK_EQ(content_browser_context, off_the_record_browser_context()); + return off_the_record_browser_context(); +} \ No newline at end of file diff --git a/browser/content_browser_client.h b/browser/content_browser_client.h new file mode 100644 index 0000000..8e621db --- /dev/null +++ b/browser/content_browser_client.h @@ -0,0 +1,55 @@ +// Copyright (c) 2015 University of Szeged. +// Copyright (c) 2015 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. + +#ifndef MINI_BROWSER_BROWSER_CONTENT_BROWSER_CLIENT_H_ +#define MINI_BROWSER_BROWSER_CONTENT_BROWSER_CLIENT_H_ + +#include + +#include "base/memory/scoped_ptr.h" +#include "content/public/browser/content_browser_client.h" + +class MiniBrowserBrowserContext; +class MiniBrowserBrowserMainParts; + +class MiniBrowserContentBrowserClient : public content::ContentBrowserClient { +public: + + MiniBrowserContentBrowserClient(); + ~MiniBrowserContentBrowserClient() override; + + // ContentBrowserClient overrides. + content::BrowserMainParts* CreateBrowserMainParts( + const content::MainFunctionParams& parameters) override; + net::URLRequestContextGetter* CreateRequestContext( + content::BrowserContext* browser_context, + content::ProtocolHandlerMap* protocol_handlers, + content::URLRequestInterceptorScopedVector request_interceptors) override; + bool IsHandledURL(const GURL& url) override; + std::string GetDefaultDownloadName() override; + void GetAdditionalMappedFilesForChildProcess( + const base::CommandLine& command_line, + int child_process_id, + content::FileDescriptorInfo* mappings) override; + + MiniBrowserBrowserContext* browser_context(); + MiniBrowserBrowserContext* off_the_record_browser_context(); + + MiniBrowserBrowserMainParts* browser_main_parts() { + return browser_main_parts_; + } + +private: + MiniBrowserBrowserContext* MiniBrowserBrowserContextForBrowserContext( + content::BrowserContext* content_browser_context); + + base::ScopedFD v8_natives_fd_; + base::ScopedFD v8_snapshot_fd_; + + MiniBrowserBrowserMainParts* browser_main_parts_; +}; + +#endif // MINI_BROWSER_BROWSER_CONTENT_BROWSER_CLIENT_H_ \ No newline at end of file diff --git a/browser/net/network_delegate.cc b/browser/net/network_delegate.cc new file mode 100644 index 0000000..8840899 --- /dev/null +++ b/browser/net/network_delegate.cc @@ -0,0 +1,122 @@ +// Copyright (c) 2015 University of Szeged. +// Copyright (c) 2015 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 "minibrowser/browser/net/network_delegate.h" + +#include "base/command_line.h" +#include "content/public/common/content_switches.h" +#include "net/base/net_errors.h" +#include "net/base/static_cookie_policy.h" +#include "net/url_request/url_request.h" + +namespace { +bool g_accept_all_cookies = true; +} + +MiniBrowserNetworkDelegate::MiniBrowserNetworkDelegate() { +} + +MiniBrowserNetworkDelegate::~MiniBrowserNetworkDelegate() { +} + +void MiniBrowserNetworkDelegate::SetAcceptAllCookies(bool accept) { + g_accept_all_cookies = accept; +} + +int MiniBrowserNetworkDelegate::OnBeforeURLRequest( + net::URLRequest* request, + const net::CompletionCallback& callback, + GURL* new_url) { + return net::OK; +} + +int MiniBrowserNetworkDelegate::OnBeforeSendHeaders( + net::URLRequest* request, + const net::CompletionCallback& callback, + net::HttpRequestHeaders* headers) { + return net::OK; +} + +void MiniBrowserNetworkDelegate::OnSendHeaders( + net::URLRequest* request, + const net::HttpRequestHeaders& headers) { +} + +int MiniBrowserNetworkDelegate::OnHeadersReceived( + net::URLRequest* request, + const net::CompletionCallback& callback, + const net::HttpResponseHeaders* original_response_headers, + scoped_refptr* override_response_headers, + GURL* allowed_unsafe_redirect_url) { + return net::OK; +} + +void MiniBrowserNetworkDelegate::OnBeforeRedirect(net::URLRequest* request, + const GURL& new_location) { +} + +void MiniBrowserNetworkDelegate::OnResponseStarted(net::URLRequest* request) { +} + +void MiniBrowserNetworkDelegate::OnRawBytesRead(const net::URLRequest& request, + int bytes_read) { +} + +void MiniBrowserNetworkDelegate::OnCompleted(net::URLRequest* request, bool started) { +} + +void MiniBrowserNetworkDelegate::OnURLRequestDestroyed(net::URLRequest* request) { +} + +void MiniBrowserNetworkDelegate::OnPACScriptError(int line_number, + const base::string16& error) { +} + +MiniBrowserNetworkDelegate::AuthRequiredResponse MiniBrowserNetworkDelegate::OnAuthRequired( + net::URLRequest* request, + const net::AuthChallengeInfo& auth_info, + const AuthCallback& callback, + net::AuthCredentials* credentials) { + return AUTH_REQUIRED_RESPONSE_NO_ACTION; +} + +bool MiniBrowserNetworkDelegate::OnCanGetCookies(const net::URLRequest& request, + const net::CookieList& cookie_list) { + net::StaticCookiePolicy::Type policy_type = g_accept_all_cookies ? + net::StaticCookiePolicy::ALLOW_ALL_COOKIES : + net::StaticCookiePolicy::BLOCK_ALL_THIRD_PARTY_COOKIES; + net::StaticCookiePolicy policy(policy_type); + int rv = policy.CanGetCookies( + request.url(), request.first_party_for_cookies()); + return rv == net::OK; +} + +bool MiniBrowserNetworkDelegate::OnCanSetCookie(const net::URLRequest& request, + const std::string& cookie_line, + net::CookieOptions* options) { + net::StaticCookiePolicy::Type policy_type = g_accept_all_cookies ? + net::StaticCookiePolicy::ALLOW_ALL_COOKIES : + net::StaticCookiePolicy::BLOCK_ALL_THIRD_PARTY_COOKIES; + net::StaticCookiePolicy policy(policy_type); + int rv = policy.CanSetCookie( + request.url(), request.first_party_for_cookies()); + return rv == net::OK; +} + +bool MiniBrowserNetworkDelegate::OnCanAccessFile(const net::URLRequest& request, + const base::FilePath& path) const { + return true; +} + +bool MiniBrowserNetworkDelegate::OnCanThrottleRequest( + const net::URLRequest& request) const { + return false; +} + +bool MiniBrowserNetworkDelegate::OnFirstPartyOnlyCookieExperimentEnabled() const { + return base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableExperimentalWebPlatformFeatures); +} diff --git a/browser/net/network_delegate.h b/browser/net/network_delegate.h new file mode 100644 index 0000000..b1c6dc0 --- /dev/null +++ b/browser/net/network_delegate.h @@ -0,0 +1,62 @@ +// Copyright (c) 2015 University of Szeged. +// Copyright (c) 2015 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. + +#ifndef MINI_BROWSER_BROWSER_NET_NETWORK_DELEGATE_H_ +#define MINI_BROWSER_BROWSER_NET_NETWORK_DELEGATE_H_ + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "net/base/network_delegate_impl.h" + +class MiniBrowserNetworkDelegate : public net::NetworkDelegateImpl { +public: + MiniBrowserNetworkDelegate(); + ~MiniBrowserNetworkDelegate() override; + + static void SetAcceptAllCookies(bool accept); + +private: + // net::NetworkDelegate implementation. + int OnBeforeURLRequest(net::URLRequest* request, + const net::CompletionCallback& callback, + GURL* new_url) override; + int OnBeforeSendHeaders(net::URLRequest* request, + const net::CompletionCallback& callback, + net::HttpRequestHeaders* headers) override; + void OnSendHeaders(net::URLRequest* request, + const net::HttpRequestHeaders& headers) override; + int OnHeadersReceived( + net::URLRequest* request, + const net::CompletionCallback& callback, + const net::HttpResponseHeaders* original_response_headers, + scoped_refptr* override_response_headers, + GURL* allowed_unsafe_redirect_url) override; + void OnBeforeRedirect(net::URLRequest* request, + const GURL& new_location) override; + void OnResponseStarted(net::URLRequest* request) override; + void OnRawBytesRead(const net::URLRequest& request, int bytes_read) override; + void OnCompleted(net::URLRequest* request, bool started) override; + void OnURLRequestDestroyed(net::URLRequest* request) override; + void OnPACScriptError(int line_number, const base::string16& error) override; + AuthRequiredResponse OnAuthRequired( + net::URLRequest* request, + const net::AuthChallengeInfo& auth_info, + const AuthCallback& callback, + net::AuthCredentials* credentials) override; + bool OnCanGetCookies(const net::URLRequest& request, + const net::CookieList& cookie_list) override; + bool OnCanSetCookie(const net::URLRequest& request, + const std::string& cookie_line, + net::CookieOptions* options) override; + bool OnCanAccessFile(const net::URLRequest& request, + const base::FilePath& path) const override; + bool OnCanThrottleRequest(const net::URLRequest& request) const override; + bool OnFirstPartyOnlyCookieExperimentEnabled() const override; + + DISALLOW_COPY_AND_ASSIGN(MiniBrowserNetworkDelegate); +}; + +#endif // MINI_BROWSER_BROWSER_NET_NETWORK_DELEGATE_H_ diff --git a/browser/net/url_request_context_getter.cc b/browser/net/url_request_context_getter.cc new file mode 100644 index 0000000..5695d76 --- /dev/null +++ b/browser/net/url_request_context_getter.cc @@ -0,0 +1,237 @@ +// Copyright (c) 2015 University of Szeged. +// Copyright (c) 2015 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 "minibrowser/browser/net/url_request_context_getter.h" + +#include "base/command_line.h" +#include "base/logging.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_split.h" +#include "base/strings/string_util.h" +#include "base/threading/sequenced_worker_pool.h" +#include "base/threading/worker_pool.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/cookie_store_factory.h" +#include "content/public/common/content_switches.h" +#include "minibrowser/browser/net/network_delegate.h" +#include "minibrowser/common/content_client.h" +#include "net/base/cache_type.h" +#include "net/cert/cert_verifier.h" +#include "net/cookies/cookie_monster.h" +#include "net/dns/host_resolver.h" +#include "net/dns/mapped_host_resolver.h" +#include "net/http/http_auth_handler_factory.h" +#include "net/http/http_cache.h" +#include "net/http/http_network_session.h" +#include "net/http/http_server_properties_impl.h" +#include "net/http/transport_security_state.h" +#include "net/proxy/proxy_service.h" +#include "net/ssl/channel_id_service.h" +#include "net/ssl/default_channel_id_store.h" +#include "net/ssl/ssl_config_service_defaults.h" +#include "net/url_request/data_protocol_handler.h" +#include "net/url_request/file_protocol_handler.h" +#include "net/url_request/static_http_user_agent_settings.h" +#include "net/url_request/url_request_context.h" +#include "net/url_request/url_request_context_storage.h" +#include "net/url_request/url_request_intercepting_job_factory.h" +#include "net/url_request/url_request_job_factory_impl.h" +#include "url/url_constants.h" + +namespace { + +void InstallProtocolHandlers(net::URLRequestJobFactoryImpl* job_factory, + content::ProtocolHandlerMap* protocol_handlers) { + for (content::ProtocolHandlerMap::iterator it = + protocol_handlers->begin(); + it != protocol_handlers->end(); + ++it) { + bool set_protocol = job_factory->SetProtocolHandler( + it->first, it->second.release()); + DCHECK(set_protocol); + } + protocol_handlers->clear(); +} + +} // namespace + +MiniBrowserURLRequestContextGetter::MiniBrowserURLRequestContextGetter( + bool ignore_certificate_errors, + const base::FilePath& base_path, + base::MessageLoop* io_loop, + base::MessageLoop* file_loop, + content::ProtocolHandlerMap* protocol_handlers, + content::URLRequestInterceptorScopedVector request_interceptors) + : ignore_certificate_errors_(ignore_certificate_errors), + base_path_(base_path), + io_loop_(io_loop), + file_loop_(file_loop), + request_interceptors_(request_interceptors.Pass()) { + // Must first be created on the UI thread. + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + + std::swap(protocol_handlers_, *protocol_handlers); + + // We must create the proxy config service on the UI loop on Linux because it + // must synchronously run on the glib message loop. This will be passed to + // the URLRequestContextStorage on the IO thread in GetURLRequestContext(). + proxy_config_service_.reset(GetProxyConfigService()); +} + +MiniBrowserURLRequestContextGetter::~MiniBrowserURLRequestContextGetter() { +} + +net::NetworkDelegate* MiniBrowserURLRequestContextGetter::CreateNetworkDelegate() { + return new MiniBrowserNetworkDelegate; +} + +net::ProxyConfigService* MiniBrowserURLRequestContextGetter::GetProxyConfigService() { + return net::ProxyService::CreateSystemProxyConfigService( + io_loop_->message_loop_proxy(), file_loop_->message_loop_proxy()); +} + +net::ProxyService* MiniBrowserURLRequestContextGetter::GetProxyService() { + // TODO(jam): use v8 if possible, look at chrome code. + return net::ProxyService::CreateUsingSystemProxyResolver( + proxy_config_service_.release(), 0, /*url_request_context_->net_log()*/ NULL); +} + +net::URLRequestContext* MiniBrowserURLRequestContextGetter::GetURLRequestContext() { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); + + if (!url_request_context_) { + const base::CommandLine& command_line = + *base::CommandLine::ForCurrentProcess(); + + url_request_context_.reset(new net::URLRequestContext()); + network_delegate_.reset(CreateNetworkDelegate()); + url_request_context_->set_network_delegate(network_delegate_.get()); + storage_.reset( + new net::URLRequestContextStorage(url_request_context_.get())); + storage_->set_cookie_store(content::CreateCookieStore(content::CookieStoreConfig())); + storage_->set_channel_id_service(make_scoped_ptr( + new net::ChannelIDService(new net::DefaultChannelIDStore(NULL), + base::WorkerPool::GetTaskRunner(true)))); + storage_->set_http_user_agent_settings( + new net::StaticHttpUserAgentSettings( + "en-us,en", GetMiniBrowserUserAgent())); + + scoped_ptr host_resolver( + net::HostResolver::CreateDefaultResolver( + /*url_request_context_->net_log()*/ NULL)); + + storage_->set_cert_verifier(net::CertVerifier::CreateDefault()); + storage_->set_transport_security_state(new net::TransportSecurityState); + storage_->set_proxy_service(GetProxyService()); + storage_->set_ssl_config_service(new net::SSLConfigServiceDefaults); + storage_->set_http_auth_handler_factory( + net::HttpAuthHandlerFactory::CreateDefault(host_resolver.get())); + storage_->set_http_server_properties( + scoped_ptr( + new net::HttpServerPropertiesImpl())); + + base::FilePath cache_path = base_path_.Append(FILE_PATH_LITERAL("Cache")); + net::HttpCache::DefaultBackend* main_backend = + new net::HttpCache::DefaultBackend( + net::DISK_CACHE, + net::CACHE_BACKEND_DEFAULT, + cache_path, + 0, + content::BrowserThread::GetMessageLoopProxyForThread(content::BrowserThread::CACHE)); + + net::HttpNetworkSession::Params network_session_params; + network_session_params.cert_verifier = + url_request_context_->cert_verifier(); + network_session_params.transport_security_state = + url_request_context_->transport_security_state(); + network_session_params.channel_id_service = + url_request_context_->channel_id_service(); + network_session_params.proxy_service = + url_request_context_->proxy_service(); + network_session_params.ssl_config_service = + url_request_context_->ssl_config_service(); + network_session_params.http_auth_handler_factory = + url_request_context_->http_auth_handler_factory(); + network_session_params.network_delegate = + network_delegate_.get(); + network_session_params.http_server_properties = + url_request_context_->http_server_properties(); + /*network_session_params.net_log = + url_request_context_->net_log();*/ + network_session_params.ignore_certificate_errors = + ignore_certificate_errors_; + if (command_line.HasSwitch(switches::kTestingFixedHttpPort)) { + int value; + base::StringToInt(command_line.GetSwitchValueASCII( + switches::kTestingFixedHttpPort), &value); + network_session_params.testing_fixed_http_port = value; + } + if (command_line.HasSwitch(switches::kTestingFixedHttpsPort)) { + int value; + base::StringToInt(command_line.GetSwitchValueASCII( + switches::kTestingFixedHttpsPort), &value); + network_session_params.testing_fixed_https_port = value; + } + if (command_line.HasSwitch(switches::kHostResolverRules)) { + scoped_ptr mapped_host_resolver( + new net::MappedHostResolver(host_resolver.Pass())); + mapped_host_resolver->SetRulesFromString( + command_line.GetSwitchValueASCII(switches::kHostResolverRules)); + host_resolver = mapped_host_resolver.Pass(); + } + + // Give |storage_| ownership at the end in case it's |mapped_host_resolver|. + storage_->set_host_resolver(host_resolver.Pass()); + network_session_params.host_resolver = + url_request_context_->host_resolver(); + + net::HttpCache* main_cache = new net::HttpCache( + network_session_params, main_backend); + storage_->set_http_transaction_factory(main_cache); + + scoped_ptr job_factory( + new net::URLRequestJobFactoryImpl()); + // Keep ProtocolHandlers added in sync with + // ShellContentBrowserClient::IsHandledURL(). + InstallProtocolHandlers(job_factory.get(), &protocol_handlers_); + bool set_protocol = job_factory->SetProtocolHandler( + url::kDataScheme, new net::DataProtocolHandler); + DCHECK(set_protocol); +#if !defined(DISABLE_FILE_SUPPORT) + set_protocol = job_factory->SetProtocolHandler( + url::kFileScheme, + new net::FileProtocolHandler( + content::BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior( + base::SequencedWorkerPool::SKIP_ON_SHUTDOWN))); + DCHECK(set_protocol); +#endif + + // Set up interceptors in the reverse order. + scoped_ptr top_job_factory = + job_factory.Pass(); + for (content::URLRequestInterceptorScopedVector::reverse_iterator i = + request_interceptors_.rbegin(); + i != request_interceptors_.rend(); + ++i) { + top_job_factory.reset(new net::URLRequestInterceptingJobFactory( + top_job_factory.Pass(), make_scoped_ptr(*i))); + } + request_interceptors_.weak_clear(); + + storage_->set_job_factory(top_job_factory.release()); + } + + return url_request_context_.get(); +} + +scoped_refptr + MiniBrowserURLRequestContextGetter::GetNetworkTaskRunner() const { + return content::BrowserThread::GetMessageLoopProxyForThread(content::BrowserThread::IO); +} + +net::HostResolver* MiniBrowserURLRequestContextGetter::host_resolver() { + return url_request_context_->host_resolver(); +} diff --git a/browser/net/url_request_context_getter.h b/browser/net/url_request_context_getter.h new file mode 100644 index 0000000..73028b7 --- /dev/null +++ b/browser/net/url_request_context_getter.h @@ -0,0 +1,75 @@ +// Copyright (c) 2015 University of Szeged. +// Copyright (c) 2015 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. + +#ifndef MINI_BROWSER_BROWSER_NET_URL_REQUEST_CONTEXT_GETTER_H_ +#define MINI_BROWSER_BROWSER_NET_URL_REQUEST_CONTEXT_GETTER_H_ + +#include "base/compiler_specific.h" +#include "base/files/file_path.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "content/public/browser/content_browser_client.h" +#include "net/proxy/proxy_config_service.h" +#include "net/url_request/url_request_context_getter.h" +#include "net/url_request/url_request_job_factory.h" + +namespace base { +class MessageLoop; +} + +namespace net { +class HostResolver; +class MappedHostResolver; +class NetworkDelegate; +class NetLog; +class ProxyConfigService; +class ProxyService; +class URLRequestContextStorage; +} + +class MiniBrowserURLRequestContextGetter : public net::URLRequestContextGetter { + public: + MiniBrowserURLRequestContextGetter( + bool ignore_certificate_errors, + const base::FilePath& base_path, + base::MessageLoop* io_loop, + base::MessageLoop* file_loop, + content::ProtocolHandlerMap* protocol_handlers, + content::URLRequestInterceptorScopedVector request_interceptors); + + // net::URLRequestContextGetter implementation. + net::URLRequestContext* GetURLRequestContext() override; + scoped_refptr GetNetworkTaskRunner() + const override; + + net::HostResolver* host_resolver(); + + protected: + ~MiniBrowserURLRequestContextGetter() override; + + // Used by subclasses to create their own implementation of NetworkDelegate + // and net::ProxyService. + virtual net::NetworkDelegate* CreateNetworkDelegate(); + virtual net::ProxyConfigService* GetProxyConfigService(); + virtual net::ProxyService* GetProxyService(); + + private: + bool ignore_certificate_errors_; + base::FilePath base_path_; + base::MessageLoop* io_loop_; + base::MessageLoop* file_loop_; + + scoped_ptr proxy_config_service_; + scoped_ptr network_delegate_; + scoped_ptr storage_; + scoped_ptr url_request_context_; + content::ProtocolHandlerMap protocol_handlers_; + content::URLRequestInterceptorScopedVector request_interceptors_; + + DISALLOW_COPY_AND_ASSIGN(MiniBrowserURLRequestContextGetter); +}; + +#endif // MINI_BROWSER_BROWSER_NET_URL_REQUEST_CONTEXT_GETTER_H_ diff --git a/browser/ui/context_menu_model.cc b/browser/ui/context_menu_model.cc new file mode 100644 index 0000000..8fb5dab --- /dev/null +++ b/browser/ui/context_menu_model.cc @@ -0,0 +1,61 @@ +// Copyright (c) 2015 University of Szeged. +// Copyright (c) 2015 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 "minibrowser/browser/ui/context_menu_model.h" + +#include "base/strings/utf_string_conversions.h" +#include "ui/base/accelerators/accelerator.h" + +MiniBrowserContextMenuModel::MiniBrowserContextMenuModel( + MiniBrowser* minibrowser, + const content::ContextMenuParams& params) + : ui::SimpleMenuModel(this), + minibrowser_(minibrowser), + params_(params) + { + AddItem(COMMAND_BACK, base::ASCIIToUTF16("Back")); + AddItem(COMMAND_FORWARD, base::ASCIIToUTF16("Forward")); + AddItem(COMMAND_RELOAD, base::ASCIIToUTF16("Reload")); +} + +bool MiniBrowserContextMenuModel::IsCommandIdChecked( + int command_id) const { + return false; +} + +bool MiniBrowserContextMenuModel::IsCommandIdEnabled( + int command_id) const { + switch (command_id) { + case COMMAND_BACK: + return minibrowser_->CanGoBack(); + case COMMAND_FORWARD: + return minibrowser_->CanGoForward(); + case COMMAND_RELOAD: + return true; + }; + return false; +} + +bool MiniBrowserContextMenuModel::GetAcceleratorForCommandId( + int command_id, + ui::Accelerator* accel) { + return false; +} + +void MiniBrowserContextMenuModel::ExecuteCommand( + int command_id, int event_flags) { + switch (command_id) { + case COMMAND_BACK: + minibrowser_->GoBackOrForward(-1); + break; + case COMMAND_FORWARD: + minibrowser_->GoBackOrForward(1); + break; + case COMMAND_RELOAD: + minibrowser_->Reload(); + break; + }; +} \ No newline at end of file diff --git a/browser/ui/context_menu_model.h b/browser/ui/context_menu_model.h new file mode 100644 index 0000000..7957667 --- /dev/null +++ b/browser/ui/context_menu_model.h @@ -0,0 +1,42 @@ +// Copyright (c) 2015 University of Szeged. +// Copyright (c) 2015 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. + +#ifndef MINI_BROWSER_BROWSER_UI_CONTEXT_MENU_MODEL_H_ +#define MINI_BROWSER_BROWSER_UI_CONTEXT_MENU_MODEL_H_ + +#include "minibrowser/browser/ui/minibrowser.h" + +#include "content/public/common/context_menu_params.h" +#include "ui/base/models/simple_menu_model.h" + +class MiniBrowserContextMenuModel : public ui::SimpleMenuModel, + public ui::SimpleMenuModel::Delegate { +public: + explicit MiniBrowserContextMenuModel( + MiniBrowser* minibrowser, + const content::ContextMenuParams& params); + + // ui::SimpleMenuModel::Delegate: + bool IsCommandIdChecked(int command_id) const override; + bool IsCommandIdEnabled(int command_id) const override; + bool GetAcceleratorForCommandId(int command_id, + ui::Accelerator* accelerator) override; + void ExecuteCommand(int command_id, int event_flags) override; + +private: + enum CommandID { + COMMAND_BACK, + COMMAND_FORWARD, + COMMAND_RELOAD + }; + + MiniBrowser* minibrowser_; + content::ContextMenuParams params_; + + DISALLOW_COPY_AND_ASSIGN(MiniBrowserContextMenuModel); +}; + +#endif // MINI_BROWSER_BROWSER_UI_CONTEXT_MENU_MODEL_H_ \ No newline at end of file diff --git a/browser/ui/minibrowser.cc b/browser/ui/minibrowser.cc new file mode 100644 index 0000000..e1d5efb --- /dev/null +++ b/browser/ui/minibrowser.cc @@ -0,0 +1,216 @@ +// Copyright (c) 2015 University of Szeged. +// Copyright (c) 2015 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 "minibrowser/browser/ui/minibrowser.h" + +#include "base/auto_reset.h" +#include "base/message_loop/message_loop.h" +#include "content/public/browser/navigation_controller.h" +#include "content/public/browser/navigation_entry.h" +#include "content/public/browser/render_view_host.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_observer.h" +#include "content/public/common/renderer_preferences.h" +#include "minibrowser/browser/browser_main_parts.h" +#include "minibrowser/browser/content_browser_client.h" + +const int kDefaultTestWindowWidthDip = 800; +const int kDefaultTestWindowHeightDip = 600; + +std::vector MiniBrowser::windows_; +bool MiniBrowser::quit_message_loop_ = true; + +MiniBrowser::MiniBrowser(content::WebContents* web_contents) + : WebContentsObserver(web_contents), + window_(NULL) { + windows_.push_back(this); +} + +MiniBrowser::~MiniBrowser() { + PlatformCleanUp(); + + for (size_t i = 0; i < windows_.size(); ++i) { + if (windows_[i] == this) { + windows_.erase(windows_.begin() + i); + break; + } + } + + if (windows_.empty() && quit_message_loop_) { + base::MessageLoop::current()->PostTask(FROM_HERE, + base::MessageLoop::QuitClosure()); + } +} + +// static +MiniBrowser* MiniBrowser::CreateMiniBrowser(content::WebContents* web_contents, + const gfx::Size& initial_size) { + MiniBrowser* minibrowser = new MiniBrowser(web_contents); + minibrowser->PlatformCreateWindow(initial_size.width(), initial_size.height()); + + minibrowser->web_contents_.reset(web_contents); + web_contents->SetDelegate(minibrowser); + + minibrowser->PlatformSetContents(); + + minibrowser->PlatformResizeSubViews(); + + return minibrowser; +} + +// static +void MiniBrowser::Initialize() { + PlatformInitialize(GetMiniBrowserDefaultSize()); +} + +// static +gfx::Size MiniBrowser::AdjustWindowSize(const gfx::Size& initial_size) { + if (!initial_size.IsEmpty()) + return initial_size; + return GetMiniBrowserDefaultSize(); +} + +// static +MiniBrowser* MiniBrowser::CreateNewWindow(content::BrowserContext* browser_context, + const GURL& url, + content::SiteInstance* site_instance, + const gfx::Size& initial_size) { + content::WebContents::CreateParams create_params(browser_context, site_instance); + create_params.initial_size = AdjustWindowSize(initial_size); + content::WebContents* web_contents = content::WebContents::Create(create_params); + MiniBrowser* minibrowser = CreateMiniBrowser(web_contents, create_params.initial_size); + if (!url.is_empty()) + minibrowser->LoadURL(url); + return minibrowser; +} + +void MiniBrowser::LoadURL(const GURL& url) { + //LoadURLForFrame(url, std::string()); + content::NavigationController::LoadURLParams params(url); + params.transition_type = ui::PageTransitionFromInt( + ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR); + web_contents_->GetController().LoadURLWithParams(params); + web_contents_->Focus(); +} + +void MiniBrowser::AddNewContents(content::WebContents* source, + content::WebContents* new_contents, + WindowOpenDisposition disposition, + const gfx::Rect& initial_rect, + bool user_gesture, + bool* was_blocked) { + CreateMiniBrowser(new_contents, AdjustWindowSize(initial_rect.size())); +} + +bool MiniBrowser::CanGoBack() { + return web_contents_->GetController().CanGoBack(); +} + +bool MiniBrowser::CanGoForward() { + return web_contents_->GetController().CanGoForward(); +} + +void MiniBrowser::GoBackOrForward(int offset) { + web_contents_->GetController().GoToOffset(offset); + web_contents_->Focus(); +} + +void MiniBrowser::Reload() { + web_contents_->GetController().Reload(false); + web_contents_->Focus(); +} + +void MiniBrowser::Stop() { + web_contents_->Stop(); + web_contents_->Focus(); +} + +void MiniBrowser::UpdateNavigationControls(bool to_different_document) { + PlatformEnableUIControl(BACK_BUTTON, CanGoBack()); + PlatformEnableUIControl(FORWARD_BUTTON, CanGoForward()); + PlatformEnableUIControl(STOP_BUTTON, + to_different_document && web_contents_->IsLoading()); +} + +gfx::NativeView MiniBrowser::GetContentView() { + if (!web_contents_) + return NULL; + return web_contents_->GetNativeView(); +} + +content::WebContents* MiniBrowser::OpenURLFromTab(content::WebContents* source, + const content::OpenURLParams& params) { + // CURRENT_TAB is the only one we implement for now. + if (params.disposition != CURRENT_TAB) + return NULL; + content::NavigationController::LoadURLParams load_url_params(params.url); + load_url_params.source_site_instance = params.source_site_instance; + load_url_params.referrer = params.referrer; + load_url_params.frame_tree_node_id = params.frame_tree_node_id; + load_url_params.transition_type = params.transition; + load_url_params.extra_headers = params.extra_headers; + load_url_params.should_replace_current_entry = + params.should_replace_current_entry; + + load_url_params.is_renderer_initiated = params.is_renderer_initiated; + if (params.transferred_global_request_id != content::GlobalRequestID()) { + load_url_params.transferred_global_request_id = + params.transferred_global_request_id; + } + + source->GetController().LoadURLWithParams(load_url_params); + return source; +} + +void MiniBrowser::LoadingStateChanged(content::WebContents* source, + bool to_different_document) { + UpdateNavigationControls(to_different_document); + PlatformSetIsLoading(source->IsLoading()); +} + +void MiniBrowser::CloseContents(content::WebContents* source) { + Close(); +} + +bool MiniBrowser::CanOverscrollContent() const { + return true; +} + +void MiniBrowser::DidNavigateMainFramePostCommit(content::WebContents* web_contents) { + PlatformSetAddressBarURL(web_contents->GetLastCommittedURL()); +} + +void MiniBrowser::ActivateContents(content::WebContents* contents) { + contents->GetRenderViewHost()->Focus(); +} + +void MiniBrowser::DeactivateContents(content::WebContents* contents) { + contents->GetRenderViewHost()->Blur(); +} + +bool MiniBrowser::HandleContextMenu(const content::ContextMenuParams& params) { + return PlatformHandleContextMenu(params); +} + +void MiniBrowser::WebContentsFocused(content::WebContents* contents) { + PlatformWebContentsFocused(contents); +} + +gfx::Size MiniBrowser::GetMiniBrowserDefaultSize() { + static gfx::Size default_minibrowser_size; + if (!default_minibrowser_size.IsEmpty()) + return default_minibrowser_size; + + default_minibrowser_size = gfx::Size( + kDefaultTestWindowWidthDip, kDefaultTestWindowHeightDip); + + return default_minibrowser_size; +} + +void MiniBrowser::TitleWasSet(content::NavigationEntry* entry, bool explicit_set) { + if (entry) + PlatformSetTitle(entry->GetTitle()); +} diff --git a/browser/ui/minibrowser.h b/browser/ui/minibrowser.h new file mode 100644 index 0000000..b7d5c65 --- /dev/null +++ b/browser/ui/minibrowser.h @@ -0,0 +1,143 @@ +// Copyright (c) 2015 University of Szeged. +// Copyright (c) 2015 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. + +#ifndef MINI_BROWSER_BROWSER_UI_MINI_BROWSER_H_ +#define MINI_BROWSER_BROWSER_UI_MINI_BROWSER_H_ + + +#include "base/callback_forward.h" +#include "base/memory/scoped_ptr.h" +#include "content/public/browser/web_contents_delegate.h" +#include "content/public/browser/web_contents_observer.h" +#include "ui/gfx/geometry/size.h" +#include "ui/gfx/native_widget_types.h" + +namespace views { +class Widget; +class ViewsDelegate; +} + +namespace content { +class BrowserContext; +class SiteInstance; +class WebContents; +} + +class GURL; +class MiniBrowserPlatformDataAura; + +// This represents one window of the MiniBrowser, i.e. all the UI including +// buttons and url bar, as well as the web content area. + +class MiniBrowser : public content::WebContentsDelegate, + public content::WebContentsObserver { + +public: + + ~MiniBrowser() override; + + void LoadURL(const GURL& url); + bool CanGoBack(); + bool CanGoForward(); + void GoBackOrForward(int offset); + void Reload(); + void Stop(); + void UpdateNavigationControls(bool to_different_document); + void Close(); + + static void Initialize(); + static MiniBrowser* CreateNewWindow(content::BrowserContext* browser_context, + const GURL& url, + content::SiteInstance* site_instance, + const gfx::Size& initial_size); + + static std::vector& windows() { return windows_; } + content::WebContents* web_contents() const { return web_contents_.get(); } + gfx::NativeWindow window() { return window_; } + + // content::WebContentsDelegate overrides. + content::WebContents* OpenURLFromTab( + content::WebContents* source, + const content::OpenURLParams& params) override; + void AddNewContents(content::WebContents* source, + content::WebContents* new_contents, + WindowOpenDisposition disposition, + const gfx::Rect& initial_rect, + bool user_gesture, + bool* was_blocked) override; + void LoadingStateChanged(content::WebContents* source, + bool to_different_document) override; + void CloseContents(content::WebContents* source) override; + bool CanOverscrollContent() const override; + void DidNavigateMainFramePostCommit(content::WebContents* web_contents) override; + void ActivateContents(content::WebContents* contents) override; + void DeactivateContents(content::WebContents* contents) override; + bool HandleContextMenu(const content::ContextMenuParams& params) override; + void WebContentsFocused(content::WebContents* contents) override; + + static gfx::Size GetMiniBrowserDefaultSize(); +private: + enum UIControl { + BACK_BUTTON, + FORWARD_BUTTON, + STOP_BUTTON + }; + + explicit MiniBrowser(content::WebContents* web_contents); + + static MiniBrowser* CreateMiniBrowser(content::WebContents* web_contents, + const gfx::Size& initial_size); + // Helper for one time initialization of application + static void PlatformInitialize(const gfx::Size& default_window_size); + // Helper for one time deinitialization of platform specific state. + static void PlatformExit(); + + static gfx::Size AdjustWindowSize(const gfx::Size& initial_size); + + // All the methods that begin with Platform need to be implemented by the + // platform specific MiniBrowser implementation. + // Called from the destructor to let each platform do any necessary cleanup. + void PlatformCleanUp(); + // Creates the main window GUI. + void PlatformCreateWindow(int width, int height); + // Links the WebContents into the newly created window. + void PlatformSetContents(); + // Resize the content area and GUI. + void PlatformResizeSubViews(); + // Enable/disable a button. + void PlatformEnableUIControl(UIControl control, bool is_enabled); + // Updates the url in the url bar. + void PlatformSetAddressBarURL(const GURL& url); + // Sets whether the spinner is spinning. + void PlatformSetIsLoading(bool loading); + // Set the title of window + void PlatformSetTitle(const base::string16& title); + // User right-clicked on the web view + bool PlatformHandleContextMenu(const content::ContextMenuParams& params); + + void PlatformWebContentsFocused(content::WebContents* contents); + + gfx::NativeView GetContentView(); + + // content::WebContentsObserver overrides. + void TitleWasSet(content::NavigationEntry* entry, bool explicit_set) override; + + scoped_ptr web_contents_; + + gfx::NativeWindow window_; + gfx::Size content_size_; + + static views::ViewsDelegate* views_delegate_; + views::Widget* window_widget_; + + static std::vector windows_; + + // True if the destructur of MiniBrowser should post a quit closure on the current + // message loop if the destructed MiniBrowser object was the last one. + static bool quit_message_loop_; +}; + +#endif // MINI_BROWSER_BROWSER_UI_MINI_BROWSER_H_ \ No newline at end of file diff --git a/browser/ui/minibrowser_views.cc b/browser/ui/minibrowser_views.cc new file mode 100644 index 0000000..e70b2ce --- /dev/null +++ b/browser/ui/minibrowser_views.cc @@ -0,0 +1,441 @@ +// Copyright (c) 2015 University of Szeged. +// Copyright (c) 2015 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 "minibrowser/browser/ui/minibrowser.h" + +#include "base/command_line.h" +#include "base/strings/utf_string_conversions.h" +#include "content/public/browser/context_factory.h" +#include "content/public/browser/render_widget_host_view.h" +#include "content/public/browser/web_contents.h" +#include "content/public/common/context_menu_params.h" +#include "minibrowser/browser/ui/context_menu_model.h" +#include "ui/aura/window_tree_host.h" +#include "ui/aura/client/screen_position_client.h" +#include "ui/aura/env.h" +#include "ui/aura/window.h" +#include "ui/aura/window_event_dispatcher.h" +#include "ui/base/clipboard/clipboard.h" +#include "ui/base/models/simple_menu_model.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/events/event.h" +#include "ui/gfx/screen.h" +#include "ui/views/background.h" +#include "ui/views/controls/button/label_button.h" +#include "ui/views/controls/button/menu_button.h" +#include "ui/views/controls/button/menu_button_listener.h" +#include "ui/views/controls/menu/menu_runner.h" +#include "ui/views/controls/textfield/textfield.h" +#include "ui/views/controls/textfield/textfield_controller.h" +#include "ui/views/controls/webview/webview.h" +#include "ui/views/layout/fill_layout.h" +#include "ui/views/layout/grid_layout.h" +#include "ui/views/test/desktop_test_views_delegate.h" +#include "ui/views/view.h" +#include "ui/views/widget/widget.h" +#include "ui/views/widget/widget_delegate.h" +#include "ui/views/widget/desktop_aura/desktop_screen.h" + +namespace { +// ViewDelegate implementation for aura minibrowser +class MiniBrowserViewsDelegateAura : public views::DesktopTestViewsDelegate { +public: + MiniBrowserViewsDelegateAura() : use_transparent_windows_(false) { + } + + ~MiniBrowserViewsDelegateAura() override {} + + void SetUseTransparentWindows(bool transparent) { + use_transparent_windows_ = transparent; + } + +private: + bool use_transparent_windows_; + + DISALLOW_COPY_AND_ASSIGN(MiniBrowserViewsDelegateAura); +}; + +// Maintain the UI controls and web view for minibrowser +class MiniBrowserWindowDelegateView : public views::WidgetDelegateView, + public views::TextfieldController, + public views::ButtonListener { +public: + enum UIControl { + BACK_BUTTON, + FORWARD_BUTTON, + STOP_BUTTON + }; + + MiniBrowserWindowDelegateView(MiniBrowser* minibrowser) + : minibrowser_(minibrowser), + toolbar_view_(new View), + contents_view_(new View) { + } + ~MiniBrowserWindowDelegateView() override {} + + // Update the state of UI controls + void SetAddressBarURL(const GURL& url) { + url_entry_->SetText(base::ASCIIToUTF16(url.spec())); + } + void SetWebContents(content::WebContents* web_contents, const gfx::Size& size) { + contents_view_->SetLayoutManager(new views::FillLayout()); + web_view_ = new views::WebView(web_contents->GetBrowserContext()); + web_view_->SetWebContents(web_contents); + web_view_->SetPreferredSize(size); + web_contents->Focus(); + contents_view_->AddChildView(web_view_); + Layout(); + + // Resize the widget, keeping the same origin. + gfx::Rect bounds = GetWidget()->GetWindowBoundsInScreen(); + bounds.set_size(GetWidget()->GetRootView()->GetPreferredSize()); + GetWidget()->SetBounds(bounds); + } + + void SetWindowTitle(const base::string16& title) { title_ = title; } + void EnableUIControl(UIControl control, bool is_enabled) { + if (control == BACK_BUTTON) { + back_button_->SetState(is_enabled ? views::CustomButton::STATE_NORMAL + : views::CustomButton::STATE_DISABLED); + } else if (control == FORWARD_BUTTON) { + forward_button_->SetState(is_enabled ? views::CustomButton::STATE_NORMAL + : views::CustomButton::STATE_DISABLED); + } else if (control == STOP_BUTTON) { + stop_button_->SetState(is_enabled ? views::CustomButton::STATE_NORMAL + : views::CustomButton::STATE_DISABLED); + } + } + + void ShowWebViewContextMenu(const content::ContextMenuParams& params) { + gfx::Point screen_point(params.x, params.y); + + // Convert from content coordinates to window coordinates. + // This code copied from chrome_web_contents_view_delegate_views.cc + aura::Window* web_contents_window = + minibrowser_->web_contents()->GetNativeView(); + aura::Window* root_window = web_contents_window->GetRootWindow(); + aura::client::ScreenPositionClient* screen_position_client = + aura::client::GetScreenPositionClient(root_window); + if (screen_position_client) { + screen_position_client->ConvertPointToScreen(web_contents_window, + &screen_point); + } + + context_menu_model_.reset(new MiniBrowserContextMenuModel(minibrowser_, params)); + context_menu_runner_.reset(new views::MenuRunner( + context_menu_model_.get(), views::MenuRunner::CONTEXT_MENU)); + + if (context_menu_runner_->RunMenuAt(web_view_->GetWidget(), + NULL, + gfx::Rect(screen_point, gfx::Size()), + views::MENU_ANCHOR_TOPRIGHT, + ui::MENU_SOURCE_NONE) == + views::MenuRunner::MENU_DELETED) { + return; + } + } + + void OnWebContentsFocused(content::WebContents* web_contents) { + if (web_view_->GetWebContents() == web_contents) + web_view_->OnWebContentsFocused(web_contents); + } + +private: + // Initialize the UI control contained in minibrowser window + void InitMiniBrowserWindow() { + set_background(views::Background::CreateStandardPanelBackground()); + + views::GridLayout* layout = new views::GridLayout(this); + SetLayoutManager(layout); + + views::ColumnSet* column_set = layout->AddColumnSet(0); + column_set->AddPaddingColumn(0, 2); + column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1, + views::GridLayout::USE_PREF, 0, 0); + column_set->AddPaddingColumn(0, 2); + + layout->AddPaddingRow(0, 2); + + // Add toolbar buttons and URL text field + { + layout->StartRow(0, 0); + views::GridLayout* toolbar_layout = new views::GridLayout(toolbar_view_); + toolbar_view_->SetLayoutManager(toolbar_layout); + + views::ColumnSet* toolbar_column_set = + toolbar_layout->AddColumnSet(0); + // Back button + back_button_ = new views::LabelButton(this, base::ASCIIToUTF16("Back")); + back_button_->SetStyle(views::Button::STYLE_BUTTON); + gfx::Size back_button_size = back_button_->GetPreferredSize(); + toolbar_column_set->AddColumn(views::GridLayout::CENTER, + views::GridLayout::CENTER, 0, + views::GridLayout::FIXED, + back_button_size.width(), + back_button_size.width() / 2); + // Forward button + forward_button_ = + new views::LabelButton(this, base::ASCIIToUTF16("Forward")); + forward_button_->SetStyle(views::Button::STYLE_BUTTON); + gfx::Size forward_button_size = forward_button_->GetPreferredSize(); + toolbar_column_set->AddColumn(views::GridLayout::CENTER, + views::GridLayout::CENTER, 0, + views::GridLayout::FIXED, + forward_button_size.width(), + forward_button_size.width() / 2); + // Refresh button + refresh_button_ = + new views::LabelButton(this, base::ASCIIToUTF16("Refresh")); + refresh_button_->SetStyle(views::Button::STYLE_BUTTON); + gfx::Size refresh_button_size = refresh_button_->GetPreferredSize(); + toolbar_column_set->AddColumn(views::GridLayout::CENTER, + views::GridLayout::CENTER, 0, + views::GridLayout::FIXED, + refresh_button_size.width(), + refresh_button_size.width() / 2); + // Stop button + stop_button_ = new views::LabelButton(this, base::ASCIIToUTF16("Stop")); + stop_button_->SetStyle(views::Button::STYLE_BUTTON); + gfx::Size stop_button_size = stop_button_->GetPreferredSize(); + toolbar_column_set->AddColumn(views::GridLayout::CENTER, + views::GridLayout::CENTER, 0, + views::GridLayout::FIXED, + stop_button_size.width(), + stop_button_size.width() / 2); + toolbar_column_set->AddPaddingColumn(0, 2); + // URL entry + url_entry_ = new views::Textfield(); + url_entry_->set_controller(this); + toolbar_column_set->AddColumn(views::GridLayout::FILL, + views::GridLayout::FILL, 1, + views::GridLayout::USE_PREF, 0, 0); + toolbar_column_set->AddPaddingColumn(0, 2); + + // Fill up the first row + toolbar_layout->StartRow(0, 0); + toolbar_layout->AddView(back_button_); + toolbar_layout->AddView(forward_button_); + toolbar_layout->AddView(refresh_button_); + toolbar_layout->AddView(stop_button_); + toolbar_layout->AddView(url_entry_); + + layout->AddView(toolbar_view_); + } + + layout->AddPaddingRow(0, 5); + + // Add web contents view as the second row + { + layout->StartRow(1, 0); + layout->AddView(contents_view_); + } + + layout->AddPaddingRow(0, 5); + + InitAccelerators(); + } + void InitAccelerators() { + static const ui::KeyboardCode keys[] = { ui::VKEY_F5, + ui::VKEY_BROWSER_BACK, + ui::VKEY_BROWSER_FORWARD }; + for (size_t i = 0; i < arraysize(keys); ++i) { + GetFocusManager()->RegisterAccelerator( + ui::Accelerator(keys[i], ui::EF_NONE), + ui::AcceleratorManager::kNormalPriority, + this); + } + } + // Overridden from TextfieldController + void ContentsChanged(views::Textfield* sender, + const base::string16& new_contents) override {} + bool HandleKeyEvent(views::Textfield* sender, + const ui::KeyEvent& key_event) override { + if (sender == url_entry_ && key_event.key_code() == ui::VKEY_RETURN) { + std::string text = base::UTF16ToUTF8(url_entry_->text()); + GURL url(text); + if (!url.has_scheme()) { + url = GURL(std::string("http://") + std::string(text)); + url_entry_->SetText(base::ASCIIToUTF16(url.spec())); + } + minibrowser_->LoadURL(url); + return true; + } + return false; + } + + // Overridden from ButtonListener + void ButtonPressed(views::Button* sender, const ui::Event& event) override { + if (sender == back_button_) + minibrowser_->GoBackOrForward(-1); + else if (sender == forward_button_) + minibrowser_->GoBackOrForward(1); + else if (sender == refresh_button_) + minibrowser_->Reload(); + else if (sender == stop_button_) + minibrowser_->Stop(); + } + + // Overridden from WidgetDelegateView + bool CanResize() const override { return true; } + bool CanMaximize() const override { return true; } + bool CanMinimize() const override { return true; } + base::string16 GetWindowTitle() const override { return title_; } + void WindowClosing() override { + if (minibrowser_) { + delete minibrowser_; + minibrowser_ = NULL; + } + } + View* GetContentsView() override { return this; } + + // Overridden from View + gfx::Size GetMinimumSize() const override { + // We want to be able to make the window smaller than its initial + // (preferred) size. + return gfx::Size(); + } + void ViewHierarchyChanged( + const ViewHierarchyChangedDetails& details) override { + if (details.is_add && details.child == this) { + InitMiniBrowserWindow(); + } + } + + // Overridden from AcceleratorTarget: + bool AcceleratorPressed(const ui::Accelerator& accelerator) override { + switch (accelerator.key_code()) { + case ui::VKEY_F5: + minibrowser_->Reload(); + return true; + case ui::VKEY_BROWSER_BACK: + minibrowser_->GoBackOrForward(-1); + return true; + case ui::VKEY_BROWSER_FORWARD: + minibrowser_->GoBackOrForward(1); + return true; + default: + return views::WidgetDelegateView::AcceleratorPressed(accelerator); + } + } + + // Hold a reference of MiniBrowser for deleting it when the window is closing + MiniBrowser* minibrowser_; + + // Window title + base::string16 title_; + + // Toolbar view contains forward/backward/reload button and URL entry + View* toolbar_view_; + views::LabelButton* back_button_; + views::LabelButton* forward_button_; + views::LabelButton* refresh_button_; + views::LabelButton* stop_button_; + views::Textfield* url_entry_; + scoped_ptr context_menu_model_; + scoped_ptr context_menu_runner_; + + // Contents view contains the web contents view + View* contents_view_; + views::WebView* web_view_; + + DISALLOW_COPY_AND_ASSIGN(MiniBrowserWindowDelegateView); +}; + +} // namespace + +views::ViewsDelegate* MiniBrowser::views_delegate_ = NULL; + +// static +void MiniBrowser::PlatformInitialize(const gfx::Size& default_window_size) { + gfx::Screen::SetScreenInstance( + gfx::SCREEN_TYPE_NATIVE, views::CreateDesktopScreen()); + views_delegate_ = new MiniBrowserViewsDelegateAura(); +} + +// static +void MiniBrowser::PlatformExit() { + delete views_delegate_; + views_delegate_ = NULL; + aura::Env::DeleteInstance(); +} + +void MiniBrowser::PlatformCleanUp() { +} + +void MiniBrowser::PlatformEnableUIControl(UIControl control, bool is_enabled) { + MiniBrowserWindowDelegateView* delegate_view = + static_cast(window_widget_->widget_delegate()); + if (control == BACK_BUTTON) { + delegate_view->EnableUIControl(MiniBrowserWindowDelegateView::BACK_BUTTON, + is_enabled); + } else if (control == FORWARD_BUTTON) { + delegate_view->EnableUIControl(MiniBrowserWindowDelegateView::FORWARD_BUTTON, + is_enabled); + } else if (control == STOP_BUTTON) { + delegate_view->EnableUIControl(MiniBrowserWindowDelegateView::STOP_BUTTON, + is_enabled); + } +} + +void MiniBrowser::PlatformSetAddressBarURL(const GURL& url) { + MiniBrowserWindowDelegateView* delegate_view = + static_cast(window_widget_->widget_delegate()); + delegate_view->SetAddressBarURL(url); +} + +void MiniBrowser::PlatformSetIsLoading(bool loading) { +} + +void MiniBrowser::PlatformCreateWindow(int width, int height) { + window_widget_ = new views::Widget; + views::Widget::InitParams params; + params.bounds = gfx::Rect(0, 0, width, height); + params.delegate = new MiniBrowserWindowDelegateView(this); + window_widget_->Init(params); + + content_size_ = gfx::Size(width, height); + + window_ = window_widget_->GetNativeWindow(); + // Call ShowRootWindow on RootWindow created by WMTestHelper without + // which XWindow owned by RootWindow doesn't get mapped. + window_->GetHost()->Show(); + window_widget_->Show(); +} + +void MiniBrowser::PlatformSetContents() { + views::WidgetDelegate* widget_delegate = window_widget_->widget_delegate(); + MiniBrowserWindowDelegateView* delegate_view = + static_cast(widget_delegate); + delegate_view->SetWebContents(web_contents_.get(), content_size_); +} + +void MiniBrowser::PlatformResizeSubViews() { +} + +void MiniBrowser::Close() { + window_widget_->CloseNow(); +} + +void MiniBrowser::PlatformSetTitle(const base::string16& title) { + MiniBrowserWindowDelegateView* delegate_view = + static_cast(window_widget_->widget_delegate()); + delegate_view->SetWindowTitle(title); + window_widget_->UpdateWindowTitle(); +} + +bool MiniBrowser::PlatformHandleContextMenu( + const content::ContextMenuParams& params) { + MiniBrowserWindowDelegateView* delegate_view = + static_cast(window_widget_->widget_delegate()); + delegate_view->ShowWebViewContextMenu(params); + return true; +} + +void MiniBrowser::PlatformWebContentsFocused(content::WebContents* contents) { + MiniBrowserWindowDelegateView* delegate_view = + static_cast(window_widget_->widget_delegate()); + delegate_view->OnWebContentsFocused(contents); +} diff --git a/common/content_client.cc b/common/content_client.cc new file mode 100644 index 0000000..527eec1 --- /dev/null +++ b/common/content_client.cc @@ -0,0 +1,40 @@ +// Copyright (c) 2015 University of Szeged. +// Copyright (c) 2015 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 "minibrowser/common/content_client.h" + +#include "content/public/common/user_agent.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/resource/resource_bundle.h" + +std::string GetMiniBrowserUserAgent() { + std::string product = "MiniBrowser/0.1.0.0"; + return content::BuildUserAgentFromProduct(product); +} + +std::string MiniBrowserContentClient::GetUserAgent() const { + return GetMiniBrowserUserAgent(); +} + +base::string16 MiniBrowserContentClient::GetLocalizedString(int message_id) const { + return l10n_util::GetStringUTF16(message_id); +} + +base::StringPiece MiniBrowserContentClient::GetDataResource( + int resource_id, + ui::ScaleFactor scale_factor) const { + return ResourceBundle::GetSharedInstance().GetRawDataResourceForScale( + resource_id, scale_factor); +} + +base::RefCountedStaticMemory* MiniBrowserContentClient::GetDataResourceBytes( + int resource_id) const { + return ResourceBundle::GetSharedInstance().LoadDataResourceBytes(resource_id); +} + +gfx::Image& MiniBrowserContentClient::GetNativeImageNamed(int resource_id) const { + return ResourceBundle::GetSharedInstance().GetNativeImageNamed(resource_id); +} \ No newline at end of file diff --git a/common/content_client.h b/common/content_client.h new file mode 100644 index 0000000..96ee29d --- /dev/null +++ b/common/content_client.h @@ -0,0 +1,32 @@ +// Copyright (c) 2015 University of Szeged. +// Copyright (c) 2015 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. + +#ifndef MINI_BROWSER_COMMON_CONTENT_CLIENT_H_ +#define MINI_BROWSER_COMMON_CONTENT_CLIENT_H_ + +#include +#include + +#include "content/public/common/content_client.h" + +std::string GetMiniBrowserUserAgent(); + +class MiniBrowserContentClient : public content::ContentClient { + +public: + + std::string GetUserAgent() const override; + base::string16 GetLocalizedString(int message_id) const override; + base::StringPiece GetDataResource( + int resource_id, + ui::ScaleFactor scale_factor) const override; + base::RefCountedStaticMemory* GetDataResourceBytes( + int resource_id) const override; + gfx::Image& GetNativeImageNamed(int resource_id) const override; +}; + + +#endif // MINI_BROWSER_COMMON_CONTENT_CLIENT_H_ \ No newline at end of file diff --git a/minibrowser.gyp b/minibrowser.gyp new file mode 100644 index 0000000..05137e2 --- /dev/null +++ b/minibrowser.gyp @@ -0,0 +1,189 @@ +{ + 'variables': { + 'minibrowser_version': '0.1.0.0', + }, + 'targets': [ + { + 'target_name': 'minibrowser_lib', + 'type': 'static_library', + 'defines': ['MINI_BROWSER_VERSION="<(minibrowser_version)"'], + 'variables': { + 'chromium_code': 1, + }, + 'dependencies': [ + '../content/app/resources/content_resources.gyp:content_resources', + '../content/app/strings/content_strings.gyp:content_strings', + '../content/content.gyp:content_app_both', + '../content/content.gyp:content_browser', + '../content/content.gyp:content_common', + '../content/content.gyp:content_gpu', + '../content/content.gyp:content_plugin', + '../content/content.gyp:content_ppapi_plugin', + '../content/content.gyp:content_renderer', + '../content/content.gyp:content_resources', + '../content/content.gyp:content_utility', + 'minibrowser_resources', + '../base/base.gyp:base', + '../base/base.gyp:base_static', + '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', + '../cc/blink/cc_blink.gyp:cc_blink', + '../cc/cc.gyp:cc', + '../components/components.gyp:crash_component', + '../components/components.gyp:web_cache_renderer', + '../device/bluetooth/bluetooth.gyp:device_bluetooth', + '../gin/gin.gyp:gin', + '../gpu/gpu.gyp:gpu', + '../ipc/ipc.gyp:ipc', + '../media/blink/media_blink.gyp:media_blink', + '../media/media.gyp:media', + '../net/net.gyp:net', + '../net/net.gyp:net_resources', + '../skia/skia.gyp:skia', + '../storage/storage_browser.gyp:storage', + '../third_party/WebKit/public/blink.gyp:blink', + '../third_party/WebKit/public/blink.gyp:blink_test_support', + '../ui/base/ime/ui_base_ime.gyp:ui_base_ime', + '../ui/base/ui_base.gyp:ui_base', + '../ui/events/events.gyp:events_base', + '../ui/gfx/gfx.gyp:gfx', + '../ui/gfx/gfx.gyp:gfx_geometry', + '../ui/gfx/ipc/gfx_ipc.gyp:gfx_ipc', + '../ui/gl/gl.gyp:gl', + '../url/url.gyp:url_lib', + '../v8/tools/gyp/v8.gyp:v8', + '../ui/events/devices/events_devices.gyp:events_devices', + '../tools/xdisplaycheck/xdisplaycheck.gyp:xdisplaycheck', + '../base/allocator/allocator.gyp:allocator', + '../ui/aura/aura.gyp:aura', + '../ui/aura/aura.gyp:aura_test_support', + '../ui/events/events.gyp:events', + '../ui/strings/ui_strings.gyp:ui_strings', + '../ui/wm/wm.gyp:wm', + '../third_party/mojo/mojo_edk.gyp:mojo_system_impl', + '../third_party/mojo/mojo_public.gyp:mojo_application_bindings', + '../third_party/mojo/mojo_public.gyp:mojo_cpp_bindings', + '../ui/resources/ui_resources.gyp:ui_resources', + '../ui/views/controls/webview/webview.gyp:webview', + '../ui/views/views.gyp:views', + '../ui/views/views.gyp:views_test_support', + ], + 'export_dependent_settings' : [ + '../third_party/mojo/mojo_public.gyp:mojo_application_bindings', + '../third_party/mojo/mojo_public.gyp:mojo_cpp_bindings', + ], + 'include_dirs': [ + '..', + ], + 'sources': [ + 'browser/browser_context.cc', + 'browser/browser_context.h', + 'browser/browser_main.cc', + 'browser/browser_main.h', + 'browser/browser_main_parts.cc', + 'browser/browser_main_parts.h', + 'browser/content_browser_client.cc', + 'browser/content_browser_client.h', + 'browser/net/network_delegate.h', + 'browser/net/network_delegate.cc', + 'browser/net/url_request_context_getter.h', + 'browser/net/url_request_context_getter.cc', + 'browser/ui/context_menu_model.cc', + 'browser/ui/context_menu_model.h', + 'browser/ui/minibrowser.cc', + 'browser/ui/minibrowser.h', + 'browser/ui/minibrowser_views.cc', + 'common/content_client.cc', + 'common/content_client.h', + ], + 'cflags': [ + '-g', + ], + }, + { + 'target_name': 'minibrowser_resources', + 'type': 'none', + 'variables': { + 'grit_out_dir': '<(SHARED_INTERMEDIATE_DIR)/minibrowser', + }, + 'actions': [ + { + 'action_name': 'generate_minibrowser_resources', + 'variables': { + 'grit_grd_file': 'minibrowser_resources.grd', + }, + 'includes': [ '../build/grit_action.gypi' ], + }, + ], + 'includes': [ '../build/grit_target.gypi' ], + 'copies': [ + { + 'destination': '<(PRODUCT_DIR)', + 'files': [ + '<(SHARED_INTERMEDIATE_DIR)/minibrowser/minibrowser_resources.pak' + ], + }, + ], + }, + { + # We build a minimal set of resources so WebKit in content_shell has + # access to necessary resources. + 'target_name': 'minibrowser_pak', + 'type': 'none', + 'dependencies': [ + '../content/app/resources/content_resources.gyp:content_resources', + '../content/app/strings/content_strings.gyp:content_strings', + #'browser/tracing/tracing_resources.gyp:tracing_resources', + '../content/content.gyp:content_resources', + 'minibrowser_resources', + '<(DEPTH)/net/net.gyp:net_resources', + '<(DEPTH)/third_party/WebKit/public/blink_resources.gyp:blink_resources', + '<(DEPTH)/ui/resources/ui_resources.gyp:ui_resources', + '<(DEPTH)/ui/strings/ui_strings.gyp:ui_strings', + ], + 'actions': [ + { + 'action_name': 'repack_minibrowser_pack', + 'variables': { + 'pak_inputs': [ + '<(SHARED_INTERMEDIATE_DIR)/blink/public/resources/blink_resources.pak', + '<(SHARED_INTERMEDIATE_DIR)/content/app/resources/content_resources_100_percent.pak', + '<(SHARED_INTERMEDIATE_DIR)/content/app/strings/content_strings_en-US.pak', + '<(SHARED_INTERMEDIATE_DIR)/content/browser/tracing/tracing_resources.pak', + '<(SHARED_INTERMEDIATE_DIR)/content/content_resources.pak', + '<(SHARED_INTERMEDIATE_DIR)/content/shell_resources.pak', + '<(SHARED_INTERMEDIATE_DIR)/net/net_resources.pak', + '<(SHARED_INTERMEDIATE_DIR)/ui/resources/ui_resources_100_percent.pak', + '<(SHARED_INTERMEDIATE_DIR)/ui/resources/webui_resources.pak', + '<(SHARED_INTERMEDIATE_DIR)/ui/strings/app_locale_settings_en-US.pak', + '<(SHARED_INTERMEDIATE_DIR)/ui/strings/ui_strings_en-US.pak', + ], + 'pak_output': '<(PRODUCT_DIR)/minibrowser.pak', + }, + 'includes': [ '../build/repack_action.gypi' ], + }, + ], + }, + { + 'target_name': 'minibrowser', + 'type': 'executable', + 'variables': { + 'chromium_code': 1, + }, + 'dependencies': [ + 'minibrowser_lib', + 'minibrowser_pak', + '../third_party/mesa/mesa.gyp:osmesa', + '../tools/imagediff/image_diff.gyp:image_diff', + '../build/linux/system.gyp:x11', + '../build/linux/system.gyp:xext', + ], + 'include_dirs': [ + '..', + ], + 'sources': [ + 'minibrowser_main.cc', + 'minibrowser_main_delegate.cc', + 'minibrowser_main_delegate.h', + ], + }] +} diff --git a/minibrowser_main.cc b/minibrowser_main.cc new file mode 100644 index 0000000..a956021 --- /dev/null +++ b/minibrowser_main.cc @@ -0,0 +1,16 @@ +// Copyright (c) 2015 University of Szeged. +// Copyright (c) 2015 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 "content/public/app/content_main.h" +#include "minibrowser/minibrowser_main_delegate.h" + +int main(int argc, const char** argv) { + MiniBrowserMainDelegate delegate; + content::ContentMainParams params(&delegate); + params.argc = argc; + params.argv = argv; + return content::ContentMain(params); +} \ No newline at end of file diff --git a/minibrowser_main_delegate.cc b/minibrowser_main_delegate.cc new file mode 100644 index 0000000..8a38c7d --- /dev/null +++ b/minibrowser_main_delegate.cc @@ -0,0 +1,60 @@ +// Copyright (c) 2015 University of Szeged. +// Copyright (c) 2015 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 "minibrowser/minibrowser_main_delegate.h" + +#include "base/files/file.h" +#include "base/files/file_path.h" +#include "base/path_service.h" +#include "content/public/browser/browser_main_runner.h" +#include "minibrowser/browser/browser_main.h" +#include "minibrowser/browser/content_browser_client.h" +#include "ui/base/resource/resource_bundle.h" + + +MiniBrowserMainDelegate::MiniBrowserMainDelegate() { +} + +MiniBrowserMainDelegate::~MiniBrowserMainDelegate() { +} + +bool MiniBrowserMainDelegate::BasicStartupComplete(int* exit_code) { + content::SetContentClient(&content_client_); + return false; +} + +void MiniBrowserMainDelegate::PreSandboxStartup() { + InitializeResourceBundle(); +} + +int MiniBrowserMainDelegate::RunProcess( + const std::string& process_type, + const content::MainFunctionParams& main_function_params) { + + if (!process_type.empty()) + return -1; + + scoped_ptr browser_runner_; + browser_runner_.reset(content::BrowserMainRunner::Create()); + + return BrowserMain(main_function_params, browser_runner_); +} + +content::ContentBrowserClient* +MiniBrowserMainDelegate::CreateContentBrowserClient() { + browser_client_.reset(new MiniBrowserContentBrowserClient); + return browser_client_.get(); +} + +// static +void MiniBrowserMainDelegate::InitializeResourceBundle() { + base::FilePath pak_file; + base::FilePath pak_dir; + + PathService::Get(base::DIR_MODULE, &pak_dir); + pak_file = pak_dir.Append(FILE_PATH_LITERAL("minibrowser.pak")); + ui::ResourceBundle::InitSharedInstanceWithPakPath(pak_file); +} \ No newline at end of file diff --git a/minibrowser_main_delegate.h b/minibrowser_main_delegate.h new file mode 100644 index 0000000..b104e89 --- /dev/null +++ b/minibrowser_main_delegate.h @@ -0,0 +1,39 @@ +// Copyright (c) 2015 University of Szeged. +// Copyright (c) 2015 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. + +#ifndef MINI_BROWSER_MAIN_DELEGATE_H_ +#define MINI_BROWSER_MAIN_DELEGATE_H_ + +#include "base/memory/scoped_ptr.h" +#include "content/public/app/content_main_delegate.h" +#include "minibrowser/common/content_client.h" + +class MiniBrowserContentBrowserClient; + +class MiniBrowserMainDelegate : public content::ContentMainDelegate { + +public: + MiniBrowserMainDelegate(); + ~MiniBrowserMainDelegate() override; + +protected: + // content::ContentMainDelegate implementation: + bool BasicStartupComplete(int* exit_code) override; + void PreSandboxStartup() override; + int RunProcess( + const std::string& process_type, + const content::MainFunctionParams& main_function_params) override; + content::ContentBrowserClient* CreateContentBrowserClient() override; + + static void InitializeResourceBundle(); +private: + scoped_ptr browser_client_; + MiniBrowserContentClient content_client_; + + DISALLOW_COPY_AND_ASSIGN(MiniBrowserMainDelegate); +}; + +#endif // MINI_BROWSER_MAIN_DELEGATE_H_ \ No newline at end of file diff --git a/minibrowser_resources.grd b/minibrowser_resources.grd new file mode 100644 index 0000000..633ec74 --- /dev/null +++ b/minibrowser_resources.grd @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/patch/build_target.patch b/patch/build_target.patch new file mode 100644 index 0000000..92eb84b --- /dev/null +++ b/patch/build_target.patch @@ -0,0 +1,18 @@ +diff --git a/build/all.gyp b/build/all.gyp +index 2813ca2..01a9a22 100644 +--- a/build/all.gyp ++++ b/build/all.gyp +@@ -276,6 +276,13 @@ + ], + }, # target_name: All + { ++ 'target_name': 'minibrowser', ++ 'type': 'none', ++ 'dependencies': [ ++ '../minibrowser/minibrowser.gyp:minibrowser', ++ ], ++ }, # target_name: minibrowser ++ { + 'target_name': 'All_syzygy', + 'type': 'none', + 'conditions': [ diff --git a/patch/gritsettings.patch b/patch/gritsettings.patch new file mode 100644 index 0000000..1cb9ad5 --- /dev/null +++ b/patch/gritsettings.patch @@ -0,0 +1,14 @@ +diff --git a/tools/gritsettings/resource_ids b/tools/gritsettings/resource_ids +index a64ae83..653becf 100644 +--- a/tools/gritsettings/resource_ids ++++ b/tools/gritsettings/resource_ids +@@ -160,6 +160,9 @@ + "content/shell/shell_resources.grd": { + "includes": [25500], + }, ++ "minibrowser/minibrowser_resources.grd": { ++ "includes": [25600], ++ }, + # This file is generated during the build. + "<(SHARED_INTERMEDIATE_DIR)/content/browser/tracing/tracing_resources.grd": { + "includes": [25750],