Home | History | Annotate | Download | only in image_viewer
      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.
      4 
      5 #include <algorithm>
      6 
      7 #include "base/strings/string_tokenizer.h"
      8 #include "mojo/public/cpp/application/application.h"
      9 #include "mojo/services/public/cpp/view_manager/node.h"
     10 #include "mojo/services/public/cpp/view_manager/types.h"
     11 #include "mojo/services/public/cpp/view_manager/view.h"
     12 #include "mojo/services/public/cpp/view_manager/view_manager.h"
     13 #include "mojo/services/public/cpp/view_manager/view_manager_delegate.h"
     14 #include "mojo/services/public/interfaces/navigation/navigation.mojom.h"
     15 #include "third_party/skia/include/core/SkBitmap.h"
     16 #include "ui/gfx/codec/png_codec.h"
     17 
     18 namespace mojo {
     19 namespace examples {
     20 
     21 class ImageViewer;
     22 
     23 class NavigatorImpl : public InterfaceImpl<navigation::Navigator> {
     24  public:
     25   explicit NavigatorImpl(ImageViewer* viewer) : viewer_(viewer) {}
     26   virtual ~NavigatorImpl() {}
     27 
     28  private:
     29   // Overridden from navigation::Navigate:
     30   virtual void Navigate(
     31       uint32_t node_id,
     32       navigation::NavigationDetailsPtr navigation_details,
     33       navigation::ResponseDetailsPtr response_details) OVERRIDE {
     34     int content_length = GetContentLength(response_details->response->headers);
     35     unsigned char* data = new unsigned char[content_length];
     36     unsigned char* buf = data;
     37     uint32_t bytes_remaining = content_length;
     38     uint32_t num_bytes = bytes_remaining;
     39     while (bytes_remaining > 0) {
     40       MojoResult result = ReadDataRaw(
     41           response_details->response_body_stream.get(),
     42           buf,
     43           &num_bytes,
     44           MOJO_READ_DATA_FLAG_NONE);
     45       if (result == MOJO_RESULT_SHOULD_WAIT) {
     46         Wait(response_details->response_body_stream.get(),
     47              MOJO_HANDLE_SIGNAL_READABLE,
     48              MOJO_DEADLINE_INDEFINITE);
     49       } else if (result == MOJO_RESULT_OK) {
     50         buf += num_bytes;
     51         num_bytes = bytes_remaining -= num_bytes;
     52       } else {
     53         break;
     54       }
     55     }
     56 
     57     SkBitmap bitmap;
     58     gfx::PNGCodec::Decode(static_cast<const unsigned char*>(data),
     59                           content_length, &bitmap);
     60     UpdateView(node_id, bitmap);
     61 
     62     delete[] data;
     63   }
     64 
     65   void UpdateView(view_manager::Id node_id, const SkBitmap& bitmap);
     66 
     67   int GetContentLength(const Array<String>& headers) {
     68     for (size_t i = 0; i < headers.size(); ++i) {
     69       base::StringTokenizer t(headers[i], ": ;=");
     70       while (t.GetNext()) {
     71         if (!t.token_is_delim() && t.token() == "Content-Length") {
     72           while (t.GetNext()) {
     73             if (!t.token_is_delim())
     74               return atoi(t.token().c_str());
     75           }
     76         }
     77       }
     78     }
     79     return 0;
     80   }
     81 
     82   ImageViewer* viewer_;
     83 
     84   DISALLOW_COPY_AND_ASSIGN(NavigatorImpl);
     85 };
     86 
     87 class ImageViewer : public Application,
     88                     public view_manager::ViewManagerDelegate {
     89  public:
     90   ImageViewer() : content_view_(NULL) {}
     91   virtual ~ImageViewer() {}
     92 
     93   void UpdateView(view_manager::Id node_id, const SkBitmap& bitmap) {
     94     bitmap_ = bitmap;
     95     DrawBitmap();
     96   }
     97 
     98  private:
     99   // Overridden from Application:
    100   virtual void Initialize() OVERRIDE {
    101     AddService<NavigatorImpl>(this);
    102     view_manager::ViewManager::Create(this, this);
    103   }
    104 
    105   // Overridden from view_manager::ViewManagerDelegate:
    106   virtual void OnRootAdded(view_manager::ViewManager* view_manager,
    107                            view_manager::Node* root) OVERRIDE {
    108     content_view_ = view_manager::View::Create(view_manager);
    109     root->SetActiveView(content_view_);
    110     content_view_->SetColor(SK_ColorRED);
    111     if (!bitmap_.isNull())
    112       DrawBitmap();
    113   }
    114 
    115   void DrawBitmap() {
    116     if (content_view_)
    117       content_view_->SetContents(bitmap_);
    118   }
    119 
    120   view_manager::View* content_view_;
    121   SkBitmap bitmap_;
    122 
    123   DISALLOW_COPY_AND_ASSIGN(ImageViewer);
    124 };
    125 
    126 void NavigatorImpl::UpdateView(view_manager::Id node_id,
    127                                      const SkBitmap& bitmap) {
    128   viewer_->UpdateView(node_id, bitmap);
    129 }
    130 
    131 }  // namespace examples
    132 
    133 // static
    134 Application* Application::Create() {
    135   return new examples::ImageViewer;
    136 }
    137 
    138 }  // namespace mojo
    139