Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/Core/src/PublicAPI/net-android/PublicAPI.Shipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3161,7 +3161,6 @@ virtual Microsoft.Maui.Handlers.ViewHandler<TVirtualView, TPlatformView>.Connect
virtual Microsoft.Maui.Handlers.ViewHandler<TVirtualView, TPlatformView>.DisconnectHandler(TPlatformView! platformView) -> void
virtual Microsoft.Maui.Handlers.ViewHandler<TVirtualView, TPlatformView>.SetVirtualView(Microsoft.Maui.IView! view) -> void
virtual Microsoft.Maui.ImageSourceService.LoadDrawableAsync(Microsoft.Maui.IImageSource! imageSource, Android.Widget.ImageView! imageView, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<Microsoft.Maui.IImageSourceServiceResult?>!
virtual Microsoft.Maui.MauiAppCompatActivity.AllowFragmentRestore.get -> bool
virtual Microsoft.Maui.MauiViewGroup.InputTransparent.get -> bool
virtual Microsoft.Maui.MauiViewGroup.InputTransparent.set -> void
virtual Microsoft.Maui.MauiViewGroup.MeasureAndLayout(int widthMeasureSpec, int heightMeasureSpec, int l, int t, int r, int b) -> void
Expand Down
1 change: 1 addition & 0 deletions src/Core/src/PublicAPI/net-android/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ static Microsoft.Maui.Platform.WebViewExtensions.UpdateUserAgent(this Android.We
Microsoft.Maui.WeakEventManager.HandleEvent(object? sender, object? args, string! eventName) -> void
static Microsoft.Maui.SizeRequest.operator !=(Microsoft.Maui.SizeRequest left, Microsoft.Maui.SizeRequest right) -> bool
static Microsoft.Maui.SizeRequest.operator ==(Microsoft.Maui.SizeRequest left, Microsoft.Maui.SizeRequest right) -> bool
virtual Microsoft.Maui.MauiAppCompatActivity.AllowFragmentRestore.get -> bool
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ public class MainActivity : MauiAppCompatActivity
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);

Microsoft.Maui.ApplicationModel.Platform.Init(this, bundle);
Microsoft.Maui.ApplicationModel.Platform.ActivityStateChanged += Platform_ActivityStateChanged;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
using System.IO;
using System.Threading.Tasks;
using System.Windows.Input;
using Microsoft.Maui.ApplicationModel;
using Microsoft.Maui.Controls;
using Microsoft.Maui.Media;
using Microsoft.Maui.Storage;

namespace Samples.ViewModel
{
#pragma warning disable CS0618
public class MediaPickerViewModel : BaseViewModel
{
string photoPath;
Expand Down Expand Up @@ -77,6 +79,8 @@ async void DoCapturePhoto()
{
try
{
if(await Permissions.RequestAsync<Permissions.Camera>() != PermissionStatus.Granted)
return;
var photo = await MediaPicker.CapturePhotoAsync();

await LoadPhotoAsync(photo);
Expand Down Expand Up @@ -173,4 +177,5 @@ public override void OnDisappearing()
base.OnDisappearing();
}
}
#pragma warning restore CS0618
}
2 changes: 2 additions & 0 deletions src/Essentials/src/Essentials.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
<Compile Include="**\*.android.*.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
<AndroidResource Include="Resources\xml\*.xml" />
<PackageReference Include="Xamarin.AndroidX.Browser" />
<PackageReference Include="Xamarin.AndroidX.Activity" Version="1.6.1.1" />
<PackageReference Include="Xamarin.AndroidX.AppCompat" Version="1.6.0.1" />
<PackageReference Include="Xamarin.AndroidX.Security.SecurityCrypto" />
<PackageReference Include="Xamarin.Google.Crypto.Tink.Android" />
</ItemGroup>
Expand Down
31 changes: 30 additions & 1 deletion src/Essentials/src/FileSystem/FileSystem.android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Threading.Tasks;
using Android.App;
using Android.Webkit;
using Microsoft.Maui.ApplicationModel;

namespace Microsoft.Maui.Storage
{
Expand Down Expand Up @@ -55,7 +56,7 @@ internal FileBase(Java.IO.File file)
{
}

string PlatformGetContentType(string extension) =>
internal string PlatformGetContentType(string extension) =>
MimeTypeMap.Singleton.GetMimeTypeFromExtension(extension.TrimStart('.'));

void PlatformInit(FileBase file)
Expand All @@ -68,4 +69,32 @@ internal virtual Task<Stream> PlatformOpenReadAsync()
return Task.FromResult<Stream>(stream);
}
}

public partial class MediaFileResult
{
readonly Android.Net.Uri _uri;
readonly string _tempFilePath;

internal MediaFileResult(string fileName, Android.Net.Uri uri, string tempFilePath = null)
{
_tempFilePath = tempFilePath;
_uri = uri;
NameWithoutExtension = Path.GetFileNameWithoutExtension(fileName);
Extension = Path.GetExtension(fileName).TrimStart('.');
ContentType = PlatformGetContentType(Extension);
Type = GetFileType(ContentType);
FileName = GetFileName(NameWithoutExtension, Extension);
}

internal override Task<Stream> PlatformOpenReadAsync()
=> Task.FromResult(Platform.AppContext.ContentResolver!.OpenInputStream(_uri));

void PlatformDispose()
{
if (!string.IsNullOrWhiteSpace(_tempFilePath) && File.Exists(_tempFilePath))
File.Delete(_tempFilePath);

_uri?.Dispose();
}
}
}
138 changes: 103 additions & 35 deletions src/Essentials/src/FileSystem/FileSystem.ios.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
using System.Linq;
using System.Threading.Tasks;
using Foundation;
using Photos;
using ImageIO;
using UIKit;
using OldUTType = MobileCoreServices.UTType;
using UTTypes = UniformTypeIdentifiers.UTTypes;

