Skip to content

Commit

Permalink
add dock alignment preference
Browse files Browse the repository at this point in the history
  • Loading branch information
EthanArbuckle committed Jan 19, 2021
1 parent f83f107 commit 796fcd6
Show file tree
Hide file tree
Showing 11 changed files with 171 additions and 64 deletions.
1 change: 0 additions & 1 deletion carplayenableprefs/CPAppListController.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

@property (nonatomic, retain) UITableView *rootTable;
@property (nonatomic, retain) NSArray *appList;
@property (nonatomic, retain) NSDictionary *cachedPreferences;

- (id)initWithAppList:(NSArray *)appList;

Expand Down
39 changes: 5 additions & 34 deletions carplayenableprefs/CPAppListController.m
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ - (id)initWithAppList:(NSArray *)appList
NSArray *sortDescriptors = [NSArray arrayWithObject:nameDescriptor];
_appList = [appList sortedArrayUsingDescriptors:sortDescriptors];

[self reloadPreferences];

_rootTable = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height) style:UITableViewStyleGrouped];
[_rootTable setDelegate:self];
[_rootTable setDataSource:self];
Expand All @@ -24,39 +22,15 @@ - (id)initWithAppList:(NSArray *)appList
return self;
}

- (void)reloadPreferences
{
if ([[NSFileManager defaultManager] fileExistsAtPath:PREFERENCES_PLIST_PATH])
{
_cachedPreferences = [[NSDictionary alloc] initWithContentsOfFile:PREFERENCES_PLIST_PATH];
}
else {
_cachedPreferences = @{};
}
}

- (BOOL)isAppCarplayEnabled:(NSString *)identifier
{
if (_cachedPreferences && [_cachedPreferences valueForKey:@"excludedApps"])
{
NSArray *excludedIdentifiers = _cachedPreferences[@"excludedApps"];
return [excludedIdentifiers containsObject:identifier] == NO;
}

return YES;
{
NSArray *excludedApps = [[CRPreferences sharedInstance] excludedApplications];
return [excludedApps containsObject:identifier] == NO;
}

- (void)setApp:(NSString *)identifier shouldBeExcluded:(BOOL)shouldExclude
{
NSMutableArray *excludedApps;
if (_cachedPreferences && [_cachedPreferences valueForKey:@"excludedApps"])
{
excludedApps = [_cachedPreferences[@"excludedApps"] mutableCopy];
}
else
{
excludedApps = [[NSMutableArray alloc] init];
}
NSMutableArray *excludedApps = [[[CRPreferences sharedInstance] excludedApplications] mutableCopy];

BOOL alreadyExcluded = [excludedApps containsObject:identifier];
if (shouldExclude && !alreadyExcluded)
Expand All @@ -68,10 +42,7 @@ - (void)setApp:(NSString *)identifier shouldBeExcluded:(BOOL)shouldExclude
[excludedApps removeObject:identifier];
}

NSMutableDictionary *updatedPrefs = [_cachedPreferences mutableCopy];
updatedPrefs[@"excludedApps"] = excludedApps;
_cachedPreferences = updatedPrefs;
[_cachedPreferences writeToFile:PREFERENCES_PLIST_PATH atomically:NO];
[[CRPreferences sharedInstance] updateValue:excludedApps forPreferenceKey:@"excludedApps"];

// Notify CarPlay of the changes
[[objc_getClass("NSDistributedNotificationCenter") defaultCenter] postNotification:[NSNotification notificationWithName:PREFERENCES_CHANGED_NOTIFICATION object:kPrefsAppLibraryChanged]];
Expand Down
28 changes: 25 additions & 3 deletions carplayenableprefs/CRERootListController.m
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@ - (id)initForContentSize:(CGSize)size
[[objc_getClass("NSDistributedNotificationCenter") defaultCenter] addObserverForName:PREFERENCES_APP_DATA_NOTIFICATION object:kPrefsAppDataReceiving queue:notificationQueue usingBlock:^(NSNotification * _Nonnull note) {
NSDictionary *data = [note userInfo];
// Create AppList controller
_appListController = [[CPAppListController alloc] initWithAppList:data[@"appList"]];
NSArray *appList = data[@"appList"];
if (appList)
{
dispatch_sync(dispatch_get_main_queue(), ^(void) {
_appListController = [[CPAppListController alloc] initWithAppList:appList];
});
}
}];

// Ask Springboard for the app data. This may have a little delay, so its being fetched before the user opens the App List controller
Expand All @@ -36,7 +42,7 @@ -(void)viewDidLoad

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
return 2;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
Expand Down Expand Up @@ -82,8 +88,17 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
else if (indexPath.row == 2)
{
[[cell textLabel] setText:@"Auto"];

}

if (indexPath.row == [[CRPreferences sharedInstance] dockAlignment])
{
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
}
else
{
[cell setAccessoryType:UITableViewCellAccessoryNone];
}
}

