call: prevent display sleep during call

Change-Id: If3af66d9e4519ca66f8fa844396afd5c429d0ce6
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 80f8325..fb03487 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -494,6 +494,7 @@
 SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -framework SystemConfiguration")
 SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -framework MetalKit")
 SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -framework Metal")
+SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -framework IOKit")
 
 # These variables are specific to our plist and are NOT standard CMake variables
 SET(MACOSX_BUNDLE_NSMAIN_NIB_FILE "MainMenu")
diff --git a/src/AppDelegate.h b/src/AppDelegate.h
index 8f3682d..a376fab 100644
--- a/src/AppDelegate.h
+++ b/src/AppDelegate.h
@@ -30,5 +30,7 @@
 - (BOOL) checkForRingAccount;
 - (QVector<QString>) getActiveCalls;
 - (QVector<QString>)getConferenceSubcalls:(QString)confId;
+- (void) disableScreenSleep;
+- (void) restoreScreenSleep;
 
 @end
diff --git a/src/AppDelegate.mm b/src/AppDelegate.mm
index 6861b91..1a91040 100644
--- a/src/AppDelegate.mm
+++ b/src/AppDelegate.mm
@@ -17,6 +17,8 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
  */
 #import <SystemConfiguration/SystemConfiguration.h>
+#import <CoreFoundation/CoreFoundation.h>
+#import <IOKit/pwr_mgt/IOPMLib.h>
 
 #import "AppDelegate.h"
 
@@ -62,6 +64,8 @@
 NSString * const CONTACT_URI = @"contact_uri_notification_info";
 NSString * const NOTIFICATION_TYPE = @"contact_type_notification_info";
 
+IOPMAssertionID assertionID = 0;
+BOOL sleepDisabled = false;
 
 @implementation AppDelegate {
 
@@ -141,6 +145,25 @@
     }
 }
 
+- (void) disableScreenSleep
+{
+    if (sleepDisabled) {
+        return;
+    }
+    CFStringRef reasonForActivity= CFSTR("Prevent display sleep during calls");
+    sleepDisabled = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep, kIOPMAssertionLevelOn, reasonForActivity, &assertionID) == kIOReturnSuccess;
+}
+
+- (void) restoreScreenSleep {
+    auto calls = [self getActiveCalls];
+
+    if (!sleepDisabled || !calls.empty()) {
+        return;
+    }
+    IOPMAssertionRelease(assertionID);
+    sleepDisabled = false;
+}
+
 static void ReachabilityCallback(SCNetworkReachabilityRef __unused target, SCNetworkConnectionFlags flags, void* info)
 {
     void (^callbackBlock)(SCNetworkReachabilityFlags) = (__bridge id)info;
diff --git a/src/CurrentCallVC.mm b/src/CurrentCallVC.mm
index 7a985c8..913aa83 100644
--- a/src/CurrentCallVC.mm
+++ b/src/CurrentCallVC.mm
@@ -559,6 +559,8 @@
             [self.delegate callFinished];
             [self removeConferenceLayout];
             [self switchToNextConferenceCall: confUid_];
+            AppDelegate* appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
+            [appDelegate restoreScreenSleep];
             break;
     }
 }
diff --git a/src/RingWindowController.mm b/src/RingWindowController.mm
index e12b096..f83f404 100644
--- a/src/RingWindowController.mm
+++ b/src/RingWindowController.mm
@@ -228,6 +228,8 @@
                      &lrc::api::BehaviorController::showCallView,
                      [self](const QString& accountId,
                             const lrc::api::conversation::Info convInfo){
+        AppDelegate* appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
+        [appDelegate disableScreenSleep];
         auto* accInfo = &self.accountModel->getAccountInfo(accountId);
         try {
             if (accInfo->contactModel->getContact(convInfo.participants[0]).profileInfo.type == lrc::api::profile::Type::PENDING)
@@ -250,6 +252,8 @@
                      &lrc::api::BehaviorController::showIncomingCallView,
                      [self](const QString& accountId,
                             const lrc::api::conversation::Info convInfo){
+        AppDelegate* appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
+        [appDelegate disableScreenSleep];
         auto* accInfo = &self.accountModel->getAccountInfo(accountId);
         auto callModel = accInfo->callModel.get();
         lrc::api::account::ConfProperties_t accountProperties = accInfo->accountModel->getAccountConfig(accInfo->id);