this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

LaunchServices: Process file associations

+113 -14
+1 -1
src/frameworks/CoreServices/src/LaunchServices/launchservicesd/CMakeLists.txt
··· 13 13 14 14 target_link_libraries(launchservicesd system Foundation CoreFoundation CoreServices FMDB sqlite3 z) 15 15 install(TARGETS launchservicesd DESTINATION libexec/darling/System/Library/CoreServices) 16 - install(FILES schema.sql RENAME launchservicesd-schema.sql DESTINATION libexec/darling/System/Library/CoreServices) 16 + install(FILES schema.sql RENAME launchservicesd-schema.sql DESTINATION libexec/darling/System/Library/Frameworks/CoreServices.framework/Versions/A/Resources)
+90 -10
src/frameworks/CoreServices/src/LaunchServices/launchservicesd/LSBundle.m
··· 186 186 } 187 187 } 188 188 189 + // https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundledocumenttypes?language=objc 190 + -(void)processFileAssociation:(NSDictionary*)dict 191 + { 192 + NSNumber* myId = [NSNumber numberWithInt: _bundleId]; 193 + NSNumber* appDocId; 194 + 195 + NSString* iconFile = dict[@"CFBundleTypeIconFile"]; 196 + NSString* displayName = dict[@"CFBundleTypeName"]; 197 + NSString* role = dict[@"CFBundleTypeRole"]; 198 + NSString* rank = dict[@"LSHandlerRank"]; 199 + NSString* documentClass = dict[@"NSDocumentClass"]; 200 + 201 + // TODO: exportable types? 202 + 203 + if (!role) 204 + role = @"None"; 205 + if (!rank) 206 + rank = @"Default"; 207 + 208 + [g_database executeUpdate:@"insert into app_doc (icon,name,role,rank,class,bundle) values (?,?,?,?,?,?)", 209 + iconFile, displayName, role, rank, documentClass, myId]; 210 + appDocId = [NSNumber numberWithInt: [g_database lastInsertRowId]]; 211 + 212 + NSArray<NSString*>* contentTypes = dict[@"LSItemContentTypes"]; 213 + if (contentTypes) 214 + { 215 + for (NSString* uti in contentTypes) 216 + { 217 + if (![uti isKindOfClass: [NSString class]]) 218 + continue; 219 + 220 + [g_database executeUpdate:@"insert into app_doc_uti (doc, uti) values (?,?)", appDocId, uti]; 221 + } 222 + } 223 + else 224 + { 225 + // Support for obsolete CFBundleTypeExtensions and CFBundleTypeMIMETypes 226 + NSArray<NSString*>* extensions = dict[@"CFBundleTypeExtensions"]; 227 + 228 + if (extensions) 229 + { 230 + for (NSString* extension in extensions) 231 + { 232 + if (![extension isKindOfClass: [NSString class]]) 233 + continue; 234 + 235 + [g_database executeUpdate:@"insert into app_doc_extension (doc, extension) values (?,?)", appDocId, extension]; 236 + } 237 + } 238 + 239 + NSArray<NSString*>* mimeTypes = dict[@"CFBundleTypeMIMETypes"]; 240 + if (mimeTypes) 241 + { 242 + for (NSString* mime in mimeTypes) 243 + { 244 + if (![mime isKindOfClass: [NSString class]]) 245 + continue; 246 + 247 + [g_database executeUpdate:@"insert into app_doc_mime (doc, mime) values (?,?)", appDocId, mime]; 248 + } 249 + } 250 + } 251 + } 252 + 189 253 -(void)processFileAssociations 190 254 { 191 255 NSDictionary<NSString*,id>* infoDict = (NSDictionary*) CFBundleGetInfoDictionary(_bundle); 256 + NSNumber* myId = [NSNumber numberWithInt: _bundleId]; 192 257 193 - NSArray<NSString*>* contentTypes = infoDict[@"LSItemContentTypes"]; 258 + [g_database executeUpdate:@"delete from app_doc where bundle = ?", [NSNumber numberWithInt: _bundleId]]; 259 + 260 + NSArray<NSDictionary*>* types = (NSArray*) infoDict[@"CFBundleDocumentTypes"]; 261 + if (types) 262 + { 263 + NSLog(@"Found type array\n"); 264 + for (NSDictionary* type in types) 265 + [self processFileAssociation: type]; 266 + } 267 + if (infoDict[@"CFBundleTypeRole"] != nil) 268 + { 269 + NSLog(@"Found a single type\n"); 270 + [self processFileAssociation: infoDict]; 271 + } 194 272 } 195 273 196 274 -(BOOL)setupBundleID ··· 256 334 257 335 NSDictionary<NSString*,id>* infoDict = (NSDictionary*) CFBundleGetInfoDictionary(_bundle); 258 336 259 - NSArray<NSDictionary*>* utis = infoDict[@"UTExportedTypeDeclarations"]; 337 + NSArray<NSDictionary*>* utis = infoDict[(NSString*) kUTExportedTypeDeclarationsKey]; 260 338 if (utis != nil) 261 339 { 262 340 [self processUTIs:utis]; 263 341 } 264 342 265 - if (infoDict[@"LSItemContentTypes"] != nil) 266 - { 267 - [self processFileAssociations]; 268 - } 269 - 343 + [self processFileAssociations]; 270 344 [g_database commit]; 271 345 } 272 346 ··· 275 349 if (self == [LSBundle class]) 276 350 { 277 351 MONITORED_DIRECTORIES = @[ 352 + // This path doesn't contain apps, but may still contain UTI definitions 353 + @"/System/Library/Frameworks", 354 + 278 355 @"/Applications", 279 356 @"/System/Applications", 280 - // This path doesn't contain apps, but may still contain UTI definitions 281 - @"/System/Library/Frameworks", 282 357 ]; 283 358 284 359 FMDatabase* db = [FMDatabase databaseWithPath: @"/private/var/db/launchservices.db"]; ··· 312 387 [b process]; 313 388 } 314 389 } 390 + 391 + [bundles release]; 315 392 } 316 393 } 317 394 ··· 319 396 { 320 397 for (NSString* dir in MONITORED_DIRECTORIES) 321 398 [LSBundle scanForBundles: dir]; 399 + NSLog(@"scanForBundles done\n"); 322 400 } 323 401 324 402 +(void)watchForBundles ··· 342 420 343 421 static void createDBSchema(void) 344 422 { 345 - NSString* sqlSchema = [NSString stringWithContentsOfFile: @"/System/Library/CoreServices/launchservicesd-schema.sql" 423 + NSString* sqlSchema = [NSString stringWithContentsOfFile: @"/System/Library/Frameworks/CoreServices.framework/Versions/A/Resources/launchservicesd-schema.sql" 346 424 encoding: NSUTF8StringEncoding 347 425 error: nil]; 348 426 ··· 406 484 [LSBundle deleteBundleAtPath:bundlePath]; 407 485 } 408 486 } 487 + 488 + // TODO: If somebody renames the bundle's directory, we still need to pick it up 409 489 } 410 490 } 411 491 index++;
+22 -3
src/frameworks/CoreServices/src/LaunchServices/launchservicesd/schema.sql
··· 69 69 CREATE TABLE `app_doc_uti` ( 70 70 `id` INTEGER PRIMARY KEY AUTOINCREMENT, 71 71 `doc` INTEGER, 72 - `uti` INTEGER, 73 - FOREIGN KEY(`doc`) REFERENCES `app_doc`(`id`) ON DELETE CASCADE, 74 - FOREIGN KEY(`uti`) REFERENCES `uti`(`id`) ON DELETE CASCADE 72 + `uti` TEXT, 73 + FOREIGN KEY(`doc`) REFERENCES `app_doc`(`id`) ON DELETE CASCADE 75 74 ); 76 75 CREATE INDEX `app_doc_uti_doc_index` ON `app_doc_uti`(`doc`); 77 76 CREATE INDEX `app_doc_uti_index` ON `app_doc_uti`(`uti`); 77 + 78 + -- obsolete CFBundleTypeMIMETypes 79 + CREATE TABLE `app_doc_mime` ( 80 + `id` INTEGER PRIMARY KEY AUTOINCREMENT, 81 + `doc` INTEGER, 82 + `mime` TEXT, 83 + FOREIGN KEY(`doc`) REFERENCES `app_doc`(`id`) ON DELETE CASCADE 84 + ); 85 + CREATE INDEX `app_doc_mime_doc_index` ON `app_doc_mime`(`doc`); 86 + CREATE INDEX `app_doc_mime_index` ON `app_doc_mime`(`mime`); 87 + 88 + -- obsolete CFBundleTypeExtensions 89 + CREATE TABLE `app_doc_extension` ( 90 + `id` INTEGER PRIMARY KEY AUTOINCREMENT, 91 + `doc` INTEGER, 92 + `extension` TEXT, 93 + FOREIGN KEY(`doc`) REFERENCES `app_doc`(`id`) ON DELETE CASCADE 94 + ); 95 + CREATE INDEX `app_doc_extension_doc_index` ON `app_doc_extension`(`doc`); 96 + CREATE INDEX `app_doc_extension_index` ON `app_doc_extension`(`extension`);