Prechádzať zdrojové kódy

Merge pull request #12337 from nextcloud/11741-auto-upload-does-not-start-automatically-on-3250

Fix auto upload does not start automatically
Alper Öztürk 1 rok pred
rodič
commit
1757edecad

+ 6 - 0
app/src/main/AndroidManifest.xml

@@ -384,6 +384,12 @@
             </intent-filter>
         </activity>
 
+        <service
+            android:name="androidx.work.impl.foreground.SystemForegroundService"
+            android:directBootAware="false"
+            android:enabled="@bool/enable_system_foreground_service_default"
+            android:exported="false"
+            android:foregroundServiceType="dataSync" />
         <service
             android:name=".services.OperationsService"
             android:exported="false" />

+ 36 - 4
app/src/main/java/com/nextcloud/client/jobs/FilesSyncWork.kt

@@ -25,9 +25,12 @@ package com.nextcloud.client.jobs
 import android.content.ContentResolver
 import android.content.Context
 import android.content.res.Resources
+import android.os.Build
 import android.text.TextUtils
+import androidx.core.app.NotificationCompat
 import androidx.exifinterface.media.ExifInterface
-import androidx.work.Worker
+import androidx.work.CoroutineWorker
+import androidx.work.ForegroundInfo
 import androidx.work.WorkerParameters
 import com.nextcloud.client.account.UserAccountManager
 import com.nextcloud.client.device.PowerManagementService
@@ -37,6 +40,7 @@ import com.owncloud.android.R
 import com.owncloud.android.datamodel.ArbitraryDataProvider
 import com.owncloud.android.datamodel.ArbitraryDataProviderImpl
 import com.owncloud.android.datamodel.FilesystemDataProvider
+import com.owncloud.android.datamodel.ForegroundServiceType
 import com.owncloud.android.datamodel.MediaFolderType
 import com.owncloud.android.datamodel.SyncedFolder
 import com.owncloud.android.datamodel.SyncedFolderProvider
@@ -45,6 +49,7 @@ import com.owncloud.android.files.services.FileUploader
 import com.owncloud.android.lib.common.utils.Log_OC
 import com.owncloud.android.operations.UploadFileOperation
 import com.owncloud.android.ui.activity.SettingsActivity
+import com.owncloud.android.ui.notifications.NotificationUtils
 import com.owncloud.android.utils.FileStorageUtils
 import com.owncloud.android.utils.FilesSyncHelper
 import com.owncloud.android.utils.MimeType
@@ -66,16 +71,38 @@ class FilesSyncWork(
     private val powerManagementService: PowerManagementService,
     private val syncedFolderProvider: SyncedFolderProvider,
     private val backgroundJobManager: BackgroundJobManager
-) : Worker(context, params) {
+) : CoroutineWorker(context, params) {
 
     companion object {
         const val TAG = "FilesSyncJob"
         const val SKIP_CUSTOM = "skipCustom"
         const val OVERRIDE_POWER_SAVING = "overridePowerSaving"
+        const val FOREGROUND_SERVICE_ID = 414
     }
 
-    override fun doWork(): Result {
+    @Suppress("MagicNumber")
+    private fun createForegroundInfo(progressPercent: Int): ForegroundInfo {
+        // update throughout worker execution to give use feedback how far worker is
+
+        val notification = NotificationCompat.Builder(context, NotificationUtils.NOTIFICATION_CHANNEL_FILE_SYNC)
+            .setTicker(context.getString(R.string.autoupload_worker_foreground_info))
+            .setContentText(context.getString(R.string.autoupload_worker_foreground_info))
+            .setSmallIcon(R.drawable.notification_icon)
+            .setContentTitle(context.getString(R.string.autoupload_worker_foreground_info))
+            .setOngoing(true)
+            .setProgress(100, progressPercent, false)
+            .build()
+        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+            ForegroundInfo(FOREGROUND_SERVICE_ID, notification, ForegroundServiceType.DataSync.getId())
+        } else {
+            ForegroundInfo(FOREGROUND_SERVICE_ID, notification)
+        }
+    }
+
+    @Suppress("MagicNumber")
+    override suspend fun doWork(): Result {
         backgroundJobManager.logStartOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class))
+        setForeground(createForegroundInfo(0))
 
         val overridePowerSaving = inputData.getBoolean(OVERRIDE_POWER_SAVING, false)
         // If we are in power save mode, better to postpone upload
@@ -93,13 +120,18 @@ class FilesSyncWork(
             connectivityService,
             powerManagementService
         )
+        setForeground(createForegroundInfo(5))
         FilesSyncHelper.insertAllDBEntries(skipCustom, syncedFolderProvider)
