From 77b3d74948b48c367b3b8f78c325f5634c741758 Mon Sep 17 00:00:00 2001 From: Christopher Snowhill Date: Sun, 24 Jul 2022 23:14:52 -0700 Subject: [PATCH] [Sandbox Paths] Automatically clean up old paths Clean up redundant paths automatically, and on startup. Also refresh the preferences dialog path list every time it is opened. Signed-off-by: Christopher Snowhill --- Application/AppController.m | 1 + Preferences/PreferencePanePlugin.h | 1 + Preferences/Preferences/GeneralPane.h | 1 + Preferences/Preferences/GeneralPane.m | 4 ++ .../SandboxPathBehaviorController.h | 2 + .../SandboxPathBehaviorController.m | 6 +++ Preferences/PreferencesWindow.m | 3 ++ Utils/SandboxBroker.h | 2 + Utils/SandboxBroker.m | 48 +++++++++++++++++++ 9 files changed, 68 insertions(+) diff --git a/Application/AppController.m b/Application/AppController.m index 0f6b44391..447589fa7 100644 --- a/Application/AppController.m +++ b/Application/AppController.m @@ -206,6 +206,7 @@ static AppController *kAppController = nil; if(!sandboxBroker) { ALog(@"Sandbox broker init failed."); } + [SandboxBroker cleanupFolderAccess]; [[playlistController undoManager] enableUndoRegistration]; diff --git a/Preferences/PreferencePanePlugin.h b/Preferences/PreferencePanePlugin.h index 13af84002..1a1df390b 100644 --- a/Preferences/PreferencePanePlugin.h +++ b/Preferences/PreferencePanePlugin.h @@ -18,6 +18,7 @@ @property(readonly) NSImage *icon; @optional +- (IBAction)refreshPathList:(id)sender; - (IBAction)showPathSuggester:(id)sender; @end diff --git a/Preferences/Preferences/GeneralPane.h b/Preferences/Preferences/GeneralPane.h index bb2249f84..13cfa8102 100644 --- a/Preferences/Preferences/GeneralPane.h +++ b/Preferences/Preferences/GeneralPane.h @@ -21,6 +21,7 @@ NS_ASSUME_NONNULL_BEGIN - (IBAction)deleteSelectedPaths:(id)sender; - (IBAction)removeStaleEntries:(id)sender; - (IBAction)showPathSuggester:(id)sender; +- (IBAction)refreshPathList:(id)sender; @end diff --git a/Preferences/Preferences/GeneralPane.m b/Preferences/Preferences/GeneralPane.m index b1a3adce0..3296fb1a3 100644 --- a/Preferences/Preferences/GeneralPane.m +++ b/Preferences/Preferences/GeneralPane.m @@ -105,4 +105,8 @@ [pathSuggester beginSuggestion:sender]; } +- (IBAction)refreshPathList:(id)sender { + [sandboxPathBehaviorController refresh]; +} + @end diff --git a/Preferences/Preferences/SandboxPathBehaviorController.h b/Preferences/Preferences/SandboxPathBehaviorController.h index d2a04c958..d19c66bb6 100644 --- a/Preferences/Preferences/SandboxPathBehaviorController.h +++ b/Preferences/Preferences/SandboxPathBehaviorController.h @@ -11,6 +11,8 @@ NS_ASSUME_NONNULL_BEGIN @interface SandboxPathBehaviorController : NSArrayController +- (void)refresh; + - (void)addUrl:(NSURL *)url; - (void)removeToken:(id)token; - (void)removeStaleEntries; diff --git a/Preferences/Preferences/SandboxPathBehaviorController.m b/Preferences/Preferences/SandboxPathBehaviorController.m index d35ddc49e..2f8f41e00 100644 --- a/Preferences/Preferences/SandboxPathBehaviorController.m +++ b/Preferences/Preferences/SandboxPathBehaviorController.m @@ -27,6 +27,10 @@ @implementation SandboxPathBehaviorController - (void)awakeFromNib { + [self refresh]; +} + +- (void)refresh { [self removeObjects:[self arrangedObjects]]; NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"path" ascending:YES]; @@ -77,6 +81,8 @@ ALog(@"Error saving bookmark: %@", [err localizedDescription]); } else { [self addObject:@{ @"path": [url path], @"valid": NSLocalizedPrefString(@"ValidYes"), @"isFolder": @(token.folder), @"token": token }]; + [NSClassFromString(@"SandboxBroker") cleanupFolderAccess]; + [self refresh]; } } } diff --git a/Preferences/PreferencesWindow.m b/Preferences/PreferencesWindow.m index 472c7098a..7db3fd4dd 100644 --- a/Preferences/PreferencesWindow.m +++ b/Preferences/PreferencesWindow.m @@ -89,6 +89,9 @@ } [self setContentView:paneView animate:display]; + if([paneController respondsToSelector:@selector(refreshPathList:)]) { + [paneController refreshPathList:self]; + } // Update defaults [[NSUserDefaults standardUserDefaults] setObject:name forKey:[self lastPaneDefaultsKey]]; diff --git a/Utils/SandboxBroker.h b/Utils/SandboxBroker.h index 08470d517..787072c31 100644 --- a/Utils/SandboxBroker.h +++ b/Utils/SandboxBroker.h @@ -18,6 +18,8 @@ NS_ASSUME_NONNULL_BEGIN + (NSURL *)urlWithoutFragment:(NSURL *)url; + (BOOL)isPath:(NSURL *)path aSubdirectoryOf:(NSURL *)directory; ++ (void)cleanupFolderAccess; + - (id)init; - (void)shutdown; diff --git a/Utils/SandboxBroker.m b/Utils/SandboxBroker.m index c9e417066..27659104f 100644 --- a/Utils/SandboxBroker.m +++ b/Utils/SandboxBroker.m @@ -258,6 +258,7 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc if(token) { token.path = [folderUrl path]; token.bookmark = bookmark; + [SandboxBroker cleanupFolderAccess]; } }); } @@ -373,6 +374,7 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc if(token) { token.path = [folderUrl path]; token.bookmark = bookmark; + [SandboxBroker cleanupFolderAccess]; } } }); @@ -380,6 +382,52 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc } } ++ (void)cleanupFolderAccess { + NSLock *lock = [SandboxBroker sharedPersistentContainerLock]; + NSPersistentContainer *pc = [SandboxBroker sharedPersistentContainer]; + + NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"path.length" ascending:YES]; + NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"SandboxToken"]; + request.sortDescriptors = @[sortDescriptor]; + + NSError *error = nil; + [lock lock]; + NSArray *results = [pc.viewContext executeFetchRequest:request error:&error]; + [lock unlock]; + + BOOL isUpdated = NO; + + if(results && [results count]) { + NSMutableArray *resultsCopy = [results mutableCopy]; + for(NSUInteger i = 0; i < [resultsCopy count] - 1; ++i) { + SandboxToken *token = resultsCopy[i]; + NSURL *url = [NSURL fileURLWithPath:token.path]; + for(NSUInteger j = i + 1; j < [resultsCopy count];) { + SandboxToken *compareToken = resultsCopy[j]; + if([SandboxBroker isPath:[NSURL fileURLWithPath:compareToken.path] aSubdirectoryOf:url]) { + [lock lock]; + [pc.viewContext deleteObject:compareToken]; + [lock unlock]; + isUpdated = YES; + [resultsCopy removeObjectAtIndex:j]; + } else { + ++j; + } + } + } + } + + if(isUpdated) { + NSError *error; + [lock lock]; + [pc.viewContext save:&error]; + [lock unlock]; + if(error) { + ALog(@"Error saving data: %@", [error localizedDescription]); + } + } +} + - (const void *)beginFolderAccess:(NSURL *)fileUrl { NSURL *folderUrl = [SandboxBroker urlWithoutFragment:fileUrl]; if(![folderUrl isFileURL]) return NULL;