2021-02-11 13:47:14 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
2021-02-10 09:04:41 -04:00
# include "IOSDeviceHelper.h"
2024-02-26 12:11:20 -05:00
# include "IOSTargetPlatformControls.h"
2021-02-10 07:28:32 -04:00
# include "IOSTargetDeviceOutput.h"
# include "HAL/PlatformProcess.h"
# include "HAL/Runnable.h"
# include "HAL/RunnableThread.h"
# include "Interfaces/ITargetPlatformManagerModule.h"
# include "Interfaces/ITargetPlatform.h"
# include "Interfaces/IProjectManager.h"
2021-09-17 05:01:42 -04:00
# include "Misc/MessageDialog.h"
2024-02-15 09:55:52 -05:00
# include "Serialization/JsonReader.h"
# include "Serialization/JsonSerializer.h"
2021-09-17 05:01:42 -04:00
# define LOCTEXT_NAMESPACE "MiscIOSMessages"
2021-02-10 07:28:32 -04:00
DEFINE_LOG_CATEGORY_STATIC ( LogIOSDeviceHelper , Log , All ) ;
2024-02-15 09:55:52 -05:00
enum DeviceConnectionInterface
{
NoValue = 0 ,
USB = 1 ,
Network = 2 ,
Simulator = 3 ,
Max = 4
} ;
2021-02-17 09:08:31 -04:00
2024-02-15 09:55:52 -05:00
struct FDeviceNotificationCallbackInformation
{
FString DeviceID ;
FString DeviceName ;
FString DeviceUDID ;
FString ProductType ;
FString DeviceOSVersion ;
DeviceConnectionInterface DeviceInterface ;
uint32 msgType ;
bool IsAuthorized ;
} ;
2021-02-10 07:28:32 -04:00
2024-02-15 09:55:52 -05:00
struct LibIMobileDevice
{
FString DeviceID ;
FString DeviceName ;
FString DeviceUDID ;
FString DeviceType ;
FString DeviceOSVersion ;
DeviceConnectionInterface DeviceInterface ;
bool IsAuthorized ;
bool IsDealtWith ;
} ;
2021-02-10 07:28:32 -04:00
2024-02-15 09:55:52 -05:00
const FString StringifyDeviceConnection ( DeviceConnectionInterface Interface )
{
switch ( Interface )
{
case DeviceConnectionInterface : : NoValue :
return TEXT ( " NoValue " ) ;
2021-02-10 07:28:32 -04:00
2024-02-15 09:55:52 -05:00
case DeviceConnectionInterface : : Network :
return TEXT ( " Network " ) ;
2021-02-10 07:28:32 -04:00
2024-02-15 09:55:52 -05:00
case DeviceConnectionInterface : : USB :
return TEXT ( " USB " ) ;
2021-02-10 07:28:32 -04:00
2024-02-15 09:55:52 -05:00
case DeviceConnectionInterface : : Simulator :
return TEXT ( " Simulator " ) ;
2021-02-17 09:08:31 -04:00
2024-02-15 09:55:52 -05:00
default :
UE_LOG ( LogIOSDeviceHelper , Warning , TEXT ( " Unknown DeviceConnectionInterface type:%d " ) , Interface ) ;
return TEXT ( " NoValue " ) ;
}
}
2021-02-17 09:08:31 -04:00
2024-02-15 09:55:52 -05:00
static TArray < LibIMobileDevice > GetLibIMobileDevices ( )
{
FString OutStdOut ;
FString OutStdErr ;
FString LibimobileDeviceId = GetLibImobileDeviceExe ( " idevice_id " ) ;
int ReturnCode ;
// get the list of devices UDID
FPlatformProcess : : ExecProcess ( * LibimobileDeviceId , TEXT ( " " ) , & ReturnCode , & OutStdOut , & OutStdErr , NULL , true ) ;
TArray < LibIMobileDevice > ToReturn ;
// separate out each line
TArray < FString > OngoingDeviceIds ;
OutStdOut . ParseIntoArray ( OngoingDeviceIds , TEXT ( " \n " ) , true ) ;
TArray < FString > DeviceStrings ;
for ( int32 StringIndex = 0 ; StringIndex < OngoingDeviceIds . Num ( ) ; + + StringIndex )
{
const FString & DeviceUDID = OngoingDeviceIds [ StringIndex ] ;
DeviceConnectionInterface OngoingDeviceInterface = DeviceConnectionInterface : : NoValue ;
FString OutStdOutInfo ;
FString OutStdErrInfo ;
FString LibimobileDeviceInfo = GetLibImobileDeviceExe ( " ideviceinfo " ) ;
int ReturnCodeInfo ;
FString Arguments ;
if ( OngoingDeviceIds [ StringIndex ] . Contains ( " USB " ) )
{
OngoingDeviceInterface = DeviceConnectionInterface : : USB ;
2023-05-24 09:39:39 -04:00
}
2024-02-15 09:55:52 -05:00
else if ( OngoingDeviceIds [ StringIndex ] . Contains ( " Network " ) )
{
OngoingDeviceInterface = DeviceConnectionInterface : : Network ;
}
OngoingDeviceIds [ StringIndex ] . Split ( TEXT ( " " ) , & OngoingDeviceIds [ StringIndex ] , nullptr , ESearchCase : : CaseSensitive , ESearchDir : : FromStart ) ;
if ( OngoingDeviceInterface = = DeviceConnectionInterface : : USB )
{
Arguments = " -u " + DeviceUDID ;
}
else if ( OngoingDeviceInterface = = DeviceConnectionInterface : : Network )
{
Arguments = " -n -u " + DeviceUDID ;
}
FPlatformProcess : : ExecProcess ( * LibimobileDeviceInfo , * Arguments , & ReturnCodeInfo , & OutStdOutInfo , & OutStdErrInfo , NULL , true ) ;
LibIMobileDevice ToAdd ;
// ideviceinfo can fail when the connected device is untrusted. It can be "Pairing dialog response pending (-19)", "Invalid HostID (-21)" or "User denied pairing (-18)"
// the only thing we can do is to make sure the Trust popup is correctly displayed.
if ( OutStdErrInfo . Contains ( " ERROR: " ) )
{
if ( OutStdErrInfo . Contains ( " Could not connect to lockdownd " ) )
{
// UE_LOG(LogIOSDeviceHelper, Warning, TEXT("Could not pair with connected iOS/tvOS device. Trust this computer by accepting the popup on device."));
FString LibimobileDevicePair = GetLibImobileDeviceExe ( " idevicepair " ) ;
FString PairArguments = " -u " + DeviceUDID + " pair " ;
FPlatformProcess : : ExecProcess ( * LibimobileDevicePair , * PairArguments , & ReturnCodeInfo , & OutStdOutInfo , & OutStdErrInfo , NULL , true ) ;
}
else
{
UE_LOG ( LogIOSDeviceHelper , Warning , TEXT ( " Libimobile call failed : %s " ) , * OutStdErrInfo ) ;
}
OutStdOutInfo . Empty ( ) ;
OutStdErrInfo . Empty ( ) ;
ToAdd . IsAuthorized = false ;
}
else
{
ToAdd . IsAuthorized = true ;
}
// parse product type and device name
FString DeviceName ;
OutStdOutInfo . Split ( TEXT ( " DeviceName: " ) , nullptr , & DeviceName , ESearchCase : : CaseSensitive , ESearchDir : : FromStart ) ;
DeviceName . Split ( LINE_TERMINATOR , & DeviceName , nullptr , ESearchCase : : CaseSensitive , ESearchDir : : FromStart ) ;
if ( ! ToAdd . IsAuthorized )
{
DeviceName = LOCTEXT ( " IosTvosUnauthorizedDevice " , " iOS / tvOS (Unauthorized) " ) . ToString ( ) ;
}
else
{
if ( OngoingDeviceInterface = = DeviceConnectionInterface : : Network )
{
DeviceName + = " [Wifi] " ;
}
}
FString ProductType ;
OutStdOutInfo . Split ( TEXT ( " ProductType: " ) , nullptr , & ProductType , ESearchCase : : CaseSensitive , ESearchDir : : FromStart ) ;
ProductType . Split ( LINE_TERMINATOR , & ProductType , nullptr , ESearchCase : : CaseSensitive , ESearchDir : : FromStart ) ;
FString OSVersion ; // iOS/iPad OS Version
OutStdOutInfo . Split ( TEXT ( " ProductVersion: " ) , nullptr , & OSVersion , ESearchCase : : CaseSensitive , ESearchDir : : FromStart ) ;
OSVersion . Split ( LINE_TERMINATOR , & OSVersion , nullptr , ESearchCase : : CaseSensitive , ESearchDir : : FromStart ) ;
FString DeviceID = FString : : Printf ( TEXT ( " %s@%s " ) ,
ProductType . Contains ( TEXT ( " AppleTV " ) ) ? TEXT ( " TVOS " ) : TEXT ( " IOS " ) ,
* DeviceUDID ) ;
ToAdd . DeviceID = DeviceID ;
ToAdd . DeviceUDID = DeviceUDID ;
ToAdd . DeviceName = DeviceName ;
ToAdd . DeviceType = ProductType ;
ToAdd . DeviceOSVersion = OSVersion ;
ToAdd . DeviceInterface = OngoingDeviceInterface ;
ToAdd . IsDealtWith = false ;
ToReturn . Add ( ToAdd ) ;
}
return ToReturn ;
}
static TArray < LibIMobileDevice > GetSimulatorDevices ( )
{
FString OutStdOut ;
FString OutStdErr ;
TArray < LibIMobileDevice > ToReturn ;
int ReturnCode ;
FString simCommand = TEXT ( " /usr/bin/xcrun " ) ;
FString simParams = TEXT ( " simctl list -je devices available " ) ;
FPlatformProcess : : ExecProcess ( * simCommand , * simParams , & ReturnCode , & OutStdOut , & OutStdErr , NULL , true ) ;
if ( OutStdOut . Len ( ) = = 0 )
{
UE_LOG ( LogIOSDeviceHelper , Warning , TEXT ( " Unable to access simctl app. Is Xcode installed? " ) ) ;
2023-05-24 09:39:39 -04:00
return ToReturn ;
}
2021-02-10 07:28:32 -04:00
2024-02-15 09:55:52 -05:00
// decode the json object
TSharedPtr < FJsonObject > JsonObject ;
TSharedRef < TJsonReader < > > Reader = TJsonReaderFactory < > : : Create ( * OutStdOut ) ; //ANSI_TO_TCHAR((const ANSICHAR *)Msg.GetData()));
if ( ! FJsonSerializer : : Deserialize ( Reader , JsonObject ) | | ! JsonObject . IsValid ( ) )
{
UE_LOG ( LogIOSDeviceHelper , Error , TEXT ( " Failed to parse message from SimCtl utility: %s " ) , * Reader - > GetErrorMessage ( ) ) ;
return ToReturn ;
}
const TSharedPtr < FJsonObject > * SimDevices ;
if ( JsonObject - > TryGetObjectField ( TEXT ( " devices " ) , /*out*/ SimDevices ) )
{
// This should be a list of iOS/tvOS/xrOS versions, each with an array of simulators for that version
for ( const auto & OSSimPair : ( * SimDevices ) - > Values )
{
// We only track iOS, for now
// The Key is format is: com.apple.CoreSimulator.SimRuntime.iOS-17-2
int IOSIndex = OSSimPair . Key . Find ( TEXT ( " iOS " ) ) ;
if ( IOSIndex > 0 )
{
FString OSVer = OSSimPair . Key . RightChop ( IOSIndex + 4 ) ;
OSVer . ReplaceInline ( TEXT ( " - " ) , TEXT ( " . " ) ) ;
LibIMobileDevice ToAdd ;
ToAdd . IsAuthorized = true ;
ToAdd . DeviceOSVersion = OSVer ;
const TArray < TSharedPtr < FJsonValue > > * SimDataArray ;
if ( OSSimPair . Value - > TryGetArray ( SimDataArray ) )
{
for ( const auto & SimData : * SimDataArray )
{
const TSharedPtr < FJsonObject > * SimDataObj ;
if ( SimData - > TryGetObject ( SimDataObj ) )
{
// For now, we only care about booted devices
const FString DeviceState = ( * SimDataObj ) - > GetStringField ( TEXT ( " state " ) ) ;
if ( DeviceState = = TEXT ( " Booted " ) )
{
const FString DeviceName = ( * SimDataObj ) - > GetStringField ( TEXT ( " name " ) ) ;
ToAdd . DeviceUDID = ( * SimDataObj ) - > GetStringField ( TEXT ( " udid " ) ) ;
ToAdd . DeviceType = ( * SimDataObj ) - > GetStringField ( TEXT ( " name " ) ) ;
ToAdd . DeviceName = DeviceName ;
FString DeviceID = FString : : Printf ( TEXT ( " IOS@%s " ) , * ToAdd . DeviceUDID ) ;
ToAdd . DeviceID = DeviceID ;
ToAdd . DeviceInterface = DeviceConnectionInterface : : Simulator ;
ToReturn . Add ( ToAdd ) ;
}
}
}
}
}
}
}
return ToReturn ;
}
2021-02-10 07:28:32 -04:00
class FIOSDevice
{
public :
2023-05-24 09:39:39 -04:00
FIOSDevice ( FString InID , FString InName , DeviceConnectionInterface InConnectionType )
2024-02-15 09:55:52 -05:00
: UDID ( InID )
, Name ( InName )
, ConnectionType ( InConnectionType )
2023-05-24 09:39:39 -04:00
{
}
~ FIOSDevice ( )
{
}
FString SerialNumber ( ) const
{
return UDID ;
}
DeviceConnectionInterface ConnectionInterface ( ) const
{
return ConnectionType ;
}
2021-02-10 07:28:32 -04:00
private :
2023-05-24 09:39:39 -04:00
FString UDID ;
FString Name ;
DeviceConnectionInterface ConnectionType ;
2021-02-10 07:28:32 -04:00
} ;
/**
* Delegate type for devices being connected or disconnected from the machine
*
* The first parameter is newly added or removed device
*/
DECLARE_MULTICAST_DELEGATE_OneParam ( FDeviceNotification , void * )
// recheck once per minute
# define RECHECK_COUNTER_RESET 12
class FDeviceQueryTask
2024-02-15 09:55:52 -05:00
: public FRunnable
2021-02-10 07:28:32 -04:00
{
public :
2024-02-15 09:55:52 -05:00
FDeviceQueryTask ( )
: Stopping ( false )
, bCheckDevices ( true )
, NeedSDKCheck ( true )
, RetryQuery ( 5 )
{ }
virtual bool Init ( ) override
{
return true ;
}
virtual uint32 Run ( ) override
{
while ( ! Stopping )
{
if ( IsEngineExitRequested ( ) )
{
break ;
}
if ( GetTargetPlatformManager ( ) )
{
FString OutTutorialPath ;
const ITargetPlatform * Platform = GetTargetPlatformManager ( ) - > FindTargetPlatform ( TEXT ( " IOS " ) ) ;
if ( Platform )
{
if ( Platform - > IsSdkInstalled ( false , OutTutorialPath ) )
{
break ;
}
}
Enable ( false ) ;
return 0 ;
}
else
{
FPlatformProcess : : Sleep ( 1.0f ) ;
}
}
int RecheckCounter = RECHECK_COUNTER_RESET ;
while ( ! Stopping )
{
if ( IsEngineExitRequested ( ) )
{
break ;
}
if ( bCheckDevices )
{
2021-02-10 07:28:32 -04:00
# if WITH_EDITOR
2024-02-15 09:55:52 -05:00
if ( ! IsRunningCommandlet ( ) )
{
//if (NeedSDKCheck)
//{
// NeedSDKCheck = false;
// FProjectStatus ProjectStatus;
// if (!IProjectManager::Get().QueryStatusForCurrentProject(ProjectStatus) || (!ProjectStatus.IsTargetPlatformSupported(TEXT("IOS")) && !ProjectStatus.IsTargetPlatformSupported(TEXT("TVOS"))))
// {
// Enable(false);
// }
//}
//else
{
// BHP - Turning off device check to prevent it from interfering with packaging
QueryDevices ( ) ;
}
}
2021-04-13 10:11:56 -04:00
# else
2024-02-15 09:55:52 -05:00
QueryDevices ( ) ;
2021-02-10 07:28:32 -04:00
# endif
2024-02-15 09:55:52 -05:00
}
RecheckCounter - - ;
if ( RecheckCounter < 0 )
{
RecheckCounter = RECHECK_COUNTER_RESET ;
bCheckDevices = true ;
NeedSDKCheck = true ;
}
FPlatformProcess : : Sleep ( 5.0f ) ;
}
return 0 ;
}
virtual void Stop ( ) override
{
Stopping = true ;
}
virtual void Exit ( ) override
{ }
FDeviceNotification & OnDeviceNotification ( )
{
return DeviceNotification ;
}
void Enable ( bool bInCheckDevices )
{
bCheckDevices = bInCheckDevices ;
}
2021-02-10 07:28:32 -04:00
private :
2024-02-15 09:55:52 -05:00
void NotifyDeviceChange ( LibIMobileDevice & Device , bool bAdd )
{
FDeviceNotificationCallbackInformation CallbackInfo ;
if ( bAdd )
{
CallbackInfo . DeviceID = Device . DeviceID ;
CallbackInfo . DeviceName = Device . DeviceName ;
2023-05-24 09:39:39 -04:00
CallbackInfo . DeviceUDID = Device . DeviceUDID ;
CallbackInfo . DeviceInterface = Device . DeviceInterface ;
2024-02-15 09:55:52 -05:00
CallbackInfo . ProductType = Device . DeviceType ;
CallbackInfo . DeviceOSVersion = Device . DeviceOSVersion ;
CallbackInfo . msgType = 1 ;
CallbackInfo . IsAuthorized = Device . IsAuthorized ;
}
else
{
CallbackInfo . DeviceID = Device . DeviceID ;
CallbackInfo . DeviceUDID = Device . DeviceUDID ;
CallbackInfo . DeviceInterface = Device . DeviceInterface ;
CallbackInfo . msgType = 2 ;
DeviceNotification . Broadcast ( & CallbackInfo ) ;
}
DeviceNotification . Broadcast ( & CallbackInfo ) ;
}
void QueryDevices ( )
{
TArray < LibIMobileDevice > SimulatorDevices ;
bool HasSimDevices = false ;
bool HasDevices = true ;
bool bEnableSimulatorSupport = false ;
GConfig - > GetBool ( TEXT ( " /Script/IOSRuntimeSettings.IOSRuntimeSettings " ) , TEXT ( " bEnableSimulatorSupport " ) , bEnableSimulatorSupport , GEngineIni ) ;
if ( bEnableSimulatorSupport )
{
SimulatorDevices = GetSimulatorDevices ( ) ;
HasSimDevices = SimulatorDevices . Num ( ) > 0 ;
}
2021-09-17 05:01:42 -04:00
2022-07-07 07:47:30 -04:00
FString LibimobileDeviceId = GetLibImobileDeviceExe ( " idevice_id " ) ;
if ( LibimobileDeviceId . Len ( ) = = 0 )
{
UE_LOG ( LogIOSDeviceHelper , Log , TEXT ( " idevice_id (iOS device detection) executable missing. Turning off iOS/tvOS device detection. " ) ) ;
2024-02-15 09:55:52 -05:00
HasDevices = false ;
2022-07-07 07:47:30 -04:00
Enable ( false ) ;
2024-02-15 09:55:52 -05:00
if ( ! HasSimDevices )
{
return ;
}
2022-07-07 07:47:30 -04:00
}
2024-02-15 09:55:52 -05:00
// get the list of devices UDID
if ( HasDevices )
{
FString OutStdOut ;
FString OutStdErr ;
int ReturnCode ;
FPlatformProcess : : ExecProcess ( * LibimobileDeviceId , TEXT ( " " ) , & ReturnCode , & OutStdOut , & OutStdErr , NULL , true ) ;
if ( OutStdOut . Len ( ) = = 0 )
2021-09-17 05:01:42 -04:00
{
2024-02-15 09:55:52 -05:00
RetryQuery - - ;
if ( RetryQuery < 0 )
{
UE_LOG ( LogIOSDeviceHelper , Verbose , TEXT ( " IOS device listing is disabled for 1 minute (too many failed attempts)! " ) ) ;
Enable ( false ) ;
}
for ( LibIMobileDevice device : CachedDevices )
{
NotifyDeviceChange ( device , false ) ;
}
CachedDevices . Empty ( ) ;
HasDevices = false ;
if ( ! HasSimDevices )
{
return ;
}
2021-09-17 05:01:42 -04:00
}
2024-02-15 09:55:52 -05:00
RetryQuery = 5 ;
}
2021-02-10 07:28:32 -04:00
2024-02-15 09:55:52 -05:00
TArray < LibIMobileDevice > ParsedDevices ;
if ( HasDevices )
{
ParsedDevices = GetLibIMobileDevices ( ) ;
}
ParsedDevices . Append ( SimulatorDevices ) ;
for ( int32 Index = 0 ; Index < ParsedDevices . Num ( ) ; + + Index )
{
LibIMobileDevice * Found = CachedDevices . FindByPredicate (
[ & ] ( LibIMobileDevice Element )
{
2023-05-24 09:39:39 -04:00
return ( Element . DeviceUDID = = ParsedDevices [ Index ] . DeviceUDID & &
2024-02-15 09:55:52 -05:00
Element . DeviceInterface = = ParsedDevices [ Index ] . DeviceInterface ) ;
2021-09-17 05:01:42 -04:00
} ) ;
if ( Found ! = nullptr )
{
2023-05-24 09:39:39 -04:00
if ( Found - > IsAuthorized ! = ParsedDevices [ Index ] . IsAuthorized )
2021-09-17 05:01:42 -04:00
{
NotifyDeviceChange ( ParsedDevices [ Index ] , false ) ;
NotifyDeviceChange ( ParsedDevices [ Index ] , true ) ;
}
2023-05-24 09:39:39 -04:00
Found - > IsDealtWith = true ;
2021-09-17 05:01:42 -04:00
}
else
{
NotifyDeviceChange ( ParsedDevices [ Index ] , true ) ;
}
2024-02-15 09:55:52 -05:00
}
for ( int32 Index = 0 ; Index < CachedDevices . Num ( ) ; + + Index )
{
if ( ! CachedDevices [ Index ] . IsDealtWith )
{
NotifyDeviceChange ( CachedDevices [ Index ] , false ) ;
}
}
CachedDevices . Empty ( ) ;
2021-09-17 05:01:42 -04:00
CachedDevices = ParsedDevices ;
2024-02-15 09:55:52 -05:00
}
bool Stopping ;
bool bCheckDevices ;
bool NeedSDKCheck ;
int RetryQuery ;
TArray < LibIMobileDevice > CachedDevices ;
FDeviceNotification DeviceNotification ;
2021-02-10 07:28:32 -04:00
} ;
/* FIOSDeviceHelper structors
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static TMap < FIOSDevice * , FIOSLaunchDaemonPong > ConnectedDevices ;
static FDeviceQueryTask * QueryTask = NULL ;
static FRunnableThread * QueryThread = NULL ;
static TArray < FDeviceNotificationCallbackInformation > NotificationMessages ;
static FTickerDelegate TickDelegate ;
bool FIOSDeviceHelper : : MessageTickDelegate ( float DeltaTime )
{
2024-02-15 09:55:52 -05:00
QUICK_SCOPE_CYCLE_COUNTER ( STAT_FIOSDeviceHelper_MessageTickDelegate ) ;
for ( int Index = 0 ; Index < NotificationMessages . Num ( ) ; + + Index )
{
FDeviceNotificationCallbackInformation cbi = NotificationMessages [ Index ] ;
FIOSDeviceHelper : : DeviceCallback ( & cbi ) ;
}
NotificationMessages . Empty ( ) ;
return true ;
2021-02-10 07:28:32 -04:00
}
void FIOSDeviceHelper : : Initialize ( bool bIsTVOS )
{
2024-02-15 09:55:52 -05:00
if ( ! bIsTVOS )
{
// add the message pump
TickDelegate = FTickerDelegate : : CreateStatic ( MessageTickDelegate ) ;
FTSTicker : : GetCoreTicker ( ) . AddTicker ( TickDelegate , 5.0f ) ;
// kick off a thread to query for connected devices
QueryTask = new FDeviceQueryTask ( ) ;
QueryTask - > OnDeviceNotification ( ) . AddStatic ( FIOSDeviceHelper : : DeviceCallback ) ;
static int32 QueryTaskCount = 1 ;
if ( QueryTaskCount = = 1 )
{
// create the socket subsystem (loadmodule in game thread)
ISocketSubsystem * SSS = ISocketSubsystem : : Get ( ) ;
QueryThread = FRunnableThread : : Create ( QueryTask , * FString : : Printf ( TEXT ( " FIOSDeviceHelper.QueryTask_%d " ) , QueryTaskCount + + ) , 128 * 1024 , TPri_Normal ) ;
}
}
2021-02-10 07:28:32 -04:00
}
void FIOSDeviceHelper : : DeviceCallback ( void * CallbackInfo )
{
2024-02-15 09:55:52 -05:00
struct FDeviceNotificationCallbackInformation * cbi = ( FDeviceNotificationCallbackInformation * ) CallbackInfo ;
if ( ! IsInGameThread ( ) )
{
NotificationMessages . Add ( * cbi ) ;
}
else
{
switch ( cbi - > msgType )
{
case 1 :
FIOSDeviceHelper : : DoDeviceConnect ( CallbackInfo ) ;
break ;
case 2 :
FIOSDeviceHelper : : DoDeviceDisconnect ( CallbackInfo ) ;
break ;
}
}
2021-02-10 07:28:32 -04:00
}
void FIOSDeviceHelper : : DoDeviceConnect ( void * CallbackInfo )
{
2024-02-15 09:55:52 -05:00
// connect to the device
struct FDeviceNotificationCallbackInformation * cbi = ( FDeviceNotificationCallbackInformation * ) CallbackInfo ;
FIOSDevice * Device = new FIOSDevice ( cbi - > DeviceUDID , cbi - > DeviceName , cbi - > DeviceInterface ) ;
// fire the event
FIOSLaunchDaemonPong Event ;
2023-05-24 09:39:39 -04:00
Event . DeviceID = cbi - > DeviceID ;
2024-02-15 09:55:52 -05:00
Event . DeviceUDID = cbi - > DeviceUDID ;
Event . DeviceName = cbi - > DeviceName ;
Event . DeviceType = cbi - > ProductType ;
Event . DeviceOSVersion = cbi - > DeviceOSVersion ;
Event . DeviceModelId = cbi - > ProductType ;
Event . DeviceConnectionType = StringifyDeviceConnection ( cbi - > DeviceInterface ) ;
2023-05-24 09:39:39 -04:00
Event . bIsAuthorized = cbi - > IsAuthorized ;
2024-02-15 09:55:52 -05:00
Event . bCanReboot = false ;
Event . bCanPowerOn = false ;
Event . bCanPowerOff = false ;
FIOSDeviceHelper : : OnDeviceConnected ( ) . Broadcast ( Event ) ;
// add to the device list
ConnectedDevices . Add ( Device , Event ) ;
2021-02-10 07:28:32 -04:00
}
void FIOSDeviceHelper : : DoDeviceDisconnect ( void * CallbackInfo )
{
2023-05-24 09:39:39 -04:00
struct FDeviceNotificationCallbackInformation * cbi = ( FDeviceNotificationCallbackInformation * ) CallbackInfo ;
FIOSDevice * device = NULL ;
for ( auto DeviceIterator = ConnectedDevices . CreateIterator ( ) ; DeviceIterator ; + + DeviceIterator )
{
if ( DeviceIterator . Key ( ) - > SerialNumber ( ) = = cbi - > DeviceUDID & &
DeviceIterator . Key ( ) - > ConnectionInterface ( ) = = cbi - > DeviceInterface )
{
device = DeviceIterator . Key ( ) ;
break ;
}
}
if ( device ! = NULL )
{
// extract the device id from the connected list
FIOSLaunchDaemonPong Event = ConnectedDevices . FindAndRemoveChecked ( device ) ;
// fire the event
FIOSDeviceHelper : : OnDeviceDisconnected ( ) . Broadcast ( Event ) ;
// delete the device
delete device ;
}
2021-02-10 07:28:32 -04:00
}
bool FIOSDeviceHelper : : InstallIPAOnDevice ( const FTargetDeviceId & DeviceId , const FString & IPAPath )
{
2024-02-15 09:55:52 -05:00
return false ;
2021-02-10 07:28:32 -04:00
}
void FIOSDeviceHelper : : EnableDeviceCheck ( bool OnOff )
{
2024-02-15 09:55:52 -05:00
QueryTask - > Enable ( OnOff ) ;
2021-02-10 07:28:32 -04:00
}
2021-09-22 06:23:52 -04:00
# undef LOCTEXT_NAMESPACE