Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(318)

Side by Side Diff: mojo/examples/png_viewer/png_viewer.cc

Issue 489493004: Update view manager to support content handling. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: blah to the blizzah Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « mojo/examples/nesting_app/nesting_app.cc ('k') | mojo/examples/window_manager/debug_panel.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <algorithm> 5 #include <algorithm>
6 6
7 #include "base/message_loop/message_loop.h" 7 #include "base/message_loop/message_loop.h"
8 #include "base/strings/string_tokenizer.h" 8 #include "base/strings/string_tokenizer.h"
9 #include "mojo/examples/media_viewer/media_viewer.mojom.h" 9 #include "mojo/examples/media_viewer/media_viewer.mojom.h"
10 #include "mojo/public/c/system/main.h" 10 #include "mojo/public/c/system/main.h"
11 #include "mojo/public/cpp/application/application_connection.h" 11 #include "mojo/public/cpp/application/application_connection.h"
12 #include "mojo/public/cpp/application/application_delegate.h" 12 #include "mojo/public/cpp/application/application_delegate.h"
13 #include "mojo/public/cpp/application/application_runner_chromium.h" 13 #include "mojo/public/cpp/application/application_runner_chromium.h"
14 #include "mojo/public/cpp/application/interface_factory_impl.h" 14 #include "mojo/public/cpp/application/interface_factory_impl.h"
15 #include "mojo/public/cpp/application/service_provider_impl.h"
15 #include "mojo/services/public/cpp/view_manager/types.h" 16 #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.h"
17 #include "mojo/services/public/cpp/view_manager/view_manager.h" 18 #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_client_factory.h"
19 #include "mojo/services/public/cpp/view_manager/view_manager_delegate.h" 20 #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/cpp/view_manager/view_observer.h"
21 #include "mojo/services/public/interfaces/navigation/navigation.mojom.h" 22 #include "mojo/services/public/interfaces/content_handler/content_handler.mojom. h"
22 #include "skia/ext/platform_canvas.h" 23 #include "skia/ext/platform_canvas.h"
23 #include "skia/ext/refptr.h" 24 #include "skia/ext/refptr.h"
24 #include "third_party/skia/include/core/SkBitmap.h" 25 #include "third_party/skia/include/core/SkBitmap.h"
25 #include "third_party/skia/include/core/SkCanvas.h" 26 #include "third_party/skia/include/core/SkCanvas.h"
26 #include "third_party/skia/include/core/SkPaint.h" 27 #include "third_party/skia/include/core/SkPaint.h"
27 #include "third_party/skia/include/core/SkScalar.h" 28 #include "third_party/skia/include/core/SkScalar.h"
28 #include "ui/gfx/codec/png_codec.h" 29 #include "ui/gfx/codec/png_codec.h"
29 30
30 namespace mojo { 31 namespace mojo {
31 namespace examples { 32 namespace examples {
32 33
33 class PNGViewer; 34 class PNGViewer;
34 35
36 // TODO(aa): Make zoom work again.
35 class ZoomableMediaImpl : public InterfaceImpl<ZoomableMedia> { 37 class ZoomableMediaImpl : public InterfaceImpl<ZoomableMedia> {
36 public: 38 public:
37 explicit ZoomableMediaImpl(PNGViewer* viewer) : viewer_(viewer) {} 39 explicit ZoomableMediaImpl(PNGViewer* viewer) : viewer_(viewer) {}
38 virtual ~ZoomableMediaImpl() {} 40 virtual ~ZoomableMediaImpl() {}
39 41
40 private: 42 private:
41 // Overridden from ZoomableMedia: 43 // Overridden from ZoomableMedia:
42 virtual void ZoomIn() OVERRIDE; 44 virtual void ZoomIn() OVERRIDE;
43 virtual void ZoomOut() OVERRIDE; 45 virtual void ZoomOut() OVERRIDE;
44 virtual void ZoomToActualSize() OVERRIDE; 46 virtual void ZoomToActualSize() OVERRIDE;
45 47
46 PNGViewer* viewer_; 48 PNGViewer* viewer_;
47 49
48 DISALLOW_COPY_AND_ASSIGN(ZoomableMediaImpl); 50 DISALLOW_COPY_AND_ASSIGN(ZoomableMediaImpl);
49 }; 51 };
50 52
51 class NavigatorImpl : public InterfaceImpl<Navigator> { 53 class PNGView : public ViewManagerDelegate,
54 public ViewObserver {
52 public: 55 public:
53 explicit NavigatorImpl(PNGViewer* viewer) : viewer_(viewer) {} 56 PNGView(ContentHandlerResponsePtr response,
54 virtual ~NavigatorImpl() {} 57 ServiceProviderImpl* exported_services,
58 scoped_ptr<ServiceProvider> imported_services)
59 : imported_services_(imported_services.Pass()),
60 root_(NULL),
61 view_manager_client_factory_(this),
62 zoom_percentage_(kDefaultZoomPercentage) {
63 exported_services->AddService(&view_manager_client_factory_);
64 DecodePNG(response.Pass());
65 }
55 66
56 private: 67 private:
57 // Overridden from Navigator: 68 static const uint16_t kMaxZoomPercentage = 400;
58 virtual void Navigate( 69 static const uint16_t kMinZoomPercentage = 20;
59 uint32_t view_id, 70 static const uint16_t kDefaultZoomPercentage = 100;
60 NavigationDetailsPtr navigation_details, 71 static const uint16_t kZoomStep = 20;
61 ResponseDetailsPtr response_details) OVERRIDE { 72
62 int content_length = GetContentLength(response_details->response->headers); 73 virtual ~PNGView() {
74 if (root_)
75 root_->RemoveObserver(this);
76 }
77
78 // Overridden from ViewManagerDelegate:
79 virtual void OnEmbed(ViewManager* view_manager,
80 View* root,
81 ServiceProviderImpl* exported_services,
82 scoped_ptr<ServiceProvider> imported_services) OVERRIDE {
83 root_ = root;
84 root_->AddObserver(this);
85 root_->SetColor(SK_ColorGRAY);
86 if (!bitmap_.isNull())
87 DrawBitmap();
88 }
89
90 virtual void OnViewManagerDisconnected(
91 ViewManager* view_manager) OVERRIDE {
92 // TODO(aa): Do we even need this?
93 }
94
95 // Overridden from ViewObserver:
96 virtual void OnViewBoundsChanged(View* view,
97 const gfx::Rect& old_bounds,
98 const gfx::Rect& new_bounds) OVERRIDE {
99 DCHECK_EQ(view, root_);
100 DrawBitmap();
101 }
102
103 virtual void OnViewDestroyed(View* view) OVERRIDE {
104 DCHECK_EQ(view, root_);
105 delete this;
106 }
107
108 void DecodePNG(ContentHandlerResponsePtr response) {
109 int content_length = GetContentLength(response->response->headers);
63 unsigned char* data = new unsigned char[content_length]; 110 unsigned char* data = new unsigned char[content_length];
64 unsigned char* buf = data; 111 unsigned char* buf = data;
65 uint32_t bytes_remaining = content_length; 112 uint32_t bytes_remaining = content_length;
66 uint32_t num_bytes = bytes_remaining; 113 uint32_t num_bytes = bytes_remaining;
67 while (bytes_remaining > 0) { 114 while (bytes_remaining > 0) {
68 MojoResult result = ReadDataRaw( 115 MojoResult result = ReadDataRaw(response->response->body.get(),
69 response_details->response->body.get(), 116 buf,
70 buf, 117 &num_bytes,
71 &num_bytes, 118 MOJO_READ_DATA_FLAG_NONE);
72 MOJO_READ_DATA_FLAG_NONE);
73 if (result == MOJO_RESULT_SHOULD_WAIT) { 119 if (result == MOJO_RESULT_SHOULD_WAIT) {
74 Wait(response_details->response->body.get(), 120 Wait(response->response->body.get(),
75 MOJO_HANDLE_SIGNAL_READABLE, 121 MOJO_HANDLE_SIGNAL_READABLE,
76 MOJO_DEADLINE_INDEFINITE); 122 MOJO_DEADLINE_INDEFINITE);
77 } else if (result == MOJO_RESULT_OK) { 123 } else if (result == MOJO_RESULT_OK) {
78 buf += num_bytes; 124 buf += num_bytes;
79 num_bytes = bytes_remaining -= num_bytes; 125 num_bytes = bytes_remaining -= num_bytes;
80 } else { 126 } else {
81 break; 127 break;
82 } 128 }
83 } 129 }
84 130
85 SkBitmap bitmap;
86 gfx::PNGCodec::Decode(static_cast<const unsigned char*>(data), 131 gfx::PNGCodec::Decode(static_cast<const unsigned char*>(data),
87 content_length, &bitmap); 132 content_length, &bitmap_);
88 UpdateView(view_id, bitmap);
89 133
134 // TODO(aa): Why is data not just on the stack?
90 delete[] data; 135 delete[] data;
91 } 136 }
92 137
93 void UpdateView(Id view_id, const SkBitmap& bitmap); 138 void DrawBitmap() {
139 if (!root_)
140 return;
94 141
95 int GetContentLength(const Array<String>& headers) { 142 skia::RefPtr<SkCanvas> canvas(skia::AdoptRef(skia::CreatePlatformCanvas(
96 for (size_t i = 0; i < headers.size(); ++i) { 143 root_->bounds().width(),
97 base::StringTokenizer t(headers[i], ": ;="); 144 root_->bounds().height(),
98 while (t.GetNext()) { 145 true)));
99 if (!t.token_is_delim() && t.token() == "Content-Length") { 146 canvas->drawColor(SK_ColorGRAY);
100 while (t.GetNext()) { 147 SkPaint paint;
101 if (!t.token_is_delim()) 148 SkScalar scale =
102 return atoi(t.token().c_str()); 149 SkFloatToScalar(zoom_percentage_ * 1.0f / kDefaultZoomPercentage);
103 } 150 canvas->scale(scale, scale);
104 } 151 canvas->drawBitmap(bitmap_, 0, 0, &paint);
105 } 152 root_->SetContents(skia::GetTopDevice(*canvas)->accessBitmap(true));
106 }
107 return 0;
108 }
109
110 PNGViewer* viewer_;
111
112 DISALLOW_COPY_AND_ASSIGN(NavigatorImpl);
113 };
114
115 class PNGViewer
116 : public ApplicationDelegate,
117 public ViewManagerDelegate,
118 public ViewObserver {
119 public:
120 PNGViewer()
121 : navigator_factory_(this),
122 zoomable_media_factory_(this),
123 view_manager_client_factory_(this),
124 root_(NULL),
125 zoom_percentage_(kDefaultZoomPercentage) {}
126 virtual ~PNGViewer() {
127 if (root_)
128 root_->RemoveObserver(this);
129 } 153 }
130 154
131 void UpdateView(Id view_id, const SkBitmap& bitmap) { 155 void UpdateView(Id view_id, const SkBitmap& bitmap) {
132 bitmap_ = bitmap; 156 bitmap_ = bitmap;
133 zoom_percentage_ = kDefaultZoomPercentage; 157 zoom_percentage_ = kDefaultZoomPercentage;
134 DrawBitmap(); 158 DrawBitmap();
135 } 159 }
136 160
137 void ZoomIn() { 161 void ZoomIn() {
138 if (zoom_percentage_ >= kMaxZoomPercentage) 162 if (zoom_percentage_ >= kMaxZoomPercentage)
139 return; 163 return;
140 zoom_percentage_ += kZoomStep; 164 zoom_percentage_ += kZoomStep;
141 DrawBitmap(); 165 DrawBitmap();
142 } 166 }
143 167
144 void ZoomOut() { 168 void ZoomOut() {
145 if (zoom_percentage_ <= kMinZoomPercentage) 169 if (zoom_percentage_ <= kMinZoomPercentage)
146 return; 170 return;
147 zoom_percentage_ -= kZoomStep; 171 zoom_percentage_ -= kZoomStep;
148 DrawBitmap(); 172 DrawBitmap();
149 } 173 }
150 174
151 void ZoomToActualSize() { 175 void ZoomToActualSize() {
152 if (zoom_percentage_ == kDefaultZoomPercentage) 176 if (zoom_percentage_ == kDefaultZoomPercentage)
153 return; 177 return;
154 zoom_percentage_ = kDefaultZoomPercentage; 178 zoom_percentage_ = kDefaultZoomPercentage;
155 DrawBitmap(); 179 DrawBitmap();
156 } 180 }
157 181
182 int GetContentLength(const Array<String>& headers) {
183 for (size_t i = 0; i < headers.size(); ++i) {
184 base::StringTokenizer t(headers[i], ": ;=");
185 while (t.GetNext()) {
186 if (!t.token_is_delim() && t.token() == "Content-Length") {
187 while (t.GetNext()) {
188 if (!t.token_is_delim())
189 return atoi(t.token().c_str());
190 }
191 }
192 }
193 }
194 return 0;
195 }
196
197 SkBitmap bitmap_;
198 scoped_ptr<ServiceProvider> imported_services_;
199 View* root_;
200 ViewManagerClientFactory view_manager_client_factory_;
201 uint16_t zoom_percentage_;
202
203 DISALLOW_COPY_AND_ASSIGN(PNGView);
204 };
205
206 class ContentHandlerImpl : public InterfaceImpl<ContentHandler> {
207 public:
208 explicit ContentHandlerImpl(ApplicationConnection* application_connection)
209 : application_connection_(application_connection) {
210 }
211 virtual ~ContentHandlerImpl() {}
212
158 private: 213 private:
159 static const uint16_t kMaxZoomPercentage = 400; 214 // Overridden from ContentHandler:
160 static const uint16_t kMinZoomPercentage = 20; 215 virtual void OnConnect(
161 static const uint16_t kDefaultZoomPercentage = 100; 216 const mojo::String& url,
162 static const uint16_t kZoomStep = 20; 217 ContentHandlerResponsePtr response,
218 InterfaceRequest<ServiceProvider> service_provider) OVERRIDE {
219 ServiceProviderImpl* exported_services =
220 new ServiceProviderImpl(application_connection_);
221 BindToRequest(exported_services, &service_provider);
222 scoped_ptr<ServiceProvider> remote(
223 exported_services->CreateRemoteServiceProvider());
224 new PNGView(response.Pass(), exported_services, remote.Pass());
225 }
163 226
227 ApplicationConnection* application_connection_;
228
229 DISALLOW_COPY_AND_ASSIGN(ContentHandlerImpl);
230 };
231
232 class PNGViewer : public ApplicationDelegate {
233 public:
234 PNGViewer() : content_handler_factory_(NULL) {
235 }
236 private:
164 // Overridden from ApplicationDelegate: 237 // Overridden from ApplicationDelegate:
165 virtual bool ConfigureIncomingConnection(ApplicationConnection* connection) 238 virtual bool ConfigureIncomingConnection(ApplicationConnection* connection)
166 MOJO_OVERRIDE { 239 MOJO_OVERRIDE {
167 connection->AddService(&navigator_factory_); 240 content_handler_factory_.set_context(connection);
168 connection->AddService(&zoomable_media_factory_); 241 connection->AddService(&content_handler_factory_);
169 connection->AddService(&view_manager_client_factory_);
170 return true; 242 return true;
171 } 243 }
172 244
173 // Overridden from ViewManagerDelegate: 245 InterfaceFactoryImplWithContext<
174 virtual void OnEmbed(ViewManager* view_manager, 246 ContentHandlerImpl, ApplicationConnection> content_handler_factory_;
175 View* root,
176 ServiceProviderImpl* exported_services,
177 scoped_ptr<ServiceProvider> imported_services) OVERRIDE {
178 root_ = root;
179 root_->AddObserver(this);
180 root_->SetColor(SK_ColorGRAY);
181 if (!bitmap_.isNull())
182 DrawBitmap();
183 }
184 virtual void OnViewManagerDisconnected(
185 ViewManager* view_manager) OVERRIDE {
186 base::MessageLoop::current()->Quit();
187 }
188
189 void DrawBitmap() {
190 if (!root_)
191 return;
192
193 skia::RefPtr<SkCanvas> canvas(skia::AdoptRef(skia::CreatePlatformCanvas(
194 root_->bounds().width(),
195 root_->bounds().height(),
196 true)));
197 canvas->drawColor(SK_ColorGRAY);
198 SkPaint paint;
199 SkScalar scale =
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));
204 }
205
206 // ViewObserver:
207 virtual void OnViewBoundsChanged(View* view,
208 const gfx::Rect& old_bounds,
209 const gfx::Rect& new_bounds) OVERRIDE {
210 DCHECK_EQ(view, root_);
211 DrawBitmap();
212 }
213 virtual void OnViewDestroyed(View* view) OVERRIDE {
214 DCHECK_EQ(view, root_);
215 view->RemoveObserver(this);
216 root_ = NULL;
217 }
218
219 InterfaceFactoryImplWithContext<NavigatorImpl, PNGViewer> navigator_factory_;
220 InterfaceFactoryImplWithContext<ZoomableMediaImpl, PNGViewer>
221 zoomable_media_factory_;
222 ViewManagerClientFactory view_manager_client_factory_;
223
224 View* root_;
225 SkBitmap bitmap_;
226 uint16_t zoom_percentage_;
227 247
228 DISALLOW_COPY_AND_ASSIGN(PNGViewer); 248 DISALLOW_COPY_AND_ASSIGN(PNGViewer);
229 }; 249 };
230 250
231 void ZoomableMediaImpl::ZoomIn() {
232 viewer_->ZoomIn();
233 }
234
235 void ZoomableMediaImpl::ZoomOut() {
236 viewer_->ZoomOut();
237 }
238
239 void ZoomableMediaImpl::ZoomToActualSize() {
240 viewer_->ZoomToActualSize();
241 }
242
243 void NavigatorImpl::UpdateView(Id view_id,
244 const SkBitmap& bitmap) {
245 viewer_->UpdateView(view_id, bitmap);
246 }
247
248 } // namespace examples 251 } // namespace examples
249 } // namespace mojo 252 } // namespace mojo
250 253
251 MojoResult MojoMain(MojoHandle shell_handle) { 254 MojoResult MojoMain(MojoHandle shell_handle) {
252 mojo::ApplicationRunnerChromium runner(new mojo::examples::PNGViewer); 255 mojo::ApplicationRunnerChromium runner(new mojo::examples::PNGViewer);
253 return runner.Run(shell_handle); 256 return runner.Run(shell_handle);
254 } 257 }
OLDNEW
« no previous file with comments | « mojo/examples/nesting_app/nesting_app.cc ('k') | mojo/examples/window_manager/debug_panel.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698