15994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber/*
25994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * Copyright (C) 2010 The Android Open Source Project
35994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber *
45994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
55994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * you may not use this file except in compliance with the License.
65994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * You may obtain a copy of the License at
75994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber *
85994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
95994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber *
105994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * Unless required by applicable law or agreed to in writing, software
115994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
125994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * See the License for the specific language governing permissions and
145994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * limitations under the License.
155994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber */
165994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber
175994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber#ifndef NU_CACHED_SOURCE_2_H_
185994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber
195994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber#define NU_CACHED_SOURCE_2_H_
205994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber
215994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber#include <media/stagefright/foundation/ABase.h>
225994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber#include <media/stagefright/foundation/AHandlerReflector.h>
235994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber#include <media/stagefright/DataSource.h>
245994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber
255994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubernamespace android {
265994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber
275994b4798b01f3dd340577c9ea9657f09093a770Andreas Huberstruct ALooper;
285994b4798b01f3dd340577c9ea9657f09093a770Andreas Huberstruct PageCache;
295994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber
305994b4798b01f3dd340577c9ea9657f09093a770Andreas Huberstruct NuCachedSource2 : public DataSource {
31316c3d929ffb004b0150d515e82aede02208ce97Wonsik Kim    static sp<NuCachedSource2> Create(
3249c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber            const sp<DataSource> &source,
3349c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber            const char *cacheConfig = NULL,
3449c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber            bool disconnectAtHighwatermark = false);
355994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber
365994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber    virtual status_t initCheck() const;
375994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber
38c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    virtual ssize_t readAt(off64_t offset, void *data, size_t size);
395994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber
4048296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang    virtual void disconnect();
4148296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang
42c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    virtual status_t getSize(off64_t *size);
435994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber    virtual uint32_t flags();
445994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber
459d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong    virtual sp<DecryptHandle> DrmInitialization(const char* mime);
46b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang    virtual void getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client);
47771b85d9245a24273497792a2515d88d31c99e1eGloria Wang    virtual String8 getUri();
486511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber
496511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber    virtual String8 getMIMEType() const;
506511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber
5169d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    virtual String8 toString() {
5269d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen        return mName;
5369d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    }
5469d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen
555994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber    ////////////////////////////////////////////////////////////////////////////
565994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber
575994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber    size_t cachedSize();
58a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    size_t approxDataRemaining(status_t *finalStatus) const;
595994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber
6034ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber    void resumeFetchingIfNecessary();
61b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong
62b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong    // The following methods are supported only if the
63b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong    // data source is HTTP-based; otherwise, ERROR_UNSUPPORTED
64b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong    // is returned.
655b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong    status_t getEstimatedBandwidthKbps(int32_t *kbps);
66b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong    status_t setCacheStatCollectFreq(int32_t freqMs);
6734ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber
6849c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber    static void RemoveCacheSpecificHeaders(
6949c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber            KeyedVector<String8, String8> *headers,
7049c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber            String8 *cacheConfig,
7149c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber            bool *disconnectAtHighwatermark);
7249c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber
735994b4798b01f3dd340577c9ea9657f09093a770Andreas Huberprotected:
745994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber    virtual ~NuCachedSource2();
755994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber
765994b4798b01f3dd340577c9ea9657f09093a770Andreas Huberprivate:
775994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber    friend struct AHandlerReflector<NuCachedSource2>;
785994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber
79316c3d929ffb004b0150d515e82aede02208ce97Wonsik Kim    NuCachedSource2(
80316c3d929ffb004b0150d515e82aede02208ce97Wonsik Kim            const sp<DataSource> &source,
81316c3d929ffb004b0150d515e82aede02208ce97Wonsik Kim            const char *cacheConfig,
82316c3d929ffb004b0150d515e82aede02208ce97Wonsik Kim            bool disconnectAtHighwatermark);
83316c3d929ffb004b0150d515e82aede02208ce97Wonsik Kim
845994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber    enum {
85a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber        kPageSize                       = 65536,
86a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber        kDefaultHighWaterThreshold      = 20 * 1024 * 1024,
87a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber        kDefaultLowWaterThreshold       = 4 * 1024 * 1024,
88a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber
89a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber        // Read data after a 15 sec timeout whether we're actively
90a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber        // fetching or not.
91a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber        kDefaultKeepAliveIntervalUs     = 15000000,
925994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber    };
935994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber
945994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber    enum {
955994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber        kWhatFetchMore  = 'fetc',
965994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber        kWhatRead       = 'read',
975994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber    };
985994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber
990683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber    enum {
1000683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber        kMaxNumRetries = 10,
1010683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber    };
1020683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber
1035994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber    sp<DataSource> mSource;
1045994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber    sp<AHandlerReflector<NuCachedSource2> > mReflector;
1055994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber    sp<ALooper> mLooper;
10669d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    String8 mName;
1075994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber
1085994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber    Mutex mSerializer;
109a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    mutable Mutex mLock;
1105994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber    Condition mCondition;
1115994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber
1125994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber    PageCache *mCache;
113c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    off64_t mCacheOffset;
1145994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber    status_t mFinalStatus;
115c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    off64_t mLastAccessPos;
1165994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber    sp<AMessage> mAsyncResult;
1175994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber    bool mFetching;
11848296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang    bool mDisconnecting;
119a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber    int64_t mLastFetchTimeUs;
1205994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber
1210683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber    int32_t mNumRetriesLeft;
1220683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber
123a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber    size_t mHighwaterThresholdBytes;
124a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber    size_t mLowwaterThresholdBytes;
125a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber
126a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber    // If the keep-alive interval is 0, keep-alives are disabled.
127a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber    int64_t mKeepAliveIntervalUs;
128a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber
12949c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber    bool mDisconnectAtHighwatermark;
13049c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber
1315994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber    void onMessageReceived(const sp<AMessage> &msg);
1325994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber    void onFetch();
1335994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber    void onRead(const sp<AMessage> &msg);
1345994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber
1355994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber    void fetchInternal();
136c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    ssize_t readInternal(off64_t offset, void *data, size_t size);
137c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    status_t seekInternal_l(off64_t offset);
1385994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber
139a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    size_t approxDataRemaining_l(status_t *finalStatus) const;
1407bf8413f91fc072452f315a91618aeef2574d420Andreas Huber
1417bf8413f91fc072452f315a91618aeef2574d420Andreas Huber    void restartPrefetcherIfNecessary_l(
1427bf8413f91fc072452f315a91618aeef2574d420Andreas Huber            bool ignoreLowWaterThreshold = false, bool force = false);
1435994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber
144a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber    void updateCacheParamsFromSystemProperty();
145a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber    void updateCacheParamsFromString(const char *s);
146a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber
1475994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(NuCachedSource2);
1485994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber};
1495994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber
1505994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber}  // namespace android
1515994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber
1525994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber#endif  // NU_CACHED_SOURCE_2_H_
153