[tor-commits] [tor-launcher/master] Show "Tor unexpectedly exited" message inside Network Settings dialog.

brade at torproject.org brade at torproject.org
Fri Sep 13 19:06:03 UTC 2013


commit 7c4d4c620ab5ef3f84725e674d0e9f98fa38e0d0
Author: Kathy Brade <brade at pearlcrescent.com>
Date:   Fri Sep 13 15:01:48 2013 -0400

    Show "Tor unexpectedly exited" message inside Network Settings dialog.
    
    Detect when the tor process exits, display an informative message along
    with a Restart button inside the Tor Network Settings dialog/wizard.
---
 src/chrome/content/network-settings-wizard.xul |    8 ++-
 src/chrome/content/network-settings.js         |   81 +++++++++++++++++++-----
 src/chrome/content/network-settings.xul        |    8 ++-
 src/chrome/locale/en/network-settings.dtd      |    1 +
 src/chrome/locale/en/torlauncher.properties    |    1 +
 src/chrome/skin/network-settings.css           |    8 ++-
 src/components/tl-process.js                   |   28 ++++++--
 7 files changed, 110 insertions(+), 25 deletions(-)

diff --git a/src/chrome/content/network-settings-wizard.xul b/src/chrome/content/network-settings-wizard.xul
index ed822f7..0002af4 100644
--- a/src/chrome/content/network-settings-wizard.xul
+++ b/src/chrome/content/network-settings-wizard.xul
@@ -129,7 +129,13 @@
     <spring flex="1" />
     <hbox>
       <spring flex="1" />
-      <label value="&torsettings.startingTor;"/>
+      <description id="startingTorMessage">&torsettings.startingTor;</description>
+      <spring flex="1" />
+    </hbox>
+    <hbox>
+      <spring flex="1" />
+      <button id="restartButton" label="&torsettings.restart;" hidden="true"
+              oncommand="onRestartApp()" />
       <spring flex="1" />
     </hbox>
     <spring flex="1" />
diff --git a/src/chrome/content/network-settings.js b/src/chrome/content/network-settings.js
index 573393d..27b6f58 100644
--- a/src/chrome/content/network-settings.js
+++ b/src/chrome/content/network-settings.js
@@ -144,19 +144,14 @@ function initDialog()
 
   gObsService.addObserver(gObserver, kTorBootstrapErrorTopic, false);
   gObsService.addObserver(gObserver, kTorLogHasWarnOrErrTopic, false);
+  gObsService.addObserver(gObserver, kTorProcessExitedTopic, false);
 
+  var status = gTorProcessService.TorProcessStatus;
   if (TorLauncherUtil.shouldStartAndOwnTor &&
-      !gTorProcessService.TorIsProcessReady)
+     (status != gTorProcessService.kStatusRunning))
   {
-    showPanel("startingTor");
-    if (haveWizard)
-    {
-      showOrHideButton("back", false, false);
-      showOrHideButton("next", false, false);
-    }
-
+    showStartingTorPanel(status == gTorProcessService.kStatusExited);
     gObsService.addObserver(gObserver, kTorProcessReadyTopic, false);
-    gObsService.addObserver(gObserver, kTorProcessExitedTopic, false);
     gObsService.addObserver(gObserver, kTorProcessDidNotStartTopic, false);
   }
   else
@@ -223,13 +218,9 @@ var gObserver = {
       return;
     }
 
-    // Process events that only occur once.
-    gObsService.removeObserver(gObserver, kTorProcessReadyTopic);
-    gObsService.removeObserver(gObserver, kTorProcessExitedTopic);
-    gObsService.removeObserver(gObserver, kTorProcessDidNotStartTopic);
-
     if (kTorProcessReadyTopic == aTopic)
     {
+      gObsService.removeObserver(gObserver, kTorProcessReadyTopic);
       var haveWizard = (getWizard() != null);
       showPanel(haveWizard ? "first" : "settings");
       if (haveWizard)
@@ -240,9 +231,15 @@ var gObserver = {
       readTorSettings();
     }
     else if (kTorProcessDidNotStartTopic == aTopic)
+    {
+      gObsService.removeObserver(gObserver, kTorProcessDidNotStartTopic);
       showErrorPanel();
-    else // kTorProcessExitedTopic
-      close();
+    }
+    else if (kTorProcessExitedTopic == aTopic)
+    {
+      gObsService.removeObserver(gObserver, kTorProcessExitedTopic);
+      showStartingTorPanel(true);
+    }
   }
 };
 
