Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add support for uploading a ParseFile from a URI #1207

Merged
merged 3 commits into from
Feb 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions parse/src/main/java/com/parse/ParseCountingUriHttpBody.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright (c) 2015-present, Parse, LLC.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.parse;

import android.net.Uri;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

class ParseCountingUriHttpBody extends ParseUriHttpBody {

private static final int DEFAULT_CHUNK_SIZE = 4096;
private static final int EOF = -1;

private final ProgressCallback progressCallback;

public ParseCountingUriHttpBody(Uri uri, ProgressCallback progressCallback) {
this(uri, null, progressCallback);
}

Check warning on line 25 in parse/src/main/java/com/parse/ParseCountingUriHttpBody.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseCountingUriHttpBody.java#L24-L25

Added lines #L24 - L25 were not covered by tests

public ParseCountingUriHttpBody(
Uri uri, String contentType, ProgressCallback progressCallback) {
super(uri, contentType);
this.progressCallback = progressCallback;
}

Check warning on line 31 in parse/src/main/java/com/parse/ParseCountingUriHttpBody.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseCountingUriHttpBody.java#L29-L31

Added lines #L29 - L31 were not covered by tests

@Override
public void writeTo(OutputStream output) throws IOException {
if (output == null) {
throw new IllegalArgumentException("Output stream may not be null");

Check warning on line 36 in parse/src/main/java/com/parse/ParseCountingUriHttpBody.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseCountingUriHttpBody.java#L36

Added line #L36 was not covered by tests
}

final InputStream fileInput =
Parse.getApplicationContext().getContentResolver().openInputStream(uri);

Check warning on line 40 in parse/src/main/java/com/parse/ParseCountingUriHttpBody.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseCountingUriHttpBody.java#L40

Added line #L40 was not covered by tests
try {
byte[] buffer = new byte[DEFAULT_CHUNK_SIZE];

Check warning on line 42 in parse/src/main/java/com/parse/ParseCountingUriHttpBody.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseCountingUriHttpBody.java#L42

Added line #L42 was not covered by tests
int n;
long totalLength = getContentLength();
long position = 0;

Check warning on line 45 in parse/src/main/java/com/parse/ParseCountingUriHttpBody.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseCountingUriHttpBody.java#L44-L45

Added lines #L44 - L45 were not covered by tests
while (EOF != (n = fileInput.read(buffer))) {
output.write(buffer, 0, n);
position += n;

Check warning on line 48 in parse/src/main/java/com/parse/ParseCountingUriHttpBody.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseCountingUriHttpBody.java#L47-L48

Added lines #L47 - L48 were not covered by tests

if (progressCallback != null) {
int progress = (int) (100 * position / totalLength);
progressCallback.done(progress);
}

Check warning on line 53 in parse/src/main/java/com/parse/ParseCountingUriHttpBody.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseCountingUriHttpBody.java#L51-L53

Added lines #L51 - L53 were not covered by tests
}
} finally {
ParseIOUtils.closeQuietly(fileInput);

Check warning on line 56 in parse/src/main/java/com/parse/ParseCountingUriHttpBody.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseCountingUriHttpBody.java#L56

Added line #L56 was not covered by tests
}
}

Check warning on line 58 in parse/src/main/java/com/parse/ParseCountingUriHttpBody.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseCountingUriHttpBody.java#L58

Added line #L58 was not covered by tests
}
27 changes: 27 additions & 0 deletions parse/src/main/java/com/parse/ParseFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
*/
package com.parse;

import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import com.parse.boltsinternal.Continuation;
Expand Down Expand Up @@ -64,6 +65,7 @@
*/
/* package for tests */ byte[] data;
/* package for tests */ File file;
/* package for tests */ Uri uri;
private State state;

