PageRenderTime 54ms CodeModel.GetById 8ms app.highlight 40ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/mac_crash_logger/llcrashloggermac.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 254 lines | 177 code | 43 blank | 34 comment | 42 complexity | f8f606652c2a9c92e70015eb928ffa52 MD5 | raw file
  1/** 
  2 * @file llcrashloggermac.cpp
  3 * @brief Mac OSX crash logger implementation
  4 *
  5 * $LicenseInfo:firstyear=2003&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27
 28#include "llcrashloggermac.h"
 29
 30#include <Carbon/Carbon.h>
 31#include <iostream>
 32
 33#include "indra_constants.h"	// CRASH_BEHAVIOR_ASK, CRASH_SETTING_NAME
 34#include "llerror.h"
 35#include "llfile.h"
 36#include "lltimer.h"
 37#include "llstring.h"
 38#include "lldir.h"
 39#include "llsdserialize.h"
 40
 41#define MAX_LOADSTRING 100
 42const char* const SETTINGS_FILE_HEADER = "version";
 43const S32 SETTINGS_FILE_VERSION = 101;
 44
 45// Windows Message Handlers
 46
 47BOOL gFirstDialog = TRUE;	// Are we currently handling the Send/Don't Send dialog?
 48LLFILE *gDebugFile = NULL;
 49
 50WindowRef gWindow = NULL;
 51EventHandlerRef gEventHandler = NULL;
 52std::string gUserNotes = "";
 53bool gSendReport = false;
 54bool gRememberChoice = false;
 55IBNibRef nib = NULL;
 56
 57OSStatus dialogHandler(EventHandlerCallRef handler, EventRef event, void *userdata)
 58{
 59	OSStatus result = eventNotHandledErr;
 60	OSStatus err;
 61	UInt32 evtClass = GetEventClass(event);
 62	UInt32 evtKind = GetEventKind(event);
 63	if((evtClass == kEventClassCommand) && (evtKind == kEventCommandProcess))
 64	{
 65		HICommand cmd;
 66		err = GetEventParameter(event, kEventParamDirectObject, typeHICommand, NULL, sizeof(cmd), NULL, &cmd);
 67		
 68
 69		
 70		if(err == noErr)
 71		{
 72			//Get the value of the checkbox
 73			ControlID id;
 74			ControlRef checkBox = NULL;
 75			id.signature = 'remb';
 76			id.id = 0;
 77			err = GetControlByID(gWindow, &id, &checkBox);
 78			
 79			if(err == noErr)
 80			{
 81				if(GetControl32BitValue(checkBox) == kControlCheckBoxCheckedValue)
 82				{
 83					gRememberChoice = true;
 84				}
 85				else
 86				{
 87					gRememberChoice = false;
 88				}
 89			}	
 90			switch(cmd.commandID)
 91			{
 92				case kHICommandOK:
 93				{
 94					char buffer[65535];		/* Flawfinder: ignore */
 95					Size size = sizeof(buffer) - 1;
 96					ControlRef textField = NULL;
 97
 98					id.signature = 'text';
 99					id.id = 0;
100
101					err = GetControlByID(gWindow, &id, &textField);
102					if(err == noErr)
103					{
104						// Get the user response text
105						err = GetControlData(textField, kControlNoPart, kControlEditTextTextTag, size, (Ptr)buffer, &size);
106					}
107					if(err == noErr)
108					{
109						// Make sure the string is terminated.
110						buffer[size] = 0;
111						gUserNotes = buffer;
112
113						llinfos << buffer << llendl;
114					}
115					
116					// Send the report.
117
118					QuitAppModalLoopForWindow(gWindow);
119					gSendReport = true;
120					result = noErr;
121				}
122				break;
123				
124				case kHICommandCancel:
125					QuitAppModalLoopForWindow(gWindow);
126					result = noErr;
127				break;
128				default:
129					result = eventNotHandledErr;
130			}
131		}
132	}
133
134	return(result);
135}
136
137
138LLCrashLoggerMac::LLCrashLoggerMac(void)
139{
140}
141
142LLCrashLoggerMac::~LLCrashLoggerMac(void)
143{
144}
145
146bool LLCrashLoggerMac::init(void)
147{	
148	bool ok = LLCrashLogger::init();
149	if(!ok) return false;
150	if(mCrashBehavior != CRASH_BEHAVIOR_ASK) return true;
151	
152	// Real UI...
153	OSStatus err;
154	
155	err = CreateNibReference(CFSTR("CrashReporter"), &nib);
156	
157	if(err == noErr)
158	{
159		err = CreateWindowFromNib(nib, CFSTR("CrashReporter"), &gWindow);
160	}
161
162	if(err == noErr)
163	{
164		// Set focus to the edit text area
165		ControlRef textField = NULL;
166		ControlID id;
167
168		id.signature = 'text';
169		id.id = 0;
170		
171		// Don't set err if any of this fails, since it's non-critical.
172		if(GetControlByID(gWindow, &id, &textField) == noErr)
173		{
174			SetKeyboardFocus(gWindow, textField, kControlFocusNextPart);
175		}
176	}
177	
178	if(err == noErr)
179	{
180		ShowWindow(gWindow);
181	}
182	
183	if(err == noErr)
184	{
185		// Set up an event handler for the window.
186		EventTypeSpec handlerEvents[] = 
187		{
188			{ kEventClassCommand, kEventCommandProcess }
189		};
190
191		InstallWindowEventHandler(
192				gWindow, 
193				NewEventHandlerUPP(dialogHandler), 
194				GetEventTypeCount (handlerEvents), 
195				handlerEvents, 
196				0, 
197				&gEventHandler);
198	}
199	return true;
200}
201
202void LLCrashLoggerMac::gatherPlatformSpecificFiles()
203{
204	updateApplication("Gathering hardware information...");
205}
206
207bool LLCrashLoggerMac::mainLoop()
208{
209	OSStatus err = noErr;
210				
211	if(err == noErr && mCrashBehavior == CRASH_BEHAVIOR_ASK)
212	{
213		RunAppModalLoopForWindow(gWindow);
214	}
215	else if (mCrashBehavior == CRASH_BEHAVIOR_ALWAYS_SEND)
216	{
217		gSendReport = true;
218	}
219	
220	if(gRememberChoice)
221	{
222		if(gSendReport) saveCrashBehaviorSetting(CRASH_BEHAVIOR_ALWAYS_SEND);
223		else saveCrashBehaviorSetting(CRASH_BEHAVIOR_NEVER_SEND);
224	}
225	
226	if(gSendReport)
227	{
228		setUserText(gUserNotes);
229		sendCrashLogs();
230	}		
231	
232	if(gWindow != NULL)
233	{
234		DisposeWindow(gWindow);
235	}
236	
237	if(nib != NULL)
238	{
239		DisposeNibReference(nib);
240	}
241	
242	return true;
243}
244
245void LLCrashLoggerMac::updateApplication(const std::string& message)
246{
247	LLCrashLogger::updateApplication(message);
248}
249
250bool LLCrashLoggerMac::cleanup()
251{
252	commonCleanup();
253	return true;
254}