Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9131)

Unified Diff: chrome/installer/mac/app/Unpacker.m

Issue 2203583002: Added unpacking step (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Ready for review! Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/installer/mac/app/Unpacker.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/installer/mac/app/Unpacker.m
diff --git a/chrome/installer/mac/app/Unpacker.m b/chrome/installer/mac/app/Unpacker.m
new file mode 100644
index 0000000000000000000000000000000000000000..d9d47d0dc9581489113a57c8063549258fd9fdf1
--- /dev/null
+++ b/chrome/installer/mac/app/Unpacker.m
@@ -0,0 +1,131 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "Unpacker.h"
+
+#include <DiskArbitration/DiskArbitration.h>
+
+#import "Downloader.h"
+
+// TODO: make paths not depend on location of executable
+// cocoa temporary folders: nstemporarydirectory
+#define PATH_FROM_EXECUTABLE(x) \
+ [[[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:x] \
+ stringByResolvingSymlinksInPath]
Sidney San Martín 2016/08/05 20:35:04 This should be a pretty quick change, any reason n
Anna Zeng 2016/08/05 21:48:40 I plan to include progress on this in the other re
+
+@implementation Unpacker
+
+@synthesize delegate = delegate_;
+
+DASessionRef session;
+
+// TODO: make testing more convenient
+
+- (void)unpackDMG {
+ // TODO: how to find this from the PATH env variable?
+ NSString* path = @"/usr/bin/hdiutil";
+ NSArray* args = @[
+ // TODO: break getDownloadsFilePath out of the downloader file
+ @"mount", [Downloader getDownloadsFilePath], @"-nobrowse", @"-mountpoint",
+ PATH_FROM_EXECUTABLE(@"tmp")
+ ];
+
+ NSTask* unmountTask = [[NSTask alloc] init];
+ unmountTask.launchPath = path;
+ unmountTask.arguments = args;
+ unmountTask.terminationHandler = ^void(NSTask* task) {
Mark Mentovai 2016/08/02 19:01:32 Aha! This is what’s causing all of the trouble wit
Anna Zeng 2016/08/02 23:58:22 Awesome! This helped immensely. I ended up using a
+ [self extractChrome];
+ };
+ [unmountTask launch];
+}
+
+- (void)extractChrome {
+ NSLog(@"extracting chrome");
+ NSFileManager* fileManager = [NSFileManager defaultManager];
+ if (![fileManager
+ fileExistsAtPath:PATH_FROM_EXECUTABLE(@"tmp/Google Chrome.app")]) {
+ NSLog(@"File in DMG doesn't exist");
+ }
+
+ // TODO: make async
+ NSError* err;
+ if (![fileManager
+ copyItemAtPath:PATH_FROM_EXECUTABLE(@"tmp/Google Chrome.app")
+ toPath:@"/Applications/Google Chromo.app"
+ error:&err]) {
+ NSLog(@"%@", err);
+ }
+
+ [self cleanUp];
+}
+- (void)cleanUp {
+ NSFileManager* fileManager = [NSFileManager defaultManager];
+ if ([fileManager removeItemAtPath:[Downloader getDownloadsFilePath]
+ error:nil]) {
+ NSLog(@"Disk image removed!");
+ }
+
+ // TODO: run the app instead of removing it every time
+ if ([fileManager removeItemAtPath:@"/Applications/Google Chromo.app"
+ error:nil]) {
+ NSLog(@"Application removed!");
+ }
+
+ session = DASessionCreate(nil);
+ DASessionScheduleWithRunLoop(session, CFRunLoopGetCurrent(),
+ kCFRunLoopCommonModes);
+ // TODO: how can we make the run loop run using the nsrunloop?
+ // DASessionScheduleWithRunLoop(session, [[NSRunLoop currentRunLoop]
+ // getCFRunLoop],
+ // (CFStringRef)NSDefaultRunLoopMode);
+ DADiskRef child_disk = DADiskCreateFromVolumePath(
+ nil, session,
+ (CFURLRef)[NSURL URLWithString:PATH_FROM_EXECUTABLE(@"tmp")]);
+ DADiskRef whole_disk = DADiskCopyWholeDisk(child_disk);
+ DADiskUnmount(whole_disk, kDADiskUnmountOptionWhole, unmount_callback,
+ (void*)self);
+ NSLog(@"Releasing disk");
+ CFRelease(whole_disk);
+ CFRelease(child_disk);
+
+ // TODO: when ivan's cr lands eliminate this bandaid
+ CFRunLoopRun();
+}
+
+void unmount_callback(DADiskRef disk, DADissenterRef dissenter, void* context) {
+ NSLog(@"reached unmount callback");
+ if (dissenter) {
+ DAReturn status = DADissenterGetStatus(dissenter);
+ if (unix_err(status)) {
+ int code = err_get_code(status);
+ NSLog(@"Error code %d", code);
+ }
+ } else {
+ DADiskEject(disk, kDADiskEjectOptionDefault, eject_callback, context);
+ }
+}
+
+void eject_callback(DADiskRef disk, DADissenterRef dissenter, void* context) {
+ NSLog(@"reached eject callback");
+ if (dissenter) {
+ DAReturn status = DADissenterGetStatus(dissenter);
+ if (unix_err(status)) {
+ int code = err_get_code(status);
+ NSLog(@"Error code %d", code);
+ }
+ }
+ Unpacker* obj_self = (__bridge Unpacker*)context;
Sidney San Martín 2016/08/05 20:35:04 These functions aren't really part of Unpacker, so
Sidney San Martín 2016/08/05 21:13:40 You should also use `static` on these functions to
Anna Zeng 2016/08/05 21:48:40 Done.
Anna Zeng 2016/08/05 21:48:40 Done.
+ [obj_self callbackFollowDisk:disk];
Sidney San Martín 2016/08/05 20:35:04 Could you include error info in the callback?
Anna Zeng 2016/08/05 21:48:40 Done, with more progress to come!
+}
+
+- (void)callbackFollowDisk:(DADiskRef)disk {
+ NSLog(@"Unscheduling session");
+ DASessionUnscheduleFromRunLoop(
+ session, CFRunLoopGetCurrent(),
+ kCFRunLoopCommonModes); // kCFRunLoopDefaultMode);
+
+ [delegate_ onUnpackSuccess];
+}
+
+@end
« no previous file with comments | « chrome/installer/mac/app/Unpacker.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698