Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Tizen] Update resizetizer for Tizen #8298

Closed
wants to merge 7 commits into from
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
39 changes: 36 additions & 3 deletions .nuspec/Microsoft.Maui.Resizetizer.targets
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@
AssemblyFile="$(_ResizetizerTaskAssemblyName)"
TaskName="Microsoft.Maui.Resizetizer.GeneratePackageAppxManifest" />

<UsingTask
AssemblyFile="$(_ResizetizerTaskAssemblyName)"
TaskName="Microsoft.Maui.Resizetizer.GenerateTizenManifest" />

<PropertyGroup>
<CleanDependsOn>
$(CleanDependsOn);
Expand Down Expand Up @@ -93,7 +97,7 @@
<_ResizetizerIsiOSApp Condition="( '$(_ResizetizerPlatformIsiOS)' == 'True' OR '$(_ResizetizerPlatformIsMacCatalyst)' == 'True' ) And ('$(OutputType)' == 'Exe' Or '$(IsAppExtension)' == 'True')">True</_ResizetizerIsiOSApp>
<_ResizetizerIsWPFApp Condition="'$(IsApplication)' == 'True' And '$(NuGetRuntimeIdentifier)' == 'win' And '$(_ResizetizerPlatformIsWindows)' == 'True'">True</_ResizetizerIsWPFApp>
<_ResizetizerIsWindowsAppSdk Condition="('$(ProjectReunionWinUI)'=='True' Or '$(WindowsAppSDKWinUI)'=='True') And '$(_ResizetizerPlatformIsWindows)' == 'True' And ('$(OutputType)' == 'WinExe' Or '$(OutputType)' == 'Exe')">True</_ResizetizerIsWindowsAppSdk>
<_ResizetizerIsTizenApp Condition="'$(_ResizetizerPlatformIsTizen)' == 'True'">True</_ResizetizerIsTizenApp>
<_ResizetizerIsTizenApp Condition="'$(_ResizetizerPlatformIsTizen)' == 'True' And ( '$(OutputType)' == 'Exe' )">True</_ResizetizerIsTizenApp>
</PropertyGroup>

<PropertyGroup Condition="'$(_ResizetizerIsAndroidApp)' == 'True' Or '$(_ResizetizerIsiOSApp)' == 'True' Or '$(_ResizetizerIsWPFApp)' == 'True' Or '$(_ResizetizerIsWindowsAppSdk)' == 'True' Or '$(_ResizetizerIsTizenApp)' == 'True'">
Expand Down Expand Up @@ -393,7 +397,7 @@
<FileWrites Include="@(_MauiSplashAssets)" />
</ItemGroup>

<!-- Tizen -->
<!-- Tizen -->
<ItemGroup Condition="'$(_ResizetizerIsTizenApp)' == 'True'">
<MauiImage Include="@(MauiSplashScreen)" />
</ItemGroup>
Expand Down Expand Up @@ -528,7 +532,6 @@
<TizenSplashUpdater
Condition="'$(_ResizetizerIsTizenApp)' == 'True' And '@(MauiSplashScreen)' != ''"
IntermediateOutputPath="$(_MauiIntermediateImages)"
ManifestFile="$(TizenManifestFile)"
MauiSplashScreen="@(MauiSplashScreen)" />

<ItemGroup>
Expand Down Expand Up @@ -677,6 +680,36 @@

</Target>

<Target Name="MauiGenerateTizenManifest"
Condition="'$(_ResizetizerIsTizenApp)' == 'True'"
BeforeTargets="$(ResizetizeBeforeTargets)"
AfterTargets="$(ResizetizeImages)"
Inputs="$(MSBuildThisFileFullPath);$(_ResizetizerTaskAssemblyName);$(_ResizetizerInputsFile);$(_MauiSplashInputsFile);$(TizenManifestFile)"
Outputs="$(_MauiManifestStampFile);$(_MauiIntermediateManifest)tizen-manifest.xml">

