Create and Register a 'IndigoHIDRegistrationPort' Port
This commit is contained in:
Родитель
993298f3c4
Коммит
5851401093
|
@ -28,11 +28,12 @@
|
|||
Creates and returns a new FBSimulatorDirectLaunch object for the provided SimDeviceFramebufferService.
|
||||
|
||||
@param framebufferService the SimDeviceFramebufferService to connect to.
|
||||
@param hidPort the Mach Port for the 'IndigoHIDRegistrationPort'.
|
||||
@param launchConfiguration the launch configuration to create the service for.
|
||||
@param simulator the Simulator to which the Framebuffer belongs.
|
||||
@return a new FBSimulatorDirectLaunch instance. Must not be nil.
|
||||
*/
|
||||
+ (instancetype)withFramebufferService:(SimDeviceFramebufferService *)framebufferService configuration:(FBSimulatorLaunchConfiguration *)launchConfiguration simulator:(FBSimulator *)simulator;
|
||||
+ (instancetype)withFramebufferService:(SimDeviceFramebufferService *)framebufferService hidPort:(mach_port_t)hidPort configuration:(FBSimulatorLaunchConfiguration *)launchConfiguration simulator:(FBSimulator *)simulator;
|
||||
|
||||
/**
|
||||
Starts listening for Framebuffer events on a background queue.
|
||||
|
|
|
@ -10,9 +10,10 @@
|
|||
#import "FBSimulatorFramebuffer.h"
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
#import <SimulatorKit/SimDeviceFramebufferBackingStore.h>
|
||||
#import <SimulatorKit/SimDeviceFramebufferService.h>
|
||||
#import <mach/exc.h>
|
||||
#import <mach/mig.h>
|
||||
|
||||
#import "FBFramebufferCompositeDelegate.h"
|
||||
#import "FBFramebufferCounter.h"
|
||||
|
@ -42,6 +43,8 @@ static const NSInteger FBFramebufferLogFrameFrequency = 100;
|
|||
@interface FBSimulatorFramebuffer () <FBFramebufferDelegate>
|
||||
|
||||
@property (nonatomic, strong, readonly) SimDeviceFramebufferService *framebufferService;
|
||||
@property (nonatomic, assign, readonly) mach_port_t hidPort;
|
||||
|
||||
@property (nonatomic, strong, readonly) FBFramebufferCounter *counter;
|
||||
@property (nonatomic, strong, readonly) id<FBSimulatorEventSink> eventSink;
|
||||
|
||||
|
@ -57,7 +60,7 @@ static const NSInteger FBFramebufferLogFrameFrequency = 100;
|
|||
|
||||
#pragma mark Initializers
|
||||
|
||||
+ (instancetype)withFramebufferService:(SimDeviceFramebufferService *)framebufferService configuration:(FBSimulatorLaunchConfiguration *)launchConfiguration simulator:(FBSimulator *)simulator {
|
||||
+ (instancetype)withFramebufferService:(SimDeviceFramebufferService *)framebufferService hidPort:(mach_port_t)hidPort configuration:(FBSimulatorLaunchConfiguration *)launchConfiguration simulator:(FBSimulator *)simulator {
|
||||
NSMutableArray *sinks = [NSMutableArray array];
|
||||
BOOL useWindow = (launchConfiguration.options & FBSimulatorLaunchOptionsShowDebugWindow) == FBSimulatorLaunchOptionsShowDebugWindow;
|
||||
if (useWindow) {
|
||||
|
@ -75,12 +78,13 @@ static const NSInteger FBFramebufferLogFrameFrequency = 100;
|
|||
[sinks addObject:[FBFramebufferImage withWritableLog:simulator.logs.screenshot eventSink:simulator.eventSink]];
|
||||
|
||||
id<FBFramebufferDelegate> delegate = [FBFramebufferCompositeDelegate withDelegates:[sinks copy]];
|
||||
return [[self alloc] initWithFramebufferService:framebufferService counter:counter eventSink:simulator.eventSink delegate:delegate];
|
||||
return [[self alloc] initWithFramebufferService:framebufferService hidPort:hidPort counter:counter eventSink:simulator.eventSink delegate:delegate];
|
||||
}
|
||||
|
||||
- (instancetype)initWithFramebufferService:(SimDeviceFramebufferService *)framebufferService counter:(FBFramebufferCounter *)counter eventSink:(id<FBSimulatorEventSink>)eventSink delegate:(id<FBFramebufferDelegate>)delegate
|
||||
- (instancetype)initWithFramebufferService:(SimDeviceFramebufferService *)framebufferService hidPort:(mach_port_t)hidPort counter:(FBFramebufferCounter *)counter eventSink:(id<FBSimulatorEventSink>)eventSink delegate:(id<FBFramebufferDelegate>)delegate
|
||||
{
|
||||
NSParameterAssert(framebufferService);
|
||||
NSParameterAssert(hidPort > 0);
|
||||
|
||||
self = [super init];
|
||||
if (!self) {
|
||||
|
@ -88,6 +92,7 @@ static const NSInteger FBFramebufferLogFrameFrequency = 100;
|
|||
}
|
||||
|
||||
_framebufferService = framebufferService;
|
||||
_hidPort = hidPort;
|
||||
_counter = counter;
|
||||
_eventSink = eventSink;
|
||||
_delegate = delegate;
|
||||
|
@ -185,6 +190,8 @@ static const NSInteger FBFramebufferLogFrameFrequency = 100;
|
|||
|
||||
[self.framebufferService unregisterClient:self];
|
||||
[self.framebufferService suspend];
|
||||
mach_port_destroy(mach_task_self(), self.hidPort);
|
||||
|
||||
[self.delegate framebufferDidBecomeInvalid:self error:error];
|
||||
[self.eventSink framebufferDidTerminate:self expected:(error != nil)];
|
||||
}
|
||||
|
|
|
@ -10,8 +10,9 @@
|
|||
#import "FBSimulatorInteraction+Lifecycle.h"
|
||||
|
||||
#import <CoreSimulator/SimDevice.h>
|
||||
|
||||
#import <SimulatorKit/SimDeviceFramebufferService.h>
|
||||
#import <mach/exc.h>
|
||||
#import <mach/mig.h>
|
||||
|
||||
#import "FBCollectionDescriptions.h"
|
||||
#import "FBInteraction+Private.h"
|
||||
|
@ -145,6 +146,10 @@
|
|||
|
||||
+ (BOOL)launchSimulatorDirectly:(FBSimulator *)simulator configuration:(FBSimulatorLaunchConfiguration *)configuration error:(NSError **)error
|
||||
{
|
||||
// If you're curious about where the knowledege for these parts of the CoreSimulator.framework comes from, take a look at:
|
||||
// $DEVELOPER_DIR/Platforms/iPhoneSimulator.platform/Developer/Library/CoreSimulator/Profiles/Runtimes/iOS [VERSION].simruntime/Contents/Resources/profile.plist
|
||||
// as well as the dissasembly for CoreSimulator.framework, SimulatorKit.Framework & the Simulator.app Executable.
|
||||
|
||||
// Creating the Framebuffer with the 'mainScreen' constructor will return a 'PurpleFBServer' and attach it to the '_registeredServices' ivar.
|
||||
// This is the Framebuffer for the Simulator's main screen, which is distinct from 'PurpleFBTVOut' and 'Stark' Framebuffers for External Displays and CarPlay.
|
||||
NSError *innerError = nil;
|
||||
|
@ -156,6 +161,35 @@
|
|||
failBool:error];
|
||||
}
|
||||
|
||||
// As above with the 'PurpleFBServer', a 'IndigoHIDRegistrationPort' is needed in order for the synthesis of touch events to work appropriately.
|
||||
// If this is not set you will see the following logger message in the System log upon booting the simulator
|
||||
// 'backboardd[10667]: BKHID: Unable to open Indigo HID system'
|
||||
// The dissasembly for backboardd shows that this will happen when the call to 'IndigoHIDSystemSpawnLoopback' fails.
|
||||
// Simulator.app creates a Mach Port for the 'IndigoHIDRegistrationPort' and therefore succeeds in the above call.
|
||||
// As with 'PurpleFBServer' this can be registered with 'register-head-services'
|
||||
// The first step is to create the mach port
|
||||
mach_port_t hidPort = 0;
|
||||
mach_port_t machTask = mach_task_self();
|
||||
kern_return_t result = mach_port_allocate(machTask, MACH_PORT_RIGHT_RECEIVE, &hidPort);
|
||||
if (result != KERN_SUCCESS) {
|
||||
return [[FBSimulatorError
|
||||
describeFormat:@"Failed to create a Mach Port for IndigoHIDRegistrationPort with code %d", result]
|
||||
failBool:error];
|
||||
}
|
||||
result = mach_port_insert_right(machTask, hidPort, hidPort, MACH_MSG_TYPE_MAKE_SEND);
|
||||
if (result != KERN_SUCCESS) {
|
||||
return [[FBSimulatorError
|
||||
describeFormat:@"Failed to 'insert_right' the mach port with code %d", result]
|
||||
failBool:error];
|
||||
}
|
||||
// Then register it as the 'IndigoHIDRegistrationPort'
|
||||
if (![simulator.device registerPort:hidPort service:@"IndigoHIDRegistrationPort" error:&innerError]) {
|
||||
return [[[FBSimulatorError
|
||||
describeFormat:@"Failed to register %d as the IndigoHIDRegistrationPort", hidPort]
|
||||
causedBy:innerError]
|
||||
failBool:error];
|
||||
}
|
||||
|
||||
// The 'register-head-services' option will attach the existing 'frameBufferService' when the Simulator is booted.
|
||||
// Simulator.app behaves similarly, except we can't peek at the Framebuffer as it is in a protected process since Xcode 7.
|
||||
// Prior to Xcode 6 it was possible to shim into the Simulator process but codesigning now prevents this https://gist.github.com/lawrencelomax/27bdc4e8a433a601008f
|
||||
|
@ -176,7 +210,7 @@
|
|||
// Create and start the consumer of the Framebuffer Service.
|
||||
// The launch configuration will define the way that the Framebuffer is consumed.
|
||||
// Then the simulator's event sink should be notified with the created framebuffer object.
|
||||
FBSimulatorFramebuffer *framebuffer = [FBSimulatorFramebuffer withFramebufferService:framebufferService configuration:configuration simulator:simulator];
|
||||
FBSimulatorFramebuffer *framebuffer = [FBSimulatorFramebuffer withFramebufferService:framebufferService hidPort:hidPort configuration:configuration simulator:simulator];
|
||||
[framebuffer startListeningInBackground];
|
||||
[simulator.eventSink framebufferDidStart:framebuffer];
|
||||
|
||||
|
@ -184,7 +218,7 @@
|
|||
if (![self launchdSimWithAllRequiredProcessesForSimulator:simulator error:&innerError]) {
|
||||
return [FBSimulatorError failBoolWithError:innerError errorOut:error];
|
||||
}
|
||||
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче