forked from Mojave/NotifyMusic
Merge pull request #1 from mcproj/master
Fix for iOS8/9 and add support to iOS11+ by mcproj.
This commit is contained in:
3
Makefile
3
Makefile
@ -1,11 +1,12 @@
|
||||
ARCHS = armv7 arm64
|
||||
VALID_ARCHS = armv7 armv7s arm64
|
||||
VALID_ARCHS = armv7 armv7s arm64 arm64e
|
||||
|
||||
include $(THEOS)/makefiles/common.mk
|
||||
|
||||
TWEAK_NAME = NotifyMusic
|
||||
NotifyMusic_FILES = Tweak.xm
|
||||
NotifyMusic_FRAMEWORKS = UIKit
|
||||
NotifyMusic_PRIVATE_FRAMEWORKS = MediaRemote
|
||||
NotifyMusic_LIBRARIES = bulletin
|
||||
|
||||
include $(THEOS_MAKE_PATH)/tweak.mk
|
||||
|
302
Tweak.xm
302
Tweak.xm
@ -1,4 +1,12 @@
|
||||
#import "notify.h"
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <MediaRemote/MediaRemote.h>
|
||||
|
||||
@interface JBBulletinManager : NSObject
|
||||
+(id)sharedInstance;
|
||||
-(id)showBulletinWithTitle:(NSString *)title message:(NSString *)message bundleID:(NSString *)bundleID;
|
||||
-(id)showBulletinWithTitle:(NSString *)title message:(NSString *)message bundleID:(NSString *)bundleID hasSound:(BOOL)hasSound soundID:(int)soundID vibrateMode:(int)vibrate soundPath:(NSString *)soundPath attachmentImage:(UIImage *)attachmentImage overrideBundleImage:(UIImage *)overrideBundleImage;
|
||||
@end
|
||||
|
||||
@interface SpringBoard
|
||||
-(id)_accessibilityFrontMostApplication;
|
||||
@ -15,53 +23,259 @@
|
||||
@end
|
||||
|
||||
@interface MPUNowPlayingController
|
||||
@property bool isPlaying;
|
||||
@property (nonatomic,readonly) NSString * nowPlayingAppDisplayID;
|
||||
@property (nonatomic,readonly) UIImage * currentNowPlayingArtwork;
|
||||
@property (nonatomic,readonly) NSDictionary * currentNowPlayingInfo;
|
||||
@property bool isPlaying;
|
||||
@property (nonatomic,readonly) NSString * nowPlayingAppDisplayID;
|
||||
@property (nonatomic,readonly) UIImage * currentNowPlayingArtwork;
|
||||
@property (nonatomic,readonly) NSDictionary * currentNowPlayingInfo;
|
||||
@property (nonatomic,readonly) double currentElapsed;
|
||||
@property (nonatomic,readonly) double currentDuration;
|
||||
-(void)_updateCurrentNowPlaying;
|
||||
-(void)_updatePlaybackState;
|
||||
-(void)setShouldUpdateNowPlayingArtwork:(BOOL)arg1 ;
|
||||
@end
|
||||
|
||||
@interface JBBulletinManager : NSObject
|
||||
+(id)sharedInstance;
|
||||
-(id)showBulletinWithTitle:(NSString *)title message:(NSString *)message bundleID:(NSString *)bundleID;
|
||||
-(id)showBulletinWithTitle:(NSString *)title message:(NSString *)message bundleID:(NSString *)bundleID hasSound:(BOOL)hasSound soundID:(int)soundID vibrateMode:(int)vibrate soundPath:(NSString *)soundPath attachmentImage:(UIImage *)attachmentImage overrideBundleImage:(UIImage *)overrideBundleImage;
|
||||
@interface SBMediaController
|
||||
@property (retain) NSDictionary * currentNowPlayingInfo;
|
||||
-(id/*SBApplication **/)nowPlayingApplication;
|
||||
-(void)setNowPlayingInfo:(NSDictionary *)arg1 ;
|
||||
-(BOOL)isPlaying;
|
||||
@end
|
||||
|
||||
@interface NotifyMusic : NSObject {
|
||||
int token;
|
||||
|
||||
BOOL notifyMusicPrefsLoaded;
|
||||
BOOL enablewhilelocked;
|
||||
BOOL showalbumname;
|
||||
BOOL albumastitle;
|
||||
BOOL enableinapp;
|
||||
BOOL showagainwhenartavail;
|
||||
|
||||
BOOL isInProgress;
|
||||
SBMediaController *cachedMediaController;
|
||||
MPUNowPlayingController *cachedNowPlayingController;
|
||||
NSString *cachedMediaInfo;
|
||||
double durationMod;
|
||||
BOOL isArtworkUpdated;
|
||||
}
|
||||
+(NotifyMusic *)sharedInstance;
|
||||
-(void)dealloc;
|
||||
-(void)_updateNotifyMusicPrefs;
|
||||
-(BOOL)isPlaying;
|
||||
-(NSString *)nowPlayingAppDisplayID;
|
||||
-(UIImage *)currentNowPlayingArtwork;
|
||||
-(NSDictionary *)currentNowPlayingInfo;
|
||||
-(double)currentDuration;
|
||||
-(BOOL)_shouldShowNotifyMusic;
|
||||
-(void)_showNotifyMusic;
|
||||
@end
|
||||
|
||||
@implementation NotifyMusic
|
||||
+(NotifyMusic *)sharedInstance {
|
||||
static NotifyMusic *instance = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
instance = [[self alloc] init];
|
||||
});
|
||||
return instance;
|
||||
}
|
||||
|
||||
-(id)init {
|
||||
if (self = [super init]) {
|
||||
notify_register_dispatch("com.gilshahar7.notifymusicprefs", &token, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(int token) {
|
||||
[self _updateNotifyMusicPrefs];
|
||||
});
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)dealloc {
|
||||
notify_cancel(token);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
-(void)_updateNotifyMusicPrefs {
|
||||
NSString *settingsPath = @"/var/mobile/Library/Preferences/com.gilshahar7.notifymusicprefs.plist";
|
||||
NSMutableDictionary *prefs = [[NSMutableDictionary alloc] initWithContentsOfFile:settingsPath];
|
||||
enablewhilelocked = [[prefs objectForKey:@"enablewhilelocked"] boolValue];
|
||||
showalbumname = [[prefs objectForKey:@"showalbumname"] boolValue];
|
||||
albumastitle = [[prefs objectForKey:@"albumastitle"] boolValue];
|
||||
enableinapp = [[prefs objectForKey:@"enableinapp"] boolValue];
|
||||
showagainwhenartavail = [[prefs objectForKey:@"showagainwhenartavail"] boolValue];
|
||||
}
|
||||
|
||||
-(void)_updateDependencyInjectionWithMC:(SBMediaController *)mediaController NPC:(MPUNowPlayingController *)nowPlayingController {
|
||||
cachedMediaController = mediaController;
|
||||
cachedNowPlayingController = nowPlayingController;
|
||||
}
|
||||
|
||||
-(BOOL)isPlaying {
|
||||
if (cachedNowPlayingController) return [cachedNowPlayingController isPlaying];
|
||||
else if (cachedMediaController) return [cachedMediaController isPlaying];
|
||||
return NO;
|
||||
}
|
||||
|
||||
-(NSString *)nowPlayingAppDisplayID {
|
||||
if (cachedNowPlayingController) return [cachedNowPlayingController nowPlayingAppDisplayID];
|
||||
else if (cachedMediaController) return [[cachedMediaController nowPlayingApplication] bundleIdentifier];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
-(UIImage *)currentNowPlayingArtwork {
|
||||
if (cachedNowPlayingController) {
|
||||
[cachedNowPlayingController setShouldUpdateNowPlayingArtwork:YES];
|
||||
return [cachedNowPlayingController currentNowPlayingArtwork];
|
||||
}
|
||||
else if (cachedMediaController) {
|
||||
if (![cachedMediaController currentNowPlayingInfo]) return NULL;
|
||||
NSData *artworkData = [cachedMediaController currentNowPlayingInfo][(__bridge NSString *)kMRMediaRemoteNowPlayingInfoArtworkData];
|
||||
if (!artworkData) return NULL;
|
||||
return [UIImage imageWithData:artworkData];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
-(NSDictionary *)currentNowPlayingInfo {
|
||||
if (cachedNowPlayingController) return [cachedNowPlayingController currentNowPlayingInfo];
|
||||
else if (cachedMediaController) return [cachedMediaController currentNowPlayingInfo];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
-(double)currentDuration {
|
||||
if (cachedNowPlayingController) return [cachedNowPlayingController currentDuration];
|
||||
else if (cachedMediaController) {
|
||||
if (![cachedMediaController currentNowPlayingInfo]) return 0;
|
||||
if (![cachedMediaController currentNowPlayingInfo][(__bridge NSString *)kMRMediaRemoteNowPlayingInfoDuration]) return 0;
|
||||
return [[cachedMediaController currentNowPlayingInfo][(__bridge NSString *)kMRMediaRemoteNowPlayingInfoDuration] doubleValue];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
-(BOOL)_shouldShowNotifyMusic {
|
||||
if (!notifyMusicPrefsLoaded) [self _updateNotifyMusicPrefs];
|
||||
NSString *frontMost = [[(SpringBoard *)[UIApplication sharedApplication] _accessibilityFrontMostApplication] bundleIdentifier];
|
||||
if(!enablewhilelocked && [[%c(SBLockScreenManager) sharedInstance] isUILocked]) return NO;
|
||||
if(!enableinapp && [self.nowPlayingAppDisplayID isEqualToString:frontMost])
|
||||
return NO;
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(void)_showNotifyMusic {
|
||||
//%orig;
|
||||
//if (![self _shouldShowNotifyMusic]) return;
|
||||
|
||||
if (isInProgress) return;
|
||||
if (!self.isPlaying) return;
|
||||
double currentDuration = self.currentDuration;
|
||||
if (!currentDuration || currentDuration <= 0) return;
|
||||
isInProgress = YES;
|
||||
|
||||
NSString *_title = self.currentNowPlayingInfo[(__bridge NSString *)kMRMediaRemoteNowPlayingInfoTitle];
|
||||
NSString *_artist = self.currentNowPlayingInfo[(__bridge NSString *)kMRMediaRemoteNowPlayingInfoArtist];
|
||||
NSString *_album = self.currentNowPlayingInfo[(__bridge NSString *)kMRMediaRemoteNowPlayingInfoAlbum];
|
||||
NSString *_mediaInfo = [NSString stringWithFormat:@"%@:%@:%@:%@:%d", self.nowPlayingAppDisplayID, _title, _artist, _album, (int)currentDuration];
|
||||
if (![_mediaInfo isEqualToString:cachedMediaInfo]) durationMod = currentDuration - (int)currentDuration;
|
||||
|
||||
BOOL hasArtwork = [self.currentNowPlayingInfo[(__bridge NSString *)kMRMediaRemoteNowPlayingInfoArtworkMIMEType] containsString:@"image"];
|
||||
double delayInSeconds = 0.5;
|
||||
if (hasArtwork) delayInSeconds = 2;
|
||||
if (hasArtwork && self.currentNowPlayingArtwork == nil) delayInSeconds = 4;
|
||||
if (currentDuration - (int)currentDuration != durationMod) delayInSeconds = 8;
|
||||
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
|
||||
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
|
||||
NSString *nowPlayingAppDisplayID = self.nowPlayingAppDisplayID;
|
||||
NSString *title = self.currentNowPlayingInfo[(__bridge NSString *)kMRMediaRemoteNowPlayingInfoTitle];
|
||||
NSString *artist = self.currentNowPlayingInfo[(__bridge NSString *)kMRMediaRemoteNowPlayingInfoArtist];
|
||||
NSString *album = self.currentNowPlayingInfo[(__bridge NSString *)kMRMediaRemoteNowPlayingInfoAlbum];
|
||||
NSString *mediaInfo = [NSString stringWithFormat:@"%@:%@:%@:%@:%d", nowPlayingAppDisplayID, title, artist, album, (int)self.currentDuration];
|
||||
if (![mediaInfo isEqualToString:_mediaInfo]) return;
|
||||
UIImage *artwork = self.currentNowPlayingArtwork;
|
||||
if ([mediaInfo isEqualToString:cachedMediaInfo] && (artwork == nil || !showagainwhenartavail || isArtworkUpdated)) return;
|
||||
//if (artwork) artwork = [artwork copy];
|
||||
cachedMediaInfo = [mediaInfo copy];
|
||||
isArtworkUpdated = artwork != nil;
|
||||
if (![self _shouldShowNotifyMusic]) return;
|
||||
if(!showalbumname){
|
||||
album = @"Now Playing";
|
||||
}
|
||||
if (showalbumname) {
|
||||
NSString *_title, *_message;
|
||||
if (albumastitle) {
|
||||
_title = album;
|
||||
_message = [NSString stringWithFormat: @"%@\n%@", title, artist];
|
||||
} else {
|
||||
_title = title;
|
||||
_message = [NSString stringWithFormat: @"%@\n%@", artist, album];
|
||||
}
|
||||
if(artwork != nil){
|
||||
[[%c(JBBulletinManager) sharedInstance] showBulletinWithTitle:_title message:_message bundleID:nowPlayingAppDisplayID hasSound:false soundID:0 vibrateMode:0 soundPath:@"" attachmentImage:artwork overrideBundleImage:nil];
|
||||
}else{
|
||||
[[%c(JBBulletinManager) sharedInstance] showBulletinWithTitle:_title message:_message bundleID:nowPlayingAppDisplayID];
|
||||
}
|
||||
} else {
|
||||
if ([album length] <= 0) {
|
||||
album = @"Now Playing";
|
||||
}
|
||||
if(artwork != nil){
|
||||
[[%c(JBBulletinManager) sharedInstance] showBulletinWithTitle:album message:[NSString stringWithFormat: @"%@\n%@", title, artist] bundleID:nowPlayingAppDisplayID hasSound:false soundID:0 vibrateMode:0 soundPath:@"" attachmentImage:artwork overrideBundleImage:nil];
|
||||
}else{
|
||||
[[%c(JBBulletinManager) sharedInstance] showBulletinWithTitle:album message:[NSString stringWithFormat: @"%@\n%@", title, artist] bundleID:nowPlayingAppDisplayID];
|
||||
}
|
||||
}
|
||||
});
|
||||
isInProgress = NO;
|
||||
}
|
||||
@end
|
||||
|
||||
%hook MPUNowPlayingController
|
||||
static NSString *cachedTitle;
|
||||
static NSString *artist;
|
||||
static NSString *album;
|
||||
-(void)_updateCurrentNowPlaying{
|
||||
%orig;
|
||||
NSString *settingsPath = @"/var/mobile/Library/Preferences/com.gilshahar7.notifymusicprefs.plist";
|
||||
NSMutableDictionary *prefs = [[NSMutableDictionary alloc] initWithContentsOfFile:settingsPath];
|
||||
BOOL enablewhilelocked = [[prefs objectForKey:@"enablewhilelocked"] boolValue];
|
||||
BOOL showalbumname = [[prefs objectForKey:@"showalbumname"] boolValue];
|
||||
BOOL enableinapp = [[prefs objectForKey:@"enableinapp"] boolValue];
|
||||
|
||||
double delayInSeconds = 0.5;
|
||||
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
|
||||
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
|
||||
if(![cachedTitle isEqualToString:self.currentNowPlayingInfo[@"kMRMediaRemoteNowPlayingInfoTitle"]]){
|
||||
cachedTitle = [self.currentNowPlayingInfo[@"kMRMediaRemoteNowPlayingInfoTitle"] copy];
|
||||
NSString *frontMost = [[(SpringBoard *)[UIApplication sharedApplication] _accessibilityFrontMostApplication] bundleIdentifier];
|
||||
if((enablewhilelocked || (![[%c(SBLockScreenManager) sharedInstance] isUILocked])) && self.isPlaying){
|
||||
if(enableinapp || (![self.nowPlayingAppDisplayID isEqualToString:frontMost])){
|
||||
artist = [NSString stringWithFormat: @"\n%@", self.currentNowPlayingInfo[@"kMRMediaRemoteNowPlayingInfoArtist"]];
|
||||
|
||||
if([self.currentNowPlayingInfo[@"kMRMediaRemoteNowPlayingInfoAlbum"] length] > 1 && showalbumname){
|
||||
album = self.currentNowPlayingInfo[@"kMRMediaRemoteNowPlayingInfoAlbum"];
|
||||
}else{
|
||||
album = @"Now Playing";
|
||||
}
|
||||
if(self.currentNowPlayingArtwork != nil){
|
||||
[[objc_getClass("JBBulletinManager") sharedInstance] showBulletinWithTitle:album message:[NSString stringWithFormat: @"%@%@", self.currentNowPlayingInfo[@"kMRMediaRemoteNowPlayingInfoTitle"], artist] bundleID:self.nowPlayingAppDisplayID hasSound:false soundID:0 vibrateMode:0 soundPath:@"" attachmentImage:self.currentNowPlayingArtwork overrideBundleImage:nil];
|
||||
}else{
|
||||
[[objc_getClass("JBBulletinManager") sharedInstance] showBulletinWithTitle:album message:[NSString stringWithFormat: @"%@%@", self.currentNowPlayingInfo[@"kMRMediaRemoteNowPlayingInfoTitle"], artist] bundleID:self.nowPlayingAppDisplayID];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
static int token;
|
||||
|
||||
-(id)init {
|
||||
self = %orig;
|
||||
if (self) {
|
||||
notify_register_dispatch("com.gilshahar7.notifymusic", &token, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(int token) {
|
||||
[self _updatePlaybackState];
|
||||
});
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)dealloc {
|
||||
notify_cancel(token);
|
||||
%orig;
|
||||
}
|
||||
|
||||
/*-(void)_updateCurrentNowPlaying{
|
||||
%orig;
|
||||
[[NotifyMusic sharedInstance] _updateDependencyInjectionWithMC:nil NPC:self];
|
||||
[[NotifyMusic sharedInstance] _showNotifyMusic];
|
||||
}*/
|
||||
|
||||
-(void)_updatePlaybackState {
|
||||
%orig;
|
||||
[[NotifyMusic sharedInstance] _updateDependencyInjectionWithMC:nil NPC:self];
|
||||
[[NotifyMusic sharedInstance] _showNotifyMusic];
|
||||
}
|
||||
%end
|
||||
|
||||
%hook SBMediaController
|
||||
%property (retain) NSDictionary * currentNowPlayingInfo;
|
||||
|
||||
-(void)setNowPlayingInfo:(NSDictionary *)arg1 {
|
||||
%orig;
|
||||
if (UIDevice.currentDevice.systemVersion.floatValue >= 11.0) {
|
||||
MRMediaRemoteGetNowPlayingInfo(dispatch_get_main_queue(), ^(CFDictionaryRef nowPlayingInfo) {
|
||||
if (self.currentNowPlayingInfo) [self.currentNowPlayingInfo release];
|
||||
self.currentNowPlayingInfo = [(__bridge NSDictionary *)nowPlayingInfo copy];
|
||||
[[NotifyMusic sharedInstance] _updateDependencyInjectionWithMC:self NPC:nil];
|
||||
[[NotifyMusic sharedInstance] _showNotifyMusic];
|
||||
});
|
||||
}
|
||||
else notify_post("com.gilshahar7.notifymusic");
|
||||
}
|
||||
|
||||
-(void)_nowPlayingAppIsPlayingDidChange {
|
||||
%orig;
|
||||
[self setNowPlayingInfo:[self _nowPlayingInfo]];
|
||||
}
|
||||
%end
|
||||
|
@ -1,4 +1,4 @@
|
||||
ARCHS = armv7 arm64
|
||||
ARCHS = armv7 arm64 arm64e
|
||||
include $(THEOS)/makefiles/common.mk
|
||||
|
||||
BUNDLE_NAME = notifymusicprefs
|
||||
|
@ -11,6 +11,8 @@
|
||||
<string>NotifyMusic</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>PostNotification</key>
|
||||
<string>com.gilshahar7.notifymusicprefs</string>
|
||||
<key>cell</key>
|
||||
<string>PSSwitchCell</string>
|
||||
<key>default</key>
|
||||
@ -22,7 +24,9 @@
|
||||
<key>label</key>
|
||||
<string>Enable while locked</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<dict>
|
||||
<key>PostNotification</key>
|
||||
<string>com.gilshahar7.notifymusicprefs</string>
|
||||
<key>cell</key>
|
||||
<string>PSSwitchCell</string>
|
||||
<key>default</key>
|
||||
@ -35,6 +39,8 @@
|
||||
<string>Enable inside now playing app</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>PostNotification</key>
|
||||
<string>com.gilshahar7.notifymusicprefs</string>
|
||||
<key>cell</key>
|
||||
<string>PSSwitchCell</string>
|
||||
<key>default</key>
|
||||
@ -44,7 +50,35 @@
|
||||
<key>key</key>
|
||||
<string>showalbumname</string>
|
||||
<key>label</key>
|
||||
<string>Show album name in title</string>
|
||||
<string>Show album name</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>PostNotification</key>
|
||||
<string>com.gilshahar7.notifymusicprefs</string>
|
||||
<key>cell</key>
|
||||
<string>PSSwitchCell</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
<key>defaults</key>
|
||||
<string>com.gilshahar7.notifymusicprefs</string>
|
||||
<key>key</key>
|
||||
<string>albumastitle</string>
|
||||
<key>label</key>
|
||||
<string>Album name as title</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>PostNotification</key>
|
||||
<string>com.gilshahar7.notifymusicprefs</string>
|
||||
<key>cell</key>
|
||||
<string>PSSwitchCell</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
<key>defaults</key>
|
||||
<string>com.gilshahar7.notifymusicprefs</string>
|
||||
<key>key</key>
|
||||
<string>showagainwhenartavail</string>
|
||||
<key>label</key>
|
||||
<string>Show again when albumart become available</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>title</key>
|
||||
|
Reference in New Issue
Block a user