@@ -295,6 +292,33 @@ function showPanel(aPanelID)
 }
 
 
+function showStartingTorPanel(aTorExited)
+{
+  if (aTorExited)
+  {
+    // Show "Tor exited; please restart" message and Restart button.
+    var elem = document.getElementById("startingTorMessage");
+    if (elem)
+    {
+      var s1 = TorLauncherUtil.getLocalizedString("tor_exited");
+      var s2 = TorLauncherUtil.getLocalizedString("please_restart_app");
+      elem.textContent = s1 + "\n\n" + s2;
+    }
+    var btn = document.getElementById("restartButton");
+    if (btn)
+      btn.removeAttribute("hidden");
+  }
+
+  showPanel("startingTor");
+  var haveWizard = (getWizard() != null);
+  if (haveWizard)
+  {
+    showOrHideButton("back", false, false);
+    showOrHideButton("next", false, false);
+  }
+}
+
+
 function showErrorPanel()
 {
   showPanel("errorPanel");
@@ -425,6 +449,31 @@ function onProxyTypeChange()
 }
 
 
+function onRestartApp()
+{
+  if (gIsInitialBootstrap)
+  {
+    // If the browser has not fully started yet, we cannot use the app startup
+    // service to restart it... so we use a delayed approach.
+    try
+    {
+      var obsSvc = Cc["@mozilla.org/observer-service;1"]
+                     .getService(Ci.nsIObserverService);
+      obsSvc.notifyObservers(null, "TorUserRequestedQuit", "restart");
+
+      window.close();
+    } catch (e) {}
+  }
+  else
+  {
+    // Restart now.
+    var asSvc = Cc["@mozilla.org/toolkit/app-startup;1"]
+                  .getService(Ci.nsIAppStartup);
+    asSvc.quit(asSvc.eAttemptQuit | asSvc.eRestart);
+  }
+}
+
+
 function onCancel()
 {
   if (gRestoreAfterHelpPanelID) // Is help open?
diff --git a/src/chrome/content/network-settings.xul b/src/chrome/content/network-settings.xul
index f50e4f6..ae4eb8d 100644
--- a/src/chrome/content/network-settings.xul
+++ b/src/chrome/content/network-settings.xul
@@ -57,7 +57,13 @@
       <spring flex="1" />
       <hbox>
         <spring flex="1" />
-        <label value="&torsettings.startingTor;"/>
+        <description id="startingTorMessage">&torsettings.startingTor;</description>
+        <spring flex="1" />
+      </hbox>
+      <hbox>
+        <spring flex="1" />
+        <button id="restartButton" label="&torsettings.restart;" hidden="true"
+                oncommand="onRestartApp()" />
         <spring flex="1" />
       </hbox>
       <spring flex="1" />
diff --git a/src/chrome/locale/en/network-settings.dtd b/src/chrome/locale/en/network-settings.dtd
index b9fedc3..3017865 100644
--- a/src/chrome/locale/en/network-settings.dtd
+++ b/src/chrome/locale/en/network-settings.dtd
@@ -27,6 +27,7 @@
 <!-- Other: -->
 
 <!ENTITY torsettings.startingTor "Waiting for Tor to start…">
+<!ENTITY torsettings.restart "Restart">
 
 <!ENTITY torsettings.optional "Optional">
 
diff --git a/src/chrome/locale/en/torlauncher.properties b/src/chrome/locale/en/torlauncher.properties
index 5ed593a..483ce43 100644
--- a/src/chrome/locale/en/torlauncher.properties
+++ b/src/chrome/locale/en/torlauncher.properties
@@ -4,6 +4,7 @@
 torlauncher.error_title=Tor Launcher
 
 torlauncher.tor_exited=Tor unexpectedly exited.
+torlauncher.please_restart_app=Please restart this application.
 torlauncher.tor_controlconn_failed=Could not connect to Tor control port.
 torlauncher.tor_failed_to_start=Tor failed to start.
 torlauncher.tor_bootstrap_failed=Tor failed to establish a Tor network connection.\n\n%S
diff --git a/src/chrome/skin/network-settings.css b/src/chrome/skin/network-settings.css
index 1d92151..7ab28c1 100644
--- a/src/chrome/skin/network-settings.css
+++ b/src/chrome/skin/network-settings.css
@@ -95,9 +95,15 @@ button.firstAnswer {
   min-height: 300px;
 }
 
-#startingTor label {
+wizardpage[pageid="startingTor"] description,
+#startingTor description {
   font-size: 120%;
   font-weight: bold;
+  white-space: pre-wrap;
+}
+
+#restartButton {
+  margin-top: 20px;
 }
 
 dialog .help {
diff --git a/src/components/tl-process.js b/src/components/tl-process.js
index 17c4012..c4f977c 100644
--- a/src/components/tl-process.js
+++ b/src/components/tl-process.js
@@ -36,6 +36,11 @@ TorProcessService.prototype =
   kMaxControlConnRetryMS: 500,
   kControlConnTimeoutMS: 30000, // Wait at most 30 seconds for tor to start.
 
+  kStatusUnknown: 0, // Tor process status.
+  kStatusStarting: 1,
+  kStatusRunning: 2,
+  kStatusExited: 3,  // Exited or failed to start.
+
   // nsISupports implementation.
   QueryInterface: function(aIID)
   {
@@ -114,6 +119,7 @@ TorProcessService.prototype =
       }
 
       this.mTorProcess = null;
+      this.mTorProcessStatus = this.kStatusExited;
 
       this.mObsSvc.notifyObservers(null, "TorProcessExited", null);
 
@@ -132,7 +138,7 @@ TorProcessService.prototype =
         if (haveConnection)
         {
           this.mControlConnTimer = null;
-          this.mIsTorProcessReady = true;
+          this.mTorProcessStatus = this.kStatusRunning;
           this.mProtocolSvc.TorStartEventMonitor();
 
           this.mProtocolSvc.TorRetrieveBootstrapStatus();
@@ -164,7 +170,10 @@ TorProcessService.prototype =
     else if (kOpenNetworkSettingsTopic == aTopic)
       this._openNetworkSettings(false);
     else if (kUserQuitTopic == aTopic)
+    {
       this.mQuitSoon = true;
+      this.mRestartWithQuit = ("restart" == aParam);
+    }
   },
 
   canUnload: function(aCompMgr) { return true; },
@@ -201,9 +210,9 @@ TorProcessService.prototype =
 
 
   // Public Properties and Methods ///////////////////////////////////////////
-  get TorIsProcessReady()
+  get TorProcessStatus()
   {
-    return (this.mTorProcess) ? this.mIsTorProcessReady : false;
+    return this.mTorProcessStatus;
   },
 
   get TorIsBootstrapDone()
@@ -225,7 +234,7 @@ TorProcessService.prototype =
 
 
   // Private Member Variables ////////////////////////////////////////////////
-  mIsTorProcessReady: false,
+  mTorProcessStatus: 0,  // kStatusUnknown
   mIsBootstrapDone: false,
   mBootstrapErrorOccurred: false,
   mIsQuitting: false,
@@ -237,6 +246,7 @@ TorProcessService.prototype =
   mControlConnTimer: null,
   mControlConnDelayMS: 0,
   mQuitSoon: false,     // Quit was requested by the user; do so soon.
+  mRestartWithQuit: false,
   mLastTorWarningPhase: null,
   mLastTorWarningText: null,
 
@@ -244,7 +254,7 @@ TorProcessService.prototype =
   // Private Methods /////////////////////////////////////////////////////////
   _startTor: function()
   {
-    this.mIsTorProcessReady = false;
+    this.mTorProcessStatus = this.kStatusUnknown;
 
     var isInitialBootstrap =
                      TorLauncherUtil.getBoolPref(this.kPrefPromptAtStartup);
@@ -300,6 +310,8 @@ TorProcessService.prototype =
         args.push("1");
       }
 
+      this.mTorProcessStatus = this.kStatusStarting;
+
       var p = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
       p.init(exeFile);
 
@@ -335,7 +347,10 @@ TorProcessService.prototype =
 
         var asSvc = Cc["@mozilla.org/toolkit/app-startup;1"]
                       .getService(Ci.nsIAppStartup);
-        asSvc.quit(asSvc.eAttemptQuit);
+        var flags = asSvc.eAttemptQuit;
+        if (this.mRestartWithQuit) 
+          flags |= asSvc.eRestart;
+        asSvc.quit(flags);
       }
       catch (e)
       {
@@ -344,6 +359,7 @@ TorProcessService.prototype =
     }
     catch (e)
     {
+      this.mTorProcessStatus = this.kStatusExited;
       var s = TorLauncherUtil.getLocalizedString("tor_failed_to_start");
       TorLauncherUtil.showAlert(null, s);
       TorLauncherLogger.safelog(4, "_startTor error: ", e);



More information about the tor-commits mailing list