Skip to content

Commit

Permalink
com.unity.mobile.notifications@1.4.3
Browse files Browse the repository at this point in the history
## [1.4.3] - 2022-04-15

### Fixes:
- [Android] [issue 101](Unity-Technologies/com.unity.mobile.notifications#101) Fix GC allocation every frame.
- [1360115](https://issuetracker.unity3d.com/issues/mobile-notifications-project-settings-window-loses-focus-when-clicking-on-any-category-while-mobile-notifications-pane-is-open) Fixed focus loss when trying to switching from notifications settings.
- [Android] [case 1376849] Fixed receivers needs to be marked as exported in manifest file, disable exact alarms on Android 12 because they require special permissions.
- [iOS] [1375744](https://issuetracker.unity3d.com/issues/ios-app-freezes-slash-crashes-when-both-mobile-notifications-and-firebase-are-used) Fixed application startup hang when application uses Unity notifications or Firebase.
- [iOS] [case 1382960] Handle numeric data in UserInfo.
- [iOS] Correctly handle boolean values in UserInfo, previously boolean values were detected as numbers and get parsed as 1 or 0, now they will be correctly handled as 'true' and 'false'.
  • Loading branch information
Unity Technologies committed Apr 15, 2022
1 parent 8b0c223 commit 2b12f3b
Show file tree
Hide file tree
Showing 21 changed files with 228 additions and 85 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

All notable changes to this package will be documented in this file.

## [1.4.3] - 2022-04-15

### Fixes:
- [Android] [issue 101](https://github.com/Unity-Technologies/com.unity.mobile.notifications/pull/101) Fix GC allocation every frame.
- [1360115](https://issuetracker.unity3d.com/issues/mobile-notifications-project-settings-window-loses-focus-when-clicking-on-any-category-while-mobile-notifications-pane-is-open) Fixed focus loss when trying to switching from notifications settings.
- [Android] [case 1376849] Fixed receivers needs to be marked as exported in manifest file, disable exact alarms on Android 12 because they require special permissions.
- [iOS] [1375744](https://issuetracker.unity3d.com/issues/ios-app-freezes-slash-crashes-when-both-mobile-notifications-and-firebase-are-used) Fixed application startup hang when application uses Unity notifications or Firebase.
- [iOS] [case 1382960] Handle numeric data in UserInfo.
- [iOS] Correctly handle boolean values in UserInfo, previously boolean values were detected as numbers and get parsed as 1 or 0, now they will be correctly handled as 'true' and 'false'.

## [1.4.2] - 2021-07-22

### Fixes:
Expand Down
3 changes: 2 additions & 1 deletion Editor/AndroidNotificationPostProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ internal static void InjectReceivers(string manifestPath, XmlDocument manifestXm

applicationXmlNode.AppendChild(notificationManagerReceiver);
}
notificationManagerReceiver.SetAttribute("exported", kAndroidNamespaceURI, "true");
notificationManagerReceiver.SetAttribute("exported", kAndroidNamespaceURI, "false");

// Create notification restart-on-boot receiver if necessary.
if (notificationRestartOnBootReceiver == null)
Expand All @@ -130,6 +130,7 @@ internal static void InjectReceivers(string manifestPath, XmlDocument manifestXm
applicationXmlNode.AppendChild(notificationRestartOnBootReceiver);
}
notificationRestartOnBootReceiver.SetAttribute("enabled", kAndroidNamespaceURI, "false");
notificationRestartOnBootReceiver.SetAttribute("exported", kAndroidNamespaceURI, "false");
}

internal static void AppendAndroidPermissionField(string manifestPath, XmlDocument xmlDoc, string name)
Expand Down
6 changes: 3 additions & 3 deletions Editor/NotificationSettingsManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -279,9 +279,9 @@ public Dictionary<string, byte[]> GenerateDrawableResourcesForExport()
var scale = drawableResource.Type == NotificationIconType.Small ? 0.375f : 1;

var textXhdpi = TextureAssetUtils.ScaleTexture(texture, (int)(128 * scale), (int)(128 * scale));
var textHdpi = TextureAssetUtils.ScaleTexture(texture, (int)(96 * scale), (int)(96 * scale));
var textMdpi = TextureAssetUtils.ScaleTexture(texture, (int)(64 * scale), (int)(64 * scale));
var textLdpi = TextureAssetUtils.ScaleTexture(texture, (int)(48 * scale), (int)(48 * scale));
var textHdpi = TextureAssetUtils.ScaleTexture(texture, (int)(96 * scale), (int)(96 * scale));
var textMdpi = TextureAssetUtils.ScaleTexture(texture, (int)(64 * scale), (int)(64 * scale));
var textLdpi = TextureAssetUtils.ScaleTexture(texture, (int)(48 * scale), (int)(48 * scale));

icons[string.Format("drawable-xhdpi-v11/{0}.png", drawableResource.Id)] = textXhdpi.EncodeToPNG();
icons[string.Format("drawable-hdpi-v11/{0}.png", drawableResource.Id)] = textHdpi.EncodeToPNG();
Expand Down
23 changes: 20 additions & 3 deletions Editor/NotificationSettingsProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using UnityEditorInternal;
using Unity.Notifications.iOS;
using UnityEngine.Assertions;
using UnityEngine.UIElements;

namespace Unity.Notifications
{
Expand All @@ -20,7 +21,7 @@ internal class NotificationSettingsProvider : SettingsProvider
private readonly GUIContent k_IdentifierLabelText = new GUIContent("Identifier");
private readonly GUIContent k_TypeLabelText = new GUIContent("Type");

private readonly string[] k_ToolbarStrings = {"Android", "iOS"};
private readonly string[] k_ToolbarStrings = { "Android", "iOS" };
private const string k_InfoStringAndroid =
"Only icons added to this list or manually added to the 'res/drawable' folder can be used for notifications.\n" +
"Note, that not all devices support colored icons.\n\n" +
Expand All @@ -47,10 +48,18 @@ static SettingsProvider CreateMobileNotificationsSettingsProvider()
return new NotificationSettingsProvider("Project/Mobile Notifications", SettingsScope.Project);
}

public override void OnActivate(string searchContext, VisualElement rootElement)
{
base.OnActivate(searchContext, rootElement);
// in case of domain reload (enter-exit play mode, this gets lost)
if (m_SettingsManager == null)
Initialize();
}

public override void OnDeactivate()
{
base.OnDeactivate();
m_SettingsManager.SaveSettings(false);
SettingsService.NotifySettingsProviderChanged();
}

private void Initialize()
Expand Down Expand Up @@ -212,6 +221,9 @@ private static Rect AddPadding(Rect rect, float horizontal, float vertical)

public override void OnGUI(string searchContext)
{
if (m_SettingsManager == null)
Initialize();

// This has to be called to sync all the changes between m_SettingsManager and m_SettingsManagerObject.
if (m_SettingsManagerObject.targetObject != null)
m_SettingsManagerObject.Update();
Expand All @@ -223,7 +235,12 @@ public override void OnGUI(string searchContext)

// Draw the toolbar for Android/iOS.
var toolBarRect = new Rect(totalRect.x, totalRect.y, totalRect.width, k_ToolbarHeight);
m_SettingsManager.ToolbarIndex = GUI.Toolbar(toolBarRect, m_SettingsManager.ToolbarIndex, k_ToolbarStrings);
var toolbarIndex = GUI.Toolbar(toolBarRect, m_SettingsManager.ToolbarIndex, k_ToolbarStrings);
if (toolbarIndex != m_SettingsManager.ToolbarIndex)
{
m_SettingsManager.ToolbarIndex = toolbarIndex;
m_SettingsManager.SaveSettings();
}

var notificationSettingsRect = new Rect(totalRect.x, k_ToolbarHeight + 2, totalRect.width, totalRect.height - k_ToolbarHeight - k_Padding);

Expand Down
2 changes: 1 addition & 1 deletion Editor/TextureAssetUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public static Texture2D ProcessTextureForType(Texture2D sourceTexture, Notificat
if (type == NotificationIconType.Small)
{
texture = new Texture2D(sourceTexture.width, sourceTexture.height, TextureFormat.RGBA32, true, false);
for (var i = 0; i < sourceTexture.mipmapCount; i++)
for (var i = 0; i < sourceTexture.mipmapCount; i++)
{
var c_0 = sourceTexture.GetPixels(i);
var c_1 = texture.GetPixels(i);
Expand Down
12 changes: 12 additions & 0 deletions Runtime/Android/AndroidNotification.cs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,9 @@ public DateTime CustomTimestamp
/// <summary>
/// Create a notification struct with all optional fields set to default values.
/// </summary>
/// <param name="title">Notification title</param>
/// <param name="text">Text to show on notification</param>
/// <param name="fireTime">Date and time when to show, can be DateTime.Now to show right away</param>
public AndroidNotification(string title, string text, DateTime fireTime)
{
Title = title;
Expand Down Expand Up @@ -214,6 +217,10 @@ public AndroidNotification(string title, string text, DateTime fireTime)
/// <summary>
/// Create a repeatable notification struct with all optional fields set to default values.
/// </summary>
/// <param name="title">Notification title</param>
/// <param name="text">Text to show on notification</param>
/// <param name="fireTime">Date and time when to show, can be DateTime.Now to show right away</param>
/// <param name="repeatInterval">Makes notification repeatable with this time interval</param>
/// <remarks>
/// There is a minimum period of 1 minute for repeating notifications.
/// </remarks>
Expand All @@ -226,6 +233,11 @@ public AndroidNotification(string title, string text, DateTime fireTime, TimeSpa
/// <summary>
/// Create a notification struct with a custom small icon and all optional fields set to default values.
/// </summary>
/// <param name="title">Notification title</param>
/// <param name="text">Text to show on notification</param>
/// <param name="fireTime">Date and time when to show, can be DateTime.Now to show right away</param>
/// <param name="repeatInterval">Makes notification repeatable with this time interval</param>
/// <param name="smallIcon">Name of the small icon to be shown on notification</param>
public AndroidNotification(string title, string text, DateTime fireTime, TimeSpan repeatInterval, string smallIcon)
: this(title, text, fireTime, repeatInterval)
{
Expand Down
2 changes: 1 addition & 1 deletion Runtime/Android/AndroidNotificationCallback.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public NotificationCallback() : base("com.unity.androidnotifications.Notificatio

public void onSentNotification(AndroidJavaObject notificationIntent)
{
AndroidReceivedNotificationMainThreadDispatcher.EnqueueReceivedNotification(notificationIntent);
AndroidReceivedNotificationMainThreadDispatcher.GetInstance().EnqueueReceivedNotification(notificationIntent);
}
}
}
23 changes: 22 additions & 1 deletion Runtime/Android/AndroidNotificationCenter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public class AndroidNotificationCenter
/// <summary>
/// Subscribe to this event to receive callbacks whenever a scheduled notification is shown to the user.
/// </summary>
public static event NotificationReceivedCallback OnNotificationReceived = delegate {};
public static event NotificationReceivedCallback OnNotificationReceived = delegate { };

private static AndroidJavaClass s_NotificationManagerClass;
private static AndroidJavaObject s_NotificationManager;
Expand All @@ -54,7 +54,9 @@ public class AndroidNotificationCenter

/// <summary>
/// Initialize the AndroidNotificationCenter class.
/// Can be safely called multiple times
/// </summary>
/// <returns>True if has been successfully initialized</returns>
public static bool Initialize()
{
if (s_Initialized)
Expand Down Expand Up @@ -93,6 +95,7 @@ public static bool Initialize()
/// On older Android versions settings set on the notification channel struct will still be applied to the notification
/// if they are supported to by the Android version the app is running on.
/// </summary>
/// <param name="channel">Channel parameters</param>
/// <remarks>
/// When a channel is deleted and recreated, all of the previous settings are restored. In order to change any settings
/// besides the name or description an entirely new channel (with a different channel ID) must be created.
Expand Down Expand Up @@ -133,6 +136,8 @@ public static void RegisterNotificationChannel(AndroidNotificationChannel channe
/// Returns the notification channel with the specified id.
/// The notification channel struct fields might not be identical to the channel struct used to initially register the channel if they were changed by the user.
/// </summary>
/// <param name="channelId">ID of the channel to retrieve</param>
/// <returns>Channel with given ID or empty struct if such channel does not exist</returns>
public static AndroidNotificationChannel GetNotificationChannel(string channelId)
{
return GetNotificationChannels().SingleOrDefault(channel => channel.Id == channelId);
Expand All @@ -141,6 +146,7 @@ public static AndroidNotificationChannel GetNotificationChannel(string channelId
/// <summary>
/// Returns all notification channels that were created by the app.
/// </summary>
/// <returns>All existing channels</returns>
public static AndroidNotificationChannel[] GetNotificationChannels()
{
if (!Initialize())
Expand Down Expand Up @@ -173,6 +179,7 @@ public static AndroidNotificationChannel[] GetNotificationChannels()
/// <summary>
/// Delete the specified notification channel.
/// </summary>
/// <param name="channelId">ID of the channel to delete</param>
public static void DeleteNotificationChannel(string channelId)
{
if (Initialize())
Expand All @@ -183,6 +190,9 @@ public static void DeleteNotificationChannel(string channelId)
/// Schedule a notification which will be shown at the time specified in the notification struct.
/// The returned id can later be used to update the notification before it's triggered, it's current status can be tracked using CheckScheduledNotificationStatus.
/// </summary>
/// <param name="notification">Data for the notification</param>
/// <param name="channelId">ID of the channel to send notification to</param>
/// <returns>The generated ID for the notification</returns>
public static int SendNotification(AndroidNotification notification, string channelId)
{
if (!Initialize())
Expand All @@ -198,6 +208,9 @@ public static int SendNotification(AndroidNotification notification, string chan
/// Schedule a notification which will be shown at the time specified in the notification struct.
/// The specified id can later be used to update the notification before it's triggered, it's current status can be tracked using CheckScheduledNotificationStatus.
/// </summary>
/// <param name="notification">Data for the notification</param>
/// <param name="channelId">ID of the channel to send notification to</param>
/// <param name="id">A unique ID for the notification</param>
public static void SendNotificationWithExplicitID(AndroidNotification notification, string channelId, int id)
{
if (Initialize())
Expand All @@ -208,6 +221,9 @@ public static void SendNotificationWithExplicitID(AndroidNotification notificati
/// Update an already scheduled notification.
/// If a notification with the specified id was already scheduled it will be overridden with the information from the passed notification struct.
/// </summary>
/// <param name="id">ID of the notification to update</param>
/// <param name="notification">Data for the notification</param>
/// <param name="channelId">ID of the channel to send notification to</param>
public static void UpdateScheduledNotification(int id, AndroidNotification notification, string channelId)
{
if (!Initialize())
Expand All @@ -221,6 +237,7 @@ public static void UpdateScheduledNotification(int id, AndroidNotification notif
/// Cancel a scheduled or previously shown notification.
/// The notification will no longer be displayed on it's scheduled time. If it's already delivered it will be removed from the status bar.
/// </summary>
/// <param name="id">ID of the notification to cancel</param>
public static void CancelNotification(int id)
{
if (!Initialize())
Expand All @@ -234,6 +251,7 @@ public static void CancelNotification(int id)
/// Cancel a scheduled notification.
/// The notification will no longer be displayed on it's scheduled time. It it will not be removed from the status bar if it's already delivered.
/// </summary>
/// <param name="id">ID of the notification to cancel</param>
public static void CancelScheduledNotification(int id)
{
if (Initialize())
Expand All @@ -244,6 +262,7 @@ public static void CancelScheduledNotification(int id)
/// Cancel a previously shown notification.
/// The notification will be removed from the status bar.
/// </summary>
/// <param name="id">ID of the notification to cancel</param>
public static void CancelDisplayedNotification(int id)
{
if (Initialize())
Expand Down Expand Up @@ -287,6 +306,8 @@ public static void CancelAllDisplayedNotifications()
/// Return the status of a scheduled notification.
/// Only available in API 23 and above.
/// </summary>
/// <param name="id">ID of the notification to check</param>
/// <returns>The status of the notification</returns>
public static NotificationStatus CheckScheduledNotificationStatus(int id)
{
if (!Initialize())
Expand Down
4 changes: 4 additions & 0 deletions Runtime/Android/AndroidNotificationChannel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ public bool Enabled
/// <summary>
/// Create a notification channel struct with all optional fields set to default values.
/// </summary>
/// <param name="id">ID for the channel</param>
/// <param name="name">Channel name</param>
/// <param name="description">Channel description</param>
/// <param name="importance">Importance of the channel</param>
public AndroidNotificationChannel(string id, string name, string description, Importance importance)
{
Id = id;
Expand Down
3 changes: 3 additions & 0 deletions Runtime/Android/AndroidNotificationIntentData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ public class AndroidNotificationIntentData
/// <summary>
/// Create an AndroidNotificationIntentData with AndroidNotification, id, and channel id.
/// </summary>
/// <param name="id">Notification id</param>
/// <param name="channelId">ID of the notification channel</param>
/// <param name="notification">Data of the received notification</param>
public AndroidNotificationIntentData(int id, string channelId, AndroidNotification notification)
{
Id = id;
Expand Down
23 changes: 13 additions & 10 deletions Runtime/Android/AndroidReceivedNotificationMainThreadDispatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ public class AndroidReceivedNotificationMainThreadDispatcher : MonoBehaviour
{
private static AndroidReceivedNotificationMainThreadDispatcher instance = null;

private static readonly Queue<AndroidJavaObject> s_ReceivedNotificationQueue = new Queue<AndroidJavaObject>();
private List<AndroidJavaObject> m_ReceivedNotificationQueue = new List<AndroidJavaObject>();

private static readonly List<AndroidJavaObject> s_ReceivedNotificationList = new List<AndroidJavaObject>();
private List<AndroidJavaObject> m_ReceivedNotificationList = new List<AndroidJavaObject>();

internal static void EnqueueReceivedNotification(AndroidJavaObject intent)
internal void EnqueueReceivedNotification(AndroidJavaObject intent)
{
lock (s_ReceivedNotificationQueue)
lock (this)
{
s_ReceivedNotificationQueue.Enqueue(intent);
m_ReceivedNotificationQueue.Add(intent);
}
}

Expand All @@ -34,18 +34,21 @@ public void Update()
{
// Note: Don't call callbacks while locking receivedNotificationQueue, otherwise there's a risk
// that callback might introduce an operations which would create a deadlock
lock (s_ReceivedNotificationQueue)
lock (this)
{
s_ReceivedNotificationList.AddRange(s_ReceivedNotificationQueue);
s_ReceivedNotificationQueue.Clear();
if (m_ReceivedNotificationQueue.Count == 0)
return;
var temp = m_ReceivedNotificationQueue;
m_ReceivedNotificationQueue = m_ReceivedNotificationList;
m_ReceivedNotificationList = temp;
}

foreach (var notification in s_ReceivedNotificationList)
foreach (var notification in m_ReceivedNotificationList)
{
AndroidNotificationCenter.ReceivedNotificationCallback(notification);
}

s_ReceivedNotificationList.Clear();
m_ReceivedNotificationList.Clear();
}

void Awake()
Expand Down
Loading

0 comments on commit 2b12f3b

Please sign in to comment.