/**
Expand Down Expand Up @@ -102,6 +104,21 @@
this.data = data;
}

/**
* Creates a new file from a content uri, file name, and content type. Content type will be used
* instead of auto-detection by file extension.
*
* @param name The file's name, ideally with extension. The file name must begin with an
* alphanumeric character, and consist of alphanumeric characters, periods, spaces,
* underscores, or dashes.
* @param uri The file uri.
* @param contentType The file's content type.
*/
public ParseFile(String name, Uri uri, String contentType) {
this(new State.Builder().name(name).mimeType(contentType).build());
this.uri = uri;
}

Check warning on line 120 in parse/src/main/java/com/parse/ParseFile.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseFile.java#L118-L120

Added lines #L118 - L120 were not covered by tests

/**
* Creates a new file from a byte array.
*
Expand Down Expand Up @@ -274,6 +291,16 @@
progressCallbackOnMainThread(
uploadProgressCallback),
cancellationToken);
} else if (uri != null) {
saveTask =
getFileController()
.saveAsync(

Check warning on line 297 in parse/src/main/java/com/parse/ParseFile.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseFile.java#L296-L297

Added lines #L296 - L297 were not covered by tests
state,
uri,
sessionToken,
progressCallbackOnMainThread(

Check warning on line 301 in parse/src/main/java/com/parse/ParseFile.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseFile.java#L301

Added line #L301 was not covered by tests
uploadProgressCallback),
cancellationToken);
} else {
saveTask =
getFileController()
Expand Down
44 changes: 44 additions & 0 deletions parse/src/main/java/com/parse/ParseFileController.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
*/
package com.parse;

import android.net.Uri;
import com.parse.boltsinternal.Task;
import com.parse.http.ParseHttpRequest;
import java.io.File;
Expand Down Expand Up @@ -163,6 +164,49 @@
ParseExecutors.io());
}

public Task<ParseFile.State> saveAsync(
final ParseFile.State state,
final Uri uri,
String sessionToken,
ProgressCallback uploadProgressCallback,
Task<Void> cancellationToken) {
if (state.url() != null) { // !isDirty
return Task.forResult(state);

Check warning on line 174 in parse/src/main/java/com/parse/ParseFileController.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseFileController.java#L174

Added line #L174 was not covered by tests
}
if (cancellationToken != null && cancellationToken.isCancelled()) {
return Task.cancelled();

Check warning on line 177 in parse/src/main/java/com/parse/ParseFileController.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseFileController.java#L177

Added line #L177 was not covered by tests
}

final ParseRESTCommand command =

Check warning on line 180 in parse/src/main/java/com/parse/ParseFileController.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseFileController.java#L180

Added line #L180 was not covered by tests
new ParseRESTFileCommand.Builder()
.fileName(state.name())
.uri(uri)
.contentType(state.mimeType())
.sessionToken(sessionToken)
.build();

Check warning on line 186 in parse/src/main/java/com/parse/ParseFileController.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseFileController.java#L182-L186

Added lines #L182 - L186 were not covered by tests

return command.executeAsync(restClient, uploadProgressCallback, null, cancellationToken)
.onSuccess(

Check warning on line 189 in parse/src/main/java/com/parse/ParseFileController.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseFileController.java#L188-L189

Added lines #L188 - L189 were not covered by tests
task -> {
JSONObject result = task.getResult();
ParseFile.State newState =

Check warning on line 192 in parse/src/main/java/com/parse/ParseFileController.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseFileController.java#L191-L192

Added lines #L191 - L192 were not covered by tests
new ParseFile.State.Builder(state)
.name(result.getString("name"))
.url(result.getString("url"))
.build();

Check warning on line 196 in parse/src/main/java/com/parse/ParseFileController.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseFileController.java#L194-L196

Added lines #L194 - L196 were not covered by tests

// Write data to cache
try {
ParseFileUtils.writeUriToFile(getCacheFile(newState), uri);
} catch (IOException e) {

Check warning on line 201 in parse/src/main/java/com/parse/ParseFileController.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseFileController.java#L200-L201

Added lines #L200 - L201 were not covered by tests
// do nothing
}

Check warning on line 203 in parse/src/main/java/com/parse/ParseFileController.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseFileController.java#L203

Added line #L203 was not covered by tests

return newState;

Check warning on line 205 in parse/src/main/java/com/parse/ParseFileController.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseFileController.java#L205

Added line #L205 was not covered by tests
},
ParseExecutors.io());

Check warning on line 207 in parse/src/main/java/com/parse/ParseFileController.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseFileController.java#L207

Added line #L207 was not covered by tests
}

