2014 snapchat source code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

190 lines
5.6 KiB

  1. //
  2. // SCCameraVolumeButtonHandler.m
  3. // Snapchat
  4. //
  5. // Created by Xiaomu Wu on 2/27/15.
  6. // Copyright (c) 2015 Snapchat, Inc. All rights reserved.
  7. //
  8. #import "SCCameraVolumeButtonHandler.h"
  9. #import <SCFoundation/SCLog.h>
  10. #import <SCFoundation/UIApplication+SCSecretFeature2.h>
  11. @implementation SCCameraVolumeButtonHandler {
  12. NSString *_secretFeatureToken;
  13. BOOL _pressingButton1; // volume down button
  14. BOOL _pressingButton2; // volume up button
  15. BOOL _stopsHandlingWhenPressingEnds;
  16. }
  17. #pragma mark - NSObject
  18. - (instancetype)init
  19. {
  20. self = [super init];
  21. if (self) {
  22. NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
  23. UIApplication *application = [UIApplication sharedApplication];
  24. [notificationCenter addObserver:self
  25. selector:@selector(_handleButton1Down:)
  26. name:[application sc_eventNotificationName1]
  27. object:nil];
  28. [notificationCenter addObserver:self
  29. selector:@selector(_handleButton1Up:)
  30. name:[application sc_eventNotificationName2]
  31. object:nil];
  32. [notificationCenter addObserver:self
  33. selector:@selector(_handleButton2Down:)
  34. name:[application sc_eventNotificationName3]
  35. object:nil];
  36. [notificationCenter addObserver:self
  37. selector:@selector(_handleButton2Up:)
  38. name:[application sc_eventNotificationName4]
  39. object:nil];
  40. }
  41. return self;
  42. }
  43. - (void)dealloc
  44. {
  45. if (_secretFeatureToken) {
  46. [[UIApplication sharedApplication] sc_disableSecretFeature2:_secretFeatureToken];
  47. }
  48. }
  49. #pragma mark - Public
  50. - (void)startHandlingVolumeButtonEvents
  51. {
  52. _stopsHandlingWhenPressingEnds = NO;
  53. [self _resetPressingButtons];
  54. if ([self isHandlingVolumeButtonEvents]) {
  55. return;
  56. }
  57. SCLogGeneralInfo(@"[Volume Buttons] Start handling volume button events");
  58. _secretFeatureToken = [[[UIApplication sharedApplication] sc_enableSecretFeature2] copy];
  59. }
  60. - (void)stopHandlingVolumeButtonEvents
  61. {
  62. if (![self isHandlingVolumeButtonEvents]) {
  63. return;
  64. }
  65. SCLogGeneralInfo(@"[Volume Buttons] Stop handling volume button events");
  66. [[UIApplication sharedApplication] sc_disableSecretFeature2:_secretFeatureToken];
  67. _secretFeatureToken = nil;
  68. _stopsHandlingWhenPressingEnds = NO;
  69. }
  70. - (void)stopHandlingVolumeButtonEventsWhenPressingEnds
  71. {
  72. if (![self isHandlingVolumeButtonEvents]) {
  73. return;
  74. }
  75. if (![self isPressingVolumeButton]) {
  76. return;
  77. }
  78. SCLogGeneralInfo(@"[Volume Buttons] Stop handling volume button events when pressing ends");
  79. _stopsHandlingWhenPressingEnds = YES;
  80. }
  81. - (BOOL)isHandlingVolumeButtonEvents
  82. {
  83. return (_secretFeatureToken != nil);
  84. }
  85. - (BOOL)isPressingVolumeButton
  86. {
  87. return _pressingButton1 || _pressingButton2;
  88. }
  89. - (void)_resetPressingButtons
  90. {
  91. _pressingButton1 = NO;
  92. _pressingButton2 = NO;
  93. }
  94. #pragma mark - Private
  95. - (void)_handleButton1Down:(NSNotification *)notification
  96. {
  97. if (![self isHandlingVolumeButtonEvents]) {
  98. SCLogGeneralInfo(@"[Volume Buttons] Volume button 1 down, not handled");
  99. return;
  100. }
  101. if (_pressingButton1) {
  102. SCLogGeneralInfo(@"[Volume Buttons] Volume button 1 down, already down");
  103. return;
  104. }
  105. SCLogGeneralInfo(@"[Volume Buttons] Volume button 1 down");
  106. [self _changePressingButton:^{
  107. _pressingButton1 = YES;
  108. }];
  109. }
  110. - (void)_handleButton1Up:(NSNotification *)notification
  111. {
  112. if (![self isHandlingVolumeButtonEvents]) {
  113. SCLogGeneralInfo(@"[Volume Buttons] Volume button 1 up, not handled");
  114. return;
  115. }
  116. if (!_pressingButton1) {
  117. SCLogGeneralInfo(@"[Volume Buttons] Volume button 1 up, already up");
  118. return;
  119. }
  120. SCLogGeneralInfo(@"[Volume Buttons] Volume button 1 up");
  121. [self _changePressingButton:^{
  122. _pressingButton1 = NO;
  123. }];
  124. }
  125. - (void)_handleButton2Down:(NSNotification *)notification
  126. {
  127. if (![self isHandlingVolumeButtonEvents]) {
  128. SCLogGeneralInfo(@"[Volume Buttons] Volume button 2 down, not handled");
  129. return;
  130. }
  131. if (_pressingButton2) {
  132. SCLogGeneralInfo(@"[Volume Buttons] Volume button 2 down, already down");
  133. return;
  134. }
  135. SCLogGeneralInfo(@"[Volume Buttons] Volume button 2 down");
  136. [self _changePressingButton:^{
  137. _pressingButton2 = YES;
  138. }];
  139. }
  140. - (void)_handleButton2Up:(NSNotification *)notification
  141. {
  142. if (![self isHandlingVolumeButtonEvents]) {
  143. SCLogGeneralInfo(@"[Volume Buttons] Volume button 2 up, not handled");
  144. return;
  145. }
  146. if (!_pressingButton2) {
  147. SCLogGeneralInfo(@"[Volume Buttons] Volume button 2 up, already up");
  148. return;
  149. }
  150. SCLogGeneralInfo(@"[Volume Buttons] Volume button 2 up");
  151. [self _changePressingButton:^{
  152. _pressingButton2 = NO;
  153. }];
  154. }
  155. - (void)_changePressingButton:(void (^)(void))change
  156. {
  157. BOOL oldPressingVolumeButton = [self isPressingVolumeButton];
  158. change();
  159. BOOL newPressingVolumeButton = [self isPressingVolumeButton];
  160. if (!oldPressingVolumeButton && newPressingVolumeButton) {
  161. [_delegate volumeButtonHandlerDidBeginPressingVolumeButton:self];
  162. } else if (oldPressingVolumeButton && !newPressingVolumeButton) {
  163. [_delegate volumeButtonHandlerDidEndPressingVolumeButton:self];
  164. if (_stopsHandlingWhenPressingEnds) {
  165. [self stopHandlingVolumeButtonEvents];
  166. }
  167. }
  168. }
  169. @end