private IDictionary <string, string> GetExtraMap(FetchState fetchState, int byteSize)
        {
            if (!fetchState.Listener.RequiresExtraMap(fetchState.Id))
            {
                return(null);
            }

            return(_networkFetcher.GetExtraMap(fetchState, byteSize));
        }
        private bool ShouldPropagateIntermediateResults(FetchState fetchState)
        {
            if (!fetchState.Context.ImageRequest.IsProgressiveRenderingEnabled)
            {
                return(false);
            }

            return(_networkFetcher.ShouldPropagate(fetchState));
        }
        private void HandleFinalResult(
            PooledByteBufferOutputStream pooledOutputStream,
            FetchState fetchState)
        {
            IDictionary <string, string> extraMap = GetExtraMap(fetchState, pooledOutputStream.Size);

            fetchState.Listener.OnProducerFinishWithSuccess(fetchState.Id, PRODUCER_NAME, extraMap);
            NotifyConsumer(pooledOutputStream, true, fetchState.Consumer);
        }
        private void MaybeHandleIntermediateResult(
            PooledByteBufferOutputStream pooledOutputStream,
            FetchState fetchState)
        {
            long nowMs = SystemClock.UptimeMillis;

            if (ShouldPropagateIntermediateResults(fetchState) &&
                nowMs - fetchState.LastIntermediateResultTimeMs >= TIME_BETWEEN_PARTIAL_RESULTS_MS)
            {
                fetchState.LastIntermediateResultTimeMs = nowMs;
                fetchState.Listener.OnProducerEvent(
                    fetchState.Id, PRODUCER_NAME, INTERMEDIATE_RESULT_PRODUCER_EVENT);
                NotifyConsumer(pooledOutputStream, false, fetchState.Consumer);
            }
        }
        /// <summary>
        /// Start producing results for given context.
        /// Provided consumer is notified whenever progress is made
        /// (new value is ready or error occurs).
        /// </summary>
        public void ProduceResults(IConsumer <EncodedImage> consumer, IProducerContext context)
        {
            context.Listener.OnProducerStart(context.Id, PRODUCER_NAME);
            FetchState fetchState = _networkFetcher.CreateFetchState(consumer, context);

            _networkFetcher.Fetch(fetchState, new NetworkFetcherCallbackImpl(
                                      (response, responseLength) =>
            {
                OnResponse(fetchState, response, responseLength);
            },
                                      (throwable) =>
            {
                OnFailure(fetchState, throwable);
            },
                                      () =>
            {
                OnCancellation(fetchState);
            }));
        }
        private void OnResponse(
            FetchState fetchState,
            Stream responseData,
            int responseContentLength)
        {
            PooledByteBufferOutputStream pooledOutputStream;

            if (responseContentLength > 0)
            {
                pooledOutputStream = _pooledByteBufferFactory.NewOutputStream(responseContentLength);
            }
            else
            {
                pooledOutputStream = _pooledByteBufferFactory.NewOutputStream();
            }

            byte[] ioArray = _byteArrayPool.Get(READ_SIZE);

            try
            {
                int length;
                while ((length = responseData.Read(ioArray, 0, ioArray.Length)) > 0)
                {
                    pooledOutputStream.Write(ioArray, 0, length);
                    MaybeHandleIntermediateResult(pooledOutputStream, fetchState);
                    float progress = CalculateProgress(pooledOutputStream.Size, responseContentLength);
                    fetchState.Consumer.OnProgressUpdate(progress);
                }

                _networkFetcher.OnFetchCompletion(fetchState, pooledOutputStream.Size);
                HandleFinalResult(pooledOutputStream, fetchState);
            }
            finally
            {
                _byteArrayPool.Release(ioArray);
                pooledOutputStream.Dispose();
            }
        }
 private void OnCancellation(FetchState fetchState)
 {
     fetchState.Listener.OnProducerFinishWithCancellation(fetchState.Id, PRODUCER_NAME, null);
     fetchState.Consumer.OnCancellation();
 }
 private void OnFailure(FetchState fetchState, Exception e)
 {
     fetchState.Listener.OnProducerFinishWithFailure(fetchState.Id, PRODUCER_NAME, e, null);
     fetchState.Consumer.OnFailure(e);
 }