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