return cell;
Expand All @@ -108,7 +123,7 @@ - (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInte
switch (section)
{
case 0:
//return @"";
return @"";
case 1:
return @"Created by Ethan Arbuckle";
default:
Expand All @@ -133,11 +148,18 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
break;
}
case 1:
{
// Save the new setting
[[CRPreferences sharedInstance] updateValue:@(indexPath.row) forPreferenceKey:@"dockAlignment"];
// Notify CarPlay of the changes
[[objc_getClass("NSDistributedNotificationCenter") defaultCenter] postNotification:[NSNotification notificationWithName:PREFERENCES_CHANGED_NOTIFICATION object:kPrefsDockAlignmentChanged]];
break;
}
default:
break;
}

[_rootTable reloadData];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}

Expand Down
2 changes: 1 addition & 1 deletion carplayenableprefs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ include $(THEOS)/makefiles/common.mk

BUNDLE_NAME = carplayenableprefs

carplayenableprefs_FILES = $(wildcard *.m)
carplayenableprefs_FILES = $(wildcard *.m) ../src/CRPreferences.mm
carplayenableprefs_INSTALL_PATH = /Library/PreferenceBundles
carplayenableprefs_FRAMEWORKS = UIKit
carplayenableprefs_PRIVATE_FRAMEWORKS = Preferences
Expand Down
1 change: 1 addition & 0 deletions src/CRCarplayWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ id getCarplayCADisplay(void);
@property (nonatomic, retain) id appViewController;
@property (nonatomic, retain) id sceneMonitor;
@property (nonatomic, retain) id application;
@property (nonatomic, retain) NSMutableArray *observers;

@property (nonatomic) int orientation;
@property (nonatomic) BOOL isFullscreen;
Expand Down
48 changes: 42 additions & 6 deletions src/CRCarplayWindow.mm
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ - (id)initWithBundleIdentifier:(id)identifier
{
if ((self = [super init]))
{
_observers = [[NSMutableArray alloc] init];
// Update this processes' preference cache
[[CRPreferences sharedInstance] reloadPreferences];

// Start in landscape
self.orientation = 3;

Expand All @@ -55,6 +59,7 @@ - (id)initWithBundleIdentifier:(id)identifier

[self.rootWindow.layer setCornerRadius:13.0f];
[self.rootWindow.layer setMasksToBounds:YES];
[self setupWallpaperBackground];
[self setupDock];

[self setupLiveAppView];
Expand Down Expand Up @@ -99,17 +104,25 @@ - (id)initWithBundleIdentifier:(id)identifier
objcInvoke(appSceneView, @"drawCarplayPlaceholder");
}
}

// Add observer the user changing the Dock's Alignment via preferences
id observer = [[objc_getClass("NSDistributedNotificationCenter") defaultCenter] addObserverForName:PREFERENCES_CHANGED_NOTIFICATION object:kPrefsDockAlignmentChanged queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
// Update this processes' preference cache
[[CRPreferences sharedInstance] reloadPreferences];
// Redraw the dock
[self setupDock];
// Relayout the app view
[self resizeAppViewForOrientation:_orientation fullscreen:_isFullscreen forceUpdate:YES];
}];
[_observers addObject:observer];
}

return self;
}

- (void)setupDock
- (void)setupWallpaperBackground
{
CGRect rootWindowFrame = [[self rootWindow] frame];
UITraitCollection *carplayTrait = [UITraitCollection traitCollectionWithUserInterfaceIdiom:3];
UITraitCollection *interfaceStyleTrait = [UITraitCollection traitCollectionWithUserInterfaceStyle:1];
UITraitCollection *traitCollection = [UITraitCollection traitCollectionWithTraitsFromCollections:@[carplayTrait, interfaceStyleTrait]];

UIImageView *wallpaperImageView = [[UIImageView alloc] initWithFrame:rootWindowFrame];
id defaultWallpaper = objcInvoke(objc_getClass("CRSUIWallpaperPreferences"), @"defaultWallpaper");
Expand All @@ -121,8 +134,21 @@ - (void)setupDock
[wallpaperBlurView setFrame:rootWindowFrame];
[wallpaperImageView addSubview:wallpaperBlurView];
[[self rootWindow] addSubview:wallpaperImageView];
}

- (void)setupDock
{
// If the dock already exists, remove it. This allows the dock to be redrawn easily if the user switches the alignment
if (_dockView)
{
[_dockView removeFromSuperview];
}

self.dockView = [[UIView alloc] initWithFrame:CGRectMake(0, rootWindowFrame.origin.y, CARPLAY_DOCK_WIDTH, rootWindowFrame.size.height)];
CGRect rootWindowFrame = [[self rootWindow] frame];
BOOL rightHandDock = [[CRPreferences sharedInstance] dockAlignment] == CRDockAlignmentRight;

CGFloat dockXOrigin = (rightHandDock) ? rootWindowFrame.size.width - CARPLAY_DOCK_WIDTH : 0;
self.dockView = [[UIView alloc] initWithFrame:CGRectMake(dockXOrigin, rootWindowFrame.origin.y, CARPLAY_DOCK_WIDTH, rootWindowFrame.size.height)];

// Setup dock visual effects
id blurEffect = objcInvoke_1(objc_getClass("UIBlurEffect"), @"effectWithBlurRadius:", 20.0);
Expand All @@ -137,6 +163,9 @@ - (void)setupDock
[[self rootWindow] addSubview:self.dockView];

NSBundle *carplayBundle = [NSBundle bundleWithPath:@"/System/Library/CoreServices/CarPlay.app"];
UITraitCollection *carplayTrait = [UITraitCollection traitCollectionWithUserInterfaceIdiom:3];
UITraitCollection *interfaceStyleTrait = [UITraitCollection traitCollectionWithUserInterfaceStyle:1];
UITraitCollection *traitCollection = [UITraitCollection traitCollectionWithTraitsFromCollections:@[carplayTrait, interfaceStyleTrait]];

CGFloat buttonSize = 35;
UIButton *closeButton = [UIButton buttonWithType:UIButtonTypeCustom];
Expand Down Expand Up @@ -372,6 +401,12 @@ - (void)dismiss
// Invalidate the scene monitor
[self.sceneMonitor invalidate];

// Remove any observers
for (id observer in _observers)
{
[[objc_getClass("NSDistributedNotificationCenter") defaultCenter] removeObserver:observer];
}

void (^cleanupAfterCarplay)() = ^() {
// Notify the application process to stop enforcing an orientation lock
int resetOrientationLock = -1;
Expand Down Expand Up @@ -519,9 +554,10 @@ - (void)resizeAppViewForOrientation:(int)desiredOrientation fullscreen:(BOOL)ful
[hostingContentView setTransform:CGAffineTransformMakeScale(widthScale, heightScale)];
[[self.appViewController view] setFrame:CGRectMake(xOrigin, [[self.appViewController view] frame].origin.y, carplayDisplaySize.width, carplayDisplaySize.height)];

BOOL rightHandDock = [[CRPreferences sharedInstance] dockAlignment] == CRDockAlignmentRight;
UIView *containingView = [self appContainerView];
CGRect containingViewFrame = [containingView frame];
containingViewFrame.origin.x = dockWidth;
containingViewFrame.origin.x = (rightHandDock) ? 0 : dockWidth;
[containingView setFrame:containingViewFrame];

[self.dockView setAlpha: (fullscreen) ? 0: 1];
Expand Down
22 changes: 22 additions & 0 deletions src/CRPreferences.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include <Foundation/Foundation.h>

typedef NS_ENUM(NSInteger, CRDockAlignment) {
CRDockAlignmentLeft = 0,
CRDockAlignmentRight,
CRDockAlignmentAuto,
};

@interface CRPreferences : NSObject

@property (nonatomic, retain) NSDictionary *cachedPreferences;

+ (instancetype)sharedInstance;

- (void)reloadPreferences;
- (void)writePreferences;
- (void)updateValue:(id)value forPreferenceKey:(NSString *)key;

- (NSArray *)excludedApplications;
- (CRDockAlignment)dockAlignment;

@end
69 changes: 69 additions & 0 deletions src/CRPreferences.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#include "common.h"

@implementation CRPreferences

+ (instancetype)sharedInstance
{
static CRPreferences *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[CRPreferences alloc] init];
});
return sharedInstance;
}

