diff options
Diffstat (limited to 'toolkit/mozapps')
12 files changed, 661 insertions, 1 deletions
diff --git a/toolkit/mozapps/update/updater/Makefile.in b/toolkit/mozapps/update/updater/Makefile.in index c1cfcead7e..84a843d185 100644 --- a/toolkit/mozapps/update/updater/Makefile.in +++ b/toolkit/mozapps/update/updater/Makefile.in @@ -14,3 +14,16 @@ endif endif include $(topsrcdir)/config/rules.mk + +ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT)) +export:: + sed -e 's/%MOZ_MACBUNDLE_ID%/$(MOZ_MACBUNDLE_ID)/' $(srcdir)/macbuild/Contents/Info.plist.in > $(DIST)/bin/Info.plist +libs:: + $(NSINSTALL) -D $(DIST)/bin/updater.app + rsync -a -C --exclude '*.in' $(srcdir)/macbuild/Contents $(DIST)/bin/updater.app + rsync -a -C $(DIST)/bin/Info.plist $(DIST)/bin/updater.app/Contents + sed -e 's/%APP_NAME%/$(MOZ_APP_DISPLAYNAME)/' $(srcdir)/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in | \ + iconv -f UTF-8 -t UTF-16 > $(DIST)/bin/updater.app/Contents/Resources/English.lproj/InfoPlist.strings + $(NSINSTALL) -D $(DIST)/bin/updater.app/Contents/MacOS + $(NSINSTALL) $(DIST)/bin/org.mozilla.updater $(DIST)/bin/updater.app/Contents/MacOS +endif diff --git a/toolkit/mozapps/update/updater/launchchild_osx.mm b/toolkit/mozapps/update/updater/launchchild_osx.mm new file mode 100644 index 0000000000..5a36ae6237 --- /dev/null +++ b/toolkit/mozapps/update/updater/launchchild_osx.mm @@ -0,0 +1,384 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include <Cocoa/Cocoa.h> +#include <CoreServices/CoreServices.h> +#include <crt_externs.h> +#include <stdlib.h> +#include <stdio.h> +#include <spawn.h> +#include <SystemConfiguration/SystemConfiguration.h> +#include "readstrings.h" + +class MacAutoreleasePool { +public: + MacAutoreleasePool() + { + mPool = [[NSAutoreleasePool alloc] init]; + } + ~MacAutoreleasePool() + { + [mPool release]; + } + +private: + NSAutoreleasePool* mPool; +}; + +void LaunchChild(int argc, const char** argv) +{ + MacAutoreleasePool pool; + + @try { + NSString* launchPath = [NSString stringWithUTF8String:argv[0]]; + NSMutableArray* arguments = [NSMutableArray arrayWithCapacity:argc - 1]; + for (int i = 1; i < argc; i++) { + [arguments addObject:[NSString stringWithUTF8String:argv[i]]]; + } + [NSTask launchedTaskWithLaunchPath:launchPath + arguments:arguments]; + } @catch (NSException* e) { + NSLog(@"%@: %@", e.name, e.reason); + } +} + +void +LaunchMacPostProcess(const char* aAppBundle) +{ + MacAutoreleasePool pool; + + // Launch helper to perform post processing for the update; this is the Mac + // analogue of LaunchWinPostProcess (PostUpdateWin). + NSString* iniPath = [NSString stringWithUTF8String:aAppBundle]; + iniPath = + [iniPath stringByAppendingPathComponent:@"Contents/Resources/updater.ini"]; + + NSFileManager* fileManager = [NSFileManager defaultManager]; + if (![fileManager fileExistsAtPath:iniPath]) { + // the file does not exist; there is nothing to run + return; + } + + int readResult; + char values[2][MAX_TEXT_LEN]; + readResult = ReadStrings([iniPath UTF8String], + "ExeRelPath\0ExeArg\0", + 2, + values, + "PostUpdateMac"); + if (readResult) { + return; + } + + NSString *exeRelPath = [NSString stringWithUTF8String:values[0]]; + NSString *exeArg = [NSString stringWithUTF8String:values[1]]; + if (!exeArg || !exeRelPath) { + return; + } + + // The path must not traverse directories and it must be a relative path. + if ([exeRelPath rangeOfString:@".."].location != NSNotFound || + [exeRelPath rangeOfString:@"./"].location != NSNotFound || + [exeRelPath rangeOfString:@"/"].location == 0) { + return; + } + + NSString* exeFullPath = [NSString stringWithUTF8String:aAppBundle]; + exeFullPath = [exeFullPath stringByAppendingPathComponent:exeRelPath]; + + char optVals[1][MAX_TEXT_LEN]; + readResult = ReadStrings([iniPath UTF8String], + "ExeAsync\0", + 1, + optVals, + "PostUpdateMac"); + + NSTask *task = [[NSTask alloc] init]; + [task setLaunchPath:exeFullPath]; + [task setArguments:[NSArray arrayWithObject:exeArg]]; + [task launch]; + if (!readResult) { + NSString *exeAsync = [NSString stringWithUTF8String:optVals[0]]; + if ([exeAsync isEqualToString:@"false"]) { + [task waitUntilExit]; + } + } + // ignore the return value of the task, there's nothing we can do with it + [task release]; +} + +id ConnectToUpdateServer() +{ + MacAutoreleasePool pool; + + id updateServer = nil; + BOOL isConnected = NO; + int currTry = 0; + const int numRetries = 10; // Number of IPC connection retries before + // giving up. + while (!isConnected && currTry < numRetries) { + @try { + updateServer = (id)[NSConnection + rootProxyForConnectionWithRegisteredName: + @"org.mozilla.updater.server" + host:nil + usingNameServer:[NSSocketPortNameServer sharedInstance]]; + if (!updateServer || + ![updateServer respondsToSelector:@selector(abort)] || + ![updateServer respondsToSelector:@selector(getArguments)] || + ![updateServer respondsToSelector:@selector(shutdown)]) { + NSLog(@"Server doesn't exist or doesn't provide correct selectors."); + sleep(1); // Wait 1 second. + currTry++; + } else { + isConnected = YES; + } + } @catch (NSException* e) { + NSLog(@"Encountered exception, retrying: %@: %@", e.name, e.reason); + sleep(1); // Wait 1 second. + currTry++; + } + } + if (!isConnected) { + NSLog(@"Failed to connect to update server after several retries."); + return nil; + } + return updateServer; +} + +void CleanupElevatedMacUpdate(bool aFailureOccurred) +{ + MacAutoreleasePool pool; + + id updateServer = ConnectToUpdateServer(); + if (updateServer) { + @try { + if (aFailureOccurred) { + [updateServer performSelector:@selector(abort)]; + } else { + [updateServer performSelector:@selector(shutdown)]; + } + } @catch (NSException* e) { } + } + + NSFileManager* manager = [NSFileManager defaultManager]; + [manager removeItemAtPath:@"/Library/PrivilegedHelperTools/org.mozilla.updater" + error:nil]; + [manager removeItemAtPath:@"/Library/LaunchDaemons/org.mozilla.updater.plist" + error:nil]; + const char* launchctlArgs[] = {"/bin/launchctl", + "remove", + "org.mozilla.updater"}; + // The following call will terminate the current process due to the "remove" + // argument in launchctlArgs. + LaunchChild(3, launchctlArgs); +} + +// Note: Caller is responsible for freeing argv. +bool ObtainUpdaterArguments(int* argc, char*** argv) +{ + MacAutoreleasePool pool; + + id updateServer = ConnectToUpdateServer(); + if (!updateServer) { + // Let's try our best and clean up. + CleanupElevatedMacUpdate(true); + return false; // Won't actually get here due to CleanupElevatedMacUpdate. + } + + @try { + NSArray* updaterArguments = + [updateServer performSelector:@selector(getArguments)]; + *argc = [updaterArguments count]; + char** tempArgv = (char**)malloc(sizeof(char*) * (*argc)); + for (int i = 0; i < *argc; i++) { + int argLen = [[updaterArguments objectAtIndex:i] length] + 1; + tempArgv[i] = (char*)malloc(argLen); + strncpy(tempArgv[i], [[updaterArguments objectAtIndex:i] UTF8String], + argLen); + } + *argv = tempArgv; + } @catch (NSException* e) { + // Let's try our best and clean up. + CleanupElevatedMacUpdate(true); + return false; // Won't actually get here due to CleanupElevatedMacUpdate. + } + return true; +} + +/** + * The ElevatedUpdateServer is launched from a non-elevated updater process. + * It allows an elevated updater process (usually a privileged helper tool) to + * connect to it and receive all the necessary arguments to complete a + * successful update. + */ +@interface ElevatedUpdateServer : NSObject +{ + NSArray* mUpdaterArguments; + BOOL mShouldKeepRunning; + BOOL mAborted; +} +- (id)initWithArgs:(NSArray*)args; +- (BOOL)runServer; +- (NSArray*)getArguments; +- (void)abort; +- (BOOL)wasAborted; +- (void)shutdown; +- (BOOL)shouldKeepRunning; +@end + +@implementation ElevatedUpdateServer + +- (id)initWithArgs:(NSArray*)args +{ + self = [super init]; + if (!self) { + return nil; + } + mUpdaterArguments = args; + mShouldKeepRunning = YES; + mAborted = NO; + return self; +} + +- (BOOL)runServer +{ + NSPort* serverPort = [NSSocketPort port]; + NSConnection* server = [NSConnection connectionWithReceivePort:serverPort + sendPort:serverPort]; + [server setRootObject:self]; + if ([server registerName:@"org.mozilla.updater.server" + withNameServer:[NSSocketPortNameServer sharedInstance]] == NO) { + NSLog(@"Unable to register as DirectoryServer."); + NSLog(@"Is another copy running?"); + return NO; + } + + while ([self shouldKeepRunning] && + [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode + beforeDate:[NSDate distantFuture]]); + return ![self wasAborted]; +} + +- (NSArray*)getArguments +{ + return mUpdaterArguments; +} + +- (void)abort +{ + mAborted = YES; + [self shutdown]; +} + +- (BOOL)wasAborted +{ + return mAborted; +} + +- (void)shutdown +{ + mShouldKeepRunning = NO; +} + +- (BOOL)shouldKeepRunning +{ + return mShouldKeepRunning; +} + +@end + +bool ServeElevatedUpdate(int argc, const char** argv) +{ + MacAutoreleasePool pool; + + NSMutableArray* updaterArguments = [NSMutableArray arrayWithCapacity:argc]; + for (int i = 0; i < argc; i++) { + [updaterArguments addObject:[NSString stringWithUTF8String:argv[i]]]; + } + + ElevatedUpdateServer* updater = + [[ElevatedUpdateServer alloc] initWithArgs:[updaterArguments copy]]; + bool didSucceed = [updater runServer]; + + [updater release]; + return didSucceed; +} + +bool IsOwnedByGroupAdmin(const char* aAppBundle) +{ + MacAutoreleasePool pool; + + NSString* appDir = [NSString stringWithUTF8String:aAppBundle]; + NSFileManager* fileManager = [NSFileManager defaultManager]; + + NSDictionary* attributes = [fileManager attributesOfItemAtPath:appDir + error:nil]; + bool isOwnedByAdmin = false; + if (attributes && + [[attributes valueForKey:NSFileGroupOwnerAccountID] intValue] == 80) { + isOwnedByAdmin = true; + } + return isOwnedByAdmin; +} + +void SetGroupOwnershipAndPermissions(const char* aAppBundle) +{ + MacAutoreleasePool pool; + + NSString* appDir = [NSString stringWithUTF8String:aAppBundle]; + NSFileManager* fileManager = [NSFileManager defaultManager]; + NSError* error = nil; + NSArray* paths = + [fileManager subpathsOfDirectoryAtPath:appDir + error:&error]; + if (error) { + return; + } + + // Set group ownership of Firefox.app to 80 ("admin") and permissions to + // 0775. + if (![fileManager setAttributes:@{ NSFileGroupOwnerAccountID: @(80), + NSFilePosixPermissions: @(0775) } + ofItemAtPath:appDir + error:&error] || error) { + return; + } + + NSArray* permKeys = [NSArray arrayWithObjects:NSFileGroupOwnerAccountID, + NSFilePosixPermissions, + nil]; + // For all descendants of Firefox.app, set group ownership to 80 ("admin") and + // ensure write permission for the group. + for (NSString* currPath in paths) { + NSString* child = [appDir stringByAppendingPathComponent:currPath]; + NSDictionary* oldAttributes = + [fileManager attributesOfItemAtPath:child + error:&error]; + if (error) { + return; + } + // Skip symlinks, since they could be pointing to files outside of the .app + // bundle. + if ([oldAttributes fileType] == NSFileTypeSymbolicLink) { + continue; + } + NSNumber* oldPerms = + (NSNumber*)[oldAttributes valueForKey:NSFilePosixPermissions]; + NSArray* permObjects = + [NSArray arrayWithObjects: + [NSNumber numberWithUnsignedLong:80], + [NSNumber numberWithUnsignedLong:[oldPerms shortValue] | 020], + nil]; + NSDictionary* attributes = [NSDictionary dictionaryWithObjects:permObjects + forKeys:permKeys]; + if (![fileManager setAttributes:attributes + ofItemAtPath:child + error:&error] || error) { + return; + } + } +} diff --git a/toolkit/mozapps/update/updater/macbuild/Contents/Info.plist.in b/toolkit/mozapps/update/updater/macbuild/Contents/Info.plist.in new file mode 100644 index 0000000000..a9b9fcba9d --- /dev/null +++ b/toolkit/mozapps/update/updater/macbuild/Contents/Info.plist.in @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>English</string> + <key>CFBundleExecutable</key> + <string>org.mozilla.updater</string> + <key>CFBundleIconFile</key> + <string>updater.icns</string> + <key>CFBundleIdentifier</key> + <string>org.mozilla.updater</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1.0</string> + <key>NSMainNibFile</key> + <string>MainMenu</string> + <key>NSPrincipalClass</key> + <string>NSApplication</string> + <key>LSMinimumSystemVersion</key> + <string>10.5</string> + <key>LSMinimumSystemVersionByArchitecture</key> + <dict> + <key>i386</key> + <string>10.5.0</string> + <key>x86_64</key> + <string>10.6.0</string> + </dict> + <key>SMAuthorizedClients</key> + <array> + <string>identifier "%MOZ_MACBUNDLE_ID%" and ((anchor apple generic and certificate leaf[field.1.2.840.113635.100.6.1.9]) or (anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] and certificate leaf[field.1.2.840.113635.100.6.1.13] and certificate leaf[subject.OU] = "43AQ936H96"))</string> + </array> +</dict> +</plist> diff --git a/toolkit/mozapps/update/updater/macbuild/Contents/PkgInfo b/toolkit/mozapps/update/updater/macbuild/Contents/PkgInfo new file mode 100644 index 0000000000..bd04210fb4 --- /dev/null +++ b/toolkit/mozapps/update/updater/macbuild/Contents/PkgInfo @@ -0,0 +1 @@ +APPL????
\ No newline at end of file diff --git a/toolkit/mozapps/update/updater/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in b/toolkit/mozapps/update/updater/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in new file mode 100644 index 0000000000..bca4022e75 --- /dev/null +++ b/toolkit/mozapps/update/updater/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in @@ -0,0 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Localized versions of Info.plist keys */ + +CFBundleName = "%APP_NAME% Software Update"; diff --git a/toolkit/mozapps/update/updater/macbuild/Contents/Resources/English.lproj/MainMenu.nib/classes.nib b/toolkit/mozapps/update/updater/macbuild/Contents/Resources/English.lproj/MainMenu.nib/classes.nib new file mode 100644 index 0000000000..6cfb50406b --- /dev/null +++ b/toolkit/mozapps/update/updater/macbuild/Contents/Resources/English.lproj/MainMenu.nib/classes.nib @@ -0,0 +1,19 @@ +{ + IBClasses = ( + { + CLASS = FirstResponder; + LANGUAGE = ObjC; + SUPERCLASS = NSObject; +}, + { + CLASS = UpdaterUI; + LANGUAGE = ObjC; + OUTLETS = { + progressBar = NSProgressIndicator; + progressTextField = NSTextField; + }; + SUPERCLASS = NSObject; +} + ); + IBVersion = 1; +}
\ No newline at end of file diff --git a/toolkit/mozapps/update/updater/macbuild/Contents/Resources/English.lproj/MainMenu.nib/info.nib b/toolkit/mozapps/update/updater/macbuild/Contents/Resources/English.lproj/MainMenu.nib/info.nib new file mode 100644 index 0000000000..1509178370 --- /dev/null +++ b/toolkit/mozapps/update/updater/macbuild/Contents/Resources/English.lproj/MainMenu.nib/info.nib @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>IBDocumentLocation</key> + <string>111 162 356 240 0 0 1440 878 </string> + <key>IBEditorPositions</key> + <dict> + <key>29</key> + <string>106 299 84 44 0 0 1440 878 </string> + </dict> + <key>IBFramework Version</key> + <string>489.0</string> + <key>IBOpenObjects</key> + <array> + <integer>21</integer> + <integer>29</integer> + </array> + <key>IBSystem Version</key> + <string>10J567</string> +</dict> +</plist> diff --git a/toolkit/mozapps/update/updater/macbuild/Contents/Resources/English.lproj/MainMenu.nib/keyedobjects.nib b/toolkit/mozapps/update/updater/macbuild/Contents/Resources/English.lproj/MainMenu.nib/keyedobjects.nib Binary files differnew file mode 100644 index 0000000000..61ff026009 --- /dev/null +++ b/toolkit/mozapps/update/updater/macbuild/Contents/Resources/English.lproj/MainMenu.nib/keyedobjects.nib diff --git a/toolkit/mozapps/update/updater/macbuild/Contents/Resources/updater.icns b/toolkit/mozapps/update/updater/macbuild/Contents/Resources/updater.icns Binary files differnew file mode 100644 index 0000000000..d7499c6692 --- /dev/null +++ b/toolkit/mozapps/update/updater/macbuild/Contents/Resources/updater.icns diff --git a/toolkit/mozapps/update/updater/moz.build b/toolkit/mozapps/update/updater/moz.build index 6cf377afef..4dc557ea34 100644 --- a/toolkit/mozapps/update/updater/moz.build +++ b/toolkit/mozapps/update/updater/moz.build @@ -3,13 +3,26 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -Program('updater') +if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': + Program('org.mozilla.updater') +else: + Program('updater') updater_rel_path = '' include('updater-common.build') CXXFLAGS += CONFIG['MOZ_BZ2_CFLAGS'] +if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': + LDFLAGS += ['-sectcreate', + '__TEXT', + '__info_plist', + TOPOBJDIR + '/dist/bin/Info.plist', + '-sectcreate', + '__TEXT', + '__launchd_plist', + SRCDIR + '/Launchd.plist'] + GENERATED_FILES = [ 'primaryCert.h', 'secondaryCert.h', diff --git a/toolkit/mozapps/update/updater/progressui_osx.mm b/toolkit/mozapps/update/updater/progressui_osx.mm new file mode 100644 index 0000000000..54c9c41b72 --- /dev/null +++ b/toolkit/mozapps/update/updater/progressui_osx.mm @@ -0,0 +1,144 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#import <Cocoa/Cocoa.h> +#include <stdio.h> +#include <unistd.h> +#include "mozilla/Sprintf.h" +#include "progressui.h" +#include "readstrings.h" +#include "errors.h" + +#define TIMER_INTERVAL 0.2 + +static float sProgressVal; // between 0 and 100 +static BOOL sQuit = NO; +static BOOL sIndeterminate = NO; +static StringTable sLabels; +static const char *sUpdatePath; + +@interface UpdaterUI : NSObject +{ + IBOutlet NSProgressIndicator *progressBar; + IBOutlet NSTextField *progressTextField; +} +@end + +@implementation UpdaterUI + +-(void)awakeFromNib +{ + NSWindow *w = [progressBar window]; + + [w setTitle:[NSString stringWithUTF8String:sLabels.title]]; + [progressTextField setStringValue:[NSString stringWithUTF8String:sLabels.info]]; + + NSRect origTextFrame = [progressTextField frame]; + [progressTextField sizeToFit]; + + int widthAdjust = progressTextField.frame.size.width - origTextFrame.size.width; + + if (widthAdjust > 0) { + NSRect f; + f.size.width = w.frame.size.width + widthAdjust; + f.size.height = w.frame.size.height; + [w setFrame:f display:YES]; + } + + [w center]; + + [progressBar setIndeterminate:sIndeterminate]; + [progressBar setDoubleValue:0.0]; + + [[NSTimer scheduledTimerWithTimeInterval:TIMER_INTERVAL target:self + selector:@selector(updateProgressUI:) + userInfo:nil repeats:YES] retain]; + + // Make sure we are on top initially + [NSApp activateIgnoringOtherApps:YES]; +} + +// called when the timer goes off +-(void)updateProgressUI:(NSTimer *)aTimer +{ + if (sQuit) { + [aTimer invalidate]; + [aTimer release]; + + // It seems to be necessary to activate and hide ourselves before we stop, + // otherwise the "run" method will not return until the user focuses some + // other app. The activate step is necessary if we are not the active app. + // This is a big hack, but it seems to do the trick. + [NSApp activateIgnoringOtherApps:YES]; + [NSApp hide:self]; + [NSApp stop:self]; + } + + float progress = sProgressVal; + + [progressBar setDoubleValue:(double)progress]; +} + +// leave this as returning a BOOL instead of NSApplicationTerminateReply +// for backward compatibility +- (BOOL)applicationShouldTerminate:(NSApplication *)sender +{ + return sQuit; +} + +@end + +int +InitProgressUI(int *pargc, char ***pargv) +{ + sUpdatePath = (*pargv)[1]; + + return 0; +} + +int +ShowProgressUI(bool indeterminate) +{ + // Only show the Progress UI if the process is taking a significant amount of + // time where a significant amount of time is defined as .5 seconds after + // ShowProgressUI is called sProgress is less than 70. + usleep(500000); + + if (sQuit || sProgressVal > 70.0f) + return 0; + + char path[PATH_MAX]; + SprintfLiteral(path, "%s/updater.ini", sUpdatePath); + if (ReadStrings(path, &sLabels) != OK) + return -1; + + // Continue the update without showing the Progress UI if any of the supplied + // strings are larger than MAX_TEXT_LEN (Bug 628829). + if (!(strlen(sLabels.title) < MAX_TEXT_LEN - 1 && + strlen(sLabels.info) < MAX_TEXT_LEN - 1)) + return -1; + + sIndeterminate = indeterminate; + [NSApplication sharedApplication]; + [NSBundle loadNibNamed:@"MainMenu" owner:NSApp]; + [NSApp run]; + + return 0; +} + +// Called on a background thread +void +QuitProgressUI() +{ + sQuit = YES; +} + +// Called on a background thread +void +UpdateProgressUI(float progress) +{ + sProgressVal = progress; // 32-bit writes are atomic +} diff --git a/toolkit/mozapps/update/updater/updater-common.build b/toolkit/mozapps/update/updater/updater-common.build index 1ace8fcc71..ce4a219001 100644 --- a/toolkit/mozapps/update/updater/updater-common.build +++ b/toolkit/mozapps/update/updater/updater-common.build @@ -73,6 +73,24 @@ if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']: 'progressui_gtk.cpp', ] +if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': + have_progressui = 1 + srcs += [ + 'launchchild_osx.mm', + 'progressui_osx.mm', + ] + OS_LIBS += [ + '-framework Cocoa', + '-framework Security', + '-framework SystemConfiguration', + ] + UNIFIED_SOURCES += [ + '/toolkit/xre/updaterfileutils_osx.mm', + ] + LOCAL_INCLUDES += [ + '/toolkit/xre', + ] + if have_progressui == 0: srcs += [ 'progressui_null.cpp', |