diff --git a/build.gradle b/build.gradle index 4822d4bd377f..922e75d9115b 100644 --- a/build.gradle +++ b/build.gradle @@ -212,7 +212,7 @@ android { android.applicationVariants.all { variant -> String variantName = variant.name - String capVariantName = variantName.substring(0, 1).toUpperCase() + variantName.substring(1); + String capVariantName = variantName.substring(0, 1).toUpperCase() + variantName.substring(1) tasks.register("spotbugs${capVariantName}", SpotBugsTask) { ignoreFailures = false effort = "max" @@ -273,7 +273,6 @@ dependencies { implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.15' implementation 'com.github.tobiaskaminsky:qrcodescanner:0.1.2.2' // 'com.github.blikoon:QRCodeScanner:0.1.2' implementation 'com.google.android:flexbox:1.1.0' - implementation 'org.parceler:parceler-api:1.1.12' annotationProcessor 'org.parceler:parceler:1.1.12' implementation('com.github.bumptech.glide:glide:3.7.0') { @@ -282,6 +281,19 @@ dependencies { implementation 'com.caverock:androidsvg:1.3' implementation 'androidx.annotation:annotation:1.0.2' implementation 'com.google.code.gson:gson:2.8.5' + implementation 'org.jetbrains:annotations:17.0.0' + + spotbugsPlugins 'com.h3xstream.findsecbugs:findsecbugs-plugin:1.9.0' + spotbugsPlugins 'com.mebigfatguy.fb-contrib:fb-contrib:7.4.3' + + implementation 'com.google.dagger:dagger:2.22.1' + implementation 'com.google.dagger:dagger-android:2.22.1' + implementation 'com.google.dagger:dagger-android-support:2.22.1' + annotationProcessor 'com.google.dagger:dagger-compiler:2.22.1' + annotationProcessor 'com.google.dagger:dagger-android-processor:2.22.1' + + compileOnly "org.projectlombok:lombok:1.18.6" + annotationProcessor "org.projectlombok:lombok:1.18.6" // dependencies for local unit tests testImplementation 'junit:junit:4.12' @@ -302,26 +314,13 @@ dependencies { // Espresso core androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.1.1' + androidTestImplementation 'org.mockito:mockito-core:2.27.0' // UIAutomator - for cross-app UI tests, and to grant screen is turned on in Espresso tests // androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0' // fix conflict in dependencies; see http://g.co/androidstudio/app-test-app-conflict for details //androidTestImplementation "com.android.support:support-annotations:${supportLibraryVersion}" - implementation 'org.jetbrains:annotations:17.0.0' - - compileOnly "org.projectlombok:lombok:1.18.6" - annotationProcessor "org.projectlombok:lombok:1.18.6" - androidTestImplementation 'tools.fastlane:screengrab:1.2.0' - spotbugsPlugins 'com.h3xstream.findsecbugs:findsecbugs-plugin:1.9.0' - spotbugsPlugins 'com.mebigfatguy.fb-contrib:fb-contrib:7.4.3' - - implementation 'com.google.dagger:dagger:2.22.1' - implementation 'com.google.dagger:dagger-android:2.22.1' - implementation 'com.google.dagger:dagger-android-support:2.22.1' - annotationProcessor 'com.google.dagger:dagger-compiler:2.22.1' - annotationProcessor 'com.google.dagger:dagger-android-processor:2.22.1' - // jacocoAnt "org.jacoco:org.jacoco.ant:${jacocoVersion}" // jacocoAgent "org.jacoco:org.jacoco.agent:${jacocoVersion}" // androidJacocoAgent "org.jacoco:org.jacoco.agent:${jacocoVersion}" diff --git a/src/androidTest/java/com/owncloud/android/util/ErrorMessageAdapterIT.java b/src/androidTest/java/com/owncloud/android/util/ErrorMessageAdapterIT.java new file mode 100644 index 000000000000..32867ac4d4a0 --- /dev/null +++ b/src/androidTest/java/com/owncloud/android/util/ErrorMessageAdapterIT.java @@ -0,0 +1,59 @@ +/* + * ownCloud Android client application + * + * @author David A. Velasco + * Copyright (C) 2016 ownCloud Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + + +package com.owncloud.android.util; + +import android.accounts.Account; +import android.content.res.Resources; + +import com.owncloud.android.MainApp; +import com.owncloud.android.lib.common.operations.RemoteOperationResult; +import com.owncloud.android.operations.RemoveFileOperation; +import com.owncloud.android.utils.ErrorMessageAdapter; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; + +import static junit.framework.TestCase.assertEquals; + +@RunWith(AndroidJUnit4.class) +public class ErrorMessageAdapterIT { + private final static String PATH_TO_DELETE = "/path/to/a.file"; + private final static String EXPECTED_ERROR_MESSAGE = "You are not permitted to delete this file"; + private final static String ACCOUNT_TYPE = "nextcloud"; + + @Test + public void getErrorCauseMessageForForbiddenRemoval() { + Resources resources = InstrumentationRegistry.getInstrumentation().getTargetContext().getResources(); + Account account = new Account("name", ACCOUNT_TYPE); + + String errorMessage = ErrorMessageAdapter.getErrorCauseMessage( + new RemoteOperationResult(RemoteOperationResult.ResultCode.FORBIDDEN), + new RemoveFileOperation(PATH_TO_DELETE, false, account, false, MainApp.getAppContext()), + resources + ); + + assertEquals(EXPECTED_ERROR_MESSAGE, errorMessage); + } +} diff --git a/src/test/java/com/owncloud/android/utils/TestSorting.java b/src/androidTest/java/com/owncloud/android/util/TestSorting.java similarity index 99% rename from src/test/java/com/owncloud/android/utils/TestSorting.java rename to src/androidTest/java/com/owncloud/android/util/TestSorting.java index 65fae56fdf17..acee99b89275 100644 --- a/src/test/java/com/owncloud/android/utils/TestSorting.java +++ b/src/androidTest/java/com/owncloud/android/util/TestSorting.java @@ -1,4 +1,4 @@ -package com.owncloud.android.utils; +package com.owncloud.android.util; import com.owncloud.android.datamodel.OCFile; diff --git a/src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java b/src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java index 658040abe4d9..19dd37a173a0 100644 --- a/src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java +++ b/src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java @@ -1091,9 +1091,8 @@ private void hidePassword() { public void onOkClick() { // this check should be unnecessary if (mServerInfo.mVersion == null || - !mServerInfo.mVersion.isVersionValid() || - mServerInfo.mBaseUrl == null || - mServerInfo.mBaseUrl.length() == 0) { + !mServerInfo.mVersion.isVersionValid() || + TextUtils.isEmpty(mServerInfo.mBaseUrl)) { mServerStatusIcon = R.drawable.ic_alert; mServerStatusText = getResources().getString(R.string.auth_wtf_reenter_URL); showServerStatus(); @@ -1898,8 +1897,7 @@ private void doOnResumeAndBound() { mOperationsServiceBinder.dispatchResultIfFinished((int) mWaitingForOpId, this); } - if (!webViewLoginMethod && mHostUrlInput.getText() != null && mHostUrlInput.getText().length() > 0 - && !mServerIsChecked) { + if (!webViewLoginMethod && !TextUtils.isEmpty(mHostUrlInput.getText()) && !mServerIsChecked) { checkOcServer(); } } diff --git a/src/main/java/com/owncloud/android/authentication/AuthenticatorUrlUtils.java b/src/main/java/com/owncloud/android/authentication/AuthenticatorUrlUtils.java index e20b53993d50..dea14c410de2 100644 --- a/src/main/java/com/owncloud/android/authentication/AuthenticatorUrlUtils.java +++ b/src/main/java/com/owncloud/android/authentication/AuthenticatorUrlUtils.java @@ -22,6 +22,7 @@ package com.owncloud.android.authentication; import android.content.Context; +import android.text.TextUtils; import com.owncloud.android.lib.resources.status.OwnCloudVersion; @@ -64,7 +65,7 @@ public static String normalizeUrlSuffix(String url) { public static String normalizeUrl(String url, boolean sslWhenUnprefixed) { String normalizedUrl = url; - if (normalizedUrl != null && normalizedUrl.length() > 0) { + if (!TextUtils.isEmpty(normalizedUrl)) { normalizedUrl = normalizedUrl.trim(); if (!normalizedUrl.toLowerCase(Locale.ROOT).startsWith(HTTP_PROTOCOL) && diff --git a/src/main/java/com/owncloud/android/datamodel/OCFile.java b/src/main/java/com/owncloud/android/datamodel/OCFile.java index 3779f0ef7907..afaf7334b645 100644 --- a/src/main/java/com/owncloud/android/datamodel/OCFile.java +++ b/src/main/java/com/owncloud/android/datamodel/OCFile.java @@ -28,6 +28,8 @@ import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; +import android.text.TextUtils; + import androidx.annotation.NonNull; import androidx.core.content.FileProvider; import com.owncloud.android.R; @@ -115,7 +117,7 @@ public class OCFile implements Parcelable, Comparable, ServerFileInterfa public OCFile(String path) { resetData(); needsUpdatingWhileSaving = false; - if (path == null || path.length() <= 0 || !path.startsWith(PATH_SEPARATOR)) { + if (TextUtils.isEmpty(path) || !path.startsWith(PATH_SEPARATOR)) { throw new IllegalArgumentException("Trying to create a OCFile with a non valid remote path: " + path); } remotePath = path; @@ -262,7 +264,7 @@ public boolean isDown() { * @return true if it is */ public boolean existsOnDevice() { - if (localPath != null && localPath.length() > 0) { + if (!TextUtils.isEmpty(localPath)) { return new File(localPath).exists(); } return false; @@ -283,7 +285,7 @@ public String getStoragePath() { * @return A URI to the local copy of the file, or NULL if not stored in the device */ public Uri getStorageUri() { - if (localPath == null || localPath.length() == 0) { + if (TextUtils.isEmpty(localPath)) { return null; } if (localUri == null) { @@ -297,7 +299,7 @@ public Uri getStorageUri() { public Uri getLegacyExposedFileUri() { - if (localPath == null || localPath.length() == 0) { + if (TextUtils.isEmpty(localPath)) { return null; } @@ -312,7 +314,7 @@ public Uri getLegacyExposedFileUri() { Partly disabled because not all apps understand paths that we get via this method for now */ public Uri getExposedFileUri(Context context) { - if (localPath == null || localPath.length() == 0) { + if (TextUtils.isEmpty(localPath)) { return null; } if (exposedFileUri == null) { @@ -360,8 +362,7 @@ public String getFileName() { */ public void setFileName(String name) { Log_OC.d(TAG, "OCFile name changing from " + remotePath); - if (name != null && name.length() > 0 && !name.contains(PATH_SEPARATOR) && - !ROOT_PATH.equals(remotePath)) { + if (!TextUtils.isEmpty(name) && !name.contains(PATH_SEPARATOR) && !ROOT_PATH.equals(remotePath)) { String parent = new File(this.getRemotePath()).getParent(); parent = parent.endsWith(PATH_SEPARATOR) ? parent : parent + PATH_SEPARATOR; remotePath = parent + name; @@ -468,7 +469,7 @@ public void setEtagOnServer(String etag) { } public long getLocalModificationTimestamp() { - if (localPath != null && localPath.length() > 0) { + if (!TextUtils.isEmpty(localPath)) { File f = new File(localPath); return f.lastModified(); } @@ -479,7 +480,7 @@ public long getLocalModificationTimestamp() { * @return 'True' if the file is hidden */ public boolean isHidden() { - return getFileName().length() > 0 && getFileName().charAt(0) == '.'; + return !TextUtils.isEmpty(getFileName()) && getFileName().charAt(0) == '.'; } /** @@ -492,7 +493,7 @@ public String getLocalId() { } public boolean isInConflict() { - return etagInConflict != null && !"".equals(etagInConflict); + return !TextUtils.isEmpty(etagInConflict); } public boolean isSharedWithMe() { diff --git a/src/main/java/com/owncloud/android/operations/DetectAuthenticationMethodOperation.java b/src/main/java/com/owncloud/android/operations/DetectAuthenticationMethodOperation.java index 165f4189eec3..f20efbb5580a 100644 --- a/src/main/java/com/owncloud/android/operations/DetectAuthenticationMethodOperation.java +++ b/src/main/java/com/owncloud/android/operations/DetectAuthenticationMethodOperation.java @@ -22,6 +22,7 @@ import android.content.Context; import android.net.Uri; +import android.text.TextUtils; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.operations.RemoteOperation; @@ -89,8 +90,7 @@ protected RemoteOperationResult run(OwnCloudClient client) { // try to access the root folder, following redirections but not SAML SSO redirections result = operation.execute(client); String redirectedLocation = result.getRedirectedLocation(); - while (redirectedLocation != null && redirectedLocation.length() > 0 && - !result.isIdPRedirection()) { + while (!TextUtils.isEmpty(redirectedLocation) && !result.isIdPRedirection()) { client.setBaseUri(Uri.parse(result.getRedirectedLocation())); result = operation.execute(client); redirectedLocation = result.getRedirectedLocation(); diff --git a/src/main/java/com/owncloud/android/operations/DownloadFileOperation.java b/src/main/java/com/owncloud/android/operations/DownloadFileOperation.java index 6842c2f8053b..73c9e5a3fe22 100644 --- a/src/main/java/com/owncloud/android/operations/DownloadFileOperation.java +++ b/src/main/java/com/owncloud/android/operations/DownloadFileOperation.java @@ -23,6 +23,7 @@ import android.accounts.Account; import android.content.Context; +import android.text.TextUtils; import android.webkit.MimeTypeMap; import com.owncloud.android.datamodel.DecryptedFolderMetadata; @@ -110,7 +111,7 @@ public String getRemotePath() { public String getMimeType() { String mimeType = file.getMimeType(); - if (mimeType == null || mimeType.length() <= 0) { + if (TextUtils.isEmpty(mimeType)) { try { mimeType = MimeTypeMap.getSingleton() .getMimeTypeFromExtension( diff --git a/src/main/java/com/owncloud/android/operations/RenameFileOperation.java b/src/main/java/com/owncloud/android/operations/RenameFileOperation.java index fa8b86e04c3a..cde479ad3cd7 100644 --- a/src/main/java/com/owncloud/android/operations/RenameFileOperation.java +++ b/src/main/java/com/owncloud/android/operations/RenameFileOperation.java @@ -21,6 +21,8 @@ package com.owncloud.android.operations; +import android.text.TextUtils; + import com.owncloud.android.datamodel.FileDataStorageManager; import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.lib.common.OwnCloudClient; @@ -157,7 +159,7 @@ private void saveLocalFile() { */ private boolean isValidNewName() throws IOException { // check tricky names - if (newName == null || newName.length() <= 0 || newName.contains(File.separator)) { + if (TextUtils.isEmpty(newName) || newName.contains(File.separator)) { return false; } // create a test file diff --git a/src/main/java/com/owncloud/android/operations/SynchronizeFileOperation.java b/src/main/java/com/owncloud/android/operations/SynchronizeFileOperation.java index 7b0b5041dee7..72e4a1ecbe61 100644 --- a/src/main/java/com/owncloud/android/operations/SynchronizeFileOperation.java +++ b/src/main/java/com/owncloud/android/operations/SynchronizeFileOperation.java @@ -24,6 +24,7 @@ import android.accounts.Account; import android.content.Context; import android.content.Intent; +import android.text.TextUtils; import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.files.services.FileDownloader; @@ -204,7 +205,7 @@ protected RemoteOperationResult run(OwnCloudClient client) { if (mServerFile != null) { /// check changes in server and local file boolean serverChanged; - if (mLocalFile.getEtag() == null || mLocalFile.getEtag().length() == 0) { + if (TextUtils.isEmpty(mLocalFile.getEtag())) { // file uploaded (null) or downloaded ("") before upgrade to version 1.8.0; check the old condition serverChanged = mServerFile.getModificationTimestamp() != mLocalFile.getModificationTimestampAtLastSyncForData(); diff --git a/src/main/java/com/owncloud/android/operations/SynchronizeFolderOperation.java b/src/main/java/com/owncloud/android/operations/SynchronizeFolderOperation.java index 32cf1605873c..e9751fbc6f49 100644 --- a/src/main/java/com/owncloud/android/operations/SynchronizeFolderOperation.java +++ b/src/main/java/com/owncloud/android/operations/SynchronizeFolderOperation.java @@ -23,6 +23,7 @@ import android.accounts.Account; import android.content.Context; import android.content.Intent; +import android.text.TextUtils; import android.util.Log; import com.owncloud.android.datamodel.FileDataStorageManager; @@ -482,7 +483,7 @@ public void cancel() { public String getFolderPath() { String path = mLocalFolder.getStoragePath(); - if (path != null && path.length() > 0) { + if (!TextUtils.isEmpty(path)) { return path; } return FileStorageUtils.getDefaultSavePathFor(mAccount.name, mLocalFolder); diff --git a/src/main/java/com/owncloud/android/operations/UploadFileOperation.java b/src/main/java/com/owncloud/android/operations/UploadFileOperation.java index 74b509a867b5..579a9185dc3c 100644 --- a/src/main/java/com/owncloud/android/operations/UploadFileOperation.java +++ b/src/main/java/com/owncloud/android/operations/UploadFileOperation.java @@ -27,6 +27,7 @@ import android.content.Context; import android.net.Uri; import android.os.Build; +import android.text.TextUtils; import android.util.Log; import com.evernote.android.job.JobRequest; @@ -153,7 +154,7 @@ public class UploadFileOperation extends SyncOperation { public static OCFile obtainNewOCFileToUpload(String remotePath, String localPath, String mimeType) { // MIME type - if (mimeType == null || mimeType.length() <= 0) { + if (TextUtils.isEmpty(mimeType)) { mimeType = MimeTypeUtil.getBestMimeTypeByFilename(localPath); } @@ -163,7 +164,7 @@ public static OCFile obtainNewOCFileToUpload(String remotePath, String localPath newFile.setLastSyncDateForData(0); // size - if (localPath != null && localPath.length() > 0) { + if (!TextUtils.isEmpty(localPath)) { File localFile = new File(localPath); newFile.setFileLength(localFile.length()); newFile.setLastSyncDateForData(localFile.lastModified()); @@ -192,7 +193,7 @@ public UploadFileOperation(UploadsStorageManager uploadsStorageManager, if (upload == null) { throw new IllegalArgumentException("Illegal NULL file in UploadFileOperation creation"); } - if (upload.getLocalPath() == null || upload.getLocalPath().length() <= 0) { + if (TextUtils.isEmpty(upload.getLocalPath())) { throw new IllegalArgumentException( "Illegal file in UploadFileOperation; storage path invalid: " + upload.getLocalPath()); diff --git a/src/main/java/com/owncloud/android/services/OperationsService.java b/src/main/java/com/owncloud/android/services/OperationsService.java index dcaf56af8345..118b6c109bee 100644 --- a/src/main/java/com/owncloud/android/services/OperationsService.java +++ b/src/main/java/com/owncloud/android/services/OperationsService.java @@ -36,6 +36,7 @@ import android.os.Looper; import android.os.Message; import android.os.Process; +import android.text.TextUtils; import android.util.Pair; import com.owncloud.android.MainApp; @@ -455,8 +456,7 @@ private void nextOperation() { ); } else { OwnCloudCredentials credentials = null; - if (mLastTarget.mCookie != null && - mLastTarget.mCookie.length() > 0) { + if (!TextUtils.isEmpty(mLastTarget.mCookie)) { // just used for GetUserName // TODO refactor to run GetUserName as AsyncTask in the context of // AuthenticatorActivity @@ -558,7 +558,7 @@ private Pair newOperation(Intent operationIntent) { case ACTION_CREATE_SHARE_VIA_LINK: remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH); password = operationIntent.getStringExtra(EXTRA_SHARE_PASSWORD); - if (remotePath.length() > 0) { + if (!TextUtils.isEmpty(remotePath)) { operation = new CreateShareViaLinkOperation(remotePath, password); } break; @@ -567,7 +567,7 @@ private Pair newOperation(Intent operationIntent) { remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH); shareId = operationIntent.getLongExtra(EXTRA_SHARE_ID, -1); - if (remotePath != null && remotePath.length() > 0) { + if (!TextUtils.isEmpty(remotePath)) { UpdateShareViaLinkOperation updateLinkOperation = new UpdateShareViaLinkOperation(remotePath); password = operationIntent.getStringExtra(EXTRA_SHARE_PASSWORD); @@ -616,7 +616,7 @@ private Pair newOperation(Intent operationIntent) { String shareeName = operationIntent.getStringExtra(EXTRA_SHARE_WITH); shareType = (ShareType) operationIntent.getSerializableExtra(EXTRA_SHARE_TYPE); int permissions = operationIntent.getIntExtra(EXTRA_SHARE_PERMISSIONS, -1); - if (remotePath.length() > 0) { + if (!TextUtils.isEmpty(remotePath)) { operation = new CreateShareWithShareeOperation(remotePath, shareeName, shareType, permissions); } @@ -627,7 +627,7 @@ private Pair newOperation(Intent operationIntent) { shareType = (ShareType) operationIntent.getSerializableExtra(EXTRA_SHARE_TYPE); String shareWith = operationIntent.getStringExtra(EXTRA_SHARE_WITH); - if (remotePath.length() > 0) { + if (!TextUtils.isEmpty(remotePath)) { operation = new UnshareOperation(remotePath, shareType, shareWith, this); } break; diff --git a/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java b/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java index 6ad33c85cce5..01d3cbdfb2d9 100644 --- a/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java +++ b/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java @@ -1989,7 +1989,7 @@ private void onCreateShareViaLinkOperationFinish(CreateShareViaLinkOperation ope // Detect Failure (403) --> maybe needs password String password = operation.getPassword(); if (result.getCode() == RemoteOperationResult.ResultCode.SHARE_FORBIDDEN && - (password == null || password.length() == 0) && + TextUtils.isEmpty(password) && getCapabilities().getFilesSharingPublicEnabled().isUnknown()) { // Was tried without password, but not sure that it's optional. diff --git a/src/main/java/com/owncloud/android/ui/activity/PassCodeActivity.java b/src/main/java/com/owncloud/android/ui/activity/PassCodeActivity.java index 5d50058e4255..60063d52fee9 100644 --- a/src/main/java/com/owncloud/android/ui/activity/PassCodeActivity.java +++ b/src/main/java/com/owncloud/android/ui/activity/PassCodeActivity.java @@ -26,6 +26,7 @@ import android.graphics.PorterDuff; import android.os.Bundle; import android.text.Editable; +import android.text.TextUtils; import android.text.TextWatcher; import android.view.KeyEvent; import android.view.View; @@ -204,7 +205,7 @@ protected void setTextListeners() { private void onPassCodeEditTextFocusChange(final int passCodeIndex) { for (int i = 0; i < passCodeIndex; i++) { - if ("".equals(mPassCodeEditTexts[i].getText().toString())) { + if (TextUtils.isEmpty(mPassCodeEditTexts[i].getText())) { mPassCodeEditTexts[i].requestFocus(); break; } diff --git a/src/main/java/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java b/src/main/java/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java index 683426418b61..9b86cb0fca43 100755 --- a/src/main/java/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java +++ b/src/main/java/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java @@ -43,6 +43,7 @@ import android.os.Handler; import android.os.Looper; import android.os.Parcelable; +import android.text.TextUtils; import android.text.format.DateFormat; import android.view.LayoutInflater; import android.view.Menu; @@ -750,7 +751,7 @@ private void populateDirectoryList() { boolean notRoot = mParents.size() > 1; if (actionBar != null) { - if ("".equals(current_dir)) { + if (TextUtils.isEmpty(current_dir)) { ThemeUtils.setColoredTitle(actionBar, R.string.uploader_top_message, this); } else { ThemeUtils.setColoredTitle(actionBar, current_dir, this); diff --git a/src/main/java/com/owncloud/android/ui/activity/ShareActivity.java b/src/main/java/com/owncloud/android/ui/activity/ShareActivity.java index edfd9373cf27..ee8f04b41fb5 100644 --- a/src/main/java/com/owncloud/android/ui/activity/ShareActivity.java +++ b/src/main/java/com/owncloud/android/ui/activity/ShareActivity.java @@ -25,6 +25,7 @@ import android.content.Intent; import android.net.Uri; import android.os.Bundle; +import android.text.TextUtils; import com.google.android.material.snackbar.Snackbar; import com.owncloud.android.R; @@ -348,7 +349,7 @@ private void onCreateShareViaLinkOperationFinish(CreateShareViaLinkOperation ope // Detect Failure (403) --> maybe needs password String password = operation.getPassword(); if (result.getCode() == RemoteOperationResult.ResultCode.SHARE_FORBIDDEN && - (password == null || password.length() == 0) && + TextUtils.isEmpty(password) && getCapabilities().getFilesSharingPublicEnabled().isUnknown()) { // Was tried without password, but not sure that it's optional. diff --git a/src/main/java/com/owncloud/android/ui/dialog/CreateFolderDialogFragment.java b/src/main/java/com/owncloud/android/ui/dialog/CreateFolderDialogFragment.java index 8963fedcfdc6..1f7dc2feb9ab 100644 --- a/src/main/java/com/owncloud/android/ui/dialog/CreateFolderDialogFragment.java +++ b/src/main/java/com/owncloud/android/ui/dialog/CreateFolderDialogFragment.java @@ -24,6 +24,7 @@ import android.content.DialogInterface; import android.graphics.PorterDuff; import android.os.Bundle; +import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.Window; @@ -124,7 +125,7 @@ public void onClick(DialogInterface dialog, int which) { ((TextView)(getDialog().findViewById(R.id.user_input))) .getText().toString().trim(); - if (newFolderName.length() <= 0) { + if (TextUtils.isEmpty(newFolderName)) { DisplayUtils.showSnackMessage(getActivity(), R.string.filename_empty); return; } diff --git a/src/main/java/com/owncloud/android/ui/dialog/RenameFileDialogFragment.java b/src/main/java/com/owncloud/android/ui/dialog/RenameFileDialogFragment.java index 9909a5f1263a..0957d13ba5b0 100644 --- a/src/main/java/com/owncloud/android/ui/dialog/RenameFileDialogFragment.java +++ b/src/main/java/com/owncloud/android/ui/dialog/RenameFileDialogFragment.java @@ -30,6 +30,7 @@ import android.content.DialogInterface; import android.graphics.PorterDuff; import android.os.Bundle; +import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.Window; @@ -139,7 +140,7 @@ public void onClick(DialogInterface dialog, int which) { ((TextView)(getDialog().findViewById(R.id.user_input))) .getText().toString().trim(); - if (newFileName.length() <= 0) { + if (TextUtils.isEmpty(newFileName)) { DisplayUtils.showSnackMessage(getActivity(), R.string.filename_empty); return; } diff --git a/src/main/java/com/owncloud/android/ui/dialog/SharePasswordDialogFragment.java b/src/main/java/com/owncloud/android/ui/dialog/SharePasswordDialogFragment.java index 535a70f2bf40..cb8b76e174e7 100644 --- a/src/main/java/com/owncloud/android/ui/dialog/SharePasswordDialogFragment.java +++ b/src/main/java/com/owncloud/android/ui/dialog/SharePasswordDialogFragment.java @@ -24,6 +24,7 @@ import android.content.DialogInterface; import android.graphics.PorterDuff; import android.os.Bundle; +import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -152,7 +153,7 @@ public void onClick(DialogInterface dialog, int which) { if (which == AlertDialog.BUTTON_POSITIVE) { String password = ((TextView) (getDialog().findViewById(R.id.share_password))).getText().toString(); - if (password.length() <= 0) { + if (TextUtils.isEmpty(password)) { DisplayUtils.showSnackMessage( getActivity().findViewById(android.R.id.content), R.string.share_link_empty_password diff --git a/src/main/java/com/owncloud/android/ui/dialog/SyncedFolderPreferencesDialogFragment.java b/src/main/java/com/owncloud/android/ui/dialog/SyncedFolderPreferencesDialogFragment.java index abd2132dca28..b590d60e8214 100644 --- a/src/main/java/com/owncloud/android/ui/dialog/SyncedFolderPreferencesDialogFragment.java +++ b/src/main/java/com/owncloud/android/ui/dialog/SyncedFolderPreferencesDialogFragment.java @@ -27,6 +27,7 @@ import android.graphics.Typeface; import android.os.Build; import android.os.Bundle; +import android.text.TextUtils; import android.text.style.StyleSpan; import android.view.LayoutInflater; import android.view.View; @@ -203,7 +204,7 @@ private void setupDialogElements(View view) { // Set values setEnabled(mSyncedFolder.getEnabled()); - if (mSyncedFolder.getLocalPath() != null && mSyncedFolder.getLocalPath().length() > 0) { + if (!TextUtils.isEmpty(mSyncedFolder.getLocalPath())) { mLocalFolderPath.setText( DisplayUtils.createTextWithSpan( String.format( @@ -216,7 +217,7 @@ private void setupDialogElements(View view) { mLocalFolderSummary.setText(R.string.choose_local_folder); } - if (mSyncedFolder.getLocalPath() != null && mSyncedFolder.getLocalPath().length() > 0) { + if (!TextUtils.isEmpty(mSyncedFolder.getLocalPath())) { mRemoteFolderSummary.setText(mSyncedFolder.getRemotePath()); } else { mRemoteFolderSummary.setText(R.string.choose_remote_folder); diff --git a/src/main/java/com/owncloud/android/ui/helpers/FileOperationsHelper.java b/src/main/java/com/owncloud/android/ui/helpers/FileOperationsHelper.java index 806aaf23dea1..789cf4a98227 100755 --- a/src/main/java/com/owncloud/android/ui/helpers/FileOperationsHelper.java +++ b/src/main/java/com/owncloud/android/ui/helpers/FileOperationsHelper.java @@ -39,6 +39,7 @@ import android.os.Build; import android.os.Environment; import android.provider.MediaStore; +import android.text.TextUtils; import android.util.Log; import android.view.View; import android.webkit.MimeTypeMap; @@ -431,7 +432,7 @@ public void shareFileViaLink(OCFile file, String password) { Intent service = new Intent(mFileActivity, OperationsService.class); service.setAction(OperationsService.ACTION_CREATE_SHARE_VIA_LINK); service.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount()); - if (password != null && password.length() > 0) { + if (!TextUtils.isEmpty(password)) { service.putExtra(OperationsService.EXTRA_SHARE_PASSWORD, password); } service.putExtra(OperationsService.EXTRA_REMOTE_PATH, file.getRemotePath()); diff --git a/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.java b/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.java index 308d37eb7ac0..5b729de7db66 100644 --- a/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.java +++ b/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.java @@ -32,6 +32,7 @@ import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; +import android.text.TextUtils; import android.view.MenuItem; import android.view.View; @@ -222,7 +223,7 @@ public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationRe // Detect Failure (403) --> maybe needs password String password = op.getPassword(); if (result.getCode() == RemoteOperationResult.ResultCode.SHARE_FORBIDDEN && - (password == null || password.length() == 0) && + TextUtils.isEmpty(password) && getCapabilities().getFilesSharingPublicEnabled().isUnknown()) { // Was tried without password, but not sure that it's optional. diff --git a/src/main/java/com/owncloud/android/utils/ClipboardUtil.java b/src/main/java/com/owncloud/android/utils/ClipboardUtil.java index ac697da6d003..8c6f62756773 100644 --- a/src/main/java/com/owncloud/android/utils/ClipboardUtil.java +++ b/src/main/java/com/owncloud/android/utils/ClipboardUtil.java @@ -24,6 +24,7 @@ import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; +import android.text.TextUtils; import android.widget.Toast; import com.owncloud.android.R; @@ -43,7 +44,7 @@ public static void copyToClipboard(Activity activity, String text) { } public static void copyToClipboard(Activity activity, String text, boolean showToast) { - if (text != null && text.length() > 0) { + if (!TextUtils.isEmpty(text)) { try { ClipData clip = ClipData.newPlainText( activity.getString( diff --git a/src/main/java/com/owncloud/android/utils/ErrorMessageAdapter.java b/src/main/java/com/owncloud/android/utils/ErrorMessageAdapter.java index fc4125345ff1..30a74bbb8656 100644 --- a/src/main/java/com/owncloud/android/utils/ErrorMessageAdapter.java +++ b/src/main/java/com/owncloud/android/utils/ErrorMessageAdapter.java @@ -22,6 +22,7 @@ package com.owncloud.android.utils; import android.content.res.Resources; +import android.text.TextUtils; import com.owncloud.android.R; import com.owncloud.android.lib.common.operations.RemoteOperation; @@ -77,11 +78,11 @@ public static String getErrorCauseMessage( ) { String message = getSpecificMessageForResultAndOperation(result, operation, res); - if (message == null || message.length() <= 0) { + if (TextUtils.isEmpty(message)) { message = getCommonMessageForResult(result, res); } - if (message == null || message.length() <= 0) { + if (TextUtils.isEmpty(message)) { message = getGenericErrorMessageForOperation(operation, res); } @@ -434,7 +435,7 @@ private static String getCommonMessageForResult(RemoteOperationResult result, Re } - else if (result.getHttpPhrase() != null && result.getHttpPhrase().length() > 0) { + else if (!TextUtils.isEmpty(result.getHttpPhrase())) { // last chance: error message from server message = result.getHttpPhrase(); } diff --git a/src/test/java/com/owncloud/android/utils/ErrorMessageAdapterUnitTest.java b/src/test/java/com/owncloud/android/utils/ErrorMessageAdapterUnitTest.java deleted file mode 100644 index 1a9b171f79c9..000000000000 --- a/src/test/java/com/owncloud/android/utils/ErrorMessageAdapterUnitTest.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * ownCloud Android client application - * - * @author David A. Velasco - * Copyright (C) 2016 ownCloud Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, - * as published by the Free Software Foundation. - * - * 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - - -package com.owncloud.android.utils; - -import android.accounts.Account; -import android.content.res.Resources; - -import com.owncloud.android.MainApp; -import com.owncloud.android.R; -import com.owncloud.android.lib.common.operations.RemoteOperationResult; -import com.owncloud.android.operations.RemoveFileOperation; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.mockito.Mockito.when; - -/** - * Local unit test, to be run out of Android emulator or device. - * - * At the moment, it's a sample to validate the automatic test environment, in the scope of local unit tests with - * mock Android dependencies. - * - * Don't take it as an example of completeness. - * - * See http://developer.android.com/intl/es/training/testing/unit-testing/local-unit-tests.html . - */ -@RunWith(MockitoJUnitRunner.class) -public class ErrorMessageAdapterUnitTest { - - private final static String MOCK_FORBIDDEN_PERMISSIONS = "You do not have permission %s"; - private final static String MOCK_TO_DELETE = "to delete this file"; - private final static String PATH_TO_DELETE = "/path/to/a.file"; - private final static String EXPECTED_ERROR_MESSAGE = "You do not have permission to delete this file"; - private final static String ACCOUNT_TYPE = "nextcloud"; - - @Mock - private Resources mMockResources; - - @Test - public void getErrorCauseMessageForForbiddenRemoval() { - // Given a mocked set of resources passed to the object under test... - when(mMockResources.getString(R.string.forbidden_permissions)) - .thenReturn(MOCK_FORBIDDEN_PERMISSIONS); - when(mMockResources.getString(R.string.forbidden_permissions_delete)) - .thenReturn(MOCK_TO_DELETE); - - Account account = new Account("name", ACCOUNT_TYPE); - - // ... when method under test is called ... - String errorMessage = ErrorMessageAdapter.getErrorCauseMessage( - new RemoteOperationResult(RemoteOperationResult.ResultCode.FORBIDDEN), - new RemoveFileOperation(PATH_TO_DELETE, false, account, false, MainApp.getAppContext()), - mMockResources - ); - - // ... then the result should be the expected one. - assertThat(errorMessage, is(EXPECTED_ERROR_MESSAGE)); - - } -}