ppp_printing_proxy.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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/ppp_printing_proxy.h" 6 7#include <string.h> 8 9#include "ppapi/c/dev/ppp_printing_dev.h" 10#include "ppapi/proxy/host_dispatcher.h" 11#include "ppapi/proxy/plugin_dispatcher.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 17namespace ppapi { 18namespace proxy { 19 20namespace { 21 22uint32_t QuerySupportedFormats(PP_Instance instance) { 23 uint32_t result = 0; 24 HostDispatcher::GetForInstance(instance)->Send( 25 new PpapiMsg_PPPPrinting_QuerySupportedFormats(API_ID_PPP_PRINTING, 26 instance, &result)); 27 return result; 28} 29 30int32_t Begin(PP_Instance instance, 31 const struct PP_PrintSettings_Dev* print_settings) { 32 // Settings is just serialized as a string. 33 std::string settings_string; 34 settings_string.resize(sizeof(*print_settings)); 35 memcpy(&settings_string[0], print_settings, sizeof(*print_settings)); 36 37 int32_t result = 0; 38 HostDispatcher::GetForInstance(instance)->Send( 39 new PpapiMsg_PPPPrinting_Begin(API_ID_PPP_PRINTING, instance, 40 settings_string, &result)); 41 return result; 42} 43 44PP_Resource PrintPages(PP_Instance instance, 45 const PP_PrintPageNumberRange_Dev* page_ranges, 46 uint32_t page_range_count) { 47 std::vector<PP_PrintPageNumberRange_Dev> pages( 48 page_ranges, page_ranges + page_range_count); 49 50 HostResource result; 51 HostDispatcher::GetForInstance(instance)->Send( 52 new PpapiMsg_PPPPrinting_PrintPages(API_ID_PPP_PRINTING, 53 instance, pages, &result)); 54 55 // How refcounting works when returning a resource: 56 // 57 // The plugin in the plugin process makes a resource that it returns to the 58 // browser. The plugin proxy code returns that ref to us and asynchronously 59 // releases it. Before any release message associated with that operation 60 // comes, we'll get this reply. We need to add one ref since our caller 61 // expects us to add one ref for it to consume. 62 PpapiGlobals::Get()->GetResourceTracker()->AddRefResource( 63 result.host_resource()); 64 return result.host_resource(); 65} 66 67void End(PP_Instance instance) { 68 HostDispatcher::GetForInstance(instance)->Send( 69 new PpapiMsg_PPPPrinting_End(API_ID_PPP_PRINTING, instance)); 70} 71 72PP_Bool IsScalingDisabled(PP_Instance instance) { 73 bool result = false; 74 HostDispatcher::GetForInstance(instance)->Send( 75 new PpapiMsg_PPPPrinting_IsScalingDisabled(API_ID_PPP_PRINTING, 76 instance, &result)); 77 return PP_FromBool(result); 78} 79 80const PPP_Printing_Dev ppp_printing_interface = { 81 &QuerySupportedFormats, 82 &Begin, 83 &PrintPages, 84 &End, 85 &IsScalingDisabled 86}; 87 88} // namespace 89 90PPP_Printing_Proxy::PPP_Printing_Proxy(Dispatcher* dispatcher) 91 : InterfaceProxy(dispatcher), 92 ppp_printing_impl_(NULL) { 93 if (dispatcher->IsPlugin()) { 94 ppp_printing_impl_ = static_cast<const PPP_Printing_Dev*>( 95 dispatcher->local_get_interface()(PPP_PRINTING_DEV_INTERFACE)); 96 } 97} 98 99PPP_Printing_Proxy::~PPP_Printing_Proxy() { 100} 101 102// static 103const PPP_Printing_Dev* PPP_Printing_Proxy::GetProxyInterface() { 104 return &ppp_printing_interface; 105} 106 107bool PPP_Printing_Proxy::OnMessageReceived(const IPC::Message& msg) { 108 bool handled = true; 109 IPC_BEGIN_MESSAGE_MAP(PPP_Printing_Proxy, msg) 110 IPC_MESSAGE_HANDLER(PpapiMsg_PPPPrinting_QuerySupportedFormats, 111 OnPluginMsgQuerySupportedFormats) 112 IPC_MESSAGE_HANDLER(PpapiMsg_PPPPrinting_Begin, 113 OnPluginMsgBegin) 114 IPC_MESSAGE_HANDLER(PpapiMsg_PPPPrinting_PrintPages, 115 OnPluginMsgPrintPages) 116 IPC_MESSAGE_HANDLER(PpapiMsg_PPPPrinting_End, 117 OnPluginMsgEnd) 118 IPC_MESSAGE_HANDLER(PpapiMsg_PPPPrinting_IsScalingDisabled, 119 OnPluginMsgIsScalingDisabled) 120 IPC_MESSAGE_UNHANDLED(handled = false) 121 IPC_END_MESSAGE_MAP() 122 return handled; 123} 124 125void PPP_Printing_Proxy::OnPluginMsgQuerySupportedFormats(PP_Instance instance, 126 uint32_t* result) { 127 if (ppp_printing_impl_) 128 *result = ppp_printing_impl_->QuerySupportedFormats(instance); 129 else 130 *result = 0; 131} 132 133void PPP_Printing_Proxy::OnPluginMsgBegin(PP_Instance instance, 134 const std::string& settings_string, 135 int32_t* result) { 136 *result = 0; 137 138 PP_PrintSettings_Dev settings; 139 if (settings_string.size() != sizeof(settings)) 140 return; 141 memcpy(&settings, &settings_string[0], sizeof(settings)); 142 143 if (ppp_printing_impl_) 144 *result = ppp_printing_impl_->Begin(instance, &settings); 145} 146 147void PPP_Printing_Proxy::OnPluginMsgPrintPages( 148 PP_Instance instance, 149 const std::vector<PP_PrintPageNumberRange_Dev>& pages, 150 HostResource* result) { 151 if (!ppp_printing_impl_ || pages.empty()) 152 return; 153 154 PP_Resource plugin_resource = ppp_printing_impl_->PrintPages( 155 instance, &pages[0], static_cast<uint32_t>(pages.size())); 156 ResourceTracker* resource_tracker = PpapiGlobals::Get()->GetResourceTracker(); 157 Resource* resource_object = resource_tracker->GetResource(plugin_resource); 158 if (!resource_object) 159 return; 160 161 *result = resource_object->host_resource(); 162 163 // See PrintPages above for how refcounting works. 164 resource_tracker->ReleaseResourceSoon(plugin_resource); 165} 166 167void PPP_Printing_Proxy::OnPluginMsgEnd(PP_Instance instance) { 168 if (ppp_printing_impl_) 169 ppp_printing_impl_->End(instance); 170} 171 172void PPP_Printing_Proxy::OnPluginMsgIsScalingDisabled(PP_Instance instance, 173 bool* result) { 174 if (ppp_printing_impl_) 175 *result = PP_ToBool(ppp_printing_impl_->IsScalingDisabled(instance)); 176 else 177 *result = false; 178} 179 180} // namespace proxy 181} // namespace ppapi 182