[email protected] | 11d0c36 | 2012-10-11 02:02:11 | [diff] [blame] | 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. |
| 4 | |
| 5 | #include "ppapi/proxy/flash_resource.h" |
| 6 | |
avi | e029c413 | 2015-12-23 06:45:22 | [diff] [blame] | 7 | #include <stddef.h> |
| 8 | |
[email protected] | c9246538 | 2012-12-17 23:51:21 | [diff] [blame] | 9 | #include <cmath> |
| 10 | |
| 11 | #include "base/containers/mru_cache.h" |
[email protected] | 92e2b68 | 2013-04-22 22:22:27 | [diff] [blame] | 12 | #include "base/debug/crash_logging.h" |
[email protected] | c9246538 | 2012-12-17 23:51:21 | [diff] [blame] | 13 | #include "base/lazy_instance.h" |
[email protected] | 5d7eb86 | 2013-06-28 15:21:24 | [diff] [blame] | 14 | #include "base/time/time.h" |
avi | e029c413 | 2015-12-23 06:45:22 | [diff] [blame] | 15 | #include "build/build_config.h" |
[email protected] | a9f2a621 | 2012-12-04 08:47:34 | [diff] [blame] | 16 | #include "ppapi/c/pp_errors.h" |
| 17 | #include "ppapi/c/private/ppb_flash.h" |
[email protected] | 24f40c1 | 2012-12-19 20:17:42 | [diff] [blame] | 18 | #include "ppapi/c/trusted/ppb_browser_font_trusted.h" |
[email protected] | db16e6d | 2012-12-19 03:32:57 | [diff] [blame] | 19 | #include "ppapi/proxy/plugin_dispatcher.h" |
[email protected] | a9f2a621 | 2012-12-04 08:47:34 | [diff] [blame] | 20 | #include "ppapi/proxy/plugin_globals.h" |
[email protected] | 11d0c36 | 2012-10-11 02:02:11 | [diff] [blame] | 21 | #include "ppapi/proxy/ppapi_messages.h" |
[email protected] | 24f40c1 | 2012-12-19 20:17:42 | [diff] [blame] | 22 | #include "ppapi/proxy/serialized_structs.h" |
[email protected] | db16e6d | 2012-12-19 03:32:57 | [diff] [blame] | 23 | #include "ppapi/shared_impl/ppapi_preferences.h" |
| 24 | #include "ppapi/shared_impl/scoped_pp_var.h" |
[email protected] | c9246538 | 2012-12-17 23:51:21 | [diff] [blame] | 25 | #include "ppapi/shared_impl/time_conversion.h" |
[email protected] | a9f2a621 | 2012-12-04 08:47:34 | [diff] [blame] | 26 | #include "ppapi/shared_impl/var.h" |
[email protected] | db16e6d | 2012-12-19 03:32:57 | [diff] [blame] | 27 | #include "ppapi/thunk/enter.h" |
[email protected] | 24f40c1 | 2012-12-19 20:17:42 | [diff] [blame] | 28 | #include "ppapi/thunk/ppb_url_request_info_api.h" |
| 29 | |
| 30 | using ppapi::thunk::EnterResourceNoLock; |
[email protected] | 11d0c36 | 2012-10-11 02:02:11 | [diff] [blame] | 31 | |
| 32 | namespace ppapi { |
| 33 | namespace proxy { |
| 34 | |
[email protected] | c9246538 | 2012-12-17 23:51:21 | [diff] [blame] | 35 | namespace { |
| 36 | |
| 37 | struct LocalTimeZoneOffsetEntry { |
| 38 | base::TimeTicks expiration; |
| 39 | double offset; |
| 40 | }; |
| 41 | |
| 42 | class 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 | |
| 51 | base::LazyInstance<LocalTimeZoneOffsetCache>::Leaky |
| 52 | g_local_time_zone_offset_cache = LAZY_INSTANCE_INITIALIZER; |
| 53 | |
| 54 | } // namespace |
| 55 | |
[email protected] | db16e6d | 2012-12-19 03:32:57 | [diff] [blame] | 56 | FlashResource::FlashResource(Connection connection, |
| 57 | PP_Instance instance, |
| 58 | PluginDispatcher* plugin_dispatcher) |
| 59 | : PluginResource(connection, instance), |
| 60 | plugin_dispatcher_(plugin_dispatcher) { |
[email protected] | 9164da3 | 2012-10-16 03:40:57 | [diff] [blame] | 61 | SendCreate(RENDERER, PpapiHostMsg_Flash_Create()); |
[email protected] | a9f2a621 | 2012-12-04 08:47:34 | [diff] [blame] | 62 | SendCreate(BROWSER, PpapiHostMsg_Flash_Create()); |
[email protected] | 11d0c36 | 2012-10-11 02:02:11 | [diff] [blame] | 63 | } |
| 64 | |
| 65 | FlashResource::~FlashResource() { |
| 66 | } |
| 67 | |
| 68 | thunk::PPB_Flash_Functions_API* FlashResource::AsPPB_Flash_Functions_API() { |
| 69 | return this; |
| 70 | } |
| 71 | |
[email protected] | a9f2a621 | 2012-12-04 08:47:34 | [diff] [blame] | 72 | PP_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 | |
| 83 | void FlashResource::UpdateActivity(PP_Instance instance) { |
| 84 | Post(BROWSER, PpapiHostMsg_Flash_UpdateActivity()); |
| 85 | } |
| 86 | |
| 87 | PP_Bool FlashResource::SetCrashData(PP_Instance instance, |
| 88 | PP_FlashCrashKey key, |
| 89 | PP_Var value) { |
[email protected] | 92e2b68 | 2013-04-22 22:22:27 | [diff] [blame] | 90 | StringVar* url_string_var(StringVar::FromPPVar(value)); |
| 91 | if (!url_string_var) |
| 92 | return PP_FALSE; |
[email protected] | a9f2a621 | 2012-12-04 08:47:34 | [diff] [blame] | 93 | switch (key) { |
| 94 | case PP_FLASHCRASHKEY_URL: { |
[email protected] | a9f2a621 | 2012-12-04 08:47:34 | [diff] [blame] | 95 | PluginGlobals::Get()->SetActiveURL(url_string_var->value()); |
| 96 | return PP_TRUE; |
| 97 | } |
[email protected] | 92e2b68 | 2013-04-22 22:22:27 | [diff] [blame] | 98 | case PP_FLASHCRASHKEY_RESOURCE_URL: { |
| 99 | base::debug::SetCrashKeyValue("subresource_url", url_string_var->value()); |
| 100 | return PP_TRUE; |
| 101 | } |
[email protected] | a9f2a621 | 2012-12-04 08:47:34 | [diff] [blame] | 102 | } |
| 103 | return PP_FALSE; |
| 104 | } |
| 105 | |
[email protected] | c9246538 | 2012-12-17 23:51:21 | [diff] [blame] | 106 | double 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. |
avi | e029c413 | 2015-12-23 06:45:22 | [diff] [blame] | 124 | const int64_t kMaxCachedLocalOffsetAgeInSeconds = 10; |
[email protected] | c9246538 | 2012-12-17 23:51:21 | [diff] [blame] | 125 | 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] | db16e6d | 2012-12-19 03:32:57 | [diff] [blame] | 151 | PP_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] | 4abba3b4 | 2013-02-12 03:45:54 | [diff] [blame] | 162 | case PP_FLASHSETTING_STAGE3DBASELINEENABLED: |
| 163 | return PP_MakeBool(PP_FromBool( |
| 164 | plugin_dispatcher_->preferences().is_stage3d_baseline_supported)); |
[email protected] | db16e6d | 2012-12-19 03:32:57 | [diff] [blame] | 165 | 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] | 24f40c1 | 2012-12-19 20:17:42 | [diff] [blame] | 184 | void FlashResource::SetInstanceAlwaysOnTop(PP_Instance instance, |
| 185 | PP_Bool on_top) { |
| 186 | Post(RENDERER, PpapiHostMsg_Flash_SetInstanceAlwaysOnTop(PP_ToBool(on_top))); |
| 187 | } |
| 188 | |
| 189 | PP_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 | |
| 235 | int32_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 | |
| 247 | PP_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] | 6a77ef2 | 2012-12-21 23:31:36 | [diff] [blame] | 254 | void FlashResource::InvokePrinting(PP_Instance instance) { |
| 255 | Post(RENDERER, PpapiHostMsg_Flash_InvokePrinting()); |
| 256 | } |
| 257 | |
[email protected] | 11d0c36 | 2012-10-11 02:02:11 | [diff] [blame] | 258 | } // namespace proxy |
| 259 | } // namespace ppapi |