blob: d8ec440a5662c2d182965081262061afcb786cbf [file] [log] [blame]
[email protected]11d0c362012-10-11 02:02:111// 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.
4
5#include "ppapi/proxy/flash_resource.h"
6
avie029c4132015-12-23 06:45:227#include <stddef.h>
8
[email protected]c92465382012-12-17 23:51:219#include <cmath>
10
11#include "base/containers/mru_cache.h"
[email protected]92e2b682013-04-22 22:22:2712#include "base/debug/crash_logging.h"
[email protected]c92465382012-12-17 23:51:2113#include "base/lazy_instance.h"
[email protected]5d7eb862013-06-28 15:21:2414#include "base/time/time.h"
avie029c4132015-12-23 06:45:2215#include "build/build_config.h"
[email protected]a9f2a6212012-12-04 08:47:3416#include "ppapi/c/pp_errors.h"
17#include "ppapi/c/private/ppb_flash.h"
[email protected]24f40c12012-12-19 20:17:4218#include "ppapi/c/trusted/ppb_browser_font_trusted.h"
[email protected]db16e6d2012-12-19 03:32:5719#include "ppapi/proxy/plugin_dispatcher.h"
[email protected]a9f2a6212012-12-04 08:47:3420#include "ppapi/proxy/plugin_globals.h"
[email protected]11d0c362012-10-11 02:02:1121#include "ppapi/proxy/ppapi_messages.h"
[email protected]24f40c12012-12-19 20:17:4222#include "ppapi/proxy/serialized_structs.h"
[email protected]db16e6d2012-12-19 03:32:5723#include "ppapi/shared_impl/ppapi_preferences.h"
24#include "ppapi/shared_impl/scoped_pp_var.h"
[email protected]c92465382012-12-17 23:51:2125#include "ppapi/shared_impl/time_conversion.h"
[email protected]a9f2a6212012-12-04 08:47:3426#include "ppapi/shared_impl/var.h"
[email protected]db16e6d2012-12-19 03:32:5727#include "ppapi/thunk/enter.h"
[email protected]24f40c12012-12-19 20:17:4228#include "ppapi/thunk/ppb_url_request_info_api.h"
29
30using ppapi::thunk::EnterResourceNoLock;
[email protected]11d0c362012-10-11 02:02:1131
32namespace ppapi {
33namespace proxy {
34
[email protected]c92465382012-12-17 23:51:2135namespace {
36
37struct LocalTimeZoneOffsetEntry {
38 base::TimeTicks expiration;
39 double offset;
40};
41
42class LocalTimeZoneOffsetCache
43 : public base::MRUCache<PP_Time, LocalTimeZoneOffsetEntry> {
44 public:
45 LocalTimeZoneOffsetCache()
46 : base::MRUCache<PP_Time, LocalTimeZoneOffsetEntry>(kCacheSize) {}
47 private:
48 static const size_t kCacheSize = 100;
49};
50
51base::LazyInstance<LocalTimeZoneOffsetCache>::Leaky
52 g_local_time_zone_offset_cache = LAZY_INSTANCE_INITIALIZER;
53
54} // namespace
55
[email protected]db16e6d2012-12-19 03:32:5756FlashResource::FlashResource(Connection connection,
57 PP_Instance instance,
58 PluginDispatcher* plugin_dispatcher)
59 : PluginResource(connection, instance),
60 plugin_dispatcher_(plugin_dispatcher) {
[email protected]9164da32012-10-16 03:40:5761 SendCreate(RENDERER, PpapiHostMsg_Flash_Create());
[email protected]a9f2a6212012-12-04 08:47:3462 SendCreate(BROWSER, PpapiHostMsg_Flash_Create());
[email protected]11d0c362012-10-11 02:02:1163}
64
65FlashResource::~FlashResource() {
66}
67
68thunk::PPB_Flash_Functions_API* FlashResource::AsPPB_Flash_Functions_API() {
69 return this;
70}
71
[email protected]a9f2a6212012-12-04 08:47:3472PP_Var FlashResource::GetProxyForURL(PP_Instance instance,
73 const std::string& url) {
74 std::string proxy;
75 int32_t result = SyncCall<PpapiPluginMsg_Flash_GetProxyForURLReply>(RENDERER,
76 PpapiHostMsg_Flash_GetProxyForURL(url), &proxy);
77
78 if (result == PP_OK)
79 return StringVar::StringToPPVar(proxy);
80 return PP_MakeUndefined();
81}
82
83void FlashResource::UpdateActivity(PP_Instance instance) {
84 Post(BROWSER, PpapiHostMsg_Flash_UpdateActivity());
85}
86
87PP_Bool FlashResource::SetCrashData(PP_Instance instance,
88 PP_FlashCrashKey key,
89 PP_Var value) {
[email protected]92e2b682013-04-22 22:22:2790 StringVar* url_string_var(StringVar::FromPPVar(value));
91 if (!url_string_var)
92 return PP_FALSE;
[email protected]a9f2a6212012-12-04 08:47:3493 switch (key) {
94 case PP_FLASHCRASHKEY_URL: {
[email protected]a9f2a6212012-12-04 08:47:3495 PluginGlobals::Get()->SetActiveURL(url_string_var->value());
96 return PP_TRUE;
97 }
[email protected]92e2b682013-04-22 22:22:2798 case PP_FLASHCRASHKEY_RESOURCE_URL: {
99 base::debug::SetCrashKeyValue("subresource_url", url_string_var->value());
100 return PP_TRUE;
101 }
[email protected]a9f2a6212012-12-04 08:47:34102 }
103 return PP_FALSE;
104}
105
[email protected]c92465382012-12-17 23:51:21106double FlashResource::GetLocalTimeZoneOffset(PP_Instance instance,
107 PP_Time t) {
108 LocalTimeZoneOffsetCache& cache = g_local_time_zone_offset_cache.Get();
109
110 // Get the minimum PP_Time value that shares the same minute as |t|.
111 // Use cached offset if cache hasn't expired and |t| is in the same minute as
112 // the time for the cached offset (assume offsets change on minute
113 // boundaries).
114 PP_Time t_minute_base = floor(t / 60.0) * 60.0;
115 LocalTimeZoneOffsetCache::iterator iter = cache.Get(t_minute_base);
116 base::TimeTicks now = base::TimeTicks::Now();
117 if (iter != cache.end() && now < iter->second.expiration)
118 return iter->second.offset;
119
120 // Cache the local offset for ten seconds, since it's slow on XP and Linux.
121 // Note that TimeTicks does not continue counting across sleep/resume on all
122 // platforms. This may be acceptable for 10 seconds, but if in the future this
123 // is changed to one minute or more, then we should consider using base::Time.
avie029c4132015-12-23 06:45:22124 const int64_t kMaxCachedLocalOffsetAgeInSeconds = 10;
[email protected]c92465382012-12-17 23:51:21125 base::TimeDelta expiration_delta =
126 base::TimeDelta::FromSeconds(kMaxCachedLocalOffsetAgeInSeconds);
127
128 LocalTimeZoneOffsetEntry cache_entry;
129 cache_entry.expiration = now + expiration_delta;
130 cache_entry.offset = 0.0;
131
132 // We can't do the conversion here on Linux because the localtime calls
133 // require filesystem access prohibited by the sandbox.
134 // TODO(shess): Figure out why OSX needs the access, the sandbox warmup should
135 // handle it. http://crbug.com/149006
136#if defined(OS_LINUX) || defined(OS_MACOSX)
137 int32_t result = SyncCall<PpapiPluginMsg_Flash_GetLocalTimeZoneOffsetReply>(
138 BROWSER,
139 PpapiHostMsg_Flash_GetLocalTimeZoneOffset(PPTimeToTime(t)),
140 &cache_entry.offset);
141 if (result != PP_OK)
142 cache_entry.offset = 0.0;
143#else
144 cache_entry.offset = PPGetLocalTimeZoneOffset(PPTimeToTime(t));
145#endif
146
147 cache.Put(t_minute_base, cache_entry);
148 return cache_entry.offset;
149}
150
[email protected]db16e6d2012-12-19 03:32:57151PP_Var FlashResource::GetSetting(PP_Instance instance,
152 PP_FlashSetting setting) {
153 switch (setting) {
154 case PP_FLASHSETTING_3DENABLED:
155 return PP_MakeBool(PP_FromBool(
156 plugin_dispatcher_->preferences().is_3d_supported));
157 case PP_FLASHSETTING_INCOGNITO:
158 return PP_MakeBool(PP_FromBool(plugin_dispatcher_->incognito()));
159 case PP_FLASHSETTING_STAGE3DENABLED:
160 return PP_MakeBool(PP_FromBool(
161 plugin_dispatcher_->preferences().is_stage3d_supported));
[email protected]4abba3b42013-02-12 03:45:54162 case PP_FLASHSETTING_STAGE3DBASELINEENABLED:
163 return PP_MakeBool(PP_FromBool(
164 plugin_dispatcher_->preferences().is_stage3d_baseline_supported));
[email protected]db16e6d2012-12-19 03:32:57165 case PP_FLASHSETTING_LANGUAGE:
166 return StringVar::StringToPPVar(
167 PluginGlobals::Get()->GetUILanguage());
168 case PP_FLASHSETTING_NUMCORES:
169 return PP_MakeInt32(
170 plugin_dispatcher_->preferences().number_of_cpu_cores);
171 case PP_FLASHSETTING_LSORESTRICTIONS: {
172 int32_t restrictions;
173 int32_t result =
174 SyncCall<PpapiPluginMsg_Flash_GetLocalDataRestrictionsReply>(BROWSER,
175 PpapiHostMsg_Flash_GetLocalDataRestrictions(), &restrictions);
176 if (result != PP_OK)
177 return PP_MakeInt32(PP_FLASHLSORESTRICTIONS_NONE);
178 return PP_MakeInt32(restrictions);
179 }
180 }
181 return PP_MakeUndefined();
182}
183
[email protected]24f40c12012-12-19 20:17:42184void FlashResource::SetInstanceAlwaysOnTop(PP_Instance instance,
185 PP_Bool on_top) {
186 Post(RENDERER, PpapiHostMsg_Flash_SetInstanceAlwaysOnTop(PP_ToBool(on_top)));
187}
188
189PP_Bool FlashResource::DrawGlyphs(
190 PP_Instance instance,
191 PP_Resource pp_image_data,
192 const PP_BrowserFont_Trusted_Description* font_desc,
193 uint32_t color,
194 const PP_Point* position,
195 const PP_Rect* clip,
196 const float transformation[3][3],
197 PP_Bool allow_subpixel_aa,
198 uint32_t glyph_count,
199 const uint16_t glyph_indices[],
200 const PP_Point glyph_advances[]) {
201 EnterResourceNoLock<thunk::PPB_ImageData_API> enter(pp_image_data, true);
202 if (enter.failed())
203 return PP_FALSE;
204 // The instance parameter isn't strictly necessary but we check that it
205 // matches anyway.
206 if (enter.resource()->pp_instance() != instance)
207 return PP_FALSE;
208
209 PPBFlash_DrawGlyphs_Params params;
210 params.image_data = enter.resource()->host_resource();
211 params.font_desc.SetFromPPBrowserFontDescription(*font_desc);
212 params.color = color;
213 params.position = *position;
214 params.clip = *clip;
215 for (int i = 0; i < 3; i++) {
216 for (int j = 0; j < 3; j++)
217 params.transformation[i][j] = transformation[i][j];
218 }
219 params.allow_subpixel_aa = allow_subpixel_aa;
220
221 params.glyph_indices.insert(params.glyph_indices.begin(),
222 &glyph_indices[0],
223 &glyph_indices[glyph_count]);
224 params.glyph_advances.insert(params.glyph_advances.begin(),
225 &glyph_advances[0],
226 &glyph_advances[glyph_count]);
227
228 // This has to be synchronous because the caller may want to composite on
229 // top of the resulting text after the call is complete.
230 int32_t result = SyncCall<IPC::Message>(RENDERER,
231 PpapiHostMsg_Flash_DrawGlyphs(params));
232 return PP_FromBool(result == PP_OK);
233}
234
235int32_t FlashResource::Navigate(PP_Instance instance,
236 PP_Resource request_info,
237 const char* target,
238 PP_Bool from_user_action) {
239 EnterResourceNoLock<thunk::PPB_URLRequestInfo_API> enter(request_info,
240 true);
241 if (enter.failed())
242 return PP_ERROR_BADRESOURCE;
243 return SyncCall<IPC::Message>(RENDERER, PpapiHostMsg_Flash_Navigate(
244 enter.object()->GetData(), target, PP_ToBool(from_user_action)));
245}
246
247PP_Bool FlashResource::IsRectTopmost(PP_Instance instance,
248 const PP_Rect* rect) {
249 int32_t result = SyncCall<IPC::Message>(RENDERER,
250 PpapiHostMsg_Flash_IsRectTopmost(*rect));
251 return PP_FromBool(result == PP_OK);
252}
253
[email protected]6a77ef22012-12-21 23:31:36254void FlashResource::InvokePrinting(PP_Instance instance) {
255 Post(RENDERER, PpapiHostMsg_Flash_InvokePrinting());
256}
257
[email protected]11d0c362012-10-11 02:02:11258} // namespace proxy
259} // namespace ppapi