Commit f0d3bf17 authored by kuchhal@chromium.org's avatar kuchhal@chromium.org

Linux: Add "set chrome as default" and "import profile data" option to First...

Linux: Add "set chrome as default" and "import profile data" option to First Run UI. Also enable it for Chromium builds.

Review URL: http://codereview.chromium.org/149348

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@20212 0039d316-1c4b-4281-b951-d872f2087c98
parent 12f3ede0
...@@ -386,30 +386,6 @@ int BrowserMain(const MainFunctionParams& parameters) { ...@@ -386,30 +386,6 @@ int BrowserMain(const MainFunctionParams& parameters) {
#endif #endif
#if defined(OS_POSIX)
// On Mac OS X / Linux we display the first run dialog as early as possible,
// so we can get the stats enabled.
// TODO(port):
// We check the kNoFirstRun command line switch explicitly here since the
// early placement of this block happens before that's factored into
// first_run_ui_bypass, we probably want to move that block up
// and remove the explicit check from here in the long run.
if (is_first_run && !first_run_ui_bypass &&
!parsed_command_line.HasSwitch(switches::kNoFirstRun)) {
// Dummy value, we don't need the profile for the OS X version of this
// method at present.
Profile* profile = NULL;
OpenFirstRunDialog(profile, &process_singleton);
#if defined(GOOGLE_CHROME_BUILD)
// If user cancelled the first run dialog box, the first run sentinel file
// didn't get created and we should exit Chrome.
if (FirstRun::IsChromeFirstRun())
return ResultCodes::NORMAL_EXIT;
#endif
}
#endif // OS_POSIX
// During first run we read the google_update registry key to find what // During first run we read the google_update registry key to find what
// language the user selected when downloading the installer. This // language the user selected when downloading the installer. This
// becomes our default language in the prefs. // becomes our default language in the prefs.
...@@ -612,12 +588,6 @@ int BrowserMain(const MainFunctionParams& parameters) { ...@@ -612,12 +588,6 @@ int BrowserMain(const MainFunctionParams& parameters) {
process_singleton.Create(); process_singleton.Create();
// TODO(port): This block of code should probably be used on all platforms!
// On Mac OS X / Linux we display this dialog before setting the value of
// kMetricsReportingEnabled, so we display this dialog much earlier.
// On Windows a download is tagged with stats enabled/disabled so the UI
// can be displayed later in the startup process.
#if !defined(OS_POSIX)
// Show the First Run UI if this is the first time Chrome has been run on // Show the First Run UI if this is the first time Chrome has been run on
// this computer, or we're being compelled to do so by a command line flag. // this computer, or we're being compelled to do so by a command line flag.
// Note that this be done _after_ the PrefService is initialized and all // Note that this be done _after_ the PrefService is initialized and all
...@@ -626,10 +596,10 @@ int BrowserMain(const MainFunctionParams& parameters) { ...@@ -626,10 +596,10 @@ int BrowserMain(const MainFunctionParams& parameters) {
if (is_first_run && !first_run_ui_bypass) { if (is_first_run && !first_run_ui_bypass) {
if (!OpenFirstRunDialog(profile, &process_singleton)) { if (!OpenFirstRunDialog(profile, &process_singleton)) {
// The user cancelled the first run dialog box, we should exit Chrome. // The user cancelled the first run dialog box, we should exit Chrome.
return ResultCodes::NORMAL_EXIT; return ResultCodes::NORMAL_EXIT;
} }
} }
#endif // OS_POSIX
// Sets things up so that if we crash from this point on, a dialog will // Sets things up so that if we crash from this point on, a dialog will
// popup asking the user to restart chrome. It is done this late to avoid // popup asking the user to restart chrome. It is done this late to avoid
......
// Copyright (c) 2009 The Chromium Authors. All rights reserved. // Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "chrome/browser/first_run.h" #include "chrome/browser/first_run.h"
#include "chrome/app/breakpad_linux.h" #include "chrome/browser/gtk/first_run_dialog.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
bool OpenFirstRunDialog(Profile* profile, ProcessSingleton* process_singleton) { bool OpenFirstRunDialog(Profile* profile, ProcessSingleton* process_singleton) {
#if defined(GOOGLE_CHROME_BUILD) // TODO(port): Use process_singleton to make sure Chrome can not be started
GtkWidget* dialog = gtk_dialog_new_with_buttons( // while this process is active.
"Google Chrome Dev Build", return FirstRunDialog::Show(profile);
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* privacy_label = gtk_label_new(
"This version of Google Chrome for Linux is not appropriate for "
"general consumer use. Certain privacy features are unavailable "
"at this time as described in our privacy policy at");
gtk_misc_set_alignment(GTK_MISC(privacy_label), 0, 0);
gtk_label_set_line_wrap(GTK_LABEL(privacy_label), TRUE);
gtk_box_pack_start(GTK_BOX(vbox), privacy_label, FALSE, FALSE, 0);
GtkWidget* url_label = gtk_label_new(NULL);
gtk_label_set_markup(GTK_LABEL(url_label),
"<tt>http://www.google.com/chrome/intl/en/privacy_linux.html</tt>");
// Set selectable to allow copy and paste.
gtk_label_set_selectable(GTK_LABEL(url_label), TRUE);
gtk_box_pack_start(GTK_BOX(vbox), url_label, FALSE, FALSE, 0);
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"
"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.
bool accepted = (response == GTK_RESPONSE_ACCEPT);
if (accepted) {
// Mark that first run has ran.
FirstRun::CreateSentinel();
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);
return accepted;
#else // defined(GOOGLE_CHROME_BUILD)
FirstRun::CreateSentinel();
return true;
#endif
} }
// 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/gtk/first_run_dialog.h"
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/message_loop.h"
#include "chrome/app/breakpad_linux.h"
#include "chrome/browser/shell_integration.h"
#include "chrome/common/gtk_util.h"
#include "chrome/installer/util/google_update_settings.h"
#include "grit/generated_resources.h"
#include "grit/google_chrome_strings.h"
// static
bool FirstRunDialog::Show(Profile* profile) {
int response = -1;
new FirstRunDialog(profile, response);
return (response == GTK_RESPONSE_ACCEPT);
}
FirstRunDialog::FirstRunDialog(Profile* profile, int& response)
: dialog_(NULL), report_crashes_(NULL), make_default_(NULL),
import_data_(NULL), import_profile_(NULL), profile_(profile),
response_(response), importer_host_(new ImporterHost()) {
dialog_ = gtk_dialog_new_with_buttons(
l10n_util::GetStringUTF8(IDS_FIRSTRUN_DLG_TITLE).c_str(),
NULL, // No parent
(GtkDialogFlags) (GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR),
l10n_util::GetStringUTF8(IDS_FIRSTRUN_DLG_OK).c_str(),
GTK_RESPONSE_ACCEPT,
l10n_util::GetStringUTF8(IDS_FIRSTRUN_DLG_CANCEL).c_str(),
GTK_RESPONSE_REJECT,
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, 350, -1);
#if defined(GOOGLE_CHROME_BUILD)
// TODO(port): remove this warning before beta release when we have all the
// privacy features working.
GtkWidget* privacy_label = gtk_label_new(
"This version of Google Chrome for Linux is not appropriate for "
"general consumer use. Certain privacy features are unavailable "
"at this time as described in our privacy policy at");
gtk_misc_set_alignment(GTK_MISC(privacy_label), 0, 0);
gtk_label_set_line_wrap(GTK_LABEL(privacy_label), TRUE);
gtk_box_pack_start(GTK_BOX(vbox), privacy_label, FALSE, FALSE, 0);
GtkWidget* url_label = gtk_label_new(NULL);
gtk_label_set_markup(GTK_LABEL(url_label),
"<tt>http://www.google.com/chrome/intl/en/privacy_linux.html</tt>");
// Set selectable to allow copy and paste.
gtk_label_set_selectable(GTK_LABEL(url_label), TRUE);
gtk_box_pack_start(GTK_BOX(vbox), url_label, FALSE, FALSE, 0);
report_crashes_ = gtk_check_button_new();
GtkWidget* check_label = gtk_label_new(
l10n_util::GetStringUTF8(IDS_OPTIONS_ENABLE_LOGGING).c_str());
gtk_label_set_line_wrap(GTK_LABEL(check_label), TRUE);
gtk_container_add(GTK_CONTAINER(report_crashes_), check_label);
gtk_box_pack_start(GTK_BOX(vbox), report_crashes_, FALSE, FALSE, 0);
#endif
make_default_ = gtk_check_button_new_with_label(
l10n_util::GetStringUTF8(IDS_FR_CUSTOMIZE_DEFAULT_BROWSER).c_str());
gtk_box_pack_start(GTK_BOX(vbox), make_default_, FALSE, FALSE, 0);
GtkWidget* combo_hbox = gtk_hbox_new(FALSE, gtk_util::kLabelSpacing);
import_data_ = gtk_check_button_new_with_label(
l10n_util::GetStringUTF8(IDS_FR_CUSTOMIZE_IMPORT).c_str());
gtk_box_pack_start(GTK_BOX(combo_hbox), import_data_, FALSE, FALSE, 0);
import_profile_ = gtk_combo_box_new_text();
gtk_box_pack_start(GTK_BOX(combo_hbox), import_profile_, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(vbox), combo_hbox, FALSE, FALSE, 0);
// Detect any supported browsers that we can import from and fill
// up the combo box. If none found, disable import data checkbox.
int profiles_count = importer_host_->GetAvailableProfileCount();
if (profiles_count > 0) {
for (int i = 0; i < profiles_count; i++) {
std::wstring profile = importer_host_->GetSourceProfileNameAt(i);
gtk_combo_box_append_text(GTK_COMBO_BOX(import_profile_),
WideToUTF8(profile).c_str());
}
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(import_data_), TRUE);
gtk_combo_box_set_active(GTK_COMBO_BOX(import_profile_), 0);
} else {
gtk_combo_box_append_text(GTK_COMBO_BOX(import_profile_),
l10n_util::GetStringUTF8(IDS_IMPORT_NO_PROFILE_FOUND).c_str());
gtk_combo_box_set_active(GTK_COMBO_BOX(import_profile_), 0);
gtk_widget_set_sensitive(import_data_, FALSE);
gtk_widget_set_sensitive(import_profile_, FALSE);
}
gtk_box_pack_start(GTK_BOX(content_area), vbox, FALSE, FALSE, 0);
// 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.
g_signal_connect(G_OBJECT(dialog_), "response",
G_CALLBACK(HandleOnResponseDialog), this);
gtk_widget_show_all(dialog_);
MessageLoop::current()->Run();
}
void FirstRunDialog::OnDialogResponse(GtkWidget* widget, int response) {
gtk_widget_hide_all(dialog_);
response_ = response;
if (response == GTK_RESPONSE_ACCEPT) {
// Mark that first run has ran.
FirstRun::CreateSentinel();
// Check if user has opted into reporting.
if (report_crashes_ &&
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(report_crashes_))) {
if (GoogleUpdateSettings::SetCollectStatsConsent(true))
InitCrashReporter();
} else {
GoogleUpdateSettings::SetCollectStatsConsent(false);
}
// If selected set as default browser.
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(make_default_)))
ShellIntegration::SetAsDefaultBrowser();
// Import data if selected.
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(import_data_))) {
const ProfileInfo& source_profile =
importer_host_->GetSourceProfileInfoAt(
gtk_combo_box_get_active(GTK_COMBO_BOX(import_profile_)));
int items = SEARCH_ENGINES + HISTORY + FAVORITES + HOME_PAGE + PASSWORDS;
// TODO(port): Call StartImportingWithUI here instead and launch
// a new process that does the actual import.
importer_host_->StartImportSettings(source_profile, profile_, items,
new ProfileWriter(profile_), true);
}
}
gtk_widget_destroy(dialog_);
MessageLoop::current()->Quit();
}
// 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.
#ifndef CHROME_BROWSER_GTK_FIRST_RUN_DIALOG_H_
#define CHROME_BROWSER_GTK_FIRST_RUN_DIALOG_H_
#include "chrome/browser/first_run.h"
#include "chrome/browser/importer/importer.h"
class FirstRunDialog {
public:
// Displays the first run UI for reporting opt-in, import data etc.
static bool Show(Profile* profile);
private:
FirstRunDialog(Profile* profile, int& response);
~FirstRunDialog() { }
static void HandleOnResponseDialog(GtkWidget* widget,
int response,
FirstRunDialog* user_data) {
user_data->OnDialogResponse(widget, response);
}
void OnDialogResponse(GtkWidget* widget, int response);
// First Run UI Dialog
GtkWidget* dialog_;
// Crash reporting checkbox
GtkWidget* report_crashes_;
// Make browser default checkbox
GtkWidget* make_default_;
// Import data checkbox
GtkWidget* import_data_;
// Combo box that displays list of profiles from which we can import.
GtkWidget* import_profile_;
// Our current profile
Profile* profile_;
// User response (accept or cancel) is returned through this.
int& response_;
// Utility class that does the actual import.
scoped_refptr<ImporterHost> importer_host_;
DISALLOW_COPY_AND_ASSIGN(FirstRunDialog);
};
#endif // CHROME_BROWSER_GTK_FIRST_RUN_DIALOG_H_
...@@ -1013,6 +1013,8 @@ ...@@ -1013,6 +1013,8 @@
'browser/gtk/download_started_animation_gtk.cc', 'browser/gtk/download_started_animation_gtk.cc',
'browser/gtk/edit_search_engine_dialog.cc', 'browser/gtk/edit_search_engine_dialog.cc',
'browser/gtk/edit_search_engine_dialog.h', 'browser/gtk/edit_search_engine_dialog.h',
'browser/gtk/first_run_dialog.cc',
'browser/gtk/first_run_dialog.h',
'browser/gtk/go_button_gtk.cc', 'browser/gtk/go_button_gtk.cc',
'browser/gtk/go_button_gtk.h', 'browser/gtk/go_button_gtk.h',
'browser/gtk/gtk_chrome_button.cc', 'browser/gtk/gtk_chrome_button.cc',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment