15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef ANDROID_WEBVIEW_NATIVE_ANDROID_STREAM_READER_URL_REQUEST_JOB_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ANDROID_WEBVIEW_NATIVE_ANDROID_STREAM_READER_URL_REQUEST_JOB_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/android/scoped_java_ref.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/location.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/ref_counted.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread_checker.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_byte_range.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_job.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace android_webview {
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class InputStream;
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class InputStreamReader;
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace base {
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TaskRunner;
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)class HttpResponseHeaders;
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class HttpResponseInfo;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class URLRequest;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class InputStreamReaderWrapper;
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A request job that reads data from a Java InputStream.
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AndroidStreamReaderURLRequestJob : public net::URLRequestJob {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /*
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   * We use a delegate so that we can share code for this job in slightly
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   * different contexts.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   */
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class Delegate {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // This method is called from a worker thread, not from the IO thread.
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual scoped_ptr<android_webview::InputStream> OpenInputStream(
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        JNIEnv* env,
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        const GURL& url) = 0;
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // This method is called on the Job's thread if the result of calling
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // OpenInputStream was null.
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Setting the |restart| parameter to true will cause the request to be
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // restarted with a new job.
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual void OnInputStreamOpenFailed(
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        net::URLRequest* request,
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        bool* restart) = 0;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual bool GetMimeType(
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        JNIEnv* env,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        net::URLRequest* request,
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        android_webview::InputStream* stream,
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        std::string* mime_type) = 0;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual bool GetCharset(
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        JNIEnv* env,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        net::URLRequest* request,
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        android_webview::InputStream* stream,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        std::string* charset) = 0;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
706d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    virtual void AppendResponseHeaders(JNIEnv* env,
716d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                       net::HttpResponseHeaders* headers) = 0;
726d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual ~Delegate() {}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AndroidStreamReaderURLRequestJob(
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::URLRequest* request,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::NetworkDelegate* network_delegate,
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scoped_ptr<Delegate> delegate);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // URLRequestJob:
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Start() OVERRIDE;
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void Kill() OVERRIDE;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool ReadRawData(net::IOBuffer* buf,
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           int buf_size,
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           int* bytes_read) OVERRIDE;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetExtraRequestHeaders(
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const net::HttpRequestHeaders& headers) OVERRIDE;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool GetMimeType(std::string* mime_type) const OVERRIDE;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool GetCharset(std::string* charset) OVERRIDE;
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual int GetResponseCode() const OVERRIDE;
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void GetResponseInfo(net::HttpResponseInfo* info) OVERRIDE;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~AndroidStreamReaderURLRequestJob();
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Gets the TaskRunner for the worker thread.
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden in unittests.
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual base::TaskRunner* GetWorkerThreadRunner();
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Creates an InputStreamReader instance.
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden in unittests to return a mock.
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual scoped_ptr<android_webview::InputStreamReader>
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateStreamReader(android_webview::InputStream* stream);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void HeadersComplete(int status_code, const std::string& status_text);
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OnInputStreamOpened(
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scoped_ptr<Delegate> delegate,
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scoped_ptr<android_webview::InputStream> input_stream);
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OnReaderSeekCompleted(int content_size);
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OnReaderReadCompleted(int bytes_read);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::HttpByteRange byte_range_;
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<net::HttpResponseInfo> response_info_;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Delegate> delegate_;
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<InputStreamReaderWrapper> input_stream_reader_wrapper_;
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ThreadChecker thread_checker_;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::WeakPtrFactory<AndroidStreamReaderURLRequestJob> weak_factory_;
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AndroidStreamReaderURLRequestJob);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // ANDROID_WEBVIEW_NATIVE_ANDROID_STREAM_READER_URL_REQUEST_JOB_H_
127