Block device from sleeping during certain activities.

// FREEBIE
This commit is contained in:
Matthew Chen 2017-07-05 10:49:27 -04:00
parent 700f3229bc
commit 0244e134f5
5 changed files with 116 additions and 11 deletions

View File

@ -34,6 +34,7 @@
3456710A1E8A9F5D006EE662 /* TSGenericAttachmentAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = 345671091E8A9F5D006EE662 /* TSGenericAttachmentAdapter.m */; };
3471B1DA1EB7C63600F6AEC8 /* NewNonContactConversationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3471B1D91EB7C63600F6AEC8 /* NewNonContactConversationViewController.m */; };
3472229F1EB22FFE00E53955 /* AddToGroupViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3472229E1EB22FFE00E53955 /* AddToGroupViewController.m */; };
348F2EAE1F0D21BC00D4ECE0 /* DeviceSleepManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 348F2EAD1F0D21BC00D4ECE0 /* DeviceSleepManager.swift */; };
3497DBEC1ECE257500DB2605 /* OWSCountryMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 3497DBEB1ECE257500DB2605 /* OWSCountryMetadata.m */; };
3497DBEF1ECE2E4700DB2605 /* DomainFrontingCountryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3497DBEE1ECE2E4700DB2605 /* DomainFrontingCountryViewController.m */; };
34B3F8711E8DF1700035BE1A /* AboutTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8351E8DF1700035BE1A /* AboutTableViewController.m */; };
@ -414,6 +415,7 @@
3471B1D91EB7C63600F6AEC8 /* NewNonContactConversationViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NewNonContactConversationViewController.m; sourceTree = "<group>"; };
3472229D1EB22FFE00E53955 /* AddToGroupViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AddToGroupViewController.h; sourceTree = "<group>"; };
3472229E1EB22FFE00E53955 /* AddToGroupViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AddToGroupViewController.m; sourceTree = "<group>"; };
348F2EAD1F0D21BC00D4ECE0 /* DeviceSleepManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeviceSleepManager.swift; sourceTree = "<group>"; };
3497DBEA1ECE257500DB2605 /* OWSCountryMetadata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSCountryMetadata.h; sourceTree = "<group>"; };
3497DBEB1ECE257500DB2605 /* OWSCountryMetadata.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSCountryMetadata.m; sourceTree = "<group>"; };
3497DBED1ECE2E4700DB2605 /* DomainFrontingCountryViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DomainFrontingCountryViewController.h; sourceTree = "<group>"; };
@ -1326,6 +1328,7 @@
76EB04CF18170B33006006FC /* collections */,
B90418E4183E9DD40038554A /* DateUtil.h */,
B90418E5183E9DD40038554A /* DateUtil.m */,
348F2EAD1F0D21BC00D4ECE0 /* DeviceSleepManager.swift */,
45E615151E8C590B0018AD52 /* DisplayableTextFilter.swift */,
76EB04EA18170B33006006FC /* FunctionalUtil.h */,
76EB04EB18170B33006006FC /* FunctionalUtil.m */,
@ -2126,6 +2129,7 @@
34B3F8931E8DF1710035BE1A /* SignalsNavigationController.m in Sources */,
76EB063A18170B33006006FC /* FunctionalUtil.m in Sources */,
34F308A21ECB469700BB7697 /* OWSBezierPathView.m in Sources */,
348F2EAE1F0D21BC00D4ECE0 /* DeviceSleepManager.swift in Sources */,
34E3EF101EFC2684007F6822 /* DebugUIPage.m in Sources */,
34E8BF3B1EEB208E00F5F4CA /* DebugUIVerification.m in Sources */,
76EB058A18170B33006006FC /* Release.m in Sources */,

View File

@ -3628,6 +3628,18 @@ typedef enum : NSUInteger {
self.voiceMessageUUID = nil;
}
- (void)setAudioRecorder:(AVAudioRecorder *)audioRecorder
{
// Prevent device from sleeping while recording a voice message.
if (audioRecorder) {
[DeviceSleepManager.sharedInstance addBlockWithBlockObject:audioRecorder];
} else if (_audioRecorder) {
[DeviceSleepManager.sharedInstance removeBlockWithBlockObject:_audioRecorder];
}
_audioRecorder = audioRecorder;
}
#pragma mark Accessory View
- (void)didPressAccessoryButton:(UIButton *)sender

View File

