Skip to content

Commit

Permalink
AvaloniaUI#6110 Implementation of storage provider for tizen
Browse files Browse the repository at this point in the history
  • Loading branch information
OmidID committed Jul 6, 2023
1 parent 18605e2 commit c68b53f
Show file tree
Hide file tree
Showing 3 changed files with 198 additions and 6 deletions.
8 changes: 8 additions & 0 deletions samples/ControlCatalog.Tizen/tizen-manifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,12 @@
<icon>ControlCatalog.Avalonia.png</icon>
<metadata key="http://tizen.org/metadata/prefer_dotnet_aot" value="true" />
</ui-application>
<privileges>
<privilege>http://tizen.org/privilege/appdir.shareddata</privilege>
<privilege>http://tizen.org/privilege/appmanager.launch</privilege>
<privilege>http://tizen.org/privilege/externalstorage</privilege>
<privilege>http://tizen.org/privilege/externalstorage.appdata</privilege>
<privilege>http://tizen.org/privilege/internet</privilege>
<privilege>http://tizen.org/privilege/network.get</privilege>
</privileges>
</manifest>
184 changes: 184 additions & 0 deletions src/Tizen/Avalonia.Tizen/TizenStorageProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
using System.Security;
using Avalonia.Platform.Storage;
using Avalonia.Platform.Storage.FileIO;
using Avalonia.Tizen.Platform;
using Tizen.Applications;

