Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #import "Unpacker.h" | |
| 6 | |
| 7 // #include <copyfile.h> | |
| 8 #include <DiskArbitration/DiskArbitration.h> | |
| 9 #include <dispatch/dispatch.h> | |
| 10 | |
| 11 #import "Downloader.h" | |
| 12 | |
| 13 dispatch_semaphore_t mount_semaphore; | |
| 14 | |
| 15 @implementation Unpacker | |
| 16 | |
| 17 @synthesize delegate = delegate_; | |
| 18 | |
| 19 DASessionRef session; | |
| 20 dispatch_queue_t unpack_dq; | |
|
Sidney San Martín
2016/08/08 18:43:17
These should be instance variables, not globals (l
Anna Zeng
2016/08/12 22:56:18
Done.
| |
| 21 | |
| 22 static void unmount_callback(DADiskRef disk, | |
| 23 DADissenterRef dissenter, | |
| 24 void* context) { | |
| 25 if (dissenter) { | |
| 26 DAReturn status = DADissenterGetStatus(dissenter); | |
| 27 if (unix_err(status)) { | |
| 28 int code = err_get_code(status); | |
| 29 NSLog(@"Unmount error code %d", code); | |
| 30 // TODO: error handling | |
| 31 } | |
| 32 } else { | |
| 33 DADiskEject(disk, kDADiskEjectOptionDefault, eject_callback, context); | |
| 34 } | |
| 35 } | |
| 36 | |
| 37 static void eject_callback(DADiskRef disk, | |
| 38 DADissenterRef dissenter, | |
| 39 void* context) { | |
| 40 NSError* error; | |
| 41 if (dissenter) { | |
| 42 DAReturn status = DADissenterGetStatus(dissenter); | |
| 43 if (unix_err(status)) { | |
| 44 int code = err_get_code(status); | |
| 45 NSLog(@"Eject error code %d", code); | |
| 46 // TODO: error handling | |
| 47 error = [NSError errorWithDomain:@"ChromeErrorDomain" | |
| 48 code:code | |
| 49 userInfo:@{ | |
| 50 NSLocalizedDescriptionKey : | |
| 51 DADissenterGetStatusString(dissenter) | |
| 52 }]; | |
| 53 } | |
| 54 } | |
| 55 Unpacker* unpacker = (__bridge Unpacker*)context; | |
| 56 [unpacker didFinishEjectingDisk:disk WithError:error]; | |
| 57 } | |
| 58 | |
| 59 - (void)mountDMG { | |
| 60 // TODO: how to find this from the PATH env variable? | |
|
Sidney San Martín
2016/08/08 18:43:17
TBH, since this is a system utility I think that h
Anna Zeng
2016/08/12 22:56:18
Done.
| |
| 61 NSString* path = @"/usr/bin/hdiutil"; | |
| 62 NSArray* args = @[ | |
| 63 // TODO: break getDownloadsFilePath out of the downloader file | |
| 64 @"mount", [Downloader getDownloadsFilePath], @"-nobrowse", @"-mountpoint", | |
| 65 PATH_FROM_EXECUTABLE(@"tmp") | |
| 66 ]; | |
| 67 | |
| 68 NSTask* mountTask = [[NSTask alloc] init]; | |
| 69 mountTask.launchPath = path; | |
| 70 mountTask.arguments = args; | |
| 71 mountTask.terminationHandler = ^void(NSTask* task) { | |
| 72 unpack_dq = dispatch_queue_create("com.google.chrome.unpack", | |
| 73 DISPATCH_QUEUE_SERIAL); | |
| 74 dispatch_async(unpack_dq, ^{ | |
| 75 [self extractChrome]; | |
| 76 }); | |
| 77 }; | |
| 78 [mountTask launch]; | |
| 79 // TODO: how to error handling | |
| 80 } | |
| 81 | |
| 82 - (void)extractChrome { | |
| 83 NSFileManager* fileManager = [NSFileManager defaultManager]; | |
| 84 if (![fileManager | |
| 85 fileExistsAtPath:PATH_FROM_EXECUTABLE(@"tmp/Google Chrome.app")]) { | |
| 86 NSLog(@"File in DMG doesn't exist"); | |
| 87 // TODO: error handling | |
| 88 } | |
| 89 | |
| 90 // TODO: add progress | |
| 91 NSError* err; | |
| 92 if (![fileManager | |
| 93 copyItemAtPath:PATH_FROM_EXECUTABLE(@"tmp/Google Chrome.app") | |
| 94 toPath:@"/Applications/Google Chromo.app" | |
|
Sidney San Martín
2016/08/08 18:43:18
This path should come from outside (property, argu
Anna Zeng
2016/08/12 22:56:18
Done.
| |
| 95 error:&err]) { | |
| 96 NSLog(@"%@", err); | |
| 97 } | |
| 98 dispatch_semaphore_signal(mount_semaphore); | |
| 99 } | |
| 100 | |
| 101 - (void)unmountDMG { | |
| 102 session = DASessionCreate(nil); | |
| 103 DASessionSetDispatchQueue(session, unpack_dq); | |
| 104 DADiskRef child_disk = DADiskCreateFromVolumePath( | |
| 105 nil, session, | |
| 106 (CFURLRef)[NSURL URLWithString:PATH_FROM_EXECUTABLE(@"tmp")]); | |
| 107 DADiskRef whole_disk = DADiskCopyWholeDisk(child_disk); | |
| 108 | |
| 109 DADiskUnmount(whole_disk, kDADiskUnmountOptionWhole, unmount_callback, | |
| 110 (void*)self); | |
| 111 | |
| 112 CFRelease(whole_disk); | |
| 113 CFRelease(child_disk); | |
| 114 } | |
| 115 | |
| 116 - (void)didFinishEjectingDisk:(DADiskRef)disk WithError:(NSError*)error { | |
| 117 DASessionSetDispatchQueue(session, NULL); | |
| 118 dispatch_release(unpack_dq); | |
| 119 [delegate_ onUnpackSuccess]; | |
| 120 } | |
| 121 | |
| 122 @end | |
| OLD | NEW |