Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / image_decoder.h
blob9e0b3edeaff92cff17a04aac93b0cbc236e06c9e
1 // Copyright (c) 2012 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.
5 #ifndef CHROME_BROWSER_IMAGE_DECODER_H_
6 #define CHROME_BROWSER_IMAGE_DECODER_H_
8 #include <map>
9 #include <string>
10 #include <vector>
12 #include "base/lazy_instance.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/sequence_checker.h"
15 #include "base/sequenced_task_runner.h"
16 #include "base/synchronization/lock.h"
17 #include "base/timer/timer.h"
18 #include "content/public/browser/utility_process_host.h"
19 #include "content/public/browser/utility_process_host_client.h"
21 class SkBitmap;
23 // This is a helper class for decoding images safely in a utility process. To
24 // use this, call ImageDecoder::Start(...) or
25 // ImageDecoder::StartWithOptions(...) on any thread.
27 // Internally, most of the work happens on the IO thread, and then
28 // the callback (ImageRequest::OnImageDecoded or
29 // ImageRequest::OnDecodeImageFailed) is posted back to the |task_runner_|
30 // associated with the ImageRequest.
31 // The Cancel() method runs on whichever thread called it. |map_lock_| is used
32 // to protect the data that is accessed from multiple threads.
33 class ImageDecoder : public content::UtilityProcessHostClient {
34 public:
35 // ImageRequest objects needs to be created and destroyed on the same
36 // SequencedTaskRunner.
37 class ImageRequest {
38 public:
39 // Called when image is decoded.
40 virtual void OnImageDecoded(const SkBitmap& decoded_image) = 0;
42 // Called when decoding image failed. ImageRequest can do some cleanup in
43 // this handler.
44 virtual void OnDecodeImageFailed() {}
46 base::SequencedTaskRunner* task_runner() const {
47 return task_runner_.get();
50 protected:
51 // Creates an ImageRequest that runs on the thread creating it.
52 ImageRequest();
53 // Explicitly pass in |task_runner| if the current thread is part of a
54 // thread pool.
55 explicit ImageRequest(
56 const scoped_refptr<base::SequencedTaskRunner>& task_runner);
57 virtual ~ImageRequest();
59 private:
60 // The thread to post OnImageDecoded() or OnDecodeImageFailed() once the
61 // the image has been decoded.
62 const scoped_refptr<base::SequencedTaskRunner> task_runner_;
64 base::SequenceChecker sequence_checker_;
67 enum ImageCodec {
68 DEFAULT_CODEC = 0, // Uses WebKit image decoding (via WebImage).
69 #if defined(OS_CHROMEOS)
70 ROBUST_JPEG_CODEC, // Restrict decoding to robust jpeg codec.
71 #endif // defined(OS_CHROMEOS)
74 // Calls StartWithOptions() with ImageCodec::DEFAULT_CODEC and
75 // shrink_to_fit = false.
76 static void Start(ImageRequest* image_request,
77 const std::string& image_data);
79 // Starts asynchronous image decoding. Once finished, the callback will be
80 // posted back to image_request's |task_runner_|.
81 static void StartWithOptions(ImageRequest* image_request,
82 const std::string& image_data,
83 ImageCodec image_codec,
84 bool shrink_to_fit);
86 // Removes all instances of |image_request| from |image_request_id_map_|,
87 // ensuring callbacks are not made to the image_request after it is destroyed.
88 static void Cancel(ImageRequest* image_request);
90 private:
91 friend struct base::DefaultLazyInstanceTraits<ImageDecoder>;
93 using RequestMap = std::map<int, ImageRequest*>;
95 ImageDecoder();
96 // It's a reference counted object, so destructor is private.
97 ~ImageDecoder() override;
99 // Sends a request to the sandboxed process to decode the image. Starts
100 // batch mode if necessary. If the utility process fails to start,
101 // an OnDecodeImageFailed task is posted to image_request's |task_runner_|.
102 void DecodeImageInSandbox(int request_id,
103 const std::vector<unsigned char>& image_data,
104 ImageCodec image_codec,
105 bool shrink_to_fit);
107 void StartWithOptionsImpl(ImageRequest* image_request,
108 const std::string& image_data,
109 ImageCodec image_codec,
110 bool shrink_to_fit);
111 void CancelImpl(ImageRequest* image_request);
113 // Starts UtilityProcessHost in batch mode and starts |batch_mode_timer_|.
114 // If the utility process fails to start, the method resets
115 // |utility_process_host_| and returns.
116 void StartBatchMode();
118 // Stops batch mode if no requests have come in since
119 // |kBatchModeTimeoutSeconds|.
120 void StopBatchMode();
122 // Fails all outstanding requests.
123 void FailAllRequests();
125 // Overidden from UtilityProcessHostClient.
126 void OnProcessCrashed(int exit_code) override;
127 void OnProcessLaunchFailed() override;
128 bool OnMessageReceived(const IPC::Message& message) override;
130 // IPC message handlers.
131 void OnDecodeImageSucceeded(const SkBitmap& decoded_image, int request_id);
132 void OnDecodeImageFailed(int request_id);
134 // For the ImageRequest identified by |request_id|, call its OnImageDecoded()
135 // or OnDecodeImageFailed() method on its task runner thread.
136 void RunOnImageDecoded(const SkBitmap& decoded_image, int request_id);
137 void RunOnDecodeImageFailed(int request_id);
139 // id to use for the next Start() request that comes in.
140 int image_request_id_counter_;
142 // Map of request id's to ImageRequests.
143 RequestMap image_request_id_map_;
145 // Protects |image_request_id_map_| and |image_request_id_counter_|.
146 base::Lock map_lock_;
148 // The UtilityProcessHost requests are sent to.
149 base::WeakPtr<content::UtilityProcessHost> utility_process_host_;
151 // Calls StopBatchMode() after |kBatchModeTimeoutSeconds| have elapsed,
152 // unless a new decoding request resets the timer.
153 scoped_ptr<base::DelayTimer<ImageDecoder>> batch_mode_timer_;
155 DISALLOW_COPY_AND_ASSIGN(ImageDecoder);
158 #endif // CHROME_BROWSER_IMAGE_DECODER_H_