+        setForeground(createForegroundInfo(50))
         // Create all the providers we'll need
         val filesystemDataProvider = FilesystemDataProvider(contentResolver)
         val currentLocale = resources.configuration.locale
         val dateFormat = SimpleDateFormat("yyyy:MM:dd HH:mm:ss", currentLocale)
         dateFormat.timeZone = TimeZone.getTimeZone(TimeZone.getDefault().id)
-        for (syncedFolder in syncedFolderProvider.syncedFolders) {
+
+        val syncedFolders = syncedFolderProvider.syncedFolders
+        for ((index, syncedFolder) in syncedFolders.withIndex()) {
+            setForeground(createForegroundInfo((50 + (index.toDouble() / syncedFolders.size.toDouble()) * 50).toInt()))
             if (syncedFolder.isEnabled && (!skipCustom || MediaFolderType.CUSTOM != syncedFolder.type)) {
                 syncFolder(
                     context,

+ 42 - 41
app/src/main/java/com/owncloud/android/datamodel/FilesystemDataProvider.java

@@ -55,10 +55,10 @@ public class FilesystemDataProvider {
 
     public int deleteAllEntriesForSyncedFolder(String syncedFolderId) {
         return contentResolver.delete(
-                ProviderMeta.ProviderTableMeta.CONTENT_URI_FILESYSTEM,
-                ProviderMeta.ProviderTableMeta.FILESYSTEM_SYNCED_FOLDER_ID + " = ?",
-                new String[]{syncedFolderId}
-        );
+            ProviderMeta.ProviderTableMeta.CONTENT_URI_FILESYSTEM,
+            ProviderMeta.ProviderTableMeta.FILESYSTEM_SYNCED_FOLDER_ID + " = ?",
+            new String[]{syncedFolderId}
+                                     );
     }
 
     public void updateFilesystemFileAsSentForUpload(String path, String syncedFolderId) {
@@ -66,12 +66,12 @@ public class FilesystemDataProvider {
         cv.put(ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_SENT_FOR_UPLOAD, 1);
 
         contentResolver.update(
-                ProviderMeta.ProviderTableMeta.CONTENT_URI_FILESYSTEM,
-                cv,
-                ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_LOCAL_PATH + " = ? and " +
-                        ProviderMeta.ProviderTableMeta.FILESYSTEM_SYNCED_FOLDER_ID + " = ?",
-                new String[]{path, syncedFolderId}
-        );
+            ProviderMeta.ProviderTableMeta.CONTENT_URI_FILESYSTEM,
+            cv,
+            ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_LOCAL_PATH + " = ? and " +
+                ProviderMeta.ProviderTableMeta.FILESYSTEM_SYNCED_FOLDER_ID + " = ?",
+            new String[]{path, syncedFolderId}
+                              );
     }
 
     public Set<String> getFilesForUpload(String localPath, String syncedFolderId) {
@@ -80,20 +80,20 @@ public class FilesystemDataProvider {
         String likeParam = localPath + "%";
 
         Cursor cursor = contentResolver.query(
-                ProviderMeta.ProviderTableMeta.CONTENT_URI_FILESYSTEM,
-                null,
-                ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_LOCAL_PATH + " LIKE ? and " +
-                        ProviderMeta.ProviderTableMeta.FILESYSTEM_SYNCED_FOLDER_ID + " = ? and " +
-                        ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_SENT_FOR_UPLOAD + " = ? and " +
-                        ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_IS_FOLDER + " = ?",
-                new String[]{likeParam, syncedFolderId, "0", "0"},
-                null);
+            ProviderMeta.ProviderTableMeta.CONTENT_URI_FILESYSTEM,
+            null,
+            ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_LOCAL_PATH + " LIKE ? and " +
+                ProviderMeta.ProviderTableMeta.FILESYSTEM_SYNCED_FOLDER_ID + " = ? and " +
+                ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_SENT_FOR_UPLOAD + " = ? and " +
+                ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_IS_FOLDER + " = ?",
+            new String[]{likeParam, syncedFolderId, "0", "0"},
+            null);
 
         if (cursor != null) {
             if (cursor.moveToFirst()) {
                 do {
                     String value = cursor.getString(cursor.getColumnIndexOrThrow(
-                            ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_LOCAL_PATH));
+                        ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_LOCAL_PATH));
                     if (value == null) {
                         Log_OC.e(TAG, "Cannot get local path");
                     } else {
@@ -159,11 +159,11 @@ public class FilesystemDataProvider {
 
 
             int result = contentResolver.update(
-                    ProviderMeta.ProviderTableMeta.CONTENT_URI_FILESYSTEM,
-                    cv,
-                    ProviderMeta.ProviderTableMeta._ID + "=?",
-                    new String[]{String.valueOf(data.getId())}
-            );
+                ProviderMeta.ProviderTableMeta.CONTENT_URI_FILESYSTEM,
+                cv,
+                ProviderMeta.ProviderTableMeta._ID + "=?",
+                new String[]{String.valueOf(data.getId())}
+                                               );
 
             if (result == 0) {
                 Log_OC.v(TAG, "Failed to update filesystem data with local path: " + localPath);
@@ -174,33 +174,33 @@ public class FilesystemDataProvider {
     private FileSystemDataSet getFilesystemDataSet(String localPathParam, SyncedFolder syncedFolder) {
 
         Cursor cursor = contentResolver.query(
-                ProviderMeta.ProviderTableMeta.CONTENT_URI_FILESYSTEM,
-                null,
-                ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_LOCAL_PATH + " = ? and " +
-                        ProviderMeta.ProviderTableMeta.FILESYSTEM_SYNCED_FOLDER_ID + " = ?",
-                new String[]{localPathParam, Long.toString(syncedFolder.getId())},
-                null
-        );
+            ProviderMeta.ProviderTableMeta.CONTENT_URI_FILESYSTEM,
+            null,
+            ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_LOCAL_PATH + " = ? and " +
+                ProviderMeta.ProviderTableMeta.FILESYSTEM_SYNCED_FOLDER_ID + " = ?",
+            new String[]{localPathParam, Long.toString(syncedFolder.getId())},
+            null
+                                             );
 
         FileSystemDataSet dataSet = null;
         if (cursor != null) {
             if (cursor.moveToFirst()) {
                 int id = cursor.getInt(cursor.getColumnIndexOrThrow(ProviderMeta.ProviderTableMeta._ID));
                 String localPath = cursor.getString(cursor.getColumnIndexOrThrow(
-                        ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_LOCAL_PATH));
+                    ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_LOCAL_PATH));
                 long modifiedAt = cursor.getLong(cursor.getColumnIndexOrThrow(
-                        ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_MODIFIED));
+                    ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_MODIFIED));
                 boolean isFolder = false;
                 if (cursor.getInt(cursor.getColumnIndexOrThrow(
-                        ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_IS_FOLDER)) != 0) {
+                    ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_IS_FOLDER)) != 0) {
                     isFolder = true;
                 }
                 long foundAt = cursor.getLong(cursor.getColumnIndexOrThrow(ProviderMeta.
-                        ProviderTableMeta.FILESYSTEM_FILE_FOUND_RECENTLY));
+                                                                               ProviderTableMeta.FILESYSTEM_FILE_FOUND_RECENTLY));
 
                 boolean isSentForUpload = false;
                 if (cursor.getInt(cursor.getColumnIndexOrThrow(
-                        ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_SENT_FOR_UPLOAD)) != 0) {
+                    ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_SENT_FOR_UPLOAD)) != 0) {
                     isSentForUpload = true;
                 }
 
@@ -210,7 +210,7 @@ public class FilesystemDataProvider {
                     Log_OC.e(TAG, "Arbitrary value could not be created from cursor");
                 } else {
                     dataSet = new FileSystemDataSet(id, localPath, modifiedAt, isFolder, isSentForUpload, foundAt,
-                            syncedFolder.getId(), crc32);
+                                                    syncedFolder.getId(), crc32);
                 }
             }
             cursor.close();
@@ -223,11 +223,12 @@ public class FilesystemDataProvider {
 
     private long getFileChecksum(String filepath) {
 
-        try (InputStream inputStream = new BufferedInputStream(new FileInputStream(filepath))){
+        try (InputStream inputStream = new BufferedInputStream(new FileInputStream(filepath))) {
             CRC32 crc = new CRC32();
-            int cnt;
-            while ((cnt = inputStream.read()) != -1) {
-                crc.update(cnt);
+            byte[] buf = new byte[1024 * 64];
+            int size;
+            while ((size = inputStream.read(buf)) > 0) {
+                crc.update(buf, 0, size);
             }
 
             return crc.getValue();

+ 1 - 0
app/src/main/res/values/strings.xml

@@ -628,6 +628,7 @@
     <string name="autoupload_hide_folder">Hide folder</string>
     <string name="autoupload_configure">Configure</string>
     <string name="synced_folders_configure_folders">Configure folders</string>
+    <string name="autoupload_worker_foreground_info">Preparing auto upload</string>
 
     <string name="empty" translatable="false" />
     <string name="test_server_button">Test server connection</string>