public Task<File> fetchAsync(
final ParseFile.State state,
@SuppressWarnings("UnusedParameters") String sessionToken,
Expand Down
25 changes: 25 additions & 0 deletions parse/src/main/java/com/parse/ParseFileUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package com.parse;

import android.net.Uri;
import androidx.annotation.NonNull;
import java.io.File;
import java.io.FileInputStream;
Expand Down Expand Up @@ -115,6 +116,30 @@
}
}

/**
* Writes a content uri to a file creating the file if it does not exist.
*
* <p>NOTE: As from v1.3, the parent directories of the file will be created if they do not
* exist.
*
* @param file the file to write to
* @param uri the content uri with data to write to the file
* @throws IOException in case of an I/O error
* @since Commons IO 1.1
*/
public static void writeUriToFile(File file, Uri uri) throws IOException {
OutputStream out = null;
InputStream in = null;

Check warning on line 132 in parse/src/main/java/com/parse/ParseFileUtils.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseFileUtils.java#L131-L132

Added lines #L131 - L132 were not covered by tests
try {
in = Parse.getApplicationContext().getContentResolver().openInputStream(uri);
out = openOutputStream(file);
ParseIOUtils.copyLarge(in, out);

Check warning on line 136 in parse/src/main/java/com/parse/ParseFileUtils.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseFileUtils.java#L134-L136

Added lines #L134 - L136 were not covered by tests
} finally {
ParseIOUtils.closeQuietly(out);
ParseIOUtils.closeQuietly(in);

Check warning on line 139 in parse/src/main/java/com/parse/ParseFileUtils.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseFileUtils.java#L138-L139

Added lines #L138 - L139 were not covered by tests
}
}

Check warning on line 141 in parse/src/main/java/com/parse/ParseFileUtils.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseFileUtils.java#L141

Added line #L141 was not covered by tests

// -----------------------------------------------------------------------

/**
Expand Down
35 changes: 29 additions & 6 deletions parse/src/main/java/com/parse/ParseRESTFileCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
*/
package com.parse;

import android.net.Uri;
import com.parse.http.ParseHttpBody;
import com.parse.http.ParseHttpRequest;
import java.io.File;
Expand All @@ -18,15 +19,23 @@
private final byte[] data;
private final String contentType;
private final File file;
private final Uri uri;

public ParseRESTFileCommand(Builder builder) {
super(builder);
if (builder.file != null && builder.data != null) {
throw new IllegalArgumentException("File and data can not be set at the same time");
}
if (builder.uri != null && builder.data != null) {
throw new IllegalArgumentException("URI and data can not be set at the same time");

Check warning on line 30 in parse/src/main/java/com/parse/ParseRESTFileCommand.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseRESTFileCommand.java#L30

Added line #L30 was not covered by tests
}
if (builder.file != null && builder.uri != null) {
throw new IllegalArgumentException("File and URI can not be set at the same time");

Check warning on line 33 in parse/src/main/java/com/parse/ParseRESTFileCommand.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseRESTFileCommand.java#L33

Added line #L33 was not covered by tests
}
this.data = builder.data;
this.contentType = builder.contentType;
this.file = builder.file;
this.uri = builder.uri;

Check warning on line 38 in parse/src/main/java/com/parse/ParseRESTFileCommand.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseRESTFileCommand.java#L38

Added line #L38 was not covered by tests
}

