Skip to content

Commit

Permalink
Improve app launch performance by moving SpringBoard-only code into i…
Browse files Browse the repository at this point in the history
…ts own binary
  • Loading branch information
rpetrich committed Dec 9, 2011
1 parent 20b7acc commit 5f5e63f
Show file tree
Hide file tree
Showing 11 changed files with 263 additions and 219 deletions.
145 changes: 4 additions & 141 deletions Events.x
Expand Up @@ -2,6 +2,7 @@
#import "libactivator-private.h"
#import "LAToggleListener.h"
#import "LAMenuListener.h"
#import "LASimpleListener.h"

%config(generator=internal);

Expand All @@ -10,62 +11,6 @@

#include <dlfcn.h>

NSString * const LAEventNameMenuPressAtSpringBoard = @"libactivator.menu.press.at-springboard";
NSString * const LAEventNameMenuPressSingle = @"libactivator.menu.press.single";
NSString * const LAEventNameMenuPressDouble = @"libactivator.menu.press.double";
NSString * const LAEventNameMenuPressTriple = @"libactivator.menu.press.triple";
NSString * const LAEventNameMenuHoldShort = @"libactivator.menu.hold.short";

NSString * const LAEventNameLockHoldShort = @"libactivator.lock.hold.short";
NSString * const LAEventNameLockPressDouble = @"libactivator.lock.press.double";

NSString * const LAEventNameSpringBoardPinch = @"libactivator.springboard.pinch";
NSString * const LAEventNameSpringBoardSpread = @"libactivator.springboard.spread";

NSString * const LAEventNameStatusBarSwipeRight = @"libactivator.statusbar.swipe.right";
NSString * const LAEventNameStatusBarSwipeLeft = @"libactivator.statusbar.swipe.left";
NSString * const LAEventNameStatusBarSwipeDown = @"libactivator.statusbar.swipe.down";
NSString * const LAEventNameStatusBarTapDouble = @"libactivator.statusbar.tap.double";
NSString * const LAEventNameStatusBarTapSingle = @"libactivator.statusbar.tap.single";
NSString * const LAEventNameStatusBarHold = @"libactivator.statusbar.hold";

NSString * const LAEventNameVolumeDownUp = @"libactivator.volume.down-up";
NSString * const LAEventNameVolumeUpDown = @"libactivator.volume.up-down";
NSString * const LAEventNameVolumeDisplayTap = @"libactivator.volume.display-tap";
NSString * const LAEventNameVolumeToggleMuteTwice = @"libactivator.volume.toggle-mute-twice";
NSString * const LAEventNameVolumeDownHoldShort = @"libactivator.volume.down.hold.short";
NSString * const LAEventNameVolumeUpHoldShort = @"libactivator.volume.up.hold.short";
NSString * const LAEventNameVolumeDownPress = @"libactivator.volume.down.press";
NSString * const LAEventNameVolumeUpPress = @"libactivator.volume.up.press";
NSString * const LAEventNameVolumeBothPress = @"libactivator.volume.both.press";

NSString * const LAEventNameSlideInFromBottom = @"libactivator.slide-in.bottom";
NSString * const LAEventNameSlideInFromBottomLeft = @"libactivator.slide-in.bottom-left";
NSString * const LAEventNameSlideInFromBottomRight = @"libactivator.slide-in.bottom-right";

NSString * const LAEventNameMotionShake = @"libactivator.motion.shake";

NSString * const LAEventNameHeadsetButtonPressSingle = @"libactivator.headset-button.press.single";
NSString * const LAEventNameHeadsetButtonHoldShort = @"libactivator.headset-button.hold.short";

NSString * const LAEventNameLockScreenClockDoubleTap = @"libactivator.lockscreen.clock.double-tap";

NSString * const LAEventNamePowerConnected = @"libactivator.power.connected";
NSString * const LAEventNamePowerDisconnected = @"libactivator.power.disconnected";

#define kSpringBoardPinchThreshold 0.95f
#define kSpringBoardSpreadThreshold 1.05f
#define kButtonHoldDelay 0.3
#define kVolumeRepeatDelay 0.15
#define kStatusBarHorizontalSwipeThreshold 50.0f
#define kStatusBarVerticalSwipeThreshold 10.0f
#define kStatusBarHoldDelay 0.5
#define kStatusBarTapDelay 0.33
#define kSlideGestureWindowHeight 13.0f
#define kWindowLevelTransparentTopMost 9999.0f
#define kShakeIgnoreTimeout 2.0
#define kAlmostTransparentColor [[UIColor grayColor] colorWithAlphaComponent:(2.0f / 255.0f)]

