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 ()<NSWindowDelegate, |
21 OmahaCommunicationDelegate, | |
22 DownloaderDelegate, | |
23 UnpackDelegate> { | |
18 InstallerWindowController* installerWindowController_; | 24 InstallerWindowController* installerWindowController_; |
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 { |
34 window_.delegate = self; | |
28 installerWindowController_ = | 35 installerWindowController_ = |
29 [[InstallerWindowController alloc] initWithWindow:window_]; | 36 [[InstallerWindowController alloc] initWithWindow:window_]; |
37 | |
30 [self startDownload]; | 38 [self startDownload]; |
31 } | 39 } |
32 | 40 |
33 - (void)applicationWillTerminate:(NSNotification*)aNotification { | 41 - (void)applicationWillTerminate:(NSNotification*)aNotification { |
34 } | 42 } |
35 | 43 |
36 - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)sender { | 44 // This function effectively takes the place of |
45 // applicationShouldTerminateAfterLastWindowClosed: to make sure that the | |
46 // application does correctly terminate after closing the installer, but does | |
47 // not terminate when we call windowOut: to hide the installer during its | |
Sidney San Martín
2016/08/19 22:06:04
orderOut:
Anna Zeng
2016/08/23 03:13:43
Done.
| |
48 // tear-down steps. | |
49 - (BOOL)windowShouldClose:(id)sender { | |
50 [NSApp terminate:nil]; | |
37 return YES; | 51 return YES; |
38 } | 52 } |
39 | 53 |
40 - (void)startDownload { | 54 - (void)startDownload { |
41 [installerWindowController_ updateStatusDescription:@"Initializing..."]; | 55 [installerWindowController_ updateStatusDescription:@"Initializing..."]; |
56 | |
42 OmahaCommunication* omahaMessenger = [[OmahaCommunication alloc] init]; | 57 OmahaCommunication* omahaMessenger = [[OmahaCommunication alloc] init]; |
43 omahaMessenger.delegate = self; | 58 omahaMessenger.delegate = self; |
44 | |
45 [omahaMessenger fetchDownloadURLs]; | 59 [omahaMessenger fetchDownloadURLs]; |
46 } | 60 } |
47 | 61 |
48 - (void)onOmahaSuccessWithURLs:(NSArray*)URLs { | 62 - (void)omahaCommunication:(OmahaCommunication*)messenger |
63 onSuccess:(NSArray*)URLs { | |
49 [installerWindowController_ updateStatusDescription:@"Downloading..."]; | 64 [installerWindowController_ updateStatusDescription:@"Downloading..."]; |
65 | |
50 Downloader* download = [[Downloader alloc] init]; | 66 Downloader* download = [[Downloader alloc] init]; |
51 download.delegate = self; | 67 download.delegate = self; |
52 [download downloadChromeImageToDownloadsDirectory:[URLs firstObject]]; | 68 [download downloadChromeImageFrom:[URLs firstObject]]; |
53 } | 69 } |
54 | 70 |
55 - (void)onOmahaFailureWithError:(NSError*)error { | 71 - (void)omahaCommunication:(OmahaCommunication*)messenger |
72 onFailure:(NSError*)error { | |
56 NSError* networkError = | 73 NSError* networkError = |
57 [NSError errorForAlerts:@"Network Error" | 74 [NSError errorForAlerts:@"Network Error" |
58 withDescription:@"Could not connect to Chrome server." | 75 withDescription:@"Could not connect to Chrome server." |
59 isRecoverable:YES]; | 76 isRecoverable:YES]; |
60 [self displayError:networkError]; | 77 [self displayError:networkError]; |
61 } | 78 } |
62 | 79 |
63 // Bridge method from Downloader to InstallerWindowController. Allows Downloader | 80 // Bridge method from Downloader to InstallerWindowController. Allows Downloader |
64 // to update the progressbar without having direct access to any UI obejcts. | 81 // to update the progressbar without having direct access to any UI obejcts. |
65 - (void)didDownloadData:(double)downloadProgressPercentage { | 82 - (void)downloader:(Downloader*)download percentProgress:(double)percentage { |
66 [installerWindowController_ | 83 [installerWindowController_ updateDownloadProgress:(double)percentage]; |
67 updateDownloadProgress:(double)downloadProgressPercentage]; | |
68 } | 84 } |
69 | 85 |
70 - (void)downloader:(Downloader*)download | 86 - (void)downloader:(Downloader*)download onSuccess:(NSURL*)diskImageURL { |
71 onDownloadSuccess:(NSURL*)diskImagePath { | 87 [installerWindowController_ updateStatusDescription:@"Installing..."]; |
72 [installerWindowController_ updateStatusDescription:@"Done."]; | 88 |
73 // TODO: replace the line of code below with real code someday | 89 Unpacker* unpacker = [[Unpacker alloc] init]; |
90 unpacker.delegate = self; | |
91 [unpacker mountDMGFromURL:diskImageURL]; | |
74 } | 92 } |
75 | 93 |
76 - (void)downloader:(Downloader*)download | 94 - (void)downloader:(Downloader*)download onFailure:(NSError*)error { |
77 onDownloadFailureWithError:(NSError*)error { | |
78 NSError* downloadError = | 95 NSError* downloadError = |
79 [NSError errorForAlerts:@"Download Failure" | 96 [NSError errorForAlerts:@"Download Failure" |
80 withDescription:@"Unable to download Google Chrome." | 97 withDescription:@"Unable to download Google Chrome." |
81 isRecoverable:NO]; | 98 isRecoverable:NO]; |
82 [self displayError:downloadError]; | 99 [self displayError:downloadError]; |
83 } | 100 } |
84 | 101 |
102 - (void)unpacker:(Unpacker*)unpacker onMountSuccess:(NSString*)mountPath { | |
103 // TODO: move the below code into AuthorizedInstall | |
104 NSString* diskAppPath = | |
105 [NSString pathWithComponents:@[ mountPath, @"Google Chrome.app" ]]; | |
106 if (![[NSFileManager defaultManager] fileExistsAtPath:diskAppPath]) { | |
107 NSLog(@"File in DMG doesn't exist"); | |
108 } | |
109 | |
110 // By disabling closing the window, we can guarantee that the user will not | |
Sidney San Martín
2016/08/19 22:06:04
I don't think guarantee is the right word :). They
Anna Zeng
2016/08/23 03:13:43
Done.
| |
111 // have a partially-copied Google Chrome application. | |
112 // TODO: should we keep this? | |
113 window_.styleMask &= ~NSClosableWindowMask; | |
Sidney San Martín
2016/08/19 22:06:04
You also need to disable quit. Implementing applic
Anna Zeng
2016/08/23 03:13:43
Done.
| |
114 | |
115 // Calling this function will change the progress bar into an indeterminate | |
116 // one. We won't need to update the progress bar any more after this point | |
117 [installerWindowController_ updateDownloadProgress:-1.0]; | |
118 | |
119 NSError* error = nil; | |
120 if ([[NSFileManager defaultManager] | |
121 fileExistsAtPath:@"/Applications/Google Chromo.app"]) { | |
122 [[NSFileManager defaultManager] | |
123 removeItemAtPath:@"/Applications/Google Chromo.app" | |
124 error:nil]; | |
125 } | |
126 if (![[NSFileManager defaultManager] | |
127 copyItemAtPath:diskAppPath | |
128 toPath:@"/Applications/Google Chromo.app" | |
129 error:&error]) { | |
130 NSLog(@"%@", error); | |
131 } | |
132 | |
133 [[NSWorkspace sharedWorkspace] | |
134 launchApplicationAtURL: | |
135 [NSURL fileURLWithPath:@"/Applications/Google Chromo.app" | |
Sidney San Martín
2016/08/19 22:06:04
All of these `@"/Applications/Google Chromo.app"`s
Anna Zeng
2016/08/23 03:13:43
This portion of the code will be taken care of by
| |
136 isDirectory:NO] | |
137 options:NSWorkspaceLaunchDefault | |
138 configuration:@{} | |
139 error:&error]; | |
140 if (error) { | |
141 NSLog(@"Chromo failed to launch: %@", error); | |
142 } | |
143 | |
144 dispatch_async(dispatch_get_main_queue(), ^{ | |
145 [window_ orderOut:nil]; | |
146 }); | |
147 | |
148 [unpacker unmountDMG]; | |
149 } | |
150 | |
151 - (void)unpacker:(Unpacker*)unpacker onMountFailure:(NSError*)error { | |
152 NSError* extractError = | |
153 [NSError errorForAlerts:@"Install Failure" | |
154 withDescription:@"Unable to add Google Chrome to Applications." | |
155 isRecoverable:NO]; | |
156 [self displayError:extractError]; | |
157 } | |
158 | |
159 - (void)unpacker:(Unpacker*)unpacker onUnmountSuccess:(NSString*)mountpath { | |
160 NSLog(@"we're done here!"); | |
161 [NSApp terminate:nil]; | |
162 } | |
163 | |
164 - (void)unpacker:(Unpacker*)unpacker onUnmountFailure:(NSError*)error { | |
165 NSLog(@"error unmounting"); | |
166 // NOTE: since we are not deleting the temporary folder if the unmount fails, | |
167 // we'll just leave it up to the computer to delete the temporary folder on | |
168 // its own time, and to unmount the disk during a restart at some point. There | |
169 // is no other work to be done in the mean time. | |
170 [NSApp terminate:nil]; | |
171 } | |
172 | |
85 // Displays an alert on the main window using the contents of the passed in | 173 // Displays an alert on the main window using the contents of the passed in |
86 // error. | 174 // error. |
87 - (void)displayError:(NSError*)error { | 175 - (void)displayError:(NSError*)error { |
88 NSAlert* alertForUser = [NSAlert alertWithError:error]; | 176 NSAlert* alertForUser = [NSAlert alertWithError:error]; |
89 | 177 dispatch_async(dispatch_get_main_queue(), ^{ |
90 dispatch_sync(dispatch_get_main_queue(), ^{ | |
91 [alertForUser beginSheetModalForWindow:window_ | 178 [alertForUser beginSheetModalForWindow:window_ |
92 completionHandler:^(NSModalResponse returnCode) { | 179 completionHandler:^(NSModalResponse returnCode) { |
93 if (returnCode != [alertForUser quitButton]) { | 180 if (returnCode != [alertForUser quitResponse]) { |
94 [self startDownload]; | 181 [self startDownload]; |
95 } else { | 182 } else { |
96 [NSApp terminate:nil]; | 183 [NSApp terminate:nil]; |
97 } | 184 } |
98 }]; | 185 }]; |
99 }); | 186 }); |
100 } | 187 } |
101 | 188 |
102 @end | 189 @end |
OLD | NEW |