-
Notifications
You must be signed in to change notification settings - Fork 98
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add prefs bundle and ability to enable/disable apps
- Loading branch information
1 parent
76530e2
commit 254eab8
Showing
11 changed files
with
442 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#import <Preferences/PSListController.h> | ||
|
||
@interface CPAppListController : PSViewController <UITableViewDelegate, UITableViewDataSource> | ||
|
||
@property (nonatomic, retain) UITableView *rootTable; | ||
@property (nonatomic, retain) NSArray *appList; | ||
@property (nonatomic, retain) NSDictionary *cachedPreferences; | ||
|
||
- (id)initWithAppList:(NSArray *)appList; | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
#include "CPAppListController.h" | ||
#include "../src/common.h" | ||
|
||
@implementation CPAppListController | ||
|
||
- (id)initWithAppList:(NSArray *)appList | ||
{ | ||
if ((self = [super init])) | ||
{ | ||
[self setTitle:@"Add or Remove Apps"]; | ||
// Sort the list by app name | ||
NSSortDescriptor *nameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES]; | ||
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]; | ||
[[self view] addSubview:_rootTable]; | ||
} | ||
|
||
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; | ||
} | ||
|
||
- (void)setApp:(NSString *)identifier shouldBeExcluded:(BOOL)shouldExclude | ||
{ | ||
NSMutableArray *excludedApps; | ||
if (_cachedPreferences && [_cachedPreferences valueForKey:@"excludedApps"]) | ||
{ | ||
excludedApps = [_cachedPreferences[@"excludedApps"] mutableCopy]; | ||
} | ||
else | ||
{ | ||
excludedApps = [[NSMutableArray alloc] init]; | ||
} | ||
|
||
BOOL alreadyExcluded = [excludedApps containsObject:identifier]; | ||
if (shouldExclude && !alreadyExcluded) | ||
{ | ||
[excludedApps addObject:identifier]; | ||
} | ||
else if (!shouldExclude && alreadyExcluded) | ||
{ | ||
[excludedApps removeObject:identifier]; | ||
} | ||
|
||
NSMutableDictionary *updatedPrefs = [_cachedPreferences mutableCopy]; | ||
updatedPrefs[@"excludedApps"] = excludedApps; | ||
_cachedPreferences = updatedPrefs; | ||
[_cachedPreferences writeToFile:PREFERENCES_PLIST_PATH atomically:NO]; | ||
|
||
// Notify CarPlay of the changes | ||
[[objc_getClass("NSDistributedNotificationCenter") defaultCenter] postNotification:[NSNotification notificationWithName:PREFERENCES_CHANGED_NOTIFICATION object:kPrefsAppLibraryChanged]]; | ||
} | ||
|
||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView | ||
{ | ||
return 1; | ||
} | ||
|
||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section | ||
{ | ||
return [_appList count]; | ||
} | ||
|
||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath | ||
{ | ||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"com.carplay.rootcell"]; | ||
if (cell == nil) | ||
{ | ||
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"com.carplay.rootcell"]; | ||
} | ||
|
||
// Get info about the current app | ||
NSDictionary *currentApp = _appList[indexPath.row]; | ||
NSString *appName = currentApp[@"name"]; | ||
NSString *appIdentifier = currentApp[@"bundleID"]; | ||
|
||
// Setup the cell | ||
[[cell textLabel] setText:appName]; | ||
if ([self isAppCarplayEnabled:appIdentifier]) | ||
{ | ||
[cell setAccessoryType:UITableViewCellAccessoryCheckmark]; | ||
} | ||
else | ||
{ | ||
[cell setAccessoryType:UITableViewCellAccessoryNone]; | ||
} | ||
|
||
return cell; | ||
} | ||
|
||
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section | ||
{ | ||
return @"Carplay enabled apps"; | ||
} | ||
|
||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath | ||
{ | ||
[tableView deselectRowAtIndexPath:indexPath animated:YES]; | ||
|
||
NSDictionary *chosenApp = _appList[indexPath.row]; | ||
NSString *appIdentifier = chosenApp[@"bundleID"]; | ||
|
||
BOOL isCurrentlyEnabled = [self isAppCarplayEnabled:appIdentifier]; | ||
[self setApp:appIdentifier shouldBeExcluded:isCurrentlyEnabled]; | ||
|
||
[self.rootTable reloadData]; | ||
} | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#import <Preferences/PSListController.h> | ||
#include "CPAppListController.h" | ||
|
||
@interface CRERootListController : PSViewController <UITableViewDelegate, UITableViewDataSource> | ||
|
||
@property (nonatomic, retain) UITableView *rootTable; | ||
@property (nonatomic, retain) CPAppListController *appListController; | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
#include "CRERootListController.h" | ||
#include "../src/common.h" | ||
|
||
@implementation CRERootListController | ||
|
||
- (id)initForContentSize:(CGSize)size | ||
{ | ||
if ((self = [super init])) | ||
{ | ||
[self setTitle:@"CarPlayEnable Preferences"]; | ||
_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]; | ||
[[self view] addSubview:_rootTable]; | ||
|
||
// The Preference process does not possess the necessary entitlements to fetch installed apps or icon data. Springboard will handle fetching the data - this process | ||
// will signal and receive the data via notifications | ||
NSOperationQueue *notificationQueue = [[NSOperationQueue alloc] init]; | ||
[[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"]]; | ||
}]; | ||
|
||
// Ask Springboard for the app data. This may have a little delay, so its being fetched before the user opens the App List controller | ||
[[objc_getClass("NSDistributedNotificationCenter") defaultCenter] postNotification:[NSNotification notificationWithName:PREFERENCES_APP_DATA_NOTIFICATION object:kPrefsAppDataRequesting]]; | ||
} | ||
|
||
return self; | ||
} | ||
|
||
-(void)viewDidLoad | ||
{ | ||
[[self view] setBackgroundColor:[UIColor redColor]]; | ||
} | ||
|
||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView | ||
{ | ||
return 1; | ||
} | ||
|
||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section | ||
{ | ||
switch (section) | ||
{ | ||
case 0: | ||
return 1; | ||
case 1: | ||
return 3; | ||
default: | ||
break; | ||
} | ||
return 0; | ||
} | ||
|
||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath | ||
{ | ||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"com.carplay.rootcell"]; | ||
if (cell == nil) | ||
{ | ||
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"com.carplay.rootcell"]; | ||
} | ||
|
||
if (indexPath.section == 0) | ||
{ | ||
if (indexPath.row == 0) | ||
{ | ||
[[cell textLabel] setText:@"Add/Remove Apps"]; | ||
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator]; | ||
} | ||
} | ||
else if (indexPath.section == 1) | ||
{ | ||
if (indexPath.row == 0) | ||
{ | ||
[[cell textLabel] setText:@"Left"]; | ||
} | ||
else if (indexPath.row == 1) | ||
{ | ||
[[cell textLabel] setText:@"Right"]; | ||
} | ||
else if (indexPath.row == 2) | ||
{ | ||
[[cell textLabel] setText:@"Auto"]; | ||
[cell setAccessoryType:UITableViewCellAccessoryCheckmark]; | ||
} | ||
} | ||
|
||
return cell; | ||
} | ||
|
||
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section | ||
{ | ||
switch (section) | ||
{ | ||
case 0: | ||
return @"CarPlay Dashboard"; | ||
case 1: | ||
return @"Dock Alignment"; | ||
default: | ||
break; | ||
} | ||
return @""; | ||
} | ||
|
||
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section | ||
{ | ||
switch (section) | ||
{ | ||
case 0: | ||
//return @""; | ||
case 1: | ||
return @"Created by Ethan Arbuckle"; | ||
default: | ||
break; | ||
} | ||
return @""; | ||
} | ||
|
||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath | ||
{ | ||
switch (indexPath.section) | ||
{ | ||
case 0: | ||
{ | ||
if (!_appListController) | ||
{ | ||
// Have not received app data from SpringBoard yet.. | ||
break; | ||
} | ||
// Push to the app list controller | ||
[[self navigationController] pushViewController:_appListController animated:YES]; | ||
break; | ||
} | ||
case 1: | ||
break; | ||
default: | ||
break; | ||
} | ||
|
||
[tableView deselectRowAtIndexPath:indexPath animated:YES]; | ||
} | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
ARCHS = arm64 | ||
TARGET = iphone:clang:13.5.1:13.5.1 | ||
|
||
include $(THEOS)/makefiles/common.mk | ||
|
||
BUNDLE_NAME = carplayenableprefs | ||
|
||
carplayenableprefs_FILES = $(wildcard *.m) | ||
carplayenableprefs_INSTALL_PATH = /Library/PreferenceBundles | ||
carplayenableprefs_FRAMEWORKS = UIKit | ||
carplayenableprefs_PRIVATE_FRAMEWORKS = Preferences | ||
carplayenableprefs_CFLAGS = -fobjc-arc | ||
|
||
include $(THEOS_MAKE_PATH)/bundle.mk | ||
|
||
internal-stage:: | ||
$(ECHO_NOTHING)mkdir -p $(THEOS_STAGING_DIR)/Library/PreferenceLoader/Preferences$(ECHO_END) | ||
$(ECHO_NOTHING)cp entry.plist $(THEOS_STAGING_DIR)/Library/PreferenceLoader/Preferences/carplayenableprefs.plist$(ECHO_END) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
<plist version="1.0"> | ||
<dict> | ||
<key>CFBundleDevelopmentRegion</key> | ||
<string>English</string> | ||
<key>CFBundleExecutable</key> | ||
<string>carplayenableprefs</string> | ||
<key>CFBundleIdentifier</key> | ||
<string>com.ethanarbuckle.carplayprefs</string> | ||
<key>CFBundleInfoDictionaryVersion</key> | ||
<string>6.0</string> | ||
<key>CFBundlePackageType</key> | ||
<string>BNDL</string> | ||
<key>CFBundleShortVersionString</key> | ||
<string>1.0.0</string> | ||
<key>CFBundleSignature</key> | ||
<string>????</string> | ||
<key>CFBundleVersion</key> | ||
<string>1.0</string> | ||
<key>NSPrincipalClass</key> | ||
<string>CRERootListController</string> | ||
</dict> | ||
</plist> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
<plist version="1.0"> | ||
<dict> | ||
<key>entry</key> | ||
<dict> | ||
<key>bundle</key> | ||
<string>carplayenableprefs</string> | ||
<key>cell</key> | ||
<string>PSLinkCell</string> | ||
<key>detail</key> | ||
<string>CRERootListController</string> | ||
<key>icon</key> | ||
<string>icon.png</string> | ||
<key>isController</key> | ||
<true/> | ||
<key>label</key> | ||
<string>CarPlayEnable</string> | ||
</dict> | ||
</dict> | ||
</plist> |
Oops, something went wrong.