FBActiveAppDetectionPoint.m 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /**
  2. * Copyright (c) 2015-present, Facebook, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. */
  9. #import "FBActiveAppDetectionPoint.h"
  10. #import "FBErrorBuilder.h"
  11. #import "FBLogger.h"
  12. #import "FBXCTestDaemonsProxy.h"
  13. #import "XCTestManager_ManagerInterface-Protocol.h"
  14. @implementation FBActiveAppDetectionPoint
  15. - (instancetype)init {
  16. if ((self = [super init])) {
  17. CGSize screenSize = [UIScreen mainScreen].bounds.size;
  18. // Consider the element, which is located close to the top left corner of the screen the on-screen one.
  19. CGFloat pointDistance = MIN(screenSize.width, screenSize.height) * (CGFloat) 0.2;
  20. _coordinates = CGPointMake(pointDistance, pointDistance);
  21. }
  22. return self;
  23. }
  24. + (instancetype)sharedInstance
  25. {
  26. static FBActiveAppDetectionPoint *instance;
  27. static dispatch_once_t onceToken;
  28. dispatch_once(&onceToken, ^{
  29. instance = [[self alloc] init];
  30. });
  31. return instance;
  32. }
  33. + (id<FBXCAccessibilityElement>)axElementWithPoint:(CGPoint)point
  34. {
  35. __block id<FBXCAccessibilityElement> onScreenElement = nil;
  36. id<XCTestManager_ManagerInterface> proxy = [FBXCTestDaemonsProxy testRunnerProxy];
  37. dispatch_semaphore_t sem = dispatch_semaphore_create(0);
  38. [proxy _XCT_requestElementAtPoint:point
  39. reply:^(id element, NSError *error) {
  40. if (nil == error) {
  41. onScreenElement = element;
  42. } else {
  43. [FBLogger logFmt:@"Cannot request the screen point at %@", NSStringFromCGPoint(point)];
  44. }
  45. dispatch_semaphore_signal(sem);
  46. }];
  47. dispatch_semaphore_wait(sem, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)));
  48. return onScreenElement;
  49. }
  50. - (id<FBXCAccessibilityElement>)axElement
  51. {
  52. return [self.class axElementWithPoint:self.coordinates];
  53. }
  54. - (BOOL)setCoordinatesWithString:(NSString *)coordinatesStr error:(NSError **)error
  55. {
  56. NSArray<NSString *> *screenPointCoords = [coordinatesStr componentsSeparatedByString:@","];
  57. if (screenPointCoords.count != 2) {
  58. return [[[FBErrorBuilder builder]
  59. withDescriptionFormat:@"The screen point coordinates should be separated by a single comma character. Got '%@' instead", coordinatesStr]
  60. buildError:error];
  61. }
  62. NSString *strX = [screenPointCoords.firstObject stringByTrimmingCharactersInSet:
  63. NSCharacterSet.whitespaceAndNewlineCharacterSet];
  64. NSString *strY = [screenPointCoords.lastObject stringByTrimmingCharactersInSet:
  65. NSCharacterSet.whitespaceAndNewlineCharacterSet];
  66. if (0 == strX.length || 0 == strY.length) {
  67. return [[[FBErrorBuilder builder]
  68. withDescriptionFormat:@"Both screen point coordinates should be valid numbers. Got '%@' instead", coordinatesStr]
  69. buildError:error];
  70. }
  71. self.coordinates = CGPointMake((CGFloat) strX.doubleValue, (CGFloat) strY.doubleValue);
  72. return YES;
  73. }
  74. - (NSString *)stringCoordinates
  75. {
  76. return [NSString stringWithFormat:@"%.2f,%.2f", self.coordinates.x, self.coordinates.y];
  77. }
  78. @end