namespace Microsoft.Maui.Storage
{
Expand Down Expand Up @@ -158,68 +160,134 @@ protected override void Dispose(bool disposing)
}
}

class UIDocumentFileResult : FileResult
class UIDocumentFileResult : MediaFileResult
{
internal UIDocumentFileResult(NSUrl url)
: base()
UIDocument document;
NSUrl assetUrl;

internal UIDocumentFileResult(NSUrl assetUrl, string fileName)
{
var doc = new UIDocument(url);
FullPath = doc.FileUrl?.Path;
FileName = doc.LocalizedName ?? Path.GetFileName(FullPath);
this.assetUrl = assetUrl;
document = new UIDocument(assetUrl);
Extension = document.FileUrl.PathExtension!;
ContentType = GetMIMEType(document.FileType);
NameWithoutExtension = !string.IsNullOrWhiteSpace(fileName)
? Path.GetFileNameWithoutExtension(fileName)
: null;
Type = GetFileType(ContentType);
FileName = GetFileName(NameWithoutExtension, Extension);
}

internal override Task<Stream> PlatformOpenReadAsync()
{
Stream fileStream = File.OpenRead(FullPath);
=> Task.FromResult<Stream>(File.OpenRead(document.FileUrl.Path!));

return Task.FromResult(fileStream);
protected internal override void PlatformDispose()
{
document?.Dispose();
document = null;
assetUrl?.Dispose();
assetUrl = null;
base.PlatformDispose();
}
}

class UIImageFileResult : FileResult
class UIImageFileResult : MediaFileResult
{
readonly UIImage uiImage;
NSData data;
UIImage img;
NSDictionary metadata;
NSMutableData imgWithMetadata;

internal UIImageFileResult(UIImage image)
: base()
internal UIImageFileResult(UIImage img, NSDictionary metadata, string name)
{
uiImage = image;

FullPath = Guid.NewGuid().ToString() + FileExtensions.Png;
FileName = FullPath;
this.img = img;
this.metadata = metadata;
NameWithoutExtension = name;
#pragma warning disable CA1422
ContentType = GetMIMEType(OldUTType.JPEG);
Extension = GetExtension(OldUTType.JPEG);
#pragma warning restore CA1422
Type = GetFileType(ContentType);
FileName = GetFileName(NameWithoutExtension, Extension);
}

internal override Task<Stream> PlatformOpenReadAsync()
{
data ??= uiImage.AsPNG();
imgWithMetadata ??= GetImageWithMeta();
return Task.FromResult(imgWithMetadata?.AsStream());
}

return Task.FromResult(data.AsStream());
public NSMutableData GetImageWithMeta()
{
if (img == null || metadata == null)
return null;

using var source = CGImageSource.FromData(img.AsJPEG());
var destData = new NSMutableData();
using var destination = CGImageDestination.Create(destData, source.TypeIdentifier, 1, null);
destination.AddImage(source, 0, metadata);
destination.Close();
DisposeSources();
return destData;
}

protected internal override void PlatformDispose()
{
imgWithMetadata?.Dispose();
imgWithMetadata = null;
DisposeSources();
base.PlatformDispose();
}

void DisposeSources()
{
img?.Dispose();
img = null;
metadata?.Dispose();
metadata = null;
}
}

class PHAssetFileResult : FileResult
class PHPickerFileResult : MediaFileResult
{
readonly PHAsset phAsset;
readonly string identifier;
NSItemProvider provider;

internal PHAssetFileResult(NSUrl url, PHAsset asset, string originalFilename)
: base()
internal PHPickerFileResult(NSItemProvider provider)
{
phAsset = asset;
this.provider = provider;
NameWithoutExtension = provider?.SuggestedName;

identifier = GetIdentifier(provider?.RegisteredTypeIdentifiers);

FullPath = url?.AbsoluteString;
FileName = originalFilename;
if (string.IsNullOrWhiteSpace(identifier))
return;

Extension = GetExtension(identifier);
ContentType = GetMIMEType(identifier);
Type = GetFileType(ContentType);
FileName = GetFileName(NameWithoutExtension, Extension);
}

[System.Runtime.Versioning.UnsupportedOSPlatform("ios13.0")]
internal override Task<Stream> PlatformOpenReadAsync()
{
var tcsStream = new TaskCompletionSource<Stream>();
internal override async Task<Stream> PlatformOpenReadAsync()
=> (await provider?.LoadDataRepresentationAsync(identifier))?.AsStream();

PHImageManager.DefaultManager.RequestImageData(phAsset, null, new PHImageDataHandler((data, str, orientation, dict) =>
tcsStream.TrySetResult(data.AsStream())));
protected internal override void PlatformDispose()
{
provider?.Dispose();
provider = null;
base.PlatformDispose();
}

return tcsStream.Task;
private string GetIdentifier(string[] identifiers)
{
if (!(identifiers?.Length > 0))
return null;

if (identifiers.Any(i => i.StartsWith(UTTypes.LivePhoto.Identifier)) && identifiers.Contains(UTTypes.Jpeg.Identifier))
return identifiers.FirstOrDefault(i => i == UTTypes.Jpeg.Identifier);
if (identifiers.Contains(UTTypes.QuickTimeMovie.Identifier))
return identifiers.FirstOrDefault(i => i == UTTypes.QuickTimeMovie.Identifier);
return identifiers.FirstOrDefault();
}
}
}
30 changes: 30 additions & 0 deletions src/Essentials/src/FileSystem/FileSystem.ios.tvos.watchos.macos.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Foundation;
using OldUTType = MobileCoreServices.UTType;
using UTType = UniformTypeIdentifiers.UTType;
using UTTypes = UniformTypeIdentifiers.UTTypes;

namespace Microsoft.Maui.Storage
{
Expand Down Expand Up @@ -78,7 +82,33 @@ void PlatformInit(FileBase file)
{
}

#pragma warning disable CA1422
internal static string GetExtension(string identifier)
=> UTTypeISSupported()
? UTType.CreateFromIdentifier(identifier)!.PreferredFilenameExtension
: OldUTType.CopyAllTags(identifier, OldUTType.TagClassFilenameExtension)?.FirstOrDefault();

internal static string GetMIMEType(string identifier)
=> UTTypeISSupported()
? UTType.CreateFromIdentifier(identifier)!.PreferredMimeType
: OldUTType.CopyAllTags(identifier, OldUTType.TagClassMIMEType)?.FirstOrDefault();
#pragma warning restore CA1422

static bool UTTypeISSupported()
=> OperatingSystem.IsIOSVersionAtLeast(14)
|| OperatingSystem.IsMacOSVersionAtLeast(11)
|| OperatingSystem.IsMacCatalystVersionAtLeast(14)
|| OperatingSystem.IsWatchOSVersionAtLeast(14)
|| OperatingSystem.IsTvOSVersionAtLeast(14)
|| OperatingSystem.IsWatchOSVersionAtLeast(7);

internal virtual Task<Stream> PlatformOpenReadAsync() =>
Task.FromResult((Stream)File.OpenRead(FullPath));
}

public partial class MediaFileResult
{
/// <summary></summary>
protected internal virtual void PlatformDispose() { }
}
}
6 changes: 6 additions & 0 deletions src/Essentials/src/FileSystem/FileSystem.netstandard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,10 @@ internal virtual Task<Stream> PlatformOpenReadAsync()
void PlatformInit(FileBase file)
=> throw ExceptionUtils.NotSupportedOrImplementedException;
}

public partial class MediaFileResult
{
/// <summary></summary>
protected internal virtual void PlatformDispose() { }
}
}
Loading