Suppress sending usage stats when discharging
Note that this has no impact on OSS build, where usage stats is
completely disabled.
BUG=
TEST=
REF_BUG=19651870
REF_CL=112549643,113117528
REF_TIME=2016-01-20T15:32:38+09:00
REF_TIME_RAW=1453271558 +0900
Tsuyoshi Matsuzaki
8 years ago
57 | 57 | jobject g_connection_data_buffer; |
58 | 58 | jobject g_dictionary_buffer; |
59 | 59 | |
60 | // Returns a job setting for usage stats job. | |
61 | const Scheduler::JobSetting GetJobSetting() { | |
62 | return Scheduler::JobSetting( | |
63 | "UsageStatsTimer", | |
64 | usage_stats::UsageStatsUploader::kDefaultScheduleInterval, | |
65 | usage_stats::UsageStatsUploader::kDefaultScheduleMaxInterval, | |
66 | usage_stats::UsageStatsUploader::kDefaultSchedulerDelay, | |
67 | usage_stats::UsageStatsUploader::kDefaultSchedulerRandomDelay, | |
68 | &usage_stats::UsageStatsUploader::Send, | |
69 | NULL); | |
70 | } | |
71 | ||
60 | 72 | // Adapter class to make a SessionHandlerInterface (held by this class) |
61 | 73 | // singleton. |
62 | 74 | // Must be accessed via mozc::Singleton<SessionHandlerSingletonAdapter>. |
99 | 111 | ->AddObserver(Singleton<session::SessionUsageObserver>::get()); |
100 | 112 | |
101 | 113 | // Start usage stats timer. |
102 | using usage_stats::UsageStatsUploader; | |
103 | mozc::Scheduler::AddJob(Scheduler::JobSetting( | |
104 | "UsageStatsTimer", | |
105 | UsageStatsUploader::kDefaultScheduleInterval, | |
106 | UsageStatsUploader::kDefaultScheduleMaxInterval, | |
107 | UsageStatsUploader::kDefaultSchedulerDelay, | |
108 | UsageStatsUploader::kDefaultSchedulerRandomDelay, | |
109 | &UsageStatsUploader::Send, | |
110 | NULL)); | |
114 | mozc::Scheduler::AddJob(GetJobSetting()); | |
111 | 115 | } |
112 | 116 | |
113 | 117 | // Concrete implementation for MozcJni.evalCommand |
168 | 172 | return env->NewStringUTF(Version::GetMozcVersion().c_str()); |
169 | 173 | } |
170 | 174 | |
175 | void JNICALL suppressSendingStats(JNIEnv *env, | |
176 | jobject clazz, | |
177 | jboolean suppress) { | |
178 | const Scheduler::JobSetting &jobSetting = GetJobSetting(); | |
179 | const string &name = jobSetting.name(); | |
180 | const bool hasJob = mozc::Scheduler::HasJob(name); | |
181 | if (suppress && hasJob) { | |
182 | mozc::Scheduler::RemoveJob(name); | |
183 | } else if (!suppress && !hasJob) { | |
184 | mozc::Scheduler::AddJob(jobSetting); | |
185 | } | |
186 | } | |
187 | ||
171 | 188 | } // namespace |
172 | 189 | } // namespace jni |
173 | 190 | } // namespace mozc |
189 | 206 | {"getVersion", |
190 | 207 | "()Ljava/lang/String;", |
191 | 208 | reinterpret_cast<void*>(&mozc::jni::getVersion)}, |
209 | {"suppressSendingStats", | |
210 | "(Z)V", | |
211 | reinterpret_cast<void*>(&mozc::jni::suppressSendingStats)}, | |
192 | 212 | }; |
193 | 213 | jclass clazz = env->FindClass( |
194 | 214 | "org/mozc/android/inputmethod/japanese/session/MozcJNI"); |
109 | 109 | * @return Version string of shared object |
110 | 110 | */ |
111 | 111 | private static native String getVersion(); |
112 | ||
113 | /** | |
114 | * Sets suppression policy against sending usage stats. | |
115 | * | |
116 | * <p>Never call this method before JNI is loaded. | |
117 | * | |
118 | * @param suppress suppresses sending if true | |
119 | */ | |
120 | private static native void suppressSendingStats(boolean suppress); | |
112 | 121 | } |
255 | 255 | return (jobs_.erase(name) != 0); |
256 | 256 | } |
257 | 257 | |
258 | virtual bool HasJob(const string &name) const { | |
259 | return (jobs_.find(name) != jobs_.end()); | |
260 | } | |
261 | ||
258 | 262 | private: |
259 | 263 | static void TimerCallback(void *param) { |
260 | 264 | Job *job = reinterpret_cast<Job *>(param); |
286 | 290 | } |
287 | 291 | } |
288 | 292 | |
289 | bool HasJob(const string &name) const { | |
290 | return (jobs_.find(name) != jobs_.end()); | |
291 | } | |
292 | ||
293 | 293 | uint32 CalcDelay(const Scheduler::JobSetting &job_setting) { |
294 | 294 | uint32 delay = job_setting.delay_start(); |
295 | 295 | if (job_setting.random_delay() != 0) { |
327 | 327 | GetSchedulerHandler()->RemoveAllJobs(); |
328 | 328 | } |
329 | 329 | |
330 | bool Scheduler::HasJob(const string &name) { | |
331 | return GetSchedulerHandler()->HasJob(name); | |
332 | } | |
333 | ||
330 | 334 | void Scheduler::SetSchedulerHandler(SchedulerInterface *handler) { |
331 | 335 | g_scheduler_handler = handler; |
332 | 336 | } |
105 | 105 | // stop all jobs |
106 | 106 | static void RemoveAllJobs(); |
107 | 107 | |
108 | // returns true is the job has been registered. | |
109 | static bool HasJob(const string &name); | |
110 | ||
108 | 111 | // This function is provided for test. |
109 | 112 | // The behavior of scheduler can be customized by replacing an underlying |
110 | 113 | // helper class inside this. |
119 | 122 | virtual bool AddJob(const JobSetting &job_setting) = 0; |
120 | 123 | virtual bool RemoveJob(const string &name) = 0; |
121 | 124 | virtual void RemoveAllJobs() = 0; |
125 | virtual bool HasJob(const string &name) const = 0; | |
122 | 126 | }; |
123 | 127 | |
124 | 128 | private: |
57 | 57 | jobs_.clear(); |
58 | 58 | } |
59 | 59 | |
60 | bool SchedulerStub::HasJob(const string &name) const { | |
61 | return (jobs_.find(name) != jobs_.end()); | |
62 | } | |
63 | ||
60 | 64 | void SchedulerStub::PutClockForward(uint64 delta_usec) { |
61 | 65 | for (map<string, JobForStub>::iterator itr = jobs_.begin(); |
62 | 66 | itr != jobs_.end(); ++itr) { |
58 | 58 | virtual bool AddJob(const Scheduler::JobSetting &job_setting); |
59 | 59 | virtual bool RemoveJob(const string &name); |
60 | 60 | virtual void RemoveAllJobs(); |
61 | virtual bool HasJob(const string &name) const; | |
61 | 62 | |
62 | 63 | // Puts stub internal clock forward. |
63 | 64 | // Jobs will be executed according to forwarded time. |
56 | 56 | |
57 | 57 | TEST_F(SchedulerStubTest, AddRemoveJob) { |
58 | 58 | SchedulerStub scheduler_stub; |
59 | EXPECT_FALSE(scheduler_stub.HasJob("Test")); | |
59 | 60 | scheduler_stub.AddJob(Scheduler::JobSetting( |
60 | 61 | "Test", 1000, 100000, 5000, 0, &TestFunc, NULL)); |
62 | EXPECT_TRUE(scheduler_stub.HasJob("Test")); | |
61 | 63 | EXPECT_EQ(0, g_counter); |
62 | 64 | scheduler_stub.PutClockForward(1000); |
63 | 65 | EXPECT_EQ(0, g_counter); |
81 | 83 | EXPECT_EQ(3, g_counter); |
82 | 84 | scheduler_stub.PutClockForward(1000); |
83 | 85 | EXPECT_EQ(3, g_counter); |
86 | EXPECT_FALSE(scheduler_stub.HasJob("Test")); | |
84 | 87 | } |
85 | 88 | |
86 | 89 | TEST_F(SchedulerStubTest, BackOff) { |
265 | 265 | bool AddJob(const Scheduler::JobSetting &job_setting) { |
266 | 266 | return (expected_name_ == job_setting.name()); |
267 | 267 | } |
268 | bool HasJob(const string &name) const { return expected_name_ == name; } | |
268 | 269 | |
269 | 270 | private: |
270 | 271 | const string expected_name_; |
0 | 0 | MAJOR=2 |
1 | 1 | MINOR=17 |
2 | BUILD=2418 | |
2 | BUILD=2419 | |
3 | 3 | REVISION=102 |
4 | 4 | # NACL_DICTIONARY_VERSION is the target version of the system dictionary to be |
5 | 5 | # downloaded by NaCl Mozc. |
47 | 47 | job_settings_.push_back(job_setting); |
48 | 48 | return true; |
49 | 49 | } |
50 | bool HasJob(const string &name) const { | |
51 | for (size_t i = 0; i < job_settings_.size(); ++i) { | |
52 | if (job_settings_[i].name() == name) { | |
53 | return true; | |
54 | } | |
55 | } | |
56 | return false; | |
57 | } | |
50 | 58 | const vector<Scheduler::JobSetting> &job_settings() const { |
51 | 59 | return job_settings_; |
52 | 60 | } |
54 | 62 | private: |
55 | 63 | vector<Scheduler::JobSetting> job_settings_; |
56 | 64 | }; |
57 | ||
58 | bool FindJobByName(const vector<Scheduler::JobSetting> &job_settings, | |
59 | const string &job_name) { | |
60 | for (size_t i = 0; i < job_settings.size(); ++i) { | |
61 | if (job_settings[i].name() == job_name) { | |
62 | return true; | |
63 | } | |
64 | } | |
65 | return false; | |
66 | } | |
67 | 65 | } // namespace |
68 | 66 | class SessionServerTest : public testing::Test { |
69 | 67 | protected: |
76 | 74 | std::unique_ptr<JobRecorder> job_recorder(new JobRecorder); |
77 | 75 | Scheduler::SetSchedulerHandler(job_recorder.get()); |
78 | 76 | std::unique_ptr<SessionServer> session_server(new SessionServer); |
79 | const vector<Scheduler::JobSetting> &job_settings = | |
80 | job_recorder->job_settings(); | |
81 | EXPECT_LE(2, job_settings.size()); | |
82 | EXPECT_TRUE(FindJobByName(job_settings, "UsageStatsTimer")); | |
83 | EXPECT_TRUE(FindJobByName(job_settings, "SaveCachedStats")); | |
77 | EXPECT_LE(2, job_recorder->job_settings().size()); | |
78 | EXPECT_TRUE(job_recorder->HasJob("UsageStatsTimer")); | |
79 | EXPECT_TRUE(job_recorder->HasJob("SaveCachedStats")); | |
84 | 80 | Scheduler::SetSchedulerHandler(NULL); |
85 | 81 | } |
86 | 82 | } // namespace mozc |
234 | 234 | const uint32 UsageStatsUploader::kDefaultSchedulerDelay = 60*1000; |
235 | 235 | // 5 min |
236 | 236 | const uint32 UsageStatsUploader::kDefaultSchedulerRandomDelay = 5*60*1000; |
237 | #ifndef OS_ANDROID | |
238 | 237 | // 5 min |
239 | 238 | const uint32 UsageStatsUploader::kDefaultScheduleInterval = 5*60*1000; |
240 | 239 | // 2 hours |
241 | 240 | const uint32 UsageStatsUploader::kDefaultScheduleMaxInterval = 2*60*60*1000; |
242 | #else // !OS_ANDROID | |
243 | // Reduce the frequency to save battery. | |
244 | // 8 hours | |
245 | const uint32 UsageStatsUploader::kDefaultScheduleInterval = 8*60*60*1000; | |
246 | // 8 hours | |
247 | const uint32 UsageStatsUploader::kDefaultScheduleMaxInterval = 8*60*60*1000; | |
248 | #endif // !OS_ANDROID | |
249 | 241 | |
250 | 242 | void UsageStatsUploader::SetClientIdHandler( |
251 | 243 | ClientIdInterface *client_id_handler) { |