PageRenderTime 60ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/ppapi/proxy/ppp_printing_proxy.cc

http://github.com/chromium/chromium
C++ | 211 lines | 161 code | 32 blank | 18 comment | 17 complexity | cd61bb320ffa4724aec5ee69fd94474d MD5 | raw file
Possible License(s): Apache-2.0, LGPL-2.0, BSD-2-Clause, LGPL-2.1, MPL-2.0, 0BSD, EPL-1.0, MPL-2.0-no-copyleft-exception, GPL-2.0, BitTorrent-1.0, CPL-1.0, LGPL-3.0, Unlicense, BSD-3-Clause, CC0-1.0, JSON, MIT, GPL-3.0, CC-BY-SA-3.0, AGPL-1.0
  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. #include "ppapi/proxy/ppp_printing_proxy.h"
  5. #include <string.h>
  6. #include "base/numerics/safe_conversions.h"
  7. #include "build/build_config.h"
  8. #include "ppapi/c/dev/ppp_printing_dev.h"
  9. #include "ppapi/proxy/host_dispatcher.h"
  10. #include "ppapi/proxy/plugin_dispatcher.h"
  11. #include "ppapi/proxy/plugin_resource_tracker.h"
  12. #include "ppapi/proxy/ppapi_messages.h"
  13. #include "ppapi/shared_impl/ppapi_globals.h"
  14. #include "ppapi/shared_impl/proxy_lock.h"
  15. #include "ppapi/shared_impl/resource_tracker.h"
  16. namespace ppapi {
  17. namespace proxy {
  18. namespace {
  19. #if !defined(OS_NACL)
  20. bool HasPrintingPermission(PP_Instance instance) {
  21. Dispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
  22. if (!dispatcher)
  23. return false;
  24. return dispatcher->permissions().HasPermission(PERMISSION_DEV);
  25. }
  26. uint32_t QuerySupportedFormats(PP_Instance instance) {
  27. if (!HasPrintingPermission(instance))
  28. return 0;
  29. uint32_t result = 0;
  30. HostDispatcher::GetForInstance(instance)->Send(
  31. new PpapiMsg_PPPPrinting_QuerySupportedFormats(API_ID_PPP_PRINTING,
  32. instance, &result));
  33. return result;
  34. }
  35. int32_t Begin(PP_Instance instance,
  36. const PP_PrintSettings_Dev* print_settings) {
  37. if (!HasPrintingPermission(instance))
  38. return 0;
  39. int32_t result = 0;
  40. HostDispatcher::GetForInstance(instance)->Send(new PpapiMsg_PPPPrinting_Begin(
  41. API_ID_PPP_PRINTING, instance, *print_settings, &result));
  42. return result;
  43. }
  44. PP_Resource PrintPages(PP_Instance instance,
  45. const PP_PrintPageNumberRange_Dev* page_ranges,
  46. uint32_t page_range_count) {
  47. if (!HasPrintingPermission(instance))
  48. return 0;
  49. std::vector<PP_PrintPageNumberRange_Dev> pages(
  50. page_ranges, page_ranges + page_range_count);
  51. HostResource result;
  52. HostDispatcher::GetForInstance(instance)->Send(
  53. new PpapiMsg_PPPPrinting_PrintPages(API_ID_PPP_PRINTING,
  54. instance, pages, &result));
  55. // Explicilty don't add a reference to the received resource here. The plugin
  56. // adds a ref during creation of the resource and it will "abandon" the
  57. // resource to release it, which ensures that the initial ref won't be
  58. // decremented. See the comment below in OnPluginMsgPrintPages.
  59. return result.host_resource();
  60. }
  61. void End(PP_Instance instance) {
  62. if (!HasPrintingPermission(instance))
  63. return;
  64. HostDispatcher::GetForInstance(instance)->Send(
  65. new PpapiMsg_PPPPrinting_End(API_ID_PPP_PRINTING, instance));
  66. }
  67. PP_Bool IsScalingDisabled(PP_Instance instance) {
  68. if (!HasPrintingPermission(instance))
  69. return PP_FALSE;
  70. bool result = false;
  71. HostDispatcher::GetForInstance(instance)->Send(
  72. new PpapiMsg_PPPPrinting_IsScalingDisabled(API_ID_PPP_PRINTING,
  73. instance, &result));
  74. return PP_FromBool(result);
  75. }
  76. const PPP_Printing_Dev ppp_printing_interface = {
  77. &QuerySupportedFormats,
  78. &Begin,
  79. &PrintPages,
  80. &End,
  81. &IsScalingDisabled
  82. };
  83. #else
  84. // The NaCl plugin doesn't need the host side interface - stub it out.
  85. static const PPP_Printing_Dev ppp_printing_interface = {};
  86. #endif // !defined(OS_NACL)
  87. } // namespace
  88. PPP_Printing_Proxy::PPP_Printing_Proxy(Dispatcher* dispatcher)
  89. : InterfaceProxy(dispatcher),
  90. ppp_printing_impl_(NULL) {
  91. if (dispatcher->IsPlugin()) {
  92. ppp_printing_impl_ = static_cast<const PPP_Printing_Dev*>(
  93. dispatcher->local_get_interface()(PPP_PRINTING_DEV_INTERFACE));
  94. }
  95. }
  96. PPP_Printing_Proxy::~PPP_Printing_Proxy() {
  97. }
  98. // static
  99. const PPP_Printing_Dev* PPP_Printing_Proxy::GetProxyInterface() {
  100. return &ppp_printing_interface;
  101. }
  102. bool PPP_Printing_Proxy::OnMessageReceived(const IPC::Message& msg) {
  103. if (!dispatcher()->IsPlugin())
  104. return false;
  105. bool handled = true;
  106. IPC_BEGIN_MESSAGE_MAP(PPP_Printing_Proxy, msg)
  107. IPC_MESSAGE_HANDLER(PpapiMsg_PPPPrinting_QuerySupportedFormats,
  108. OnPluginMsgQuerySupportedFormats)
  109. IPC_MESSAGE_HANDLER(PpapiMsg_PPPPrinting_Begin,
  110. OnPluginMsgBegin)
  111. IPC_MESSAGE_HANDLER(PpapiMsg_PPPPrinting_PrintPages,
  112. OnPluginMsgPrintPages)
  113. IPC_MESSAGE_HANDLER(PpapiMsg_PPPPrinting_End,
  114. OnPluginMsgEnd)
  115. IPC_MESSAGE_HANDLER(PpapiMsg_PPPPrinting_IsScalingDisabled,
  116. OnPluginMsgIsScalingDisabled)
  117. IPC_MESSAGE_UNHANDLED(handled = false)
  118. IPC_END_MESSAGE_MAP()
  119. return handled;
  120. }
  121. void PPP_Printing_Proxy::OnPluginMsgQuerySupportedFormats(PP_Instance instance,
  122. uint32_t* result) {
  123. if (ppp_printing_impl_) {
  124. *result = CallWhileUnlocked(ppp_printing_impl_->QuerySupportedFormats,
  125. instance);
  126. } else {
  127. *result = 0;
  128. }
  129. }
  130. void PPP_Printing_Proxy::OnPluginMsgBegin(PP_Instance instance,
  131. const PP_PrintSettings_Dev& settings,
  132. int32_t* result) {
  133. if (!ppp_printing_impl_) {
  134. *result = 0;
  135. return;
  136. }
  137. *result = CallWhileUnlocked(ppp_printing_impl_->Begin, instance, &settings);
  138. }
  139. void PPP_Printing_Proxy::OnPluginMsgPrintPages(
  140. PP_Instance instance,
  141. const std::vector<PP_PrintPageNumberRange_Dev>& pages,
  142. HostResource* result) {
  143. if (!ppp_printing_impl_ || pages.empty())
  144. return;
  145. PP_Resource plugin_resource = CallWhileUnlocked(
  146. ppp_printing_impl_->PrintPages,
  147. instance, &pages[0], base::checked_cast<uint32_t>(pages.size()));
  148. ResourceTracker* resource_tracker = PpapiGlobals::Get()->GetResourceTracker();
  149. Resource* resource_object = resource_tracker->GetResource(plugin_resource);
  150. if (!resource_object)
  151. return;
  152. *result = resource_object->host_resource();
  153. // Abandon the resource on the plugin side. This releases a reference to the
  154. // resource and allows the plugin side of the resource (the proxy resource) to
  155. // be destroyed without sending a message to the renderer notifing it that the
  156. // plugin has released the resource. This used to call
  157. // ResourceTracker::ReleaseResource directly which would trigger an IPC to be
  158. // sent to the renderer to remove a ref to the resource. However due to
  159. // arbitrary ordering of received sync/async IPCs in the renderer, this
  160. // sometimes resulted in the resource being destroyed in the renderer before
  161. // the renderer had a chance to add a reference to it. See crbug.com/490611.
  162. static_cast<PluginResourceTracker*>(resource_tracker)
  163. ->AbandonResource(plugin_resource);
  164. }
  165. void PPP_Printing_Proxy::OnPluginMsgEnd(PP_Instance instance) {
  166. if (ppp_printing_impl_)
  167. CallWhileUnlocked(ppp_printing_impl_->End, instance);
  168. }
  169. void PPP_Printing_Proxy::OnPluginMsgIsScalingDisabled(PP_Instance instance,
  170. bool* result) {
  171. if (ppp_printing_impl_) {
  172. *result = PP_ToBool(CallWhileUnlocked(ppp_printing_impl_->IsScalingDisabled,
  173. instance));
  174. } else {
  175. *result = false;
  176. }
  177. }
  178. } // namespace proxy
  179. } // namespace ppapi