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_
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"
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
{
35 // ImageRequest objects needs to be created and destroyed on the same
36 // SequencedTaskRunner.
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
44 virtual void OnDecodeImageFailed() {}
46 base::SequencedTaskRunner
* task_runner() const {
47 return task_runner_
.get();
51 // Creates an ImageRequest that runs on the thread creating it.
53 // Explicitly pass in |task_runner| if the current thread is part of a
55 explicit ImageRequest(
56 const scoped_refptr
<base::SequencedTaskRunner
>& task_runner
);
57 virtual ~ImageRequest();
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_
;
68 DEFAULT_CODEC
= 0, // Uses WebKit image decoding (via WebImage).
69 ROBUST_JPEG_CODEC
, // Restrict decoding to robust jpeg codec.
72 // Calls StartWithOptions() with ImageCodec::DEFAULT_CODEC and
73 // shrink_to_fit = false.
74 static void Start(ImageRequest
* image_request
,
75 const std::string
& image_data
);
77 // Starts asynchronous image decoding. Once finished, the callback will be
78 // posted back to image_request's |task_runner_|.
79 static void StartWithOptions(ImageRequest
* image_request
,
80 const std::string
& image_data
,
81 ImageCodec image_codec
,
84 // Removes all instances of |image_request| from |image_request_id_map_|,
85 // ensuring callbacks are not made to the image_request after it is destroyed.
86 static void Cancel(ImageRequest
* image_request
);
89 friend struct base::DefaultLazyInstanceTraits
<ImageDecoder
>;
91 using RequestMap
= std::map
<int, ImageRequest
*>;
94 // It's a reference counted object, so destructor is private.
95 ~ImageDecoder() override
;
97 // Sends a request to the sandboxed process to decode the image. Starts
98 // batch mode if necessary. If the utility process fails to start,
99 // an OnDecodeImageFailed task is posted to image_request's |task_runner_|.
100 void DecodeImageInSandbox(int request_id
,
101 const std::vector
<unsigned char>& image_data
,
102 ImageCodec image_codec
,
105 void StartWithOptionsImpl(ImageRequest
* image_request
,
106 const std::string
& image_data
,
107 ImageCodec image_codec
,
109 void CancelImpl(ImageRequest
* image_request
);
111 // Starts UtilityProcessHost in batch mode and starts |batch_mode_timer_|.
112 // If the utility process fails to start, the method resets
113 // |utility_process_host_| and returns.
114 void StartBatchMode();
116 // Stops batch mode if no requests have come in since
117 // |kBatchModeTimeoutSeconds|.
118 void StopBatchMode();
120 // Fails all outstanding requests.
121 void FailAllRequests();
123 // Overidden from UtilityProcessHostClient.
124 void OnProcessCrashed(int exit_code
) override
;
125 void OnProcessLaunchFailed() override
;
126 bool OnMessageReceived(const IPC::Message
& message
) override
;
128 // IPC message handlers.
129 void OnDecodeImageSucceeded(const SkBitmap
& decoded_image
, int request_id
);
130 void OnDecodeImageFailed(int request_id
);
132 // For the ImageRequest identified by |request_id|, call its OnImageDecoded()
133 // or OnDecodeImageFailed() method on its task runner thread.
134 void RunOnImageDecoded(const SkBitmap
& decoded_image
, int request_id
);
135 void RunOnDecodeImageFailed(int request_id
);
137 // id to use for the next Start() request that comes in.
138 int image_request_id_counter_
;
140 // Map of request id's to ImageRequests.
141 RequestMap image_request_id_map_
;
143 // Protects |image_request_id_map_| and |image_request_id_counter_|.
144 base::Lock map_lock_
;
146 // The UtilityProcessHost requests are sent to.
147 base::WeakPtr
<content::UtilityProcessHost
> utility_process_host_
;
149 // Calls StopBatchMode() after |kBatchModeTimeoutSeconds| have elapsed,
150 // unless a new decoding request resets the timer.
151 scoped_ptr
<base::DelayTimer
<ImageDecoder
>> batch_mode_timer_
;
153 DISALLOW_COPY_AND_ASSIGN(ImageDecoder
);
156 #endif // CHROME_BROWSER_IMAGE_DECODER_H_