EC-308 Fix crash produced by creating avatar image on AccountSwitchingOverlayHelper and also added more logging to see when it happens. (#1983)

This commit is contained in:
Federico Maccaroni 2022-07-07 16:24:29 -03:00 committed by GitHub
parent 7802da2b9c
commit 846d3a85a2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 8 deletions

View file

@ -1,4 +1,5 @@
using System.Threading.Tasks; using System;
using System.Threading.Tasks;
using Bit.App.Controls; using Bit.App.Controls;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Core.Utilities; using Bit.Core.Utilities;
@ -10,6 +11,8 @@ namespace Bit.iOS.Core.Utilities
{ {
public class AccountSwitchingOverlayHelper public class AccountSwitchingOverlayHelper
{ {
const string DEFAULT_SYSTEM_AVATAR_IMAGE = "person.2";
IStateService _stateService; IStateService _stateService;
IMessagingService _messagingService; IMessagingService _messagingService;
ILogger _logger; ILogger _logger;
@ -23,9 +26,22 @@ namespace Bit.iOS.Core.Utilities
public async Task<UIImage> CreateAvatarImageAsync() public async Task<UIImage> CreateAvatarImageAsync()
{ {
var avatarImageSource = new AvatarImageSource(await _stateService.GetNameAsync(), await _stateService.GetEmailAsync()); try
var avatarUIImage = await avatarImageSource.GetNativeImageAsync(); {
return avatarUIImage.ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal); if (_stateService is null)
{
throw new NullReferenceException(nameof(_stateService));
}
var avatarImageSource = new AvatarImageSource(await _stateService.GetNameAsync(), await _stateService.GetEmailAsync());
var avatarUIImage = await avatarImageSource.GetNativeImageAsync();
return avatarUIImage?.ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal) ?? UIImage.GetSystemImage(DEFAULT_SYSTEM_AVATAR_IMAGE);
}
catch (Exception ex)
{
_logger.Exception(ex);
return UIImage.GetSystemImage(DEFAULT_SYSTEM_AVATAR_IMAGE);
}
} }
public AccountSwitchingOverlayView CreateAccountSwitchingOverlayView(UIView containerView) public AccountSwitchingOverlayView CreateAccountSwitchingOverlayView(UIView containerView)

View file

@ -1,9 +1,9 @@
using System; using System;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Bit.Core.Services;
using UIKit; using UIKit;
using Xamarin.Forms; using Xamarin.Forms;
using Xamarin.Forms.Internals;
using Xamarin.Forms.Platform.iOS; using Xamarin.Forms.Platform.iOS;
namespace Bit.iOS.Core.Utilities namespace Bit.iOS.Core.Utilities
@ -17,25 +17,29 @@ namespace Bit.iOS.Core.Utilities
public static async Task<UIImage> GetNativeImageAsync(this ImageSource source, CancellationToken cancellationToken = default(CancellationToken)) public static async Task<UIImage> GetNativeImageAsync(this ImageSource source, CancellationToken cancellationToken = default(CancellationToken))
{ {
if (source == null || source.IsEmpty) if (source == null || source.IsEmpty)
{
return null; return null;
}
var handler = Xamarin.Forms.Internals.Registrar.Registered.GetHandlerForObject<IImageSourceHandler>(source); var handler = Xamarin.Forms.Internals.Registrar.Registered.GetHandlerForObject<IImageSourceHandler>(source);
if (handler == null) if (handler == null)
{
LoggerHelper.LogEvenIfCantBeResolved(new InvalidOperationException("GetNativeImageAsync failed cause IImageSourceHandler couldn't be found"));
return null; return null;
}
try try
{ {
float scale = (float)UIScreen.MainScreen.Scale; float scale = (float)UIScreen.MainScreen.Scale;
return await handler.LoadImageAsync(source, scale: scale, cancelationToken: cancellationToken); return await handler.LoadImageAsync(source, scale: scale, cancelationToken: cancellationToken);
} }
catch (OperationCanceledException) catch (OperationCanceledException)
{ {
Log.Warning("Image loading", "Image load cancelled"); LoggerHelper.LogEvenIfCantBeResolved(new OperationCanceledException("GetNativeImageAsync was cancelled"));
} }
catch (Exception ex) catch (Exception ex)
{ {
Log.Warning("Image loading", $"Image load failed: {ex}"); LoggerHelper.LogEvenIfCantBeResolved(new InvalidOperationException("GetNativeImageAsync failed", ex));
} }
return null; return null;