Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / mandoline / app / desktop / launcher_process.cc
blob95e876b8fe4d2388dd0b1b486c373fbf75293fae
1 // Copyright 2015 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.
5 #include <stdio.h>
6 #include <string.h>
8 #include <algorithm>
9 #include <iostream>
11 #include "base/base_switches.h"
12 #include "base/bind.h"
13 #include "base/command_line.h"
14 #include "base/files/file_util.h"
15 #include "base/message_loop/message_loop.h"
16 #include "base/synchronization/waitable_event.h"
17 #include "base/trace_event/trace_event.h"
18 #include "components/tracing/startup_tracing.h"
19 #include "mandoline/app/core_services_initialization.h"
20 #include "mandoline/app/desktop/launcher_process.h"
21 #include "mojo/runner/context.h"
22 #include "mojo/runner/switches.h"
24 namespace mandoline {
25 namespace {
27 // Whether we're currently tracing.
28 bool g_tracing = false;
30 // Number of tracing blocks written.
31 uint32_t g_blocks = 0;
33 // Trace file, if open.
34 FILE* g_trace_file = nullptr;
36 void WriteTraceDataCollected(
37 base::WaitableEvent* event,
38 const scoped_refptr<base::RefCountedString>& events_str,
39 bool has_more_events) {
40 if (g_blocks) {
41 fwrite(",", 1, 1, g_trace_file);
44 ++g_blocks;
45 fwrite(events_str->data().c_str(), 1, events_str->data().length(),
46 g_trace_file);
47 if (!has_more_events) {
48 static const char kEnd[] = "]}";
49 fwrite(kEnd, 1, strlen(kEnd), g_trace_file);
50 PCHECK(fclose(g_trace_file) == 0);
51 g_trace_file = nullptr;
52 event->Signal();
56 void EndTraceAndFlush(base::WaitableEvent* event) {
57 g_trace_file = fopen("mojo_shell.trace", "w+");
58 PCHECK(g_trace_file);
59 static const char kStart[] = "{\"traceEvents\":[";
60 fwrite(kStart, 1, strlen(kStart), g_trace_file);
61 base::trace_event::TraceLog::GetInstance()->SetDisabled();
62 base::trace_event::TraceLog::GetInstance()->Flush(
63 base::Bind(&WriteTraceDataCollected, base::Unretained(event)));
66 void StopTracingAndFlushToDisk() {
67 g_tracing = false;
68 base::trace_event::TraceLog::GetInstance()->SetDisabled();
69 base::WaitableEvent flush_complete_event(false, false);
70 // TraceLog::Flush requires a message loop but we've already shut ours down.
71 // Spin up a new thread to flush things out.
72 base::Thread flush_thread("mojo_shell_trace_event_flush");
73 flush_thread.Start();
74 flush_thread.message_loop()->PostTask(
75 FROM_HERE,
76 base::Bind(EndTraceAndFlush, base::Unretained(&flush_complete_event)));
77 flush_complete_event.Wait();
80 } // namespace
82 int LauncherProcessMain(int argc, char** argv) {
83 const base::CommandLine& command_line =
84 *base::CommandLine::ForCurrentProcess();
85 if (command_line.HasSwitch(switches::kTraceStartup)) {
86 g_tracing = true;
87 base::trace_event::TraceConfig trace_config(
88 command_line.GetSwitchValueASCII(switches::kTraceStartup),
89 base::trace_event::RECORD_UNTIL_FULL);
90 base::trace_event::TraceLog::GetInstance()->SetEnabled(
91 trace_config, base::trace_event::TraceLog::RECORDING_MODE);
92 } else {
93 // |g_tracing| is not touched in this case and Telemetry will stop tracing
94 // on demand later.
95 tracing::EnableStartupTracingIfConfigFileExists();
98 // We want the runner::Context to outlive the MessageLoop so that pipes are
99 // all gracefully closed / error-out before we try to shut the Context down.
100 mojo::runner::Context shell_context;
101 InitCoreServicesForContext(&shell_context);
103 base::MessageLoop message_loop;
104 if (!shell_context.Init()) {
105 return 0;
107 if (g_tracing) {
108 message_loop.PostDelayedTask(FROM_HERE,
109 base::Bind(StopTracingAndFlushToDisk),
110 base::TimeDelta::FromSeconds(5));
113 message_loop.PostTask(FROM_HERE,
114 base::Bind(&mojo::runner::Context::Run,
115 base::Unretained(&shell_context),
116 GURL("mojo:browser")));
117 message_loop.Run();
119 // Must be called before |message_loop| is destroyed.
120 shell_context.Shutdown();
123 if (g_tracing)
124 StopTracingAndFlushToDisk();
125 return 0;
128 } // namespace mandoline