Commit 1525185a authored by palmer@chromium.org's avatar palmer@chromium.org

Improve the UI for handling profile lock contention.

Linux/GTK only.

BUG=282509
TEST=ln -s fake.com-123 SingletonLock, then run Chromium, then check that [ Quit ] and [ Unlock and Relaunch ] work.

Review URL: https://chromiumcodereview.appspot.com/23506011

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@222159 0039d316-1c4b-4281-b951-d872f2087c98
parent b6eb8e33
......@@ -1051,6 +1051,15 @@ Signing in anyway will merge Chromium information like bookmarks, history, and o
<message name="IDS_MEDIA_STREAM_STATUS_TRAY_TEXT_VIDEO_ONLY" desc="Tool tip for the capture status tray icon when camera is being used">
Chromium is using your camera.
</message>
<!-- ProcessSingleton -->
<message name="IDS_PROFILE_IN_USE_LINUX" desc="Message shown when the browser cannot start because the profile is in use on a different host.">
The profile appears to be in use by another Chromium process (<ph name="PROCESS_ID">$1<ex>12345</ex></ph>) on another computer (<ph name="HOST_NAME">$2<ex>example.com</ex></ph>). Chromium has locked the profile so that it doesn't get corrupted. If you are sure no other processes are using this profile, you can unlock the profile and relaunch Chromium.
</message>
<message name="IDS_PROFILE_IN_USE_LINUX_RELAUNCH" desc="Text of button in dialog to delete the profile lock file.">
Unlock Profile and Relaunch
</message>
</messages>
</release>
</grit>
......@@ -13784,11 +13784,6 @@ Some features may be unavailable. Please check that the profile exists and you
Would you like to save this password?
</message>
<!-- ProcessSingleton -->
<message name="IDS_PROFILE_IN_USE_LINUX" desc="Message shown when the browser cannot start because the profile is in use on a different host.">
The profile appears to be in use by process <ph name="PROCESS_ID">$1<ex>12345</ex></ph> on host <ph name="HOST_NAME">$2<ex>example.com</ex></ph>. If you are sure no other processes are using this profile, delete the file <ph name="LOCK_FILE">$3<ex>/home/user/.config/google-chrome/SingletonLock</ex></ph> and relaunch <ph name="PRODUCT_NAME">$4<ex>Google Chrome</ex></ph>.
</message>
<!-- Update Recommended dialog -->
<if expr="not pp_ifdef('chromeos')">
<message name="IDS_UPDATE_RECOMMENDED" desc="The main text of the Update Recommended dialog.">
......
......@@ -975,6 +975,15 @@ Signing in anyway will merge Chrome information like bookmarks, history, and oth
<message name="IDS_MEDIA_STREAM_STATUS_TRAY_TEXT_VIDEO_ONLY" desc="Tool tip for the capture status tray icon when camera is being used">
Google Chrome is using your camera.
</message>
<!-- ProcessSingleton -->
<message name="IDS_PROFILE_IN_USE_LINUX" desc="Message shown when the browser cannot start because the profile is in use on a different host.">
The profile appears to be in use by another Google Chrome process (<ph name="PROCESS_ID">$1<ex>12345</ex></ph>) on another computer (<ph name="HOST_NAME">$2<ex>example.com</ex></ph>). Chrome has locked the profile so that it doesn't get corrupted. If you are sure no other processes are using this profile, you can unlock the profile and relaunch Chrome.
</message>
<message name="IDS_PROFILE_IN_USE_LINUX_RELAUNCH" desc="Text of button in dialog to delete the profile lock file.">
Unlock Profile and Relaunch
</message>
</messages>
</release>
</grit>
......@@ -294,23 +294,28 @@ bool ParseLockPath(const base::FilePath& path,
return true;
}
void DisplayProfileInUseError(const std::string& lock_path,
// Returns true if the user opted to unlock the profile.
bool DisplayProfileInUseError(const base::FilePath& lock_path,
const std::string& hostname,
int pid) {
string16 error = l10n_util::GetStringFUTF16(
IDS_PROFILE_IN_USE_LINUX,
base::IntToString16(pid),
ASCIIToUTF16(hostname),
WideToUTF16(base::SysNativeMBToWide(lock_path)),
l10n_util::GetStringUTF16(IDS_PRODUCT_NAME));
string16 relaunch_button_text = l10n_util::GetStringFUTF16(
IDS_PROFILE_IN_USE_LINUX_RELAUNCH,
string16());
LOG(ERROR) << base::SysWideToNativeMB(UTF16ToWide(error)).c_str();
if (!g_disable_prompt) {
#if defined(TOOLKIT_GTK)
ProcessSingletonDialog::ShowAndRun(UTF16ToUTF8(error));
return ProcessSingletonDialog::ShowAndRun(
UTF16ToUTF8(error), UTF16ToUTF8(relaunch_button_text));
#else
NOTIMPLEMENTED();
#endif
}
return false;
}
bool IsChromeProcess(pid_t pid) {
......@@ -734,9 +739,13 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout(
return PROCESS_NONE;
}
if (hostname != net::GetHostName()) {
// Locked by process on another host.
DisplayProfileInUseError(lock_path_.value(), hostname, pid);
if (hostname != net::GetHostName() && !IsChromeProcess(pid)) {
// Locked by process on another host. If the user selected to unlock
// the profile, try to continue; otherwise quit.
if (DisplayProfileInUseError(lock_path_, hostname, pid)) {
UnlinkPath(lock_path_);
return PROCESS_NONE;
}
return PROFILE_IN_USE;
}
......@@ -958,8 +967,7 @@ bool ProcessSingleton::KillProcessByLockPath() {
ParseLockPath(lock_path_, &hostname, &pid);
if (!hostname.empty() && hostname != net::GetHostName()) {
DisplayProfileInUseError(lock_path_.value(), hostname, pid);
return false;
return DisplayProfileInUseError(lock_path_, hostname, pid);
}
UnlinkPath(lock_path_);
......
......@@ -12,11 +12,15 @@
#include "ui/base/l10n/l10n_util.h"
// static
void ProcessSingletonDialog::ShowAndRun(const std::string& message) {
ProcessSingletonDialog dialog(message);
bool ProcessSingletonDialog::ShowAndRun(const std::string& message,
const std::string& relaunch_text) {
ProcessSingletonDialog dialog(message, relaunch_text);
return dialog.GetResponseId() == GTK_RESPONSE_ACCEPT;
}
ProcessSingletonDialog::ProcessSingletonDialog(const std::string& message) {
ProcessSingletonDialog::ProcessSingletonDialog(
const std::string& message,
const std::string& relaunch_text) {
dialog_ = gtk_message_dialog_new(
NULL,
static_cast<GtkDialogFlags>(0),
......@@ -29,6 +33,9 @@ ProcessSingletonDialog::ProcessSingletonDialog(const std::string& message) {
l10n_util::GetStringUTF8(IDS_PRODUCT_NAME).c_str());
gtk_dialog_add_button(GTK_DIALOG(dialog_), GTK_STOCK_QUIT,
GTK_RESPONSE_REJECT);
gtk_dialog_add_button(GTK_DIALOG(dialog_), relaunch_text.c_str(),
GTK_RESPONSE_ACCEPT);
gtk_dialog_set_default_response(GTK_DIALOG(dialog_), GTK_RESPONSE_ACCEPT);
g_signal_connect(dialog_, "response", G_CALLBACK(OnResponseThunk), this);
......@@ -37,6 +44,7 @@ ProcessSingletonDialog::ProcessSingletonDialog(const std::string& message) {
}
void ProcessSingletonDialog::OnResponse(GtkWidget* dialog, int response_id) {
response_id_ = response_id;
gtk_widget_destroy(dialog_);
base::MessageLoop::current()->Quit();
}
......@@ -8,6 +8,7 @@
#include <string>
#include "base/basictypes.h"
#include "base/files/file_path.h"
#include "ui/base/gtk/gtk_signal.h"
typedef struct _GtkWidget GtkWidget;
......@@ -18,14 +19,19 @@ typedef struct _GtkWidget GtkWidget;
class ProcessSingletonDialog {
public:
// Shows the dialog, and returns once the dialog has been closed.
static void ShowAndRun(const std::string& message);
static bool ShowAndRun(const std::string& message,
const std::string& relaunch_text);
int GetResponseId() const { return response_id_; }
private:
explicit ProcessSingletonDialog(const std::string& message);
ProcessSingletonDialog(const std::string& message,
const std::string& relaunch_text);
CHROMEGTK_CALLBACK_1(ProcessSingletonDialog, void, OnResponse, int);
GtkWidget* dialog_;
int response_id_;
DISALLOW_COPY_AND_ASSIGN(ProcessSingletonDialog);
};
......
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