Selaa lähdekoodia

Merge branch 'main' into photo_integration

Neeraj Gupta 2 vuotta sitten
vanhempi
commit
b3c0ec3941

+ 2 - 2
fastlane/metadata/android/zh/full_description.txt

@@ -4,7 +4,7 @@ ente 是一个简单的应用程序来备份和分享您的照片和视频。
 
 我们在Android、iOS、web 和桌面上有开源应用, 和您的照片将以端到端加密方式无缝同步 (e2ee)。
 
-即使您不是亲人,也可以轻松地与您的个人分享您的相册。 即使您不是亲人,也可以轻松地与您的个人分享您的相册。 您可以分享可公开查看的链接,他们可以通过添加照片来查看您的相册并进行协作,即使没有帐户或应用。
+如果你一直在寻找一个隐私友好的可以替代Google Photos,你已经来到了正确的地方。 使用 Ente,它们以端到端加密 (e2ee) 的方式存储。 这意味着只有您可以查看它们。 使用 Ente,它们以端到端加密 (e2ee) 的方式存储。 这意味着只有您可以查看它们。 即使您不是亲人,也可以轻松地与您的个人分享您的相册。 即使您不是亲人,也可以轻松地与您的个人分享您的相册。 您可以分享可公开查看的链接,他们可以通过添加照片来查看您的相册并进行协作,即使没有帐户或应用。
 
 您的加密数据已复制到三个不同的地点,包括巴黎的一个铺面掩体。 我们认真对待子孙后代,并确保您回忆比您长寿。 我们认真对待子孙后代,并确保您回忆比您长寿。
 
@@ -30,7 +30,7 @@ ente 是一个简单的应用程序来备份和分享您的照片和视频。
 ente requests for certain permissions to serve the purpose of a photo storage provider, which can be reviewed here: https://github.com/ente-io/photos-app/blob/f-droid/android/permissions.md
 
 价格
-我们不会永远提供免费计划,因为我们必须保持可持续性,经受住时间的考验。 相反,我们提供您可以自由分享的负担得起的计划。 您可以在 ente. 相反,我们提供您可以自由分享的负担得起的计划。 您可以在 ente.io找到更多信息。
+我们不会永远提供免费计划,因为我们必须保持可持续性,经受住时间的考验。 相反,我们提供您可以自由分享的负担得起的计划。 您可以在 ente. 相反,我们提供您可以自由分享的负担得起的计划。 您可以在 ente.io找到更多信息。 您可以在 ente.io找到更多信息。
 
 支持
 我们对提供人的支持感到自豪。 我们对提供人的支持感到自豪。 如果您是我们的付费客户,您可以联系Team@ente.io并期待我们的团队在24小时内做出回应。

+ 3 - 0
lib/main.dart

@@ -3,6 +3,7 @@ import 'dart:io';
 
 import "package:adaptive_theme/adaptive_theme.dart";
 import 'package:background_fetch/background_fetch.dart';
+import "package:computer/computer.dart";
 import 'package:firebase_messaging/firebase_messaging.dart';
 import 'package:flutter/foundation.dart';
 import 'package:flutter/material.dart';
@@ -153,6 +154,8 @@ Future<void> _init(bool isBackground, {String via = ''}) async {
   } else {
     AppLifecycleService.instance.onAppInForeground('init via: $via');
   }
+  // Start workers asynchronously. No need to wait for them to start
+  Computer.shared().turnOn(workersCount: 4, verbose: kDebugMode);
   CryptoUtil.init();
   await NotificationService.instance.init();
   await NetworkClient.instance.init();

+ 23 - 15
lib/services/local/local_sync_util.dart

