1 // Copyright 2010-2018, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 //     * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 //     * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 //     * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 
30 #include "usage_stats/usage_stats_uploader.h"
31 
32 #ifdef OS_ANDROID
33 #include <jni.h>
34 #endif  // OS_ANDROID
35 
36 #include <algorithm>
37 #include <map>
38 #include <string>
39 #include <utility>
40 #include <vector>
41 
42 #include "base/clock.h"
43 #include "base/port.h"
44 #include "base/singleton.h"
45 #include "base/system_util.h"
46 #include "base/util.h"
47 #include "base/version.h"
48 #include "base/win_util.h"
49 #include "config/config_handler.h"
50 #include "net/http_client.h"
51 #include "storage/registry.h"
52 #include "storage/storage_interface.h"
53 #include "testing/base/public/gunit.h"
54 #include "usage_stats/usage_stats.h"
55 #include "usage_stats/usage_stats.pb.h"
56 #include "usage_stats/usage_stats_testing_util.h"
57 
58 #ifdef OS_ANDROID
59 #include "base/android_jni_mock.h"
60 #include "base/android_jni_proxy.h"
61 #include "base/android_util.h"
62 #endif  // OS_ANDROID
63 
64 DECLARE_string(test_tmpdir);
65 
66 namespace mozc {
67 namespace usage_stats {
68 namespace {
69 
70 class TestableUsageStatsUploader : public UsageStatsUploader {
71  public:
72   // Change access rights.
73   using UsageStatsUploader::LoadStats;
74   using UsageStatsUploader::GetClientId;
75 };
76 
77 class TestHTTPClient : public HTTPClientInterface {
78  public:
Get(const string & url,const HTTPClient::Option & option,string * output) const79   bool Get(const string &url, const HTTPClient::Option &option,
80            string *output) const { return true; }
Head(const string & url,const HTTPClient::Option & option,string * output) const81   bool Head(const string &url, const HTTPClient::Option &option,
82             string *output) const { return true; }
Post(const string & url,const string & data,const HTTPClient::Option & option,string * output) const83   bool Post(const string &url, const string &data,
84             const HTTPClient::Option &option, string *output) const {
85     LOG(INFO) << "url: " << url;
86     LOG(INFO) << "data: " << data;
87     if (result_.expected_url != url) {
88       LOG(INFO) << "expected_url: " << result_.expected_url;
89       return false;
90     }
91 
92     std::vector<string> data_set;
93     Util::SplitStringUsing(data, "&", &data_set);
94     for (size_t i = 0; i < expected_data_.size(); ++i) {
95       std::vector<string>::const_iterator itr =
96           std::find(data_set.begin(), data_set.end(), expected_data_[i]);
97       const bool found = (itr != data_set.end());
98       // we can't compile EXPECT_NE(itr, data_set.end()), so we use EXPECT_TRUE
99       EXPECT_TRUE(found) << expected_data_[i];
100     }
101 
102     *output = result_.expected_result;
103     return true;
104   }
105 
106   struct Result {
107     string expected_url;
108     string expected_result;
109   };
110 
set_result(const Result & result)111   void set_result(const Result &result) {
112     result_ = result;
113   }
114 
115   // TODO(toshiyuki): integrate with struct Result
AddExpectedData(const string & data)116   void AddExpectedData(const string &data) {
117     expected_data_.push_back(data);
118   }
119 
120  private:
121   // usage stats key and value parameter
122   // format is "<key>:<type>=<value>"
123   std::vector<string> expected_data_;
124   Result result_;
125 };
126 
127 const uint32 kOneDaySec = 24 * 60 * 60;  // 24 hours
128 const uint32 kHalfDaySec = 12 * 60 * 60;  // 12 hours
129 const char kBaseUrl[] =
130 #ifdef OS_NACL
131     "https://clients4.google.com/tbproxy/usagestats";
132 #else  // OS_NACL
133     "http://clients4.google.com/tbproxy/usagestats";
134 #endif  // OS_NACL
135 const char kTestClientId[] = "TestClientId";
136 const char kCountStatsKey[] = "Commit";
137 const uint32 kCountStatsDefaultValue = 100;
138 const char kIntegerStatsKey[] = "UserRegisteredWord";
139 const int kIntegerStatsDefaultValue = 2;
140 
SetUpMetaDataWithMozcVersion(uint32 last_upload_time,const string & mozc_version)141 void SetUpMetaDataWithMozcVersion(uint32 last_upload_time,
142                                   const string &mozc_version) {
143   EXPECT_TRUE(storage::Registry::Insert("usage_stats.last_upload",
144                                         last_upload_time));
145   EXPECT_TRUE(storage::Registry::Insert("usage_stats.mozc_version",
146                                         mozc_version));
147 }
148 
SetUpMetaData(uint32 last_upload_time)149 void SetUpMetaData(uint32 last_upload_time) {
150   SetUpMetaDataWithMozcVersion(last_upload_time, Version::GetMozcVersion());
151 }
152 
153 class TestClientId : public ClientIdInterface {
154  public:
TestClientId()155   TestClientId() {}
~TestClientId()156   virtual ~TestClientId() {}
GetClientId(string * output)157   void GetClientId(string *output) {
158     *output = kTestClientId;
159   }
160 };
161 
162 class UsageStatsUploaderTest : public ::testing::Test {
163  protected:
SetUp()164   virtual void SetUp() {
165     SystemUtil::SetUserProfileDirectory(FLAGS_test_tmpdir);
166 
167     TestableUsageStatsUploader::SetClientIdHandler(&client_id_);
168     HTTPClient::SetHTTPClientHandler(&client_);
169     EXPECT_TRUE(storage::Registry::Clear());
170 
171     // save test stats
172     UsageStats::IncrementCountBy(kCountStatsKey, kCountStatsDefaultValue);
173     EXPECT_COUNT_STATS(kCountStatsKey, kCountStatsDefaultValue);
174     UsageStats::SetInteger(kIntegerStatsKey, kIntegerStatsDefaultValue);
175     EXPECT_INTEGER_STATS(kIntegerStatsKey, kIntegerStatsDefaultValue);
176   }
177 
TearDown()178   virtual void TearDown() {
179     TestableUsageStatsUploader::SetClientIdHandler(NULL);
180     HTTPClient::SetHTTPClientHandler(NULL);
181     EXPECT_TRUE(storage::Registry::Clear());
182   }
183 
SetValidResult()184   void SetValidResult() {
185     std::vector<std::pair<string, string> > params;
186     params.push_back(std::make_pair("sourceid", "ime"));
187     params.push_back(std::make_pair("hl", "ja"));
188     params.push_back(std::make_pair("v", Version::GetMozcVersion()));
189     params.push_back(std::make_pair("client_id", kTestClientId));
190     params.push_back(
191         std::make_pair("os_ver", SystemUtil::GetOSVersionString()));
192 #ifdef OS_ANDROID
193     params.push_back(
194         std::make_pair("model",
195                        AndroidUtil::GetSystemProperty(
196                            AndroidUtil::kSystemPropertyModel, "Unknown")));
197 #endif  // OS_ANDROID
198 
199     string url = string(kBaseUrl) + "?";
200     Util::AppendCGIParams(params, &url);
201     TestHTTPClient::Result result;
202     result.expected_url = url;
203     client_.set_result(result);
204   }
205 
206   TestHTTPClient client_;
207   TestClientId client_id_;
208   scoped_usage_stats_enabler usage_stats_enabler_;
209 };
210 
TEST_F(UsageStatsUploaderTest,SendTest)211 TEST_F(UsageStatsUploaderTest, SendTest) {
212   const uint32 current_sec = static_cast<uint32>(Clock::GetTime());
213   const uint32 last_upload_sec = current_sec - kOneDaySec;
214   SetUpMetaData(last_upload_sec);
215   SetValidResult();
216 
217   EXPECT_TRUE(TestableUsageStatsUploader::Send(NULL));
218 
219   // COUNT stats are cleared
220   EXPECT_STATS_NOT_EXIST(kCountStatsKey);
221   // INTEGER stats are not cleared
222   EXPECT_INTEGER_STATS(kIntegerStatsKey, kIntegerStatsDefaultValue);
223   uint32 recorded_sec;
224   string recorded_version;
225   EXPECT_TRUE(storage::Registry::Lookup("usage_stats.last_upload",
226                                         &recorded_sec));
227   EXPECT_TRUE(storage::Registry::Lookup("usage_stats.mozc_version",
228                                         &recorded_version));
229   EXPECT_LE(current_sec, recorded_sec);
230   EXPECT_EQ(Version::GetMozcVersion(), recorded_version);
231 }
232 
TEST_F(UsageStatsUploaderTest,FirstTimeSendTest)233 TEST_F(UsageStatsUploaderTest, FirstTimeSendTest) {
234   const uint32 current_sec = static_cast<uint32>(Clock::GetTime());
235   // Don't call SetUpMetaData()..
236   SetValidResult();
237 
238   uint32 recorded_sec;
239   string recorded_version;
240   EXPECT_FALSE(storage::Registry::Lookup("usage_stats.last_upload",
241                                          &recorded_sec));
242   EXPECT_FALSE(storage::Registry::Lookup("usage_stats.mozc_version",
243                                          &recorded_version));
244 
245   EXPECT_TRUE(TestableUsageStatsUploader::Send(NULL));
246 
247   EXPECT_STATS_NOT_EXIST(kCountStatsKey);
248   EXPECT_INTEGER_STATS(kIntegerStatsKey, kIntegerStatsDefaultValue);
249   EXPECT_TRUE(storage::Registry::Lookup("usage_stats.last_upload",
250                                         &recorded_sec));
251   EXPECT_TRUE(storage::Registry::Lookup("usage_stats.mozc_version",
252                                         &recorded_version));
253   EXPECT_LE(current_sec, recorded_sec);
254   EXPECT_EQ(Version::GetMozcVersion(), recorded_version);
255 }
256 
TEST_F(UsageStatsUploaderTest,SendFailTest)257 TEST_F(UsageStatsUploaderTest, SendFailTest) {
258   const uint32 current_sec = static_cast<uint32>(Clock::GetTime());
259   const uint32 last_upload_sec = current_sec - kHalfDaySec;
260   SetUpMetaData(last_upload_sec);
261   SetValidResult();
262 
263   EXPECT_FALSE(TestableUsageStatsUploader::Send(NULL));
264 
265   EXPECT_COUNT_STATS(kCountStatsKey, kCountStatsDefaultValue);
266   EXPECT_INTEGER_STATS(kIntegerStatsKey, kIntegerStatsDefaultValue);
267   uint32 recorded_sec;
268   EXPECT_TRUE(storage::Registry::Lookup("usage_stats.last_upload",
269                                         &recorded_sec));
270   EXPECT_EQ(last_upload_sec, recorded_sec);
271 }
272 
TEST_F(UsageStatsUploaderTest,InvalidLastUploadTest)273 TEST_F(UsageStatsUploaderTest, InvalidLastUploadTest) {
274   const uint32 current_sec = static_cast<uint32>(Clock::GetTime());
275   // future time
276   // for example: time zone has changed
277   const uint32 invalid_sec = current_sec + kHalfDaySec;
278   SetUpMetaData(invalid_sec);
279   SetValidResult();
280 
281   EXPECT_TRUE(TestableUsageStatsUploader::Send(NULL));
282 
283   EXPECT_STATS_NOT_EXIST(kCountStatsKey);
284   EXPECT_INTEGER_STATS(kIntegerStatsKey, kIntegerStatsDefaultValue);
285   uint32 recorded_sec;
286   EXPECT_TRUE(storage::Registry::Lookup("usage_stats.last_upload",
287                                         &recorded_sec));
288   // Save new last_upload_time
289   EXPECT_LE(current_sec, recorded_sec);
290 }
291 
TEST_F(UsageStatsUploaderTest,MozcVersionMismatchTest)292 TEST_F(UsageStatsUploaderTest, MozcVersionMismatchTest) {
293   const uint32 current_sec = static_cast<uint32>(Clock::GetTime());
294   const uint32 last_upload_sec = current_sec - kOneDaySec;
295   SetUpMetaDataWithMozcVersion(last_upload_sec, "invalid_mozc_version");
296   SetValidResult();
297 
298   EXPECT_TRUE(TestableUsageStatsUploader::Send(NULL));
299 
300   EXPECT_STATS_NOT_EXIST(kCountStatsKey);
301   EXPECT_INTEGER_STATS(kIntegerStatsKey, kIntegerStatsDefaultValue);
302   uint32 recorded_sec;
303   string recorded_version;
304   EXPECT_TRUE(storage::Registry::Lookup("usage_stats.last_upload",
305                                         &recorded_sec));
306   EXPECT_TRUE(storage::Registry::Lookup("usage_stats.mozc_version",
307                                         &recorded_version));
308   // Save new last_upload_time and recorded_version.
309   EXPECT_LE(current_sec, recorded_sec);
310   EXPECT_EQ(Version::GetMozcVersion(), recorded_version);
311 }
312 
313 class TestStorage: public storage::StorageInterface {
314  public:
Open(const string & filename)315   bool Open(const string &filename) { return true; }
Sync()316   bool Sync() { return true; }
Lookup(const string & key,string * value) const317   bool Lookup(const string &key, string *value) const { return false; }
318   // return false
Insert(const string & key,const string & value)319   bool Insert(const string &key, const string &value) { return false; }
Erase(const string & key)320   bool Erase(const string &key) { return true; }
Clear()321   bool Clear() { return true; }
Size() const322   size_t Size() const { return 0; }
TestStorage()323   TestStorage() {}
~TestStorage()324   virtual ~TestStorage() {}
325 };
326 
TEST_F(UsageStatsUploaderTest,SaveMetadataFailTest)327 TEST_F(UsageStatsUploaderTest, SaveMetadataFailTest) {
328   const uint32 current_sec = static_cast<uint32>(Clock::GetTime());
329   const uint32 last_upload_sec = current_sec - kOneDaySec;
330   const string current_version = Version::GetMozcVersion();
331   SetUpMetaData(last_upload_sec);
332   SetValidResult();
333 
334   // set the TestStorage as a storage handler.
335   // writing to the registry will be failed.
336   storage::Registry::SetStorage(Singleton<TestStorage>::get());
337   // confirm that we can not insert.
338   EXPECT_FALSE(storage::Registry::Insert("usage_stats.last_upload",
339                                          last_upload_sec));
340   EXPECT_FALSE(storage::Registry::Insert("usage_stats.mozc_version",
341                                          current_version));
342 
343   EXPECT_FALSE(TestableUsageStatsUploader::Send(NULL));
344   // restore
345   storage::Registry::SetStorage(NULL);
346 
347   // stats data are kept
348   EXPECT_COUNT_STATS(kCountStatsKey, kCountStatsDefaultValue);
349   EXPECT_INTEGER_STATS(kIntegerStatsKey, kIntegerStatsDefaultValue);
350   uint32 recorded_sec;
351   string recorded_version;
352   EXPECT_TRUE(storage::Registry::Lookup("usage_stats.last_upload",
353                                         &recorded_sec));
354   EXPECT_TRUE(storage::Registry::Lookup("usage_stats.mozc_version",
355                                         &recorded_version));
356   EXPECT_EQ(last_upload_sec, recorded_sec);
357   EXPECT_EQ(current_version, recorded_version);
358 }
359 
TEST_F(UsageStatsUploaderTest,UploadFailTest)360 TEST_F(UsageStatsUploaderTest, UploadFailTest) {
361   const uint32 current_sec = static_cast<uint32>(Clock::GetTime());
362   const uint32 last_upload_sec = current_sec - kOneDaySec;
363   SetUpMetaData(last_upload_sec);
364   SetValidResult();
365 
366   TestHTTPClient::Result result;
367   // set dummy result url so that upload will be failed.
368   result.expected_url = "fail_url";
369   client_.set_result(result);
370 
371   EXPECT_FALSE(TestableUsageStatsUploader::Send(NULL));
372 
373   // stats data are not cleared
374   EXPECT_COUNT_STATS(kCountStatsKey, kCountStatsDefaultValue);
375   EXPECT_INTEGER_STATS(kIntegerStatsKey, kIntegerStatsDefaultValue);
376   // "UsageStatsUploadFailed" is incremented
377   EXPECT_COUNT_STATS("UsageStatsUploadFailed", 1);
378   uint32 recorded_sec;
379   EXPECT_TRUE(storage::Registry::Lookup("usage_stats.last_upload",
380                                         &recorded_sec));
381   // last_upload is not updated
382   EXPECT_EQ(last_upload_sec, recorded_sec);
383 }
384 
TEST_F(UsageStatsUploaderTest,UploadRetryTest)385 TEST_F(UsageStatsUploaderTest, UploadRetryTest) {
386   const uint32 current_sec = static_cast<uint32>(Clock::GetTime());
387   const uint32 last_upload_sec = current_sec - kOneDaySec;
388   SetUpMetaData(last_upload_sec);
389   SetValidResult();
390 
391   TestHTTPClient::Result result;
392   // set dummy result url so that upload will be failed.
393   result.expected_url = "fail_url";
394   client_.set_result(result);
395 
396   EXPECT_FALSE(TestableUsageStatsUploader::Send(NULL));
397 
398   // stats data are not cleared
399   EXPECT_COUNT_STATS(kCountStatsKey, kCountStatsDefaultValue);
400   EXPECT_INTEGER_STATS(kIntegerStatsKey, kIntegerStatsDefaultValue);
401   uint32 recorded_sec;
402   EXPECT_TRUE(storage::Registry::Lookup("usage_stats.last_upload",
403                                         &recorded_sec));
404   // last_upload is not updated
405   EXPECT_EQ(last_upload_sec, recorded_sec);
406 
407   // retry
408   SetValidResult();
409   // We can send stats if network is available.
410   EXPECT_TRUE(TestableUsageStatsUploader::Send(NULL));
411 
412   // Stats are cleared
413   EXPECT_STATS_NOT_EXIST(kCountStatsKey);
414   // However, INTEGER stats are not cleared
415   EXPECT_INTEGER_STATS(kIntegerStatsKey, kIntegerStatsDefaultValue);
416   // last upload is updated
417   EXPECT_TRUE(storage::Registry::Lookup("usage_stats.last_upload",
418                                         &recorded_sec));
419   EXPECT_LE(last_upload_sec, recorded_sec);
420 }
421 
TEST_F(UsageStatsUploaderTest,UploadDataTest)422 TEST_F(UsageStatsUploaderTest, UploadDataTest) {
423   const uint32 current_sec = static_cast<uint32>(Clock::GetTime());
424   const uint32 last_upload_sec = current_sec - kOneDaySec;
425   SetUpMetaData(last_upload_sec);
426   SetValidResult();
427 
428 #ifdef OS_WIN
429   const string win64 = (string("WindowsX64:b=")
430                         + (SystemUtil::IsWindowsX64()? "t" : "f"));
431   client_.AddExpectedData(win64);
432 #endif
433   client_.AddExpectedData(Util::StringPrintf("%s:c=%u", kCountStatsKey,
434                                              kCountStatsDefaultValue));
435   client_.AddExpectedData(Util::StringPrintf("%s:i=%d", kIntegerStatsKey,
436                                              kIntegerStatsDefaultValue));
437   client_.AddExpectedData("Daily");
438 
439   EXPECT_TRUE(TestableUsageStatsUploader::Send(NULL));
440 }
441 
SetDoubleValueStats(uint32 num,double total,double square_total,usage_stats::Stats::DoubleValueStats * double_stats)442 void SetDoubleValueStats(
443     uint32 num, double total, double square_total,
444     usage_stats::Stats::DoubleValueStats *double_stats) {
445   double_stats->set_num(num);
446   double_stats->set_total(total);
447   double_stats->set_square_total(square_total);
448 }
449 
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,usage_stats::Stats::TouchEventStats * event_stats)450 void SetEventStats(
451     uint32 source_id,
452     uint32 sx_num, double sx_total, double sx_square_total,
453     uint32 sy_num, double sy_total, double sy_square_total,
454     uint32 dx_num, double dx_total, double dx_square_total,
455     uint32 dy_num, double dy_total, double dy_square_total,
456     uint32 tl_num, double tl_total, double tl_square_total,
457     usage_stats::Stats::TouchEventStats *event_stats) {
458   event_stats->set_source_id(source_id);
459   SetDoubleValueStats(sx_num, sx_total, sx_square_total,
460                       event_stats->mutable_start_x_stats());
461   SetDoubleValueStats(sy_num, sy_total, sy_square_total,
462                       event_stats->mutable_start_y_stats());
463   SetDoubleValueStats(dx_num, dx_total, dx_square_total,
464                       event_stats->mutable_direction_x_stats());
465   SetDoubleValueStats(dy_num, dy_total, dy_square_total,
466                       event_stats->mutable_direction_y_stats());
467   SetDoubleValueStats(tl_num, tl_total, tl_square_total,
468                       event_stats->mutable_time_length_stats());
469 }
470 
TEST_F(UsageStatsUploaderTest,UploadTouchEventStats)471 TEST_F(UsageStatsUploaderTest, UploadTouchEventStats) {
472   // save last_upload
473   const uint32 current_sec = static_cast<uint32>(Clock::GetTime());
474   const uint32 last_upload_sec = current_sec - kOneDaySec;
475   SetUpMetaData(last_upload_sec);
476   SetValidResult();
477 
478   EXPECT_STATS_NOT_EXIST("VirtualKeyboardStats");
479   EXPECT_STATS_NOT_EXIST("VirtualKeyboardMissStats");
480   std::map<string, std::map<uint32, Stats::TouchEventStats> > touch_stats;
481   std::map<string, std::map<uint32, Stats::TouchEventStats> > miss_touch_stats;
482 
483   Stats::TouchEventStats &event_stats1 = touch_stats["KEYBOARD_01"][10];
484   SetEventStats(10, 2, 3, 8, 2, 4, 10, 2, 5, 16, 2, 2, 2,
485                 2, 3, 9, &event_stats1);
486 
487   Stats::TouchEventStats &event_stats2 = touch_stats["KEYBOARD_02"][20];
488   SetEventStats(20, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
489                 114, 115, 116, &event_stats2);
490 
491   Stats::TouchEventStats &event_stats3 = touch_stats["KEYBOARD_01"][20];
492   SetEventStats(20, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213,
493                 214, 215, 216, &event_stats3);
494 
495   Stats::TouchEventStats &event_stats4 = miss_touch_stats["KEYBOARD_01"][20];
496   SetEventStats(20, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313,
497                 314, 315, 316, &event_stats4);
498 
499   Stats::TouchEventStats &event_stats5 = miss_touch_stats["KEYBOARD_01"][30];
500   SetEventStats(30, 404, 406, 408, 410, 412, 414, 416, 418, 420, 422, 424, 426,
501                 428, 430, 432, &event_stats5);
502 
503   UsageStats::StoreTouchEventStats("VirtualKeyboardStats", touch_stats);
504   UsageStats::StoreTouchEventStats("VirtualKeyboardMissStats",
505                                    miss_touch_stats);
506 
507   Stats stats;
508   EXPECT_TRUE(UsageStats::GetVirtualKeyboardForTest("VirtualKeyboardStats",
509                                                     &stats));
510   EXPECT_EQ(2, stats.virtual_keyboard_stats_size());
511   EXPECT_EQ("KEYBOARD_01",
512             stats.virtual_keyboard_stats(0).keyboard_name());
513   EXPECT_EQ("KEYBOARD_02",
514             stats.virtual_keyboard_stats(1).keyboard_name());
515   EXPECT_EQ(2, stats.virtual_keyboard_stats(0).touch_event_stats_size());
516   EXPECT_EQ(1, stats.virtual_keyboard_stats(1).touch_event_stats_size());
517 
518   EXPECT_EQ(event_stats1.DebugString(),
519             stats.virtual_keyboard_stats(0).touch_event_stats(0).DebugString());
520   EXPECT_EQ(event_stats3.DebugString(),
521             stats.virtual_keyboard_stats(0).touch_event_stats(1).DebugString());
522   EXPECT_EQ(event_stats2.DebugString(),
523             stats.virtual_keyboard_stats(1).touch_event_stats(0).DebugString());
524 
525   EXPECT_TRUE(UsageStats::GetVirtualKeyboardForTest("VirtualKeyboardMissStats",
526                                                     &stats));
527   EXPECT_EQ(1, stats.virtual_keyboard_stats_size());
528   EXPECT_EQ("KEYBOARD_01",
529             stats.virtual_keyboard_stats(0).keyboard_name());
530   EXPECT_EQ(2, stats.virtual_keyboard_stats(0).touch_event_stats_size());
531   EXPECT_EQ(event_stats4.DebugString(),
532             stats.virtual_keyboard_stats(0).touch_event_stats(0).DebugString());
533   EXPECT_EQ(event_stats5.DebugString(),
534             stats.virtual_keyboard_stats(0).touch_event_stats(1).DebugString());
535 
536   client_.AddExpectedData(string("vks%5Fname%5FKEYBOARD%5F01:i=0"));
537   client_.AddExpectedData(string("vks%5Fname%5FKEYBOARD%5F02:i=1"));
538   client_.AddExpectedData(string("vkms%5Fname%5FKEYBOARD%5F01:i=0"));
539 
540   // Average = total / num
541   // Variance = square_total / num - (total / num) ^ 2
542   // Because the current log analysis system can only deal with int values,
543   // we multiply these values by a scale factor and send them to server.
544   //   sxa, sya, dxa, dya : scale = 10000000
545   //   sxv, syv, dxv, dyv : scale = 10000000
546   //   tla, tlv : scale = 10000000
547 
548   // (3 / 2) * 10000000
549   client_.AddExpectedData(string("vks%5F0%5F10%5Fsxa:i=15000000"));
550   // (8 / 2 - (3 / 2) ^ 2) * 10000000
551   client_.AddExpectedData(string("vks%5F0%5F10%5Fsxv:i=17500000"));
552   // (4 / 2) * 10000000
553   client_.AddExpectedData(string("vks%5F0%5F10%5Fsya:i=20000000"));
554   // (10 / 2 - (4 / 2) ^ 2) * 10000000
555   client_.AddExpectedData(string("vks%5F0%5F10%5Fsyv:i=10000000"));
556   // (5 / 2) * 10000000
557   client_.AddExpectedData(string("vks%5F0%5F10%5Fdxa:i=25000000"));
558   // (16 / 2 - (5 / 2) ^ 2) * 10000000
559   client_.AddExpectedData(string("vks%5F0%5F10%5Fdxv:i=17500000"));
560   // (2 / 2) * 10000000
561   client_.AddExpectedData(string("vks%5F0%5F10%5Fdya:i=10000000"));
562   // (2 / 2 - (2 / 2) ^ 2) * 10000000
563   client_.AddExpectedData(string("vks%5F0%5F10%5Fdyv:i=0"));
564   // (3 / 2) * 10000000
565   client_.AddExpectedData(string("vks%5F0%5F10%5Ftla:i=15000000"));
566   // (9 / 2 - (3 / 2) ^ 2) * 10000000
567   client_.AddExpectedData(string("vks%5F0%5F10%5Ftlv:i=22500000"));
568   EXPECT_TRUE(TestableUsageStatsUploader::Send(NULL));
569 }
570 
TEST(ClientIdTest,CreateClientIdTest)571 TEST(ClientIdTest, CreateClientIdTest) {
572   // test default client id handler here
573   TestableUsageStatsUploader::SetClientIdHandler(NULL);
574   SystemUtil::SetUserProfileDirectory(FLAGS_test_tmpdir);
575   EXPECT_TRUE(storage::Registry::Clear());
576   string client_id1;
577   TestableUsageStatsUploader::GetClientId(&client_id1);
578   string client_id_in_storage1;
579   EXPECT_TRUE(storage::Registry::Lookup("usage_stats.client_id",
580                                         &client_id_in_storage1));
581   EXPECT_TRUE(storage::Registry::Clear());
582   string client_id2;
583   TestableUsageStatsUploader::GetClientId(&client_id2);
584   string client_id_in_storage2;
585   EXPECT_TRUE(storage::Registry::Lookup("usage_stats.client_id",
586                                         &client_id_in_storage2));
587 
588   EXPECT_NE(client_id1, client_id2);
589   EXPECT_NE(client_id_in_storage1, client_id_in_storage2);
590 }
591 
TEST(ClientIdTest,GetClientIdTest)592 TEST(ClientIdTest, GetClientIdTest) {
593   // test default client id handler here.
594   TestableUsageStatsUploader::SetClientIdHandler(NULL);
595   SystemUtil::SetUserProfileDirectory(FLAGS_test_tmpdir);
596   EXPECT_TRUE(storage::Registry::Clear());
597   string client_id1;
598   TestableUsageStatsUploader::GetClientId(&client_id1);
599   string client_id2;
600   TestableUsageStatsUploader::GetClientId(&client_id2);
601   // we can get same client id.
602   EXPECT_EQ(client_id1, client_id2);
603 
604   string client_id_in_storage;
605   EXPECT_TRUE(storage::Registry::Lookup("usage_stats.client_id",
606                                         &client_id_in_storage));
607   // encrypted value is in storage
608   EXPECT_NE(client_id1, client_id_in_storage);
609 }
610 
TEST(ClientIdTest,GetClientIdFailTest)611 TEST(ClientIdTest, GetClientIdFailTest) {
612   // test default client id handler here.
613   TestableUsageStatsUploader::SetClientIdHandler(NULL);
614   SystemUtil::SetUserProfileDirectory(FLAGS_test_tmpdir);
615   EXPECT_TRUE(storage::Registry::Clear());
616   string client_id1;
617   TestableUsageStatsUploader::GetClientId(&client_id1);
618   // insert invalid data
619   EXPECT_TRUE(storage::Registry::Insert("usage_stats.client_id",
620                                         "invalid_data"));
621 
622   string client_id2;
623   // decript should be failed
624   TestableUsageStatsUploader::GetClientId(&client_id2);
625   // new id should be generated
626   EXPECT_NE(client_id1, client_id2);
627 }
628 
629 }  // namespace
630 }  // namespace usage_stats
631 }  // namespace mozc
632