PageRenderTime 35ms CodeModel.GetById 19ms RepoModel.GetById 0ms 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
Possible License(s): LGPL-2.1
  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. #include "llcrashloggermac.h"
  27. #include <Carbon/Carbon.h>
  28. #include <iostream>
  29. #include "indra_constants.h" // CRASH_BEHAVIOR_ASK, CRASH_SETTING_NAME
  30. #include "llerror.h"
  31. #include "llfile.h"
  32. #include "lltimer.h"
  33. #include "llstring.h"
  34. #include "lldir.h"
  35. #include "llsdserialize.h"
  36. #define MAX_LOADSTRING 100
  37. const char* const SETTINGS_FILE_HEADER = "version";
  38. const S32 SETTINGS_FILE_VERSION = 101;
  39. // Windows Message Handlers
  40. BOOL gFirstDialog = TRUE; // Are we currently handling the Send/Don't Send dialog?
  41. LLFILE *gDebugFile = NULL;
  42. WindowRef gWindow = NULL;
  43. EventHandlerRef gEventHandler = NULL;
  44. std::string gUserNotes = "";
  45. bool gSendReport = false;
  46. bool gRememberChoice = false;
  47. IBNibRef nib = NULL;
  48. OSStatus dialogHandler(EventHandlerCallRef handler, EventRef event, void *userdata)
  49. {
  50. OSStatus result = eventNotHandledErr;
  51. OSStatus err;
  52. UInt32 evtClass = GetEventClass(event);
  53. UInt32 evtKind = GetEventKind(event);
  54. if((evtClass == kEventClassCommand) && (evtKind == kEventCommandProcess))
  55. {
  56. HICommand cmd;
  57. err = GetEventParameter(event, kEventParamDirectObject, typeHICommand, NULL, sizeof(cmd), NULL, &cmd);
  58. if(err == noErr)
  59. {
  60. //Get the value of the checkbox
  61. ControlID id;
  62. ControlRef checkBox = NULL;
  63. id.signature = 'remb';
  64. id.id = 0;
  65. err = GetControlByID(gWindow, &id, &checkBox);
  66. if(err == noErr)
  67. {
  68. if(GetControl32BitValue(checkBox) == kControlCheckBoxCheckedValue)
  69. {
  70. gRememberChoice = true;
  71. }
  72. else
  73. {
  74. gRememberChoice = false;
  75. }
  76. }
  77. switch(cmd.commandID)
  78. {
  79. case kHICommandOK:
  80. {
  81. char buffer[65535]; /* Flawfinder: ignore */
  82. Size size = sizeof(buffer) - 1;
  83. ControlRef textField = NULL;
  84. id.signature = 'text';
  85. id.id = 0;
  86. err = GetControlByID(gWindow, &id, &textField);
  87. if(err == noErr)
  88. {
  89. // Get the user response text
  90. err = GetControlData(textField, kControlNoPart, kControlEditTextTextTag, size, (Ptr)buffer, &size);
  91. }
  92. if(err == noErr)
  93. {
  94. // Make sure the string is terminated.
  95. buffer[size] = 0;
  96. gUserNotes = buffer;
  97. llinfos << buffer << llendl;
  98. }
  99. // Send the report.
  100. QuitAppModalLoopForWindow(gWindow);
  101. gSendReport = true;
  102. result = noErr;
  103. }
  104. break;
  105. case kHICommandCancel:
  106. QuitAppModalLoopForWindow(gWindow);
  107. result = noErr;
  108. break;
  109. default:
  110. result = eventNotHandledErr;
  111. }
  112. }
  113. }
  114. return(result);
  115. }
  116. LLCrashLoggerMac::LLCrashLoggerMac(void)
  117. {
  118. }
  119. LLCrashLoggerMac::~LLCrashLoggerMac(void)
  120. {
  121. }
  122. bool LLCrashLoggerMac::init(void)
  123. {
  124. bool ok = LLCrashLogger::init();
  125. if(!ok) return false;
  126. if(mCrashBehavior != CRASH_BEHAVIOR_ASK) return true;
  127. // Real UI...
  128. OSStatus err;
  129. err = CreateNibReference(CFSTR("CrashReporter"), &nib);
  130. if(err == noErr)
  131. {
  132. err = CreateWindowFromNib(nib, CFSTR("CrashReporter"), &gWindow);
  133. }
  134. if(err == noErr)
  135. {
  136. // Set focus to the edit text area
  137. ControlRef textField = NULL;
  138. ControlID id;
  139. id.signature = 'text';
  140. id.id = 0;
  141. // Don't set err if any of this fails, since it's non-critical.
  142. if(GetControlByID(gWindow, &id, &textField) == noErr)
  143. {
  144. SetKeyboardFocus(gWindow, textField, kControlFocusNextPart);
  145. }
  146. }
  147. if(err == noErr)
  148. {
  149. ShowWindow(gWindow);
  150. }
  151. if(err == noErr)
  152. {
  153. // Set up an event handler for the window.
  154. EventTypeSpec handlerEvents[] =
  155. {
  156. { kEventClassCommand, kEventCommandProcess }
  157. };
  158. InstallWindowEventHandler(
  159. gWindow,
  160. NewEventHandlerUPP(dialogHandler),
  161. GetEventTypeCount (handlerEvents),
  162. handlerEvents,
  163. 0,
  164. &gEventHandler);
  165. }
  166. return true;
  167. }
  168. void LLCrashLoggerMac::gatherPlatformSpecificFiles()
  169. {
  170. updateApplication("Gathering hardware information...");
  171. }
  172. bool LLCrashLoggerMac::mainLoop()
  173. {
  174. OSStatus err = noErr;
  175. if(err == noErr && mCrashBehavior == CRASH_BEHAVIOR_ASK)
  176. {
  177. RunAppModalLoopForWindow(gWindow);
  178. }
  179. else if (mCrashBehavior == CRASH_BEHAVIOR_ALWAYS_SEND)
  180. {
  181. gSendReport = true;
  182. }
  183. if(gRememberChoice)
  184. {
  185. if(gSendReport) saveCrashBehaviorSetting(CRASH_BEHAVIOR_ALWAYS_SEND);
  186. else saveCrashBehaviorSetting(CRASH_BEHAVIOR_NEVER_SEND);
  187. }
  188. if(gSendReport)
  189. {
  190. setUserText(gUserNotes);
  191. sendCrashLogs();
  192. }
  193. if(gWindow != NULL)
  194. {
  195. DisposeWindow(gWindow);
  196. }
  197. if(nib != NULL)
  198. {
  199. DisposeNibReference(nib);
  200. }
  201. return true;
  202. }
  203. void LLCrashLoggerMac::updateApplication(const std::string& message)
  204. {
  205. LLCrashLogger::updateApplication(message);
  206. }
  207. bool LLCrashLoggerMac::cleanup()
  208. {
  209. commonCleanup();
  210. return true;
  211. }