summaryrefslogtreecommitdiffstats
path: root/ppapi/proxy/flash_resource.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ppapi/proxy/flash_resource.cc')
-rw-r--r--ppapi/proxy/flash_resource.cc72
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