bug 376720 - send time-since-install with crash report
authorted.mielczarek@gmail.com
Tue, 24 Jul 2007 18:06:15 -0700
changeset 3934 bdffd92b963a350bfdd347b875799f1c3e7d8f40
parent 3933 2216222562221400a649619a0cd72949ea410d74
child 3935 d7bd9c7b104c2f285f4fe0df33f8747b3f60754c
push idunknown
push userunknown
push dateunknown
bugs376720
milestone1.9a7pre
bug 376720 - send time-since-install with crash report
toolkit/crashreporter/nsExceptionHandler.cpp
toolkit/crashreporter/nsExceptionHandler.h
--- a/toolkit/crashreporter/nsExceptionHandler.cpp
+++ b/toolkit/crashreporter/nsExceptionHandler.cpp
@@ -61,16 +61,17 @@
 #error "Not yet implemented for this platform"
 #endif // defined(XP_WIN32)
 
 #ifndef HAVE_CPP_2BYTE_WCHAR_T
 #error "This code expects a 2 byte wchar_t.  You should --disable-airbag."
 #endif
 
 #include <stdlib.h>
+#include <time.h>
 #include <prenv.h>
 #include <prio.h>
 #include "nsDebug.h"
 #include "nsCRT.h"
 #include "nsILocalFile.h"
 #include "nsDataHashtable.h"
 
 namespace CrashReporter {
@@ -394,31 +395,43 @@ GetFileContents(nsIFile* aFile, nsACStri
 // Function typedef for initializing a piece of data that we
 // don't already have.
 typedef nsresult (*InitDataFunc)(nsACString&);
 
 // Attempt to read aFile's contents into aContents, if aFile
 // does not exist, create it and initialize its contents
 // by calling aInitFunc for the data.
 static nsresult 
-GetOrInit(nsIFile* aFile, nsACString& aContents, InitDataFunc aInitFunc)
+GetOrInit(nsILocalFile* aDir, const nsAString& filename,
+          nsACString& aContents, InitDataFunc aInitFunc)
 {
   PRBool exists;
-  nsresult rv = aFile->Exists(&exists);
+
+  nsCOMPtr<nsIFile> dataFile;
+  nsresult rv = aDir->Clone(getter_AddRefs(dataFile));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = dataFile->Append(filename);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = dataFile->Exists(&exists);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!exists) {
     // get the initial value and write it to the file
     rv = aInitFunc(aContents);
     NS_ENSURE_SUCCESS(rv, rv);
-    return WriteDataToFile(aFile, aContents);
+    rv = WriteDataToFile(dataFile, aContents);
+  }
+  else {
+    // just get the file's contents
+    rv = GetFileContents(dataFile, aContents);
   }
 
-  // just get the file's contents
-  return GetFileContents(aFile, aContents);
+  return rv;
 }
 
 // Generate a unique user ID.  We're using a GUID form,
 // but not jumping through hoops to make it cryptographically
 // secure.  We just want it to distinguish unique users.
 static nsresult
 InitUserID(nsACString& aUserID)
 {
@@ -448,33 +461,50 @@ InitUserID(nsACString& aUserID)
 #endif
 
   nsCAutoString id_str(id.ToString());
   aUserID = Substring(id_str, 1, id_str.Length()-2);
   
   return NS_OK;
 }
 
+// Init the "install time" data.  We're taking an easy way out here
+// and just setting this to "the time when this version was first run".
+static nsresult
+InitInstallTime(nsACString& aInstallTime)
+{
+  time_t t = time(NULL);
+  char buf[16];
+  sprintf(buf, "%ld", t);
+  aInstallTime = buf;
+  
+  return NS_OK;
+}
+
 // Annotate the crash report with a Unique User ID.
 // TODO: also add time since install, and time since last crash.
 // (bug 376720 and bug 376721)
 // If any piece of data doesn't exist, initialize it first.
-nsresult SetupExtraData(nsILocalFile* aAppDataDirectory)
+nsresult SetupExtraData(nsILocalFile* aAppDataDirectory,
+                        const nsACString& aBuildID)
 {
   nsresult rv = aAppDataDirectory->Append(NS_LITERAL_STRING("Crash Reports"));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCOMPtr<nsIFile> userIDfile;
-  if (NS_SUCCEEDED(aAppDataDirectory->Clone(getter_AddRefs(userIDfile)))
-      && NS_SUCCEEDED(userIDfile->Append(NS_LITERAL_STRING("UserID")))) {
-    nsCAutoString userID;
-    if (NS_SUCCEEDED(GetOrInit(userIDfile, userID, InitUserID))) {
-      AnnotateCrashReport(NS_LITERAL_CSTRING("UserID"), userID);
-    }
-  }
+  nsCAutoString data;
+  if(NS_SUCCEEDED(GetOrInit(aAppDataDirectory, NS_LITERAL_STRING("UserID"),
+                            data, InitUserID)))
+    AnnotateCrashReport(NS_LITERAL_CSTRING("UserID"), data);
+
+  if(NS_SUCCEEDED(GetOrInit(aAppDataDirectory,
+                            NS_LITERAL_STRING("InstallTime") +
+                            NS_ConvertASCIItoUTF16(aBuildID),
+                            data, InitInstallTime)))
+    AnnotateCrashReport(NS_LITERAL_CSTRING("InstallTime"), data);
+
   return NS_OK;
 }
 
 nsresult UnsetExceptionHandler()
 {
   // do this here in the unlikely case that we succeeded in allocating
   // our strings but failed to allocate gExceptionHandler.
   if (crashReporterAPIData_Hash) {
--- a/toolkit/crashreporter/nsExceptionHandler.h
+++ b/toolkit/crashreporter/nsExceptionHandler.h
@@ -44,12 +44,13 @@
 
 namespace CrashReporter {
 nsresult SetExceptionHandler(nsILocalFile* aXREDirectory,
                              const char* aServerURL);
 nsresult SetMinidumpPath(const nsAString& aPath);
 nsresult UnsetExceptionHandler();
 nsresult AnnotateCrashReport(const nsACString &key, const nsACString &data);
 nsresult SetRestartArgs(int argc, char **argv);
-nsresult SetupExtraData(nsILocalFile* aAppDataDirectory);
+nsresult SetupExtraData(nsILocalFile* aAppDataDirectory,
+                        const nsACString& aBuildID);
 }
 
 #endif /* nsAirbagExceptionHandler_h__ */