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
|
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/first_run.h"
#include "chrome/app/breakpad_linux.h"
// We need to reach through the browser process to tweak the metrics flag.
#include "chrome/browser/browser_process.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"
#include "chrome/installer/util/google_update_settings.h"
#include "base/message_loop.h"
namespace {
// Callback for the "response" signal of the first run dialog.
// Fills in the int* |data| with the dialog response and quits the message loop.
// See the TODO below for why this is necessary (it's a bug).
void DialogResponseCallback(GtkDialog* dialog, gint response,
gpointer data) {
int* response_out = static_cast<int*>(data);
*response_out = response;
MessageLoop::current()->Quit();
}
} // namespace
void OpenFirstRunDialog(Profile* profile, ProcessSingleton* process_singleton) {
#if defined(GOOGLE_CHROME_BUILD)
GtkWidget* dialog = gtk_dialog_new_with_buttons(
"Google Chrome Alpha",
NULL, // No parent
(GtkDialogFlags) (GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR),
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
NULL);
gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
g_signal_connect(G_OBJECT(dialog), "delete-event",
G_CALLBACK(gtk_widget_hide_on_delete), NULL);
GtkWidget* content_area = GTK_DIALOG(dialog)->vbox;
gtk_box_set_spacing(GTK_BOX(content_area), 18);
GtkWidget* vbox = gtk_vbox_new(FALSE, 12);
// Force a size on the vbox so the labels wrap.
gtk_widget_set_size_request(vbox, 400, -1);
GtkWidget* intro_label = gtk_label_new(
"This dialog would normally prompt you to import information from other "
"browsers, but that is not yet fully implemented.\n\n"
"Instead, we have only one important setting available: Crash dumps. "
"We cannot fix your crashes without your crash reports, so there's "
"little reason to run a dev channel build without turning them on.");
gtk_misc_set_alignment(GTK_MISC(intro_label), 0, 0);
gtk_label_set_line_wrap(GTK_LABEL(intro_label), TRUE);
gtk_box_pack_start(GTK_BOX(vbox), intro_label, FALSE, FALSE, 0);
GtkWidget* check = gtk_check_button_new();
GtkWidget* check_label = gtk_label_new(NULL);
gtk_label_set_markup(GTK_LABEL(check_label),
"<b>Optional:</b> Help make Google Chrome better by "
"automatically sending crash reports (and eventually "
"usage statistics, but that is also unimplemented) "
"to Google.");
gtk_label_set_line_wrap(GTK_LABEL(check_label), TRUE);
gtk_container_add(GTK_CONTAINER(check), check_label);
gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
#define UTF8_BULLET " \xE2\x80\xA2 "
GtkWidget* crashinfo_label = gtk_label_new(NULL);
gtk_label_set_markup(GTK_LABEL(crashinfo_label),
"A crash dump contains:\n"
UTF8_BULLET "Stacks and registers of all the threads in the crashing "
"process\n"
UTF8_BULLET "The current URL if a render process crashes\n"
UTF8_BULLET "<tt>/proc/cpuinfo</tt>, <tt>/etc/lsb-release</tt>\n"
UTF8_BULLET "Other misc information about the process (its "
"<tt>/proc/pid/maps</tt>, <tt>/proc/pid/status</tt>, etc.)");
gtk_misc_set_alignment(GTK_MISC(crashinfo_label), 0, 0);
gtk_label_set_line_wrap(GTK_LABEL(crashinfo_label), TRUE);
gtk_box_pack_start(GTK_BOX(vbox), crashinfo_label, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(content_area), vbox, FALSE, FALSE, 0);
gtk_widget_show_all(vbox);
// TODO(port): it should be sufficient to just run the dialog:
// int response = gtk_dialog_run(GTK_DIALOG(dialog));
// but that spins a nested message loop and hoses us. :(
// http://code.google.com/p/chromium/issues/detail?id=12552
// Instead, run a loop and extract the response manually.
int response = 0;
g_signal_connect(G_OBJECT(dialog), "response",
G_CALLBACK(DialogResponseCallback), &response);
gtk_widget_show(dialog);
MessageLoop::current()->Run();
// End of above TODO.
if (response == GTK_RESPONSE_ACCEPT) {
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check))) {
// They opted in.
if (GoogleUpdateSettings::SetCollectStatsConsent(true)) {
InitCrashReporter();
}
} else {
GoogleUpdateSettings::SetCollectStatsConsent(false);
}
}
gtk_widget_destroy(dialog);
#endif // defined(GOOGLE_CHROME_BUILD)
// Mark that first run has ran.
FirstRun::CreateSentinel();
}
|