@@ -16,7 +16,6 @@ const assetFetchPageSize = 2000;
 Future<Tuple2<List<LocalPathAsset>, List<File>>> getLocalPathAssetsAndFiles(
   int fromTime,
   int toTime,
-  Computer computer,
 ) async {
   final pathEntities = await _getGalleryList(
     updateFromTime: fromTime,
@@ -31,17 +30,24 @@ Future<Tuple2<List<LocalPathAsset>, List<File>>> getLocalPathAssetsAndFiles(
   final List<File> uniqueFiles = [];
   for (AssetPathEntity pathEntity in pathEntities) {
     final List<AssetEntity> assetsInPath = await _getAllAssetLists(pathEntity);
-    final Tuple2<Set<String>, List<File>> result = await computer.compute(
-      _getLocalIDsAndFilesFromAssets,
-      param: <String, dynamic>{
-        "pathEntity": pathEntity,
-        "fromTime": fromTime,
-        "alreadySeenLocalIDs": alreadySeenLocalIDs,
-        "assetList": assetsInPath,
-      },
-    );
-    alreadySeenLocalIDs.addAll(result.item1);
-    uniqueFiles.addAll(result.item2);
+    late Tuple2<Set<String>, List<File>> result;
+    if (assetsInPath.isEmpty) {
+      result = const Tuple2({}, []);
+    } else {
+      result = await Computer.shared().compute(
+        _getLocalIDsAndFilesFromAssets,
+        param: <String, dynamic>{
+          "pathEntity": pathEntity,
+          "fromTime": fromTime,
+          "alreadySeenLocalIDs": alreadySeenLocalIDs,
+          "assetList": assetsInPath,
+        },
+        taskName:
+            "getLocalPathAssetsAndFiles-${pathEntity.name}-count-${assetsInPath.length}",
+      );
+      alreadySeenLocalIDs.addAll(result.item1);
+      uniqueFiles.addAll(result.item2);
+    }
     localPathAssets.add(
       LocalPathAsset(
         localIDs: result.item1,
@@ -118,15 +124,17 @@ Future<LocalDiffResult> getDiffWithLocal(
   Set<String> existingIDs, // localIDs of files already imported in app
   Map<String, Set<String>> pathToLocalIDs,
   Set<String> invalidIDs,
-  Computer computer,
 ) async {
   final Map<String, dynamic> args = <String, dynamic>{};
   args['assets'] = assets;
   args['existingIDs'] = existingIDs;
   args['invalidIDs'] = invalidIDs;
   args['pathToLocalIDs'] = pathToLocalIDs;
-  final LocalDiffResult diffResult =
-      await computer.compute(_getLocalAssetsDiff, param: args);
+  final LocalDiffResult diffResult = await Computer.shared().compute(
+    _getLocalAssetsDiff,
+    param: args,
+    taskName: "getLocalAssetsDiff",
+  );
   if (diffResult.localPathAssets != null) {
     diffResult.uniqueLocalFiles =
         await _convertLocalAssetsToUniqueFiles(diffResult.localPathAssets!);

+ 9 - 12
lib/services/local_sync_service.dart

@@ -1,7 +1,6 @@
 import 'dart:async';
 import 'dart:io';
 
-import 'package:computer/computer.dart';
 import 'package:flutter/foundation.dart';
 import 'package:logging/logging.dart';
 import 'package:photo_manager/photo_manager.dart';
@@ -24,7 +23,6 @@ import 'package:tuple/tuple.dart';
 class LocalSyncService {
   final _logger = Logger("LocalSyncService");
   final _db = FilesDB.instance;
-  final Computer _computer = Computer();
   late SharedPreferences _prefs;
   Completer<void>? _existingSync;
 
@@ -47,7 +45,6 @@ class LocalSyncService {
     if (!AppLifecycleService.instance.isForeground) {
       await PhotoManager.setIgnorePermissionCheck(true);
     }
-    await _computer.turnOn(workersCount: 1);
     if (hasGrantedPermissions()) {
       _registerChangeCallback();
     }
@@ -164,7 +161,6 @@ class LocalSyncService {
       existingLocalFileIDs,
       pathToLocalIDs,
       invalidIDs,
-      _computer,
     );
     bool hasAnyMappingChanged = false;
     if (localDiffResult.newPathToLocalIDs?.isNotEmpty ?? false) {
@@ -268,17 +264,18 @@ class LocalSyncService {
     required int toTime,
   }) async {
     final Tuple2<List<LocalPathAsset>, List<File>> result =
-        await getLocalPathAssetsAndFiles(fromTime, toTime, _computer);
-
-    // Update the mapping for device path_id to local file id. Also, keep track
-    // of newly discovered device paths
-    await FilesDB.instance.insertLocalAssets(
-      result.item1,
-      shouldAutoBackup: Configuration.instance.hasSelectedAllFoldersForBackup(),
-    );
+        await getLocalPathAssetsAndFiles(fromTime, toTime);
 
     final List<File> files = result.item2;
     if (files.isNotEmpty) {
+      // Update the mapping for device path_id to local file id. Also, keep track
+      // of newly discovered device paths
+      await FilesDB.instance.insertLocalAssets(
+        result.item1,
+        shouldAutoBackup:
+            Configuration.instance.hasSelectedAllFoldersForBackup(),
+      );
+
       _logger.info(
         "Loaded ${files.length} photos from " +
             DateTime.fromMicrosecondsSinceEpoch(fromTime).toString() +

+ 24 - 8
lib/utils/crypto_util.dart

@@ -166,10 +166,10 @@ Uint8List chachaDecryptData(Map<String, dynamic> args) {
 }
 
 class CryptoUtil {
-  static final Computer _computer = Computer();
+  // Note: workers are turned on during app startup.
+  static final Computer _computer = Computer.shared();
 
   static init() {
-    _computer.turnOn(workersCount: 4);
     Sodium.init();
   }
 
@@ -231,7 +231,11 @@ class CryptoUtil {
     args["cipher"] = cipher;
     args["nonce"] = nonce;
     args["key"] = key;
-    return _computer.compute(cryptoSecretboxOpenEasy, param: args);
+    return _computer.compute(
+      cryptoSecretboxOpenEasy,
+      param: args,
+      taskName: "decrypt",
+    );
   }
 
   // Decrypts the given cipher, with the given key and nonce using XSalsa20
@@ -262,7 +266,11 @@ class CryptoUtil {
     final args = <String, dynamic>{};
     args["source"] = source;
     args["key"] = key;
-    return _computer.compute(chachaEncryptData, param: args);
+    return _computer.compute(
+      chachaEncryptData,
+      param: args,
+      taskName: "encryptChaCha",
+    );
   }
 
   // Decrypts the given source, with the given key and header using XChaCha20
@@ -277,7 +285,11 @@ class CryptoUtil {
     args["source"] = source;
     args["key"] = key;
     args["header"] = header;
-    return _computer.compute(chachaDecryptData, param: args);
+    return _computer.compute(
+      chachaDecryptData,
+      param: args,
+      taskName: "decryptChaCha",
+    );
   }
 
   // Encrypts the file at sourceFilePath, with the key (if provided) and a
@@ -293,7 +305,8 @@ class CryptoUtil {
     args["sourceFilePath"] = sourceFilePath;
     args["destinationFilePath"] = destinationFilePath;
     args["key"] = key;
-    return _computer.compute(chachaEncryptFile, param: args);
+    return _computer.compute(chachaEncryptFile,
+        param: args, taskName: "encryptFile");
   }
 
   // Decrypts the file at sourceFilePath, with the given key and header using
@@ -309,7 +322,8 @@ class CryptoUtil {
     args["destinationFilePath"] = destinationFilePath;
     args["header"] = header;
     args["key"] = key;
-    return _computer.compute(chachaDecryptFile, param: args);
+    return _computer.compute(chachaDecryptFile,
+        param: args, taskName: "decryptFile");
   }
 
   // Generates and returns a 256-bit key.
@@ -391,7 +405,7 @@ class CryptoUtil {
     return DerivedKeyResult(key, memLimit, opsLimit);
   }
 
-  // Derives a key for a given password, salt, memLimit and opsLimit using 
+  // Derives a key for a given password, salt, memLimit and opsLimit using
   // Argon2id, v1.3.
   static Future<Uint8List> deriveKey(
     Uint8List password,
@@ -407,6 +421,7 @@ class CryptoUtil {
         "memLimit": memLimit,
         "opsLimit": opsLimit,
       },
+      taskName: "deriveKey",
     );
   }
 
@@ -417,6 +432,7 @@ class CryptoUtil {
       param: {
         "sourceFilePath": source.path,
       },
+      taskName: "fileHash",
     );
   }
 }

+ 6 - 5
pubspec.lock

@@ -275,11 +275,12 @@ packages:
   computer:
     dependency: "direct main"
     description:
-      name: computer
-      sha256: "3df9f1ef497aaf69e066b00f4441726eb28037dc33e97b5d56393967f92c5fe8"
-      url: "https://pub.dev"
-    source: hosted
-    version: "2.0.0"
+      path: "."
+      ref: HEAD
+      resolved-ref: "82e365fed8a1a76f6eea0220de98389eed7b0445"
+      url: "https://github.com/ente-io/computer.git"
+    source: git
+    version: "3.2.1"
   confetti:
     dependency: "direct main"
     description:

+ 2 - 1
pubspec.yaml

@@ -28,7 +28,8 @@ dependencies:
   chewie:
     path: thirdparty/chewie
   collection: # dart
-  computer: ^2.0.0
+  computer:
+    git: "https://github.com/ente-io/computer.git"
   confetti: ^0.6.0
   connectivity_plus: ^3.0.3
   crypto: ^3.0.2