@ -82,6 +82,8 @@ NS_ASSUME_NONNULL_BEGIN
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[DeviceSleepManager.sharedInstance removeBlockWithBlockObject:self];
[self stop];
}
@ -133,6 +135,9 @@ NS_ASSUME_NONNULL_BEGIN
selector:@selector(audioPlayerUpdated:)
userInfo:nil
repeats:YES];
// Prevent device from sleeping while playing audio.
[DeviceSleepManager.sharedInstance addBlockWithBlockObject:self];
}
- (void)pause
@ -145,6 +150,8 @@ NS_ASSUME_NONNULL_BEGIN
[self.audioPlayerPoller invalidate];
[self.delegate setAudioProgress:[self.audioPlayer currentTime] duration:[self.audioPlayer duration]];
[self.delegate setAudioIconToPlay];
[DeviceSleepManager.sharedInstance removeBlockWithBlockObject:self];
}
- (void)stop
@ -157,6 +164,8 @@ NS_ASSUME_NONNULL_BEGIN
[self.delegate setAudioIconToPlay];
self.delegate.isAudioPlaying = NO;
self.delegate.isPaused = NO;
[DeviceSleepManager.sharedInstance removeBlockWithBlockObject:self];
}
- (void)togglePlayState

View File

@ -138,7 +138,16 @@ protocol CallServiceObserver: class {
call?.addObserverAndSyncState(observer: self)
updateIsVideoEnabled()
updateLockTimerEnabling()
// Prevent device from sleeping while we have an active call.
if oldValue != call {
if let oldValue = oldValue {
DeviceSleepManager.sharedInstance.removeBlock(blockObject: oldValue)
}
if let call = call {
DeviceSleepManager.sharedInstance.addBlock(blockObject: call)
}
}
Logger.debug("\(self.TAG) .call setter: \(oldValue?.identifiersForLogs as Optional) -> \(call?.identifiersForLogs as Optional)")
@ -1351,16 +1360,6 @@ protocol CallServiceObserver: class {
remoteVideoTrack:remoteVideoTrack)
}
}
private func updateLockTimerEnabling() {
AssertIsOnMainThread()
// Prevent screen from dimming during call.
//
// Note that this state has no effect if app is in the background.
let hasCall = call != nil
UIApplication.shared.isIdleTimerDisabled = hasCall
}
}
fileprivate extension MessageSender {

View File

@ -0,0 +1,81 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
import Foundation
// This entity has responsibility for blocking the device from sleeping if
// certain behaviors (e.g. recording or playing voice messages) are in progress.
//
// Sleep blocking is keyed using "block objects" whose lifetime correponds to
// the duration of the block. For example, sleep blocking during audio playback
// can be keyed to the audio player. This provides a measure of robustness.
// On the one hand, we can use weak references to track block objects and stop
// blocking if the block object is deallocated even if removeBlock() is not
// called. On the other hand, we will also get correct behavior to addBlock()
// being called twice with the same block object.
@objc class DeviceSleepManager: NSObject {
let TAG = "[DeviceSleepManager]"
static let sharedInstance = DeviceSleepManager()
private class SleepBlock {
weak var blockObject: NSObject?
init(blockObject: NSObject) {
self.blockObject = blockObject
}
}
private var blocks: [SleepBlock] = []
override init() {
super.init()
NotificationCenter.default.addObserver(self,
selector:#selector(didEnterBackground),
name:NSNotification.Name.UIApplicationDidEnterBackground,
object:nil)
}
deinit {
NotificationCenter.default.removeObserver(self)
}
func didEnterBackground() {
AssertIsOnMainThread()
ensureSleepBlocking()
}
public func addBlock(blockObject: NSObject) {
blocks.append(SleepBlock(blockObject: blockObject))
ensureSleepBlocking()
}
public func removeBlock(blockObject: NSObject) {
blocks = blocks.filter {
$0.blockObject != nil && $0.blockObject != blockObject
}
ensureSleepBlocking()
}
private func ensureSleepBlocking() {
// Cull expired blocks.
blocks = blocks.filter {
$0.blockObject != nil
}
let shouldBlock = blocks.count > 0
if UIApplication.shared.isIdleTimerDisabled != shouldBlock {
if shouldBlock {
Logger.info("\(self.TAG) \(#function): Blocking sleep")
} else {
Logger.info("\(self.TAG) \(#function): Unblocking sleep")
}
}
UIApplication.shared.isIdleTimerDisabled = shouldBlock
}
}