<GenerateTizenManifest
IntermediateOutputPath="$(_MauiIntermediateManifest)"
TizenManifestFile="$(TizenManifestFile)"
GeneratedFilename="tizen-manifest.xml"
ApplicationId="$(ApplicationId)"
ApplicationDisplayVersion="$(ApplicationDisplayVersion)"
ApplicationVersion="$(ApplicationVersion)"
ApplicationTitle="$(ApplicationTitle)"
AppIcon="@(MauiImage->WithMetadataValue('IsAppIcon', 'true'))"
SplashScreen="@(MauiSplashScreen)" />

<!-- replace user manifest -->
<PropertyGroup>
<TizenManifestFile>$(_MauiIntermediateManifest)tizen-manifest.xml</TizenManifestFile>
</PropertyGroup>

<!-- Stamp file for Outputs -->
<Touch Files="$(_MauiManifestStampFile)" AlwaysCreate="True" />
<ItemGroup>
<FileWrites Include="$(_MauiManifestStampFile)" />
</ItemGroup>
</Target>

<!-- This is required because the "GetAssemblyAttributes" target does not have an open DependsOnTargets. -->
<Target Name="_GetAssemblyAttributesBeforeTarget"
BeforeTargets="GetAssemblyAttributes"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.microsoft.maui.singleproject" version="1.0.0" api-version="7" xmlns="http://tizen.org/ns/packages">
<manifest package="maui-application-id-placeholder" version="0.0.0" api-version="7" xmlns="http://tizen.org/ns/packages">
<profile name="common" />
<ui-application appid="com.microsoft.maui.singleproject" exec="Maui.Controls.Sample.dll" multiple="false" nodisplay="false" taskmanage="true" type="dotnet" launch_mode="single">
<label>SingleProject</label>
<icon>appicon.xhigh.png</icon>
<ui-application appid="maui-application-id-placeholder" exec="Maui.Controls.Sample.dll" multiple="false" nodisplay="false" taskmanage="true" type="dotnet" launch_mode="single">
<label>maui-application-title-placeholder</label>
<icon>maui-appicon-placeholder</icon>
<metadata key="http://tizen.org/metadata/prefer_dotnet_aot" value="true" />
<splash-screens>
<splash-screen src="splash/appicon_foreground.ldpi.png" type="img" dpi="ldpi" orientation="portrait" indicator-display="false" app-control-operation="http://tizen.org/appcontrol/operation/default" />
<splash-screen src="splash/appicon_foreground.ldpi.png" type="img" dpi="ldpi" orientation="landscape" indicator-display="false" app-control-operation="http://tizen.org/appcontrol/operation/default" />
<splash-screen src="splash/appicon_foreground.mdpi.png" type="img" dpi="mdpi" orientation="portrait" indicator-display="false" app-control-operation="http://tizen.org/appcontrol/operation/default" />
<splash-screen src="splash/appicon_foreground.mdpi.png" type="img" dpi="mdpi" orientation="landscape" indicator-display="false" app-control-operation="http://tizen.org/appcontrol/operation/default" />
<splash-screen src="splash/appicon_foreground.hdpi.png" type="img" dpi="hdpi" orientation="portrait" indicator-display="false" app-control-operation="http://tizen.org/appcontrol/operation/default" />
<splash-screen src="splash/appicon_foreground.hdpi.png" type="img" dpi="hdpi" orientation="landscape" indicator-display="false" app-control-operation="http://tizen.org/appcontrol/operation/default" />
<splash-screen src="splash/appicon_foreground.xhdpi.png" type="img" dpi="xhdpi" orientation="portrait" indicator-display="false" app-control-operation="http://tizen.org/appcontrol/operation/default" />
<splash-screen src="splash/appicon_foreground.xhdpi.png" type="img" dpi="xhdpi" orientation="landscape" indicator-display="false" app-control-operation="http://tizen.org/appcontrol/operation/default" />
<splash-screen src="splash/appicon_foreground.xxhdpi.png" type="img" dpi="xxhdpi" orientation="portrait" indicator-display="false" app-control-operation="http://tizen.org/appcontrol/operation/default" />
<splash-screen src="splash/appicon_foreground.xxhdpi.png" type="img" dpi="xxhdpi" orientation="landscape" indicator-display="false" app-control-operation="http://tizen.org/appcontrol/operation/default" />
</splash-screens>
<splash-screens />
</ui-application>
<shortcut-list />
<dependencies />
<provides-appdefined-privileges />
<privileges>
<privilege>http://tizen.org/privilege/internet</privilege>
</privileges>
</manifest>
</manifest>
237 changes: 237 additions & 0 deletions src/SingleProject/Resizetizer/src/GenerateTizenManifest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
#nullable enable
using System;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

