diff options
Diffstat (limited to 'ppapi/proxy/flash_resource.cc')
-rw-r--r-- | ppapi/proxy/flash_resource.cc | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/ppapi/proxy/flash_resource.cc b/ppapi/proxy/flash_resource.cc index be5acd3..176bd16 100644 --- a/ppapi/proxy/flash_resource.cc +++ b/ppapi/proxy/flash_resource.cc @@ -4,15 +4,42 @@ #include "ppapi/proxy/flash_resource.h" +#include <cmath> + +#include "base/containers/mru_cache.h" +#include "base/lazy_instance.h" +#include "base/time.h" #include "ppapi/c/pp_errors.h" #include "ppapi/c/private/ppb_flash.h" #include "ppapi/proxy/plugin_globals.h" #include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/shared_impl/time_conversion.h" #include "ppapi/shared_impl/var.h" namespace ppapi { namespace proxy { +namespace { + +struct LocalTimeZoneOffsetEntry { + base::TimeTicks expiration; + double offset; +}; + +class LocalTimeZoneOffsetCache + : public base::MRUCache<PP_Time, LocalTimeZoneOffsetEntry> { + public: + LocalTimeZoneOffsetCache() + : base::MRUCache<PP_Time, LocalTimeZoneOffsetEntry>(kCacheSize) {} + private: + static const size_t kCacheSize = 100; +}; + +base::LazyInstance<LocalTimeZoneOffsetCache>::Leaky + g_local_time_zone_offset_cache = LAZY_INSTANCE_INITIALIZER; + +} // namespace + FlashResource::FlashResource(Connection connection, PP_Instance instance) : PluginResource(connection, instance) { SendCreate(RENDERER, PpapiHostMsg_Flash_Create()); @@ -56,5 +83,50 @@ PP_Bool FlashResource::SetCrashData(PP_Instance instance, return PP_FALSE; } +double FlashResource::GetLocalTimeZoneOffset(PP_Instance instance, + PP_Time t) { + LocalTimeZoneOffsetCache& cache = g_local_time_zone_offset_cache.Get(); + + // Get the minimum PP_Time value that shares the same minute as |t|. + // Use cached offset if cache hasn't expired and |t| is in the same minute as + // the time for the cached offset (assume offsets change on minute + // boundaries). + PP_Time t_minute_base = floor(t / 60.0) * 60.0; + LocalTimeZoneOffsetCache::iterator iter = cache.Get(t_minute_base); + base::TimeTicks now = base::TimeTicks::Now(); + if (iter != cache.end() && now < iter->second.expiration) + return iter->second.offset; + + // Cache the local offset for ten seconds, since it's slow on XP and Linux. + // Note that TimeTicks does not continue counting across sleep/resume on all + // platforms. This may be acceptable for 10 seconds, but if in the future this + // is changed to one minute or more, then we should consider using base::Time. + const int64 kMaxCachedLocalOffsetAgeInSeconds = 10; + base::TimeDelta expiration_delta = + base::TimeDelta::FromSeconds(kMaxCachedLocalOffsetAgeInSeconds); + + LocalTimeZoneOffsetEntry cache_entry; + cache_entry.expiration = now + expiration_delta; + cache_entry.offset = 0.0; + + // We can't do the conversion here on Linux because the localtime calls + // require filesystem access prohibited by the sandbox. + // TODO(shess): Figure out why OSX needs the access, the sandbox warmup should + // handle it. http://crbug.com/149006 +#if defined(OS_LINUX) || defined(OS_MACOSX) + int32_t result = SyncCall<PpapiPluginMsg_Flash_GetLocalTimeZoneOffsetReply>( + BROWSER, + PpapiHostMsg_Flash_GetLocalTimeZoneOffset(PPTimeToTime(t)), + &cache_entry.offset); + if (result != PP_OK) + cache_entry.offset = 0.0; +#else + cache_entry.offset = PPGetLocalTimeZoneOffset(PPTimeToTime(t)); +#endif + + cache.Put(t_minute_base, cache_entry); + return cache_entry.offset; +} + } // namespace proxy } // namespace ppapi |