Chromium Code Reviews| Index: chrome/installer/mac/app/AppDelegate.m |
| diff --git a/chrome/installer/mac/app/AppDelegate.m b/chrome/installer/mac/app/AppDelegate.m |
| index f60f0db6e36ed8641e1c40dca619541c7b868187..4505114bbda71c4d531ef93bbd95b1312fb33e26 100644 |
| --- a/chrome/installer/mac/app/AppDelegate.m |
| +++ b/chrome/installer/mac/app/AppDelegate.m |
| @@ -4,9 +4,12 @@ |
| #import "AppDelegate.h" |
| +#import "Downloader.h" |
| #import "InstallerWindowController.h" |
| #import "NSError+ChromeInstallerAdditions.h" |
| #import "NSAlert+ChromeInstallerAdditions.h" |
| +#import "OmahaCommunication.h" |
| +#import "Unpacker.h" |
| @interface NSAlert () |
| - (void)beginSheetModalForWindow:(NSWindow*)sheetWindow |
| @@ -14,10 +17,15 @@ |
| (void (^__nullable)(NSModalResponse returnCode))handler; |
| @end |
| -@interface AppDelegate ()<OmahaCommunicationDelegate, DownloaderDelegate> { |
| +@interface AppDelegate ()<NSWindowDelegate, |
| + OmahaCommunicationDelegate, |
| + DownloaderDelegate, |
| + UnpackDelegate> { |
| InstallerWindowController* installerWindowController_; |
| + BOOL preventTermination_; |
| } |
| @property(strong) NSWindow* window; |
| +- (void)exit; |
| @end |
| @implementation AppDelegate |
| @@ -25,34 +33,55 @@ |
| // Sets up the main window and begins the downloading process. |
| - (void)applicationDidFinishLaunching:(NSNotification*)aNotification { |
| + window_.delegate = self; |
| installerWindowController_ = |
| [[InstallerWindowController alloc] initWithWindow:window_]; |
| + |
| [self startDownload]; |
| } |
| - (void)applicationWillTerminate:(NSNotification*)aNotification { |
| } |
| -- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)sender { |
| +// This function effectively takes the place of |
| +// applicationShouldTerminateAfterLastWindowClosed: to make sure that the |
| +// application does correctly terminate after closing the installer, but does |
| +// not terminate when we call orderOut: to hide the installer during its |
| +// tear-down steps. |
| +- (BOOL)windowShouldClose:(id)sender { |
| + [self exit]; |
|
Elly Fong-Jones
2016/08/23 21:57:40
does orderOut constitute a window close?
Anna Zeng
2016/08/24 01:30:10
The window is hidden when we call orderOut. To the
|
| return YES; |
| } |
| +- (NSApplicationTerminateReply)applicationShouldTerminate: |
| + (NSApplication*)sender { |
| + return preventTermination_ ? NSTerminateCancel : NSTerminateNow; |
| +} |
| + |
| +- (void)exit { |
| + preventTermination_ = NO; |
| + [NSApp terminate:nil]; |
| +} |
| + |
| - (void)startDownload { |
| [installerWindowController_ updateStatusDescription:@"Initializing..."]; |
| + |
| OmahaCommunication* omahaMessenger = [[OmahaCommunication alloc] init]; |
| omahaMessenger.delegate = self; |
| - |
| [omahaMessenger fetchDownloadURLs]; |
| } |
| -- (void)onOmahaSuccessWithURLs:(NSArray*)URLs { |
| +- (void)omahaCommunication:(OmahaCommunication*)messenger |
| + onSuccess:(NSArray*)URLs { |
| [installerWindowController_ updateStatusDescription:@"Downloading..."]; |
| + |
| Downloader* download = [[Downloader alloc] init]; |
| download.delegate = self; |
| - [download downloadChromeImageToDownloadsDirectory:[URLs firstObject]]; |
| + [download downloadChromeImageFrom:[URLs firstObject]]; |
| } |
| -- (void)onOmahaFailureWithError:(NSError*)error { |
| +- (void)omahaCommunication:(OmahaCommunication*)messenger |
| + onFailure:(NSError*)error { |
| NSError* networkError = |
| [NSError errorForAlerts:@"Network Error" |
| withDescription:@"Could not connect to Chrome server." |
| @@ -62,19 +91,19 @@ |
| // Bridge method from Downloader to InstallerWindowController. Allows Downloader |
| // to update the progressbar without having direct access to any UI obejcts. |
| -- (void)didDownloadData:(double)downloadProgressPercentage { |
| - [installerWindowController_ |
| - updateDownloadProgress:(double)downloadProgressPercentage]; |
| +- (void)downloader:(Downloader*)download percentProgress:(double)percentage { |
| + [installerWindowController_ updateDownloadProgress:(double)percentage]; |
| } |
| -- (void)downloader:(Downloader*)download |
| - onDownloadSuccess:(NSURL*)diskImagePath { |
| - [installerWindowController_ updateStatusDescription:@"Done."]; |
| - // TODO: replace the line of code below with real code someday |
| +- (void)downloader:(Downloader*)download onSuccess:(NSURL*)diskImageURL { |
| + [installerWindowController_ updateStatusDescription:@"Installing..."]; |
| + |
| + Unpacker* unpacker = [[Unpacker alloc] init]; |
| + unpacker.delegate = self; |
| + [unpacker mountDMGFromURL:diskImageURL]; |
| } |
| -- (void)downloader:(Downloader*)download |
| - onDownloadFailureWithError:(NSError*)error { |
| +- (void)downloader:(Downloader*)download onFailure:(NSError*)error { |
| NSError* downloadError = |
| [NSError errorForAlerts:@"Download Failure" |
| withDescription:@"Unable to download Google Chrome." |
| @@ -82,15 +111,83 @@ |
| [self displayError:downloadError]; |
| } |
| +- (void)unpacker:(Unpacker*)unpacker onMountSuccess:(NSString*)tempAppPath { |
| + // Calling this function will change the progress bar into an indeterminate |
| + // one. We won't need to update the progress bar any more after this point. |
| + [installerWindowController_ updateDownloadProgress:-1.0]; |
| + // By disabling closing the window or quitting, we can tell the user that |
| + // closing the application at this point is not a good idea. |
| + window_.styleMask &= ~NSClosableWindowMask; |
| + preventTermination_ = YES; |
| + |
| + // TODO: move the below code into AuthorizedInstall |
| + |
| + NSError* error = nil; |
| + if ([[NSFileManager defaultManager] |
| + fileExistsAtPath:@"/Applications/Google Chromo.app"]) { |
|
Elly Fong-Jones
2016/08/23 21:57:40
This constant should probably not be repeated all
Anna Zeng
2016/08/24 01:30:10
Acknowledged. Fixed temporarily; this code would s
|
| + [[NSFileManager defaultManager] |
| + moveItemAtPath:@"/Applications/Google Chromo.app" |
| + toPath:tempAppPath |
| + error:nil]; |
| + } |
| + if (![[NSFileManager defaultManager] |
| + moveItemAtPath:tempAppPath |
| + toPath:@"/Applications/Google Chromo.app" |
| + error:&error]) { |
| + NSLog(@"%@", error); |
| + } |
| + |
| + // TODO: edit the below code to feed in command line arguments |
| + |
| + [[NSWorkspace sharedWorkspace] |
| + launchApplicationAtURL: |
| + [NSURL fileURLWithPath:@"/Applications/Google Chromo.app" |
| + isDirectory:NO] |
| + options:NSWorkspaceLaunchDefault |
| + configuration:@{} |
| + error:&error]; |
| + if (error) { |
| + NSLog(@"Chromo failed to launch: %@", error); |
| + } |
| + |
| + // Begin teardown stuff! |
| + dispatch_async(dispatch_get_main_queue(), ^{ |
| + [window_ orderOut:nil]; |
| + }); |
| + |
| + [unpacker unmountDMG]; |
| +} |
| + |
| +- (void)unpacker:(Unpacker*)unpacker onMountFailure:(NSError*)error { |
| + NSError* extractError = |
| + [NSError errorForAlerts:@"Install Failure" |
| + withDescription:@"Unable to add Google Chrome to Applications." |
| + isRecoverable:NO]; |
| + [self displayError:extractError]; |
| +} |
| + |
| +- (void)unpacker:(Unpacker*)unpacker onUnmountSuccess:(NSString*)mountpath { |
| + NSLog(@"we're done here!"); |
| + [self exit]; |
| +} |
| + |
| +- (void)unpacker:(Unpacker*)unpacker onUnmountFailure:(NSError*)error { |
| + NSLog(@"error unmounting"); |
| + // NOTE: since we are not deleting the temporary folder if the unmount fails, |
| + // we'll just leave it up to the computer to delete the temporary folder on |
| + // its own time, and to unmount the disk during a restart at some point. There |
| + // is no other work to be done in the mean time. |
| + [self exit]; |
| +} |
| + |
| // Displays an alert on the main window using the contents of the passed in |
| // error. |
| - (void)displayError:(NSError*)error { |
| NSAlert* alertForUser = [NSAlert alertWithError:error]; |
| - |
| - dispatch_sync(dispatch_get_main_queue(), ^{ |
| + dispatch_async(dispatch_get_main_queue(), ^{ |
| [alertForUser beginSheetModalForWindow:window_ |
| completionHandler:^(NSModalResponse returnCode) { |
| - if (returnCode != [alertForUser quitButton]) { |
| + if (returnCode != [alertForUser quitResponse]) { |
| [self startDownload]; |
| } else { |
| [NSApp terminate:nil]; |