diff --git a/android/app/src/main/kotlin/com/leastauthority/destiny/MainActivity.kt b/android/app/src/main/kotlin/com/leastauthority/destiny/MainActivity.kt index 5dc1f555..c7ffb9e2 100644 --- a/android/app/src/main/kotlin/com/leastauthority/destiny/MainActivity.kt +++ b/android/app/src/main/kotlin/com/leastauthority/destiny/MainActivity.kt @@ -7,6 +7,7 @@ import android.net.Uri import android.os.Bundle import android.os.Handler import android.os.Looper +import android.os.UserManager import android.util.Log import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat @@ -19,6 +20,7 @@ class MainActivity : FlutterActivity() { private val FILE_SELECTOR_CHANNEL_NAME = "destiny.android/file_selector" private val SHARE_FILE_CHANNEL_NAME = "destiny.androids/share_file" private val SAVE_AS_CHANNEL_NAME = "destiny.android/save_as" + private val USER_ID_CHANNEL_NAME = "destiny.android/user_id" private var SHARE_FILE_CHANNEL: MethodChannel? = null @@ -44,6 +46,14 @@ class MainActivity : FlutterActivity() { } } + // Get emphmeral user id to be used in accessing a directory name + private fun getUserID(call: MethodCall, result: MethodChannel.Result) { + val userManager = getContext().getSystemService(UserManager::class.java) + + val ephemeralUserId = userManager!!.getSerialNumberForUser(android.os.Process.myUserHandle()) + result.success(ephemeralUserId); + } + private fun sendFileFromIntent(intent: Intent) { val uri = intent.getParcelableExtra(Intent.EXTRA_STREAM) as Uri if (SHARE_FILE_CHANNEL != null) { @@ -101,6 +111,20 @@ class MainActivity : FlutterActivity() { } } + MethodChannel( + flutterEngine.dartExecutor.binaryMessenger, + USER_ID_CHANNEL_NAME + ).setMethodCallHandler { call, result -> + when (call.method) { + "getUserID" -> getUserID(call, result) + else -> result.error( + UNKNOWN_METHOD, + "Unknown method called on save as channel: ${call.method}", + "" + ) + } + } + SHARE_FILE_CHANNEL = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, SHARE_FILE_CHANNEL_NAME) diff --git a/lib/constants/app_constants.dart b/lib/constants/app_constants.dart index 6923b4d0..6e9e1dff 100644 --- a/lib/constants/app_constants.dart +++ b/lib/constants/app_constants.dart @@ -179,7 +179,9 @@ const String SETTINGS_SCREEN_SELECT_A_FOLDER_BUTTON = 'SETTINGS_SCREEN_SELECT_A_FOLDER_BUTTON'; const String SETTINGS_SCREEN_BOTTOM_SPACE_PLACEHOLDER = 'SETTINGS_SCREEN_BOTTOM_SPACE_PLACEHOLDER'; -const String ANDROID_DOWNLOADS_FOLDER_PATH = '/storage/emulated/0/Download'; +const String ANDROID_DOWNLOADS_PATH = '/storage/emulated/'; +const String ANDROID_DOWNLOADS_FOLDER = '/Download'; +const int DEFAULT_ANDROID_USER = 0; const String WINDOW_TITLE = "Destiny"; diff --git a/lib/main.dart b/lib/main.dart index 6bee84ed..06238133 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -19,18 +19,21 @@ import 'locator.dart'; // This is our global ServiceLocator GetIt getIt = GetIt.instance; -void startApp(Config c) { +void startApp(Config c) async { WidgetsFlutterBinding.ensureInitialized(); SystemChrome.setPreferredOrientations( [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]); register(getIt, c); + // Wait for all preferences to be loaded. Getting UserID leads to a crash if + await getIt.allReady(); if (Platform.isWindows || Platform.isLinux || Platform.isMacOS) { setWindowMinSize(const Size(900, 800)); setWindowMaxSize(const Size(1600, 1200)); setWindowFrame(Rect.fromLTWH(0, 0, 900, 800)); } + runApp(MultiProvider(providers: [ ChangeNotifierProvider(create: (context) => SendSharedState()), ChangeNotifierProvider(create: (context) => ReceiveSharedState()) diff --git a/lib/views/shared/file_picker.dart b/lib/views/shared/file_picker.dart index b627eca4..d2f34b22 100644 --- a/lib/views/shared/file_picker.dart +++ b/lib/views/shared/file_picker.dart @@ -161,11 +161,21 @@ FilePicker getMediaPicker() { Future getDownloadPath() async { Directory? directory; + try { if (Platform.isIOS) { directory = await getApplicationDocumentsDirectory(); } else if (Platform.isAndroid) { - directory = Directory(ANDROID_DOWNLOADS_FOLDER_PATH); + final userData = MethodChannel('destiny.android/user_id'); + int userId = DEFAULT_ANDROID_USER; + + // try determinate emphemeral user id, to select download folder for multiple users + userId = await userData.invokeMethod("getUserID"); + + directory = Directory(ANDROID_DOWNLOADS_PATH + + userId.toString() + + ANDROID_DOWNLOADS_FOLDER); + if (!await directory.exists()) { directory = await getExternalStorageDirectory(); } @@ -173,7 +183,7 @@ Future getDownloadPath() async { directory = await getDownloadsDirectory(); } } catch (err) { - print("Cannot get download folder path"); + print("Cannot get download folder path" + err.toString()); } return directory!.path; } diff --git a/lib/views/shared/receive.dart b/lib/views/shared/receive.dart index cb393db2..7415162a 100644 --- a/lib/views/shared/receive.dart +++ b/lib/views/shared/receive.dart @@ -11,7 +11,6 @@ import 'package:dart_wormhole_william/client/native_client.dart'; import 'package:flutter/material.dart'; import 'package:file_picker/file_picker.dart' as f; import 'package:flutter/services.dart'; -import 'package:path_provider/path_provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:wakelock/wakelock.dart'; @@ -102,21 +101,11 @@ class ReceiveSharedState extends ChangeNotifier { this.prefs = prefs; }); - if (dartIO.Platform.isAndroid) { - defaultPathForPlatform = ANDROID_DOWNLOADS_FOLDER_PATH; - } else if (dartIO.Platform.isIOS) { - getApplicationDocumentsDirectory().then((downloadsDir) { - setState(() { - defaultPathForPlatform = downloadsDir.path; - }); - }); - } else { - getDownloadsDirectory().then((downloadsDir) { - setState(() { - defaultPathForPlatform = downloadsDir?.path; - }); + getDownloadPath().then((downloadPath) { + setState(() { + defaultPathForPlatform = downloadPath; }); - } + }); } late ProgressSharedState progress = ProgressSharedState(setState, () { diff --git a/lib/views/shared/send.dart b/lib/views/shared/send.dart index ad724570..6d6eb42d 100644 --- a/lib/views/shared/send.dart +++ b/lib/views/shared/send.dart @@ -33,8 +33,6 @@ class SendSharedState extends ChangeNotifier { SendScreenStates currentState = SendScreenStates.Initial; - final appSettings = getIt(); - CancelFunc cancelFunc = () { print("No cancel function assigned. Doing nothing"); }; @@ -179,6 +177,8 @@ class SendSharedState extends ChangeNotifier { }, onError: defaultErrorHandler); } + final appSettings = getIt(); + Client createClient() => Client(appSettings.config()); Widget widgetByState(