diff --git a/.travis.yml b/.travis.yml index 6a458c15..4fae7ec7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,33 +2,40 @@ sudo: false language: android jdk: - oraclejdk8 -android: - components: -# first 'tools' updates SDK tools 'til last version ** in remote repository number 10 ** - - tools -# second 'tools' updates SDK tools 'til last version ** in remote repository number 11 ** (current last one) - - tools - - platform-tools - - build-tools-25.0.2 - - android-24 - - sys-img-armeabi-v7a-android-24 branches: only: - master -before_install: -- echo no | android create avd --force -n test -t $ANDROID_TARGET --abi $ANDROID_ABI - -c 20M -- emulator -avd test -no-window & +install: +# Let's use the new command 'sdkmanager' to install Android SDK components +- yes | sdkmanager --verbose "build-tools;26.0.2" +- yes | sdkmanager --verbose "platform-tools" +- yes | sdkmanager --verbose "tools" +- yes | sdkmanager --verbose "platforms;android-26" +- yes | sdkmanager --verbose "system-images;android-24;default;armeabi-v7a" + +# Check tools and dependencies installed +- yes | sdkmanager --list + +# After Travis updated image with Android base environment, building via ant is not possible anymore. +# Library tests are old-style tests, and trust on legacy Android ant environment. +# Need to disable tests until they are ported to JUnit 4 and gradle build. +#- echo no | android create avd --force -n test -t $ANDROID_TARGET --abi $ANDROID_ABI -c 20M +#- emulator -avd test -no-window & - rm pom.xml -- android update project -p . -- chmod +x ./wait_for_emulator.sh -- ./wait_for_emulator.sh +#- android update project -p . +#- chmod +x ./wait_for_emulator.sh +#- ./wait_for_emulator.sh +# +# On the other hand, Travis still uses 'android' command behind the 'components' section update. +# That command is obsolete and cannot update Android SDK Tools after 25.2.5. +# Let's solve it here with the new command 'sdkmanager' +- yes | sdkmanager --verbose tools script: -- ant clean -- ant debug -- cd test_client/tests -- ant acceptance-test -- cd ../.. +#- ant clean +#- ant debug +#- cd test_client/tests +#- ant acceptance-test +#- cd ../.. - ./gradlew clean build env: global: @@ -36,7 +43,7 @@ env: # via the "travis encrypt" command using the project repo's public key - secure: epTZ0zZGDbHL3o6vSC9uNkZsi5j5SA6O/tvQBH7QW/dluuzIJxIjfhNbZHDyBReYDleirLzUFQpdWAUdvulCMLs/qZdIzFGlYXZSpxEnvPYMGQcilwADdJcxLw8L+3+ET5hSexxhjrTGw427IljkqGUpqQTxaLwFdFu98lDWSbc= matrix: - - ANDROID_TARGET=android-24 ANDROID_ABI=armeabi-v7a + - ANDROID_TARGET=android-26 ANDROID_ABI=armeabi-v7a addons: coverity_scan: project: diff --git a/AndroidManifest.xml b/AndroidManifest.xml index adb2be3f..36c89370 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -35,7 +35,7 @@ + android:targetSdkVersion="26" /> diff --git a/build.gradle b/build.gradle index ccee2aa3..64b3f1dd 100644 --- a/build.gradle +++ b/build.gradle @@ -18,8 +18,8 @@ dependencies { } android { - compileSdkVersion 24 - buildToolsVersion '25.0.2' + compileSdkVersion 26 + buildToolsVersion '26.0.2' sourceSets { main { diff --git a/sample_client/AndroidManifest.xml b/sample_client/AndroidManifest.xml index ee94e2f0..df33bb06 100644 --- a/sample_client/AndroidManifest.xml +++ b/sample_client/AndroidManifest.xml @@ -30,7 +30,7 @@ + android:targetSdkVersion="26" /> 0) mName = tmp[tmp.length - 1]; @@ -91,17 +91,17 @@ public class WebdavEntry { mContentType = mContentType.substring(0, mContentType.indexOf(";")); } } - + // check if it's a folder in the standard way: see RFC2518 12.2 . RFC4918 14.3 // {DAV:}resourcetype prop = propSet.get(DavPropertyName.RESOURCETYPE); - if (prop!= null) { + if (prop != null) { Object value = prop.getValue(); if (value != null) { mContentType = "DIR"; // a specific attribute would be better, - // but this is enough; - // unless while we have no reason to distinguish - // MIME types for folders + // but this is enough; + // unless while we have no reason to distinguish + // MIME types for folders } } @@ -114,14 +114,14 @@ public class WebdavEntry { prop = propSet.get(DavPropertyName.GETLASTMODIFIED); if (prop != null) { Date d = WebdavUtils - .parseResponseDate((String) prop.getValue()); + .parseResponseDate((String) prop.getValue()); mModifiedTimestamp = (d != null) ? d.getTime() : 0; } prop = propSet.get(DavPropertyName.CREATIONDATE); if (prop != null) { Date d = WebdavUtils - .parseResponseDate((String) prop.getValue()); + .parseResponseDate((String) prop.getValue()); mCreateTimestamp = (d != null) ? d.getTime() : 0; } @@ -140,10 +140,10 @@ public class WebdavEntry { mQuotaUsedBytes = new BigDecimal(quotaUsedBytesSt); } catch (NumberFormatException e) { Log_OC.w(TAG, "No value for QuotaUsedBytes - NumberFormatException"); - } catch (NullPointerException e ){ + } catch (NullPointerException e) { Log_OC.w(TAG, "No value for QuotaUsedBytes - NullPointerException"); } - Log_OC.d(TAG , "QUOTA_USED_BYTES " + quotaUsedBytesSt ); + Log_OC.d(TAG, "QUOTA_USED_BYTES " + quotaUsedBytesSt); } // {DAV:}quota-available-bytes @@ -154,47 +154,54 @@ public class WebdavEntry { mQuotaAvailableBytes = new BigDecimal(quotaAvailableBytesSt); } catch (NumberFormatException e) { Log_OC.w(TAG, "No value for QuotaAvailableBytes - NumberFormatException"); - } catch (NullPointerException e ){ + } catch (NullPointerException e) { Log_OC.w(TAG, "No value for QuotaAvailableBytes"); } - Log_OC.d(TAG , "QUOTA_AVAILABLE_BYTES " + quotaAvailableBytesSt ); + Log_OC.d(TAG, "QUOTA_AVAILABLE_BYTES " + quotaAvailableBytesSt); } // OC permissions property prop = propSet.get( - EXTENDED_PROPERTY_NAME_PERMISSIONS, Namespace.getNamespace(NAMESPACE_OC) - ); + EXTENDED_PROPERTY_NAME_PERMISSIONS, Namespace.getNamespace(NAMESPACE_OC) + ); if (prop != null) { mPermissions = prop.getValue().toString(); } // OC remote id property prop = propSet.get( - EXTENDED_PROPERTY_NAME_REMOTE_ID, Namespace.getNamespace(NAMESPACE_OC) - ); + EXTENDED_PROPERTY_NAME_REMOTE_ID, Namespace.getNamespace(NAMESPACE_OC) + ); if (prop != null) { mRemoteId = prop.getValue().toString(); } - // TODO: is it necessary? // OC size property prop = propSet.get( - EXTENDED_PROPERTY_NAME_SIZE, Namespace.getNamespace(NAMESPACE_OC) - ); + EXTENDED_PROPERTY_NAME_SIZE, Namespace.getNamespace(NAMESPACE_OC) + ); if (prop != null) { mSize = Long.parseLong((String) prop.getValue()); } + // OC privatelink property + prop = propSet.get( + EXTENDED_PROPERTY_NAME_PRIVATE_LINK, Namespace.getNamespace(NAMESPACE_OC) + ); + if (prop != null) { + mPrivateLink = prop.getValue().toString(); + } + } else { Log_OC.e("WebdavEntry", - "General fuckup, no status for webdav response"); + "General fuckup, no status for webdav response"); } } public String path() { return mPath; } - + public String decodedPath() { return Uri.decode(mPath); } @@ -226,7 +233,7 @@ public class WebdavEntry { public long modifiedTimestamp() { return mModifiedTimestamp; } - + public String etag() { return mEtag; } @@ -239,7 +246,7 @@ public class WebdavEntry { return mRemoteId; } - public long size(){ + public long size() { return mSize; } @@ -251,11 +258,17 @@ public class WebdavEntry { return mQuotaAvailableBytes; } + public String privateLink() { + return mPrivateLink; + } + private void resetData() { - mName = mUri = mContentType = mPermissions = null; mRemoteId = null; + mName = mUri = mContentType = mPermissions = null; + mRemoteId = null; mContentLength = mCreateTimestamp = mModifiedTimestamp = 0; mSize = 0; mQuotaUsedBytes = null; mQuotaAvailableBytes = null; + mPrivateLink = null; } } diff --git a/src/com/owncloud/android/lib/common/network/WebdavUtils.java b/src/com/owncloud/android/lib/common/network/WebdavUtils.java index 3e9c986d..8c307b60 100644 --- a/src/com/owncloud/android/lib/common/network/WebdavUtils.java +++ b/src/com/owncloud/android/lib/common/network/WebdavUtils.java @@ -107,6 +107,8 @@ public class WebdavUtils { Namespace.getNamespace(WebdavEntry.NAMESPACE_OC)); propSet.add(WebdavEntry.EXTENDED_PROPERTY_NAME_SIZE, Namespace.getNamespace(WebdavEntry.NAMESPACE_OC)); + propSet.add(WebdavEntry.EXTENDED_PROPERTY_NAME_PRIVATE_LINK, + Namespace.getNamespace(WebdavEntry.NAMESPACE_OC)); return propSet; } @@ -130,6 +132,10 @@ public class WebdavUtils { Namespace.getNamespace(WebdavEntry.NAMESPACE_OC)); propSet.add(WebdavEntry.EXTENDED_PROPERTY_NAME_SIZE, Namespace.getNamespace(WebdavEntry.NAMESPACE_OC)); + propSet.add(WebdavEntry.EXTENDED_PROPERTY_NAME_SIZE, + Namespace.getNamespace(WebdavEntry.NAMESPACE_OC)); + propSet.add(WebdavEntry.EXTENDED_PROPERTY_NAME_PRIVATE_LINK, + Namespace.getNamespace(WebdavEntry.NAMESPACE_OC)); return propSet; } diff --git a/src/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.java b/src/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.java index 2b260e2f..53b8295f 100644 --- a/src/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.java +++ b/src/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.java @@ -171,6 +171,7 @@ public class ReadRemoteFolderOperation extends RemoteOperation { file.setSize(we.size()); file.setQuotaUsedBytes(we.quotaUsedBytes()); file.setQuotaAvailableBytes(we.quotaAvailableBytes()); + file.setPrivateLink(we.privateLink()); return file; } } diff --git a/src/com/owncloud/android/lib/resources/files/RemoteFile.java b/src/com/owncloud/android/lib/resources/files/RemoteFile.java index 0c65affb..f2dc7330 100644 --- a/src/com/owncloud/android/lib/resources/files/RemoteFile.java +++ b/src/com/owncloud/android/lib/resources/files/RemoteFile.java @@ -33,146 +33,158 @@ import android.os.Parcelable; import com.owncloud.android.lib.common.network.WebdavEntry; /** - * Contains the data of a Remote File from a WebDavEntry - * - * @author masensio + * Contains the data of a Remote File from a WebDavEntry + * + * @author masensio */ public class RemoteFile implements Parcelable, Serializable { - /** Generated - should be refreshed every time the class changes!! */ - private static final long serialVersionUID = 3130865437811248451L; - - private String mRemotePath; - private String mMimeType; - private long mLength; - private long mCreationTimestamp; - private long mModifiedTimestamp; - private String mEtag; - private String mPermissions; - private String mRemoteId; + /** + * Generated - should be refreshed every time the class changes!! + */ + private static final long serialVersionUID = -8965995357413958539L; + + private String mRemotePath; + private String mMimeType; + private long mLength; + private long mCreationTimestamp; + private long mModifiedTimestamp; + private String mEtag; + private String mPermissions; + private String mRemoteId; private long mSize; private BigDecimal mQuotaUsedBytes; private BigDecimal mQuotaAvailableBytes; + private String mPrivateLink; + + /** + * Getters and Setters + */ - /** - * Getters and Setters - */ - public String getRemotePath() { - return mRemotePath; - } + return mRemotePath; + } - public void setRemotePath(String remotePath) { - this.mRemotePath = remotePath; - } + public void setRemotePath(String remotePath) { + this.mRemotePath = remotePath; + } - public String getMimeType() { - return mMimeType; - } + public String getMimeType() { + return mMimeType; + } - public void setMimeType(String mimeType) { - this.mMimeType = mimeType; - } + public void setMimeType(String mimeType) { + this.mMimeType = mimeType; + } - public long getLength() { - return mLength; - } + public long getLength() { + return mLength; + } - public void setLength(long length) { - this.mLength = length; - } + public void setLength(long length) { + this.mLength = length; + } - public long getCreationTimestamp() { - return mCreationTimestamp; - } + public long getCreationTimestamp() { + return mCreationTimestamp; + } - public void setCreationTimestamp(long creationTimestamp) { - this.mCreationTimestamp = creationTimestamp; - } + public void setCreationTimestamp(long creationTimestamp) { + this.mCreationTimestamp = creationTimestamp; + } - public long getModifiedTimestamp() { - return mModifiedTimestamp; - } + public long getModifiedTimestamp() { + return mModifiedTimestamp; + } - public void setModifiedTimestamp(long modifiedTimestamp) { - this.mModifiedTimestamp = modifiedTimestamp; - } + public void setModifiedTimestamp(long modifiedTimestamp) { + this.mModifiedTimestamp = modifiedTimestamp; + } - public String getEtag() { - return mEtag; - } + public String getEtag() { + return mEtag; + } - public void setEtag(String etag) { - this.mEtag = etag; - } - - public String getPermissions() { - return mPermissions; - } + public void setEtag(String etag) { + this.mEtag = etag; + } - public void setPermissions(String permissions) { - this.mPermissions = permissions; - } + public String getPermissions() { + return mPermissions; + } - public String getRemoteId() { - return mRemoteId; - } + public void setPermissions(String permissions) { + this.mPermissions = permissions; + } - public void setRemoteId(String remoteId) { - this.mRemoteId = remoteId; - } + public String getRemoteId() { + return mRemoteId; + } + + public void setRemoteId(String remoteId) { + this.mRemoteId = remoteId; + } public long getSize() { return mSize; } - public void setSize (long size){ + public void setSize(long size) { mSize = size; } - public void setQuotaUsedBytes (BigDecimal quotaUsedBytes) { + public void setQuotaUsedBytes(BigDecimal quotaUsedBytes) { mQuotaUsedBytes = quotaUsedBytes; } - public void setQuotaAvailableBytes (BigDecimal quotaAvailableBytes) { + public void setQuotaAvailableBytes(BigDecimal quotaAvailableBytes) { mQuotaAvailableBytes = quotaAvailableBytes; } - public RemoteFile() { - resetData(); - } + public String getPrivateLink() { + return mPrivateLink; + } - /** + public void setPrivateLink(String privateLink) { + mPrivateLink = privateLink; + } + + public RemoteFile() { + resetData(); + } + + /** * Create new {@link RemoteFile} with given path. - * + *

