Files
UnrealEngineUWP/Engine/Source/Developer/Android/AndroidPlatformEditor/Private/AndroidTargetSettingsCustomization.cpp
Peter Sauerbrei 865909dbbb Copying //UE4/Dev-Mobile to Dev-Main (//UE4/Dev-Main) @2911599
#lockdown nick.penwarden

==========================
MAJOR FEATURES + CHANGES
==========================

Change 2854295 on 2016/02/03 by Gareth.Martin@gareth.martin

	Added support for Landscape grass to use the landscape's light/shadow maps
	(original github pull request #1798 by Frugality)

Change 2875167 on 2016/02/21 by Rolando.Caloca@Home_DM

	DM - glslang

Change 2875650 on 2016/02/22 by Rolando.Caloca@rolando.caloca_T3903_DM

	DM - Common RHI changes

Change 2876429 on 2016/02/22 by Rolando.Caloca@rolando.caloca_T3903_DM

	DM - Initial rhi check-in. Tappy & SunTemple working on PC.
	#codereview Jack.Porter, Chris.Babcock, Josh.Adams

Change 2876665 on 2016/02/22 by Rolando.Caloca@rolando.caloca_T3903_DM

	DM - Split Immediate command list off RHI

Change 2881242 on 2016/02/25 by Jack.Porter@Jack.Porter_UE4_Stream

	changes to exclude LPV shaders from Vulkan
	(reapplied with edit instead of integrate records)

Change 2881356 on 2016/02/25 by Jack.Porter@Jack.Porter_UE4_Stream

	Static shadowing + dynamic-object CSM

Change 2881359 on 2016/02/25 by Jack.Porter@Jack.Porter_UE4_Stream

	Mobile GPU particles

Change 2881360 on 2016/02/25 by Jack.Porter@Jack.Porter_UE4_Stream

	Planar reflections very WIP

Change 2881363 on 2016/02/25 by Jack.Porter@Jack.Porter_UE4_Stream

	Separate Translucency very WIP

Change 2881365 on 2016/02/25 by Jack.Porter@Jack.Porter_UE4_Stream

	ProtoStar engine changes

Change 2881371 on 2016/02/25 by Jack.Porter@Jack.Porter_UE4_Stream

	HACK for Max Texture Samplers hardcoded to 8 on ES2
	Should be cleaned up better with UE-24419.
Change 2884295 on 2016/02/26 by Rolando.Caloca@rolando.caloca_T3903_DM

	DM - Integrate pipeline cache

Change 2887043 on 2016/02/29 by Rolando.Caloca@Home_DM

	DM - Initial CCT support

Change 2887572 on 2016/03/01 by Rolando.Caloca@rolando.caloca_T3903_DM

	DM - Empty bound shader states cache
	- Only used currently on Vulkan

Change 2889114 on 2016/03/01 by Rolando.Caloca@Home_DM

	DM - Added GRHINeedsExtraDeletionLatency from 4.11

Change 2889115 on 2016/03/01 by Rolando.Caloca@Home_DM

	DM - Remove batched elements quads (was not been used at least since UE3!)

Change 2895373 on 2016/03/04 by Rolando.Caloca@rolando.caloca_T3903_DM

	DM - Fence mgr (disabled)

Change 2898926 on 2016/03/08 by Rolando.Caloca@rolando.caloca_T3903_DM

	DM - Resource management (disabled)

Change 2899937 on 2016/03/08 by Rolando.Caloca@rolando.caloca_T3903_DM

	DM - Expand number of stencil op bits

Change 2901132 on 2016/03/09 by Rolando.Caloca@rolando.caloca_T3903_DM

	DM - Add support for more MaxSimultaneousRenderTargets

Change 2903074 on 2016/03/10 by Rolando.Caloca@rolando.caloca_T3903_DM

	DM - Support for 3d staging textures

Change 2903211 on 2016/03/10 by Jack.Porter@Jack.Porter_UE4_Stream

	Vulkan RHI stub for new SharedResourceView RHI call

Change 2904014 on 2016/03/10 by Rolando.Caloca@rolando.caloca_T3903_DM

	DM - SM4 preq

Change 2905389 on 2016/03/11 by Jack.Porter@Jack.Porter_UE4_Stream

	Android Vulkan support initial checkin

Change 2908458 on 2016/03/14 by Allan.Bentham@Dev-Mobile

	Reinstate vertex fog, fixes UE-28166

Change 2910294 on 2016/03/15 by Rolando.Caloca@rolando.caloca_T3903_DM

	DM - Use fence manager

Change 2910801 on 2016/03/15 by Rolando.Caloca@rolando.caloca_T3903_DM

	DM - Descriptor pool

[CL 2912606 by Peter Sauerbrei in Main branch]
2016-03-16 21:16:51 -04:00

420 lines
18 KiB
C++

// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
#include "AndroidPlatformEditorPrivatePCH.h"
#include "AndroidTargetSettingsCustomization.h"
#include "DetailLayoutBuilder.h"
#include "DetailCategoryBuilder.h"
#include "PropertyEditing.h"
#include "ScopedTransaction.h"
#include "SExternalImageReference.h"
#include "SHyperlinkLaunchURL.h"
#include "SPlatformSetupMessage.h"
#include "PlatformIconInfo.h"
#include "SourceControlHelpers.h"
#include "ManifestUpdateHelper.h"
#include "SNotificationList.h"
#include "NotificationManager.h"
#include "EngineBuildSettings.h"
#define LOCTEXT_NAMESPACE "AndroidRuntimeSettings"
//////////////////////////////////////////////////////////////////////////
// FAndroidTargetSettingsCustomization
namespace FAndroidTargetSettingsCustomizationConstants
{
const FText DisabledTip = LOCTEXT("GitHubSourceRequiredToolTip", "This requires GitHub source.");
}
TSharedRef<IDetailCustomization> FAndroidTargetSettingsCustomization::MakeInstance()
{
return MakeShareable(new FAndroidTargetSettingsCustomization);
}
FAndroidTargetSettingsCustomization::FAndroidTargetSettingsCustomization()
: AndroidRelativePath(TEXT(""))
, EngineAndroidPath(FPaths::EngineDir() + TEXT("Build/Android/Java"))
, GameAndroidPath(FPaths::GameDir() + TEXT("Build/Android"))
, EngineGooglePlayAppIDPath(EngineAndroidPath / TEXT("res") / TEXT("values") / TEXT("GooglePlayAppID.xml"))
, GameGooglePlayAppIDPath(GameAndroidPath / TEXT("res") / TEXT("values") / TEXT("GooglePlayAppID.xml"))
, EngineProguardPath(EngineAndroidPath / TEXT("proguard-project.txt"))
, GameProguardPath(GameAndroidPath / TEXT("proguard-project.txt"))
, EngineProjectPropertiesPath(EngineAndroidPath / TEXT("project.properties"))
, GameProjectPropertiesPath(GameAndroidPath / TEXT("project.properties"))
{
new (IconNames) FPlatformIconInfo(TEXT("res/drawable/icon.png"), LOCTEXT("SettingsIcon", "Icon"), FText::GetEmpty(), 48, 48, FPlatformIconInfo::Required);
new (IconNames) FPlatformIconInfo(TEXT("res/drawable-ldpi/icon.png"), LOCTEXT("SettingsIcon_LDPI", "LDPI Icon"), FText::GetEmpty(), 36, 36, FPlatformIconInfo::Required);
new (IconNames) FPlatformIconInfo(TEXT("res/drawable-mdpi/icon.png"), LOCTEXT("SettingsIcon_MDPI", "MDPI Icon"), FText::GetEmpty(), 48, 48, FPlatformIconInfo::Required);
new (IconNames) FPlatformIconInfo(TEXT("res/drawable-hdpi/icon.png"), LOCTEXT("SettingsIcon_HDPI", "HDPI Icon"), FText::GetEmpty(), 72, 72, FPlatformIconInfo::Required);
new (IconNames) FPlatformIconInfo(TEXT("res/drawable-xhdpi/icon.png"), LOCTEXT("SettingsIcon_XHDPI", "XHDPI Icon"), FText::GetEmpty(), 96, 96, FPlatformIconInfo::Required);
new (LaunchImageNames)FPlatformIconInfo(TEXT("res/drawable/downloadimagev.png"), LOCTEXT("SettingsIcon_DownloadImageV", "Download Background Vertical Image"), FText::GetEmpty(), 720, 1280, FPlatformIconInfo::Required);
new (LaunchImageNames)FPlatformIconInfo(TEXT("res/drawable/splashscreen_portrait.png"), LOCTEXT("LaunchImage_Portrait", "Launch Portrait"), FText::GetEmpty(), 360, 640, FPlatformIconInfo::Required);
new (LaunchImageNames)FPlatformIconInfo(TEXT("res/drawable/splashscreen_landscape.png"), LOCTEXT("LaunchImage_Landscape", "Launch Landscape"), FText::GetEmpty(), 640, 360, FPlatformIconInfo::Required);
}
void FAndroidTargetSettingsCustomization::CustomizeDetails(IDetailLayoutBuilder& DetailLayout)
{
SavedLayoutBuilder = &DetailLayout;
BuildAppManifestSection(DetailLayout);
BuildIconSection(DetailLayout);
BuildLaunchImageSection(DetailLayout);
}
static void OnBrowserLinkClicked(const FSlateHyperlinkRun::FMetadata& Metadata)
{
const FString* URL = Metadata.Find(TEXT("href"));
if(URL)
{
FPlatformProcess::LaunchURL(**URL, nullptr, nullptr);
}
}
void FAndroidTargetSettingsCustomization::BuildAppManifestSection(IDetailLayoutBuilder& DetailLayout)
{
// Cache some categories
IDetailCategoryBuilder& APKPackagingCategory = DetailLayout.EditCategory(TEXT("APKPackaging"));
IDetailCategoryBuilder& BuildCategory = DetailLayout.EditCategory(TEXT("Build"));
IDetailCategoryBuilder& SigningCategory = DetailLayout.EditCategory(TEXT("DistributionSigning"));
TSharedRef<SPlatformSetupMessage> PlatformSetupMessage = SNew(SPlatformSetupMessage, GameProjectPropertiesPath)
.PlatformName(LOCTEXT("AndroidPlatformName", "Android"))
.OnSetupClicked(this, &FAndroidTargetSettingsCustomization::CopySetupFilesIntoProject);
SetupForPlatformAttribute = PlatformSetupMessage->GetReadyToGoAttribute();
APKPackagingCategory.AddCustomRow(LOCTEXT("Warning", "Warning"), false)
.WholeRowWidget
[
PlatformSetupMessage
];
APKPackagingCategory.AddCustomRow(LOCTEXT("UpgradeInfo", "Upgrade Info"), false)
.WholeRowWidget
[
SNew(SBorder)
.Padding(1)
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.Padding(FMargin(10, 10, 10, 10))
.FillWidth(1.0f)
[
SNew(SRichTextBlock)
.Text(LOCTEXT("UpgradeInfoMessage", "<RichTextBlock.TextHighlight>Note to users from 4.6 or earlier</>: We now <RichTextBlock.TextHighlight>GENERATE</> an AndroidManifest.xml when building, so if you have customized your .xml file, you will need to put all of your changes into the below settings. Note that we don't touch your AndroidManifest.xml that is in your project directory.\nAdditionally, we no longer use SigningConfig.xml, the settings are now set in the Distribution Signing section."))
.TextStyle(FEditorStyle::Get(), "MessageLog")
.DecoratorStyleSet(&FEditorStyle::Get())
.AutoWrapText(true)
+ SRichTextBlock::HyperlinkDecorator(TEXT("browser"), FSlateHyperlinkRun::FOnClick::CreateStatic(&OnBrowserLinkClicked))
]
]
];
APKPackagingCategory.AddCustomRow(LOCTEXT("BuildFolderLabel", "Build Folder"), false)
.IsEnabled(SetupForPlatformAttribute)
.NameContent()
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.Padding(FMargin(0, 1, 0, 1))
.FillWidth(1.0f)
[
SNew(STextBlock)
.Text(LOCTEXT("BuildFolderLabel", "Build Folder"))
.Font(DetailLayout.GetDetailFont())
]
]
.ValueContent()
[
SNew(SHorizontalBox)
+SHorizontalBox::Slot()
.AutoWidth()
[
SNew(SButton)
.Text(LOCTEXT("OpenBuildFolderButton", "Open Build Folder"))
.ToolTipText(LOCTEXT("OpenManifestFolderButton_Tooltip", "Opens the folder containing the build files in Explorer or Finder (it's recommended you check these in to source control to share with your team)"))
.OnClicked(this, &FAndroidTargetSettingsCustomization::OpenBuildFolder)
]
];
// Signing category
SigningCategory.AddCustomRow(LOCTEXT("SigningHyperlink", "Signing Hyperlink"), false)
.WholeRowWidget
[
SNew(SBox)
.HAlign(HAlign_Center)
[
SNew(SHyperlinkLaunchURL, TEXT("http://developer.android.com/tools/publishing/app-signing.html#releasemode"))
.Text(LOCTEXT("AndroidDeveloperSigningPage", "Android Developer page on Signing for Distribution"))
.ToolTipText(LOCTEXT("AndroidDeveloperSigningPageTooltip", "Opens a page that discusses the signing using keytool"))
]
];
// Google Play category
IDetailCategoryBuilder& GooglePlayCategory = DetailLayout.EditCategory(TEXT("GooglePlayServices"));
TSharedRef<SPlatformSetupMessage> GooglePlaySetupMessage = SNew(SPlatformSetupMessage, GameGooglePlayAppIDPath)
.PlatformName(LOCTEXT("GooglePlayPlatformName", "Google Play services"))
.OnSetupClicked(this, &FAndroidTargetSettingsCustomization::CopyGooglePlayAppIDFileIntoProject);
SetupForGooglePlayAttribute = GooglePlaySetupMessage->GetReadyToGoAttribute();
GooglePlayCategory.AddCustomRow(LOCTEXT("Warning", "Warning"), false)
.WholeRowWidget
[
GooglePlaySetupMessage
];
GooglePlayCategory.AddCustomRow(LOCTEXT("AppIDHyperlink", "App ID Hyperlink"), false)
.WholeRowWidget
[
SNew(SBox)
.HAlign(HAlign_Center)
[
SNew(SHyperlinkLaunchURL, TEXT("http://developer.android.com/google/index.html"))
.Text(LOCTEXT("GooglePlayDeveloperPage", "Android Developer Page on Google Play services"))
.ToolTipText(LOCTEXT("GooglePlayDeveloperPageTooltip", "Opens a page that discusses Google Play services"))
]
];
TSharedRef<IPropertyHandle> EnabledProperty = DetailLayout.GetProperty(GET_MEMBER_NAME_CHECKED(UAndroidRuntimeSettings, bEnableGooglePlaySupport));
GooglePlayCategory.AddProperty(EnabledProperty)
.EditCondition(SetupForGooglePlayAttribute, NULL);
TSharedRef<IPropertyHandle> AppIDProperty = DetailLayout.GetProperty(GET_MEMBER_NAME_CHECKED(UAndroidRuntimeSettings, GamesAppID));
AppIDProperty->SetOnPropertyValueChanged(FSimpleDelegate::CreateRaw(this, &FAndroidTargetSettingsCustomization::OnAppIDModified));
GooglePlayCategory.AddProperty(AppIDProperty)
.EditCondition(SetupForGooglePlayAttribute, NULL);
TSharedRef<IPropertyHandle> AdMobAdUnitIDProperty = DetailLayout.GetProperty(GET_MEMBER_NAME_CHECKED(UAndroidRuntimeSettings, AdMobAdUnitID));
AdMobAdUnitIDProperty->MarkHiddenByCustomization();
TSharedRef<IPropertyHandle> AdMobAdUnitIDsProperty = DetailLayout.GetProperty(GET_MEMBER_NAME_CHECKED(UAndroidRuntimeSettings, AdMobAdUnitIDs));
GooglePlayCategory.AddProperty(AdMobAdUnitIDsProperty)
.EditCondition(SetupForGooglePlayAttribute, NULL);
TSharedRef<IPropertyHandle> GooglePlayLicenseKeyProperty = DetailLayout.GetProperty(GET_MEMBER_NAME_CHECKED(UAndroidRuntimeSettings, GooglePlayLicenseKey));
GooglePlayCategory.AddProperty(GooglePlayLicenseKeyProperty)
.EditCondition(SetupForGooglePlayAttribute, NULL);
#define SETUP_SOURCEONLY_PROP(PropName, Category, Tip) \
{ \
TSharedRef<IPropertyHandle> PropertyHandle = DetailLayout.GetProperty(GET_MEMBER_NAME_CHECKED(UAndroidRuntimeSettings, PropName)); \
Category.AddProperty(PropertyHandle) \
.IsEnabled(FEngineBuildSettings::IsSourceDistribution()) \
.ToolTip(FEngineBuildSettings::IsSourceDistribution() ? Tip : FAndroidTargetSettingsCustomizationConstants::DisabledTip); \
}
SETUP_SOURCEONLY_PROP(bBuildForArmV7, BuildCategory, LOCTEXT("BuildForArmV7ToolTip", "Enable ArmV7 CPU architecture support? (this will be used if all CPU architecture types are unchecked)"));
SETUP_SOURCEONLY_PROP(bBuildForX86, BuildCategory, LOCTEXT("BuildForX86ToolTip", "Enable X86 CPU architecture support?"));
SETUP_SOURCEONLY_PROP(bBuildForX8664, BuildCategory, LOCTEXT("BuildForX8664ToolTip", "Enable X86-64 CPU architecture support?"));
SETUP_SOURCEONLY_PROP(bBuildForES2, BuildCategory, LOCTEXT("BuildForES2ToolTip", "Enable OpenGL ES2 rendering support? (this will be used if rendering types are unchecked)"));
SETUP_SOURCEONLY_PROP(bBuildForES31, BuildCategory, LOCTEXT("BuildForES31ToolTip", "Enable OpenGL ES31 + AEP (Android Extension Pack) rendering support?"));
SETUP_SOURCEONLY_PROP(bSupportsVulkan, BuildCategory, LOCTEXT("SupportsVulkanToolTip", "Enable Vulkan rendering support?"));
// @todo android fat binary: Put back in when we expose those
// SETUP_SOURCEONLY_PROP(bSplitIntoSeparateApks, BuildCategory, LOCTEXT("SplitIntoSeparateAPKsToolTip", "If checked, CPU architectures and rendering types will be split into separate .apk files"));
}
void FAndroidTargetSettingsCustomization::BuildIconSection(IDetailLayoutBuilder& DetailLayout)
{
// Icon category
IDetailCategoryBuilder& IconCategory = DetailLayout.EditCategory(TEXT("Icons"));
IconCategory.AddCustomRow(LOCTEXT("IconsHyperlink", "Icons Hyperlink"), false)
.WholeRowWidget
[
SNew(SBox)
.HAlign(HAlign_Center)
[
SNew(SHyperlinkLaunchURL, TEXT("http://developer.android.com/design/style/iconography.html"))
.Text(LOCTEXT("AndroidDeveloperIconographyPage", "Android Developer Page on Iconography"))
.ToolTipText(LOCTEXT("AndroidDeveloperIconographyPageTooltip", "Opens a page on Android Iconography"))
]
];
for (const FPlatformIconInfo& Info : IconNames)
{
const FString AutomaticImagePath = EngineAndroidPath / Info.IconPath;
const FString TargetImagePath = GameAndroidPath / Info.IconPath;
IconCategory.AddCustomRow(Info.IconName)
.NameContent()
[
SNew(SHorizontalBox)
+SHorizontalBox::Slot()
.Padding( FMargin( 0, 1, 0, 1 ) )
.FillWidth(1.0f)
[
SNew(STextBlock)
.Text(Info.IconName)
.Font(DetailLayout.GetDetailFont())
]
]
.ValueContent()
.MaxDesiredWidth(400.0f)
.MinDesiredWidth(100.0f)
[
SNew(SHorizontalBox)
+SHorizontalBox::Slot()
.FillWidth(1.0f)
.VAlign(VAlign_Center)
[
SNew(SExternalImageReference, AutomaticImagePath, TargetImagePath)
.FileDescription(Info.IconDescription)
.RequiredSize(Info.IconRequiredSize)
.MaxDisplaySize(FVector2D(FMath::Min(96, Info.IconRequiredSize.X), FMath::Min(96, Info.IconRequiredSize.Y)))
]
];
}
}
void FAndroidTargetSettingsCustomization::BuildLaunchImageSection(IDetailLayoutBuilder& DetailLayout)
{
// Add the launch images
IDetailCategoryBuilder& LaunchImageCategory = DetailLayout.EditCategory(TEXT("LaunchImages"));
LaunchImageCategory.AddCustomRow(LOCTEXT("LaunchImageInfo", "Launch Image Info"), false)
.WholeRowWidget
[
SNew(SBorder)
.Padding(1)
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.Padding(FMargin(10, 10, 10, 10))
.FillWidth(1.0f)
[
SNew(SRichTextBlock)
.Text(LOCTEXT("LaunchImageInfoMessage", "The <RichTextBlock.TextHighlight>Download Background</> image is used as the background for OBB downloading. The <RichTextBlock.TextHighlight>Launch Portrait</> image is used as a splash screen for applications with Portrait, Reverse Portrait, Sensor Portrait, Sensor, or Full Sensor orientation. The <RichTextBlock.TextHighlight>Launch Landscape</> image is used as a splash screen for applications with Landscape, Sensor Landscape, Reverse Landscape, Sensor, or Full Sensor orientation.\n\nThe launch images will be scaled to fit the device in the active orientation. Additional optional launch images may be provided as overrides for LDPI, MDPI, HDPI, and XHDPI by placing them in the project's corresponding Build/Android/res/drawable-* directory."))
.TextStyle(FEditorStyle::Get(), "MessageLog")
.DecoratorStyleSet(&FEditorStyle::Get())
.AutoWrapText(true)
+ SRichTextBlock::HyperlinkDecorator(TEXT("browser"), FSlateHyperlinkRun::FOnClick::CreateStatic(&OnBrowserLinkClicked))
]
]
];
const FVector2D LaunchImageMaxSize(150.0f, 150.0f);
for (const FPlatformIconInfo& Info : LaunchImageNames)
{
const FString AutomaticImagePath = EngineAndroidPath / Info.IconPath;
const FString TargetImagePath = GameAndroidPath / Info.IconPath;
LaunchImageCategory.AddCustomRow(Info.IconName)
.NameContent()
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.Padding(FMargin(0, 1, 0, 1))
.FillWidth(1.0f)
[
SNew(STextBlock)
.Text(Info.IconName)
.Font(DetailLayout.GetDetailFont())
]
]
.ValueContent()
.MaxDesiredWidth(400.0f)
.MinDesiredWidth(100.0f)
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.FillWidth(1.0f)
.VAlign(VAlign_Center)
[
SNew(SExternalImageReference, AutomaticImagePath, TargetImagePath)
.FileDescription(Info.IconDescription)
// .RequiredSize(Info.IconRequiredSize)
.MaxDisplaySize(LaunchImageMaxSize)
]
];
}
}
FReply FAndroidTargetSettingsCustomization::OpenBuildFolder()
{
const FString BuildFolder = FPaths::ConvertRelativePathToFull(FPaths::GetPath(GameProjectPropertiesPath));
FPlatformProcess::ExploreFolder(*BuildFolder);
return FReply::Handled();
}
void FAndroidTargetSettingsCustomization::CopySetupFilesIntoProject()
{
// First copy the manifest, it must get copied
FText ErrorMessage;
if (!SourceControlHelpers::CopyFileUnderSourceControl(GameProjectPropertiesPath, EngineProjectPropertiesPath, LOCTEXT("ProjectProperties", "Project Properties"), /*out*/ ErrorMessage))
{
FNotificationInfo Info(ErrorMessage);
Info.ExpireDuration = 3.0f;
FSlateNotificationManager::Get().AddNotification(Info);
}
else
{
// Now try to copy all of the icons, etc... (these can be ignored if the file already exists)
for (const FPlatformIconInfo& Info : IconNames)
{
const FString EngineImagePath = EngineAndroidPath / Info.IconPath;
const FString ProjectImagePath = GameAndroidPath / Info.IconPath;
if (!FPaths::FileExists(ProjectImagePath))
{
SourceControlHelpers::CopyFileUnderSourceControl(ProjectImagePath, EngineImagePath, Info.IconName, /*out*/ ErrorMessage);
}
}
// Now try to copy all of the launch images... (these can be ignored if the file already exists)
for (const FPlatformIconInfo& Info : LaunchImageNames)
{
const FString EngineImagePath = EngineAndroidPath / Info.IconPath;
const FString ProjectImagePath = GameAndroidPath / Info.IconPath;
if (!FPaths::FileExists(ProjectImagePath))
{
SourceControlHelpers::CopyFileUnderSourceControl(ProjectImagePath, EngineImagePath, Info.IconName, /*out*/ ErrorMessage);
}
}
// and copy the other files (aren't required)
//SourceControlHelpers::CopyFileUnderSourceControl(GameProguardPath, EngineProguardPath, LOCTEXT("Proguard", "Proguard Settings"), /*out*/ ErrorMessage);
}
SavedLayoutBuilder->ForceRefreshDetails();
}
void FAndroidTargetSettingsCustomization::CopyGooglePlayAppIDFileIntoProject()
{
FText ErrorMessage;
if (!SourceControlHelpers::CopyFileUnderSourceControl(GameGooglePlayAppIDPath, EngineGooglePlayAppIDPath, LOCTEXT("GooglePlayAppID", "GooglePlayAppID.xml"), /*out*/ ErrorMessage))
{
FNotificationInfo Info(ErrorMessage);
Info.ExpireDuration = 3.0f;
FSlateNotificationManager::Get().AddNotification(Info);
}
SavedLayoutBuilder->ForceRefreshDetails();
}
void FAndroidTargetSettingsCustomization::OnAppIDModified()
{
check(SetupForPlatformAttribute.Get() == true);
FManifestUpdateHelper Updater(GameGooglePlayAppIDPath);
const FString AppIDTag(TEXT("name=\"app_id\">"));
const FString ClosingTag(TEXT("</string>"));
const FString NewIDString = GetDefault<UAndroidRuntimeSettings>()->GamesAppID;
Updater.ReplaceKey(AppIDTag, ClosingTag, NewIDString);
Updater.Finalize(GameGooglePlayAppIDPath);
}
//////////////////////////////////////////////////////////////////////////
#undef LOCTEXT_NAMESPACE