Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |