diff options
Diffstat (limited to 'indra/newview')
37 files changed, 741 insertions, 346 deletions
| diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 4f7ce88165..93ad77e058 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -4,7 +4,6 @@ project(viewer)  include(00-Common)  include(Boost) -include(BuildVersion)  include(DBusGlib)  include(DirectX)  include(OpenSSL) @@ -84,6 +83,7 @@ include_directories(      ${OPENAL_LIB_INCLUDE_DIRS}      ${LIBS_PREBUILT_DIR}/include/collada/1.4      ${LLAPPEARANCE_INCLUDE_DIRS} +    ${CMAKE_CURRENT_SOURCE_DIR}      )  include_directories(SYSTEM @@ -297,6 +297,7 @@ set(viewer_SOURCE_FILES      llgroupiconctrl.cpp      llgrouplist.cpp      llgroupmgr.cpp +    llhasheduniqueid.cpp      llhints.cpp      llhomelocationresponder.cpp      llhudeffect.cpp @@ -876,6 +877,7 @@ set(viewer_HEADER_FILES      llgroupiconctrl.h      llgrouplist.h      llgroupmgr.h +    llhasheduniqueid.h      llhints.h      llhomelocationresponder.h      llhudeffect.h @@ -1242,6 +1244,18 @@ set(viewer_HEADER_FILES  source_group("CMake Rules" FILES ViewerInstall.cmake) +add_custom_target(generate_viewer_version ALL +                  COMMAND echo "${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}" > ${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt +                  COMMENT Generating viewer_version.txt for manifest processing +                  ) + +set_source_files_properties( +   llversioninfo.cpp tests/llversioninfo_test.cpp  +   PROPERTIES +   DEPENDS generate_viewer_version  # dummy dependency to force recompile every time +   COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}" # see BuildVersion.cmake +   ) +  if (DARWIN)    LIST(APPEND viewer_SOURCE_FILES llappviewermacosx.cpp) @@ -1319,15 +1333,17 @@ if (WINDOWS)      # Replace the icons with the appropriate ones for the channel      # ('test' is the default)      set(ICON_PATH "test") +    set(VIEWER_MACOSX_PHASE "d")      string(TOLOWER ${VIEWER_CHANNEL} channel_lower)      if(channel_lower MATCHES "^second life release")          set(ICON_PATH "release") -    elseif(channel_lower MATCHES "^second life beta viewer") +        set(VIEWER_MACOSX_PHASE "f") +    elseif(channel_lower MATCHES "^second life beta")          set(ICON_PATH "beta") -    elseif(channel_lower MATCHES "^second life development") -        set(ICON_PATH "development") -    elseif(channel_lower MATCHES "project") +        set(VIEWER_MACOSX_PHASE "b") +    elseif(channel_lower MATCHES "^second life project")          set(ICON_PATH "project") +        set(VIEWER_MACOSX_PHASE "a")      endif()      message("Copying icons for ${ICON_PATH}")      execute_process( @@ -1396,11 +1412,18 @@ if (WINDOWS)      set_source_files_properties(${viewer_RESOURCE_FILES}                                  PROPERTIES HEADER_FILE_ONLY TRUE) +    configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/res/viewerRes.rc +                    ${CMAKE_CURRENT_BINARY_DIR}/viewerRes.rc +                    )      set(viewer_RESOURCE_FILES -        res/viewerRes.rc +        ${CMAKE_CURRENT_BINARY_DIR}/viewerRes.rc          ${viewer_RESOURCE_FILES}          ) +    set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/viewerRes.rc +      PROPERTIES COMPILE_FLAGS "-I${CMAKE_CURRENT_SOURCE_DIR}/res" +      ) +      SOURCE_GROUP("Resource Files" FILES ${viewer_RESOURCE_FILES})      if (NOT STANDALONE) @@ -1715,10 +1738,13 @@ if (WINDOWS)          --configuration=${CMAKE_CFG_INTDIR}          --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}          --grid=${GRID} +        --channel=${VIEWER_CHANNEL} +        --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt          --source=${CMAKE_CURRENT_SOURCE_DIR}          --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/copy_touched.bat        DEPENDS          ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py +        generate_viewer_version          stage_third_party_libs          ${COPY_INPUT_DEPENDENCIES}        COMMENT "Performing viewer_manifest copy" @@ -1777,21 +1803,23 @@ if (WINDOWS)            --build=${CMAKE_CURRENT_BINARY_DIR}            --buildtype=${CMAKE_BUILD_TYPE}            --channel=${VIEWER_CHANNEL} +          --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt            --configuration=${CMAKE_CFG_INTDIR}            --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}            --grid=${GRID} -          --login_channel=${VIEWER_LOGIN_CHANNEL}            --source=${CMAKE_CURRENT_SOURCE_DIR}            --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/touched.bat          DEPENDS              ${VIEWER_BINARY_NAME}              ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py +            ${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt              ${COPY_INPUT_DEPENDENCIES}          )        add_custom_target(package ALL DEPENDS          ${CMAKE_CFG_INTDIR}/touched.bat          windows-setup-build-all +        generate_viewer_version          )          # temporarily disable packaging of event_host until hg subrepos get          # sorted out on the parabuild cluster... @@ -1864,14 +1892,11 @@ target_link_libraries(${VIEWER_BINARY_NAME}      ${LLAPPEARANCE_LIBRARIES}      ) -build_version(viewer) -  set(ARTWORK_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH      "Path to artwork files.") -  if (LINUX) -  set(product SecondLife-${ARCH}-${viewer_VERSION}) +  set(product SecondLife-${ARCH}-${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION})    # These are the generated targets that are copied to package/    set(COPY_INPUT_DEPENDENCIES @@ -1893,20 +1918,22 @@ if (LINUX)          --build=${CMAKE_CURRENT_BINARY_DIR}          --buildtype=${CMAKE_BUILD_TYPE}          --channel=${VIEWER_CHANNEL} +        --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt          --configuration=${CMAKE_CFG_INTDIR}          --dest=${CMAKE_CURRENT_BINARY_DIR}/packaged          --grid=${GRID}          --installer_name=${product} -        --login_channel=${VIEWER_LOGIN_CHANNEL}          --source=${CMAKE_CURRENT_SOURCE_DIR}          --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.touched        DEPENDS          ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py +        generate_viewer_version          ${COPY_INPUT_DEPENDENCIES}        )    if (PACKAGE)    endif (PACKAGE) +    add_custom_command(      OUTPUT  ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.copy_touched      COMMAND ${PYTHON_EXECUTABLE} @@ -1920,9 +1947,12 @@ if (LINUX)        --configuration=${CMAKE_CFG_INTDIR}        --dest=${CMAKE_CURRENT_BINARY_DIR}/packaged        --grid=${GRID} +      --channel=${VIEWER_CHANNEL} +      --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt        --source=${CMAKE_CURRENT_SOURCE_DIR}      DEPENDS        ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py +      generate_viewer_version        ${COPY_INPUT_DEPENDENCIES}      COMMENT "Performing viewer_manifest copy"      ) @@ -1939,20 +1969,26 @@ endif (LINUX)  if (DARWIN)    set(product "Second Life") +    set_target_properties(      ${VIEWER_BINARY_NAME}      PROPERTIES      OUTPUT_NAME "${product}" -    MACOSX_BUNDLE_INFO_STRING "info string - localize me" +    MACOSX_BUNDLE_INFO_STRING "Second Life Viewer"      MACOSX_BUNDLE_ICON_FILE "secondlife.icns" -    MACOSX_BUNDLE_GUI_IDENTIFIER "Second Life" -    MACOSX_BUNDLE_LONG_VERSION_STRING "ververver" +    MACOSX_BUNDLE_GUI_IDENTIFIER "com.secondlife.indra.viewer" +    MACOSX_BUNDLE_LONG_VERSION_STRING "${VIEWER_CHANNEL} ${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}"      MACOSX_BUNDLE_BUNDLE_NAME "Second Life" -    MACOSX_BUNDLE_SHORT_VERSION_STRING "asdf" -    MACOSX_BUNDLE_BUNDLE_VERSION "asdf" -    MACOSX_BUNDLE_COPYRIGHT "copyright linden lab 2007 - localize me and run me through a legal wringer" +    MACOSX_BUNDLE_SHORT_VERSION_STRING "${VIEWER_SHORT_VERSION}" +    MACOSX_BUNDLE_BUNDLE_VERSION "${VIEWER_SHORT_VERSION}${VIEWER_MACOSX_PHASE}${VIEWER_REVISION}" +    MACOSX_BUNDLE_COPYRIGHT "Copyright © Linden Research, Inc. 2007"      ) +  configure_file( +     "${CMAKE_CURRENT_SOURCE_DIR}/Info-SecondLife.plist" +     "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app/Contents/Info.plist" +               ) +    add_custom_command(      TARGET ${VIEWER_BINARY_NAME} POST_BUILD      COMMAND ${PYTHON_EXECUTABLE} @@ -1965,11 +2001,16 @@ if (DARWIN)        --configuration=${CMAKE_CFG_INTDIR}        --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app        --grid=${GRID} +      --channel=${VIEWER_CHANNEL} +      --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt        --source=${CMAKE_CURRENT_SOURCE_DIR} -    DEPENDS ${VIEWER_BINARY_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py +    DEPENDS +      ${VIEWER_BINARY_NAME} +      ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py +      generate_viewer_version      ) -  add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_webkit mac-updater mac-crash-logger) +  add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_webkit mac-crash-logger)    if (ENABLE_SIGNING)        set(SIGNING_SETTING "--signature=${SIGNING_IDENTITY}") @@ -1979,6 +2020,7 @@ if (DARWIN)    if (PACKAGE)        add_custom_target(package ALL DEPENDS ${VIEWER_BINARY_NAME}) +      add_dependencies(package generate_viewer_version)        add_custom_command(          TARGET package POST_BUILD @@ -1992,12 +2034,14 @@ if (DARWIN)            --configuration=${CMAKE_CFG_INTDIR}            --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app            --grid=${GRID} -          --login_channel=${VIEWER_LOGIN_CHANNEL} +          --channel=${VIEWER_CHANNEL} +          --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt            --source=${CMAKE_CURRENT_SOURCE_DIR}            --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.touched            ${SIGNING_SETTING}          DEPENDS            ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py +          generate_viewer_version        )    endif (PACKAGE)  endif (DARWIN) @@ -2022,12 +2066,11 @@ if (PACKAGE)      # *TODO: Generate these search dirs in the cmake files related to each binary.      list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/llplugin/slplugin/${CMAKE_CFG_INTDIR}")      list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/mac_crash_logger/${CMAKE_CFG_INTDIR}") -    list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/mac_updater/${CMAKE_CFG_INTDIR}")      list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/gstreamer010/${CMAKE_CFG_INTDIR}")      list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/quicktime/${CMAKE_CFG_INTDIR}")      list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/webkit/${CMAKE_CFG_INTDIR}")      set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-darwin.tar.bz2") -    set(VIEWER_EXE_GLOBS "'Second Life' SLPlugin mac-updater mac-crash-logger") +    set(VIEWER_EXE_GLOBS "'Second Life' SLPlugin mac-crash-logger")      set(VIEWER_LIB_GLOB "*.dylib")    endif (DARWIN)    if (LINUX) diff --git a/indra/newview/English.lproj/InfoPlist.strings b/indra/newview/English.lproj/InfoPlist.strings index 1802e14703..041b8cea0b 100644 --- a/indra/newview/English.lproj/InfoPlist.strings +++ b/indra/newview/English.lproj/InfoPlist.strings @@ -2,6 +2,6 @@  CFBundleName = "Second Life"; -CFBundleShortVersionString = "Second Life version 3.4.1.264760"; -CFBundleGetInfoString = "Second Life version 3.4.1.264760, Copyright 2004-2009 Linden Research, Inc."; +CFBundleShortVersionString = "Second Life version %%VERSION%%"; +CFBundleGetInfoString = "Second Life version %%VERSION%%, Copyright 2004 Linden Research, Inc."; diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist index 035d6cbe6c..a19844f11c 100644 --- a/indra/newview/Info-SecondLife.plist +++ b/indra/newview/Info-SecondLife.plist @@ -60,7 +60,7 @@  		</dict>  	</array>  	<key>CFBundleVersion</key> -	<string>3.4.1.264760</string> +	<string>${VIEWER_VERSION_MAJOR}.${VIEWER_VERSION_MINOR}.${VIEWER_VERSION_PATCH}.${VIEWER_VERSION_REVISION}</string>  	<key>CSResourcesFileMapped</key>  	<true/>  </dict> diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt new file mode 100644 index 0000000000..d5c0c99142 --- /dev/null +++ b/indra/newview/VIEWER_VERSION.txt @@ -0,0 +1 @@ +3.5.1 diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index f66d8fca5b..a8679caaa5 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -12439,6 +12439,17 @@        <key>Value</key>        <integer>3</integer>      </map> +    <key>UpdaterWillingToTest</key> +    <map> +      <key>Comment</key> +      <string>Allow upgrades to release candidate viewers with new features and fixes.</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>1</integer> +    </map>      <key>UpdaterServiceCheckPeriod</key>      <map>        <key>Comment</key> @@ -12472,17 +12483,6 @@        <key>Value</key>        <string>update</string>      </map> -    <key>UpdaterServiceProtocolVersion</key> -    <map> -      <key>Comment</key> -      <string>The update protocol version to use.</string> -      <key>Persist</key> -      <integer>0</integer> -      <key>Type</key> -      <string>String</string> -      <key>Value</key> -      <string>v1.0</string> -    </map>      <key>UploadBakedTexOld</key>      <map>        <key>Comment</key> diff --git a/indra/newview/icons/development/secondlife.icns b/indra/newview/icons/development/secondlife.icnsBinary files differ deleted file mode 100644 index 44f63d384c..0000000000 --- a/indra/newview/icons/development/secondlife.icns +++ /dev/null diff --git a/indra/newview/icons/development/secondlife.ico b/indra/newview/icons/development/secondlife.icoBinary files differ deleted file mode 100644 index b53f23ae58..0000000000 --- a/indra/newview/icons/development/secondlife.ico +++ /dev/null diff --git a/indra/newview/icons/development/secondlife_128.png b/indra/newview/icons/development/secondlife_128.pngBinary files differ deleted file mode 100644 index 9b9fe656fc..0000000000 --- a/indra/newview/icons/development/secondlife_128.png +++ /dev/null diff --git a/indra/newview/icons/development/secondlife_16.png b/indra/newview/icons/development/secondlife_16.pngBinary files differ deleted file mode 100644 index 91493a033c..0000000000 --- a/indra/newview/icons/development/secondlife_16.png +++ /dev/null diff --git a/indra/newview/icons/development/secondlife_256.BMP b/indra/newview/icons/development/secondlife_256.BMPBinary files differ deleted file mode 100644 index 174b22319a..0000000000 --- a/indra/newview/icons/development/secondlife_256.BMP +++ /dev/null diff --git a/indra/newview/icons/development/secondlife_256.png b/indra/newview/icons/development/secondlife_256.pngBinary files differ deleted file mode 100644 index 29ed40abdc..0000000000 --- a/indra/newview/icons/development/secondlife_256.png +++ /dev/null diff --git a/indra/newview/icons/development/secondlife_32.png b/indra/newview/icons/development/secondlife_32.pngBinary files differ deleted file mode 100644 index 3b84f5ec77..0000000000 --- a/indra/newview/icons/development/secondlife_32.png +++ /dev/null diff --git a/indra/newview/icons/development/secondlife_48.png b/indra/newview/icons/development/secondlife_48.pngBinary files differ deleted file mode 100644 index d2636d9d72..0000000000 --- a/indra/newview/icons/development/secondlife_48.png +++ /dev/null diff --git a/indra/newview/icons/development/secondlife_512.png b/indra/newview/icons/development/secondlife_512.pngBinary files differ deleted file mode 100644 index 75f9b231f4..0000000000 --- a/indra/newview/icons/development/secondlife_512.png +++ /dev/null diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh index 1381e49c62..40f77263e1 100755 --- a/indra/newview/linux_tools/wrapper.sh +++ b/indra/newview/linux_tools/wrapper.sh @@ -122,7 +122,7 @@ export SAVED_LD_LIBRARY_PATH="${LD_LIBRARY_PATH}"  export LD_LIBRARY_PATH="$PWD/lib:${LD_LIBRARY_PATH}"  # Have to deal specially with gridargs.dat; typical contents look like: -# --channel "Second Life Developer"  --settings settings_developer.xml +# --channel "Second Life Test"  --settings settings_test.xml  # Simply embedding $(<etc/gridargs.dat) into a command line treats each of  # Second, Life and Developer as separate args -- no good. We need bash to  # process quotes using eval. diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 3adf956ae3..fd26b2767f 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -30,7 +30,6 @@  // Viewer includes  #include "llversioninfo.h" -#include "llversionviewer.h"  #include "llfeaturemanager.h"  #include "lluictrlfactory.h"  #include "lltexteditor.h" @@ -123,6 +122,7 @@  #include <boost/bind.hpp>  #include <boost/foreach.hpp>  #include <boost/algorithm/string.hpp> +#include <boost/regex.hpp>  #if LL_WINDOWS @@ -252,6 +252,7 @@ static LLAppViewerListener sAppViewerListener(LLAppViewer::instance);  // viewer.cpp - these are only used in viewer, should be easily moved.  #if LL_DARWIN +const char * const LL_VERSION_BUNDLE_ID = "com.secondlife.indra.viewer";  extern void init_apple_menu(const char* product);  #endif // LL_DARWIN @@ -269,6 +270,20 @@ BOOL gShowObjectUpdates = FALSE;  BOOL gUseQuickTime = TRUE;  eLastExecEvent gLastExecEvent = LAST_EXEC_NORMAL; +S32 gLastExecDuration = -1; // (<0 indicates unknown)  + +#if LL_WINDOWS   +#   define LL_PLATFORM_KEY "win" +#elif LL_DARWIN +#   define LL_PLATFORM_KEY "mac" +#elif LL_LINUX +#   define LL_PLATFORM_KEY "lnx" +#elif LL_SOLARIS +#   define LL_PLATFORM_KEY "sol" +#else +#   error "Unknown Platform" +#endif +const char* gPlatform = LL_PLATFORM_KEY;  LLSD gDebugInfo; @@ -328,8 +343,9 @@ BOOL gLogoutInProgress = FALSE;  ////////////////////////////////////////////////////////////  // Internal globals... that should be removed.  static std::string gArgs; - +const int MAX_MARKER_LENGTH = 1024;  const std::string MARKER_FILE_NAME("SecondLife.exec_marker"); +const std::string START_MARKER_FILE_NAME("SecondLife.start_marker");  const std::string ERROR_MARKER_FILE_NAME("SecondLife.error_marker");  const std::string LLERROR_MARKER_FILE_NAME("SecondLife.llerror_marker");  const std::string LOGOUT_MARKER_FILE_NAME("SecondLife.logout_marker"); @@ -642,7 +658,7 @@ LLTextureFetch* LLAppViewer::sTextureFetch = NULL;  LLAppViewer::LLAppViewer() :   	mMarkerFile(), -	mLogoutMarkerFile(NULL), +	mLogoutMarkerFile(),  	mReportedCrash(false),  	mNumSessions(0),  	mPurgeCache(false), @@ -672,6 +688,7 @@ LLAppViewer::LLAppViewer() :  	gLoggedInTime.stop();  	LLLoginInstance::instance().setUpdaterService(mUpdater.get()); +	LLLoginInstance::instance().setPlatformInfo(gPlatform, getOSInfo().getOSVersionString());  }  LLAppViewer::~LLAppViewer() @@ -2118,7 +2135,7 @@ void errorCallback(const std::string &error_string)  	LLError::crashAndLoop(error_string);  } -bool LLAppViewer::initLogging() +void LLAppViewer::initLogging()  {  	//  	// Set up logging defaults for the viewer @@ -2132,17 +2149,46 @@ bool LLAppViewer::initLogging()  							     "SecondLife.old");  	LLFile::remove(old_log_file); -	// Rename current log file to ".old" +	// Get name of the log file  	std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,  							     "SecondLife.log"); +	/* +	 * Before touching any log files, compute the duration of the last run +	 * by comparing the ctime of the previous start marker file with the ctime +	 * of the last log file. +	 */ +	std::string start_marker_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, START_MARKER_FILE_NAME); +	llstat start_marker_stat; +	llstat log_file_stat; +	if (   0 == LLFile::stat(start_marker_file_name, &start_marker_stat) +		&& 0 == LLFile::stat(log_file, &log_file_stat) +		) +	{ +		int elapsed_seconds = log_file_stat.st_ctime - start_marker_stat.st_ctime; +		// only report a last run time if the last viewer was the same version +		// because this stat will be counted against this version +		gLastExecDuration = markerIsSameVersion(start_marker_file_name) ? elapsed_seconds : -1; +	} +	else +	{ +		// at least one of the LLFile::stat calls failed, so we can't compute the run time +		gLastExecDuration = -1; // unknown +	} +	 +	// Create a new start marker file for comparison with log file time for the next run +	LLAPRFile start_marker_file ; +	start_marker_file.open(start_marker_file_name, LL_APR_W); +	if (start_marker_file.getFileHandle()) +	{ +		recordMarkerVersion(start_marker_file); +		start_marker_file.close(); +	} + +	// Rename current log file to ".old"  	LLFile::rename(log_file, old_log_file);  	// Set the log file to SecondLife.log -  	LLError::logToFile(log_file); - -	// *FIX:Mani no error handling here! -	return true;  }  bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key, @@ -2717,51 +2763,37 @@ bool LLAppViewer::initConfiguration()  		}  	} -	if (!gSavedSettings.getBOOL("AllowMultipleViewers")) +	// +	// Check for another instance of the app running +	// +	mSecondInstance = anotherInstanceRunning(); +	if (mSecondInstance && !gSavedSettings.getBOOL("AllowMultipleViewers"))  	{ -	    // -	    // Check for another instance of the app running -	    // - -		mSecondInstance = anotherInstanceRunning(); -		 -		if (mSecondInstance) -		{ -			std::ostringstream msg; -			msg << LLTrans::getString("MBAlreadyRunning"); -			OSMessageBox( -				msg.str(), -				LLStringUtil::null, -				OSMB_OK); -			return false; -		} +		std::ostringstream msg; +		msg << LLTrans::getString("MBAlreadyRunning"); +		OSMessageBox( +			msg.str(), +			LLStringUtil::null, +			OSMB_OK); +		return false; +	} -		initMarkerFile(); +	initMarkerFile(); -        checkForCrash(); -    } -	else +	if (mSecondInstance)  	{ -		mSecondInstance = anotherInstanceRunning(); -		 -		if (mSecondInstance) +		// This is the second instance of SL. Turn off voice support, +		// but make sure the setting is *not* persisted. +		LLControlVariable* disable_voice = gSavedSettings.getControl("CmdLineDisableVoice"); +		if(disable_voice)  		{ -			// This is the second instance of SL. Turn off voice support, -			// but make sure the setting is *not* persisted. -			LLControlVariable* disable_voice = gSavedSettings.getControl("CmdLineDisableVoice"); -			if(disable_voice) -			{ -				const BOOL DO_NOT_PERSIST = FALSE; -				disable_voice->setValue(LLSD(TRUE), DO_NOT_PERSIST); -			} +			const BOOL DO_NOT_PERSIST = FALSE; +			disable_voice->setValue(LLSD(TRUE), DO_NOT_PERSIST);  		} - -		initMarkerFile(); -         -        if(!mSecondInstance) -        { -            checkForCrash(); -        } +	} +	else +	{ +		checkForCrash();  	}     	// NextLoginLocation is set from the command line option @@ -2868,25 +2900,46 @@ namespace {  		std::string notification_name;  		void (*apply_callback)(LLSD const &, LLSD const &) = NULL; +		/* Build up the notification name... +		 * it can be any of these, which are included here for the sake of grep: +		 *   RequiredUpdateDownloadedDialog +		 *   RequiredUpdateDownloadedVerboseDialog +		 *   OtherChannelRequiredUpdateDownloadedDialog +		 *   OtherChannelRequiredUpdateDownloadedVerbose +		 *   DownloadBackgroundTip +		 *   DownloadBackgroundDialog +		 *   OtherChannelDownloadBackgroundTip +		 *   OtherChannelDownloadBackgroundDialog +		 */ +		{ +			LL_DEBUGS("UpdaterService") << "data = "; +			std::ostringstream data_dump; +			LLSDSerialize::toNotation(data, data_dump); +			LL_CONT << data_dump.str() << LL_ENDL; +		} +		if(data["channel"].asString() != LLVersionInfo::getChannel()) +		{ +			notification_name.append("OtherChannel"); +		}  		if(data["required"].asBoolean())  		{  			if(LLStartUp::getStartupState() <= STATE_LOGIN_WAIT)  			{  				// The user never saw the progress bar.  				apply_callback = &apply_update_ok_callback; -				notification_name = "RequiredUpdateDownloadedVerboseDialog"; +				notification_name += "RequiredUpdateDownloadedVerboseDialog";  			}  			else if(LLStartUp::getStartupState() < STATE_WORLD_INIT)  			{  				// The user is logging in but blocked.  				apply_callback = &apply_update_ok_callback; -				notification_name = "RequiredUpdateDownloadedDialog"; +				notification_name += "RequiredUpdateDownloadedDialog";  			}  			else  			{  				// The user is already logged in; treat like an optional update.  				apply_callback = &apply_update_callback; -				notification_name = "DownloadBackgroundTip"; +				notification_name += "DownloadBackgroundTip";  			}  		}  		else @@ -2896,36 +2949,47 @@ namespace {  			{  				// CHOP-262 we need to use a different notification  				// method prior to login. -				notification_name = "DownloadBackgroundDialog"; +				notification_name += "DownloadBackgroundDialog";  			}  			else  			{ -				notification_name = "DownloadBackgroundTip"; +				notification_name += "DownloadBackgroundTip";  			}  		}  		LLSD substitutions;  		substitutions["VERSION"] = data["version"]; - -		// truncate version at the rightmost '.'  -		std::string version_short(data["version"]); -		size_t short_length = version_short.rfind('.'); -		if (short_length != std::string::npos) +		std::string new_channel = data["channel"].asString(); +		substitutions["NEW_CHANNEL"] = new_channel; +		std::string info_url    = data["info_url"].asString(); +		if ( !info_url.empty() )  		{ -			version_short.resize(short_length); +			substitutions["INFO_URL"] = info_url;  		} +		else +		{ +			LL_WARNS("UpdaterService") << "no info url supplied - defaulting to hard coded release notes pattern" << LL_ENDL; -		LLUIString relnotes_url("[RELEASE_NOTES_BASE_URL][CHANNEL_URL]/[VERSION_SHORT]"); -		relnotes_url.setArg("[VERSION_SHORT]", version_short); +			// truncate version at the rightmost '.'  +			std::string version_short(data["version"]); +			size_t short_length = version_short.rfind('.'); +			if (short_length != std::string::npos) +			{ +				version_short.resize(short_length); +			} -		// *TODO thread the update service's response through to this point -		std::string const & channel = LLVersionInfo::getChannel(); -		boost::shared_ptr<char> channel_escaped(curl_escape(channel.c_str(), channel.size()), &curl_free); +			LLUIString relnotes_url("[RELEASE_NOTES_BASE_URL][CHANNEL_URL]/[VERSION_SHORT]"); +			relnotes_url.setArg("[VERSION_SHORT]", version_short); -		relnotes_url.setArg("[CHANNEL_URL]", channel_escaped.get()); -		relnotes_url.setArg("[RELEASE_NOTES_BASE_URL]", LLTrans::getString("RELEASE_NOTES_BASE_URL")); -		substitutions["RELEASE_NOTES_FULL_URL"] = relnotes_url.getString(); +			// *TODO thread the update service's response through to this point +			std::string const & channel = LLVersionInfo::getChannel(); +			boost::shared_ptr<char> channel_escaped(curl_escape(channel.c_str(), channel.size()), &curl_free); +			relnotes_url.setArg("[CHANNEL_URL]", channel_escaped.get()); +			relnotes_url.setArg("[RELEASE_NOTES_BASE_URL]", LLTrans::getString("RELEASE_NOTES_BASE_URL")); +			substitutions["INFO_URL"] = relnotes_url.getString(); +		} +		  		LLNotificationsUtil::add(notification_name, substitutions, LLSD(), apply_callback);  	} @@ -2973,16 +3037,40 @@ void LLAppViewer::initUpdater()  	std::string url = gSavedSettings.getString("UpdaterServiceURL");  	std::string channel = LLVersionInfo::getChannel();  	std::string version = LLVersionInfo::getVersion(); -	std::string protocol_version = gSavedSettings.getString("UpdaterServiceProtocolVersion");  	std::string service_path = gSavedSettings.getString("UpdaterServicePath");  	U32 check_period = gSavedSettings.getU32("UpdaterServiceCheckPeriod"); +	bool willing_to_test; +	LL_DEBUGS("UpdaterService") << "channel " << channel << LL_ENDL; +	static const boost::regex is_test_channel("\\bTest$"); +	if (boost::regex_search(channel, is_test_channel))  +	{ +		LL_INFOS("UpdaterService") << "Test build: overriding willing_to_test by sending testno" << LL_ENDL; +		willing_to_test = false; +	} +	else +	{ +		willing_to_test = gSavedSettings.getBOOL("UpdaterWillingToTest"); +	} +    unsigned char unique_id[MD5HEX_STR_SIZE]; +	if ( ! llHashedUniqueID(unique_id) ) +	{ +		if ( willing_to_test ) +		{ +			LL_WARNS("UpdaterService") << "Unable to provide a unique id; overriding willing_to_test by sending testno" << LL_ENDL; +		} +		willing_to_test = false; +	}  	mUpdater->setAppExitCallback(boost::bind(&LLAppViewer::forceQuit, this)); -	mUpdater->initialize(protocol_version,  -						 url,  +	mUpdater->initialize(url,   						 service_path,   						 channel,  -						 version); +						 version, +						 gPlatform, +						 getOSInfo().getOSVersionString(), +						 unique_id, +						 willing_to_test +						 );   	mUpdater->setCheckPeriod(check_period);  	mUpdater->setBandwidthLimit((int)gSavedSettings.getF32("UpdaterMaximumBandwidth") * (1024/8));  	gSavedSettings.getControl("UpdaterMaximumBandwidth")->getSignal()-> @@ -3240,8 +3328,8 @@ void LLAppViewer::writeSystemInfo()  	}  	// Dump some debugging info -	LL_INFOS("SystemInfo") << LLTrans::getString("APP_NAME") -			<< " version " << LLVersionInfo::getShortVersion() << LL_ENDL; +	LL_INFOS("SystemInfo") << "Application: " << LLTrans::getString("APP_NAME") << LL_ENDL; +	LL_INFOS("SystemInfo") << "Version: " << LLVersionInfo::getChannelAndVersion() << LL_ENDL;  	// Dump the local time and time zone  	time_t now; @@ -3367,22 +3455,27 @@ void LLAppViewer::handleViewerCrash()  	//we're already in a crash situation	  	if (gDirUtilp)  	{ -		std::string crash_file_name; -		if(gLLErrorActivated) crash_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LLERROR_MARKER_FILE_NAME); -		else crash_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,ERROR_MARKER_FILE_NAME); -		llinfos << "Creating crash marker file " << crash_file_name << llendl; +		std::string crash_file_name = ( gLLErrorActivated ) +			? gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LLERROR_MARKER_FILE_NAME) +			: gDirUtilp->getExpandedFilename(LL_PATH_LOGS,ERROR_MARKER_FILE_NAME); +		LL_INFOS("MarkerFile") << "Creating crash marker file " << crash_file_name << LL_ENDL;  		LLAPRFile crash_file ;  		crash_file.open(crash_file_name, LL_APR_W);  		if (crash_file.getFileHandle())  		{  			LL_INFOS("MarkerFile") << "Created crash marker file " << crash_file_name << LL_ENDL; +			recordMarkerVersion(crash_file);  		}  		else  		{  			LL_WARNS("MarkerFile") << "Cannot create error marker file " << crash_file_name << LL_ENDL;  		}		  	} +	else +	{ +		LL_WARNS("MarkerFile") << "No gDirUtilp with which to create error marker file name" << LL_ENDL; +	}		  	if (gMessageSystem && gDirUtilp)  	{ @@ -3434,7 +3527,7 @@ bool LLAppViewer::anotherInstanceRunning()  	// If the file is currently locked, that means another process is already running.  	std::string marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, MARKER_FILE_NAME); -	LL_DEBUGS("MarkerFile") << "Checking marker file for lock..." << LL_ENDL; +	LL_DEBUGS("MarkerFile") << "Checking marker file '"<< marker_file << "' for lock..." << LL_ENDL;  	//Freeze case checks  	if (LLAPRFile::isExist(marker_file, NULL, LL_APR_RB)) @@ -3460,6 +3553,46 @@ bool LLAppViewer::anotherInstanceRunning()  	return false;  } +// static +void LLAppViewer::recordMarkerVersion(LLAPRFile& marker_file)  +{		 +	std::string marker_version(LLVersionInfo::getChannelAndVersion()); +	if ( marker_version.length() > MAX_MARKER_LENGTH ) +	{ +		LL_WARNS_ONCE("MarkerFile") << "Version length ("<< marker_version.length()<< ") greater than maximum: marker matching may be incorrect" << LL_ENDL; +	} + +	// record the viewer version in the marker file +	marker_file.write(marker_version.data(), marker_version.length()); +} + +bool LLAppViewer::markerIsSameVersion(const std::string& marker_name) const +{ +	bool sameVersion = false; + +	std::string my_version(LLVersionInfo::getChannelAndVersion()); +	char marker_version[MAX_MARKER_LENGTH]; +	S32  marker_version_length; + +	LLAPRFile marker_file; +	marker_file.open(marker_name, LL_APR_RB); +	if (marker_file.getFileHandle()) +	{ +		marker_version_length = marker_file.read(marker_version, sizeof(marker_version)); +		LL_DEBUGS("MarkerFile") << "Compare markers: "; +		std::string marker_string(marker_version, marker_version_length); +		LL_CONT << "\n   mine '" << my_version    << "'" +				<< "\n marker '" << marker_string << "'" +				<< LL_ENDL; +		if ( 0 == my_version.compare( 0, my_version.length(), marker_version, 0, marker_version_length ) ) +		{ +			sameVersion = true; +		} +		marker_file.close(); +	} +	return sameVersion; +} +  void LLAppViewer::initMarkerFile()  {  	//First, check for the existence of other files. @@ -3482,27 +3615,55 @@ void LLAppViewer::initMarkerFile()  	if (LLAPRFile::isExist(mMarkerFileName, NULL, LL_APR_RB) && !anotherInstanceRunning())  	{ -		gLastExecEvent = LAST_EXEC_FROZE; -		LL_INFOS("MarkerFile") << "Exec marker found: program froze on previous execution" << LL_ENDL; +		if ( markerIsSameVersion(mMarkerFileName) ) +		{ +			LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found" << LL_ENDL; +			gLastExecEvent = LAST_EXEC_FROZE; +		} +		else +		{ +			LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found, but versions did not match" << LL_ENDL; +		}  	}      	if(LLAPRFile::isExist(logout_marker_file, NULL, LL_APR_RB))  	{ -		gLastExecEvent = LAST_EXEC_LOGOUT_FROZE; -		LL_INFOS("MarkerFile") << "Last exec LLError crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL; +		if (markerIsSameVersion(logout_marker_file)) +		{ +			gLastExecEvent = LAST_EXEC_LOGOUT_FROZE; +			LL_INFOS("MarkerFile") << "Logout crashed '"<< logout_marker_file << "', setting LastExecEvent to " << gLastExecEvent << LL_ENDL; +		} +		else +		{ +			LL_INFOS("MarkerFile") << "Logout crash marker '"<< logout_marker_file << "' found, but versions did not match" << LL_ENDL; +		}  		LLAPRFile::remove(logout_marker_file);  	}  	if(LLAPRFile::isExist(llerror_marker_file, NULL, LL_APR_RB))  	{ -		if(gLastExecEvent == LAST_EXEC_LOGOUT_FROZE) gLastExecEvent = LAST_EXEC_LOGOUT_CRASH; -		else gLastExecEvent = LAST_EXEC_LLERROR_CRASH; -		LL_INFOS("MarkerFile") << "Last exec LLError crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL; +		if (markerIsSameVersion(llerror_marker_file)) +		{ +			gLastExecEvent = ( gLastExecEvent == LAST_EXEC_LOGOUT_FROZE ) +				? LAST_EXEC_LOGOUT_CRASH : LAST_EXEC_LLERROR_CRASH; +			LL_INFOS("MarkerFile") << "Last exec LLError '"<< llerror_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL; +		} +		else +		{ +			LL_INFOS("MarkerFile") << "Last exec LLError marker '"<< llerror_marker_file << "' found, but versions did not match" << LL_ENDL; +		}  		LLAPRFile::remove(llerror_marker_file);  	}  	if(LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB))  	{ -		if(gLastExecEvent == LAST_EXEC_LOGOUT_FROZE) gLastExecEvent = LAST_EXEC_LOGOUT_CRASH; -		else gLastExecEvent = LAST_EXEC_OTHER_CRASH; -		LL_INFOS("MarkerFile") << "Last exec crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL; +		if (markerIsSameVersion(error_marker_file)) +		{ +			gLastExecEvent = (gLastExecEvent == LAST_EXEC_LOGOUT_FROZE) +				? LAST_EXEC_LOGOUT_CRASH : LAST_EXEC_OTHER_CRASH; +			LL_INFOS("MarkerFile") << "Last exec '"<< error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL; +		} +		else +		{ +			LL_INFOS("MarkerFile") << "Last exec '"<< error_marker_file << "' marker found, but versions did not match" << LL_ENDL; +		}  		LLAPRFile::remove(error_marker_file);  	} @@ -3518,35 +3679,48 @@ void LLAppViewer::initMarkerFile()  	if (s == APR_SUCCESS && mMarkerFile.getFileHandle())  	{ -		LL_DEBUGS("MarkerFile") << "Marker file created." << LL_ENDL; +		LL_DEBUGS("MarkerFile") << "Marker file '"<< mMarkerFileName << "' created." << LL_ENDL; +		if (APR_SUCCESS == apr_file_lock(mMarkerFile.getFileHandle(), APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE))  +		{ +			recordMarkerVersion(mMarkerFile); +			LL_DEBUGS("MarkerFile") << "Marker file locked." << LL_ENDL; +		} +		else +		{ +			LL_INFOS("MarkerFile") << "Marker file cannot be locked." << LL_ENDL; +		}  	}  	else  	{ -		LL_INFOS("MarkerFile") << "Failed to create marker file." << LL_ENDL; -		return; -	} -	if (apr_file_lock(mMarkerFile.getFileHandle(), APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE) != APR_SUCCESS)  -	{ -		mMarkerFile.close() ; -		LL_INFOS("MarkerFile") << "Marker file cannot be locked." << LL_ENDL; -		return; +		LL_INFOS("MarkerFile") << "Failed to create marker file '"<< mMarkerFileName << "'." << LL_ENDL;  	} - -	LL_DEBUGS("MarkerFile") << "Marker file locked." << LL_ENDL;  }  void LLAppViewer::removeMarkerFile(bool leave_logout_marker)  { -	LL_DEBUGS("MarkerFile") << "removeMarkerFile()" << LL_ENDL; +	LL_DEBUGS("MarkerFile") << "removeMarkerFile("<<leave_logout_marker<<")" << LL_ENDL;  	if (mMarkerFile.getFileHandle())  	{ -		mMarkerFile.close() ; +		LL_DEBUGS("MarkerFile") << "removeMarkerFile marker '"<<mMarkerFileName<<"'"<< LL_ENDL; +		mMarkerFile.close();  		LLAPRFile::remove( mMarkerFileName );  	} -	if (mLogoutMarkerFile != NULL && !leave_logout_marker) +	else +	{ +		LL_WARNS("MarkerFile") << "removeMarkerFile marker '"<<mMarkerFileName<<"' not open"<< LL_ENDL; +	} +	if (!leave_logout_marker)  	{ +		if (mLogoutMarkerFile.getFileHandle()) +		{ +			LL_DEBUGS("MarkerFile") << "removeMarkerFile marker '"<<mLogoutMarkerFileName<<"'"<< LL_ENDL; +			mLogoutMarkerFile.close(); +		} +		else +		{ +			LL_WARNS("MarkerFile") << "removeMarkerFile marker '"<<mLogoutMarkerFileName<<"' not open"<< LL_ENDL; +		}  		LLAPRFile::remove( mLogoutMarkerFileName ); -		mLogoutMarkerFile = NULL;  	}  } @@ -4760,16 +4934,15 @@ void LLAppViewer::sendLogoutRequest()  		mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LOGOUT_MARKER_FILE_NAME);  		LLAPRFile outfile ; -		outfile.open(mLogoutMarkerFileName, LL_APR_W); -		mLogoutMarkerFile =  outfile.getFileHandle() ; -		if (mLogoutMarkerFile) +		mLogoutMarkerFile.open(mLogoutMarkerFileName, LL_APR_W); +		if (mLogoutMarkerFile.getFileHandle())  		{ -			llinfos << "Created logout marker file " << mLogoutMarkerFileName << llendl; -    		apr_file_close(mLogoutMarkerFile); +			LL_INFOS("MarkerFile") << "Created logout marker file '"<< mLogoutMarkerFileName << "' " << mLogoutMarkerFileName << LL_ENDL; +			recordMarkerVersion(outfile);  		}  		else  		{ -			llwarns << "Cannot create logout marker file " << mLogoutMarkerFileName << llendl; +			LL_WARNS("MarkerFile") << "Cannot create logout marker file " << mLogoutMarkerFileName << LL_ENDL;  		}		  	}  } @@ -5166,17 +5339,9 @@ void LLAppViewer::handleLoginComplete()  void LLAppViewer::launchUpdater()  { -		LLSD query_map = LLSD::emptyMap(); -	// *TODO place os string in a global constant -#if LL_WINDOWS   -	query_map["os"] = "win"; -#elif LL_DARWIN -	query_map["os"] = "mac"; -#elif LL_LINUX -	query_map["os"] = "lnx"; -#elif LL_SOLARIS -	query_map["os"] = "sol"; -#endif +	LLSD query_map = LLSD::emptyMap(); +	query_map["os"] = gPlatform; +  	// *TODO change userserver to be grid on both viewer and sim, since  	// userserver no longer exists.  	query_map["userserver"] = LLGridManager::getInstance()->getGridId(); diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 08039100b3..d3a8cf24d9 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -183,7 +183,7 @@ public:  protected:  	virtual bool initWindow(); // Initialize the viewer's window. -	virtual bool initLogging(); // Initialize log files, logging system, return false on failure. +	virtual void initLogging(); // Initialize log files, logging system  	virtual void initConsole() {}; // Initialize OS level debugging console.  	virtual bool initHardwareTest() { return true; } // A false result indicates the app should quit.  	virtual bool initSLURLHandler(); @@ -217,7 +217,9 @@ private:  	bool anotherInstanceRunning();   	void initMarkerFile();  -     +	static void recordMarkerVersion(LLAPRFile& marker_file); +	bool markerIsSameVersion(const std::string& marker_name) const; +	      void idle();       void idleShutdown();  	// update avatar SLID and display name caches @@ -237,7 +239,7 @@ private:  	LLAPRFile mMarkerFile; // A file created to indicate the app is running.  	std::string mLogoutMarkerFileName; -	apr_file_t* mLogoutMarkerFile; // A file created to indicate the app is running. +	LLAPRFile mLogoutMarkerFile; // A file created to indicate the app is running.  	LLOSInfo mSysOSInfo;  @@ -321,6 +323,9 @@ typedef enum  } eLastExecEvent;  extern eLastExecEvent gLastExecEvent; // llstartup +extern S32 gLastExecDuration; ///< the duration of the previous run in seconds (<0 indicates unknown) + +extern const char* gPlatform;  extern U32 gFrameCount;  extern U32 gForegroundFrameCount; diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp index 8695652168..5f98fd0a34 100644 --- a/indra/newview/llappviewerlinux.cpp +++ b/indra/newview/llappviewerlinux.cpp @@ -440,7 +440,7 @@ bool LLAppViewerLinux::beingDebugged()  #endif  } -bool LLAppViewerLinux::initLogging() +void LLAppViewerLinux::initLogging()  {  	// Remove the last stack trace, if any  	// This file is no longer created, since the move to Google Breakpad @@ -449,7 +449,7 @@ bool LLAppViewerLinux::initLogging()  		gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log");  	LLFile::remove(old_stack_file); -	return LLAppViewer::initLogging(); +	LLAppViewer::initLogging();  }  bool LLAppViewerLinux::initParseCommandLine(LLCommandLineParser& clp) diff --git a/indra/newview/llappviewerlinux.h b/indra/newview/llappviewerlinux.h index 58e5160180..b30977acb3 100644 --- a/indra/newview/llappviewerlinux.h +++ b/indra/newview/llappviewerlinux.h @@ -63,7 +63,7 @@ protected:  	virtual bool restoreErrorTrap();  	virtual void handleCrashReporting(bool reportFreeze); -	virtual bool initLogging(); +	virtual void initLogging();  	virtual bool initParseCommandLine(LLCommandLineParser& clp);  	virtual bool initSLURLHandler(); diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 82b93b52a2..0ba3669487 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -509,9 +509,9 @@ bool LLAppViewerWin32::cleanup()  	return result;  } -bool LLAppViewerWin32::initLogging() +void LLAppViewerWin32::initLogging()  { -	return LLAppViewer::initLogging(); +	LLAppViewer::initLogging();  }  void LLAppViewerWin32::initConsole() diff --git a/indra/newview/llappviewerwin32.h b/indra/newview/llappviewerwin32.h index 67594aea48..d95174dd1d 100644 --- a/indra/newview/llappviewerwin32.h +++ b/indra/newview/llappviewerwin32.h @@ -44,7 +44,7 @@ public:  	virtual bool cleanup();  protected: -	virtual bool initLogging(); // Override to clean stack_trace info. +	virtual void initLogging(); // Override to clean stack_trace info.  	virtual void initConsole(); // Initialize OS level debugging console.  	virtual bool initHardwareTest(); // Win32 uses DX9 to test hardware.  	virtual bool initParseCommandLine(LLCommandLineParser& clp); diff --git a/indra/newview/llhasheduniqueid.cpp b/indra/newview/llhasheduniqueid.cpp new file mode 100644 index 0000000000..03192d3e61 --- /dev/null +++ b/indra/newview/llhasheduniqueid.cpp @@ -0,0 +1,55 @@ +/**  + * @file llhasheduniqueid.cpp + * @brief retrieves an obfuscated unique id for the system + * + * $LicenseInfo:firstyear=2013&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2013, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llhasheduniqueid.h" +#include "llviewernetwork.h" +#include "lluuid.h" +#include "llmachineid.h" + +bool llHashedUniqueID(unsigned char id[MD5HEX_STR_SIZE]) +{ +	bool idIsUnique = true; +	LLMD5 hashed_unique_id; +	unsigned char unique_id[MAC_ADDRESS_BYTES]; +	if (   LLUUID::getNodeID(unique_id) +		|| LLMachineID::getUniqueID(unique_id, sizeof(unique_id)) +		) +	{ +		hashed_unique_id.update(unique_id, MAC_ADDRESS_BYTES); +		hashed_unique_id.finalize(); +		hashed_unique_id.hex_digest((char*)id); +		LL_INFOS_ONCE("AppInit") << "System ID " << id << LL_ENDL; +	} +	else +	{ +		idIsUnique = false; +		memcpy(id,"00000000000000000000000000000000", MD5HEX_STR_SIZE); +		LL_WARNS_ONCE("AppInit") << "Failed to get an id; cannot uniquely identify this machine." << LL_ENDL; +	} +	return idIsUnique; +} + diff --git a/indra/newview/llhasheduniqueid.h b/indra/newview/llhasheduniqueid.h new file mode 100644 index 0000000000..8ef706c1f3 --- /dev/null +++ b/indra/newview/llhasheduniqueid.h @@ -0,0 +1,34 @@ +/**  + * @file llhasheduniqueid.h + * @brief retrieves obfuscated but unique id for the system + * + * $LicenseInfo:firstyear=2013&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2013, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ +#ifndef LL_LLHASHEDUNIQUEID_H +#define LL_LLHASHEDUNIQUEID_H +#include "llmd5.h" + +/// Get an obfuscated identifier for this system  +bool llHashedUniqueID(unsigned char id[MD5HEX_STR_SIZE]); +///< @returns true if the id is considered valid (if false, the id is all zeros) + +#endif // LL_LLHASHEDUNIQUEID_H diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index 419641d23c..977c50682f 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -30,7 +30,6 @@  // llcommon  #include "llevents.h" -#include "llmd5.h"  #include "stringize.h"  // llmessage (!) @@ -40,6 +39,7 @@  #include "lllogin.h"  // newview +#include "llhasheduniqueid.h"  #include "llviewernetwork.h"  #include "llviewercontrol.h"  #include "llversioninfo.h" @@ -202,7 +202,7 @@ MandatoryUpdateMachine::MandatoryUpdateMachine(LLLoginInstance & loginInstance,  void MandatoryUpdateMachine::start(void)  { -	llinfos << "starting manditory update machine" << llendl; +	llinfos << "starting mandatory update machine" << llendl;  	if(mUpdaterService.isChecking()) {  		switch(mUpdaterService.getState()) { @@ -488,6 +488,13 @@ LLLoginInstance::LLLoginInstance() :  	mDispatcher.add("indeterminate", "", boost::bind(&LLLoginInstance::handleIndeterminate, this, _1));  } +void LLLoginInstance::setPlatformInfo(const std::string platform, +									  const std::string platform_version) +{ +	mPlatform = platform; +	mPlatformVersion = platform_version; +} +  LLLoginInstance::~LLLoginInstance()  {  } @@ -579,26 +586,22 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia  	// (re)initialize the request params with creds.  	LLSD request_params = user_credential->getLoginParams(); -	char hashed_unique_id_string[MD5HEX_STR_SIZE];		/* Flawfinder: ignore */ -	LLMD5 hashed_unique_id; -	unsigned char unique_id[MAC_ADDRESS_BYTES]; -	if(LLUUID::getNodeID(unique_id) == 0) { -		if(LLMachineID::getUniqueID(unique_id, sizeof(unique_id)) == 0) { -			llerrs << "Failed to get an id; cannot uniquely identify this machine." << llendl; -		} +	unsigned char hashed_unique_id_string[MD5HEX_STR_SIZE]; +	if ( ! llHashedUniqueID(hashed_unique_id_string) ) +	{ +		llwarns << "Not providing a unique id in request params" << llendl;  	} -	hashed_unique_id.update(unique_id, MAC_ADDRESS_BYTES); -	hashed_unique_id.finalize(); -	hashed_unique_id.hex_digest(hashed_unique_id_string); -	  	request_params["start"] = construct_start_string();  	request_params["skipoptional"] = mSkipOptionalUpdate;  	request_params["agree_to_tos"] = false; // Always false here. Set true in   	request_params["read_critical"] = false; // handleTOSResponse  	request_params["last_exec_event"] = mLastExecEvent; -	request_params["mac"] = hashed_unique_id_string; -	request_params["version"] = LLVersionInfo::getChannelAndVersion(); // Includes channel name +	request_params["last_exec_duration"] = mLastExecDuration; +	request_params["mac"] = (char*)hashed_unique_id_string; +	request_params["version"] = LLVersionInfo::getVersion();  	request_params["channel"] = LLVersionInfo::getChannel(); +	request_params["platform"] = mPlatform; +	request_params["platform_version"] = mPlatformVersion;  	request_params["id0"] = mSerialNumber;  	request_params["host_id"] = gSavedSettings.getString("HostID");  	request_params["extended_errors"] = true; // request message_id and message_args @@ -784,20 +787,20 @@ void LLLoginInstance::updateApp(bool mandatory, const std::string& auth_msg)  	LLSD payload;  	payload["mandatory"] = mandatory; -/* - We're constructing one of the following 9 strings here: -	 "DownloadWindowsMandatory" -	 "DownloadWindowsReleaseForDownload" -	 "DownloadWindows" -	 "DownloadMacMandatory" -	 "DownloadMacReleaseForDownload" -	 "DownloadMac" -	 "DownloadLinuxMandatory" -	 "DownloadLinuxReleaseForDownload" -	 "DownloadLinux" -  - I've called them out explicitly in this comment so that they can be grepped for. - */ +	/* +	 * We're constructing one of the following 9 strings here: +	 *   "DownloadWindowsMandatory" +	 *	 "DownloadWindowsReleaseForDownload" +	 *	 "DownloadWindows" +	 *	 "DownloadMacMandatory" +	 *	 "DownloadMacReleaseForDownload" +	 *	 "DownloadMac" +	 *	 "DownloadLinuxMandatory" +	 *	 "DownloadLinuxReleaseForDownload" +	 *	 "DownloadLinux" + 	 * +	 * I've called them out explicitly in this comment so that they can be grepped for. +	 */  	std::string notification_name = "Download";  #if LL_WINDOWS diff --git a/indra/newview/lllogininstance.h b/indra/newview/lllogininstance.h index 8b53431219..b0247da7c8 100644 --- a/indra/newview/lllogininstance.h +++ b/indra/newview/lllogininstance.h @@ -66,6 +66,8 @@ public:  	void setSkipOptionalUpdate(bool state) { mSkipOptionalUpdate = state; }  	void setSerialNumber(const std::string& sn) { mSerialNumber = sn; }  	void setLastExecEvent(int lee) { mLastExecEvent = lee; } +	void setLastExecDuration(S32 duration) { mLastExecDuration = duration; } +	void setPlatformInfo(const std::string platform, const std::string platform_version);  	void setNotificationsInterface(LLNotificationsInterface* ni) { mNotifications = ni; } @@ -99,6 +101,9 @@ private:  	F64 mTransferRate;  	std::string mSerialNumber;  	int mLastExecEvent; +	S32 mLastExecDuration; +	std::string mPlatform; +	std::string mPlatformVersion;  	UpdaterLauncherCallback mUpdaterLauncher;  	LLEventDispatcher mDispatcher;  	LLUpdaterService * mUpdaterService;	 diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 8b71f1067f..51dfaa56e8 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -26,6 +26,7 @@  #include "llviewerprecompiledheaders.h" +#include "llappviewer.h"  #include "llstartup.h"  #if LL_WINDOWS @@ -1032,6 +1033,7 @@ bool idle_startup()  		login->setSerialNumber(LLAppViewer::instance()->getSerialNumber());  		login->setLastExecEvent(gLastExecEvent); +		login->setLastExecDuration(gLastExecDuration);  		login->setUpdaterLauncher(boost::bind(&LLAppViewer::launchUpdater, LLAppViewer::instance()));  		// This call to LLLoginInstance::connect() starts the  diff --git a/indra/newview/llversioninfo.cpp b/indra/newview/llversioninfo.cpp index 673d0c24cf..6a8fad0134 100644 --- a/indra/newview/llversioninfo.cpp +++ b/indra/newview/llversioninfo.cpp @@ -26,73 +26,76 @@   */  #include "llviewerprecompiledheaders.h" +#include <iostream> +#include <sstream>  #include "llversioninfo.h" -#include "llversionviewer.h" +#if ! defined(LL_VIEWER_CHANNEL)       \ + || ! defined(LL_VIEWER_VERSION_MAJOR) \ + || ! defined(LL_VIEWER_VERSION_MINOR) \ + || ! defined(LL_VIEWER_VERSION_PATCH) \ + || ! defined(LL_VIEWER_VERSION_BUILD) + #error "Channel or Version information is undefined" +#endif + +const char * const LL_CHANNEL = LL_VIEWER_CHANNEL;  // -// Set the version numbers in indra/llcommon/llversionviewer.h +// Set the version numbers in indra/VIEWER_VERSION  //  //static  S32 LLVersionInfo::getMajor()  { -	return LL_VERSION_MAJOR; +	return LL_VIEWER_VERSION_MAJOR;  }  //static  S32 LLVersionInfo::getMinor()  { -	return LL_VERSION_MINOR; +	return LL_VIEWER_VERSION_MINOR;  }  //static  S32 LLVersionInfo::getPatch()  { -	return LL_VERSION_PATCH; +	return LL_VIEWER_VERSION_PATCH;  }  //static  S32 LLVersionInfo::getBuild()  { -	return LL_VERSION_BUILD; +	return LL_VIEWER_VERSION_BUILD;  }  //static  const std::string &LLVersionInfo::getVersion()  {  	static std::string version(""); -  	if (version.empty())  	{ -		// cache the version string  		std::ostringstream stream; -		stream << LL_VERSION_MAJOR << "." -		       << LL_VERSION_MINOR << "." -		       << LL_VERSION_PATCH << "." -		       << LL_VERSION_BUILD; +		stream << LLVersionInfo::getShortVersion() << "." << LLVersionInfo::getBuild(); +		// cache the version string  		version = stream.str();  	} -  	return version;  }  //static  const std::string &LLVersionInfo::getShortVersion()  { -	static std::string version(""); - -	if (version.empty()) +	static std::string short_version(""); +	if(short_version.empty())  	{  		// cache the version string  		std::ostringstream stream; -		stream << LL_VERSION_MAJOR << "." -		       << LL_VERSION_MINOR << "." -		       << LL_VERSION_PATCH; -		version = stream.str(); +		stream << LL_VIEWER_VERSION_MAJOR << "." +		       << LL_VIEWER_VERSION_MINOR << "." +		       << LL_VIEWER_VERSION_PATCH; +		short_version = stream.str();  	} - -	return version; +	return short_version;  }  namespace @@ -100,7 +103,7 @@ namespace  	/// Storage of the channel name the viewer is using.  	//  The channel name is set by hardcoded constant,   	//  or by calling LLVersionInfo::resetChannel() -	std::string sWorkingChannelName(LL_CHANNEL); +	std::string sWorkingChannelName(LL_VIEWER_CHANNEL);  	// Storage for the "version and channel" string.  	// This will get reset too. @@ -113,11 +116,7 @@ const std::string &LLVersionInfo::getChannelAndVersion()  	if (sVersionChannel.empty())  	{  		// cache the version string -		std::ostringstream stream; -		stream << LLVersionInfo::getChannel() -			   << " " -			   << LLVersionInfo::getVersion(); -		sVersionChannel = stream.str(); +		sVersionChannel = LLVersionInfo::getChannel() + " " + LLVersionInfo::getVersion();  	}  	return sVersionChannel; diff --git a/indra/newview/llversioninfo.h b/indra/newview/llversioninfo.h index 6f64544f3b..077105cae8 100644 --- a/indra/newview/llversioninfo.h +++ b/indra/newview/llversioninfo.h @@ -29,6 +29,7 @@  #define LL_LLVERSIONINFO_H  #include <string> +#include "stdtypes.h"  ///  /// This API provides version information for the viewer.  This diff --git a/indra/newview/llviewerstatsrecorder.cpp b/indra/newview/llviewerstatsrecorder.cpp index 91e485d01b..f9a725547f 100644 --- a/indra/newview/llviewerstatsrecorder.cpp +++ b/indra/newview/llviewerstatsrecorder.cpp @@ -187,6 +187,7 @@ void LLViewerStatsRecorder::writeToLog( F32 interval )  		<< mObjectUpdateFailures << " update failures"  		<< llendl; +	U32 data_size;  	if (mObjectCacheFile == NULL)  	{  		mStartTime = LLTimer::getTotalSeconds(); @@ -216,7 +217,11 @@ void LLViewerStatsRecorder::writeToLog( F32 interval )  				<< "Texture Fetch bps\t"  				<< "\n"; -			fwrite(data_msg.str().c_str(), 1, data_msg.str().size(), mObjectCacheFile ); +			data_size = data_msg.str().size(); +			if (fwrite(data_msg.str().c_str(), 1, data_size, mObjectCacheFile ) != data_size) +			{ +				llwarns << "failed to write full headers to " << STATS_FILE_NAME << llendl; +			}  		}  		else  		{ @@ -249,7 +254,12 @@ void LLViewerStatsRecorder::writeToLog( F32 interval )  		<< "\t" << (mTextureFetchSize * 8 / delta_time)  		<< "\n"; -	fwrite(data_msg.str().c_str(), 1, data_msg.str().size(), mObjectCacheFile ); +	data_size = data_msg.str().size(); +	if (fwrite(data_msg.str().c_str(), 1, data_size, mObjectCacheFile ) != data_size) +	{ +		llwarns << "failed to write full stats to " << STATS_FILE_NAME << llendl; +	} +  	clearStats();  } diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 0910b7536d..fe4d5b3e4d 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -34,6 +34,7 @@  #include <fstream>  #include <algorithm>  #include <boost/lambda/core.hpp> +#include <boost/regex.hpp>  #include "llagent.h"  #include "llagentcamera.h" @@ -2249,29 +2250,42 @@ void LLViewerWindow::setMenuBackgroundColor(bool god_mode, bool dev_grid)  	// no l10n problem because channel is always an english string  	std::string channel = LLVersionInfo::getChannel(); -	bool isProject = (channel.find("Project") != std::string::npos); +	static const boost::regex is_beta_channel("\\bBeta\\b"); +	static const boost::regex is_project_channel("\\bProject\\b"); +	static const boost::regex is_test_channel("\\bTest$");  	// god more important than project, proj more important than grid -    if(god_mode && LLGridManager::getInstance()->isInProductionGrid()) +    if ( god_mode )       { -        new_bg_color = LLUIColorTable::instance().getColor( "MenuBarGodBgColor" ); -    } -    else if(god_mode && !LLGridManager::getInstance()->isInProductionGrid()) -    { -        new_bg_color = LLUIColorTable::instance().getColor( "MenuNonProductionGodBgColor" ); +		if ( LLGridManager::getInstance()->isInProductionGrid() ) +		{ +			new_bg_color = LLUIColorTable::instance().getColor( "MenuBarGodBgColor" ); +		} +		else +		{ +			new_bg_color = LLUIColorTable::instance().getColor( "MenuNonProductionGodBgColor" ); +		}      } -	else if (!god_mode && isProject) +	else if (boost::regex_search(channel, is_beta_channel)) +	{ +		new_bg_color = LLUIColorTable::instance().getColor( "MenuBarBetaBgColor" ); +	} +	else if (boost::regex_search(channel, is_project_channel))  	{  		new_bg_color = LLUIColorTable::instance().getColor( "MenuBarProjectBgColor" ); -    } -    else if(!god_mode && !LLGridManager::getInstance()->isInProductionGrid()) -    { -        new_bg_color = LLUIColorTable::instance().getColor( "MenuNonProductionBgColor" ); -    } -    else  -    { -        new_bg_color = LLUIColorTable::instance().getColor( "MenuBarBgColor" ); -    } +	} +	else if (boost::regex_search(channel, is_test_channel)) +	{ +		new_bg_color = LLUIColorTable::instance().getColor( "MenuBarTestBgColor" ); +	} +	else if(!LLGridManager::getInstance()->isInProductionGrid()) +	{ +		new_bg_color = LLUIColorTable::instance().getColor( "MenuNonProductionBgColor" ); +	} +	else  +	{ +		new_bg_color = LLUIColorTable::instance().getColor( "MenuBarBgColor" ); +	}      if(gMenuBarView)      { diff --git a/indra/newview/res/viewerRes.rc b/indra/newview/res/viewerRes.rc index 471a896019..8587243791 100644 --- a/indra/newview/res/viewerRes.rc +++ b/indra/newview/res/viewerRes.rc @@ -135,8 +135,8 @@ TOOLNO                  CURSOR                  "llno.cur"  //  VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,4,1,264760 - PRODUCTVERSION 3,4,1,264760 + FILEVERSION ${VIEWER_VERSION_MAJOR},${VIEWER_VERSION_MINOR},${VIEWER_VERSION_PATCH},${VIEWER_VERSION_REVISION} + PRODUCTVERSION ${VIEWER_VERSION_MAJOR},${VIEWER_VERSION_MINOR},${VIEWER_VERSION_PATCH},${VIEWER_VERSION_REVISION}   FILEFLAGSMASK 0x3fL  #ifdef _DEBUG   FILEFLAGS 0x1L @@ -153,12 +153,12 @@ BEGIN          BEGIN              VALUE "CompanyName", "Linden Lab"              VALUE "FileDescription", "Second Life" -            VALUE "FileVersion", "3.4.1.264760" +            VALUE "FileVersion", "${VIEWER_VERSION_MAJOR}.${VIEWER_VERSION_MINOR}.${VIEWER_VERSION_PATCH}.${VIEWER_VERSION_REVISION}"              VALUE "InternalName", "Second Life" -            VALUE "LegalCopyright", "Copyright � 2001-2010, Linden Research, Inc." +            VALUE "LegalCopyright", "Copyright � 2001, Linden Research, Inc."              VALUE "OriginalFilename", "SecondLife.exe"              VALUE "ProductName", "Second Life" -            VALUE "ProductVersion", "3.4.1.264760" +            VALUE "ProductVersion", "${VIEWER_VERSION_MAJOR}.${VIEWER_VERSION_MINOR}.${VIEWER_VERSION_PATCH}.${VIEWER_VERSION_REVISION}"          END      END      BLOCK "VarFileInfo" diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index 0de217fc0d..42568775d9 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -102,6 +102,9 @@  	name="MdBlue"  	value=".07 .38 .51 1" />    <color +      name="DkBlue" +      value=".06 .06 .3 1" /> +  <color        name="LtRed"        value="1 0.2 0.2 1" />    <color @@ -111,6 +114,9 @@        name="Red_80"        value="1 0 0 0.8" />    <color +      name="DkRed" +      value="0.3 0.06 0.06 1" /> +  <color        name="Green_80"        value="0 1 0 0.8" />    <color @@ -830,9 +836,14 @@       name="ChatTimestampColor"       reference="White" />      <color +      name="MenuBarBetaBgColor" +      reference="DkBlue" /> +  <color       name="MenuBarProjectBgColor"       reference="MdBlue" /> -   +  <color +      name="MenuBarTestBgColor" +      reference="DkRed" />      <color        name="MeshImportTableNormalColor"        value="1 1 1 1"/> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 105bef7321..6cc8387328 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -3454,7 +3454,7 @@ or you can install it now.     name="DownloadBackgroundTip"     type="notify">  We have downloaded an update to your [APP_NAME] installation. -Version [VERSION] [[RELEASE_NOTES_FULL_URL] Information about this update] +Version [VERSION] [[INFO_URL] Information about this update]      <tag>confirm</tag>      <usetemplate       name="okcancelbuttons" @@ -3467,7 +3467,7 @@ Version [VERSION] [[RELEASE_NOTES_FULL_URL] Information about this update]   name="DownloadBackgroundDialog"   type="alertmodal">  We have downloaded an update to your [APP_NAME] installation. -Version [VERSION] [[RELEASE_NOTES_FULL_URL] Information about this update] +Version [VERSION] [[INFO_URL] Information about this update]      <tag>confirm</tag>      <usetemplate       name="okcancelbuttons" @@ -3480,7 +3480,7 @@ Version [VERSION] [[RELEASE_NOTES_FULL_URL] Information about this update]   name="RequiredUpdateDownloadedVerboseDialog"   type="alertmodal">  We have downloaded a required software update. -Version [VERSION] +Version [VERSION] [[INFO_URL] Information about this update]  We must restart [APP_NAME] to install the update.      <tag>confirm</tag> @@ -3494,6 +3494,66 @@ We must restart [APP_NAME] to install the update.   name="RequiredUpdateDownloadedDialog"   type="alertmodal">  We must restart [APP_NAME] to install the update. +[[INFO_URL] Information about this update] +    <tag>confirm</tag> +    <usetemplate +     name="okbutton" +     yestext="OK"/> +  </notification> + +  <notification +   icon="notify.tga" +   name="OtherChannelDownloadBackgroundTip" +   type="notify"> +We have downloaded an update to your [APP_NAME] installation. +Version [VERSION]  +This experimental viewer has been replaced by a [NEW_CHANNEL] viewer; +see [[INFO_URL] for details about this update] +    <tag>confirm</tag> +    <usetemplate +     name="okcancelbuttons" +     notext="Later..." +     yestext="Install now and restart [APP_NAME]"/> +  </notification> + +  <notification + icon="alertmodal.tga" + name="OtherChannelDownloadBackgroundDialog" + type="alertmodal"> +We have downloaded an update to your [APP_NAME] installation. +Version [VERSION] +This experimental viewer has been replaced by a [NEW_CHANNEL] viewer; +see [[INFO_URL] Information about this update] +    <tag>confirm</tag> +    <usetemplate +     name="okcancelbuttons" +     notext="Later..." +     yestext="Install now and restart [APP_NAME]"/> +  </notification> +   +  <notification + icon="alertmodal.tga" + name="OtherChannelRequiredUpdateDownloadedVerboseDialog" + type="alertmodal"> +We have downloaded a required software update. +Version [VERSION] +This experimental viewer has been replaced by a [NEW_CHANNEL] viewer; +see [[INFO_URL] Information about this update] + +We must restart [APP_NAME] to install the update. +    <tag>confirm</tag> +    <usetemplate +     name="okbutton" +     yestext="OK"/> +  </notification> +   +  <notification + icon="alertmodal.tga" + name="OtherChannelRequiredUpdateDownloadedDialog" + type="alertmodal"> +We must restart [APP_NAME] to install the update. +This experimental viewer has been replaced by a [NEW_CHANNEL] viewer; +see [[INFO_URL] Information about this update]      <tag>confirm</tag>      <usetemplate       name="okbutton" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml index 4aeea8823e..2fb6a9fd40 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml @@ -232,6 +232,19 @@           name="Install_manual"           value="0" />    </combo_box> +  <check_box +    top_delta="4" +    enabled="true" +    follows="left|top" +    height="14" +    initial_value="true" +    control_name="UpdateWillingToTest" +    label="Willing to update to release candidates" +    left_delta="0" +    mouse_opaque="true" +    name="update_willing_to_test" +    width="400"            +    top_pad="5"/>    <text       type="string"       length="1" diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp index 7705b4c567..f038112fd0 100644 --- a/indra/newview/tests/lllogininstance_test.cpp +++ b/indra/newview/tests/lllogininstance_test.cpp @@ -50,7 +50,7 @@ const std::string VIEWERLOGIN_GRIDLABEL("viewerlogin_grid");  const std::string APPVIEWER_SERIALNUMBER("appviewer_serialno");  const std::string VIEWERLOGIN_CHANNEL("invalid_channel"); -const std::string VIEWERLOGIN_VERSION_CHANNEL("invalid_version"); +const std::string VIEWERLOGIN_VERSION("invalid_version");  // Link seams. @@ -73,7 +73,7 @@ void LLViewerWindow::setShowProgress(BOOL show) {}  LLProgressView * LLViewerWindow::getProgressView(void) const { return 0; }  LLViewerWindow* gViewerWindow; - +	  class LLLogin::Impl  {  }; @@ -183,7 +183,7 @@ void LLUIColorTable::saveUserSettings(void)const {}  //-----------------------------------------------------------------------------  #include "../llversioninfo.h" -const std::string &LLVersionInfo::getChannelAndVersion() { return VIEWERLOGIN_VERSION_CHANNEL; } +const std::string &LLVersionInfo::getVersion() { return VIEWERLOGIN_VERSION; }  const std::string &LLVersionInfo::getChannel() { return VIEWERLOGIN_CHANNEL; }  //----------------------------------------------------------------------------- @@ -208,11 +208,15 @@ std::string const & LLUpdaterService::pumpName(void)  	return wakka;  }  bool LLUpdaterService::updateReadyToInstall(void) { return false; } -void LLUpdaterService::initialize(const std::string& protocol_version, -				const std::string& url,  -				const std::string& path, -				const std::string& channel, -								  const std::string& version) {} +void LLUpdaterService::initialize(const std::string& url,  +								  const std::string& path, +								  const std::string& channel, +								  const std::string& version, +								  const std::string& platform, +								  const std::string& platform_version, +								  const unsigned char uniqueid[MD5HEX_STR_SIZE], +								  const bool&         willing_to_test +								  ) {}  void LLUpdaterService::setCheckPeriod(unsigned int seconds) {}  void LLUpdaterService::startChecking(bool install_if_ready) {} @@ -221,6 +225,12 @@ bool LLUpdaterService::isChecking() { return false; }  LLUpdaterService::eUpdaterState LLUpdaterService::getState() { return INITIAL; }  std::string LLUpdaterService::updatedVersion() { return ""; } +bool llHashedUniqueID(unsigned char* id)  +{ +	memcpy( id, "66666666666666666666666666666666", MD5HEX_STR_SIZE ); +	return true; +} +  //-----------------------------------------------------------------------------  #include "llnotifications.h"  #include "llfloaterreg.h" @@ -360,6 +370,7 @@ namespace tut  			accountCredential->setCredentialData(identifier, authenticator);			  			logininstance->setNotificationsInterface(¬ifications); +			logininstance->setPlatformInfo("win", "1.3.5");  		}  		LLLoginInstance* logininstance; diff --git a/indra/newview/tests/llversioninfo_test.cpp b/indra/newview/tests/llversioninfo_test.cpp index 398d8f16ed..6b0be29c2d 100644 --- a/indra/newview/tests/llversioninfo_test.cpp +++ b/indra/newview/tests/llversioninfo_test.cpp @@ -28,7 +28,6 @@  #include "../test/lltut.h"  #include "../llversioninfo.h" -#include "llversionviewer.h"  namespace tut  { @@ -38,20 +37,20 @@ namespace tut  			: mResetChannel("Reset Channel")  		{  			std::ostringstream stream; -			stream << LL_VERSION_MAJOR << "." -				   << LL_VERSION_MINOR << "." -				   << LL_VERSION_PATCH << "." -				   << LL_VERSION_BUILD; +			stream << LL_VIEWER_VERSION_MAJOR << "." +				   << LL_VIEWER_VERSION_MINOR << "." +				   << LL_VIEWER_VERSION_PATCH << "." +				   << LL_VIEWER_VERSION_BUILD;  			mVersion = stream.str();  			stream.str(""); -			stream << LL_VERSION_MAJOR << "." -				   << LL_VERSION_MINOR << "." -				   << LL_VERSION_PATCH; +			stream << LL_VIEWER_VERSION_MAJOR << "." +				   << LL_VIEWER_VERSION_MINOR << "." +				   << LL_VIEWER_VERSION_PATCH;  			mShortVersion = stream.str();  			stream.str(""); -			stream << LL_CHANNEL +			stream << LL_VIEWER_CHANNEL  				   << " "  				   << mVersion;  			mVersionAndChannel = stream.str(); @@ -78,20 +77,19 @@ namespace tut  	{  		ensure_equals("Major version",   					  LLVersionInfo::getMajor(),  -					  LL_VERSION_MAJOR); +					  LL_VIEWER_VERSION_MAJOR);  		ensure_equals("Minor version",   					  LLVersionInfo::getMinor(),  -					  LL_VERSION_MINOR); +					  LL_VIEWER_VERSION_MINOR);  		ensure_equals("Patch version",   					  LLVersionInfo::getPatch(),  -					  LL_VERSION_PATCH); +					  LL_VIEWER_VERSION_PATCH);  		ensure_equals("Build version",   					  LLVersionInfo::getBuild(),  -					  LL_VERSION_BUILD); +					  LL_VIEWER_VERSION_BUILD);  		ensure_equals("Channel version",   					  LLVersionInfo::getChannel(),  -					  LL_CHANNEL); - +					  LL_VIEWER_CHANNEL);  		ensure_equals("Version String",   					  LLVersionInfo::getVersion(),   					  mVersion); diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 69248e26bc..26c1e62522 100644 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -160,14 +160,6 @@ class ViewerManifest(LLManifest):              if not self.path2basename(os.path.join(os.pardir, os.pardir), "summary.json"):                  print "No summary.json file" -    def login_channel(self): -        """Channel reported for login and upgrade purposes ONLY; -        used for A/B testing""" -        # NOTE: Do not return the normal channel if login_channel -        # is not specified, as some code may branch depending on -        # whether or not this is present -        return self.args.get('login_channel') -      def grid(self):          return self.args['grid']      def channel(self): @@ -179,16 +171,24 @@ class ViewerManifest(LLManifest):      def channel_lowerword(self):          return self.channel_oneword().lower() +    def app_name(self): +        app_suffix='Test' +        channel_type=self.channel_lowerword() +        if channel_type == 'release' : +            app_suffix='Viewer' +        elif re.match('^(beta|project).*',channel_type) : +            app_suffix=self.channel_unique() +        return "Second Life "+app_suffix +              def icon_path(self):          icon_path="icons/"          channel_type=self.channel_lowerword() -        if channel_type == 'release' \ -        or channel_type == 'development' \ -        : +        print "Icon channel type '%s'" % channel_type +        if channel_type == 'release' :              icon_path += channel_type -        elif channel_type == 'betaviewer' : +        elif re.match('^beta.*',channel_type) :              icon_path += 'beta' -        elif re.match('project.*',channel_type) : +        elif re.match('^project.*',channel_type) :              icon_path += 'project'          else :              icon_path += 'test' @@ -205,14 +205,6 @@ class ViewerManifest(LLManifest):                           "--helperuri http://preview-%(grid)s.secondlife.com/helpers/" %\                             {'grid':self.grid()} -        # set command line flags for channel -        channel_flags = '' -        if self.login_channel() and self.login_channel() != self.channel(): -            # Report a special channel during login, but use default -            channel_flags = '--channel "%s"' % (self.login_channel()) -        elif not self.default_channel(): -            channel_flags = '--channel "%s"' % self.channel() -          # Deal with settings           setting_flags = ''          if not self.default_channel() or not self.default_grid(): @@ -223,7 +215,7 @@ class ViewerManifest(LLManifest):                  setting_flags = '--settings settings_%s_%s.xml'\                                  % (self.grid(), self.channel_lowerword()) -        return " ".join((channel_flags, grid_flags, setting_flags)).strip() +        return " ".join((grid_flags, setting_flags)).strip()      def extract_names(self,src):          try: @@ -250,13 +242,13 @@ class ViewerManifest(LLManifest):  class WindowsManifest(ViewerManifest):      def final_exe(self): -        if self.default_channel(): -            if self.default_grid(): -                return "SecondLife.exe" -            else: -                return "SecondLifePreview.exe" -        else: -            return ''.join(self.channel().split()) + '.exe' +        app_suffix="Test" +        channel_type=self.channel_lowerword() +        if channel_type == 'release' : +            app_suffix='' +        elif re.match('^(beta|project).*',channel_type) : +            app_suffix=''.join(self.channel_unique().split()) +        return "SecondLife"+app_suffix+".exe"      def test_msvcrt_and_copy_action(self, src, dst):          # This is used to test a dll manifest. @@ -304,26 +296,9 @@ class WindowsManifest(ViewerManifest):          else:              print "Doesn't exist:", src -    ### DISABLED MANIFEST CHECKING for vs2010.  we may need to reenable this -    # shortly.  If this hasn't been reenabled by the 2.9 viewer release then it -    # should be deleted -brad -    #def enable_crt_manifest_check(self): -    #    if self.is_packaging_viewer(): -    #       WindowsManifest.copy_action = WindowsManifest.test_msvcrt_and_copy_action - -    #def enable_no_crt_manifest_check(self): -    #    if self.is_packaging_viewer(): -    #        WindowsManifest.copy_action = WindowsManifest.test_for_no_msvcrt_manifest_and_copy_action - -    #def disable_manifest_check(self): -    #    if self.is_packaging_viewer(): -    #        del WindowsManifest.copy_action -      def construct(self):          super(WindowsManifest, self).construct() -        #self.enable_crt_manifest_check() -          if self.is_packaging_viewer():              # Find secondlife-bin.exe in the 'configuration' dir, then rename it to the result of final_exe.              self.path(src='%s/secondlife-bin.exe' % self.args['configuration'], dst=self.final_exe()) @@ -333,15 +308,11 @@ class WindowsManifest(ViewerManifest):                                          'llplugin', 'slplugin', self.args['configuration']),                             "slplugin.exe") -        #self.disable_manifest_check() -          self.path2basename("../viewer_components/updater/scripts/windows", "update_install.bat")          # Get shared libs from the shared libs staging directory          if self.prefix(src=os.path.join(os.pardir, 'sharedlibs', self.args['configuration']),                         dst=""): -            #self.enable_crt_manifest_check() -                          # Get llcommon and deps. If missing assume static linkage and continue.              try:                  self.path('llcommon.dll') @@ -353,8 +324,6 @@ class WindowsManifest(ViewerManifest):                  print err.message                  print "Skipping llcommon.dll (assuming llcommon was linked statically)" -            #self.disable_manifest_check() -              # Mesh 3rd party libs needed for auto LOD and collada reading              try:                  if self.args['configuration'].lower() == 'debug': @@ -418,8 +387,6 @@ class WindowsManifest(ViewerManifest):          self.path("featuretable.txt")          self.path("featuretable_xp.txt") -        #self.enable_no_crt_manifest_check() -          # Media plugins - QuickTime          if self.prefix(src='../media_plugins/quicktime/%s' % self.args['configuration'], dst="llplugin"):              self.path("media_plugin_quicktime.dll") @@ -499,15 +466,10 @@ class WindowsManifest(ViewerManifest):                  self.end_prefix() -        #self.disable_manifest_check() -          # pull in the crash logger and updater from other projects          # tag:"crash-logger" here as a cue to the exporter          self.path(src='../win_crash_logger/%s/windows-crash-logger.exe' % self.args['configuration'],                    dst="win_crash_logger.exe") -# For CHOP-397, windows updater no longer used. -#        self.path(src='../win_updater/%s/windows-updater.exe' % self.args['configuration'], -#                  dst="updater.exe")          if not self.is_packaging_viewer():              self.package_file = "copied_deps"     @@ -570,6 +532,7 @@ class WindowsManifest(ViewerManifest):              'channel':self.channel(),              'channel_oneword':self.channel_oneword(),              'channel_unique':self.channel_unique(), +            'subchannel_underscores':'_'.join(self.channel_unique().split())              }          version_vars = """ @@ -591,7 +554,7 @@ class WindowsManifest(ViewerManifest):                  Caption "Second Life"                  """              else: -                # beta grid viewer +                # alternate grid viewer                  installer_file = "Second_Life_%(version_dashes)s_(%(grid_caps)s)_Setup.exe"                  grid_vars_template = """                  OutFile "%(installer_file)s" @@ -603,8 +566,8 @@ class WindowsManifest(ViewerManifest):                  Caption "Second Life %(grid)s ${VERSION}"                  """          else: -            # some other channel on some grid -            installer_file = "Second_Life_%(version_dashes)s_%(channel_oneword)s_Setup.exe" +            # some other channel (grid name not used) +            installer_file = "Second_Life_%(version_dashes)s_%(subchannel_underscores)s_Setup.exe"              grid_vars_template = """              OutFile "%(installer_file)s"              !define INSTFLAGS "%(flags)s" @@ -666,13 +629,15 @@ class DarwinManifest(ViewerManifest):          self.path(self.args['configuration'] + "/Second Life.app", dst="")          if self.prefix(src="", dst="Contents"):  # everything goes in Contents -            self.path("Info-SecondLife.plist", dst="Info.plist") +            self.path("Info.plist", dst="Info.plist")              # copy additional libs in <bundle>/Contents/MacOS/              self.path("../packages/lib/release/libndofdev.dylib", dst="Resources/libndofdev.dylib")              self.path("../packages/lib/release/libhunspell-1.3.0.dylib", dst="Resources/libhunspell-1.3.0.dylib") -            self.path("../viewer_components/updater/scripts/darwin/update_install", "MacOS/update_install") +            if self.prefix(dst="MacOS"): +                self.path2basename("../viewer_components/updater/scripts/darwin", "*.py") +                self.end_prefix()              # most everything goes in the Resources directory              if self.prefix(src="", dst="Resources"): @@ -694,7 +659,11 @@ class DarwinManifest(ViewerManifest):                  self.path("SecondLife.nib")                  # Translations -                self.path("English.lproj") +                self.path("English.lproj/language.txt") +                self.replace_in(src="English.lproj/InfoPlist.strings", +                                dst="English.lproj/InfoPlist.strings", +                                searchdict={'%%VERSION%%':'.'.join(self.args['version'])} +                                )                  self.path("German.lproj")                  self.path("Japanese.lproj")                  self.path("Korean.lproj") @@ -764,7 +733,6 @@ class DarwinManifest(ViewerManifest):                  # our apps                  for app_bld_dir, app in (("mac_crash_logger", "mac-crash-logger.app"), -                                         ("mac_updater", "mac-updater.app"),                                           # plugin launcher                                           (os.path.join("llplugin", "slplugin"), "SLPlugin.app"),                                           ): @@ -810,7 +778,7 @@ class DarwinManifest(ViewerManifest):      def copy_finish(self):          # Force executable permissions to be set for scripts          # see CHOP-223 and http://mercurial.selenic.com/bts/issue1802 -        for script in 'Contents/MacOS/update_install',: +        for script in 'Contents/MacOS/update_install.py',:              self.run_command("chmod +x %r" % os.path.join(self.get_dst_prefix(), script))      def package_finish(self): @@ -879,10 +847,7 @@ class DarwinManifest(ViewerManifest):              # Copy everything in to the mounted .dmg -            if self.default_channel() and not self.default_grid(): -                app_name = "Second Life " + self.args['grid'] -            else: -                app_name = channel_standin.strip() +            app_name = self.app_name()              # Hack:              # Because there is no easy way to coerce the Finder into positioning | 