namespace Avalonia.Tizen;
internal class TizenStorageProvider : IStorageProvider
{
public bool CanOpen => true;

public bool CanSave => false;

public bool CanPickFolder => true;

public Task<IStorageBookmarkFile?> OpenFileBookmarkAsync(string bookmark)
{
throw new NotImplementedException();
}

private static async Task CheckPermission()
{
Permissions.EnsureDeclared(Permissions.AppManagerLaunchPrivilege);
if (await Permissions.RequestPrivilegeAsync(Permissions.MediaStoragePrivilege) == false)
{
throw new SecurityException("Application doesn't have storage permission.");
}
}

public async Task<IReadOnlyList<IStorageFile>> OpenFilePickerAsync(FilePickerOpenOptions options)
{
await CheckPermission();

var tcs = new TaskCompletionSource<IReadOnlyList<IStorageFile>>();

#pragma warning disable CS8603 // Possible null reference return.
var fileType = options.FileTypeFilter?
.Where(w => w.MimeTypes != null)
.SelectMany(s => s.MimeTypes);
#pragma warning restore CS8603 // Possible null reference return.

var appControl = new AppControl
{
Operation = AppControlOperations.Pick,
Mime = fileType?.Any() == true
? fileType.Aggregate((o, n) => o + ";" + n)
: "*/*"
};
appControl.ExtraData.Add(AppControlData.SectionMode, options.AllowMultiple ? "multiple" : "single");
if (options.SuggestedStartLocation?.Path is { } startupPath)
appControl.ExtraData.Add(AppControlData.Path, startupPath.ToString());
appControl.LaunchMode = AppControlLaunchMode.Single;

var fileResults = new List<IStorageFile>();

AppControl.SendLaunchRequest(appControl, (request, reply, result) =>
{
if (result == AppControlReplyResult.Succeeded)
{
if (reply.ExtraData.Count() > 0)
{
var selectedFiles = reply.ExtraData.Get<IEnumerable<string>>(AppControlData.Selected).ToList();
fileResults.AddRange(selectedFiles.Select(f => new BclStorageFile(new(f))));
}
}

tcs.TrySetResult(fileResults);
});

return await tcs.Task;
}

public async Task<IReadOnlyList<IStorageFolder>> OpenFolderPickerAsync(FolderPickerOpenOptions options)
{
Permissions.EnsureDeclared(Permissions.AppManagerLaunchPrivilege);
if (await Permissions.RequestPrivilegeAsync(Permissions.MediaStoragePrivilege) == false)
{
throw new SecurityException("Application doesn't have storage permission.");
}

var tcs = new TaskCompletionSource<IReadOnlyList<IStorageFolder>>();

var appControl = new AppControl
{
Operation = AppControlOperations.Pick,
Mime = "inode/directory"
};
appControl.ExtraData.Add(AppControlData.SectionMode, options.AllowMultiple ? "multiple" : "single");
if (options.SuggestedStartLocation?.Path is { } startupPath)
appControl.ExtraData.Add(AppControlData.Path, startupPath.ToString());
appControl.LaunchMode = AppControlLaunchMode.Single;

var fileResults = new List<IStorageFolder>();

AppControl.SendLaunchRequest(appControl, (request, reply, result) =>
{
if (result == AppControlReplyResult.Succeeded)
{
if (reply.ExtraData.Count() > 0)
{
var selectedFiles = reply.ExtraData.Get<IEnumerable<string>>(AppControlData.Selected).ToList();
fileResults.AddRange(selectedFiles.Select(f => new BclStorageFolder(new System.IO.DirectoryInfo(f))));
}
}

tcs.TrySetResult(fileResults);
});

return await tcs.Task;
}

public Task<IStorageBookmarkFolder?> OpenFolderBookmarkAsync(string bookmark)
{
throw new NotImplementedException();
}

public Task<IStorageFile?> SaveFilePickerAsync(FilePickerSaveOptions options)
{
throw new NotImplementedException();
}

public async Task<IStorageFile?> TryGetFileFromPathAsync(Uri filePath)
{
await CheckPermission();

if (filePath is not { IsAbsoluteUri: true, Scheme: "file" })
{
throw new ArgumentException("File path is expected to be an absolute link with \"file\" scheme.");
}

var path = Path.Combine(global::Tizen.Applications.Application.Current.DirectoryInfo.Resource, filePath.AbsolutePath);
var file = new FileInfo(path);
if (!file.Exists)
{
return null;
}

return new BclStorageFile(file);
}

public async Task<IStorageFolder?> TryGetFolderFromPathAsync(Uri folderPath)
{
if (folderPath is null)
{
throw new ArgumentNullException(nameof(folderPath));
}

await CheckPermission();

if (folderPath is not { IsAbsoluteUri: true, Scheme: "file" })
{
throw new ArgumentException("File path is expected to be an absolute link with \"file\" scheme.");
}

var path = Path.Combine(global::Tizen.Applications.Application.Current.DirectoryInfo.Resource, folderPath.AbsolutePath);
var directory = new System.IO.DirectoryInfo(path);
if (!directory.Exists)
return null;

return new BclStorageFolder(directory);
}

public Task<IStorageFolder?> TryGetWellKnownFolderAsync(WellKnownFolder wellKnownFolder)
{
var folder = wellKnownFolder switch
{
WellKnownFolder.Desktop => null,
WellKnownFolder.Documents => global::Tizen.Applications.Application.Current.DirectoryInfo.Data,
WellKnownFolder.Downloads => global::Tizen.Applications.Application.Current.DirectoryInfo.SharedData,
WellKnownFolder.Music => null,
WellKnownFolder.Pictures => null,
WellKnownFolder.Videos => null,
_ => throw new ArgumentOutOfRangeException(nameof(wellKnownFolder), wellKnownFolder, null),
};

if (folder == null)
return Task.FromResult<IStorageFolder?>(null);

var storageFolder = new BclStorageFolder(new System.IO.DirectoryInfo(folder));
return Task.FromResult<IStorageFolder?>(storageFolder);
}


}
12 changes: 6 additions & 6 deletions src/Tizen/Avalonia.Tizen/TopLevelImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ public class TopLevelImpl : ITopLevelImpl
{
private readonly ITizenView _view;
private readonly NuiClipboardImpl _clipboard;
//private IStorageProvider _storageProvider;
private IStorageProvider _storageProvider;

public TopLevelImpl(ITizenView view)
{
_view = view;

//_nativeControlHost = new NativeControlHostImpl(view);
//_storageProvider = new TizenStorageProvider();
_storageProvider = new TizenStorageProvider();
//_insetsManager = new InsetsManager(view);
//_insetsManager.DisplayEdgeToEdgeChanged += (sender, b) =>
//{
Expand Down Expand Up @@ -88,10 +88,10 @@ public void SetTransparencyLevelHint(IReadOnlyList<WindowTransparencyLevel> tran

public object? TryGetFeature(Type featureType)
{
//if (featureType == typeof(IStorageProvider))
//{
// return _storageProvider;
//}
if (featureType == typeof(IStorageProvider))
{
return _storageProvider;
}

if (featureType == typeof(ITextInputMethodImpl))
{
Expand Down

0 comments on commit c68b53f

Please sign in to comment.