// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_IMAGE_DECODER_H_
#define CHROME_BROWSER_IMAGE_DECODER_H_

#include <map>
#include <string>
#include <vector>

#include "base/lazy_instance.h"
#include "base/memory/ref_counted.h"
#include "base/sequence_checker.h"
#include "base/sequenced_task_runner.h"
#include "base/synchronization/lock.h"
#include "base/timer/timer.h"
#include "content/public/browser/utility_process_host.h"
#include "content/public/browser/utility_process_host_client.h"

class SkBitmap;

// This is a helper class for decoding images safely in a utility process. To
// use this, call ImageDecoder::Start(...) or
// ImageDecoder::StartWithOptions(...) on any thread.
//
// Internally, most of the work happens on the IO thread, and then
// the callback (ImageRequest::OnImageDecoded or
// ImageRequest::OnDecodeImageFailed) is posted back to the |task_runner_|
// associated with the ImageRequest.
// The Cancel() method runs on whichever thread called it. |map_lock_| is used
// to protect the data that is accessed from multiple threads.
class ImageDecoder : public content::UtilityProcessHostClient {
 public:
  // ImageRequest objects needs to be created and destroyed on the same
  // SequencedTaskRunner.
  class ImageRequest {
   public:
    // Called when image is decoded.
    virtual void OnImageDecoded(const SkBitmap& decoded_image) = 0;

    // Called when decoding image failed. ImageRequest can do some cleanup in
    // this handler.
    virtual void OnDecodeImageFailed() {}

    base::SequencedTaskRunner* task_runner() const {
      return task_runner_.get();
    }

   protected:
    // Creates an ImageRequest that runs on the thread creating it.
    ImageRequest();
    // Explicitly pass in |task_runner| if the current thread is part of a
    // thread pool.
    explicit ImageRequest(
        const scoped_refptr<base::SequencedTaskRunner>& task_runner);
    virtual ~ImageRequest();

   private:
    // The thread to post OnImageDecoded() or OnDecodeImageFailed() once the
    // the image has been decoded.
    const scoped_refptr<base::SequencedTaskRunner> task_runner_;

    base::SequenceChecker sequence_checker_;
  };

  enum ImageCodec {
    DEFAULT_CODEC = 0,  // Uses WebKit image decoding (via WebImage).
#if defined(OS_CHROMEOS)
    ROBUST_JPEG_CODEC,  // Restrict decoding to robust jpeg codec.
#endif  // defined(OS_CHROMEOS)
  };

  // Calls StartWithOptions() with ImageCodec::DEFAULT_CODEC and
  // shrink_to_fit = false.
  static void Start(ImageRequest* image_request,
                    const std::string& image_data);

  // Starts asynchronous image decoding. Once finished, the callback will be
  // posted back to image_request's |task_runner_|.
  static void StartWithOptions(ImageRequest* image_request,
                               const std::string& image_data,
                               ImageCodec image_codec,
                               bool shrink_to_fit);

  // Removes all instances of |image_request| from |image_request_id_map_|,
  // ensuring callbacks are not made to the image_request after it is destroyed.
  static void Cancel(ImageRequest* image_request);

 private:
  friend struct base::DefaultLazyInstanceTraits<ImageDecoder>;

  using RequestMap = std::map<int, ImageRequest*>;

  ImageDecoder();
  // It's a reference counted object, so destructor is private.
  ~ImageDecoder() override;

  // Sends a request to the sandboxed process to decode the image. Starts
  // batch mode if necessary. If the utility process fails to start,
  // an OnDecodeImageFailed task is posted to image_request's |task_runner_|.
  void DecodeImageInSandbox(int request_id,
                            const std::vector<unsigned char>& image_data,
                            ImageCodec image_codec,
                            bool shrink_to_fit);

  void StartWithOptionsImpl(ImageRequest* image_request,
                            const std::string& image_data,
                            ImageCodec image_codec,
                            bool shrink_to_fit);
  void CancelImpl(ImageRequest* image_request);

  // Starts UtilityProcessHost in batch mode and starts |batch_mode_timer_|.
  // If the utility process fails to start, the method resets
  // |utility_process_host_| and returns.
  void StartBatchMode();

  // Stops batch mode if no requests have come in since
  // |kBatchModeTimeoutSeconds|.
  void StopBatchMode();

  // Fails all outstanding requests.
  void FailAllRequests();

  // Overidden from UtilityProcessHostClient.
  void OnProcessCrashed(int exit_code) override;
  void OnProcessLaunchFailed() override;
  bool OnMessageReceived(const IPC::Message& message) override;

  // IPC message handlers.
  void OnDecodeImageSucceeded(const SkBitmap& decoded_image, int request_id);
  void OnDecodeImageFailed(int request_id);

  // For the ImageRequest identified by |request_id|, call its OnImageDecoded()
  // or OnDecodeImageFailed() method on its task runner thread.
  void RunOnImageDecoded(const SkBitmap& decoded_image, int request_id);
  void RunOnDecodeImageFailed(int request_id);

  // id to use for the next Start() request that comes in.
  int image_request_id_counter_;

  // Map of request id's to ImageRequests.
  RequestMap image_request_id_map_;

  // Protects |image_request_id_map_| and |image_request_id_counter_|.
  base::Lock map_lock_;

  // The UtilityProcessHost requests are sent to.
  base::WeakPtr<content::UtilityProcessHost> utility_process_host_;

  // Calls StopBatchMode() after |kBatchModeTimeoutSeconds| have elapsed,
  // unless a new decoding request resets the timer.
  scoped_ptr<base::DelayTimer> batch_mode_timer_;

  DISALLOW_COPY_AND_ASSIGN(ImageDecoder);
};

#endif  // CHROME_BROWSER_IMAGE_DECODER_H_