//static BOOL isInSleep;

static BOOL shouldInterceptMenuPresses;
Expand All @@ -79,14 +24,6 @@ static LASlideGestureWindow *rightSlideGestureWindow;
static LAQuickDoDelegate *sharedQuickDoDelegate;
static UIButton *quickDoButton;

__attribute__((always_inline))
static inline LAEvent *LASendEventWithName(NSString *eventName)
{
LAEvent *event = [[[LAEvent alloc] initWithName:eventName mode:[LASharedActivator currentEventMode]] autorelease];
[LASharedActivator sendEventToListener:event];
return event;
}

__attribute__((always_inline))
static inline void LAAbortEvent(LAEvent *event)
{
Expand Down Expand Up @@ -464,8 +401,6 @@ static void HideVolumeTapWindow()

@end

%group SpringBoard

static CFAbsoluteTime lastRingerChangedTime;

%hook SpringBoard
Expand Down Expand Up @@ -1592,82 +1527,10 @@ static NSInteger lastAwayDateTapCount;

%end

%end

%group All

%hook UIStatusBar

static BOOL passThroughStatusBar;

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if (passThroughStatusBar) {
passThroughStatusBar = NO;
%orig;
} else {
DestroyCurrentStatusBarHoldTimer();
DestroyCurrentStatusBarTapTimer();
statusBarHoldTimer = CFRunLoopTimerCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent() + kStatusBarHoldDelay, 0.0, 0, 0, StatusBarHeldCallback, NULL);
CFRunLoopAddTimer(CFRunLoopGetCurrent(), statusBarHoldTimer, kCFRunLoopCommonModes);
statusBarTouchDown = [[touches anyObject] locationInView:self];
hasSentStatusBarEvent = NO;
}
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
if (!hasSentStatusBarEvent) {
DestroyCurrentStatusBarHoldTimer();
DestroyCurrentStatusBarTapTimer();
CGPoint currentPosition = [[touches anyObject] locationInView:self];
CGFloat deltaX = currentPosition.x - statusBarTouchDown.x;
CGFloat deltaY = currentPosition.y - statusBarTouchDown.y;
if ((deltaX * deltaX) > (deltaY * deltaY)) {
if (deltaX > kStatusBarHorizontalSwipeThreshold) {
hasSentStatusBarEvent = YES;
LASendEventWithName(LAEventNameStatusBarSwipeRight);
} else if (deltaX < -kStatusBarHorizontalSwipeThreshold) {
hasSentStatusBarEvent = YES;
LASendEventWithName(LAEventNameStatusBarSwipeLeft);
}
} else {
if (deltaY > kStatusBarVerticalSwipeThreshold) {
hasSentStatusBarEvent = YES;
LASendEventWithName(LAEventNameStatusBarSwipeDown);
}
}
}
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
DestroyCurrentStatusBarHoldTimer();
DestroyCurrentStatusBarTapTimer();
if (!hasSentStatusBarEvent) {
if ([[touches anyObject] tapCount] == 2)
LASendEventWithName(LAEventNameStatusBarTapDouble);
else {
statusBarTapTimer = CFRunLoopTimerCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent() + kStatusBarTapDelay, 0.0, 0, 0, StatusBarTapCallback, NULL);
CFRunLoopAddTimer(CFRunLoopGetCurrent(), statusBarTapTimer, kCFRunLoopCommonModes);
passThroughStatusBar = YES;
[self touchesBegan:touches withEvent:event];
%orig;
}
}
}

%end

%end

%ctor
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
if (objc_getClass("SpringBoard")) {
%init(SpringBoard, SBIcon = objc_getClass("SBIconView") ?: objc_getClass("SBIcon"));
}
%init(All);
%init(SBIcon = objc_getClass("SBIconView") ?: objc_getClass("SBIcon"));
[[LASpringBoardActivator alloc] init];
[LADefaultEventDataSource sharedInstance];
[[LAVersionChecker class] performSelector:@selector(checkVersion) withObject:nil afterDelay:0.1];
[pool drain];
}
3 changes: 1 addition & 2 deletions LAApplicationListener.h
Expand Up @@ -3,8 +3,7 @@
@class SBApplication;

