summaryrefslogtreecommitdiffstats
path: root/xpcom/base/AppShutdown.h
blob: 605633890065c963b2cb84cd2e13013b2f5dda16 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef AppShutdown_h
#define AppShutdown_h

#include <type_traits>
#include "nsCOMPtr.h"
#include "nsISupports.h"
#include "ShutdownPhase.h"

namespace mozilla {

enum class AppShutdownMode {
  Normal,
  Restart,
};

enum class AppShutdownReason {
  // No reason.
  Unknown,
  // Normal application shutdown.
  AppClose,
  // The application wants to restart.
  AppRestart,
  // The OS is force closing us.
  OSForceClose,
  // The user is logging off from the OS session, the system may stay alive.
  OSSessionEnd,
  // The system is shutting down (and maybe restarting).
  OSShutdown,
  // We unexpectedly received MOZ_WM_APP_QUIT, see bug 1827807.
  WinUnexpectedMozQuit,
};

class AppShutdown {
 public:
  static ShutdownPhase GetCurrentShutdownPhase();
  static bool IsInOrBeyond(ShutdownPhase aPhase);

  /**
   * Returns the current exit code that the process will be terminated with.
   */
  static int GetExitCode();

  /**
   * Save environment variables that we might need if the app initiates a
   * restart later in its lifecycle.
   */
  static void SaveEnvVarsForPotentialRestart();

  /**
   * Init the shutdown with the requested shutdown mode, exit code and optional
   * a reason (if missing it will be derived from aMode).
   */
  static void Init(AppShutdownMode aMode, int aExitCode,
                   AppShutdownReason aReason);

  /**
   * Confirm that we are in fact going to be shutting down.
   */
  static void OnShutdownConfirmed();

  /**
   * If we've attempted to initiate a restart, this call will set up the
   * necessary environment variables and launch the new process.
   */
  static void MaybeDoRestart();

  /**
   * The _exit() call is not a safe way to terminate your own process on
   * Windows, because _exit runs DLL detach callbacks which run static
   * destructors for xul.dll.
   *
   * This method terminates the current process without those issues.
   *
   * Optionally a custom exit code can be supplied.
   */
  static void DoImmediateExit(int aExitCode = 0);

  /**
   * True if the application is currently attempting to shut down in order to
   * restart.
   */
  static bool IsRestarting();

  /**
   * Wrapper for shutdown notifications that informs the terminator before
   * we notify other observers. Calls MaybeFastShutdown.
   */
  static void AdvanceShutdownPhase(
      ShutdownPhase aPhase, const char16_t* aNotificationData = nullptr,
      const nsCOMPtr<nsISupports>& aNotificationSubject =
          nsCOMPtr<nsISupports>(nullptr));

  /**
   * XXX: Before tackling bug 1697745 we need the
   * possibility to advance the phase without notification
   * in the content process.
   */
  static void AdvanceShutdownPhaseWithoutNotify(ShutdownPhase aPhase);

  /**
   * Map shutdown phase to observer key
   */
  static const char* GetObserverKey(ShutdownPhase aPhase);

  /**
   * Map shutdown phase to readable name
   */
  static const char* GetShutdownPhaseName(ShutdownPhase aPhase);

  /**
   * Map observer topic key to shutdown phase
   */
  static ShutdownPhase GetShutdownPhaseFromTopic(const char* aTopic);

#ifdef DEBUG
  /**
   * Check, if we are allowed to send a shutdown notification.
   * Shutdown specific topics are only allowed during calls to
   * AdvanceShutdownPhase itself.
   */
  static bool IsNoOrLegalShutdownTopic(const char* aTopic);
#endif

 private:
  /**
   * Set the shutdown reason annotation.
   */
  static void AnnotateShutdownReason(AppShutdownReason aReason);

  /**
   * This will perform a fast shutdown via _exit(0) or similar if the user's
   * prefs are configured to do so at this phase.
   */
  static void MaybeFastShutdown(ShutdownPhase aPhase);

  /**
   * Internal helper function, uses MaybeFastShutdown.
   */
  static void AdvanceShutdownPhaseInternal(
      ShutdownPhase aPhase, bool doNotify, const char16_t* aNotificationData,
      const nsCOMPtr<nsISupports>& aNotificationSubject);
};

}  // namespace mozilla

#endif  // AppShutdown_h