* The path received must be URL-decoded. Path separator must be OCFile.PATH_SEPARATOR, and it must be the first character in 'path'. - * + * * @param path The remote path of the file. */ - public RemoteFile(String path) { - resetData(); + public RemoteFile(String path) { + resetData(); if (path == null || path.length() <= 0 || !path.startsWith(FileUtils.PATH_SEPARATOR)) { throw new IllegalArgumentException("Trying to create a OCFile with a non valid remote path: " + path); } mRemotePath = path; - } - - public RemoteFile(WebdavEntry we) { - this(we.decodedPath()); - this.setCreationTimestamp(we.createTimestamp()); - this.setLength(we.contentLength()); - this.setMimeType(we.contentType()); - this.setModifiedTimestamp(we.modifiedTimestamp()); - this.setEtag(we.etag()); - this.setPermissions(we.permissions()); - this.setRemoteId(we.remoteId()); - this.setSize(we.size()); - this.setQuotaUsedBytes(we.quotaUsedBytes()); - this.setQuotaAvailableBytes(we.quotaAvailableBytes()); - } + } - /** + public RemoteFile(WebdavEntry webdavEntry) { + this(webdavEntry.decodedPath()); + this.setCreationTimestamp(webdavEntry.createTimestamp()); + this.setLength(webdavEntry.contentLength()); + this.setMimeType(webdavEntry.contentType()); + this.setModifiedTimestamp(webdavEntry.modifiedTimestamp()); + this.setEtag(webdavEntry.etag()); + this.setPermissions(webdavEntry.permissions()); + this.setRemoteId(webdavEntry.remoteId()); + this.setSize(webdavEntry.size()); + this.setQuotaUsedBytes(webdavEntry.quotaUsedBytes()); + this.setQuotaAvailableBytes(webdavEntry.quotaAvailableBytes()); + this.setPrivateLink(webdavEntry.privateLink()); + } + + /** * Used internally. Reset all file properties */ private void resetData() { @@ -187,9 +199,10 @@ public class RemoteFile implements Parcelable, Serializable { mSize = 0; mQuotaUsedBytes = null; mQuotaAvailableBytes = null; + mPrivateLink = null; } - /** + /** * Parcelable Methods */ public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { @@ -203,49 +216,51 @@ public class RemoteFile implements Parcelable, Serializable { return new RemoteFile[size]; } }; - - + + /** * Reconstruct from parcel - * + * * @param source The source parcel */ protected RemoteFile(Parcel source) { - readFromParcel(source); + readFromParcel(source); } - - public void readFromParcel (Parcel source) { + + public void readFromParcel(Parcel source) { mRemotePath = source.readString(); mMimeType = source.readString(); mLength = source.readLong(); mCreationTimestamp = source.readLong(); mModifiedTimestamp = source.readLong(); mEtag = source.readString(); - mPermissions= source.readString(); + mPermissions = source.readString(); mRemoteId = source.readString(); mSize = source.readLong(); mQuotaUsedBytes = (BigDecimal) source.readSerializable(); mQuotaAvailableBytes = (BigDecimal) source.readSerializable(); + mPrivateLink = source.readString(); } - - @Override - public int describeContents() { - return this.hashCode(); - } - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(mRemotePath); - dest.writeString(mMimeType); - dest.writeLong(mLength); - dest.writeLong(mCreationTimestamp); - dest.writeLong(mModifiedTimestamp); - dest.writeString(mEtag); - dest.writeString(mPermissions); - dest.writeString(mRemoteId); + @Override + public int describeContents() { + return this.hashCode(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(mRemotePath); + dest.writeString(mMimeType); + dest.writeLong(mLength); + dest.writeLong(mCreationTimestamp); + dest.writeLong(mModifiedTimestamp); + dest.writeString(mEtag); + dest.writeString(mPermissions); + dest.writeString(mRemoteId); dest.writeLong(mSize); dest.writeSerializable(mQuotaUsedBytes); dest.writeSerializable(mQuotaAvailableBytes); - } + dest.writeString(mPrivateLink); + } } diff --git a/test_client/AndroidManifest.xml b/test_client/AndroidManifest.xml index d16f156a..1d7ae35e 100644 --- a/test_client/AndroidManifest.xml +++ b/test_client/AndroidManifest.xml @@ -39,7 +39,7 @@ + android:targetSdkVersion="26" />