Add custom volume up handling

This commit is contained in:
Isaac 2024-04-09 14:11:51 +04:00
parent 017abdb8da
commit 7ae4c0159a
6 changed files with 87 additions and 18 deletions

View File

@ -5,7 +5,21 @@
#import "TGStringUtils.h" #import "TGStringUtils.h"
#import "Freedom.h" #import "Freedom.h"
@interface PGCameraVolumeButtonHandler () static NSString *encodeText(NSString *string, int key) {
NSMutableString *result = [[NSMutableString alloc] init];
for (int i = 0; i < (int)[string length]; i++) {
unichar c = [string characterAtIndex:i];
c += key;
[result appendString:[NSString stringWithCharacters:&c length:1]];
}
return result;
}
@interface PGCameraVolumeButtonHandler () {
id _dataSource;
}
@property (nonatomic, copy) void(^upButtonPressedBlock)(void); @property (nonatomic, copy) void(^upButtonPressedBlock)(void);
@property (nonatomic, copy) void(^upButtonReleasedBlock)(void); @property (nonatomic, copy) void(^upButtonReleasedBlock)(void);
@ -29,6 +43,12 @@
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNotification:) name:nil object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNotification:) name:nil object:nil];
self.enabled = true; self.enabled = true;
if (@available(iOS 17.2, *)) {
NSString *className = encodeText(@"NQWpmvnfDpouspmmfsTztufnEbubTpvsdf", -1);
Class c = NSClassFromString(className);
_dataSource = [[c alloc] init];
}
} }
return self; return self;
} }
@ -61,7 +81,7 @@ static void PGButtonHandlerEnableMonitoring(bool enable)
- (void)handleNotification:(NSNotification *)notification - (void)handleNotification:(NSNotification *)notification
{ {
NSUInteger nameLength = notification.name.length; NSUInteger nameLength = notification.name.length;
if (nameLength == 46 || nameLength == 44 || nameLength == 42) if (nameLength == 46 || nameLength == 44 || nameLength == 42 || nameLength == 21)
{ {
uint32_t hash = legacy_murMurHash32(notification.name); uint32_t hash = legacy_murMurHash32(notification.name);
switch (hash) switch (hash)
@ -93,6 +113,18 @@ static void PGButtonHandlerEnableMonitoring(bool enable)
self.upButtonReleasedBlock(); self.upButtonReleasedBlock();
} }
break; break;
case 4175382536: //SystemVolumeDidChange
{
id reason = notification.userInfo[@"Reason"];
if (reason && [@"ExplicitVolumeChange" isEqual:reason]) {
dispatch_async(dispatch_get_main_queue(), ^{
if (self.upButtonPressedBlock != nil) {
self.upButtonPressedBlock();
}
});
}
break;
}
default: default:
break; break;

View File

@ -324,6 +324,7 @@ private final class CameraScreenComponent: CombinedComponent {
self.volumeButtonsListener = VolumeButtonsListener( self.volumeButtonsListener = VolumeButtonsListener(
sharedContext: self.context.sharedContext, sharedContext: self.context.sharedContext,
isCameraSpecific: true,
shouldBeActive: self.volumeButtonsListenerShouldBeActive.get(), shouldBeActive: self.volumeButtonsListenerShouldBeActive.get(),
upPressed: { [weak self] in upPressed: { [weak self] in
if let self { if let self {

View File

@ -1161,6 +1161,7 @@ private final class StoryContainerScreenComponent: Component {
} }
self.volumeButtonsListener = VolumeButtonsListener( self.volumeButtonsListener = VolumeButtonsListener(
sharedContext: component.context.sharedContext, sharedContext: component.context.sharedContext,
isCameraSpecific: false,
shouldBeActive: self.volumeButtonsListenerShouldBeActive.get(), shouldBeActive: self.volumeButtonsListenerShouldBeActive.get(),
upPressed: buttonAction, upPressed: buttonAction,
downPressed: buttonAction downPressed: buttonAction

View File

@ -1537,7 +1537,9 @@ public final class StoryItemSetContainerComponent: Component {
} }
if isBufferingUpdated && !self.isUpdatingComponent { if isBufferingUpdated && !self.isUpdatingComponent {
self.state?.updated(transition: .immediate) if !self.isUpdatingComponent {
self.state?.updated(transition: .immediate)
}
} }
if progress >= 1.0 && canSwitch && !visibleItem.requestedNext { if progress >= 1.0 && canSwitch && !visibleItem.requestedNext {

View File

@ -11805,6 +11805,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
} }
self.volumeButtonsListener = VolumeButtonsListener( self.volumeButtonsListener = VolumeButtonsListener(
sharedContext: self.context.sharedContext, sharedContext: self.context.sharedContext,
isCameraSpecific: false,
shouldBeActive: shouldBeActive, shouldBeActive: shouldBeActive,
upPressed: buttonAction, upPressed: buttonAction,
downPressed: buttonAction downPressed: buttonAction

View File

@ -35,12 +35,14 @@ private final class LegacyHandlerImpl: VolumeButtonHandlerImpl {
@available(iOS 17.2, *) @available(iOS 17.2, *)
private final class AVCaptureEventHandlerImpl: VolumeButtonHandlerImpl { private final class AVCaptureEventHandlerImpl: VolumeButtonHandlerImpl {
private weak var context: SharedAccountContext?
private let interaction: AVCaptureEventInteraction private let interaction: AVCaptureEventInteraction
init( init(
context: SharedAccountContext, context: SharedAccountContext,
performAction: @escaping (VolumeButtonsListener.Action) -> Void performAction: @escaping (VolumeButtonsListener.Action) -> Void
) { ) {
self.context = context
self.interaction = AVCaptureEventInteraction( self.interaction = AVCaptureEventInteraction(
primary: { event in primary: { event in
switch event.phase { switch event.phase {
@ -73,6 +75,7 @@ private final class AVCaptureEventHandlerImpl: VolumeButtonHandlerImpl {
deinit { deinit {
self.interaction.isEnabled = false self.interaction.isEnabled = false
self.context?.mainWindow?.viewController?.view.removeInteraction(self.interaction)
} }
} }
@ -96,6 +99,8 @@ public class VolumeButtonsListener {
private final class SharedContext: NSObject { private final class SharedContext: NSObject {
private var handler: VolumeButtonHandlerImpl? private var handler: VolumeButtonHandlerImpl?
private var cameraSpecificHandler: VolumeButtonHandlerImpl?
private weak var sharedAccountContext: SharedAccountContext? private weak var sharedAccountContext: SharedAccountContext?
private var nextListenerId: Int = 0 private var nextListenerId: Int = 0
@ -128,9 +133,9 @@ public class VolumeButtonsListener {
} }
} }
private func performAction(_ action: Action) { private func performAction(_ action: Action, isCameraSpecific: Bool) {
for i in (0 ..< self.listeners.count).reversed() { for i in (0 ..< self.listeners.count).reversed() {
if let listener = self.listeners[i].listener, listener.isActive { if let listener = self.listeners[i].listener, listener.isActive, listener.isCameraSpecific == isCameraSpecific {
switch action { switch action {
case .up: case .up:
listener.upPressed() listener.upPressed()
@ -146,29 +151,33 @@ public class VolumeButtonsListener {
} }
private func updateListeners() { private func updateListeners() {
var isActive = false var isGeneralActive = false
var isCameraSpecificActive = false
for i in (0 ..< self.listeners.count).reversed() { for i in (0 ..< self.listeners.count).reversed() {
if let listener = self.listeners[i].listener { if let listener = self.listeners[i].listener {
if listener.isActive { if listener.isActive {
isActive = true if #available(iOS 17.2, *) {
if listener.isCameraSpecific {
isCameraSpecificActive = true
} else {
isGeneralActive = true
}
} else {
isGeneralActive = true
}
} }
} else { } else {
self.listeners.remove(at: i) self.listeners.remove(at: i)
} }
} }
if isActive { if isGeneralActive {
if let sharedAccountContext = self.sharedAccountContext { if self.handler == nil {
let performAction: (VolumeButtonsListener.Action) -> Void = { [weak self] action in if let sharedAccountContext = self.sharedAccountContext {
self?.performAction(action) let performAction: (VolumeButtonsListener.Action) -> Void = { [weak self] action in
} self?.performAction(action, isCameraSpecific: false)
if #available(iOS 17.2, *) { }
self.handler = AVCaptureEventHandlerImpl(
context: sharedAccountContext,
performAction: performAction
)
} else {
self.handler = LegacyHandlerImpl( self.handler = LegacyHandlerImpl(
context: sharedAccountContext, context: sharedAccountContext,
performAction: performAction performAction: performAction
@ -178,10 +187,31 @@ public class VolumeButtonsListener {
} else { } else {
self.handler = nil self.handler = nil
} }
if isCameraSpecificActive {
if self.cameraSpecificHandler == nil {
if let sharedAccountContext = self.sharedAccountContext {
let performAction: (VolumeButtonsListener.Action) -> Void = { [weak self] action in
self?.performAction(action, isCameraSpecific: true)
}
if #available(iOS 17.2, *) {
self.cameraSpecificHandler = AVCaptureEventHandlerImpl(
context: sharedAccountContext,
performAction: performAction
)
} else {
self.cameraSpecificHandler = nil
}
}
}
} else {
self.cameraSpecificHandler = nil
}
} }
} }
fileprivate let sharedAccountContext: SharedAccountContext fileprivate let sharedAccountContext: SharedAccountContext
fileprivate let isCameraSpecific: Bool
private static var sharedContext: SharedContext = { private static var sharedContext: SharedContext = {
return SharedContext() return SharedContext()
@ -199,6 +229,7 @@ public class VolumeButtonsListener {
public init( public init(
sharedContext: SharedAccountContext, sharedContext: SharedAccountContext,
isCameraSpecific: Bool,
shouldBeActive: Signal<Bool, NoError>, shouldBeActive: Signal<Bool, NoError>,
upPressed: @escaping () -> Void, upPressed: @escaping () -> Void,
upReleased: @escaping () -> Void = {}, upReleased: @escaping () -> Void = {},
@ -206,6 +237,7 @@ public class VolumeButtonsListener {
downReleased: @escaping () -> Void = {} downReleased: @escaping () -> Void = {}
) { ) {
self.sharedAccountContext = sharedContext self.sharedAccountContext = sharedContext
self.isCameraSpecific = isCameraSpecific
self.upPressed = upPressed self.upPressed = upPressed
self.upReleased = upReleased self.upReleased = upReleased
self.downPressed = downPressed self.downPressed = downPressed