1 // Copyright 2015 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.
4 
5 #ifndef COMPONENTS_CRONET_CRONET_UPLOAD_DATA_STREAM_H_
6 #define COMPONENTS_CRONET_CRONET_UPLOAD_DATA_STREAM_H_
7 
8 #include <stdint.h>
9 
10 #include <memory>
11 
12 #include "base/macros.h"
13 #include "base/memory/scoped_refptr.h"
14 #include "base/memory/weak_ptr.h"
15 #include "net/base/upload_data_stream.h"
16 
17 namespace net {
18 class IOBuffer;
19 }  // namespace net
20 
21 namespace cronet {
22 
23 // The CronetUploadDataStream is created on a client thread, but afterwards,
24 // lives and is deleted on the network thread. It's responsible for ensuring
25 // only one read/rewind request sent to client is outstanding at a time.
26 // The main complexity is around Reset/Initialize calls while there's a pending
27 // read or rewind.
28 class CronetUploadDataStream : public net::UploadDataStream {
29  public:
30   class Delegate {
31    public:
32     // Called once during initial setup on the network thread, called before
33     // all other methods.
34     virtual void InitializeOnNetworkThread(
35         base::WeakPtr<CronetUploadDataStream> upload_data_stream) = 0;
36 
37     // Called for each read request. Delegate must respond by calling
38     // OnReadSuccess on the network thread asynchronous, or failing the request.
39     // Only called when there's no other pending read or rewind operation.
40     virtual void Read(scoped_refptr<net::IOBuffer> buffer, int buf_len) = 0;
41 
42     // Called to rewind the stream. Not called when already at the start of the
43     // stream. The delegate must respond by calling OnRewindSuccess
44     // asynchronously on the network thread, or failing the request. Only called
45     // when there's no other pending read or rewind operation.
46     virtual void Rewind() = 0;
47 
48     // Called when the CronetUploadDataStream is destroyed. The Delegate is then
49     // responsible for destroying itself. May be called when there's a pending
50     // read or rewind operation.
51     virtual void OnUploadDataStreamDestroyed() = 0;
52 
53    protected:
Delegate()54     Delegate() {}
~Delegate()55     virtual ~Delegate() {}
56 
57    private:
58     DISALLOW_COPY_AND_ASSIGN(Delegate);
59   };
60 
61   CronetUploadDataStream(Delegate* delegate, int64_t size);
62   ~CronetUploadDataStream() override;
63 
64   // Failure is handled at the Java layer. These two success callbacks are
65   // invoked by client UploadDataSink upon completion of the operation.
66   void OnReadSuccess(int bytes_read, bool final_chunk);
67   void OnRewindSuccess();
68 
69  private:
70   // net::UploadDataStream implementation:
71   int InitInternal(const net::NetLogWithSource& net_log) override;
72   int ReadInternal(net::IOBuffer* buf, int buf_len) override;
73   void ResetInternal() override;
74 
75   // Starts rewinding the stream. Only called when not already at the front of
76   // the stream, and no operation is pending. Completes asynchronously.
77   void StartRewind();
78 
79   // Size of the upload. -1 if chunked.
80   const int64_t size_;
81 
82   // True if ReadInternal has been called, the read hasn't completed, and there
83   // hasn't been a ResetInternal call yet.
84   bool waiting_on_read_;
85   // True if there's a read operation in progress. This will always be true
86   // when |waiting_on_read_| is true. This will only be set to false once it
87   // completes, even though ResetInternal may have been called since the read
88   // started.
89   bool read_in_progress_;
90 
91   // True if InitInternal has been called, the rewind hasn't completed, and
92   // there hasn't been a ResetInternal call yet. Note that this may be true
93   // even when the rewind hasn't yet started, if there's a read in progress.
94   bool waiting_on_rewind_;
95   // True if there's a rewind operation in progress. Rewinding will only start
96   // when |waiting_on_rewind_| is true, and |read_in_progress_| is false. This
97   // will only be set to false once it completes, even though ResetInternal may
98   // have been called since the rewind started.
99   bool rewind_in_progress_;
100 
101   // Set to false when a read starts, true when a rewind completes.
102   bool at_front_of_stream_;
103 
104   Delegate* const delegate_;
105 
106   // Vends pointers on the network thread, though created on a client thread.
107   base::WeakPtrFactory<CronetUploadDataStream> weak_factory_{this};
108 
109   DISALLOW_COPY_AND_ASSIGN(CronetUploadDataStream);
110 };
111 
112 }  // namespace cronet
113 
114 #endif  // COMPONENTS_CRONET_CRONET_UPLOAD_DATA_STREAM_H_
115