OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #import "AppDelegate.h" | 5 #import "AppDelegate.h" |
6 | 6 |
| 7 #import "Downloader.h" |
7 #import "InstallerWindowController.h" | 8 #import "InstallerWindowController.h" |
8 #import "NSError+ChromeInstallerAdditions.h" | 9 #import "NSError+ChromeInstallerAdditions.h" |
9 #import "NSAlert+ChromeInstallerAdditions.h" | 10 #import "NSAlert+ChromeInstallerAdditions.h" |
| 11 #import "OmahaCommunication.h" |
| 12 #import "Unpacker.h" |
10 | 13 |
11 @interface NSAlert () | 14 @interface NSAlert () |
12 - (void)beginSheetModalForWindow:(NSWindow*)sheetWindow | 15 - (void)beginSheetModalForWindow:(NSWindow*)sheetWindow |
13 completionHandler: | 16 completionHandler: |
14 (void (^__nullable)(NSModalResponse returnCode))handler; | 17 (void (^__nullable)(NSModalResponse returnCode))handler; |
15 @end | 18 @end |
16 | 19 |
17 @interface AppDelegate ()<OmahaCommunicationDelegate, DownloaderDelegate> { | 20 @interface AppDelegate ()<OmahaCommunicationDelegate, |
| 21 DownloaderDelegate, |
| 22 UnpackDelegate> { |
18 InstallerWindowController* installerWindowController_; | 23 InstallerWindowController* installerWindowController_; |
| 24 Unpacker* unpacker_; |
19 } | 25 } |
20 @property(strong) NSWindow* window; | 26 @property(strong) NSWindow* window; |
21 @end | 27 @end |
22 | 28 |
23 @implementation AppDelegate | 29 @implementation AppDelegate |
24 @synthesize window = window_; | 30 @synthesize window = window_; |
25 | 31 |
26 // Sets up the main window and begins the downloading process. | 32 // Sets up the main window and begins the downloading process. |
27 - (void)applicationDidFinishLaunching:(NSNotification*)aNotification { | 33 - (void)applicationDidFinishLaunching:(NSNotification*)aNotification { |
28 installerWindowController_ = | 34 installerWindowController_ = |
29 [[InstallerWindowController alloc] initWithWindow:window_]; | 35 [[InstallerWindowController alloc] initWithWindow:window_]; |
| 36 unpacker_ = [[Unpacker alloc] |
| 37 // NOTE: purposefully misspelled Chrome in order to avoid overwriting the |
| 38 // current machine's Google Chrome installation. |
| 39 // TODO: this app name can be a command-line flag |
| 40 initWithFinalAppPath:@"/Applications/Google Chromo.app"]; |
| 41 unpacker_.delegate = self; |
| 42 |
30 [self startDownload]; | 43 [self startDownload]; |
31 } | 44 } |
32 | 45 |
33 - (void)applicationWillTerminate:(NSNotification*)aNotification { | 46 - (void)applicationWillTerminate:(NSNotification*)aNotification { |
34 } | 47 } |
35 | 48 |
36 - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)sender { | 49 - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)sender { |
37 return YES; | 50 return YES; |
38 } | 51 } |
39 | 52 |
40 - (void)startDownload { | 53 - (void)startDownload { |
41 [installerWindowController_ updateStatusDescription:@"Initializing..."]; | 54 [installerWindowController_ updateStatusDescription:@"Initializing..."]; |
42 OmahaCommunication* omahaMessenger = [[OmahaCommunication alloc] init]; | 55 OmahaCommunication* omahaMessenger = [[OmahaCommunication alloc] init]; |
43 omahaMessenger.delegate = self; | 56 omahaMessenger.delegate = self; |
44 | 57 |
45 [omahaMessenger fetchDownloadURLs]; | 58 [omahaMessenger fetchDownloadURLs]; |
46 } | 59 } |
47 | 60 |
48 - (void)onOmahaSuccessWithURLs:(NSArray*)URLs { | 61 - (void)omahaCommunication:(OmahaCommunication*)messenger |
| 62 onSuccess:(NSArray*)URLs { |
49 [installerWindowController_ updateStatusDescription:@"Downloading..."]; | 63 [installerWindowController_ updateStatusDescription:@"Downloading..."]; |
50 Downloader* download = [[Downloader alloc] init]; | 64 Downloader* download = [[Downloader alloc] init]; |
51 download.delegate = self; | 65 download.delegate = self; |
52 [download downloadChromeImageToDownloadsDirectory:[URLs firstObject]]; | 66 [download downloadChromeImageFrom:[URLs firstObject]]; |
53 } | 67 } |
54 | 68 |
55 - (void)onOmahaFailureWithError:(NSError*)error { | 69 - (void)omahaCommunication:(OmahaCommunication*)messenger |
| 70 onFailure:(NSError*)error { |
56 NSError* networkError = | 71 NSError* networkError = |
57 [NSError errorForAlerts:@"Network Error" | 72 [NSError errorForAlerts:@"Network Error" |
58 withDescription:@"Could not connect to Chrome server." | 73 withDescription:@"Could not connect to Chrome server." |
59 isRecoverable:YES]; | 74 isRecoverable:YES]; |
60 [self displayError:networkError]; | 75 [self displayError:networkError]; |
61 } | 76 } |
62 | 77 |
63 // Bridge method from Downloader to InstallerWindowController. Allows Downloader | 78 // Bridge method from Downloader to InstallerWindowController. Allows Downloader |
64 // to update the progressbar without having direct access to any UI obejcts. | 79 // to update the progressbar without having direct access to any UI obejcts. |
65 - (void)didDownloadData:(double)downloadProgressPercentage { | 80 - (void)downloader:(Downloader*)download percentProgress:(double)percentage { |
66 [installerWindowController_ | 81 [installerWindowController_ updateDownloadProgress:(double)percentage]; |
67 updateDownloadProgress:(double)downloadProgressPercentage]; | |
68 } | 82 } |
69 | 83 |
70 - (void)downloader:(Downloader*)download | 84 - (void)downloader:(Downloader*)download onSuccess:(NSURL*)diskImageURL { |
71 onDownloadSuccess:(NSURL*)diskImagePath { | |
72 [installerWindowController_ updateStatusDescription:@"Done."]; | 85 [installerWindowController_ updateStatusDescription:@"Done."]; |
73 // TODO: replace the line of code below with real code someday | 86 [unpacker_ mountDMGFromURL:diskImageURL]; |
74 } | 87 } |
75 | 88 |
76 - (void)downloader:(Downloader*)download | 89 - (void)downloader:(Downloader*)download onFailure:(NSError*)error { |
77 onDownloadFailureWithError:(NSError*)error { | |
78 NSError* downloadError = | 90 NSError* downloadError = |
79 [NSError errorForAlerts:@"Download Failure" | 91 [NSError errorForAlerts:@"Download Failure" |
80 withDescription:@"Unable to download Google Chrome." | 92 withDescription:@"Unable to download Google Chrome." |
81 isRecoverable:NO]; | 93 isRecoverable:NO]; |
82 [self displayError:downloadError]; | 94 [self displayError:downloadError]; |
83 } | 95 } |
84 | 96 |
| 97 - (void)unpacker:(Unpacker*)unpacker onSuccess:(NSString*)appPath { |
| 98 NSError* error = nil; |
| 99 [[NSWorkspace sharedWorkspace] |
| 100 launchApplicationAtURL:[NSURL fileURLWithPath:appPath isDirectory:NO] |
| 101 options:NSWorkspaceLaunchDefault |
| 102 configuration:@{} |
| 103 error:&error]; |
| 104 if (error) { |
| 105 NSLog(@"Chromo failed to launch: %@", error); |
| 106 } |
| 107 // TODO: make it seem like the installer has finished its work, and begin |
| 108 // tear-down work |
| 109 [unpacker unmountDMG]; |
| 110 } |
| 111 |
| 112 - (void)unpacker:(Unpacker*)unpacker onFailure:(NSError*)error { |
| 113 NSError* extractError = |
| 114 [NSError errorForAlerts:@"Install Failure" |
| 115 withDescription:@"Unable to add Google Chrome to Applications." |
| 116 isRecoverable:NO]; |
| 117 [self displayError:extractError]; |
| 118 } |
| 119 |
| 120 - (void)unpacker:(Unpacker*)unpacker onUnmountSuccess:(NSString*)mountpath { |
| 121 // TODO: add temporary folder deleting |
| 122 NSLog(@"we're done here!"); |
| 123 } |
| 124 |
| 125 - (void)unpacker:(Unpacker*)unpacker onUnmountFailure:(NSError*)error { |
| 126 NSLog(@"error unmounting"); |
| 127 // NOTE: since we are not deleting the temporary folder if the unmount fails, |
| 128 // we'll just leave it up to the computer to delete the temporary folder on |
| 129 // its own time, and to unmount the disk during a restart at some point. there |
| 130 // is no other work to be done in the mean time. |
| 131 [NSApp teminate:nil]; |
| 132 } |
| 133 |
85 // Displays an alert on the main window using the contents of the passed in | 134 // Displays an alert on the main window using the contents of the passed in |
86 // error. | 135 // error. |
87 - (void)displayError:(NSError*)error { | 136 - (void)displayError:(NSError*)error { |
88 NSAlert* alertForUser = [NSAlert alertWithError:error]; | 137 NSAlert* alertForUser = [NSAlert alertWithError:error]; |
89 | 138 |
90 dispatch_sync(dispatch_get_main_queue(), ^{ | 139 dispatch_sync(dispatch_get_main_queue(), ^{ |
91 [alertForUser beginSheetModalForWindow:window_ | 140 [alertForUser beginSheetModalForWindow:window_ |
92 completionHandler:^(NSModalResponse returnCode) { | 141 completionHandler:^(NSModalResponse returnCode) { |
93 if (returnCode != [alertForUser quitButton]) { | 142 if (returnCode != [alertForUser quitResponse]) { |
94 [self startDownload]; | 143 [self startDownload]; |
95 } else { | 144 } else { |
96 [NSApp terminate:nil]; | 145 [NSApp terminate:nil]; |
97 } | 146 } |
98 }]; | 147 }]; |
99 }); | 148 }); |
100 } | 149 } |
101 | 150 |
102 @end | 151 @end |
OLD | NEW |