chromium/components/cronet/android/cronet_url_request_adapter.h

// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_CRONET_ANDROID_CRONET_URL_REQUEST_ADAPTER_H_
#define COMPONENTS_CRONET_ANDROID_CRONET_URL_REQUEST_ADAPTER_H_

#include <jni.h>

#include <memory>
#include <string>

#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "base/android/scoped_java_ref.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "components/cronet/cronet_url_request.h"
#include "net/third_party/quiche/src/quiche/quic/core/quic_types.h"
#include "url/gurl.h"

namespace net {
enum LoadState;
class UploadDataStream;
}  // namespace net

namespace cronet {

class CronetContextAdapter;
class TestUtil;

// An adapter from Java CronetUrlRequest object to native CronetURLRequest.
// Created and configured from a Java thread. Start, ReadData, and Destroy are
// posted to network thread and all callbacks into the Java CronetUrlRequest are
// done on the network thread. Java CronetUrlRequest is expected to initiate the
// next step like FollowDeferredRedirect, ReadData or Destroy. Public methods
// can be called on any thread.
class CronetURLRequestAdapter : public CronetURLRequest::Callback {
 public:
  // Bypasses cache if |jdisable_cache| is true. If context is not set up to
  // use cache, |jdisable_cache| has no effect. |jdisable_connection_migration|
  // causes connection migration to be disabled for this request if true. If
  // global connection migration flag is not enabled,
  // |jdisable_connection_migration| has no effect.
  CronetURLRequestAdapter(
      CronetContextAdapter* context,
      JNIEnv* env,
      jobject jurl_request,
      const GURL& url,
      net::RequestPriority priority,
      jboolean jdisable_cache,
      jboolean jdisable_connection_migration,
      jboolean jtraffic_stats_tag_set,
      jint jtraffic_stats_tag,
      jboolean jtraffic_stats_uid_set,
      jint jtraffic_stats_uid,
      net::Idempotency idempotency,
      scoped_refptr<net::SharedDictionary> shared_dictionary,
      jlong network);

  CronetURLRequestAdapter(const CronetURLRequestAdapter&) = delete;
  CronetURLRequestAdapter& operator=(const CronetURLRequestAdapter&) = delete;

  ~CronetURLRequestAdapter() override;

  // Methods called prior to Start are never called on network thread.

  // Sets the request method GET, POST etc.
  jboolean SetHttpMethod(JNIEnv* env,
                         const base::android::JavaParamRef<jobject>& jcaller,
                         const base::android::JavaParamRef<jstring>& jmethod);

  // Adds a header to the request before it starts.
  jboolean AddRequestHeader(JNIEnv* env,
                            const base::android::JavaParamRef<jobject>& jcaller,
                            const base::android::JavaParamRef<jstring>& jname,
                            const base::android::JavaParamRef<jstring>& jvalue);

  // Adds a request body to the request before it starts.
  void SetUpload(std::unique_ptr<net::UploadDataStream> upload);

  // Starts the request.
  void Start(JNIEnv* env, const base::android::JavaParamRef<jobject>& jcaller);

  void GetStatus(JNIEnv* env,
                 const base::android::JavaParamRef<jobject>& jcaller,
                 const base::android::JavaParamRef<jobject>& jstatus_listener);

  // Follows redirect.
  void FollowDeferredRedirect(
      JNIEnv* env,
      const base::android::JavaParamRef<jobject>& jcaller);

  // Reads more data.
  jboolean ReadData(JNIEnv* env,
                    const base::android::JavaParamRef<jobject>& jcaller,
                    const base::android::JavaParamRef<jobject>& jbyte_buffer,
                    jint jposition,
                    jint jcapacity);

  // Releases all resources for the request and deletes the object itself.
  // |jsend_on_canceled| indicates if Java onCanceled callback should be
  // issued to indicate when no more callbacks will be issued.
  void Destroy(JNIEnv* env,
               const base::android::JavaParamRef<jobject>& jcaller,
               jboolean jsend_on_canceled);

  // CronetURLRequest::Callback implementations:
  void OnReceivedRedirect(const std::string& new_location,
                          int http_status_code,
                          const std::string& http_status_text,
                          const net::HttpResponseHeaders* headers,
                          bool was_cached,
                          const std::string& negotiated_protocol,
                          const std::string& proxy_server,
                          int64_t received_byte_count) override;
  void OnResponseStarted(int http_status_code,
                         const std::string& http_status_text,
                         const net::HttpResponseHeaders* headers,
                         bool was_cached,
                         const std::string& negotiated_protocol,
                         const std::string& proxy_server,
                         int64_t received_byte_count) override;
  void OnReadCompleted(scoped_refptr<net::IOBuffer> buffer,
                       int bytes_read,
                       int64_t received_byte_count) override;
  void OnSucceeded(int64_t received_byte_count) override;
  void OnError(int net_error,
               int quic_error,
               quic::ConnectionCloseSource source,
               const std::string& error_string,
               int64_t received_byte_count) override;
  void OnCanceled() override;
  void OnDestroyed() override;
  void OnMetricsCollected(const base::Time& request_start_time,
                          const base::TimeTicks& request_start,
                          const base::TimeTicks& dns_start,
                          const base::TimeTicks& dns_end,
                          const base::TimeTicks& connect_start,
                          const base::TimeTicks& connect_end,
                          const base::TimeTicks& ssl_start,
                          const base::TimeTicks& ssl_end,
                          const base::TimeTicks& send_start,
                          const base::TimeTicks& send_end,
                          const base::TimeTicks& push_start,
                          const base::TimeTicks& push_end,
                          const base::TimeTicks& receive_headers_end,
                          const base::TimeTicks& request_end,
                          bool socket_reused,
                          int64_t sent_bytes_count,
                          int64_t received_bytes_count,
                          bool quic_connection_migration_attempted,
                          bool quic_connection_migration_successful) override;

  void OnStatus(
      const base::android::ScopedJavaGlobalRef<jobject>& status_listener_ref,
      net::LoadState load_status);

 private:
  friend class TestUtil;

  // Native Cronet URL Request that owns |this|.
  raw_ptr<CronetURLRequest> request_;

  // Java object that owns this CronetContextAdapter.
  base::android::ScopedJavaGlobalRef<jobject> owner_;
};

}  // namespace cronet

#endif  // COMPONENTS_CRONET_ANDROID_CRONET_URL_REQUEST_ADAPTER_H_