Commit f2aaf05e authored by nona@chromium.org's avatar nona@chromium.org

Remove PendingCreateICRequest.

PendingCreateICRequest is no longer necessary because the libibus dependent code is gone, just state flag is fine.
In addition to this, PendingCreateICRequest cause memory leak if the response from ibus-daemon is lost.

BUG=134717,135049
TEST=ran ui_unittests and manually check on lumpy.

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@150517 0039d316-1c4b-4281-b951-d872f2087c98
parent e41777ab
...@@ -38,6 +38,7 @@ namespace { ...@@ -38,6 +38,7 @@ namespace {
const int kIBusReleaseMask = 1 << 30; const int kIBusReleaseMask = 1 << 30;
const char kClientName[] = "chrome"; const char kClientName[] = "chrome";
const int kMaxRetryCount = 10;
// Following capability mask is introduced from // Following capability mask is introduced from
// http://ibus.googlecode.com/svn/docs/ibus-1.4/ibus-ibustypes.html#IBusCapabilite // http://ibus.googlecode.com/svn/docs/ibus-1.4/ibus-ibustypes.html#IBusCapabilite
...@@ -162,69 +163,12 @@ void InputMethodIBus::PendingKeyEvent::ProcessPostIME(bool handled) { ...@@ -162,69 +163,12 @@ void InputMethodIBus::PendingKeyEvent::ProcessPostIME(bool handled) {
// and 'unmodified_character_' to support i18n VKs like a French VK! // and 'unmodified_character_' to support i18n VKs like a French VK!
} }
// A class to hold information of a pending request for creating an ibus input
// context.
class InputMethodIBus::PendingCreateICRequest {
public:
PendingCreateICRequest(InputMethodIBus* input_method,
PendingCreateICRequest** request_ptr);
virtual ~PendingCreateICRequest();
// Set up signal handlers, or destroy object proxy if the input context is
// already abandoned.
void InitOrAbandonInputContext();
// Called if the create input context method call is failed.
void OnCreateInputContextFailed();
// Abandon this pending key event. Its result will just be discarded.
void Abandon() {
input_method_ = NULL;
request_ptr_ = NULL;
// Do not reset |ibus_client_| here.
}
private:
InputMethodIBus* input_method_;
PendingCreateICRequest** request_ptr_;
DISALLOW_COPY_AND_ASSIGN(PendingCreateICRequest);
};
InputMethodIBus::PendingCreateICRequest::PendingCreateICRequest(
InputMethodIBus* input_method,
PendingCreateICRequest** request_ptr)
: input_method_(input_method),
request_ptr_(request_ptr) {
}
InputMethodIBus::PendingCreateICRequest::~PendingCreateICRequest() {
if (request_ptr_) {
DCHECK_EQ(*request_ptr_, this);
*request_ptr_ = NULL;
}
}
void InputMethodIBus::PendingCreateICRequest::OnCreateInputContextFailed() {
// TODO(nona): If the connection between Chrome and ibus-daemon terminates
// for some reason, the create ic request will fail. We might want to call
// ibus_client_->CreateContext() again after some delay.
}
void InputMethodIBus::PendingCreateICRequest::InitOrAbandonInputContext() {
if (input_method_) {
DCHECK(input_method_->IsContextReady());
input_method_->SetUpSignalHandlers();
} else {
GetInputContextClient()->ResetObjectProxy();
}
}
// InputMethodIBus implementation ----------------------------------------- // InputMethodIBus implementation -----------------------------------------
InputMethodIBus::InputMethodIBus( InputMethodIBus::InputMethodIBus(
internal::InputMethodDelegate* delegate) internal::InputMethodDelegate* delegate)
: ibus_client_(new internal::IBusClient), : ibus_client_(new internal::IBusClient),
pending_create_ic_request_(NULL), input_context_state_(INPUT_CONTEXT_STOP),
create_input_context_fail_count_(0),
context_focused_(false), context_focused_(false),
composing_text_(false), composing_text_(false),
composition_changed_(false), composition_changed_(false),
...@@ -423,20 +367,23 @@ void InputMethodIBus::OnDidChangeFocusedClient(TextInputClient* focused_before, ...@@ -423,20 +367,23 @@ void InputMethodIBus::OnDidChangeFocusedClient(TextInputClient* focused_before,
void InputMethodIBus::CreateContext() { void InputMethodIBus::CreateContext() {
DCHECK(IsConnected()); DCHECK(IsConnected());
DCHECK(!pending_create_ic_request_);
pending_create_ic_request_ = new PendingCreateICRequest( if (input_context_state_ != INPUT_CONTEXT_STOP) {
this, &pending_create_ic_request_); DVLOG(1) << "Input context is already created or waiting ibus-daemon"
" response.";
return;
}
input_context_state_ = INPUT_CONTEXT_WAIT_CREATE_INPUT_CONTEXT_RESPONSE;
// Creates the input context asynchronously. // Creates the input context asynchronously.
DCHECK(!IsContextReady());
chromeos::DBusThreadManager::Get()->GetIBusClient()->CreateInputContext( chromeos::DBusThreadManager::Get()->GetIBusClient()->CreateInputContext(
kClientName, kClientName,
base::Bind(&InputMethodIBus::CreateInputContextDone, base::Bind(&InputMethodIBus::CreateInputContextDone,
weak_ptr_factory_.GetWeakPtr(), weak_ptr_factory_.GetWeakPtr()),
base::Unretained(pending_create_ic_request_)),
base::Bind(&InputMethodIBus::CreateInputContextFail, base::Bind(&InputMethodIBus::CreateInputContextFail,
weak_ptr_factory_.GetWeakPtr(), weak_ptr_factory_.GetWeakPtr()));
base::Unretained(pending_create_ic_request_)));
} }
void InputMethodIBus::SetUpSignalHandlers() { void InputMethodIBus::SetUpSignalHandlers() {
...@@ -478,13 +425,9 @@ void InputMethodIBus::SetUpSignalHandlers() { ...@@ -478,13 +425,9 @@ void InputMethodIBus::SetUpSignalHandlers() {
} }
void InputMethodIBus::DestroyContext() { void InputMethodIBus::DestroyContext() {
if (pending_create_ic_request_) { if (input_context_state_ == INPUT_CONTEXT_STOP)
DCHECK(!IsContextReady());
// |pending_create_ic_request_| will be deleted in CreateInputContextDone().
pending_create_ic_request_->Abandon();
pending_create_ic_request_ = NULL;
return; return;
} input_context_state_ = INPUT_CONTEXT_STOP;
const chromeos::IBusInputContextClient* input_context = const chromeos::IBusInputContextClient* input_context =
chromeos::DBusThreadManager::Get()->GetIBusInputContextClient(); chromeos::DBusThreadManager::Get()->GetIBusInputContextClient();
if (input_context && input_context->IsObjectProxyReady()) { if (input_context && input_context->IsObjectProxyReady()) {
...@@ -906,19 +849,46 @@ void InputMethodIBus::ResetInputContext() { ...@@ -906,19 +849,46 @@ void InputMethodIBus::ResetInputContext() {
} }
void InputMethodIBus::CreateInputContextDone( void InputMethodIBus::CreateInputContextDone(
PendingCreateICRequest* ic_request,
const dbus::ObjectPath& object_path) { const dbus::ObjectPath& object_path) {
DCHECK_NE(INPUT_CONTEXT_RUNNING, input_context_state_);
if (input_context_state_ == INPUT_CONTEXT_STOP) {
// DestroyContext has already been called.
return;
}
chromeos::DBusThreadManager::Get()->GetIBusInputContextClient() chromeos::DBusThreadManager::Get()->GetIBusInputContextClient()
->Initialize(chromeos::DBusThreadManager::Get()->GetIBusBus(), ->Initialize(chromeos::DBusThreadManager::Get()->GetIBusBus(),
object_path); object_path);
ic_request->InitOrAbandonInputContext();
delete ic_request; input_context_state_ = INPUT_CONTEXT_RUNNING;
DCHECK(IsContextReady());
SetUpSignalHandlers();
} }
void InputMethodIBus::CreateInputContextFail( void InputMethodIBus::CreateInputContextFail() {
PendingCreateICRequest* ic_request) { DCHECK_NE(INPUT_CONTEXT_RUNNING, input_context_state_);
ic_request->OnCreateInputContextFailed(); if (input_context_state_ == INPUT_CONTEXT_STOP) {
delete ic_request; // CreateInputContext failed but the input context is no longer
// necessary, thus do nothing.
return;
}
if (++create_input_context_fail_count_ >= kMaxRetryCount) {
DVLOG(1) << "CreateInputContext failed even tried "
<< kMaxRetryCount << " times, give up.";
create_input_context_fail_count_ = 0;
input_context_state_ = INPUT_CONTEXT_STOP;
return;
}
// Try CreateInputContext again.
chromeos::DBusThreadManager::Get()->GetIBusClient()->CreateInputContext(
kClientName,
base::Bind(&InputMethodIBus::CreateInputContextDone,
weak_ptr_factory_.GetWeakPtr()),
base::Bind(&InputMethodIBus::CreateInputContextFail,
weak_ptr_factory_.GetWeakPtr()));
} }
bool InputMethodIBus::IsConnected() { bool InputMethodIBus::IsConnected() {
......
...@@ -67,8 +67,16 @@ class UI_EXPORT InputMethodIBus : public InputMethodBase { ...@@ -67,8 +67,16 @@ class UI_EXPORT InputMethodIBus : public InputMethodBase {
CompositionText* out_composition) const; CompositionText* out_composition) const;
private: private:
enum InputContextState {
// The input context is not working.
INPUT_CONTEXT_STOP,
// The input context is waiting for CreateInputContext reply from
// ibus-daemon.
INPUT_CONTEXT_WAIT_CREATE_INPUT_CONTEXT_RESPONSE,
// The input context is working and ready to communicate with ibus-daemon.
INPUT_CONTEXT_RUNNING,
};
class PendingKeyEvent; class PendingKeyEvent;
class PendingCreateICRequest;
// Overridden from InputMethodBase: // Overridden from InputMethodBase:
virtual void OnWillChangeFocusedClient(TextInputClient* focused_before, virtual void OnWillChangeFocusedClient(TextInputClient* focused_before,
...@@ -160,9 +168,8 @@ class UI_EXPORT InputMethodIBus : public InputMethodBase { ...@@ -160,9 +168,8 @@ class UI_EXPORT InputMethodIBus : public InputMethodBase {
bool visible); bool visible);
void OnHidePreeditText(); void OnHidePreeditText();
void CreateInputContextDone(PendingCreateICRequest* ic_request, void CreateInputContextDone(const dbus::ObjectPath& object_path);
const dbus::ObjectPath& object_path); void CreateInputContextFail();
void CreateInputContextFail(PendingCreateICRequest* ic_request);
static void ProcessKeyEventDone(PendingKeyEvent* pending_key_event, static void ProcessKeyEventDone(PendingKeyEvent* pending_key_event,
bool is_handled); bool is_handled);
static void ProcessKeyEventFail(PendingKeyEvent* pending_key_event); static void ProcessKeyEventFail(PendingKeyEvent* pending_key_event);
...@@ -174,9 +181,11 @@ class UI_EXPORT InputMethodIBus : public InputMethodBase { ...@@ -174,9 +181,11 @@ class UI_EXPORT InputMethodIBus : public InputMethodBase {
// They will be deleted in ProcessKeyEventDone(). // They will be deleted in ProcessKeyEventDone().
std::set<PendingKeyEvent*> pending_key_events_; std::set<PendingKeyEvent*> pending_key_events_;
// The pending request for creating the input context. We need to keep this // Represents input context's state.
// pointer so that we can receive or abandon the result. InputContextState input_context_state_;
PendingCreateICRequest* pending_create_ic_request_;
// The count of CreateInputContext message failure.
int create_input_context_fail_count_;
// Pending composition text generated by the current pending key event. // Pending composition text generated by the current pending key event.
// It'll be sent to the focused text input client as soon as we receive the // It'll be sent to the focused text input client as soon as we receive the
......
This diff is collapsed.
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