| // Copyright 2014 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 "sky/viewer/platform/platform_impl.h" |
| |
| #include <cmath> |
| |
| #include "base/debug/trace_event.h" |
| #include "base/rand_util.h" |
| #include "base/stl_util.h" |
| #include "base/synchronization/waitable_event.h" |
| #include "base/time/time.h" |
| #include "mojo/public/cpp/application/application_impl.h" |
| #include "net/base/data_url.h" |
| #include "net/base/mime_util.h" |
| #include "net/base/net_errors.h" |
| #include "sky/engine/public/platform/WebConvertableToTraceFormat.h" |
| #include "sky/viewer/platform/weburlloader_impl.h" |
| |
| namespace sky { |
| namespace { |
| |
| class ConvertableToTraceFormatWrapper |
| : public base::debug::ConvertableToTraceFormat { |
| public: |
| explicit ConvertableToTraceFormatWrapper( |
| const blink::WebConvertableToTraceFormat& convertable) |
| : convertable_(convertable) {} |
| virtual void AppendAsTraceFormat(std::string* out) const override { |
| *out += convertable_.asTraceFormat().utf8(); |
| } |
| |
| private: |
| virtual ~ConvertableToTraceFormatWrapper() {} |
| |
| blink::WebConvertableToTraceFormat convertable_; |
| }; |
| |
| } // namespace |
| |
| PlatformImpl::PlatformImpl(mojo::ApplicationImpl* app) |
| : main_loop_(base::MessageLoop::current()), |
| main_thread_task_runner_(base::MessageLoop::current()->task_runner()), |
| shared_timer_func_(NULL), |
| shared_timer_fire_time_(0.0), |
| shared_timer_fire_time_was_set_while_suspended_(false), |
| shared_timer_suspended_(0) { |
| app->ConnectToService("mojo://network_service/", &network_service_); |
| |
| mojo::CookieStorePtr cookie_store; |
| network_service_->GetCookieStore(GetProxy(&cookie_store)); |
| } |
| |
| PlatformImpl::~PlatformImpl() { |
| } |
| |
| blink::WebMimeRegistry* PlatformImpl::mimeRegistry() { |
| return &mime_registry_; |
| } |
| |
| blink::WebThemeEngine* PlatformImpl::themeEngine() { |
| return &theme_engine_; |
| } |
| |
| blink::WebString PlatformImpl::defaultLocale() { |
| return blink::WebString::fromUTF8("en-US"); |
| } |
| |
| double PlatformImpl::currentTime() { |
| return base::Time::Now().ToDoubleT(); |
| } |
| |
| double PlatformImpl::monotonicallyIncreasingTime() { |
| return base::TimeTicks::Now().ToInternalValue() / |
| static_cast<double>(base::Time::kMicrosecondsPerSecond); |
| } |
| |
| void PlatformImpl::setSharedTimerFiredFunction(void (*func)()) { |
| shared_timer_func_ = func; |
| } |
| |
| void PlatformImpl::setSharedTimerFireInterval( |
| double interval_seconds) { |
| shared_timer_fire_time_ = interval_seconds + monotonicallyIncreasingTime(); |
| if (shared_timer_suspended_) { |
| shared_timer_fire_time_was_set_while_suspended_ = true; |
| return; |
| } |
| |
| // By converting between double and int64 representation, we run the risk |
| // of losing precision due to rounding errors. Performing computations in |
| // microseconds reduces this risk somewhat. But there still is the potential |
| // of us computing a fire time for the timer that is shorter than what we |
| // need. |
| // As the event loop will check event deadlines prior to actually firing |
| // them, there is a risk of needlessly rescheduling events and of |
| // needlessly looping if sleep times are too short even by small amounts. |
| // This results in measurable performance degradation unless we use ceil() to |
| // always round up the sleep times. |
| int64 interval = static_cast<int64>( |
| ceil(interval_seconds * base::Time::kMillisecondsPerSecond) |
| * base::Time::kMicrosecondsPerMillisecond); |
| |
| if (interval < 0) |
| interval = 0; |
| |
| shared_timer_.Stop(); |
| shared_timer_.Start(FROM_HERE, base::TimeDelta::FromMicroseconds(interval), |
| this, &PlatformImpl::DoTimeout); |
| } |
| |
| void PlatformImpl::stopSharedTimer() { |
| shared_timer_.Stop(); |
| } |
| |
| base::SingleThreadTaskRunner* PlatformImpl::mainThreadTaskRunner() { |
| return main_thread_task_runner_.get(); |
| } |
| |
| bool PlatformImpl::isThreadedCompositingEnabled() { |
| return true; |
| } |
| |
| blink::WebCompositorSupport* PlatformImpl::compositorSupport() { |
| return &compositor_support_; |
| } |
| |
| blink::WebScrollbarBehavior* PlatformImpl::scrollbarBehavior() { |
| return &scrollbar_behavior_; |
| } |
| |
| mojo::NetworkService* PlatformImpl::networkService() { |
| return network_service_.get(); |
| } |
| |
| blink::WebURLLoader* PlatformImpl::createURLLoader() { |
| return new WebURLLoaderImpl(network_service_.get()); |
| } |
| |
| blink::WebURLError PlatformImpl::cancelledError(const blink::WebURL& url) |
| const { |
| blink::WebURLError error; |
| error.domain = blink::WebString::fromUTF8(net::kErrorDomain); |
| error.reason = net::ERR_ABORTED; |
| error.unreachableURL = url; |
| error.staleCopyInCache = false; |
| error.isCancellation = true; |
| return error; |
| } |
| |
| const unsigned char* PlatformImpl::getTraceCategoryEnabledFlag( |
| const char* category_group) { |
| return TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category_group); |
| } |
| |
| long* PlatformImpl::getTraceSamplingState(const unsigned thread_bucket) { |
| switch (thread_bucket) { |
| case 0: |
| return reinterpret_cast<long*>(&TRACE_EVENT_API_THREAD_BUCKET(0)); |
| case 1: |
| return reinterpret_cast<long*>(&TRACE_EVENT_API_THREAD_BUCKET(1)); |
| case 2: |
| return reinterpret_cast<long*>(&TRACE_EVENT_API_THREAD_BUCKET(2)); |
| default: |
| NOTREACHED() << "Unknown thread bucket type."; |
| } |
| return NULL; |
| } |
| |
| COMPILE_ASSERT( |
| sizeof(blink::Platform::TraceEventHandle) == |
| sizeof(base::debug::TraceEventHandle), |
| TraceEventHandle_types_must_be_same_size); |
| |
| blink::Platform::TraceEventHandle PlatformImpl::addTraceEvent( |
| char phase, |
| const unsigned char* category_group_enabled, |
| const char* name, |
| unsigned long long id, |
| int num_args, |
| const char** arg_names, |
| const unsigned char* arg_types, |
| const unsigned long long* arg_values, |
| unsigned char flags) { |
| base::debug::TraceEventHandle handle = TRACE_EVENT_API_ADD_TRACE_EVENT( |
| phase, category_group_enabled, name, id, |
| num_args, arg_names, arg_types, arg_values, NULL, flags); |
| blink::Platform::TraceEventHandle result; |
| memcpy(&result, &handle, sizeof(result)); |
| return result; |
| } |
| |
| blink::Platform::TraceEventHandle PlatformImpl::addTraceEvent( |
| char phase, |
| const unsigned char* category_group_enabled, |
| const char* name, |
| unsigned long long id, |
| int num_args, |
| const char** arg_names, |
| const unsigned char* arg_types, |
| const unsigned long long* arg_values, |
| const blink::WebConvertableToTraceFormat* convertable_values, |
| unsigned char flags) { |
| scoped_refptr<base::debug::ConvertableToTraceFormat> convertable_wrappers[2]; |
| if (convertable_values) { |
| size_t size = std::min(static_cast<size_t>(num_args), |
| arraysize(convertable_wrappers)); |
| for (size_t i = 0; i < size; ++i) { |
| if (arg_types[i] == TRACE_VALUE_TYPE_CONVERTABLE) { |
| convertable_wrappers[i] = |
| new ConvertableToTraceFormatWrapper(convertable_values[i]); |
| } |
| } |
| } |
| base::debug::TraceEventHandle handle = |
| TRACE_EVENT_API_ADD_TRACE_EVENT(phase, |
| category_group_enabled, |
| name, |
| id, |
| num_args, |
| arg_names, |
| arg_types, |
| arg_values, |
| convertable_wrappers, |
| flags); |
| blink::Platform::TraceEventHandle result; |
| memcpy(&result, &handle, sizeof(result)); |
| return result; |
| } |
| |
| void PlatformImpl::updateTraceEventDuration( |
| const unsigned char* category_group_enabled, |
| const char* name, |
| TraceEventHandle handle) { |
| base::debug::TraceEventHandle traceEventHandle; |
| memcpy(&traceEventHandle, &handle, sizeof(handle)); |
| TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION( |
| category_group_enabled, name, traceEventHandle); |
| } |
| |
| } // namespace sky |