@Override
Expand All @@ -35,20 +44,29 @@
// file
// in ParseFileController
if (progressCallback == null) {
return data != null
? new ParseByteArrayHttpBody(data, contentType)
: new ParseFileHttpBody(file, contentType);
if (data != null) {
return new ParseByteArrayHttpBody(data, contentType);

Check warning on line 48 in parse/src/main/java/com/parse/ParseRESTFileCommand.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseRESTFileCommand.java#L48

Added line #L48 was not covered by tests
} else if (uri != null) {
return new ParseUriHttpBody(uri, contentType);

Check warning on line 50 in parse/src/main/java/com/parse/ParseRESTFileCommand.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseRESTFileCommand.java#L50

Added line #L50 was not covered by tests
} else {
return new ParseFileHttpBody(file, contentType);

Check warning on line 52 in parse/src/main/java/com/parse/ParseRESTFileCommand.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseRESTFileCommand.java#L52

Added line #L52 was not covered by tests
}
}
if (data != null) {
return new ParseCountingByteArrayHttpBody(data, contentType, progressCallback);

Check warning on line 56 in parse/src/main/java/com/parse/ParseRESTFileCommand.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseRESTFileCommand.java#L56

Added line #L56 was not covered by tests
} else if (uri != null) {
return new ParseCountingUriHttpBody(uri, contentType, progressCallback);

Check warning on line 58 in parse/src/main/java/com/parse/ParseRESTFileCommand.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseRESTFileCommand.java#L58

Added line #L58 was not covered by tests
} else {
return new ParseCountingFileHttpBody(file, contentType, progressCallback);

Check warning on line 60 in parse/src/main/java/com/parse/ParseRESTFileCommand.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseRESTFileCommand.java#L60

Added line #L60 was not covered by tests
}
return data != null
? new ParseCountingByteArrayHttpBody(data, contentType, progressCallback)
: new ParseCountingFileHttpBody(file, contentType, progressCallback);
}

