1 // Copyright 2014 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.
7 #include "base/message_loop/message_loop.h"
8 #include "base/strings/string_tokenizer.h"
9 #include "mojo/examples/media_viewer/media_viewer.mojom.h"
10 #include "mojo/public/c/system/main.h"
11 #include "mojo/public/cpp/application/application_connection.h"
12 #include "mojo/public/cpp/application/application_delegate.h"
13 #include "mojo/public/cpp/application/application_runner_chromium.h"
14 #include "mojo/public/cpp/application/interface_factory_impl.h"
15 #include "mojo/services/public/cpp/view_manager/types.h"
16 #include "mojo/services/public/cpp/view_manager/view.h"
17 #include "mojo/services/public/cpp/view_manager/view_manager.h"
18 #include "mojo/services/public/cpp/view_manager/view_manager_client_factory.h"
19 #include "mojo/services/public/cpp/view_manager/view_manager_delegate.h"
20 #include "mojo/services/public/cpp/view_manager/view_observer.h"
21 #include "mojo/services/public/interfaces/navigation/navigation.mojom.h"
22 #include "skia/ext/platform_canvas.h"
23 #include "skia/ext/refptr.h"
24 #include "third_party/skia/include/core/SkBitmap.h"
25 #include "third_party/skia/include/core/SkCanvas.h"
26 #include "third_party/skia/include/core/SkPaint.h"
27 #include "third_party/skia/include/core/SkScalar.h"
28 #include "ui/gfx/codec/png_codec.h"
35 class ZoomableMediaImpl
: public InterfaceImpl
<ZoomableMedia
> {
37 explicit ZoomableMediaImpl(PNGViewer
* viewer
) : viewer_(viewer
) {}
38 virtual ~ZoomableMediaImpl() {}
41 // Overridden from ZoomableMedia:
42 virtual void ZoomIn() OVERRIDE
;
43 virtual void ZoomOut() OVERRIDE
;
44 virtual void ZoomToActualSize() OVERRIDE
;
48 DISALLOW_COPY_AND_ASSIGN(ZoomableMediaImpl
);
51 class NavigatorImpl
: public InterfaceImpl
<Navigator
> {
53 explicit NavigatorImpl(PNGViewer
* viewer
) : viewer_(viewer
) {}
54 virtual ~NavigatorImpl() {}
57 // Overridden from Navigator:
58 virtual void Navigate(
60 NavigationDetailsPtr navigation_details
,
61 ResponseDetailsPtr response_details
) OVERRIDE
{
62 int content_length
= GetContentLength(response_details
->response
->headers
);
63 unsigned char* data
= new unsigned char[content_length
];
64 unsigned char* buf
= data
;
65 uint32_t bytes_remaining
= content_length
;
66 uint32_t num_bytes
= bytes_remaining
;
67 while (bytes_remaining
> 0) {
68 MojoResult result
= ReadDataRaw(
69 response_details
->response
->body
.get(),
72 MOJO_READ_DATA_FLAG_NONE
);
73 if (result
== MOJO_RESULT_SHOULD_WAIT
) {
74 Wait(response_details
->response
->body
.get(),
75 MOJO_HANDLE_SIGNAL_READABLE
,
76 MOJO_DEADLINE_INDEFINITE
);
77 } else if (result
== MOJO_RESULT_OK
) {
79 num_bytes
= bytes_remaining
-= num_bytes
;
86 gfx::PNGCodec::Decode(static_cast<const unsigned char*>(data
),
87 content_length
, &bitmap
);
88 UpdateView(view_id
, bitmap
);
93 void UpdateView(Id view_id
, const SkBitmap
& bitmap
);
95 int GetContentLength(const Array
<String
>& headers
) {
96 for (size_t i
= 0; i
< headers
.size(); ++i
) {
97 base::StringTokenizer
t(headers
[i
], ": ;=");
99 if (!t
.token_is_delim() && t
.token() == "Content-Length") {
100 while (t
.GetNext()) {
101 if (!t
.token_is_delim())
102 return atoi(t
.token().c_str());
112 DISALLOW_COPY_AND_ASSIGN(NavigatorImpl
);
116 : public ApplicationDelegate
,
117 public ViewManagerDelegate
,
118 public ViewObserver
{
121 : navigator_factory_(this),
122 zoomable_media_factory_(this),
123 view_manager_client_factory_(this),
125 zoom_percentage_(kDefaultZoomPercentage
) {}
126 virtual ~PNGViewer() {
128 root_
->RemoveObserver(this);
131 void UpdateView(Id view_id
, const SkBitmap
& bitmap
) {
133 zoom_percentage_
= kDefaultZoomPercentage
;
138 if (zoom_percentage_
>= kMaxZoomPercentage
)
140 zoom_percentage_
+= kZoomStep
;
145 if (zoom_percentage_
<= kMinZoomPercentage
)
147 zoom_percentage_
-= kZoomStep
;
151 void ZoomToActualSize() {
152 if (zoom_percentage_
== kDefaultZoomPercentage
)
154 zoom_percentage_
= kDefaultZoomPercentage
;
159 static const uint16_t kMaxZoomPercentage
= 400;
160 static const uint16_t kMinZoomPercentage
= 20;
161 static const uint16_t kDefaultZoomPercentage
= 100;
162 static const uint16_t kZoomStep
= 20;
164 // Overridden from ApplicationDelegate:
165 virtual bool ConfigureIncomingConnection(ApplicationConnection
* connection
)
167 connection
->AddService(&navigator_factory_
);
168 connection
->AddService(&zoomable_media_factory_
);
169 connection
->AddService(&view_manager_client_factory_
);
173 // Overridden from ViewManagerDelegate:
174 virtual void OnEmbed(ViewManager
* view_manager
,
176 ServiceProviderImpl
* exported_services
,
177 scoped_ptr
<ServiceProvider
> imported_services
) OVERRIDE
{
179 root_
->AddObserver(this);
180 root_
->SetColor(SK_ColorGRAY
);
181 if (!bitmap_
.isNull())
184 virtual void OnViewManagerDisconnected(
185 ViewManager
* view_manager
) OVERRIDE
{
186 base::MessageLoop::current()->Quit();
193 skia::RefPtr
<SkCanvas
> canvas(skia::AdoptRef(skia::CreatePlatformCanvas(
194 root_
->bounds().width(),
195 root_
->bounds().height(),
197 canvas
->drawColor(SK_ColorGRAY
);
200 SkFloatToScalar(zoom_percentage_
* 1.0f
/ kDefaultZoomPercentage
);
201 canvas
->scale(scale
, scale
);
202 canvas
->drawBitmap(bitmap_
, 0, 0, &paint
);
203 root_
->SetContents(skia::GetTopDevice(*canvas
)->accessBitmap(true));
207 virtual void OnViewBoundsChanged(View
* view
,
208 const gfx::Rect
& old_bounds
,
209 const gfx::Rect
& new_bounds
) OVERRIDE
{
210 DCHECK_EQ(view
, root_
);
213 virtual void OnViewDestroyed(View
* view
) OVERRIDE
{
214 DCHECK_EQ(view
, root_
);
215 view
->RemoveObserver(this);
219 InterfaceFactoryImplWithContext
<NavigatorImpl
, PNGViewer
> navigator_factory_
;
220 InterfaceFactoryImplWithContext
<ZoomableMediaImpl
, PNGViewer
>
221 zoomable_media_factory_
;
222 ViewManagerClientFactory view_manager_client_factory_
;
226 uint16_t zoom_percentage_
;
228 DISALLOW_COPY_AND_ASSIGN(PNGViewer
);
231 void ZoomableMediaImpl::ZoomIn() {
235 void ZoomableMediaImpl::ZoomOut() {
239 void ZoomableMediaImpl::ZoomToActualSize() {
240 viewer_
->ZoomToActualSize();
243 void NavigatorImpl::UpdateView(Id view_id
,
244 const SkBitmap
& bitmap
) {
245 viewer_
->UpdateView(view_id
, bitmap
);
248 } // namespace examples
251 MojoResult
MojoMain(MojoHandle shell_handle
) {
252 mojo::ApplicationRunnerChromium
runner(new mojo::examples::PNGViewer
);
253 return runner
.Run(shell_handle
);