__attribute__((visibility("hidden")))
@interface LAApplicationListener : NSObject<LAListener> {
}
@interface LAApplicationListener : NSObject<LAListener>

+ (id)sharedInstance;
- (BOOL)activateApplication:(SBApplication *)application;
Expand Down
14 changes: 5 additions & 9 deletions LAApplicationListener.x
Expand Up @@ -295,13 +295,9 @@ static inline SBDisplayStack *SBWGetDisplayStackAtIndex(NSInteger index)

%ctor
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
if (objc_getClass("SBApplicationController")) {
%init;
sharedApplicationListener = [[LAApplicationListener alloc] init];
allEventModesExceptLockScreen = [[NSArray alloc] initWithObjects:LAEventModeSpringBoard, LAEventModeApplication, nil];
ignoredDisplayIdentifiers = [[NSArray alloc] initWithObjects:@"com.apple.DemoApp", @"com.apple.fieldtest", @"com.apple.springboard", @"com.apple.AdSheet", @"com.apple.iphoneos.iPodOut", @"com.apple.TrustMe", @"com.apple.DataActivation", @"com.apple.WebSheet", @"com.apple.AdSheetPhone", @"com.apple.AdSheetPad", @"com.apple.iosdiagnostics", @"com.apple.purplebuddy", nil];
displayStacks = (NSMutableArray *)CFArrayCreateMutable(kCFAllocatorDefault, 0, NULL);
}
[pool drain];
%init;
sharedApplicationListener = [[LAApplicationListener alloc] init];
allEventModesExceptLockScreen = [[NSArray alloc] initWithObjects:LAEventModeSpringBoard, LAEventModeApplication, nil];
ignoredDisplayIdentifiers = [[NSArray alloc] initWithObjects:@"com.apple.DemoApp", @"com.apple.fieldtest", @"com.apple.springboard", @"com.apple.AdSheet", @"com.apple.iphoneos.iPodOut", @"com.apple.TrustMe", @"com.apple.DataActivation", @"com.apple.WebSheet", @"com.apple.AdSheetPhone", @"com.apple.AdSheetPad", @"com.apple.iosdiagnostics", @"com.apple.purplebuddy", nil];
displayStacks = (NSMutableArray *)CFArrayCreateMutable(kCFAllocatorDefault, 0, NULL);
}
28 changes: 28 additions & 0 deletions LASimpleListener.h
@@ -0,0 +1,28 @@
#import "libactivator.h"

__attribute__((visibility("hidden")))
@interface LASimpleListener : NSObject<LAListener>
+ (LASimpleListener *)sharedInstance;

// System
- (BOOL)homeButton;
- (BOOL)sleepButton;
- (BOOL)respring;
- (BOOL)reboot;
- (BOOL)powerDown;
- (BOOL)spotlight;
- (BOOL)takeScreenshot;
- (BOOL)voiceControl;

// Lock Screen
- (BOOL)showLockScreen;
- (BOOL)dismissLockScreen;
- (BOOL)toggleLockScreen;

// iPod
- (BOOL)togglePlayback;
- (BOOL)previousTrack;
- (BOOL)nextTrack;
- (BOOL)musicControls;

@end
3 changes: 2 additions & 1 deletion LASimpleListener.x
@@ -1,5 +1,6 @@
#import "libactivator.h"
#import "libactivator-private.h"
#import "LASimpleListener.h"
#import "LAApplicationListener.h"
#import <UIKit/UIKit2.h>
#import <SpringBoard/SpringBoard.h>
Expand Down Expand Up @@ -523,7 +524,7 @@ static UIWindow *tweetFormerKeyWindow;