namespace Microsoft.Maui.Resizetizer
{
public class GenerateTizenManifest : Task
{
const string ApplicationIdPlaceholder = "maui-application-id-placeholder";
const string LabelPlaceholder = "maui-application-title-placeholder";
const string ManifestVersionPlaceholder = "0.0.0";
const string AppIconPlaceholder = "maui-appicon-placeholder";
const string TizenManifestFileName = "tizen-manifest.xml";
const string IconDefaultDpiType = "xhdpi";
const string IconImageExtension = ".png";
const string UiApplicationName = "ui-application";
const string PackageName = "package";
const string AppidName = "appid";
const string VersionName = "version";
const string LabelName = "label";
const string IconName = "icon";
const string SplashScreensName = "splash-screens";
const string SplashScreenName = "splash-screen";
const string DpiName = "dpi";

[Required]
public string IntermediateOutputPath { get; set; } = null!;

[Required]
public string TizenManifestFile { get; set; } = TizenManifestFileName;

public string GeneratedFilename { get; set; } = TizenManifestFileName;

public string? ApplicationId { get; set; }

public string? ApplicationDisplayVersion { get; set; }

public string? ApplicationVersion { get; set; }

public string? ApplicationTitle { get; set; }

public ITaskItem[]? AppIcon { get; set; }

public ITaskItem[]? SplashScreen { get; set; }

[Output]
public ITaskItem GeneratedTizenManifest { get; set; } = null!;

string? _tizenManifestFilePath;

public override bool Execute()
{
try
{
Directory.CreateDirectory(IntermediateOutputPath);

_tizenManifestFilePath = Path.Combine(Environment.CurrentDirectory, TizenManifestFile);

var targetFilename = Path.Combine(IntermediateOutputPath, GeneratedFilename);

var manifest = XDocument.Load(_tizenManifestFilePath);

UpdateManifest(manifest);

manifest.Save(targetFilename);

GeneratedTizenManifest = new TaskItem(targetFilename);
}
catch (Exception ex)
{
Log.LogErrorFromException(ex);
}

return !Log.HasLoggedErrors;
}

void UpdateManifest(XDocument tizenManifest)
{
var xmlns = tizenManifest.Root!.GetDefaultNamespace();
var manifest = tizenManifest.Root;
var uiApplication = manifest.Element(xmlns + UiApplicationName);

if (manifest == null || uiApplication == null)
{
return;
}

UpdateSharedManifest(xmlns, manifest);

UpdateSharedResources(xmlns, manifest);
}

void UpdateSharedManifest(XNamespace xmlns ,XElement manifest)
{
var uiApplication = manifest.Element(xmlns + UiApplicationName);

if (!string.IsNullOrEmpty(ApplicationId))
{
UpdateElementAttribute(manifest, PackageName, ApplicationId, ApplicationIdPlaceholder);
UpdateElementAttribute(uiApplication, AppidName, ApplicationId, ApplicationIdPlaceholder);
}

if (!string.IsNullOrEmpty(ApplicationDisplayVersion))
{
if (TryMergeVersionNumbers(ApplicationDisplayVersion, out var finalVersion))
{
UpdateElementAttribute(manifest, VersionName, finalVersion, ManifestVersionPlaceholder);
}
else
{
Log.LogWarning($"ApplicationDisplayVersion '{ApplicationDisplayVersion}' was not a valid version for Tizen");
}

}

if (!string.IsNullOrEmpty(ApplicationTitle))
{
var label = uiApplication.Element(xmlns + LabelName);
if (label == null)
{
label = new XElement(xmlns + LabelName);
uiApplication.AddFirst(label);
}
UpdateElementValue(label, ApplicationTitle, LabelPlaceholder);
}
}

void UpdateSharedResources(XNamespace xmlns, XElement manifestElement)
{
var uiApplicationElement = manifestElement.Element(xmlns + UiApplicationName);
var appIconInfo = AppIcon?.Length > 0 ? ResizeImageInfo.Parse(AppIcon[0]) : null;

if (appIconInfo != null)
{
var xiconName = xmlns + IconName;
var iconElements = uiApplicationElement.Elements(xiconName);

var iconPlaceholderElements = iconElements.Where(d => d.Value == AppIconPlaceholder);
foreach (var icon in iconPlaceholderElements)
{
if (icon.Attribute(DpiName) == null)
{
var defaultDpi = DpiPath.Tizen.AppIcon.Where(n => n.Path.EndsWith(IconDefaultDpiType)).FirstOrDefault();
icon.Value = IconDefaultDpiType + "/" + appIconInfo.OutputName + defaultDpi.FileSuffix + IconImageExtension;
}
else
{
string dpiValue = icon.Attribute(DpiName).Value;
string fileSuffix = dpiValue == IconDefaultDpiType ? "xhigh" : "high";
icon.Value = dpiValue + "/" + appIconInfo.OutputName + fileSuffix + IconImageExtension;
}
}
}
var splashInfo = SplashScreen?.Length > 0 ? ResizeImageInfo.Parse(SplashScreen[0]) : null;

if (splashInfo != null)
{
var splashscreensElement = uiApplicationElement.Element(xmlns + SplashScreensName);
if (splashscreensElement == null)
{
splashscreensElement = new XElement(xmlns + SplashScreensName);
uiApplicationElement.Add(splashscreensElement);
}

foreach (var image in TizenSplashUpdater.splashDpiMap)
{
var splashElements = splashscreensElement.Elements(xmlns + SplashScreenName).Where(
d => d.Attribute("type")?.Value == "img"
&& d.Attribute(DpiName)?.Value == image.Key.Resolution
&& d.Attribute("orientation")?.Value == image.Key.Orientation
&& d.Attribute("indicator-display")?.Value == "false");
if (splashElements.Count() == 0)
{
var splashscreenElement = new XElement(xmlns + SplashScreenName);
splashscreenElement.SetAttributeValue("src", image.Value);
splashscreenElement.SetAttributeValue("type", "img");
splashscreenElement.SetAttributeValue(DpiName, image.Key.Resolution);
splashscreenElement.SetAttributeValue("orientation", image.Key.Orientation);
splashscreenElement.SetAttributeValue("indicator-display", "false");
splashscreensElement.Add(splashscreenElement);
}
}
}
}

void UpdateElementAttribute(XElement element, XName attrName, string? value, string? placeholder)
{
var attr = element.Attribute(attrName);
if (attr == null || string.IsNullOrEmpty(attr.Value) || attr.Value == placeholder)
{
element.SetAttributeValue(attrName, value);
}
}

void UpdateElementValue(XElement element, string? value, string? placeholder)
{
if (string.IsNullOrEmpty(element.Value) || element.Value == placeholder)
{
element.Value = value;
}
}

public static bool TryMergeVersionNumbers(string? displayVersion, out string? finalVersion)
{
displayVersion = displayVersion?.Trim();
finalVersion = null;

var parts = displayVersion?.Split('.') ?? Array.Empty<string>();
if (parts.Length > 3)
return false;

var v = new int[3];
for (var i = 0; i < 3 && i < parts.Length; i++)
{
if (!int.TryParse(parts[i], out var parsed))
return false;

v[i] = parsed;
}

if (!VerifyTizenVersion(v[0], v[1], v[2]))
return false;

finalVersion = $"{v[0]:0}.{v[1]:0}.{v[2]:0}";
return true;
}

static bool VerifyTizenVersion(int x, int y, int z)
{
return (x < 0 || x > 255 || y < 0 || y > 255 || z < 0 || z > 65535) ? false : true;
}
}
}
5 changes: 0 additions & 5 deletions src/SingleProject/Resizetizer/src/ResizetizeImages.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,6 @@ void ProcessAppIcon(ResizeImageInfo img, ConcurrentBag<ResizedImageInfo> resized

resizedImages.Add(windowsIconGen.Generate());
}
else if (PlatformType == "tizen")
{
var updator = new TizenIconManifestUpdater(appIconName, appIconDpis, this);
updator.Update();
}

LogDebugMessage($"Generating App Icon Bitmaps for DPIs");

Expand Down
Loading