diff --git a/build.gradle b/build.gradle
index b122155c88cf..527aac2327ba 100644
--- a/build.gradle
+++ b/build.gradle
@@ -184,7 +184,7 @@ dependencies {
/// dependencies for app building
implementation name: 'touch-image-view'
implementation 'com.android.support:multidex:1.0.2'
- implementation 'com.github.nextcloud:android-library:1.0.26'
+ implementation 'com.github.nextcloud:android-library:1.0.28'
implementation "com.android.support:support-v4:${supportLibraryVersion}"
implementation "com.android.support:design:${supportLibraryVersion}"
implementation 'com.jakewharton:disklrucache:2.0.2'
diff --git a/scripts/lint/lint-results.txt b/scripts/lint/lint-results.txt
index d551712f07d4..00f8637331de 100644
--- a/scripts/lint/lint-results.txt
+++ b/scripts/lint/lint-results.txt
@@ -1,2 +1,2 @@
DO NOT TOUCH; GENERATED BY DRONE
- Lint Report: 1 error and 515 warnings
+ Lint Report: 1 error and 512 warnings
diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml
index f0a4268f62f4..5bb0ab5df2ce 100644
--- a/src/main/AndroidManifest.xml
+++ b/src/main/AndroidManifest.xml
@@ -235,6 +235,9 @@
+
+
+
diff --git a/src/main/java/com/owncloud/android/MainApp.java b/src/main/java/com/owncloud/android/MainApp.java
index 0f4ac2720d3f..d429b17dbe00 100644
--- a/src/main/java/com/owncloud/android/MainApp.java
+++ b/src/main/java/com/owncloud/android/MainApp.java
@@ -125,26 +125,7 @@ public void onCreate() {
Log_OC.d("Debug", "start logging");
}
- updateToAutoUpload();
- cleanOldEntries();
- updateAutoUploadEntries();
-
- if (PermissionUtil.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
- splitOutAutoUploadEntries();
- } else {
- PreferenceManager.setAutoUploadSplitEntries(this, true);
- }
-
- initiateExistingAutoUploadEntries();
-
- FilesSyncHelper.scheduleFilesSyncIfNeeded();
- FilesSyncHelper.restartJobsIfNeeded();
-
- ReceiversHelper.registerNetworkChangeReceiver();
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
- ReceiversHelper.registerPowerChangeReceiver();
- }
+ initAutoUpload();
// register global protection with pass code
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
@@ -190,6 +171,31 @@ public void onActivityDestroyed(Activity activity) {
});
}
+ public static void initAutoUpload() {
+ updateToAutoUpload();
+ cleanOldEntries();
+ updateAutoUploadEntries();
+
+ if (getAppContext() != null) {
+ if (PermissionUtil.checkSelfPermission(getAppContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
+ splitOutAutoUploadEntries();
+ } else {
+ PreferenceManager.setAutoUploadSplitEntries(getAppContext(), true);
+ }
+ }
+
+ initiateExistingAutoUploadEntries();
+
+ FilesSyncHelper.scheduleFilesSyncIfNeeded();
+ FilesSyncHelper.restartJobsIfNeeded();
+
+ ReceiversHelper.registerNetworkChangeReceiver();
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+ ReceiversHelper.registerPowerChangeReceiver();
+ }
+ }
+
public static Context getAppContext() {
return MainApp.mContext;
}
@@ -301,12 +307,13 @@ public static String getUserAgent() {
return userAgent;
}
- private void updateToAutoUpload() {
- if (PreferenceManager.instantPictureUploadEnabled(this) ||
- PreferenceManager.instantPictureUploadEnabled(this)) {
+ private static void updateToAutoUpload() {
+ Context context = getAppContext();
+ if (PreferenceManager.instantPictureUploadEnabled(context) ||
+ PreferenceManager.instantPictureUploadEnabled(context)) {
// remove legacy shared preferences
- SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(this).edit();
+ SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(context).edit();
editor.remove("instant_uploading")
.remove("instant_video_uploading")
.remove("instant_upload_path")
@@ -322,16 +329,16 @@ private void updateToAutoUpload() {
// show info pop-up
try {
- new AlertDialog.Builder(this, R.style.Theme_ownCloud_Dialog)
+ new AlertDialog.Builder(context, R.style.Theme_ownCloud_Dialog)
.setTitle(R.string.drawer_synced_folders)
.setMessage(R.string.synced_folders_new_info)
.setPositiveButton(R.string.drawer_open, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// show Auto Upload
- Intent folderSyncIntent = new Intent(getApplicationContext(),
+ Intent folderSyncIntent = new Intent(context,
SyncedFoldersActivity.class);
dialog.dismiss();
- startActivity(folderSyncIntent);
+ context.startActivity(folderSyncIntent);
}
})
.setNegativeButton(R.string.drawer_close, new DialogInterface.OnClickListener() {
@@ -347,21 +354,23 @@ public void onClick(DialogInterface dialog, int which) {
}
}
- private void updateAutoUploadEntries() {
+ private static void updateAutoUploadEntries() {
// updates entries to reflect their true paths
- if (!PreferenceManager.getAutoUploadPathsUpdate(this)) {
+ Context context = getAppContext();
+ if (!PreferenceManager.getAutoUploadPathsUpdate(context)) {
SyncedFolderProvider syncedFolderProvider =
new SyncedFolderProvider(MainApp.getAppContext().getContentResolver());
syncedFolderProvider.updateAutoUploadPaths(mContext);
}
}
- private void splitOutAutoUploadEntries() {
- if (!PreferenceManager.getAutoUploadSplitEntries(this)) {
+ private static void splitOutAutoUploadEntries() {
+ Context context = getAppContext();
+ if (!PreferenceManager.getAutoUploadSplitEntries(context)) {
// magic to split out existing synced folders in two when needed
// otherwise, we migrate them to their proper type (image or video)
Log_OC.i(TAG, "Migrate synced_folders records for image/video split");
- ContentResolver contentResolver = this.getContentResolver();
+ ContentResolver contentResolver = context.getContentResolver();
SyncedFolderProvider syncedFolderProvider = new SyncedFolderProvider(contentResolver);
@@ -405,11 +414,11 @@ private void splitOutAutoUploadEntries() {
syncedFolderProvider.deleteSyncedFolder(id);
}
- PreferenceManager.setAutoUploadSplitEntries(this, true);
+ PreferenceManager.setAutoUploadSplitEntries(context, true);
}
}
- private void initiateExistingAutoUploadEntries() {
+ private static void initiateExistingAutoUploadEntries() {
new Thread(() -> {
if (!PreferenceManager.getAutoUploadInit(getAppContext())) {
SyncedFolderProvider syncedFolderProvider =
@@ -427,13 +436,15 @@ private void initiateExistingAutoUploadEntries() {
}).start();
}
- private void cleanOldEntries() {
+ private static void cleanOldEntries() {
// previous versions of application created broken entries in the SyncedFolderProvider
// database, and this cleans all that and leaves 1 (newest) entry per synced folder
- if (!PreferenceManager.getLegacyClean(this)) {
+ Context context = getAppContext();
+
+ if (!PreferenceManager.getLegacyClean(context)) {
SyncedFolderProvider syncedFolderProvider =
- new SyncedFolderProvider(MainApp.getAppContext().getContentResolver());
+ new SyncedFolderProvider(context.getContentResolver());
List syncedFolderList = syncedFolderProvider.getSyncedFolders();
Map, Long> syncedFolders = new HashMap<>();
@@ -454,7 +465,7 @@ private void cleanOldEntries() {
if (ids.size() > 0) {
syncedFolderProvider.deleteSyncedFoldersNotInList(mContext, ids);
} else {
- PreferenceManager.setLegacyClean(this, true);
+ PreferenceManager.setLegacyClean(context, true);
}
}
}
diff --git a/src/main/java/com/owncloud/android/datamodel/UploadsStorageManager.java b/src/main/java/com/owncloud/android/datamodel/UploadsStorageManager.java
index 9c9ebb6a37a6..9d139771be04 100644
--- a/src/main/java/com/owncloud/android/datamodel/UploadsStorageManager.java
+++ b/src/main/java/com/owncloud/android/datamodel/UploadsStorageManager.java
@@ -154,6 +154,7 @@ public int updateUpload(OCUpload ocUpload) {
cv.put(ProviderTableMeta.UPLOADS_STATUS, ocUpload.getUploadStatus().value);
cv.put(ProviderTableMeta.UPLOADS_LAST_RESULT, ocUpload.getLastResult().getValue());
cv.put(ProviderTableMeta.UPLOADS_UPLOAD_END_TIMESTAMP, ocUpload.getUploadEndTimestamp());
+ cv.put(ProviderTableMeta.UPLOADS_FILE_SIZE, ocUpload.getFileSize());
int result = getDB().update(ProviderTableMeta.CONTENT_URI_UPLOADS,
cv,
diff --git a/src/main/java/com/owncloud/android/files/BootupBroadcastReceiver.java b/src/main/java/com/owncloud/android/files/BootupBroadcastReceiver.java
index 76d499b69135..ac4be345e938 100644
--- a/src/main/java/com/owncloud/android/files/BootupBroadcastReceiver.java
+++ b/src/main/java/com/owncloud/android/files/BootupBroadcastReceiver.java
@@ -4,6 +4,7 @@
* @author David A. Velasco
* Copyright (C) 2012 Bartek Przybylski
* Copyright (C) 2015 ownCloud Inc.
+ * Copyright (C) 2017 Mario Danic
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
@@ -24,6 +25,7 @@
import android.content.Context;
import android.content.Intent;
+import com.owncloud.android.MainApp;
import com.owncloud.android.lib.common.utils.Log_OC;
import com.owncloud.android.services.observer.FileObserverService;
@@ -46,13 +48,11 @@ public class BootupBroadcastReceiver extends BroadcastReceiver {
*/
@Override
public void onReceive(Context context, Intent intent) {
- if (!intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
- Log_OC.e(TAG, "Incorrect action sent " + intent.getAction());
- return;
- }
Log_OC.d(TAG, "Starting file observer service...");
Intent initObservers = FileObserverService.makeInitIntent(context);
context.startService(initObservers);
+
+ MainApp.initAutoUpload();
}
}
diff --git a/src/main/java/com/owncloud/android/files/services/FileDownloader.java b/src/main/java/com/owncloud/android/files/services/FileDownloader.java
index a44cc4be49b8..5cd2bc550f1a 100644
--- a/src/main/java/com/owncloud/android/files/services/FileDownloader.java
+++ b/src/main/java/com/owncloud/android/files/services/FileDownloader.java
@@ -28,6 +28,7 @@
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
+import android.graphics.BitmapFactory;
import android.os.Binder;
import android.os.Handler;
import android.os.HandlerThread;
@@ -59,6 +60,7 @@
import com.owncloud.android.ui.preview.PreviewImageActivity;
import com.owncloud.android.ui.preview.PreviewImageFragment;
import com.owncloud.android.utils.ErrorMessageAdapter;
+import com.owncloud.android.utils.ThemeUtils;
import java.io.File;
import java.util.AbstractList;
@@ -127,6 +129,10 @@ public void onCreate() {
mNotification = new NotificationCompat.Builder(this).setContentTitle(getApplicationContext().
getResources().getString(R.string.app_name))
+ .setContentText(getApplicationContext().getResources().getString(R.string.foreground_service_download))
+ .setSmallIcon(R.drawable.notification_icon)
+ .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.notification_icon))
+ .setColor(ThemeUtils.primaryColor())
.build();
// add AccountsUpdatedListener
diff --git a/src/main/java/com/owncloud/android/files/services/FileUploader.java b/src/main/java/com/owncloud/android/files/services/FileUploader.java
index 7e1d4de507a9..78e18d68cada 100644
--- a/src/main/java/com/owncloud/android/files/services/FileUploader.java
+++ b/src/main/java/com/owncloud/android/files/services/FileUploader.java
@@ -33,6 +33,7 @@
import android.app.Service;
import android.content.Context;
import android.content.Intent;
+import android.graphics.BitmapFactory;
import android.os.Binder;
import android.os.Handler;
import android.os.HandlerThread;
@@ -71,6 +72,7 @@
import com.owncloud.android.ui.activity.UploadListActivity;
import com.owncloud.android.ui.notifications.NotificationUtils;
import com.owncloud.android.utils.ErrorMessageAdapter;
+import com.owncloud.android.utils.ThemeUtils;
import java.io.File;
import java.util.AbstractList;
@@ -418,6 +420,10 @@ public void onCreate() {
mNotification = new NotificationCompat.Builder(this).setContentTitle(getApplicationContext().
getResources().getString(R.string.app_name))
+ .setContentText(getApplicationContext().getResources().getString(R.string.foreground_service_upload))
+ .setSmallIcon(R.drawable.notification_icon)
+ .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.notification_icon))
+ .setColor(ThemeUtils.primaryColor())
.build();
int failedCounter = mUploadsStorageManager.failInProgressUploads(
diff --git a/src/main/java/com/owncloud/android/operations/UploadFileOperation.java b/src/main/java/com/owncloud/android/operations/UploadFileOperation.java
index 0e4d343aa496..9fa3f43d40d4 100644
--- a/src/main/java/com/owncloud/android/operations/UploadFileOperation.java
+++ b/src/main/java/com/owncloud/android/operations/UploadFileOperation.java
@@ -28,6 +28,7 @@
import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.datamodel.ThumbnailsCacheManager;
+import com.owncloud.android.datamodel.UploadsStorageManager;
import com.owncloud.android.db.OCUpload;
import com.owncloud.android.files.services.FileUploader;
import com.owncloud.android.lib.common.OwnCloudClient;
@@ -319,6 +320,19 @@ protected RemoteOperationResult run(OwnCloudClient client) {
File expectedFile = null;
FileLock fileLock = null;
+ UploadsStorageManager uploadsStorageManager = new UploadsStorageManager(mContext.getContentResolver(),
+ mContext);
+
+ long size = 0;
+
+ for (OCUpload ocUpload : uploadsStorageManager.getAllStoredUploads()) {
+ if (ocUpload.getUploadId() == getOCUploadId()) {
+ ocUpload.setFileSize(size);
+ uploadsStorageManager.updateUpload(ocUpload);
+ break;
+ }
+ }
+
try {
/// Check that connectivity conditions are met and delays the upload otherwise
@@ -396,13 +410,51 @@ protected RemoteOperationResult run(OwnCloudClient client) {
Long timeStampLong = originalFile.lastModified() / 1000;
String timeStamp = timeStampLong.toString();
+ FileChannel channel = null;
+ try {
+ channel = new RandomAccessFile(mFile.getStoragePath(), "rw").getChannel();
+ fileLock = channel.tryLock();
+ } catch (FileNotFoundException e) {
+ // this basically means that the file is on SD card
+ // try to copy file to temporary dir if it doesn't exist
+ String temporalPath = FileStorageUtils.getTemporalPath(mAccount.name) + mFile.getRemotePath();
+ mFile.setStoragePath(temporalPath);
+ temporalFile = new File(temporalPath);
+
+ Files.deleteIfExists(Paths.get(temporalPath));
+ result = copy(originalFile, temporalFile);
+
+ if (result == null) {
+ if (temporalFile.length() == originalFile.length()) {
+ channel = new RandomAccessFile(temporalFile.getAbsolutePath(), "rw").getChannel();
+ fileLock = channel.tryLock();
+ } else {
+ result = new RemoteOperationResult(ResultCode.LOCK_FAILED);
+ }
+ }
+ }
+
+ try {
+ size = channel.size();
+ } catch (IOException e1) {
+ size = new File(mFile.getStoragePath()).length();
+ }
+
+ for (OCUpload ocUpload : uploadsStorageManager.getAllStoredUploads()) {
+ if (ocUpload.getUploadId() == getOCUploadId()) {
+ ocUpload.setFileSize(size);
+ uploadsStorageManager.updateUpload(ocUpload);
+ break;
+ }
+ }
+
/// perform the upload
if (mChunked &&
- (new File(mFile.getStoragePath())).length() >
- ChunkedUploadRemoteFileOperation.CHUNK_SIZE) {
+ (size > ChunkedUploadRemoteFileOperation.CHUNK_SIZE)) {
mUploadOperation = new ChunkedUploadRemoteFileOperation(mContext, mFile.getStoragePath(),
mFile.getRemotePath(), mFile.getMimetype(), mFile.getEtagInConflict(), timeStamp);
} else {
+
mUploadOperation = new UploadRemoteFileOperation(mFile.getStoragePath(),
mFile.getRemotePath(), mFile.getMimetype(), mFile.getEtagInConflict(), timeStamp);
}
@@ -416,53 +468,18 @@ protected RemoteOperationResult run(OwnCloudClient client) {
throw new OperationCancelledException();
}
- FileChannel channel = null;
- try {
- channel = new RandomAccessFile(mFile.getStoragePath(), "rw").getChannel();
- fileLock = channel.tryLock();
- } catch (FileNotFoundException e) {
- if (temporalFile == null) {
- String temporalPath = FileStorageUtils.getTemporalPath(mAccount.name) + mFile.getRemotePath();
- mFile.setStoragePath(temporalPath);
- temporalFile = new File(temporalPath);
-
- result = copy(originalFile, temporalFile);
+ if (result == null || result.isSuccess() && mUploadOperation != null) {
+ result = mUploadOperation.execute(client);
- if (result != null) {
- return result;
- } else {
- if (temporalFile.length() == originalFile.length()) {
- channel = new RandomAccessFile(temporalFile.getAbsolutePath(), "rw").getChannel();
- fileLock = channel.tryLock();
- } else {
- while (temporalFile.length() != originalFile.length()) {
- Files.deleteIfExists(Paths.get(temporalPath));
- result = copy(originalFile, temporalFile);
-
- if (result != null) {
- return result;
- } else {
- channel = new RandomAccessFile(temporalFile.getAbsolutePath(), "rw").
- getChannel();
- fileLock = channel.tryLock();
- }
- }
- }
- }
- } else {
- channel = new RandomAccessFile(temporalFile.getAbsolutePath(), "rw").getChannel();
- fileLock = channel.tryLock();
+ /// move local temporal file or original file to its corresponding
+ // location in the ownCloud local folder
+ if (!result.isSuccess() && result.getHttpCode() == HttpStatus.SC_PRECONDITION_FAILED) {
+ result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT);
}
- }
-
- result = mUploadOperation.execute(client);
- /// move local temporal file or original file to its corresponding
- // location in the ownCloud local folder
- if (!result.isSuccess() && result.getHttpCode() == HttpStatus.SC_PRECONDITION_FAILED) {
- result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT);
}
+
} catch (FileNotFoundException e) {
Log_OC.d(TAG, mOriginalStoragePath + " not exists anymore");
result = new RemoteOperationResult(ResultCode.LOCAL_FILE_NOT_FOUND);
@@ -486,6 +503,7 @@ protected RemoteOperationResult run(OwnCloudClient client) {
if (temporalFile != null && !originalFile.equals(temporalFile)) {
temporalFile.delete();
}
+
if (result == null) {
result = new RemoteOperationResult(ResultCode.UNKNOWN_ERROR);
}
diff --git a/src/main/java/com/owncloud/android/ui/adapter/ExpandableUploadListAdapter.java b/src/main/java/com/owncloud/android/ui/adapter/ExpandableUploadListAdapter.java
index ce42214e3509..77c20b277abc 100755
--- a/src/main/java/com/owncloud/android/ui/adapter/ExpandableUploadListAdapter.java
+++ b/src/main/java/com/owncloud/android/ui/adapter/ExpandableUploadListAdapter.java
@@ -237,7 +237,11 @@ private View getView(OCUpload[] uploadsItems, int position, View convertView, Vi
// file size
TextView fileSizeTextView = (TextView) view.findViewById(R.id.upload_file_size);
- fileSizeTextView.setText(DisplayUtils.bytesToHumanReadable(upload.getFileSize()) + ", ");
+ if (upload.getFileSize() != 0) {
+ fileSizeTextView.setText(DisplayUtils.bytesToHumanReadable(upload.getFileSize()) + ", ");
+ } else {
+ fileSizeTextView.setText("");
+ }
//* upload date
TextView uploadDateTextView = (TextView) view.findViewById(R.id.upload_date);
@@ -269,6 +273,7 @@ private View getView(OCUpload[] uploadsItems, int position, View convertView, Vi
/// Reset fields visibility
uploadDateTextView.setVisibility(View.VISIBLE);
pathTextView.setVisibility(View.VISIBLE);
+
fileSizeTextView.setVisibility(View.VISIBLE);
accountNameTextView.setVisibility(View.VISIBLE);
statusTextView.setVisibility(View.VISIBLE);
diff --git a/src/main/res/layout/file_details_share_user_item.xml b/src/main/res/layout/file_details_share_user_item.xml
index 16f59de85554..e824daf2778c 100644
--- a/src/main/res/layout/file_details_share_user_item.xml
+++ b/src/main/res/layout/file_details_share_user_item.xml
@@ -31,7 +31,7 @@
+ android:textSize="32sp"/>
+ android:textSize="@dimen/upload_list_item_text_size"/>
+ android:textSize="@dimen/upload_list_item_text_size"/>
diff --git a/src/main/res/values/dims.xml b/src/main/res/values/dims.xml
index 0133ffc07a3f..4fab9ef46f35 100644
--- a/src/main/res/values/dims.xml
+++ b/src/main/res/values/dims.xml
@@ -71,7 +71,7 @@
15dp
40dp
240dp
- 16dip
+ 16sp
100dp
2dp
32dp
@@ -83,7 +83,6 @@
180dp
60dp
12sp
- 12dip
35dp
12dp
2dp
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index 289ca1180642..69c3843be699 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -695,4 +695,7 @@
Use your fingerprint to unlock the app
BACK
Go back to old login method
+
+ Uploading files…
+ Downloading files…