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 |