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

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

Issue 741453002: Make sure that Content Handled application can be connected multiple times. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 6 years, 1 month 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
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/macros.h" 7 #include "base/macros.h"
8 #include "base/memory/scoped_ptr.h" 8 #include "base/memory/scoped_ptr.h"
9 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/string_tokenizer.h" 10 #include "base/strings/string_tokenizer.h"
(...skipping 13 matching lines...) Expand all
24 #include "mojo/services/public/cpp/view_manager/view_manager_client_factory.h" 24 #include "mojo/services/public/cpp/view_manager/view_manager_client_factory.h"
25 #include "mojo/services/public/cpp/view_manager/view_manager_delegate.h" 25 #include "mojo/services/public/cpp/view_manager/view_manager_delegate.h"
26 #include "mojo/services/public/cpp/view_manager/view_observer.h" 26 #include "mojo/services/public/cpp/view_manager/view_observer.h"
27 #include "mojo/services/public/interfaces/content_handler/content_handler.mojom. h" 27 #include "mojo/services/public/interfaces/content_handler/content_handler.mojom. h"
28 #include "third_party/skia/include/core/SkColor.h" 28 #include "third_party/skia/include/core/SkColor.h"
29 #include "ui/gfx/codec/png_codec.h" 29 #include "ui/gfx/codec/png_codec.h"
30 30
31 namespace mojo { 31 namespace mojo {
32 namespace examples { 32 namespace examples {
33 33
34 namespace {
35
36 class EmbedderData {
37 public:
38 EmbedderData(Shell* shell, View* root) : bitmap_uploader_(root) {
39 bitmap_uploader_.Init(shell);
40 bitmap_uploader_.SetColor(SK_ColorGRAY);
41 }
42
43 BitmapUploader& bitmap_uploader() { return bitmap_uploader_; }
44
45 private:
46 BitmapUploader bitmap_uploader_;
47
48 DISALLOW_COPY_AND_ASSIGN(EmbedderData);
49 };
50
51 } // namespace
52
34 // TODO(aa): Hook up ZoomableMedia interface again. 53 // TODO(aa): Hook up ZoomableMedia interface again.
35 class PNGView : public ApplicationDelegate, 54 class PNGView : public ApplicationDelegate,
36 public ViewManagerDelegate, 55 public ViewManagerDelegate,
37 public ViewObserver { 56 public ViewObserver {
38 public: 57 public:
39 PNGView(URLResponsePtr response) 58 PNGView(URLResponsePtr response)
40 : width_(0), 59 : width_(0),
41 height_(0), 60 height_(0),
42 app_(nullptr), 61 app_(nullptr),
43 root_(nullptr),
44 zoom_percentage_(kDefaultZoomPercentage) { 62 zoom_percentage_(kDefaultZoomPercentage) {
45 DecodePNG(response.Pass()); 63 DecodePNG(response.Pass());
46 } 64 }
47 65
48 virtual ~PNGView() { 66 virtual ~PNGView() {
49 if (root_) 67 for (auto& roots : embedder_for_roots_) {
50 root_->RemoveObserver(this); 68 roots.first->RemoveObserver(this);
69 delete roots.second;
70 }
51 } 71 }
52 72
53 private: 73 private:
54 static const uint16_t kMaxZoomPercentage = 400; 74 static const uint16_t kMaxZoomPercentage = 400;
55 static const uint16_t kMinZoomPercentage = 20; 75 static const uint16_t kMinZoomPercentage = 20;
56 static const uint16_t kDefaultZoomPercentage = 100; 76 static const uint16_t kDefaultZoomPercentage = 100;
57 static const uint16_t kZoomStep = 20; 77 static const uint16_t kZoomStep = 20;
58 78
59 // Overridden from ApplicationDelegate: 79 // Overridden from ApplicationDelegate:
60 virtual void Initialize(ApplicationImpl* app) override { 80 virtual void Initialize(ApplicationImpl* app) override {
61 app_ = app; 81 app_ = app;
62 view_manager_client_factory_.reset( 82 view_manager_client_factory_.reset(
63 new ViewManagerClientFactory(app->shell(), this)); 83 new ViewManagerClientFactory(app->shell(), this));
64 } 84 }
65 85
66 // Overridden from ApplicationDelegate: 86 // Overridden from ApplicationDelegate:
67 virtual bool ConfigureIncomingConnection( 87 virtual bool ConfigureIncomingConnection(
68 ApplicationConnection* connection) override { 88 ApplicationConnection* connection) override {
69 connection->AddService(view_manager_client_factory_.get()); 89 connection->AddService(view_manager_client_factory_.get());
70 return true; 90 return true;
71 } 91 }
72 92
73 // Overridden from ViewManagerDelegate: 93 // Overridden from ViewManagerDelegate:
74 virtual void OnEmbed(ViewManager* view_manager, 94 virtual void OnEmbed(ViewManager* view_manager,
75 View* root, 95 View* root,
76 ServiceProviderImpl* exported_services, 96 ServiceProviderImpl* exported_services,
77 scoped_ptr<ServiceProvider> imported_services) override { 97 scoped_ptr<ServiceProvider> imported_services) override {
78 // TODO(qsr): The same view should be embeddable on multiple views. 98 // TODO(qsr): The same view should be embeddable on multiple views.
79 DCHECK(!root_); 99 DCHECK(embedder_for_roots_.find(root) == embedder_for_roots_.end());
80 root_ = root; 100 root->AddObserver(this);
81 root_->AddObserver(this); 101 EmbedderData* embedder_data = new EmbedderData(app_->shell(), root);
82 bitmap_uploader_.reset(new BitmapUploader(root_)); 102 embedder_for_roots_[root] = embedder_data;
83 bitmap_uploader_->Init(app_->shell()); 103 embedder_data->bitmap_uploader().SetBitmap(
84 bitmap_uploader_->SetColor(SK_ColorGRAY); 104 width_, height_,
85 if (bitmap_.get()) 105 make_scoped_ptr(new std::vector<unsigned char>(*bitmap_)),
86 DrawBitmap(); 106 BitmapUploader::BGRA);
87 } 107 }
88 108
89 virtual void OnViewManagerDisconnected(ViewManager* view_manager) override { 109 virtual void OnViewManagerDisconnected(ViewManager* view_manager) override {
90 // TODO(aa): Need to figure out how shutdown works. 110 // TODO(aa): Need to figure out how shutdown works.
Aaron Boodman 2014/11/19 15:58:15 Can you remove this comment? Or move it to OnViewD
qsr 2014/11/19 16:37:21 Done.
91 } 111 }
92 112
93 // Overridden from ViewObserver: 113 // Overridden from ViewObserver:
94 virtual void OnViewBoundsChanged(View* view, 114 virtual void OnViewBoundsChanged(View* view,
95 const Rect& old_bounds, 115 const Rect& old_bounds,
96 const Rect& new_bounds) override { 116 const Rect& new_bounds) override {
97 DCHECK_EQ(view, root_); 117 DCHECK(embedder_for_roots_.find(view) != embedder_for_roots_.end());
98 DrawBitmap();
99 } 118 }
100 119
101 virtual void OnViewDestroyed(View* view) override { 120 virtual void OnViewDestroyed(View* view) override {
102 DCHECK_EQ(view, root_); 121 const auto& it = embedder_for_roots_.find(view);
103 // TODO(qsr): It should not be necessary to cleanup the uploader, but it 122 DCHECK(it != embedder_for_roots_.end());
104 // crashes if the GL context goes away. 123 delete it->second;
105 bitmap_uploader_.reset(); 124 embedder_for_roots_.erase(it);
106 ApplicationImpl::Terminate(); 125 if (embedder_for_roots_.size() == 0)
107 } 126 ApplicationImpl::Terminate();
Aaron Boodman 2014/11/18 23:46:15 Out of scope for this CL, but I don't think this i
qsr 2014/11/19 13:42:37 Can you elaborate? I can always change it in a nex
Aaron Boodman 2014/11/19 15:58:15 This depends on the order you receive OnEmbed() an
qsr 2014/11/19 16:37:21 Hum... I really hope I can count on receiving OnEm
Aaron Boodman 2014/11/20 00:59:01 No what I mean is that, during navigation for exam
108
109 void DrawBitmap() {
110 if (!root_)
111 return;
112
113 bitmap_uploader_->SetBitmap(
114 width_, height_, bitmap_.Pass(), BitmapUploader::BGRA);
115 } 127 }
116 128
117 void ZoomIn() { 129 void ZoomIn() {
130 // TODO(qsr,aa) Zoom should be per embedder view.
118 if (zoom_percentage_ >= kMaxZoomPercentage) 131 if (zoom_percentage_ >= kMaxZoomPercentage)
119 return; 132 return;
120 zoom_percentage_ += kZoomStep; 133 zoom_percentage_ += kZoomStep;
121 DrawBitmap();
122 } 134 }
123 135
124 void ZoomOut() { 136 void ZoomOut() {
125 if (zoom_percentage_ <= kMinZoomPercentage) 137 if (zoom_percentage_ <= kMinZoomPercentage)
126 return; 138 return;
127 zoom_percentage_ -= kZoomStep; 139 zoom_percentage_ -= kZoomStep;
128 DrawBitmap();
129 } 140 }
130 141
131 void ZoomToActualSize() { 142 void ZoomToActualSize() {
132 if (zoom_percentage_ == kDefaultZoomPercentage) 143 if (zoom_percentage_ == kDefaultZoomPercentage)
133 return; 144 return;
134 zoom_percentage_ = kDefaultZoomPercentage; 145 zoom_percentage_ = kDefaultZoomPercentage;
135 DrawBitmap();
136 } 146 }
137 147
138 void DecodePNG(URLResponsePtr response) { 148 void DecodePNG(URLResponsePtr response) {
139 int content_length = GetContentLength(response->headers); 149 int content_length = GetContentLength(response->headers);
140 scoped_ptr<unsigned char[]> data(new unsigned char[content_length]); 150 scoped_ptr<unsigned char[]> data(new unsigned char[content_length]);
141 unsigned char* buf = data.get(); 151 unsigned char* buf = data.get();
142 uint32_t bytes_remaining = content_length; 152 uint32_t bytes_remaining = content_length;
143 uint32_t num_bytes = bytes_remaining; 153 uint32_t num_bytes = bytes_remaining;
144 while (bytes_remaining > 0) { 154 while (bytes_remaining > 0) {
145 MojoResult result = ReadDataRaw( 155 MojoResult result = ReadDataRaw(response->body.get(), buf, &num_bytes,
146 response->body.get(), buf, &num_bytes, MOJO_READ_DATA_FLAG_NONE); 156 MOJO_READ_DATA_FLAG_NONE);
147 if (result == MOJO_RESULT_SHOULD_WAIT) { 157 if (result == MOJO_RESULT_SHOULD_WAIT) {
148 Wait(response->body.get(), 158 Wait(response->body.get(), MOJO_HANDLE_SIGNAL_READABLE,
149 MOJO_HANDLE_SIGNAL_READABLE,
150 MOJO_DEADLINE_INDEFINITE); 159 MOJO_DEADLINE_INDEFINITE);
151 } else if (result == MOJO_RESULT_OK) { 160 } else if (result == MOJO_RESULT_OK) {
152 buf += num_bytes; 161 buf += num_bytes;
153 num_bytes = bytes_remaining -= num_bytes; 162 num_bytes = bytes_remaining -= num_bytes;
154 } else { 163 } else {
155 break; 164 break;
156 } 165 }
157 } 166 }
158 167
159 bitmap_.reset(new std::vector<unsigned char>); 168 bitmap_.reset(new std::vector<unsigned char>);
160 gfx::PNGCodec::Decode(static_cast<const unsigned char*>(data.get()), 169 gfx::PNGCodec::Decode(static_cast<const unsigned char*>(data.get()),
161 content_length, 170 content_length, gfx::PNGCodec::FORMAT_BGRA,
162 gfx::PNGCodec::FORMAT_BGRA, 171 bitmap_.get(), &width_, &height_);
163 bitmap_.get(),
164 &width_,
165 &height_);
166 } 172 }
167 173
168 int GetContentLength(const Array<String>& headers) { 174 int GetContentLength(const Array<String>& headers) {
169 for (size_t i = 0; i < headers.size(); ++i) { 175 for (size_t i = 0; i < headers.size(); ++i) {
170 base::StringTokenizer t(headers[i], ": ;="); 176 base::StringTokenizer t(headers[i], ": ;=");
171 while (t.GetNext()) { 177 while (t.GetNext()) {
172 if (!t.token_is_delim() && t.token() == "Content-Length") { 178 if (!t.token_is_delim() && t.token() == "Content-Length") {
173 while (t.GetNext()) { 179 while (t.GetNext()) {
174 if (!t.token_is_delim()) 180 if (!t.token_is_delim())
175 return atoi(t.token().c_str()); 181 return atoi(t.token().c_str());
176 } 182 }
177 } 183 }
178 } 184 }
179 } 185 }
180 return 0; 186 return 0;
181 } 187 }
182 188
183 int width_; 189 int width_;
184 int height_; 190 int height_;
185 scoped_ptr<std::vector<unsigned char>> bitmap_; 191 scoped_ptr<std::vector<unsigned char>> bitmap_;
186 ApplicationImpl* app_; 192 ApplicationImpl* app_;
187 View* root_; 193 std::map<View*, EmbedderData*> embedder_for_roots_;
188 scoped_ptr<ViewManagerClientFactory> view_manager_client_factory_; 194 scoped_ptr<ViewManagerClientFactory> view_manager_client_factory_;
189 uint16_t zoom_percentage_; 195 uint16_t zoom_percentage_;
190 scoped_ptr<BitmapUploader> bitmap_uploader_;
191 196
192 DISALLOW_COPY_AND_ASSIGN(PNGView); 197 DISALLOW_COPY_AND_ASSIGN(PNGView);
193 }; 198 };
194 199
195 class PNGViewer : public ApplicationDelegate, 200 class PNGViewer : public ApplicationDelegate,
196 public ContentHandlerFactory::Delegate { 201 public ContentHandlerFactory::Delegate {
197 public: 202 public:
198 PNGViewer() : content_handler_factory_(this) {} 203 PNGViewer() : content_handler_factory_(this) {}
199 204
200 private: 205 private:
(...skipping 16 matching lines...) Expand all
217 DISALLOW_COPY_AND_ASSIGN(PNGViewer); 222 DISALLOW_COPY_AND_ASSIGN(PNGViewer);
218 }; 223 };
219 224
220 } // namespace examples 225 } // namespace examples
221 } // namespace mojo 226 } // namespace mojo
222 227
223 MojoResult MojoMain(MojoHandle shell_handle) { 228 MojoResult MojoMain(MojoHandle shell_handle) {
224 mojo::ApplicationRunnerChromium runner(new mojo::examples::PNGViewer()); 229 mojo::ApplicationRunnerChromium runner(new mojo::examples::PNGViewer());
225 return runner.Run(shell_handle); 230 return runner.Run(shell_handle);
226 } 231 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698