| // Copyright 2010-2015, Google Inc. |
| // All rights reserved. |
| // |
| // Redistribution and use in source and binary forms, with or without |
| // modification, are permitted provided that the following conditions are |
| // met: |
| // |
| // * Redistributions of source code must retain the above copyright |
| // notice, this list of conditions and the following disclaimer. |
| // * Redistributions in binary form must reproduce the above |
| // copyright notice, this list of conditions and the following disclaimer |
| // in the documentation and/or other materials provided with the |
| // distribution. |
| // * Neither the name of Google Inc. nor the names of its |
| // contributors may be used to endorse or promote products derived from |
| // this software without specific prior written permission. |
| // |
| // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| #include "session/session_usage_observer.h" |
| |
| #include <string> |
| |
| #include "base/clock_mock.h" |
| #include "base/logging.h" |
| #include "base/scheduler.h" |
| #include "base/scheduler_stub.h" |
| #include "base/system_util.h" |
| #include "base/util.h" |
| #include "config/stats_config_util.h" |
| #include "config/stats_config_util_mock.h" |
| #include "session/commands.pb.h" |
| #include "testing/base/public/googletest.h" |
| #include "testing/base/public/gunit.h" |
| #include "usage_stats/usage_stats.h" |
| #include "usage_stats/usage_stats.pb.h" |
| #include "usage_stats/usage_stats_testing_util.h" |
| |
| using mozc::usage_stats::Stats; |
| using mozc::usage_stats::UsageStats; |
| |
| DECLARE_string(test_tmpdir); |
| |
| namespace mozc { |
| namespace session { |
| |
| class SessionUsageObserverTest : public testing::Test { |
| protected: |
| virtual void SetUp() { |
| SystemUtil::SetUserProfileDirectory(FLAGS_test_tmpdir); |
| UsageStats::ClearAllStatsForTest(); |
| |
| Util::SetClockHandler(NULL); |
| |
| scheduler_stub_.reset(new SchedulerStub); |
| Scheduler::SetSchedulerHandler(scheduler_stub_.get()); |
| |
| stats_config_util_mock_.reset(new config::StatsConfigUtilMock); |
| config::StatsConfigUtil::SetHandler(stats_config_util_mock_.get()); |
| } |
| |
| virtual void TearDown() { |
| Util::SetClockHandler(NULL); |
| Scheduler::SetSchedulerHandler(NULL); |
| config::StatsConfigUtil::SetHandler(NULL); |
| |
| UsageStats::ClearAllStatsForTest(); |
| } |
| |
| void EnsureSave() const { |
| // Make sure to save stats. |
| const uint32 kWaitngUsecForEnsureSave = 10 * 60 * 1000; |
| scheduler_stub_->PutClockForward(kWaitngUsecForEnsureSave); |
| } |
| |
| void SetDoubleValueStats( |
| uint32 num, double total, double square_total, |
| Stats::DoubleValueStats *double_stats) { |
| DCHECK(double_stats); |
| double_stats->set_num(num); |
| double_stats->set_total(total); |
| double_stats->set_square_total(square_total); |
| } |
| |
| void SetEventStats( |
| uint32 source_id, |
| uint32 sx_num, double sx_total, double sx_square_total, |
| uint32 sy_num, double sy_total, double sy_square_total, |
| uint32 dx_num, double dx_total, double dx_square_total, |
| uint32 dy_num, double dy_total, double dy_square_total, |
| uint32 tl_num, double tl_total, double tl_square_total, |
| Stats::TouchEventStats *event_stats) { |
| event_stats->set_source_id(source_id); |
| SetDoubleValueStats(sx_num, sx_total, sx_square_total, |
| event_stats->mutable_start_x_stats()); |
| SetDoubleValueStats(sy_num, sy_total, sy_square_total, |
| event_stats->mutable_start_y_stats()); |
| SetDoubleValueStats(dx_num, dx_total, dx_square_total, |
| event_stats->mutable_direction_x_stats()); |
| SetDoubleValueStats(dy_num, dy_total, dy_square_total, |
| event_stats->mutable_direction_y_stats()); |
| SetDoubleValueStats(tl_num, tl_total, tl_square_total, |
| event_stats->mutable_time_length_stats()); |
| } |
| |
| scoped_ptr<SchedulerStub> scheduler_stub_; |
| scoped_ptr<config::StatsConfigUtilMock> stats_config_util_mock_; |
| }; |
| |
| TEST_F(SessionUsageObserverTest, DoNotSaveWhenDeleted) { |
| stats_config_util_mock_->SetEnabled(false); |
| |
| scoped_ptr<SessionUsageObserver> observer(new SessionUsageObserver); |
| |
| // Add command |
| commands::Command command; |
| command.mutable_input()->set_type(commands::Input::NONE); |
| command.mutable_input()->set_id(0); |
| command.mutable_output()->set_consumed(true); |
| for (int i = 0; i < 5; ++i) { |
| observer->EvalCommandHandler(command); |
| EXPECT_STATS_NOT_EXIST("SessionAllEvent"); |
| } |
| |
| observer.reset(); |
| EXPECT_STATS_NOT_EXIST("SessionAllEvent"); |
| } |
| |
| TEST_F(SessionUsageObserverTest, ClientSideStatsInfolist) { |
| scoped_ptr<SessionUsageObserver> observer(new SessionUsageObserver); |
| |
| // create session |
| { |
| commands::Command command; |
| command.mutable_input()->set_type(commands::Input::CREATE_SESSION); |
| command.mutable_input()->set_id(1); |
| command.mutable_output()->set_id(1); |
| observer->EvalCommandHandler(command); |
| } |
| |
| const uint64 kSeconds = 0; |
| const uint32 kMicroSeconds = 0; |
| ClockMock clock(kSeconds, kMicroSeconds); |
| Util::SetClockHandler(&clock); |
| |
| // prepare command |
| commands::Command orig_show_command, orig_hide_command; |
| orig_show_command.mutable_input()->set_type(commands::Input::SEND_COMMAND); |
| orig_show_command.mutable_input()->set_id(1); |
| orig_show_command.mutable_input()->mutable_command()->set_type( |
| commands::SessionCommand::USAGE_STATS_EVENT); |
| orig_show_command.mutable_input()->mutable_command()->set_usage_stats_event( |
| commands::SessionCommand::INFOLIST_WINDOW_SHOW); |
| orig_show_command.mutable_output()->set_consumed(false); |
| EXPECT_TRUE(orig_show_command.output().has_consumed()); |
| EXPECT_FALSE(orig_show_command.output().consumed()); |
| EXPECT_TRUE(orig_show_command.input().has_id()); |
| orig_hide_command.CopyFrom(orig_show_command); |
| orig_hide_command.mutable_input()->mutable_command()->set_usage_stats_event( |
| commands::SessionCommand::INFOLIST_WINDOW_HIDE); |
| |
| { // show infolist, wait 1,100,000 usec and hide infolist. |
| commands::Command show_command, hide_command; |
| show_command.CopyFrom(orig_show_command); |
| hide_command.CopyFrom(orig_hide_command); |
| |
| observer->EvalCommandHandler(show_command); |
| EXPECT_STATS_NOT_EXIST("InfolistWindowDurationMSec"); |
| clock.PutClockForward(1, 100000); |
| observer->EvalCommandHandler(hide_command); |
| EXPECT_TIMING_STATS("InfolistWindowDurationMSec", 1100, 1, 1100, 1100); |
| } |
| |
| { // show infolist, wait 1,200,000 usec and hide infolist. |
| commands::Command show_command, hide_command; |
| show_command.CopyFrom(orig_show_command); |
| hide_command.CopyFrom(orig_hide_command); |
| |
| observer->EvalCommandHandler(show_command); |
| clock.PutClockForward(1, 200000); |
| observer->EvalCommandHandler(hide_command); |
| EXPECT_TIMING_STATS("InfolistWindowDurationMSec", 2300, 2, 1100, 1200); |
| } |
| } |
| |
| TEST_F(SessionUsageObserverTest, ClientSideStatsSoftwareKeyboardLayout) { |
| SessionUsageObserver observer; |
| |
| // create session |
| commands::Command command; |
| command.mutable_input()->set_type(commands::Input::CREATE_SESSION); |
| command.mutable_input()->set_id(1); |
| command.mutable_output()->set_id(1); |
| observer.EvalCommandHandler(command); |
| |
| EXPECT_STATS_NOT_EXIST("SoftwareKeyboardLayoutLandscape"); |
| EXPECT_STATS_NOT_EXIST("SoftwareKeyboardLayoutPortrait"); |
| |
| command.mutable_input()->set_type(commands::Input::SEND_COMMAND); |
| commands::SessionCommand *session_command = |
| command.mutable_input()->mutable_command(); |
| session_command->set_type(commands::SessionCommand::USAGE_STATS_EVENT); |
| session_command->set_usage_stats_event( |
| commands::SessionCommand::SOFTWARE_KEYBOARD_LAYOUT_LANDSCAPE); |
| session_command->set_usage_stats_event_int_value(1); |
| observer.EvalCommandHandler(command); |
| EXPECT_INTEGER_STATS("SoftwareKeyboardLayoutLandscape", 1); |
| EXPECT_STATS_NOT_EXIST("SoftwareKeyboardLayoutPortrait"); |
| |
| session_command->set_usage_stats_event_int_value(2); |
| observer.EvalCommandHandler(command); |
| EXPECT_INTEGER_STATS("SoftwareKeyboardLayoutLandscape", 2); |
| EXPECT_STATS_NOT_EXIST("SoftwareKeyboardLayoutPortrait"); |
| |
| session_command->set_usage_stats_event( |
| commands::SessionCommand::SOFTWARE_KEYBOARD_LAYOUT_PORTRAIT); |
| session_command->set_usage_stats_event_int_value(3); |
| observer.EvalCommandHandler(command); |
| EXPECT_INTEGER_STATS("SoftwareKeyboardLayoutLandscape", 2); |
| EXPECT_INTEGER_STATS("SoftwareKeyboardLayoutPortrait", 3); |
| } |
| |
| TEST_F(SessionUsageObserverTest, SubmittedCandidateRow) { |
| SessionUsageObserver observer; |
| |
| // create session |
| commands::Command command; |
| command.mutable_input()->set_type(commands::Input::CREATE_SESSION); |
| command.mutable_input()->set_id(1); |
| command.mutable_output()->set_id(1); |
| observer.EvalCommandHandler(command); |
| |
| EXPECT_STATS_NOT_EXIST("SubmittedCandidateRow0"); |
| EXPECT_STATS_NOT_EXIST("SubmittedCandidateRow1"); |
| EXPECT_STATS_NOT_EXIST("SubmittedCandidateRow2"); |
| EXPECT_STATS_NOT_EXIST("SubmittedCandidateRow3"); |
| EXPECT_STATS_NOT_EXIST("SubmittedCandidateRow4"); |
| EXPECT_STATS_NOT_EXIST("SubmittedCandidateRow5"); |
| EXPECT_STATS_NOT_EXIST("SubmittedCandidateRow6"); |
| EXPECT_STATS_NOT_EXIST("SubmittedCandidateRow7"); |
| EXPECT_STATS_NOT_EXIST("SubmittedCandidateRow8"); |
| EXPECT_STATS_NOT_EXIST("SubmittedCandidateRow9"); |
| EXPECT_STATS_NOT_EXIST("SubmittedCandidateRowGE10"); |
| |
| command.mutable_input()->set_type(commands::Input::SEND_COMMAND); |
| commands::SessionCommand *session_command = |
| command.mutable_input()->mutable_command(); |
| session_command->set_type(commands::SessionCommand::USAGE_STATS_EVENT); |
| session_command->set_usage_stats_event( |
| commands::SessionCommand::SUBMITTED_CANDIDATE_ROW_0); |
| observer.EvalCommandHandler(command); |
| EXPECT_COUNT_STATS("SubmittedCandidateRow0", 1); |
| |
| observer.EvalCommandHandler(command); |
| EXPECT_COUNT_STATS("SubmittedCandidateRow0", 2); |
| } |
| |
| TEST_F(SessionUsageObserverTest, LogTouchEvent) { |
| scoped_ptr<SessionUsageObserver> observer(new SessionUsageObserver); |
| |
| // create session |
| { |
| commands::Command command; |
| command.mutable_input()->set_type(commands::Input::CREATE_SESSION); |
| command.mutable_input()->set_id(1); |
| command.mutable_output()->set_id(1); |
| observer->EvalCommandHandler(command); |
| } |
| // set keyboard |
| { |
| commands::Command command; |
| command.mutable_input()->set_type(commands::Input::SET_REQUEST); |
| command.mutable_input()->set_id(1); |
| command.mutable_input()->mutable_request()->set_keyboard_name("KB1"); |
| observer->EvalCommandHandler(command); |
| } |
| { |
| commands::Command command; |
| command.mutable_input()->set_type(commands::Input::SEND_KEY); |
| command.mutable_input()->set_id(1); |
| commands::Input::TouchEvent *touch_event = |
| command.mutable_input()->add_touch_events(); |
| touch_event->set_source_id(10); |
| commands::Input::TouchPosition *pos1 = touch_event->add_stroke(); |
| pos1->set_action(commands::Input::TOUCH_DOWN); |
| pos1->set_x(1); |
| pos1->set_y(2); |
| pos1->set_timestamp(0); |
| commands::Input::TouchPosition *pos2 = touch_event->add_stroke(); |
| pos2->set_action(commands::Input::TOUCH_UP); |
| pos2->set_x(2); |
| pos2->set_y(1); |
| pos2->set_timestamp(1500); |
| observer->EvalCommandHandler(command); |
| } |
| { |
| commands::Command command; |
| command.mutable_input()->set_type(commands::Input::SEND_KEY); |
| command.mutable_input()->set_id(1); |
| commands::Input::TouchEvent *touch_event = |
| command.mutable_input()->add_touch_events(); |
| touch_event->set_source_id(10); |
| commands::Input::TouchPosition *pos1 = touch_event->add_stroke(); |
| pos1->set_action(commands::Input::TOUCH_DOWN); |
| pos1->set_x(2); |
| pos1->set_y(2); |
| pos1->set_timestamp(0); |
| commands::Input::TouchPosition *pos2 = touch_event->add_stroke(); |
| pos2->set_action(commands::Input::TOUCH_MOVE); |
| pos2->set_x(2); |
| pos2->set_y(2); |
| pos2->set_timestamp(1000); |
| commands::Input::TouchPosition *pos3 = touch_event->add_stroke(); |
| pos3->set_action(commands::Input::TOUCH_MOVE); |
| pos3->set_x(1); |
| pos3->set_y(1); |
| pos3->set_timestamp(2000); |
| observer->EvalCommandHandler(command); |
| } |
| // change keyboard |
| { |
| commands::Command command; |
| command.mutable_input()->set_type(commands::Input::SET_REQUEST); |
| command.mutable_input()->set_id(1); |
| command.mutable_input()->mutable_request()->set_keyboard_name("KB2"); |
| commands::Input::TouchEvent *touch_event = |
| command.mutable_input()->add_touch_events(); |
| touch_event->set_source_id(100); |
| commands::Input::TouchPosition *pos1 = touch_event->add_stroke(); |
| pos1->set_action(commands::Input::TOUCH_DOWN); |
| pos1->set_x(1); |
| pos1->set_y(1); |
| pos1->set_timestamp(0); |
| commands::Input::TouchPosition *pos2 = touch_event->add_stroke(); |
| pos2->set_action(commands::Input::TOUCH_UP); |
| pos2->set_x(1); |
| pos2->set_y(1); |
| pos2->set_timestamp(1000); |
| observer->EvalCommandHandler(command); |
| } |
| { |
| commands::Command command; |
| command.mutable_input()->set_type(commands::Input::SEND_KEY); |
| command.mutable_input()->set_id(1); |
| commands::Input::TouchEvent *touch_event = |
| command.mutable_input()->add_touch_events(); |
| touch_event->set_source_id(10); |
| commands::Input::TouchPosition *pos1 = touch_event->add_stroke(); |
| pos1->set_action(commands::Input::TOUCH_DOWN); |
| pos1->set_x(1); |
| pos1->set_y(2); |
| pos1->set_timestamp(0); |
| commands::Input::TouchPosition *pos2 = touch_event->add_stroke(); |
| pos2->set_action(commands::Input::TOUCH_UP); |
| pos2->set_x(2); |
| pos2->set_y(1); |
| pos2->set_timestamp(1500); |
| observer->EvalCommandHandler(command); |
| } |
| { |
| commands::Command command; |
| command.mutable_input()->set_type(commands::Input::SEND_KEY); |
| command.mutable_input()->set_id(1); |
| commands::Input::TouchEvent *touch_event = |
| command.mutable_input()->add_touch_events(); |
| touch_event->set_source_id(20); |
| commands::Input::TouchPosition *pos1 = touch_event->add_stroke(); |
| pos1->set_action(commands::Input::TOUCH_DOWN); |
| pos1->set_x(2); |
| pos1->set_y(2); |
| pos1->set_timestamp(0); |
| commands::Input::TouchPosition *pos2 = touch_event->add_stroke(); |
| pos2->set_action(commands::Input::TOUCH_UP); |
| pos2->set_x(1); |
| pos2->set_y(1); |
| pos2->set_timestamp(2000); |
| |
| // add preedit |
| command.mutable_output()->mutable_preedit(); |
| command.mutable_output()->set_consumed(true); |
| observer->EvalCommandHandler(command); |
| } |
| { |
| // send BACKSPACE |
| commands::Command command; |
| command.mutable_input()->set_type(commands::Input::SEND_KEY); |
| command.mutable_input()->set_id(1); |
| command.mutable_input()->mutable_key()->set_special_key( |
| commands::KeyEvent::BACKSPACE); |
| observer->EvalCommandHandler(command); |
| } |
| { |
| commands::Command command; |
| command.mutable_input()->set_type(commands::Input::SEND_KEY); |
| command.mutable_input()->set_id(1); |
| commands::Input::TouchEvent *touch_event = |
| command.mutable_input()->add_touch_events(); |
| touch_event->set_source_id(30); |
| commands::Input::TouchPosition *pos1 = touch_event->add_stroke(); |
| pos1->set_action(commands::Input::TOUCH_DOWN); |
| pos1->set_x(2); |
| pos1->set_y(2); |
| pos1->set_timestamp(0); |
| commands::Input::TouchPosition *pos2 = touch_event->add_stroke(); |
| pos2->set_action(commands::Input::TOUCH_MOVE); |
| pos2->set_x(1); |
| pos2->set_y(1); |
| pos2->set_timestamp(1000); |
| commands::Input::TouchPosition *pos3 = touch_event->add_stroke(); |
| pos3->set_action(commands::Input::TOUCH_UP); |
| pos3->set_x(1); |
| pos3->set_y(3); |
| pos3->set_timestamp(2000); |
| observer->EvalCommandHandler(command); |
| } |
| { |
| commands::Command command; |
| command.mutable_input()->set_type(commands::Input::NONE); |
| command.mutable_input()->set_id(1); |
| observer->EvalCommandHandler(command); |
| } |
| |
| EXPECT_STATS_NOT_EXIST("VirtualKeyboardStats"); |
| EXPECT_STATS_NOT_EXIST("VirtualKeyboardMissStats"); |
| EnsureSave(); |
| |
| { |
| Stats stats; |
| UsageStats::GetVirtualKeyboardForTest("VirtualKeyboardStats", &stats); |
| ASSERT_EQ(2, stats.virtual_keyboard_stats_size()); |
| ASSERT_EQ(2, stats.virtual_keyboard_stats(0).touch_event_stats_size()); |
| |
| Stats::TouchEventStats expected_event_stats; |
| SetEventStats(10, 2, 3, 5, 2, 4, 8, 2, 0, 2, 2, -2, 2, 2, 3.5, 6.25, |
| &expected_event_stats); |
| EXPECT_EQ( |
| expected_event_stats.DebugString(), |
| stats.virtual_keyboard_stats(0).touch_event_stats(0).DebugString()); |
| |
| SetEventStats(100, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, |
| &expected_event_stats); |
| EXPECT_EQ( |
| expected_event_stats.DebugString(), |
| stats.virtual_keyboard_stats(0).touch_event_stats(1).DebugString()); |
| |
| ASSERT_EQ(2, stats.virtual_keyboard_stats(1).touch_event_stats_size()); |
| |
| SetEventStats(10, 1, 1, 1, 1, 2, 4, 1, 1, 1, 1, -1, 1, 1, 1.5, 2.25, |
| &expected_event_stats); |
| EXPECT_EQ( |
| expected_event_stats.DebugString(), |
| stats.virtual_keyboard_stats(1).touch_event_stats(0).DebugString()); |
| |
| SetEventStats(30, 1, 2, 4, 1, 2, 4, 1, -1, 1, 1, 1, 1, 1, 2, 4, |
| &expected_event_stats); |
| EXPECT_EQ( |
| expected_event_stats.DebugString(), |
| stats.virtual_keyboard_stats(1).touch_event_stats(1).DebugString()); |
| } |
| { |
| Stats stats; |
| UsageStats::GetVirtualKeyboardForTest("VirtualKeyboardMissStats", &stats); |
| ASSERT_EQ(1, stats.virtual_keyboard_stats_size()); |
| ASSERT_EQ(1, stats.virtual_keyboard_stats(0).touch_event_stats_size()); |
| Stats::TouchEventStats expected_event_stats; |
| SetEventStats(20, 1, 2, 4, 1, 2, 4, 1, -1, 1, 1, -1, 1, 1, 2, 4, |
| &expected_event_stats); |
| EXPECT_EQ( |
| expected_event_stats.DebugString(), |
| stats.virtual_keyboard_stats(0).touch_event_stats(0).DebugString()); |
| } |
| } |
| |
| TEST_F(SessionUsageObserverTest, LogTouchEventPasswordField) { |
| scoped_ptr<SessionUsageObserver> observer(new SessionUsageObserver); |
| |
| // create session |
| { |
| commands::Command command; |
| command.mutable_input()->set_type(commands::Input::CREATE_SESSION); |
| command.mutable_input()->set_id(1); |
| command.mutable_output()->set_id(1); |
| observer->EvalCommandHandler(command); |
| } |
| // set keyboard |
| { |
| commands::Command command; |
| command.mutable_input()->set_type(commands::Input::SET_REQUEST); |
| command.mutable_input()->set_id(1); |
| command.mutable_input()->mutable_request()->set_keyboard_name("KB1"); |
| observer->EvalCommandHandler(command); |
| } |
| { |
| commands::Command command; |
| command.mutable_input()->set_type(commands::Input::SEND_KEY); |
| command.mutable_input()->set_id(1); |
| commands::Input::TouchEvent *touch_event = |
| command.mutable_input()->add_touch_events(); |
| touch_event->set_source_id(10); |
| commands::Input::TouchPosition *pos1 = touch_event->add_stroke(); |
| pos1->set_action(commands::Input::TOUCH_DOWN); |
| pos1->set_x(1); |
| pos1->set_y(1); |
| pos1->set_timestamp(0); |
| commands::Input::TouchPosition *pos2 = touch_event->add_stroke(); |
| pos2->set_action(commands::Input::TOUCH_UP); |
| pos2->set_x(1); |
| pos2->set_y(1); |
| pos2->set_timestamp(1000); |
| observer->EvalCommandHandler(command); |
| } |
| { |
| commands::Command command; |
| command.mutable_input()->set_type(commands::Input::SEND_KEY); |
| command.mutable_input()->set_id(1); |
| commands::Input::TouchEvent *touch_event = |
| command.mutable_input()->add_touch_events(); |
| touch_event->set_source_id(20); |
| commands::Input::TouchPosition *pos1 = touch_event->add_stroke(); |
| pos1->set_action(commands::Input::TOUCH_DOWN); |
| pos1->set_x(1); |
| pos1->set_y(1); |
| pos1->set_timestamp(0); |
| commands::Input::TouchPosition *pos2 = touch_event->add_stroke(); |
| pos2->set_action(commands::Input::TOUCH_MOVE); |
| pos2->set_x(1); |
| pos2->set_y(1); |
| pos2->set_timestamp(1000); |
| observer->EvalCommandHandler(command); |
| } |
| { |
| // Changes INPUT_FIELD_TYPE to PASSWORD |
| commands::Command command; |
| command.mutable_input()->set_type(commands::Input::SEND_COMMAND); |
| command.mutable_input()->set_id(1); |
| command.mutable_input()->mutable_command()->set_type( |
| commands::SessionCommand::SWITCH_INPUT_FIELD_TYPE); |
| command.mutable_input()->mutable_context()->set_input_field_type( |
| commands::Context::PASSWORD); |
| observer->EvalCommandHandler(command); |
| } |
| { |
| commands::Command command; |
| command.mutable_input()->set_type(commands::Input::SEND_KEY); |
| command.mutable_input()->set_id(1); |
| commands::Input::TouchEvent *touch_event = |
| command.mutable_input()->add_touch_events(); |
| touch_event->set_source_id(30); |
| commands::Input::TouchPosition *pos1 = touch_event->add_stroke(); |
| pos1->set_action(commands::Input::TOUCH_DOWN); |
| pos1->set_x(1); |
| pos1->set_y(1); |
| pos1->set_timestamp(0); |
| commands::Input::TouchPosition *pos2 = touch_event->add_stroke(); |
| pos2->set_action(commands::Input::TOUCH_UP); |
| pos2->set_x(1); |
| pos2->set_y(1); |
| pos2->set_timestamp(1000); |
| observer->EvalCommandHandler(command); |
| } |
| { |
| // Changes INPUT_FIELD_TYPE to NORMAL |
| commands::Command command; |
| command.mutable_input()->set_type(commands::Input::SEND_COMMAND); |
| command.mutable_input()->set_id(1); |
| command.mutable_input()->mutable_command()->set_type( |
| commands::SessionCommand::SWITCH_INPUT_FIELD_TYPE); |
| command.mutable_input()->mutable_context()->set_input_field_type( |
| commands::Context::NORMAL); |
| observer->EvalCommandHandler(command); |
| } |
| { |
| commands::Command command; |
| command.mutable_input()->set_type(commands::Input::SEND_KEY); |
| command.mutable_input()->set_id(1); |
| commands::Input::TouchEvent *touch_event = |
| command.mutable_input()->add_touch_events(); |
| touch_event->set_source_id(40); |
| commands::Input::TouchPosition *pos1 = touch_event->add_stroke(); |
| pos1->set_action(commands::Input::TOUCH_DOWN); |
| pos1->set_x(1); |
| pos1->set_y(1); |
| pos1->set_timestamp(0); |
| commands::Input::TouchPosition *pos2 = touch_event->add_stroke(); |
| pos2->set_action(commands::Input::TOUCH_UP); |
| pos2->set_x(1); |
| pos2->set_y(1); |
| pos2->set_timestamp(1000); |
| observer->EvalCommandHandler(command); |
| } |
| { |
| commands::Command command; |
| command.mutable_input()->set_type(commands::Input::NONE); |
| command.mutable_input()->set_id(1); |
| observer->EvalCommandHandler(command); |
| } |
| |
| EXPECT_STATS_NOT_EXIST("VirtualKeyboardStats"); |
| EXPECT_STATS_NOT_EXIST("VirtualKeyboardMissStats"); |
| EnsureSave(); |
| |
| { |
| Stats stats; |
| UsageStats::GetVirtualKeyboardForTest("VirtualKeyboardStats", &stats); |
| ASSERT_EQ(1, stats.virtual_keyboard_stats_size()); |
| ASSERT_EQ(3, stats.virtual_keyboard_stats(0).touch_event_stats_size()); |
| |
| Stats::TouchEventStats expected_event_stats; |
| SetEventStats(10, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, |
| &expected_event_stats); |
| EXPECT_EQ( |
| expected_event_stats.DebugString(), |
| stats.virtual_keyboard_stats(0).touch_event_stats(0).DebugString()); |
| SetEventStats(20, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, |
| &expected_event_stats); |
| EXPECT_EQ( |
| expected_event_stats.DebugString(), |
| stats.virtual_keyboard_stats(0).touch_event_stats(1).DebugString()); |
| SetEventStats(40, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, |
| &expected_event_stats); |
| EXPECT_EQ( |
| expected_event_stats.DebugString(), |
| stats.virtual_keyboard_stats(0).touch_event_stats(2).DebugString()); |
| } |
| } |
| |
| } // namespace session |
| } // namespace mozc |