Fix iOS build for XCode 4.6.
[chromium-blink-merge.git] / ppapi / proxy / flash_resource.cc
blob3f72e782241837b31382ea42272171d719fc9e34
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"
7 #include <cmath>
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/c/trusted/ppb_browser_font_trusted.h"
15 #include "ppapi/proxy/plugin_dispatcher.h"
16 #include "ppapi/proxy/plugin_globals.h"
17 #include "ppapi/proxy/ppapi_messages.h"
18 #include "ppapi/proxy/serialized_structs.h"
19 #include "ppapi/shared_impl/ppapi_preferences.h"
20 #include "ppapi/shared_impl/scoped_pp_var.h"
21 #include "ppapi/shared_impl/time_conversion.h"
22 #include "ppapi/shared_impl/var.h"
23 #include "ppapi/thunk/enter.h"
24 #include "ppapi/thunk/ppb_url_request_info_api.h"
26 using ppapi::thunk::EnterResourceNoLock;
28 namespace ppapi {
29 namespace proxy {
31 namespace {
33 struct LocalTimeZoneOffsetEntry {
34 base::TimeTicks expiration;
35 double offset;
38 class LocalTimeZoneOffsetCache
39 : public base::MRUCache<PP_Time, LocalTimeZoneOffsetEntry> {
40 public:
41 LocalTimeZoneOffsetCache()
42 : base::MRUCache<PP_Time, LocalTimeZoneOffsetEntry>(kCacheSize) {}
43 private:
44 static const size_t kCacheSize = 100;
47 base::LazyInstance<LocalTimeZoneOffsetCache>::Leaky
48 g_local_time_zone_offset_cache = LAZY_INSTANCE_INITIALIZER;
50 } // namespace
52 FlashResource::FlashResource(Connection connection,
53 PP_Instance instance,
54 PluginDispatcher* plugin_dispatcher)
55 : PluginResource(connection, instance),
56 plugin_dispatcher_(plugin_dispatcher) {
57 SendCreate(RENDERER, PpapiHostMsg_Flash_Create());
58 SendCreate(BROWSER, PpapiHostMsg_Flash_Create());
61 FlashResource::~FlashResource() {
64 thunk::PPB_Flash_Functions_API* FlashResource::AsPPB_Flash_Functions_API() {
65 return this;
68 PP_Var FlashResource::GetProxyForURL(PP_Instance instance,
69 const std::string& url) {
70 std::string proxy;
71 int32_t result = SyncCall<PpapiPluginMsg_Flash_GetProxyForURLReply>(RENDERER,
72 PpapiHostMsg_Flash_GetProxyForURL(url), &proxy);
74 if (result == PP_OK)
75 return StringVar::StringToPPVar(proxy);
76 return PP_MakeUndefined();
79 void FlashResource::UpdateActivity(PP_Instance instance) {
80 Post(BROWSER, PpapiHostMsg_Flash_UpdateActivity());
83 PP_Bool FlashResource::SetCrashData(PP_Instance instance,
84 PP_FlashCrashKey key,
85 PP_Var value) {
86 switch (key) {
87 case PP_FLASHCRASHKEY_URL: {
88 StringVar* url_string_var(StringVar::FromPPVar(value));
89 if (!url_string_var)
90 return PP_FALSE;
91 PluginGlobals::Get()->SetActiveURL(url_string_var->value());
92 return PP_TRUE;
95 return PP_FALSE;
98 double FlashResource::GetLocalTimeZoneOffset(PP_Instance instance,
99 PP_Time t) {
100 LocalTimeZoneOffsetCache& cache = g_local_time_zone_offset_cache.Get();
102 // Get the minimum PP_Time value that shares the same minute as |t|.
103 // Use cached offset if cache hasn't expired and |t| is in the same minute as
104 // the time for the cached offset (assume offsets change on minute
105 // boundaries).
106 PP_Time t_minute_base = floor(t / 60.0) * 60.0;
107 LocalTimeZoneOffsetCache::iterator iter = cache.Get(t_minute_base);
108 base::TimeTicks now = base::TimeTicks::Now();
109 if (iter != cache.end() && now < iter->second.expiration)
110 return iter->second.offset;
112 // Cache the local offset for ten seconds, since it's slow on XP and Linux.
113 // Note that TimeTicks does not continue counting across sleep/resume on all
114 // platforms. This may be acceptable for 10 seconds, but if in the future this
115 // is changed to one minute or more, then we should consider using base::Time.
116 const int64 kMaxCachedLocalOffsetAgeInSeconds = 10;
117 base::TimeDelta expiration_delta =
118 base::TimeDelta::FromSeconds(kMaxCachedLocalOffsetAgeInSeconds);
120 LocalTimeZoneOffsetEntry cache_entry;
121 cache_entry.expiration = now + expiration_delta;
122 cache_entry.offset = 0.0;
124 // We can't do the conversion here on Linux because the localtime calls
125 // require filesystem access prohibited by the sandbox.
126 // TODO(shess): Figure out why OSX needs the access, the sandbox warmup should
127 // handle it. http://crbug.com/149006
128 #if defined(OS_LINUX) || defined(OS_MACOSX)
129 int32_t result = SyncCall<PpapiPluginMsg_Flash_GetLocalTimeZoneOffsetReply>(
130 BROWSER,
131 PpapiHostMsg_Flash_GetLocalTimeZoneOffset(PPTimeToTime(t)),
132 &cache_entry.offset);
133 if (result != PP_OK)
134 cache_entry.offset = 0.0;
135 #else
136 cache_entry.offset = PPGetLocalTimeZoneOffset(PPTimeToTime(t));
137 #endif
139 cache.Put(t_minute_base, cache_entry);
140 return cache_entry.offset;
143 PP_Var FlashResource::GetSetting(PP_Instance instance,
144 PP_FlashSetting setting) {
145 switch (setting) {
146 case PP_FLASHSETTING_3DENABLED:
147 return PP_MakeBool(PP_FromBool(
148 plugin_dispatcher_->preferences().is_3d_supported));
149 case PP_FLASHSETTING_INCOGNITO:
150 return PP_MakeBool(PP_FromBool(plugin_dispatcher_->incognito()));
151 case PP_FLASHSETTING_STAGE3DENABLED:
152 return PP_MakeBool(PP_FromBool(
153 plugin_dispatcher_->preferences().is_stage3d_supported));
154 case PP_FLASHSETTING_LANGUAGE:
155 return StringVar::StringToPPVar(
156 PluginGlobals::Get()->GetUILanguage());
157 case PP_FLASHSETTING_NUMCORES:
158 return PP_MakeInt32(
159 plugin_dispatcher_->preferences().number_of_cpu_cores);
160 case PP_FLASHSETTING_LSORESTRICTIONS: {
161 int32_t restrictions;
162 int32_t result =
163 SyncCall<PpapiPluginMsg_Flash_GetLocalDataRestrictionsReply>(BROWSER,
164 PpapiHostMsg_Flash_GetLocalDataRestrictions(), &restrictions);
165 if (result != PP_OK)
166 return PP_MakeInt32(PP_FLASHLSORESTRICTIONS_NONE);
167 return PP_MakeInt32(restrictions);
170 return PP_MakeUndefined();
173 void FlashResource::SetInstanceAlwaysOnTop(PP_Instance instance,
174 PP_Bool on_top) {
175 Post(RENDERER, PpapiHostMsg_Flash_SetInstanceAlwaysOnTop(PP_ToBool(on_top)));
178 PP_Bool FlashResource::DrawGlyphs(
179 PP_Instance instance,
180 PP_Resource pp_image_data,
181 const PP_BrowserFont_Trusted_Description* font_desc,
182 uint32_t color,
183 const PP_Point* position,
184 const PP_Rect* clip,
185 const float transformation[3][3],
186 PP_Bool allow_subpixel_aa,
187 uint32_t glyph_count,
188 const uint16_t glyph_indices[],
189 const PP_Point glyph_advances[]) {
190 EnterResourceNoLock<thunk::PPB_ImageData_API> enter(pp_image_data, true);
191 if (enter.failed())
192 return PP_FALSE;
193 // The instance parameter isn't strictly necessary but we check that it
194 // matches anyway.
195 if (enter.resource()->pp_instance() != instance)
196 return PP_FALSE;
198 PPBFlash_DrawGlyphs_Params params;
199 params.image_data = enter.resource()->host_resource();
200 params.font_desc.SetFromPPBrowserFontDescription(*font_desc);
201 params.color = color;
202 params.position = *position;
203 params.clip = *clip;
204 for (int i = 0; i < 3; i++) {
205 for (int j = 0; j < 3; j++)
206 params.transformation[i][j] = transformation[i][j];
208 params.allow_subpixel_aa = allow_subpixel_aa;
210 params.glyph_indices.insert(params.glyph_indices.begin(),
211 &glyph_indices[0],
212 &glyph_indices[glyph_count]);
213 params.glyph_advances.insert(params.glyph_advances.begin(),
214 &glyph_advances[0],
215 &glyph_advances[glyph_count]);
217 // This has to be synchronous because the caller may want to composite on
218 // top of the resulting text after the call is complete.
219 int32_t result = SyncCall<IPC::Message>(RENDERER,
220 PpapiHostMsg_Flash_DrawGlyphs(params));
221 return PP_FromBool(result == PP_OK);
224 int32_t FlashResource::Navigate(PP_Instance instance,
225 PP_Resource request_info,
226 const char* target,
227 PP_Bool from_user_action) {
228 EnterResourceNoLock<thunk::PPB_URLRequestInfo_API> enter(request_info,
229 true);
230 if (enter.failed())
231 return PP_ERROR_BADRESOURCE;
232 return SyncCall<IPC::Message>(RENDERER, PpapiHostMsg_Flash_Navigate(
233 enter.object()->GetData(), target, PP_ToBool(from_user_action)));
236 PP_Bool FlashResource::IsRectTopmost(PP_Instance instance,
237 const PP_Rect* rect) {
238 int32_t result = SyncCall<IPC::Message>(RENDERER,
239 PpapiHostMsg_Flash_IsRectTopmost(*rect));
240 return PP_FromBool(result == PP_OK);
243 void FlashResource::InvokePrinting(PP_Instance instance) {
244 Post(RENDERER, PpapiHostMsg_Flash_InvokePrinting());
247 } // namespace proxy
248 } // namespace ppapi