/* * Catroid: An on-device visual programming system for Android devices * Copyright (C) 2010-2016 The Catrobat Team * (<http://developer.catrobat.org/credits>) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * An additional term exception under section 7 of the GNU Affero * General Public License, version 3, is available at * http://developer.catrobat.org/license_additional_term * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.catrobat.catroid.web; import android.os.Bundle; import android.os.ResultReceiver; import com.squareup.okhttp.MediaType; import com.squareup.okhttp.ResponseBody; import org.catrobat.catroid.common.Constants; import java.io.IOException; import okio.Buffer; import okio.BufferedSource; import okio.ForwardingSource; import okio.Okio; import okio.Source; public class ProgressResponseBody extends ResponseBody { public static final String TAG_PROGRESS = "currentDownloadProgress"; public static final String TAG_ENDOFFILE = "endOfFileReached"; public static final String TAG_NOTIFICATION_ID = "notificationId"; public static final String TAG_PROGRAM_NAME = "programName"; public static final String TAG_REQUEST_URL = "requestUrl"; private final ResponseBody responseBody; private final ResultReceiver receiver; private final int notificationId; private final String programName; private final String requestUrl; private BufferedSource bufferedSource; public ProgressResponseBody(ResponseBody responseBody, ResultReceiver receiver, int notificationId, String programName, String requestUrl) throws IOException { this.responseBody = responseBody; this.receiver = receiver; this.notificationId = notificationId; this.programName = programName; this.requestUrl = requestUrl; } @Override public MediaType contentType() { return responseBody.contentType(); } @Override public long contentLength() throws IOException { return responseBody.contentLength(); } @Override public BufferedSource source() throws IOException { if (bufferedSource == null) { bufferedSource = Okio.buffer(source(responseBody.source())); } return bufferedSource; } private Source source(Source source) { return new ForwardingSource(source) { long totalBytesRead = 0L; long lastProgress = -1L; @Override public long read(Buffer sink, long byteCount) throws IOException { long bytesRead = super.read(sink, byteCount); totalBytesRead += bytesRead != -1 ? bytesRead : 0; long progress = (100 * totalBytesRead) / contentLength(); boolean endOfFile = bytesRead == -1; if (progress > lastProgress || endOfFile) { sendUpdateIntent(progress, endOfFile); lastProgress = progress; } return bytesRead; } }; } private void sendUpdateIntent(long progress, boolean endOfFileReached) { Bundle progressBundle = new Bundle(); progressBundle.putLong(TAG_PROGRESS, progress); progressBundle.putBoolean(TAG_ENDOFFILE, endOfFileReached); progressBundle.putInt(TAG_NOTIFICATION_ID, notificationId); progressBundle.putString(TAG_PROGRAM_NAME, programName); progressBundle.putString(TAG_REQUEST_URL, requestUrl); receiver.send(Constants.UPDATE_DOWNLOAD_PROGRESS, progressBundle); } }