You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
#lockdown nick.penwarden #rb none ========================== MAJOR FEATURES + CHANGES ========================== Change 2958982 on 2016/04/28 by Dmitriy.Dyomin Set owner name for RHI texture, for easier debugging Change 2976446 on 2016/05/12 by Niklas.Smedberg Fixed Device Profile CVars so they work even if a DLL with the cvar definition is loaded afterwards. (And they now also go through the common code path for CVars.) Change 2983781 on 2016/05/19 by Steve.Cano Check in PlayUsingLauncher if the device we're launching to is authorized by the computer. Could not get to this information about Devices so added an IsAuthorized interface to ITargetDevice that is overriden in the AndroidTargetDevice. Also make sure to referesh the authorized state as needed for Android device detection. Finally, changed the name of the authorized variable to be more readable (true == authorized instead of true == unauthorized) #jira UE-21121 #ue4 #android Change 2994202 on 2016/05/31 by Allan.Bentham Prevent clear transulcency volume null deref crash. Change test for allocated deferred render targets by testing against an exclusively deferred target (instead of potentially shared shadow depth surface) probable fix for UE-22073 Change 2995613 on 2016/05/31 by Dmitriy.Dyomin Added: Option to force full precision in a material UEMOB-109 Change 2997960 on 2016/06/02 by Gareth.Martin Refactored Landscape serialization to allow cooking both the data used for normal rendering and mobile rendering into the same package #jira UE-31474 Change 2997988 on 2016/06/02 by Gareth.Martin Files missing from CL 2997960 #jira UE-31474 Change 2999222 on 2016/06/03 by Jack.Porter Fix up ETargetPlatformFeatures::ForwardRendering and ETargetPlatformFeatures::DeferredRendering for iOS to support the Metal MRT deferred renderer Change 2999229 on 2016/06/03 by Jack.Porter Rename ETargetPlatformFeatures::ForwardRendering to TargetPlatformFeatures::MobileRendering Change 3003540 on 2016/06/07 by Jack.Porter Merging //UE4/Dev-Main to Dev-Mobile (//UE4/Dev-Mobile) Change 3003779 on 2016/06/07 by Dmitriy.Dyomin Fixed: Criss-crossed sublevels cause NavMesh errors #jira UE-27157 Change 3004535 on 2016/06/07 by Steve.Cano Adding the OnControllerConnectionChange delegate message when a controller is connected on Android. Also added additional future broadcast statement when disconnect support is added for Android. #jira UE-25697 #ue4 #android Change 3005205 on 2016/06/07 by Niklas.Smedberg Bumped ASTC format version to invalidate bad server DDC Change 3005347 on 2016/06/08 by Dmitriy.Dyomin Added a way to cache OpenGL program binaries on the disk. Disabled by default. Can be enabled only on Android platform (r.UseProgramBinaryCache=1) #jira UEMOB-108 Change 3005524 on 2016/06/08 by Dmitriy.Dyomin Fixed iOS build broken by CL# 3005347 Change 3005528 on 2016/06/08 by Jack.Porter Changed hardcoded checkboxes from quality level overrides dialog to use the general property details code. Now magically supports any uproperty types such as enums or integers added to FMaterialQualityOverrides. Change 3005607 on 2016/06/08 by Dmitriy.Dyomin Fixed: Occasional crash on using Launch on Android device when device is being disconnected Change 3006705 on 2016/06/08 by Chris.Babcock Fix virtual joystick to return -1 to 1 ranges for thumbsticks #jira UE-31799 #ue4 #android #ios Change 3006960 on 2016/06/08 by Jack.Porter Merging //UE4/Dev-Main to Dev-Mobile (//UE4/Dev-Mobile) Change 3007050 on 2016/06/09 by Jack.Porter FAutomationWorkerModule::ReportTestComplete() needs to send analytics first as the message endpoint will free the memory resulting in a crash Change 3007129 on 2016/06/09 by Dmitriy.Dyomin Fixed: Black edges seen on flames in Sun Temple #jira UE-31712 Change 3010686 on 2016/06/13 by Dmitriy.Dyomin Fixed: Android Monolithic warnings for glGetProgramBinaryOES and glProgramBinaryOES #jira UE-31933 [CL 3011074 by Jack Porter in Main branch]
466 lines
14 KiB
C++
466 lines
14 KiB
C++
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
|
|
|
|
/*=============================================================================
|
|
AndroidTargetPlatform.inl: Implements the FAndroidTargetPlatform class.
|
|
=============================================================================*/
|
|
|
|
|
|
/* FAndroidTargetPlatform structors
|
|
*****************************************************************************/
|
|
|
|
#define LOCTEXT_NAMESPACE "FAndroidTargetPlatform"
|
|
|
|
static bool SupportsES2()
|
|
{
|
|
// default to support ES2
|
|
bool bBuildForES2 = true;
|
|
GConfig->GetBool(TEXT("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings"), TEXT("bBuildForES2"), bBuildForES2, GEngineIni);
|
|
return bBuildForES2;
|
|
}
|
|
|
|
static bool SupportsAEP()
|
|
{
|
|
// default to not supporting ES31
|
|
bool bBuildForES31 = false;
|
|
GConfig->GetBool(TEXT("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings"), TEXT("bBuildForES31"), bBuildForES31, GEngineIni);
|
|
return bBuildForES31;
|
|
}
|
|
|
|
static bool SupportsVulkan()
|
|
{
|
|
// default to not supporting Vulkan
|
|
bool bSupportsVulkan = false;
|
|
GConfig->GetBool(TEXT("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings"), TEXT("bSupportsVulkan"), bSupportsVulkan, GEngineIni);
|
|
|
|
// glslang library is needed for vulkan shader compiling
|
|
bool GlslangAvailable = false;
|
|
#if PLATFORM_WINDOWS
|
|
#if PLATFORM_64BITS
|
|
GlslangAvailable = true;
|
|
#endif
|
|
#elif PLATFORM_MAC
|
|
GlslangAvailable = false; // @TODO: change when glslang library compiled for Mac
|
|
#elif PLATFORM_LINUX
|
|
GlslangAvailable = false; // @TODO: change when glslang library compiled for Linux
|
|
#endif
|
|
|
|
return bSupportsVulkan && GlslangAvailable;
|
|
}
|
|
|
|
template<class TPlatformProperties>
|
|
inline FAndroidTargetPlatform<TPlatformProperties>::FAndroidTargetPlatform( ) :
|
|
DeviceDetection(nullptr)
|
|
{
|
|
#if WITH_ENGINE
|
|
FConfigCacheIni::LoadLocalIniFile(EngineSettings, TEXT("Engine"), true, *TTargetPlatformBase<TPlatformProperties>::PlatformName());
|
|
TextureLODSettings = nullptr; // These are registered by the device profile system.
|
|
StaticMeshLODSettings.Initialize(EngineSettings);
|
|
#endif
|
|
|
|
TickDelegate = FTickerDelegate::CreateRaw(this, &FAndroidTargetPlatform::HandleTicker);
|
|
TickDelegateHandle = FTicker::GetCoreTicker().AddTicker(TickDelegate, 4.0f);
|
|
}
|
|
|
|
|
|
template<class TPlatformProperties>
|
|
inline FAndroidTargetPlatform<TPlatformProperties>::~FAndroidTargetPlatform()
|
|
{
|
|
FTicker::GetCoreTicker().RemoveTicker(TickDelegateHandle);
|
|
}
|
|
|
|
|
|
/* ITargetPlatform overrides
|
|
*****************************************************************************/
|
|
|
|
template<class TPlatformProperties>
|
|
inline void FAndroidTargetPlatform<TPlatformProperties>::GetAllDevices( TArray<ITargetDevicePtr>& OutDevices ) const
|
|
{
|
|
OutDevices.Reset();
|
|
|
|
for (auto Iter = Devices.CreateConstIterator(); Iter; ++Iter)
|
|
{
|
|
OutDevices.Add(Iter.Value());
|
|
}
|
|
}
|
|
|
|
template<class TPlatformProperties>
|
|
inline ECompressionFlags FAndroidTargetPlatform<TPlatformProperties>::GetBaseCompressionMethod( ) const
|
|
{
|
|
return COMPRESS_ZLIB;
|
|
}
|
|
|
|
template<class TPlatformProperties>
|
|
inline ITargetDevicePtr FAndroidTargetPlatform<TPlatformProperties>::GetDefaultDevice( ) const
|
|
{
|
|
// return the first device in the list
|
|
if (Devices.Num() > 0)
|
|
{
|
|
auto Iter = Devices.CreateConstIterator();
|
|
if (Iter)
|
|
{
|
|
return Iter.Value();
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
template<class TPlatformProperties>
|
|
inline ITargetDevicePtr FAndroidTargetPlatform<TPlatformProperties>::GetDevice( const FTargetDeviceId& DeviceId )
|
|
{
|
|
if (DeviceId.GetPlatformName() == TTargetPlatformBase<TPlatformProperties>::PlatformName())
|
|
{
|
|
return Devices.FindRef(DeviceId.GetDeviceName());
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
template<class TPlatformProperties>
|
|
inline bool FAndroidTargetPlatform<TPlatformProperties>::IsRunningPlatform( ) const
|
|
{
|
|
return false; // This platform never runs the target platform framework
|
|
}
|
|
|
|
|
|
template<class TPlatformProperties>
|
|
inline bool FAndroidTargetPlatform<TPlatformProperties>::IsSdkInstalled(bool bProjectHasCode, FString& OutDocumentationPath) const
|
|
{
|
|
OutDocumentationPath = FString("Shared/Tutorials/SettingUpAndroidTutorial");
|
|
return true;
|
|
}
|
|
|
|
|
|
template<class TPlatformProperties>
|
|
inline bool FAndroidTargetPlatform<TPlatformProperties>::SupportsFeature( ETargetPlatformFeatures Feature ) const
|
|
{
|
|
switch (Feature)
|
|
{
|
|
case ETargetPlatformFeatures::Packaging:
|
|
return true;
|
|
|
|
case ETargetPlatformFeatures::LowQualityLightmaps:
|
|
case ETargetPlatformFeatures::MobileRendering:
|
|
return SupportsES2() || SupportsVulkan();
|
|
|
|
case ETargetPlatformFeatures::HighQualityLightmaps:
|
|
case ETargetPlatformFeatures::Tessellation:
|
|
case ETargetPlatformFeatures::DeferredRendering:
|
|
return SupportsAEP();
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return TTargetPlatformBase<TPlatformProperties>::SupportsFeature(Feature);
|
|
}
|
|
|
|
|
|
#if WITH_ENGINE
|
|
|
|
template<class TPlatformProperties>
|
|
inline void FAndroidTargetPlatform<TPlatformProperties>::GetAllPossibleShaderFormats( TArray<FName>& OutFormats ) const
|
|
{
|
|
static FName NAME_OPENGL_ES2(TEXT("GLSL_ES2"));
|
|
static FName NAME_GLSL_310_ES_EXT(TEXT("GLSL_310_ES_EXT"));
|
|
static FName NAME_SF_VULKAN_ES31_ANDROID(TEXT("SF_VULKAN_ES31_ANDROID"));
|
|
|
|
if (SupportsVulkan())
|
|
{
|
|
OutFormats.AddUnique(NAME_SF_VULKAN_ES31_ANDROID);
|
|
}
|
|
|
|
if (SupportsES2())
|
|
{
|
|
OutFormats.AddUnique(NAME_OPENGL_ES2);
|
|
}
|
|
if (SupportsAEP())
|
|
{
|
|
OutFormats.AddUnique(NAME_GLSL_310_ES_EXT);
|
|
}
|
|
}
|
|
|
|
template<class TPlatformProperties>
|
|
inline void FAndroidTargetPlatform<TPlatformProperties>::GetAllTargetedShaderFormats( TArray<FName>& OutFormats ) const
|
|
{
|
|
GetAllPossibleShaderFormats(OutFormats);
|
|
}
|
|
|
|
|
|
template<class TPlatformProperties>
|
|
inline const FStaticMeshLODSettings& FAndroidTargetPlatform<TPlatformProperties>::GetStaticMeshLODSettings( ) const
|
|
{
|
|
return StaticMeshLODSettings;
|
|
}
|
|
|
|
|
|
template<class TPlatformProperties>
|
|
inline void FAndroidTargetPlatform<TPlatformProperties>::GetTextureFormats( const UTexture* InTexture, TArray<FName>& OutFormats ) const
|
|
{
|
|
check(InTexture);
|
|
|
|
// The order we add texture formats to OutFormats is important. When multiple formats are cooked
|
|
// and supported by the device, the first supported format listed will be used.
|
|
// eg, ETC1/uncompressed should always be last
|
|
|
|
bool bNoCompression = InTexture->CompressionNone // Code wants the texture uncompressed.
|
|
|| (InTexture->LODGroup == TEXTUREGROUP_ColorLookupTable) // Textures in certain LOD groups should remain uncompressed.
|
|
|| (InTexture->LODGroup == TEXTUREGROUP_Bokeh)
|
|
|| (InTexture->CompressionSettings == TC_EditorIcon)
|
|
|| (InTexture->Source.GetSizeX() < 4) // Don't compress textures smaller than the DXT block size.
|
|
|| (InTexture->Source.GetSizeY() < 4)
|
|
|| (InTexture->Source.GetSizeX() % 4 != 0)
|
|
|| (InTexture->Source.GetSizeY() % 4 != 0);
|
|
|
|
bool bIsNonPOT = false;
|
|
#if WITH_EDITORONLY_DATA
|
|
// is this texture not a power of 2?
|
|
bIsNonPOT = !InTexture->Source.IsPowerOfTwo();
|
|
#endif
|
|
|
|
// Determine the pixel format of the compressed texture.
|
|
if (bNoCompression && InTexture->HasHDRSource())
|
|
{
|
|
OutFormats.Add(AndroidTexFormat::NameRGBA16F);
|
|
}
|
|
else if (bNoCompression)
|
|
{
|
|
OutFormats.Add(AndroidTexFormat::NameBGRA8);
|
|
}
|
|
else if (InTexture->CompressionSettings == TC_HDR
|
|
|| InTexture->CompressionSettings == TC_HDR_Compressed)
|
|
{
|
|
OutFormats.Add(AndroidTexFormat::NameRGBA16F);
|
|
}
|
|
else if (InTexture->CompressionSettings == TC_Normalmap)
|
|
{
|
|
AddTextureFormatIfSupports(AndroidTexFormat::NamePVRTC4, OutFormats, bIsNonPOT);
|
|
AddTextureFormatIfSupports(AndroidTexFormat::NameDXT5, OutFormats, bIsNonPOT);
|
|
AddTextureFormatIfSupports(AndroidTexFormat::NameATC_RGBA_I, OutFormats, bIsNonPOT);
|
|
AddTextureFormatIfSupports(AndroidTexFormat::NameAutoETC2, OutFormats, bIsNonPOT);
|
|
AddTextureFormatIfSupports(AndroidTexFormat::NameAutoETC1, OutFormats, bIsNonPOT);
|
|
}
|
|
else if (InTexture->CompressionSettings == TC_Displacementmap)
|
|
{
|
|
OutFormats.Add(AndroidTexFormat::NameRGBA16F);
|
|
}
|
|
else if (InTexture->CompressionSettings == TC_VectorDisplacementmap)
|
|
{
|
|
OutFormats.Add(AndroidTexFormat::NameBGRA8);
|
|
}
|
|
else if (InTexture->CompressionSettings == TC_Grayscale)
|
|
{
|
|
OutFormats.Add(AndroidTexFormat::NameG8);
|
|
}
|
|
else if (InTexture->CompressionSettings == TC_Alpha)
|
|
{
|
|
OutFormats.Add(AndroidTexFormat::NameG8);
|
|
}
|
|
else if (InTexture->CompressionSettings == TC_DistanceFieldFont)
|
|
{
|
|
OutFormats.Add(AndroidTexFormat::NameG8);
|
|
}
|
|
else if (InTexture->bForcePVRTC4
|
|
|| InTexture->CompressionSettings == TC_BC7)
|
|
{
|
|
AddTextureFormatIfSupports(AndroidTexFormat::NamePVRTC4, OutFormats, bIsNonPOT);
|
|
AddTextureFormatIfSupports(AndroidTexFormat::NameDXT5, OutFormats, bIsNonPOT);
|
|
AddTextureFormatIfSupports(AndroidTexFormat::NameATC_RGBA_I, OutFormats, bIsNonPOT);
|
|
AddTextureFormatIfSupports(AndroidTexFormat::NameAutoETC2, OutFormats, bIsNonPOT);
|
|
AddTextureFormatIfSupports(AndroidTexFormat::NameAutoETC1, OutFormats, bIsNonPOT);
|
|
}
|
|
else if (InTexture->CompressionNoAlpha)
|
|
{
|
|
AddTextureFormatIfSupports(AndroidTexFormat::NamePVRTC2, OutFormats, bIsNonPOT);
|
|
AddTextureFormatIfSupports(AndroidTexFormat::NameDXT1, OutFormats, bIsNonPOT);
|
|
AddTextureFormatIfSupports(AndroidTexFormat::NameATC_RGB, OutFormats, bIsNonPOT);
|
|
AddTextureFormatIfSupports(AndroidTexFormat::NameETC2_RGB, OutFormats, bIsNonPOT);
|
|
AddTextureFormatIfSupports(AndroidTexFormat::NameETC1, OutFormats, bIsNonPOT);
|
|
}
|
|
else if (InTexture->bDitherMipMapAlpha)
|
|
{
|
|
AddTextureFormatIfSupports(AndroidTexFormat::NamePVRTC4, OutFormats, bIsNonPOT);
|
|
AddTextureFormatIfSupports(AndroidTexFormat::NameDXT5, OutFormats, bIsNonPOT);
|
|
AddTextureFormatIfSupports(AndroidTexFormat::NameATC_RGBA_I, OutFormats, bIsNonPOT);
|
|
AddTextureFormatIfSupports(AndroidTexFormat::NameAutoETC2, OutFormats, bIsNonPOT);
|
|
AddTextureFormatIfSupports(AndroidTexFormat::NameAutoETC1, OutFormats, bIsNonPOT);
|
|
}
|
|
else
|
|
{
|
|
AddTextureFormatIfSupports(AndroidTexFormat::NameAutoPVRTC, OutFormats, bIsNonPOT);
|
|
AddTextureFormatIfSupports(AndroidTexFormat::NameAutoDXT, OutFormats, bIsNonPOT);
|
|
AddTextureFormatIfSupports(AndroidTexFormat::NameAutoATC, OutFormats, bIsNonPOT);
|
|
AddTextureFormatIfSupports(AndroidTexFormat::NameAutoETC2, OutFormats, bIsNonPOT);
|
|
AddTextureFormatIfSupports(AndroidTexFormat::NameAutoETC1, OutFormats, bIsNonPOT);
|
|
}
|
|
}
|
|
|
|
|
|
template<class TPlatformProperties>
|
|
void FAndroidTargetPlatform<TPlatformProperties>::GetReflectionCaptureFormats( TArray<FName>& OutFormats ) const
|
|
{
|
|
if (SupportsAEP())
|
|
{
|
|
// use Full HDR with AEP
|
|
OutFormats.Add(FName(TEXT("FullHDR")));
|
|
}
|
|
|
|
// always emit encoded
|
|
OutFormats.Add(FName(TEXT("EncodedHDR")));
|
|
}
|
|
|
|
|
|
template<class TPlatformProperties>
|
|
const UTextureLODSettings& FAndroidTargetPlatform<TPlatformProperties>::GetTextureLODSettings() const
|
|
{
|
|
return *TextureLODSettings;
|
|
}
|
|
|
|
|
|
template<class TPlatformProperties>
|
|
FName FAndroidTargetPlatform<TPlatformProperties>::GetWaveFormat( const class USoundWave* Wave ) const
|
|
{
|
|
static bool formatRead = false;
|
|
static FName NAME_FORMAT;
|
|
|
|
if (!formatRead)
|
|
{
|
|
formatRead = true;
|
|
|
|
FString audioSetting;
|
|
if (!GConfig->GetString(TEXT("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings"), TEXT("AndroidAudio"), audioSetting, GEngineIni))
|
|
{
|
|
audioSetting = TEXT("DEFAULT");
|
|
}
|
|
|
|
#if WITH_OGGVORBIS
|
|
if (audioSetting == TEXT("OGG") || audioSetting == TEXT("Default"))
|
|
{
|
|
static FName NAME_OGG(TEXT("OGG"));
|
|
NAME_FORMAT = NAME_OGG;
|
|
}
|
|
#else
|
|
if (audioSetting == TEXT("OGG"))
|
|
{
|
|
UE_LOG(LogAudio, Error, TEXT("Attemped to select Ogg Vorbis encoding when the cooker is built without Ogg Vorbis support."));
|
|
}
|
|
#endif
|
|
else
|
|
{
|
|
|
|
// Otherwise return ADPCM as it'll either be option '2' or 'default' depending on WITH_OGGVORBIS config
|
|
static FName NAME_ADPCM(TEXT("ADPCM"));
|
|
NAME_FORMAT = NAME_ADPCM;
|
|
}
|
|
}
|
|
return NAME_FORMAT;
|
|
}
|
|
|
|
#endif //WITH_ENGINE
|
|
|
|
template<class TPlatformProperties>
|
|
bool FAndroidTargetPlatform<TPlatformProperties>::SupportsVariants() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
template<class TPlatformProperties>
|
|
FText FAndroidTargetPlatform<TPlatformProperties>::GetVariantTitle() const
|
|
{
|
|
return LOCTEXT("AndroidVariantTitle", "Texture Format");
|
|
}
|
|
|
|
/* FAndroidTargetPlatform implementation
|
|
*****************************************************************************/
|
|
|
|
template<class TPlatformProperties>
|
|
inline void FAndroidTargetPlatform<TPlatformProperties>::AddTextureFormatIfSupports( FName Format, TArray<FName>& OutFormats, bool bIsCompressedNonPOT ) const
|
|
{
|
|
if (SupportsTextureFormat(Format))
|
|
{
|
|
if (bIsCompressedNonPOT && SupportsCompressedNonPOT() == false)
|
|
{
|
|
OutFormats.Add(AndroidTexFormat::NamePOTERROR);
|
|
}
|
|
else
|
|
{
|
|
OutFormats.Add(Format);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* FAndroidTargetPlatform callbacks
|
|
*****************************************************************************/
|
|
|
|
template<class TPlatformProperties>
|
|
inline bool FAndroidTargetPlatform<TPlatformProperties>::HandleTicker( float DeltaTime )
|
|
{
|
|
QUICK_SCOPE_CYCLE_COUNTER(STAT_FAndroidTargetPlatform_HandleTicker);
|
|
|
|
if (DeviceDetection == nullptr)
|
|
{
|
|
DeviceDetection = FModuleManager::LoadModuleChecked<IAndroidDeviceDetectionModule>("AndroidDeviceDetection").GetAndroidDeviceDetection();
|
|
}
|
|
|
|
TArray<FString> ConnectedDeviceIds;
|
|
|
|
{
|
|
FScopeLock ScopeLock(DeviceDetection->GetDeviceMapLock());
|
|
|
|
auto DeviceIt = DeviceDetection->GetDeviceMap().CreateConstIterator();
|
|
|
|
for (; DeviceIt; ++DeviceIt)
|
|
{
|
|
ConnectedDeviceIds.Add(DeviceIt.Key());
|
|
|
|
const FAndroidDeviceInfo& DeviceInfo = DeviceIt.Value();
|
|
|
|
// see if this device is already known
|
|
if (Devices.Contains(DeviceIt.Key()))
|
|
{
|
|
//still update its authorized status, which could change while connected
|
|
Devices[DeviceIt.Key()]->SetAuthorized(DeviceInfo.bAuthorizedDevice);
|
|
continue;
|
|
}
|
|
|
|
// check if this platform is supported by the extensions and version
|
|
if (!SupportedByExtensionsString(DeviceInfo.GLESExtensions, DeviceInfo.GLESVersion))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// create target device
|
|
FAndroidTargetDevicePtr& Device = Devices.Add(DeviceInfo.SerialNumber);
|
|
|
|
Device = MakeShareable(new FAndroidTargetDevice(*this, DeviceInfo.SerialNumber, GetAndroidVariantName()));
|
|
|
|
Device->SetConnected(true);
|
|
Device->SetModel(DeviceInfo.Model);
|
|
Device->SetDeviceName(DeviceInfo.DeviceName);
|
|
Device->SetAuthorized(DeviceInfo.bAuthorizedDevice);
|
|
Device->SetVersions(DeviceInfo.SDKVersion, DeviceInfo.HumanAndroidVersion);
|
|
|
|
DeviceDiscoveredEvent.Broadcast(Device.ToSharedRef());
|
|
}
|
|
}
|
|
|
|
// remove disconnected devices
|
|
for (auto Iter = Devices.CreateIterator(); Iter; ++Iter)
|
|
{
|
|
if (!ConnectedDeviceIds.Contains(Iter.Key()))
|
|
{
|
|
FAndroidTargetDevicePtr RemovedDevice = Iter.Value();
|
|
RemovedDevice->SetConnected(false);
|
|
|
|
Iter.RemoveCurrent();
|
|
|
|
DeviceLostEvent.Broadcast(RemovedDevice.ToSharedRef());
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
#undef LOCTEXT_NAMESPACE
|