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#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_USERS_AVATAR_USER_IMAGE_LOADER_H_
6#define CHROME_BROWSER_CHROMEOS_LOGIN_USERS_AVATAR_USER_IMAGE_LOADER_H_
7
8#include <map>
9#include <string>
10
11#include "base/callback.h"
12#include "base/compiler_specific.h"
13#include "base/memory/ref_counted.h"
14#include "chrome/browser/image_decoder.h"
15
16class SkBitmap;
17
18namespace base {
19class SequencedTaskRunner;
20}
21
22namespace user_manager {
23class UserImage;
24}
25
26namespace chromeos {
27
28// Helper that reads, decodes and optionally resizes an image on a background
29// thread. Returns the image in the form of an SkBitmap.
30class UserImageLoader : public base::RefCountedThreadSafe<UserImageLoader>,
31                        public ImageDecoder::Delegate {
32 public:
33  // Callback used to return the result of an image load operation.
34  typedef base::Callback<void(const user_manager::UserImage& user_image)>
35      LoadedCallback;
36
37  // All file I/O, decoding and resizing are done via |background_task_runner|.
38  UserImageLoader(
39      ImageDecoder::ImageCodec image_codec,
40      scoped_refptr<base::SequencedTaskRunner> background_task_runner);
41
42  // Load an image in the background and call |loaded_cb| with the resulting
43  // UserImage (which may be empty in case of error). If |pixels_per_side| is
44  // positive, the image is cropped to a square and shrunk so that it does not
45  // exceed |pixels_per_side|x|pixels_per_side|. The first variant of this
46  // method reads the image from |filepath| on disk, the second processes |data|
47  // read into memory already.
48  void Start(const std::string& filepath,
49             int pixels_per_side,
50             const LoadedCallback& loaded_cb);
51  void Start(scoped_ptr<std::string> data,
52             int pixels_per_side,
53             const LoadedCallback& loaded_cb);
54
55 private:
56  friend class base::RefCountedThreadSafe<UserImageLoader>;
57
58  // Contains attributes we need to know about each image we decode.
59  struct ImageInfo {
60    ImageInfo(const std::string& file_path,
61              int pixels_per_side,
62              const LoadedCallback& loaded_cb);
63    ~ImageInfo();
64
65    const std::string file_path;
66    const int pixels_per_side;
67    const LoadedCallback loaded_cb;
68  };
69
70  typedef std::map<const ImageDecoder*, ImageInfo> ImageInfoMap;
71
72  virtual ~UserImageLoader();
73
74  // Reads the image from |image_info.file_path| and starts the decoding
75  // process. This method may only be invoked via the |background_task_runner_|.
76  void ReadAndDecodeImage(const ImageInfo& image_info);
77
78  // Decodes the image |data|. This method may only be invoked via the
79  // |background_task_runner_|.
80  void DecodeImage(const scoped_ptr<std::string> data,
81                   const ImageInfo& image_info);
82
83  // ImageDecoder::Delegate implementation. These callbacks will only be invoked
84  // via the |background_task_runner_|.
85  virtual void OnImageDecoded(const ImageDecoder* decoder,
86                              const SkBitmap& decoded_image) OVERRIDE;
87  virtual void OnDecodeImageFailed(const ImageDecoder* decoder) OVERRIDE;
88
89  // The foreground task runner on which |this| is instantiated, Start() is
90  // called and LoadedCallbacks are invoked.
91  scoped_refptr<base::SequencedTaskRunner> foreground_task_runner_;
92
93  // The background task runner on which file I/O, image decoding and resizing
94  // are done.
95  scoped_refptr<base::SequencedTaskRunner> background_task_runner_;
96
97  // Specify how the file should be decoded in the utility process.
98  const ImageDecoder::ImageCodec image_codec_;
99
100  // Holds information about the images currently being decoded. Accessed via
101  // |background_task_runner_| only.
102  ImageInfoMap image_info_map_;
103
104  DISALLOW_COPY_AND_ASSIGN(UserImageLoader);
105};
106
107}  // namespace chromeos
108
109#endif  // CHROME_BROWSER_CHROMEOS_LOGIN_USERS_AVATAR_USER_IMAGE_LOADER_H_
110