1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ppapi/proxy/flash_resource.h"
9 #include "base/containers/mru_cache.h"
10 #include "base/lazy_instance.h"
11 #include "base/time.h"
12 #include "ppapi/c/pp_errors.h"
13 #include "ppapi/c/private/ppb_flash.h"
14 #include "ppapi/proxy/plugin_globals.h"
15 #include "ppapi/proxy/ppapi_messages.h"
16 #include "ppapi/shared_impl/time_conversion.h"
17 #include "ppapi/shared_impl/var.h"
24 struct LocalTimeZoneOffsetEntry
{
25 base::TimeTicks expiration
;
29 class LocalTimeZoneOffsetCache
30 : public base::MRUCache
<PP_Time
, LocalTimeZoneOffsetEntry
> {
32 LocalTimeZoneOffsetCache()
33 : base::MRUCache
<PP_Time
, LocalTimeZoneOffsetEntry
>(kCacheSize
) {}
35 static const size_t kCacheSize
= 100;
38 base::LazyInstance
<LocalTimeZoneOffsetCache
>::Leaky
39 g_local_time_zone_offset_cache
= LAZY_INSTANCE_INITIALIZER
;
43 FlashResource::FlashResource(Connection connection
, PP_Instance instance
)
44 : PluginResource(connection
, instance
) {
45 SendCreate(RENDERER
, PpapiHostMsg_Flash_Create());
46 SendCreate(BROWSER
, PpapiHostMsg_Flash_Create());
49 FlashResource::~FlashResource() {
52 thunk::PPB_Flash_Functions_API
* FlashResource::AsPPB_Flash_Functions_API() {
56 PP_Var
FlashResource::GetProxyForURL(PP_Instance instance
,
57 const std::string
& url
) {
59 int32_t result
= SyncCall
<PpapiPluginMsg_Flash_GetProxyForURLReply
>(RENDERER
,
60 PpapiHostMsg_Flash_GetProxyForURL(url
), &proxy
);
63 return StringVar::StringToPPVar(proxy
);
64 return PP_MakeUndefined();
67 void FlashResource::UpdateActivity(PP_Instance instance
) {
68 Post(BROWSER
, PpapiHostMsg_Flash_UpdateActivity());
71 PP_Bool
FlashResource::SetCrashData(PP_Instance instance
,
75 case PP_FLASHCRASHKEY_URL
: {
76 StringVar
* url_string_var(StringVar::FromPPVar(value
));
79 PluginGlobals::Get()->SetActiveURL(url_string_var
->value());
86 double FlashResource::GetLocalTimeZoneOffset(PP_Instance instance
,
88 LocalTimeZoneOffsetCache
& cache
= g_local_time_zone_offset_cache
.Get();
90 // Get the minimum PP_Time value that shares the same minute as |t|.
91 // Use cached offset if cache hasn't expired and |t| is in the same minute as
92 // the time for the cached offset (assume offsets change on minute
94 PP_Time t_minute_base
= floor(t
/ 60.0) * 60.0;
95 LocalTimeZoneOffsetCache::iterator iter
= cache
.Get(t_minute_base
);
96 base::TimeTicks now
= base::TimeTicks::Now();
97 if (iter
!= cache
.end() && now
< iter
->second
.expiration
)
98 return iter
->second
.offset
;
100 // Cache the local offset for ten seconds, since it's slow on XP and Linux.
101 // Note that TimeTicks does not continue counting across sleep/resume on all
102 // platforms. This may be acceptable for 10 seconds, but if in the future this
103 // is changed to one minute or more, then we should consider using base::Time.
104 const int64 kMaxCachedLocalOffsetAgeInSeconds
= 10;
105 base::TimeDelta expiration_delta
=
106 base::TimeDelta::FromSeconds(kMaxCachedLocalOffsetAgeInSeconds
);
108 LocalTimeZoneOffsetEntry cache_entry
;
109 cache_entry
.expiration
= now
+ expiration_delta
;
110 cache_entry
.offset
= 0.0;
112 // We can't do the conversion here on Linux because the localtime calls
113 // require filesystem access prohibited by the sandbox.
114 // TODO(shess): Figure out why OSX needs the access, the sandbox warmup should
115 // handle it. http://crbug.com/149006
116 #if defined(OS_LINUX) || defined(OS_MACOSX)
117 int32_t result
= SyncCall
<PpapiPluginMsg_Flash_GetLocalTimeZoneOffsetReply
>(
119 PpapiHostMsg_Flash_GetLocalTimeZoneOffset(PPTimeToTime(t
)),
120 &cache_entry
.offset
);
122 cache_entry
.offset
= 0.0;
124 cache_entry
.offset
= PPGetLocalTimeZoneOffset(PPTimeToTime(t
));
127 cache
.Put(t_minute_base
, cache_entry
);
128 return cache_entry
.offset
;