+ (void)initialize
{
if ((self == [LASimpleListener class]) && LASharedActivator.runningInsideSpringBoard) {
if (self == [LASimpleListener class]) {
%init;
sharedSimpleListener = [[self alloc] init];
// System
Expand Down
42 changes: 19 additions & 23 deletions LAToggleListener.m
Expand Up @@ -35,11 +35,9 @@ @implementation LAToggleListener

+ (void)initialize
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
if (self == [LAToggleListener class]) {
sharedInstance = [[self alloc] init];
}
[pool drain];
}

+ (id)sharedInstance
Expand All @@ -60,27 +58,25 @@ + (NSString *)defaultThemePath
- (id)init
{
if ((self = [super init])) {
if (LASharedActivator.runningInsideSpringBoard) {
toggles = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, NULL);
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *togglesPath = [LAToggleListener togglesPath];
for (NSString *subpath in [fileManager contentsOfDirectoryAtPath:togglesPath error:NULL]) {
if ([subpath hasPrefix:@"."])
continue;
if ([subpath isEqualToString:@"Fast Notes"])
continue;
if ([subpath isEqualToString:@"Brightness"])
continue;
if ([subpath isEqualToString:@"Processes"])
continue;
NSString *togglePath = [[togglesPath stringByAppendingPathComponent:subpath] stringByAppendingPathComponent:@"Toggle.dylib"];
void *toggle = dlopen([togglePath UTF8String], RTLD_LAZY);
if (toggle && isCapable(toggle)) {
[LASharedActivator registerListener:self forName:ListenerNameFromToggleName(subpath) ignoreHasSeen:YES];
CFDictionaryAddValue(toggles, subpath, toggle);
} else {
dlclose(toggle);
}
toggles = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, NULL);
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *togglesPath = [LAToggleListener togglesPath];
for (NSString *subpath in [fileManager contentsOfDirectoryAtPath:togglesPath error:NULL]) {
if ([subpath hasPrefix:@"."])
continue;
if ([subpath isEqualToString:@"Fast Notes"])
continue;
if ([subpath isEqualToString:@"Brightness"])
continue;
if ([subpath isEqualToString:@"Processes"])
continue;
NSString *togglePath = [[togglesPath stringByAppendingPathComponent:subpath] stringByAppendingPathComponent:@"Toggle.dylib"];
void *toggle = dlopen([togglePath UTF8String], RTLD_LAZY);
if (toggle && isCapable(toggle)) {
[LASharedActivator registerListener:self forName:ListenerNameFromToggleName(subpath) ignoreHasSeen:YES];
CFDictionaryAddValue(toggles, subpath, toggle);
} else {
dlclose(toggle);
}
}
}
Expand Down
12 changes: 10 additions & 2 deletions Makefile
Expand Up @@ -4,12 +4,20 @@ all clean package install::
$(MAKE) $(MAKEFLAGS) MAKELEVEL=0 $@
else

LIBRARY_NAME = libactivator SpringBoard

# libactivator.dylib (/usr/lib)
LIBRARY_NAME = libactivator
libactivator_FILES = Events.x LAEvent.m LAApplicationListener.x LASimpleListener.x LARemoteListener.m LAListener.m ListenerSettingsViewController.m libactivator.x LAToggleListener.m LASettingsViewController.m ActivatorEventViewHeader.m LAWebSettingsController.m LARootSettingsController.m LAModeSettingsController.m LAEventSettingsController.m LAEventGroupSettingsController.m LAEventDataSource.m LADefaultEventDataSource.m LASpringBoardActivator.x LAListenerTableViewDataSource.m LAMenuListener.m LAMenuSettingsController.m LAMenuItemsController.m LAMenuListenerSelectionController.m
libactivator_FILES = LAEvent.m LARemoteListener.m LAListener.m ListenerSettingsViewController.m libactivator.x LASettingsViewController.m ActivatorEventViewHeader.m LAWebSettingsController.m LARootSettingsController.m LAModeSettingsController.m LAEventSettingsController.m LAEventGroupSettingsController.m LAEventDataSource.m LAListenerTableViewDataSource.m LAMenuSettingsController.m LAMenuItemsController.m LAMenuListenerSelectionController.m StatusBarEvents.x
libactivator_FRAMEWORKS = UIKit CoreGraphics QuartzCore
libactivator_PRIVATE_FRAMEWORKS = AppSupport GraphicsServices

# SpringBoard.dylib (/Library/Activator)
SpringBoard_FILES = Events.x LASimpleListener.x LAApplicationListener.x LAToggleListener.m LASpringBoardActivator.x LAMenuListener.m LADefaultEventDataSource.m
SpringBoard_INSTALL_PATH = /Library/Activator
SpringBoard_FRAMEWORKS = UIKit CoreGraphics QuartzCore
SpringBoard_PRIVATE_FRAMEWORKS = AppSupport GraphicsServices
SpringBoard_LDFLAGS = -L$(FW_OBJ_DIR) -lactivator

# LibActivator.bundle (/System/Library/PreferenceBundles)
BUNDLE_NAME = LibActivator
LibActivator_FILES = Preferences.m
Expand Down

0 comments on commit 5f5e63f

Please sign in to comment.