mirror of
https://github.com/owncloud/android-library.git
synced 2025-06-07 16:06:08 +00:00
make the new merged changes from bitfire compile
This commit is contained in:
parent
7bc9a885b0
commit
4968ca6e62
@ -24,6 +24,7 @@ dependencies {
|
||||
// Used for network and database debuging
|
||||
debugApi 'com.facebook.stetho:stetho:1.5.0'
|
||||
debugApi 'com.facebook.stetho:stetho-okhttp3:1.5.0'
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.2.51"
|
||||
}
|
||||
|
||||
android {
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit c6c06a144a1eaf3a75035dfe8700c42b86b0d223
|
||||
Subproject commit da434d7693db7d4cfd434ee22d0d336f37f4b6f8
|
@ -36,6 +36,7 @@ import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory
|
||||
import com.owncloud.android.lib.common.http.HttpClient;
|
||||
import com.owncloud.android.lib.common.http.HttpConstants;
|
||||
import com.owncloud.android.lib.common.http.methods.HttpBaseMethod;
|
||||
import com.owncloud.android.lib.common.http.methods.webdav.CopyMethod;
|
||||
import com.owncloud.android.lib.common.network.RedirectionPath;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
||||
|
@ -52,9 +52,11 @@ public abstract class HttpBaseMethod {
|
||||
protected RequestBody mRequestBody;
|
||||
protected Response mResponse;
|
||||
protected Call mCall;
|
||||
protected URL mUrl;
|
||||
|
||||
protected HttpBaseMethod (URL url) {
|
||||
mOkHttpClient = HttpClient.getOkHttpClient();
|
||||
mUrl = url;
|
||||
mRequest = new Request.Builder()
|
||||
.url(HttpUrl.parse(url.toString()))
|
||||
.build();
|
||||
|
@ -3,7 +3,10 @@ package com.owncloud.android.lib.common.http.methods.webdav;
|
||||
import java.net.URL;
|
||||
|
||||
import at.bitfire.dav4android.exception.UnauthorizedException;
|
||||
import kotlin.Unit;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.Response;
|
||||
|
||||
public class CopyMethod extends DavMethod {
|
||||
|
||||
@ -19,10 +22,10 @@ public class CopyMethod extends DavMethod {
|
||||
@Override
|
||||
public int onExecute() throws Exception {
|
||||
try {
|
||||
mDavResource.copy(destinationUrl, forceOverride);
|
||||
|
||||
mRequest = mDavResource.getRequest();
|
||||
mResponse = mDavResource.getResponse();
|
||||
mDavResource.copy(destinationUrl, forceOverride, response -> {
|
||||
mResponse = response;
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
|
||||
} catch (UnauthorizedException davException) {
|
||||
// Do nothing, we will use the 401 code to handle the situation
|
||||
|
@ -30,6 +30,7 @@ import com.owncloud.android.lib.common.http.methods.HttpBaseMethod;
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import at.bitfire.dav4android.Constants;
|
||||
import at.bitfire.dav4android.DavOCResource;
|
||||
import at.bitfire.dav4android.DavResource;
|
||||
import at.bitfire.dav4android.exception.RedirectException;
|
||||
@ -47,14 +48,14 @@ public abstract class DavMethod extends HttpBaseMethod {
|
||||
super(url);
|
||||
mDavResource = new DavOCResource(
|
||||
mOkHttpClient,
|
||||
HttpUrl.parse(url.toString()));
|
||||
mDavResource.setFollowRedirects(false);
|
||||
HttpUrl.parse(mUrl.toString()),
|
||||
Constants.INSTANCE.getLog());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void abort() {
|
||||
mDavResource.cancelCall();
|
||||
//TODO: abort here
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -62,7 +63,6 @@ public abstract class DavMethod extends HttpBaseMethod {
|
||||
try {
|
||||
return onExecute();
|
||||
} catch(RedirectException e) {
|
||||
mResponse = getDavResource().getResponse();
|
||||
return getStatusCode();
|
||||
}
|
||||
}
|
||||
@ -74,22 +74,38 @@ public abstract class DavMethod extends HttpBaseMethod {
|
||||
// Connection parameters
|
||||
@Override
|
||||
public void setReadTimeout(long readTimeout, TimeUnit timeUnit) {
|
||||
mDavResource.setReadTimeout(readTimeout, timeUnit);
|
||||
super.setReadTimeout(readTimeout, timeUnit);
|
||||
mDavResource = new DavOCResource(
|
||||
mOkHttpClient,
|
||||
HttpUrl.parse(mUrl.toString()),
|
||||
Constants.INSTANCE.getLog());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConnectionTimeout(long connectionTimeout, TimeUnit timeUnit) {
|
||||
mDavResource.setConnectionTimeout(connectionTimeout, timeUnit);
|
||||
super.setConnectionTimeout(connectionTimeout, timeUnit);
|
||||
mDavResource = new DavOCResource(
|
||||
mOkHttpClient,
|
||||
HttpUrl.parse(mUrl.toString()),
|
||||
Constants.INSTANCE.getLog());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFollowRedirects(boolean followRedirects) {
|
||||
mDavResource.setFollowRedirects(followRedirects);
|
||||
super.setFollowRedirects(followRedirects);
|
||||
mDavResource = new DavOCResource(
|
||||
mOkHttpClient,
|
||||
HttpUrl.parse(mUrl.toString()),
|
||||
Constants.INSTANCE.getLog());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRetryOnConnectionFailure(boolean retryOnConnectionFailure) {
|
||||
mDavResource.setRetryOnConnectionFailure(retryOnConnectionFailure);
|
||||
super.setRetryOnConnectionFailure(retryOnConnectionFailure);
|
||||
mDavResource = new DavOCResource(
|
||||
mOkHttpClient,
|
||||
HttpUrl.parse(mUrl.toString()),
|
||||
Constants.INSTANCE.getLog());
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
@ -98,20 +114,19 @@ public abstract class DavMethod extends HttpBaseMethod {
|
||||
|
||||
@Override
|
||||
public boolean getRetryOnConnectionFailure() {
|
||||
return mDavResource.isRetryOnConnectionFailure();
|
||||
return false; //TODO: implement me
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAborted() {
|
||||
return mDavResource.isCallAborted();
|
||||
return true; //TODO: implement me
|
||||
}
|
||||
|
||||
|
||||
public DavResource getDavResource() {
|
||||
return mDavResource;
|
||||
}
|
||||
|
||||
public void setUrl(HttpUrl url) {
|
||||
mDavResource = new DavOCResource(mOkHttpClient, url);
|
||||
public void setUrl(URL url) {
|
||||
mUrl = url;
|
||||
mDavResource = new DavOCResource(
|
||||
mOkHttpClient,
|
||||
HttpUrl.parse(mUrl.toString()),
|
||||
Constants.INSTANCE.getLog());
|
||||
}
|
||||
}
|
@ -3,6 +3,9 @@ package com.owncloud.android.lib.common.http.methods.webdav;
|
||||
import java.net.URL;
|
||||
|
||||
import at.bitfire.dav4android.exception.UnauthorizedException;
|
||||
import kotlin.Unit;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import okhttp3.Response;
|
||||
|
||||
public class MkColMethod extends DavMethod {
|
||||
public MkColMethod(URL url) {
|
||||
@ -12,10 +15,10 @@ public class MkColMethod extends DavMethod {
|
||||
@Override
|
||||
public int onExecute() throws Exception {
|
||||
try {
|
||||
mDavResource.mkCol(null);
|
||||
|
||||
mRequest = mDavResource.getRequest();
|
||||
mResponse = mDavResource.getResponse();
|
||||
mDavResource.mkCol(null, response -> {
|
||||
mResponse = response;
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
|
||||
} catch (UnauthorizedException davException) {
|
||||
// Do nothing, we will use the 401 code to handle the situation
|
||||
|
@ -5,6 +5,9 @@ import com.owncloud.android.lib.common.http.HttpConstants;
|
||||
import java.net.URL;
|
||||
|
||||
import at.bitfire.dav4android.exception.UnauthorizedException;
|
||||
import kotlin.Unit;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import okhttp3.Response;
|
||||
|
||||
public class MoveMethod extends DavMethod {
|
||||
final String destinationUrl;
|
||||
@ -23,11 +26,10 @@ public class MoveMethod extends DavMethod {
|
||||
destinationUrl,
|
||||
forceOverride,
|
||||
super.getRequestHeader(HttpConstants.OC_TOTAL_LENGTH_HEADER),
|
||||
super.getRequestHeader(HttpConstants.OC_X_OC_MTIME_HEADER)
|
||||
);
|
||||
|
||||
mRequest = mDavResource.getRequest();
|
||||
mResponse = mDavResource.getResponse();
|
||||
super.getRequestHeader(HttpConstants.OC_X_OC_MTIME_HEADER), response -> {
|
||||
mResponse = response;
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
|
||||
} catch (UnauthorizedException davException) {
|
||||
// Do nothing, we will use the 401 code to handle the situation
|
||||
|
@ -26,14 +26,13 @@ package com.owncloud.android.lib.common.http.methods.webdav;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Set;
|
||||
|
||||
import at.bitfire.dav4android.DavResource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import at.bitfire.dav4android.Property;
|
||||
import at.bitfire.dav4android.Response;
|
||||
import at.bitfire.dav4android.exception.DavException;
|
||||
import at.bitfire.dav4android.exception.HttpException;
|
||||
import at.bitfire.dav4android.exception.UnauthorizedException;
|
||||
import okhttp3.HttpUrl;
|
||||
import kotlin.Unit;
|
||||
|
||||
/**
|
||||
* Propfind calls wrapper
|
||||
@ -41,28 +40,48 @@ import okhttp3.HttpUrl;
|
||||
*/
|
||||
public class PropfindMethod extends DavMethod {
|
||||
|
||||
private int mDepth;
|
||||
private Property.Name[] mProperties;
|
||||
private Set<DavResource> mMembers;
|
||||
// request
|
||||
private final int mDepth;
|
||||
private final Property.Name[] mPropertiesToRequest;
|
||||
|
||||
public PropfindMethod(URL url, int depth, Property.Name[] properties) {
|
||||
// response
|
||||
private final List<Response> mMembers;
|
||||
private Response mRoot;
|
||||
|
||||
public PropfindMethod(URL url, int depth, Property.Name[] propertiesToRequest) {
|
||||
super(url);
|
||||
mDepth = depth;
|
||||
mProperties = properties;
|
||||
};
|
||||
mPropertiesToRequest = propertiesToRequest;
|
||||
mMembers = new ArrayList<>();
|
||||
mRoot = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onExecute() throws IOException, HttpException, DavException {
|
||||
public int onExecute() throws IOException, DavException {
|
||||
try {
|
||||
mDavResource.propfind(mDepth, mProperties);
|
||||
mMembers = mDavResource.getMembers();
|
||||
mDavResource.propfind(mDepth, mPropertiesToRequest,
|
||||
(Response response, Response.HrefRelation hrefRelation) -> {
|
||||
switch (hrefRelation) {
|
||||
case MEMBER:
|
||||
mMembers.add(response);
|
||||
break;
|
||||
case SELF:
|
||||
mRoot = response;
|
||||
break;
|
||||
case OTHER:
|
||||
default:
|
||||
}
|
||||
|
||||
return Unit.INSTANCE;
|
||||
}, response -> {
|
||||
mResponse = response;
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
} catch (UnauthorizedException davException) {
|
||||
// Do nothing, we will use the 401 code to handle the situation
|
||||
return davException.getCode();
|
||||
}
|
||||
|
||||
mRequest = mDavResource.getRequest();
|
||||
mResponse = mDavResource.getResponse();
|
||||
|
||||
return super.getStatusCode();
|
||||
}
|
||||
|
||||
@ -70,7 +89,11 @@ public class PropfindMethod extends DavMethod {
|
||||
return mDepth;
|
||||
}
|
||||
|
||||
public Set<DavResource> getMembers() {
|
||||
public List<Response> getMembers() {
|
||||
return mMembers;
|
||||
}
|
||||
|
||||
public Response getRoot() {
|
||||
return mRoot;
|
||||
}
|
||||
}
|
@ -32,8 +32,11 @@ import java.net.URL;
|
||||
import at.bitfire.dav4android.exception.DavException;
|
||||
import at.bitfire.dav4android.exception.HttpException;
|
||||
import at.bitfire.dav4android.exception.UnauthorizedException;
|
||||
import kotlin.Unit;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
|
||||
/**
|
||||
* Put calls wrapper
|
||||
@ -51,16 +54,12 @@ public class PutMethod extends DavMethod {
|
||||
mDavResource.put(
|
||||
mRequestBody,
|
||||
super.getRequestHeader(HttpConstants.IF_MATCH_HEADER),
|
||||
// Save a file not known to exist, guaranteeing that another upload didn't happen
|
||||
// before, losing the data of the previous put
|
||||
true,
|
||||
super.getRequestHeader(HttpConstants.CONTENT_TYPE_HEADER),
|
||||
super.getRequestHeader(HttpConstants.OC_TOTAL_LENGTH_HEADER),
|
||||
super.getRequestHeader(HttpConstants.OC_X_OC_MTIME_HEADER)
|
||||
);
|
||||
|
||||
mRequest = mDavResource.getRequest();
|
||||
mResponse = mDavResource.getResponse();
|
||||
super.getRequestHeader(HttpConstants.OC_X_OC_MTIME_HEADER), response -> {
|
||||
mResponse = response;
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
|
||||
} catch (UnauthorizedException davException) {
|
||||
// Do nothing, we will use the 401 code to handle the situation
|
||||
|
@ -87,10 +87,9 @@ public class ReadRemoteFileOperation extends RemoteOperation<RemoteFile> {
|
||||
|
||||
if (status == HttpConstants.HTTP_MULTI_STATUS
|
||||
|| status == HttpConstants.HTTP_OK) {
|
||||
// Parse response
|
||||
final DavResource resource = propfind.getDavResource();
|
||||
|
||||
final RemoteFile file = new RemoteFile(resource, client.getAccount().getDisplayName());
|
||||
final RemoteFile file = new RemoteFile(propfind.getRoot(),
|
||||
client.getAccount().getDisplayName());
|
||||
|
||||
result = new RemoteOperationResult<>(OK);
|
||||
result.setData(file);
|
||||
|
@ -38,6 +38,7 @@ import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import at.bitfire.dav4android.DavResource;
|
||||
import at.bitfire.dav4android.Response;
|
||||
|
||||
import static com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK;
|
||||
|
||||
@ -88,11 +89,11 @@ public class ReadRemoteFolderOperation extends RemoteOperation<ArrayList<RemoteF
|
||||
|
||||
// parse data from remote folder
|
||||
mFolderAndFiles.add(
|
||||
new RemoteFile(propfindMethod.getDavResource(), client.getAccount().getDisplayName())
|
||||
new RemoteFile(propfindMethod.getRoot(), client.getAccount().getDisplayName())
|
||||
);
|
||||
|
||||
// loop to update every child
|
||||
for (DavResource resource : propfindMethod.getMembers()) {
|
||||
for (Response resource : propfindMethod.getMembers()) {
|
||||
RemoteFile file = new RemoteFile(resource, client.getAccount().getDisplayName());
|
||||
mFolderAndFiles.add(file);
|
||||
}
|
||||
|
@ -30,9 +30,12 @@ import android.os.Parcelable;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import at.bitfire.dav4android.DavResource;
|
||||
import at.bitfire.dav4android.Property;
|
||||
import at.bitfire.dav4android.PropertyCollection;
|
||||
import at.bitfire.dav4android.Response;
|
||||
import at.bitfire.dav4android.property.CreationDate;
|
||||
import at.bitfire.dav4android.property.GetContentLength;
|
||||
import at.bitfire.dav4android.property.GetContentType;
|
||||
@ -183,36 +186,45 @@ public class RemoteFile implements Parcelable, Serializable {
|
||||
throw new IllegalArgumentException("Trying to create a OCFile with a non valid remote path: " + path);
|
||||
}
|
||||
mRemotePath = path;
|
||||
mCreationTimestamp = 0;
|
||||
mLength = 0;
|
||||
mMimeType = "DIR";
|
||||
mQuotaUsedBytes = BigDecimal.ZERO;
|
||||
mQuotaAvailableBytes = BigDecimal.ZERO;
|
||||
mPrivateLink = null;
|
||||
}
|
||||
|
||||
public RemoteFile(final DavResource davResource, String displayName) {
|
||||
this(getRemotePathFromUrl(davResource.getLocation(), displayName));
|
||||
final PropertyCollection properties = davResource.getProperties();
|
||||
this.setCreationTimestamp(properties.get(CreationDate.class) != null
|
||||
? Long.parseLong(properties.get(CreationDate.class).getCreationDate())
|
||||
: 0);
|
||||
this.setLength(properties.get(GetContentLength.class) != null
|
||||
? properties.get(GetContentLength.class).getContentLength()
|
||||
: 0);
|
||||
this.setMimeType(properties.get(GetContentType.class) != null
|
||||
? properties.get(GetContentType.class).getType()
|
||||
: "DIR");
|
||||
this.setModifiedTimestamp(properties.get(GetLastModified.class).getLastModified());
|
||||
this.setEtag(properties.get(GetETag.class).getETag());
|
||||
this.setPermissions(properties.get(OCPermissions.class).getPermission());
|
||||
this.setRemoteId(properties.get(OCId.class).getId());
|
||||
this.setSize(properties.get(OCSize.class).getSize());
|
||||
this.setQuotaUsedBytes(properties.get(QuotaUsedBytes.class) != null
|
||||
? BigDecimal.valueOf(
|
||||
properties.get(QuotaUsedBytes.class).getQuotaUsedBytes())
|
||||
: BigDecimal.ZERO);
|
||||
this.setQuotaAvailableBytes(properties.get(QuotaAvailableBytes.class) != null
|
||||
? BigDecimal.valueOf(
|
||||
properties.get(QuotaAvailableBytes.class).getQuotaAvailableBytes())
|
||||
: BigDecimal.ZERO);
|
||||
this.setPrivateLink(properties.get(OCPrivatelink.class) != null
|
||||
? properties.get(OCPrivatelink.class).getLink()
|
||||
: null);
|
||||
public RemoteFile(final Response davResource, String displayName) {
|
||||
this(getRemotePathFromUrl(davResource.getHref(), displayName));
|
||||
final List<Property> properties = davResource.getProperties();
|
||||
|
||||
for(Property property : properties) {
|
||||
if(property instanceof CreationDate)
|
||||
this.setCreationTimestamp(
|
||||
Long.parseLong(((CreationDate) property).getCreationDate()));
|
||||
if(property instanceof GetContentLength)
|
||||
this.setLength(((GetContentLength) property).getContentLength());
|
||||
if(property instanceof GetContentType)
|
||||
this.setMimeType(((GetContentType) property).getType());
|
||||
if(property instanceof GetLastModified)
|
||||
this.setModifiedTimestamp(((GetLastModified) property).getLastModified());
|
||||
if(property instanceof GetETag)
|
||||
this.setEtag(((GetETag) property).getETag());
|
||||
if(property instanceof OCPermissions)
|
||||
this.setPermissions(((OCPermissions) property).getPermission());
|
||||
if(property instanceof OCId)
|
||||
this.setRemoteId(((OCId) property).getId());
|
||||
if(property instanceof OCSize)
|
||||
this.setSize(((OCSize) property).getSize());
|
||||
if(property instanceof QuotaUsedBytes)
|
||||
this.setQuotaUsedBytes(
|
||||
BigDecimal.valueOf(((QuotaUsedBytes) property).getQuotaUsedBytes()));
|
||||
if(property instanceof QuotaAvailableBytes)
|
||||
this.setQuotaAvailableBytes(
|
||||
BigDecimal.valueOf(((QuotaAvailableBytes) property).getQuotaAvailableBytes()));
|
||||
if(property instanceof OCPrivatelink)
|
||||
this.setPrivateLink(((OCPrivatelink) property).getLink());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -37,7 +37,9 @@ import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
|
||||
import at.bitfire.dav4android.Property;
|
||||
import at.bitfire.dav4android.PropertyCollection;
|
||||
import at.bitfire.dav4android.property.QuotaAvailableBytes;
|
||||
import at.bitfire.dav4android.property.QuotaUsedBytes;
|
||||
@ -90,13 +92,12 @@ public class GetRemoteUserQuotaOperation extends RemoteOperation<GetRemoteUserQu
|
||||
PropfindMethod propfindMethod = new PropfindMethod(
|
||||
new URL(client.getNewFilesWebDavUri() + WebdavUtils.encodePath(mRemotePath)),
|
||||
DEPTH_0,
|
||||
DavUtils.getQuotaPropSet()
|
||||
);
|
||||
DavUtils.getQuotaPropSet());
|
||||
|
||||
int status = client.executeHttpMethod(propfindMethod);
|
||||
|
||||
if (isSuccess(status)) {
|
||||
RemoteQuota remoteQuota = readData(propfindMethod.getDavResource().getProperties());
|
||||
RemoteQuota remoteQuota = readData(propfindMethod.getRoot().getProperties());
|
||||
|
||||
result = new RemoteOperationResult<>(OK);
|
||||
|
||||
@ -139,10 +140,16 @@ public class GetRemoteUserQuotaOperation extends RemoteOperation<GetRemoteUserQu
|
||||
* @param properties WebDAV properties containing quota data
|
||||
* @return new {@link RemoteQuota} instance representing the data read from the server
|
||||
*/
|
||||
private RemoteQuota readData(PropertyCollection properties) {
|
||||
private RemoteQuota readData(List<Property> properties) {
|
||||
long quotaAvailable = 0;
|
||||
long quotaUsed = 0;
|
||||
|
||||
long quotaAvailable = properties.get(QuotaAvailableBytes.class).getQuotaAvailableBytes();
|
||||
long quotaUsed = properties.get(QuotaUsedBytes.class).getQuotaUsedBytes();
|
||||
for(Property property : properties) {
|
||||
if(property instanceof QuotaAvailableBytes)
|
||||
quotaAvailable = ((QuotaAvailableBytes) property).getQuotaAvailableBytes();
|
||||
if(property instanceof QuotaUsedBytes)
|
||||
quotaUsed = ((QuotaUsedBytes) property).getQuotaUsedBytes();
|
||||
}
|
||||
|
||||
// If there's a special case, quota available will contain a negative code
|
||||
// -1, PENDING: Not computed yet, e.g. external storage mounted but folder sizes need scanning
|
||||
|
Loading…
x
Reference in New Issue
Block a user