public static class Builder extends Init<Builder> {

private byte[] data = null;
private String contentType = null;
private File file;
private Uri uri;

public Builder() {
// We only ever use ParseRESTFileCommand for file uploads, so default to POST.
Expand All @@ -74,6 +92,11 @@
return this;
}

public Builder uri(Uri uri) {
this.uri = uri;
return this;

Check warning on line 97 in parse/src/main/java/com/parse/ParseRESTFileCommand.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseRESTFileCommand.java#L96-L97

Added lines #L96 - L97 were not covered by tests
}

@Override
/* package */ Builder self() {
return this;
Expand Down
96 changes: 96 additions & 0 deletions parse/src/main/java/com/parse/ParseUriHttpBody.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
* Copyright (c) 2015-present, Parse, LLC.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.parse;

import static com.parse.Parse.getApplicationContext;

import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.provider.OpenableColumns;
import com.parse.http.ParseHttpBody;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

class ParseUriHttpBody extends ParseHttpBody {

/* package */ final Uri uri;

public ParseUriHttpBody(Uri uri) {
this(uri, null);
}

Check warning on line 29 in parse/src/main/java/com/parse/ParseUriHttpBody.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseUriHttpBody.java#L28-L29

Added lines #L28 - L29 were not covered by tests

public ParseUriHttpBody(Uri uri, String contentType) {
super(contentType, getUriLength(uri));
this.uri = uri;
}

Check warning on line 34 in parse/src/main/java/com/parse/ParseUriHttpBody.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseUriHttpBody.java#L32-L34

Added lines #L32 - L34 were not covered by tests

private static long getUriLength(Uri uri) {
long length = -1;

Check warning on line 37 in parse/src/main/java/com/parse/ParseUriHttpBody.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseUriHttpBody.java#L37

Added line #L37 was not covered by tests

try (Cursor cursor =
getApplicationContext()
.getContentResolver()
.query(uri, null, null, null, null, null)) {

Check warning on line 42 in parse/src/main/java/com/parse/ParseUriHttpBody.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseUriHttpBody.java#L40-L42

Added lines #L40 - L42 were not covered by tests
if (cursor != null && cursor.moveToFirst()) {
int sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE);

Check warning on line 44 in parse/src/main/java/com/parse/ParseUriHttpBody.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseUriHttpBody.java#L44

Added line #L44 was not covered by tests
if (!cursor.isNull(sizeIndex)) {
length = cursor.getLong(sizeIndex);

Check warning on line 46 in parse/src/main/java/com/parse/ParseUriHttpBody.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseUriHttpBody.java#L46

Added line #L46 was not covered by tests
}
}
}
if (length == -1) {
try {
ParcelFileDescriptor parcelFileDescriptor =
getApplicationContext().getContentResolver().openFileDescriptor(uri, "r");

Check warning on line 53 in parse/src/main/java/com/parse/ParseUriHttpBody.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseUriHttpBody.java#L53

Added line #L53 was not covered by tests
if (parcelFileDescriptor != null) {
length = parcelFileDescriptor.getStatSize();
parcelFileDescriptor.close();

Check warning on line 56 in parse/src/main/java/com/parse/ParseUriHttpBody.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseUriHttpBody.java#L55-L56

Added lines #L55 - L56 were not covered by tests
}
} catch (IOException ignored) {
}

Check warning on line 59 in parse/src/main/java/com/parse/ParseUriHttpBody.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseUriHttpBody.java#L58-L59

Added lines #L58 - L59 were not covered by tests
}
if (length == -1) {
try {
AssetFileDescriptor assetFileDescriptor =
getApplicationContext()
.getContentResolver()
.openAssetFileDescriptor(uri, "r");

Check warning on line 66 in parse/src/main/java/com/parse/ParseUriHttpBody.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseUriHttpBody.java#L64-L66

Added lines #L64 - L66 were not covered by tests
if (assetFileDescriptor != null) {
length = assetFileDescriptor.getLength();
assetFileDescriptor.close();

Check warning on line 69 in parse/src/main/java/com/parse/ParseUriHttpBody.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseUriHttpBody.java#L68-L69

Added lines #L68 - L69 were not covered by tests
}
} catch (IOException ignored) {
}

Check warning on line 72 in parse/src/main/java/com/parse/ParseUriHttpBody.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseUriHttpBody.java#L71-L72

Added lines #L71 - L72 were not covered by tests
}
return length;

Check warning on line 74 in parse/src/main/java/com/parse/ParseUriHttpBody.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseUriHttpBody.java#L74

Added line #L74 was not covered by tests
}

@Override
public InputStream getContent() throws IOException {
return getApplicationContext().getContentResolver().openInputStream(uri);

Check warning on line 79 in parse/src/main/java/com/parse/ParseUriHttpBody.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseUriHttpBody.java#L79

Added line #L79 was not covered by tests
}

@Override
public void writeTo(OutputStream out) throws IOException {
if (out == null) {
throw new IllegalArgumentException("Output stream can not be null");

Check warning on line 85 in parse/src/main/java/com/parse/ParseUriHttpBody.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseUriHttpBody.java#L85

Added line #L85 was not covered by tests
}

final InputStream fileInput =
getApplicationContext().getContentResolver().openInputStream(uri);

Check warning on line 89 in parse/src/main/java/com/parse/ParseUriHttpBody.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseUriHttpBody.java#L89

Added line #L89 was not covered by tests
try {
ParseIOUtils.copy(fileInput, out);

Check warning on line 91 in parse/src/main/java/com/parse/ParseUriHttpBody.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseUriHttpBody.java#L91

Added line #L91 was not covered by tests
} finally {
ParseIOUtils.closeQuietly(fileInput);

Check warning on line 93 in parse/src/main/java/com/parse/ParseUriHttpBody.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseUriHttpBody.java#L93

Added line #L93 was not covered by tests
}
}

Check warning on line 95 in parse/src/main/java/com/parse/ParseUriHttpBody.java

View check run for this annotation

Codecov / codecov/patch

parse/src/main/java/com/parse/ParseUriHttpBody.java#L95

Added line #L95 was not covered by tests
}
Loading
Loading