- (id)init
{
if ((self = [super init]))
{
[self reloadPreferences];
}

return self;
}

- (void)reloadPreferences
{
if ([[NSFileManager defaultManager] fileExistsAtPath:PREFERENCES_PLIST_PATH])
{
_cachedPreferences = [[NSDictionary alloc] initWithContentsOfFile:PREFERENCES_PLIST_PATH];
}
else {
_cachedPreferences = @{};
}
}

- (void)writePreferences
{
[_cachedPreferences writeToFile:PREFERENCES_PLIST_PATH atomically:NO];
}

- (void)updateValue:(id)value forPreferenceKey:(NSString *)key
{
NSMutableDictionary *copy = [_cachedPreferences mutableCopy];
copy[key] = value;
_cachedPreferences = copy;
[self writePreferences];
}

- (NSArray *)excludedApplications
{
if (_cachedPreferences && [_cachedPreferences valueForKey:@"excludedApps"])
{
return [_cachedPreferences valueForKey:@"excludedApps"];
}

return @[];
}

- (CRDockAlignment)dockAlignment
{
if (_cachedPreferences && [_cachedPreferences valueForKey:@"dockAlignment"])
{
return (CRDockAlignment)[[_cachedPreferences valueForKey:@"dockAlignment"] intValue];
}

return CRDockAlignmentAuto;
}

@end
2 changes: 2 additions & 0 deletions src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <UIKit/UIKit.h>
#include <objc/message.h>
#include <dlfcn.h>
#include "CRPreferences.h"

#define BAIL_IF_UNSUPPORTED_IOS { \
if ([[[UIDevice currentDevice] systemVersion] compare:@"14.0" options:NSNumericSearch] == NSOrderedAscending) \
Expand Down Expand Up @@ -42,6 +43,7 @@ static char *kPropertyKey_didDrawPlaceholder;
#define kPrefsAppDataRequesting @"Requesting"
#define kPrefsAppDataReceiving @"Receiving"
#define kPrefsAppLibraryChanged @"appLibrary"
#define kPrefsDockAlignmentChanged @"dockAlignment"

#define BLACKLIST_PLIST_PATH @"/var/mobile/Library/Preferences/com.carplayenable.blacklisted-apps.plist"

Expand Down
Loading

0 comments on commit 796fcd6

Please sign in to comment.