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

Side by Side Diff: chrome/installer/mac/app/AppDelegate.m

Issue 2203583002: Added unpacking step (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added DMG to build file Created 4 years, 3 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 unified diff | Download patch
« no previous file with comments | « chrome/installer/mac/app/AppDelegate.h ('k') | chrome/installer/mac/app/BUILD.gn » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include <Security/Security.h>
8
9 #import "Downloader.h"
7 #import "InstallerWindowController.h" 10 #import "InstallerWindowController.h"
8 #import "NSError+ChromeInstallerAdditions.h" 11 #import "NSError+ChromeInstallerAdditions.h"
9 #import "NSAlert+ChromeInstallerAdditions.h" 12 #import "NSAlert+ChromeInstallerAdditions.h"
10 #import "AuthorizedInstall.h" 13 #import "AuthorizedInstall.h"
14 #import "OmahaCommunication.h"
15 #import "Unpacker.h"
11 16
12 @interface NSAlert () 17 @interface NSAlert ()
13 - (void)beginSheetModalForWindow:(NSWindow*)sheetWindow 18 - (void)beginSheetModalForWindow:(NSWindow*)sheetWindow
14 completionHandler: 19 completionHandler:
15 (void (^__nullable)(NSModalResponse returnCode))handler; 20 (void (^__nullable)(NSModalResponse returnCode))handler;
16 @end 21 @end
17 22
18 @interface AppDelegate ()<OmahaCommunicationDelegate, DownloaderDelegate> { 23 @interface AppDelegate ()<NSWindowDelegate,
24 OmahaCommunicationDelegate,
25 DownloaderDelegate,
26 UnpackDelegate> {
19 InstallerWindowController* installerWindowController_; 27 InstallerWindowController* installerWindowController_;
20 AuthorizedInstall* authorizedInstall_; 28 AuthorizedInstall* authorizedInstall_;
29 BOOL preventTermination_;
21 } 30 }
22 @property(strong) NSWindow* window; 31 @property(strong) NSWindow* window;
32 - (void)exit;
23 @end 33 @end
24 34
25 @implementation AppDelegate 35 @implementation AppDelegate
26 @synthesize window = window_; 36 @synthesize window = window_;
27 37
28 // Sets up the main window and begins the downloading process. 38 // Sets up the main window and begins the downloading process.
29 - (void)applicationDidFinishLaunching:(NSNotification*)aNotification { 39 - (void)applicationDidFinishLaunching:(NSNotification*)aNotification {
30 // TODO: fix UI not loading until after asking for authorization. 40 // TODO: fix UI not loading until after asking for authorization.
41 window_.delegate = self;
31 installerWindowController_ = 42 installerWindowController_ =
32 [[InstallerWindowController alloc] initWithWindow:window_]; 43 [[InstallerWindowController alloc] initWithWindow:window_];
33 authorizedInstall_ = [[AuthorizedInstall alloc] init]; 44 authorizedInstall_ = [[AuthorizedInstall alloc] init];
34 if ([authorizedInstall_ loadInstallationTool]) { 45 if ([authorizedInstall_ loadInstallationTool]) {
35 [self startDownload]; 46 [self startDownload];
36 } else { 47 } else {
37 [self onLoadInstallationToolFailure]; 48 [self onLoadInstallationToolFailure];
38 } 49 }
39 } 50 }
40 51
41 - (void)applicationWillTerminate:(NSNotification*)aNotification { 52 - (void)applicationWillTerminate:(NSNotification*)aNotification {
42 } 53 }
43 54
44 - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)sender { 55 - (NSApplicationTerminateReply)applicationShouldTerminate:
56 (NSApplication*)sender {
57 return preventTermination_ ? NSTerminateCancel : NSTerminateNow;
58 }
59
60 // This function effectively takes the place of
61 // applicationShouldTerminateAfterLastWindowClosed: to make sure that the
62 // application does correctly terminate after closing the installer, but does
63 // not terminate when we call orderOut: to hide the installer during its
64 // tear-down steps.
65 - (BOOL)windowShouldClose:(id)sender {
66 [self exit];
45 return YES; 67 return YES;
46 } 68 }
47 69
70 - (void)exit {
71 preventTermination_ = NO;
72 [NSApp terminate:nil];
73 }
74
48 - (void)startDownload { 75 - (void)startDownload {
49 [installerWindowController_ updateStatusDescription:@"Initializing..."]; 76 [installerWindowController_ updateStatusDescription:@"Initializing..."];
77
50 OmahaCommunication* omahaMessenger = [[OmahaCommunication alloc] init]; 78 OmahaCommunication* omahaMessenger = [[OmahaCommunication alloc] init];
51 omahaMessenger.delegate = self; 79 omahaMessenger.delegate = self;
52
53 [omahaMessenger fetchDownloadURLs]; 80 [omahaMessenger fetchDownloadURLs];
54 } 81 }
55 82
56 - (void)onOmahaSuccessWithURLs:(NSArray*)URLs { 83 - (void)onLoadInstallationToolFailure {
84 NSError* loadToolError = [NSError
85 errorForAlerts:@"Could not load installion tool"
86 withDescription:
87 @"Your Chrome Installer may be corrupted. Download and try again."
88 isRecoverable:NO];
89 [self displayError:loadToolError];
90 }
91
92 - (void)omahaCommunication:(OmahaCommunication*)messenger
93 onSuccess:(NSArray*)URLs {
57 [installerWindowController_ updateStatusDescription:@"Downloading..."]; 94 [installerWindowController_ updateStatusDescription:@"Downloading..."];
95
58 Downloader* download = [[Downloader alloc] init]; 96 Downloader* download = [[Downloader alloc] init];
59 download.delegate = self; 97 download.delegate = self;
60 [download downloadChromeImageToDownloadsDirectory:[URLs firstObject]]; 98 [download downloadChromeImageFrom:[URLs firstObject]];
61 } 99 }
62 100
63 - (void)onOmahaFailureWithError:(NSError*)error { 101 - (void)omahaCommunication:(OmahaCommunication*)messenger
102 onFailure:(NSError*)error {
64 NSError* networkError = 103 NSError* networkError =
65 [NSError errorForAlerts:@"Network Error" 104 [NSError errorForAlerts:@"Network Error"
66 withDescription:@"Could not connect to Chrome server." 105 withDescription:@"Could not connect to Chrome server."
67 isRecoverable:YES]; 106 isRecoverable:YES];
68 [self displayError:networkError]; 107 [self displayError:networkError];
69 } 108 }
70 109
71 // Bridge method from Downloader to InstallerWindowController. Allows Downloader 110 // Bridge method from Downloader to InstallerWindowController. Allows Downloader
72 // to update the progressbar without having direct access to any UI obejcts. 111 // to update the progressbar without having direct access to any UI obejcts.
73 - (void)didDownloadData:(double)downloadProgressPercentage { 112 - (void)downloader:(Downloader*)download percentProgress:(double)percentage {
74 [installerWindowController_ 113 [installerWindowController_ updateDownloadProgress:(double)percentage];
75 updateDownloadProgress:(double)downloadProgressPercentage];
76 } 114 }
77 115
78 - (void)downloader:(Downloader*)download 116 - (void)downloader:(Downloader*)download onSuccess:(NSURL*)diskImageURL {
79 onDownloadSuccess:(NSURL*)diskImagePath { 117 [installerWindowController_ updateStatusDescription:@"Installing..."];
80 [installerWindowController_ updateStatusDescription:@"Done."];
81 [installerWindowController_ enableLaunchButton]; 118 [installerWindowController_ enableLaunchButton];
82 // TODO: Add unpacking step here and pass the path to the app bundle inside 119 // TODO: Add unpacking step here and pass the path to the app bundle inside
83 // the mounted disk image path to startInstall. Currently passing hardcoded 120 // the mounted disk image path to startInstall. Currently passing hardcoded
84 // path to preunpacked app bundle. 121 // path to preunpacked app bundle.
85 //[authorizedInstall_ 122 //[authorizedInstall_
86 // startInstall:@"$HOME/Downloads/Google Chrome.app"]; 123 // startInstall:@"$HOME/Downloads/Google Chrome.app"];
124
125 Unpacker* unpacker = [[Unpacker alloc] init];
126 unpacker.delegate = self;
127 [unpacker mountDMGFromURL:diskImageURL];
87 } 128 }
88 129
89 - (void)downloader:(Downloader*)download 130 - (void)downloader:(Downloader*)download onFailure:(NSError*)error {
90 onDownloadFailureWithError:(NSError*)error {
91 NSError* downloadError = 131 NSError* downloadError =
92 [NSError errorForAlerts:@"Download Failure" 132 [NSError errorForAlerts:@"Download Failure"
93 withDescription:@"Unable to download Google Chrome." 133 withDescription:@"Unable to download Google Chrome."
94 isRecoverable:NO]; 134 isRecoverable:NO];
95 [self displayError:downloadError]; 135 [self displayError:downloadError];
96 } 136 }
97 137
98 - (void)onLoadInstallationToolFailure { 138 - (void)unpacker:(Unpacker*)unpacker onMountSuccess:(NSString*)tempAppPath {
99 NSError* loadToolError = [NSError 139 SecStaticCodeRef diskStaticCode;
100 errorForAlerts:@"Could not load installion tool" 140 SecRequirementRef diskRequirement;
101 withDescription: 141 // TODO: flush out error handling more
102 @"Your Chrome Installer may be corrupted. Download and try again." 142 OSStatus oserror;
103 isRecoverable:NO]; 143 oserror = SecStaticCodeCreateWithPath(
104 [self displayError:loadToolError]; 144 (__bridge CFURLRef)[NSURL fileURLWithPath:tempAppPath isDirectory:NO],
145 kSecCSDefaultFlags, &diskStaticCode);
146 if (oserror != errSecSuccess)
147 NSLog(@"code %d", oserror);
148 // TODO: add in a more specific code sign requirement
149 oserror =
150 SecRequirementCreateWithString((CFStringRef) @"anchor apple generic",
151 kSecCSDefaultFlags, &diskRequirement);
152 if (oserror != errSecSuccess)
153 NSLog(@"requirement %d", oserror);
154 oserror = SecStaticCodeCheckValidity(diskStaticCode, kSecCSDefaultFlags,
155 diskRequirement);
156 if (oserror != errSecSuccess)
157 NSLog(@"static code %d", oserror);
158
159 // Calling this function will change the progress bar into an indeterminate
160 // one. We won't need to update the progress bar any more after this point.
161 [installerWindowController_ updateDownloadProgress:-1.0];
162 // By disabling closing the window or quitting, we can tell the user that
163 // closing the application at this point is not a good idea.
164 window_.styleMask &= ~NSClosableWindowMask;
165 preventTermination_ = YES;
166
167 // TODO: move the below code into AuthorizedInstall
168 NSString* chromeInApplicationsFolder = @"/Applications/Google Chromo.app";
169
170 NSError* error = nil;
171 if ([[NSFileManager defaultManager]
172 fileExistsAtPath:chromeInApplicationsFolder]) {
173 [[NSFileManager defaultManager] moveItemAtPath:chromeInApplicationsFolder
174 toPath:tempAppPath
175 error:nil];
176 }
177 if (![[NSFileManager defaultManager] moveItemAtPath:tempAppPath
178 toPath:chromeInApplicationsFolder
179 error:&error]) {
180 NSLog(@"%@", error);
181 }
182 // TODO: move the above code into AuthorizedInstall
183
184 [[NSWorkspace sharedWorkspace]
185 launchApplicationAtURL:[NSURL fileURLWithPath:chromeInApplicationsFolder
186 isDirectory:NO]
187 options:NSWorkspaceLaunchDefault
188 configuration:@{}
189 error:&error];
190 if (error) {
191 NSLog(@"Chrome failed to launch: %@", error);
192 }
193
194 // Begin teardown stuff!
195 dispatch_async(dispatch_get_main_queue(), ^{
196 [window_ orderOut:nil];
197 });
198
199 [unpacker unmountDMG];
200 }
201
202 - (void)unpacker:(Unpacker*)unpacker onMountFailure:(NSError*)error {
203 NSError* extractError =
204 [NSError errorForAlerts:@"Install Failure"
205 withDescription:@"Unable to add Google Chrome to Applications."
206 isRecoverable:NO];
207 [self displayError:extractError];
208 }
209
210 - (void)unpacker:(Unpacker*)unpacker onUnmountSuccess:(NSString*)mountpath {
211 NSLog(@"we're done here!");
212 [self exit];
213 }
214
215 - (void)unpacker:(Unpacker*)unpacker onUnmountFailure:(NSError*)error {
216 NSLog(@"error unmounting");
217 // NOTE: since we are not deleting the temporary folder if the unmount fails,
218 // we'll just leave it up to the computer to delete the temporary folder on
219 // its own time, and to unmount the disk during a restart at some point. There
220 // is no other work to be done in the mean time.
221 [self exit];
105 } 222 }
106 223
107 // Displays an alert on the main window using the contents of the passed in 224 // Displays an alert on the main window using the contents of the passed in
108 // error. 225 // error.
109 - (void)displayError:(NSError*)error { 226 - (void)displayError:(NSError*)error {
110 NSAlert* alertForUser = [NSAlert alertWithError:error]; 227 NSAlert* alertForUser = [NSAlert alertWithError:error];
111
112 dispatch_async(dispatch_get_main_queue(), ^{ 228 dispatch_async(dispatch_get_main_queue(), ^{
113 [alertForUser beginSheetModalForWindow:window_ 229 [alertForUser beginSheetModalForWindow:window_
114 completionHandler:^(NSModalResponse returnCode) { 230 completionHandler:^(NSModalResponse returnCode) {
115 if (returnCode != [alertForUser quitButton]) { 231 if (returnCode != [alertForUser quitResponse]) {
116 [self startDownload]; 232 [self startDownload];
117 } else { 233 } else {
118 [NSApp terminate:nil]; 234 [NSApp terminate:nil];
119 } 235 }
120 }]; 236 }];
121 }); 237 });
122 } 238 }
123 239
124 @end 240 @end
OLDNEW
« no previous file with comments | « chrome/installer/mac/app/AppDelegate.h ('k') | chrome/installer/mac/app/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698