Files
custom_wda/WebDriverAgentLib/Utilities/XCUIApplicationProcessDelay.m

84 lines
2.5 KiB
Mathematica
Raw Permalink Normal View History

2026-02-03 16:52:44 +08:00
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "XCUIApplicationProcessDelay.h"
#import <objc/runtime.h>
#import "XCUIApplicationProcess.h"
#import "FBLogger.h"
static void (*orig_set_event_loop_has_idled)(id, SEL, BOOL);
static NSTimeInterval eventloopIdleDelay = 0;
static BOOL isSwizzled = NO;
// '-[XCUIApplicationProcess setEventLoopHasIdled:]' can be called from different queues.
// Lets lock the setup and access to the 'eventloopIdleDelay' variable
static NSLock * lock = nil;
@implementation XCUIApplicationProcessDelay
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-load-method"
+ (void)load
{
lock = [[NSLock alloc] init];
}
#pragma clang diagnostic pop
+ (void)setEventLoopHasIdledDelay:(NSTimeInterval)delay
{
[lock lock];
if (!isSwizzled && delay < DBL_EPSILON) {
// don't swizzle methods until we need to
[lock unlock];
return;
}
eventloopIdleDelay = delay;
if (isSwizzled) {
[lock unlock];
return;
}
[self swizzleSetEventLoopHasIdled];
[lock unlock];
}
+ (void)disableEventLoopDelay
{
// Once the methods were swizzled they stay like that since the only change in the implementation
// is the thread sleep, which is skipped on setting it to zero.
[self setEventLoopHasIdledDelay:0];
}
+ (void)swizzleSetEventLoopHasIdled {
Method original = class_getInstanceMethod([XCUIApplicationProcess class], @selector(setEventLoopHasIdled:));
if (original == nil) {
[FBLogger log:@"Could not find method -[XCUIApplicationProcess setEventLoopHasIdled:]"];
return;
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wcast-function-type-strict"
orig_set_event_loop_has_idled = (void(*)(id, SEL, BOOL)) method_getImplementation(original);
#pragma clang diagnostic pop
Method replace = class_getClassMethod([XCUIApplicationProcessDelay class], @selector(setEventLoopHasIdled:));
method_setImplementation(original, method_getImplementation(replace));
isSwizzled = YES;
}
+ (void)setEventLoopHasIdled:(BOOL)idled {
[lock lock];
NSTimeInterval delay = eventloopIdleDelay;
[lock unlock];
if (delay > 0.0) {
[FBLogger verboseLog:[NSString stringWithFormat:@"Delaying -[XCUIApplicationProcess setEventLoopHasIdled:] by %.2f seconds", delay]];
[NSThread sleepForTimeInterval:delay];
}
orig_set_event_loop_has_idled(self, _cmd, idled);
}
@end