From 2bd47c9eb192b5802ec9ddcc5c8681cee1748aa0 Mon Sep 17 00:00:00 2001 From: ethanarbuckle Date: Wed, 6 Jan 2021 14:17:37 -0800 Subject: [PATCH] dismiss carplay-hosted windows if the carplay screen becomes unavailable --- src/CRCarplayWindow.h | 2 ++ src/hooks/SpringBoard.xm | 24 ++++++++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/CRCarplayWindow.h b/src/CRCarplayWindow.h index 8b93130..eb807ca 100644 --- a/src/CRCarplayWindow.h +++ b/src/CRCarplayWindow.h @@ -1,5 +1,7 @@ #include +id getCarplayCADisplay(void); + @interface CRCarPlayWindow : NSObject @property (nonatomic, retain) UIWindow *rootWindow; diff --git a/src/hooks/SpringBoard.xm b/src/hooks/SpringBoard.xm index 2c8ded7..06016ea 100644 --- a/src/hooks/SpringBoard.xm +++ b/src/hooks/SpringBoard.xm @@ -65,7 +65,7 @@ When an app icon is tapped on the Carplay dashboard { objcInvoke(liveCarplayWindow, @"dismiss"); } - + // Launch the requested app liveCarplayWindow = [[CRCarPlayWindow alloc] initWithBundleIdentifier:identifier]; objc_setAssociatedObject(self, &kPropertyKey_liveCarplayWindow, liveCarplayWindow, OBJC_ASSOCIATION_RETAIN_NONATOMIC); @@ -85,12 +85,15 @@ Invoked when SpringBoard finishes launching // Setup to receive App Launch notifications from the CarPlay process [[objc_getClass("NSDistributedNotificationCenter") defaultCenter] addObserver:self selector:NSSelectorFromString(@"handleCarPlayLaunchNotification:") name:@"com.carplayenable" object:nil]; + // Receive notifications for Carplay connect/disconnect events. When a Carplay screen becomes unavailable while an app is being hosted on it, that app window needs to be closed + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(uiscreenDidDisconnect) name:@"CarPlayIsConnectedDidChange" object:nil]; + NSMutableArray *appIdentifiersToIgnoreLockAssertions = [[NSMutableArray alloc] init]; objc_setAssociatedObject(self, &kPropertyKey_lockAssertionIdentifiers, appIdentifiersToIgnoreLockAssertions, OBJC_ASSOCIATION_RETAIN_NONATOMIC); %orig; - // Upload any relevant crashlogs + // Upload any relevant crashlogs symbolicateAndUploadCrashlogs(); } @@ -100,6 +103,23 @@ Invoked when SpringBoard finishes launching return objc_getAssociatedObject(self, &kPropertyKey_liveCarplayWindow); } +/* +A Carplay connected/disconnected event +*/ +%new +- (void)uiscreenDidDisconnect +{ + LOG_LIFECYCLE_EVENT; + // If a window is being hosted, and the carplay UIScreen disconnected, close the window + id liveCarplayWindow = objcInvoke(self, @"liveCarplayWindow"); + if (liveCarplayWindow && !getCarplayCADisplay()) + { + dispatch_sync(dispatch_get_main_queue(), ^(void) { + objcInvoke(liveCarplayWindow, @"dismiss"); + }); + } +} + %end %hook SBSceneView