1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef NU_CACHED_SOURCE_2_H_
18
19#define NU_CACHED_SOURCE_2_H_
20
21#include <media/stagefright/foundation/ABase.h>
22#include <media/stagefright/foundation/AHandlerReflector.h>
23#include <media/stagefright/DataSource.h>
24
25namespace android {
26
27struct ALooper;
28struct PageCache;
29
30struct NuCachedSource2 : public DataSource {
31    NuCachedSource2(
32            const sp<DataSource> &source,
33            const char *cacheConfig = NULL,
34            bool disconnectAtHighwatermark = false);
35
36    virtual status_t initCheck() const;
37
38    virtual ssize_t readAt(off64_t offset, void *data, size_t size);
39
40    virtual status_t getSize(off64_t *size);
41    virtual uint32_t flags();
42
43    virtual sp<DecryptHandle> DrmInitialization();
44    virtual void getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client);
45    virtual String8 getUri();
46
47    virtual String8 getMIMEType() const;
48
49    ////////////////////////////////////////////////////////////////////////////
50
51    size_t cachedSize();
52    size_t approxDataRemaining(status_t *finalStatus);
53
54    void resumeFetchingIfNecessary();
55
56    // The following methods are supported only if the
57    // data source is HTTP-based; otherwise, ERROR_UNSUPPORTED
58    // is returned.
59    status_t getEstimatedBandwidthKbps(int32_t *kbps);
60    status_t setCacheStatCollectFreq(int32_t freqMs);
61
62    static void RemoveCacheSpecificHeaders(
63            KeyedVector<String8, String8> *headers,
64            String8 *cacheConfig,
65            bool *disconnectAtHighwatermark);
66
67protected:
68    virtual ~NuCachedSource2();
69
70private:
71    friend struct AHandlerReflector<NuCachedSource2>;
72
73    enum {
74        kPageSize                       = 65536,
75        kDefaultHighWaterThreshold      = 20 * 1024 * 1024,
76        kDefaultLowWaterThreshold       = 4 * 1024 * 1024,
77
78        // Read data after a 15 sec timeout whether we're actively
79        // fetching or not.
80        kDefaultKeepAliveIntervalUs     = 15000000,
81    };
82
83    enum {
84        kWhatFetchMore  = 'fetc',
85        kWhatRead       = 'read',
86    };
87
88    enum {
89        kMaxNumRetries = 10,
90    };
91
92    sp<DataSource> mSource;
93    sp<AHandlerReflector<NuCachedSource2> > mReflector;
94    sp<ALooper> mLooper;
95
96    Mutex mSerializer;
97    Mutex mLock;
98    Condition mCondition;
99
100    PageCache *mCache;
101    off64_t mCacheOffset;
102    status_t mFinalStatus;
103    off64_t mLastAccessPos;
104    sp<AMessage> mAsyncResult;
105    bool mFetching;
106    int64_t mLastFetchTimeUs;
107
108    int32_t mNumRetriesLeft;
109
110    size_t mHighwaterThresholdBytes;
111    size_t mLowwaterThresholdBytes;
112
113    // If the keep-alive interval is 0, keep-alives are disabled.
114    int64_t mKeepAliveIntervalUs;
115
116    bool mDisconnectAtHighwatermark;
117
118    void onMessageReceived(const sp<AMessage> &msg);
119    void onFetch();
120    void onRead(const sp<AMessage> &msg);
121
122    void fetchInternal();
123    ssize_t readInternal(off64_t offset, void *data, size_t size);
124    status_t seekInternal_l(off64_t offset);
125
126    size_t approxDataRemaining_l(status_t *finalStatus);
127
128    void restartPrefetcherIfNecessary_l(
129            bool ignoreLowWaterThreshold = false, bool force = false);
130
131    void updateCacheParamsFromSystemProperty();
132    void updateCacheParamsFromString(const char *s);
133
134    DISALLOW_EVIL_CONSTRUCTORS(NuCachedSource2);
135};
136
137}  // namespace android
138
139#endif  // NU_CACHED_SOURCE_2_H_
140