[M85 Dev][EFL] Fix errors to generate ninja files
[platform/framework/web/chromium-efl.git] / chrome / browser / chrome_browser_main_posix.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/chrome_browser_main_posix.h"
6
7 #include <errno.h>
8 #include <pthread.h>
9 #include <signal.h>
10 #include <stddef.h>
11 #include <string.h>
12 #include <sys/resource.h>
13
14 #include <string>
15
16 #include "base/bind.h"
17 #include "base/check_op.h"
18 #include "base/macros.h"
19 #include "base/notreached.h"
20 #include "build/build_config.h"
21 #include "chrome/app/shutdown_signal_handlers_posix.h"
22 #include "chrome/browser/lifetime/application_lifetime.h"
23 #include "chrome/browser/sessions/session_restore.h"
24 #include "content/public/browser/browser_task_traits.h"
25 #include "content/public/browser/browser_thread.h"
26 #include "content/public/common/result_codes.h"
27
28 using content::BrowserThread;
29
30 namespace {
31
32 // See comment in |PreEarlyInitialization()|, where sigaction is called.
33 void SIGCHLDHandler(int signal) {
34 }
35
36 // ExitHandler takes care of servicing an exit (from a signal) at the
37 // appropriate time. Specifically if we get an exit and have not finished
38 // session restore we delay the exit. To do otherwise means we're exiting part
39 // way through startup which causes all sorts of problems.
40 class ExitHandler {
41  public:
42   // Invokes exit when appropriate.
43   static void ExitWhenPossibleOnUIThread(int signal);
44
45  private:
46   ExitHandler();
47   ~ExitHandler();
48
49   // Called when a session restore has finished.
50   void OnSessionRestoreDone(int num_tabs_restored);
51
52   // Does the appropriate call to Exit.
53   static void Exit();
54
55   // Points to the on-session-restored callback that was registered with
56   // SessionRestore's callback list. When objects of this class are destroyed,
57   // the subscription object's destructor will automatically unregister the
58   // callback in SessionRestore, so that the callback list does not contain any
59   // obsolete callbacks.
60   SessionRestore::CallbackSubscription
61       on_session_restored_callback_subscription_;
62
63   DISALLOW_COPY_AND_ASSIGN(ExitHandler);
64 };
65
66 // static
67 void ExitHandler::ExitWhenPossibleOnUIThread(int signal) {
68   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
69   if (SessionRestore::IsRestoringSynchronously()) {
70     // ExitHandler takes care of deleting itself.
71     new ExitHandler();
72   } else {
73 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
74     switch (signal) {
75       case SIGINT:
76       case SIGHUP:
77         // SIGINT gets sent when the user types Ctrl+C, but the session is
78         // likely not going away, so try to exit gracefully.  SIGHUP is sent on
79         // most systems as a first warning of shutdown.  If the process takes
80         // too long to quit, the next signal is usually SIGTERM.
81         Exit();
82         break;
83       case SIGTERM:
84         // SIGTERM is usually sent instead of SIGKILL to gracefully shutdown
85         // processes.  But most systems use it as a shutdown warning, so
86         // conservatively assume that the session is ending.  If the process
87         // still doesn't quit within a bounded time, most systems will finally
88         // send SIGKILL, which we're unable to install a signal handler for.
89         // TODO(thomasanderson): Try to distinguish if the session is really
90         // ending or not.  Maybe there's a systemd or DBus API to query.
91         chrome::SessionEnding();
92         break;
93       default:
94         NOTREACHED();
95     }
96 #else
97     Exit();
98 #endif
99   }
100 }
101
102 ExitHandler::ExitHandler() {
103   on_session_restored_callback_subscription_ =
104       SessionRestore::RegisterOnSessionRestoredCallback(
105           base::Bind(&ExitHandler::OnSessionRestoreDone,
106                      base::Unretained(this)));
107 }
108
109 ExitHandler::~ExitHandler() {
110 }
111
112 void ExitHandler::OnSessionRestoreDone(int /* num_tabs */) {
113   if (!SessionRestore::IsRestoringSynchronously()) {
114     // At this point the message loop may not be running (meaning we haven't
115     // gotten through browser startup, but are close). Post the task to at which
116     // point the message loop is running.
117     content::GetUIThreadTaskRunner({})->PostTask(
118         FROM_HERE, base::BindOnce(&ExitHandler::Exit));
119     delete this;
120   }
121 }
122
123 // static
124 void ExitHandler::Exit() {
125 #if defined(OS_CHROMEOS)
126   // On ChromeOS, exiting on signal should be always clean.
127   chrome::ExitIgnoreUnloadHandlers();
128 #else
129   chrome::AttemptExit();
130 #endif
131 }
132
133 }  // namespace
134
135 // ChromeBrowserMainPartsPosix -------------------------------------------------
136
137 ChromeBrowserMainPartsPosix::ChromeBrowserMainPartsPosix(
138     const content::MainFunctionParams& parameters,
139     StartupData* startup_data)
140     : ChromeBrowserMainParts(parameters, startup_data) {}
141
142 int ChromeBrowserMainPartsPosix::PreEarlyInitialization() {
143   const int result = ChromeBrowserMainParts::PreEarlyInitialization();
144   if (result != service_manager::RESULT_CODE_NORMAL_EXIT)
145     return result;
146
147   // We need to accept SIGCHLD, even though our handler is a no-op because
148   // otherwise we cannot wait on children. (According to POSIX 2001.)
149   struct sigaction action;
150   memset(&action, 0, sizeof(action));
151   action.sa_handler = SIGCHLDHandler;
152   CHECK_EQ(0, sigaction(SIGCHLD, &action, NULL));
153
154   return service_manager::RESULT_CODE_NORMAL_EXIT;
155 }
156
157 void ChromeBrowserMainPartsPosix::PostMainMessageLoopStart() {
158   ChromeBrowserMainParts::PostMainMessageLoopStart();
159
160   // Exit in response to SIGINT, SIGTERM, etc.
161   InstallShutdownSignalHandlers(
162       base::BindOnce(&ExitHandler::ExitWhenPossibleOnUIThread),
163       content::GetUIThreadTaskRunner({}));
164 }
165
166 void ChromeBrowserMainPartsPosix::ShowMissingLocaleMessageBox() {
167 #if defined(OS_CHROMEOS)
168   NOTREACHED();  // Should not ever happen on ChromeOS.
169 #elif defined(OS_MACOSX)
170   // Not called on Mac because we load the locale files differently.
171   NOTREACHED();
172 #elif defined(USE_AURA)
173   // TODO(port): We may want a views based message dialog here eventually, but
174   // for now, crash.
175   NOTREACHED();
176 #else
177 #error "Need MessageBox implementation."
178 #endif
179 }