blob: 42e192910fd7aad1fea173c059348e71b0aa7cde [file] [log] [blame]
[email protected]9049a7b2013-03-07 22:22:031// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/sync/profile_sync_service_android.h"
6
7#include "base/android/jni_android.h"
8#include "base/android/jni_string.h"
9#include "base/bind.h"
10#include "base/i18n/time_formatting.h"
11#include "base/json/json_writer.h"
12#include "base/logging.h"
13#include "base/memory/scoped_ptr.h"
[email protected]34ee0512013-03-12 17:49:5414#include "base/prefs/pref_service.h"
[email protected]e309f312013-06-07 21:50:0815#include "base/strings/utf_string_conversions.h"
[email protected]cc86ccfe2013-06-28 00:10:5016#include "base/time/time.h"
[email protected]9049a7b2013-03-07 22:22:0317#include "chrome/browser/browser_process.h"
[email protected]dcc8fbc2013-07-12 00:54:0918#include "chrome/browser/chrome_notification_types.h"
[email protected]9049a7b2013-03-07 22:22:0319#include "chrome/browser/profiles/profile_manager.h"
20#include "chrome/browser/signin/signin_manager.h"
21#include "chrome/browser/signin/signin_manager_factory.h"
[email protected]9049a7b2013-03-07 22:22:0322#include "chrome/browser/sync/about_sync_util.h"
23#include "chrome/browser/sync/profile_sync_service.h"
24#include "chrome/browser/sync/profile_sync_service_factory.h"
25#include "chrome/browser/sync/sync_prefs.h"
26#include "chrome/browser/sync/sync_ui_util.h"
[email protected]9049a7b2013-03-07 22:22:0327#include "chrome/common/pref_names.h"
28#include "content/public/browser/notification_service.h"
[email protected]9a3de842013-06-12 20:16:5129#include "content/public/browser/notification_source.h"
[email protected]9049a7b2013-03-07 22:22:0330#include "google/cacheinvalidation/types.pb.h"
31#include "google_apis/gaia/gaia_constants.h"
32#include "google_apis/gaia/google_service_auth_error.h"
33#include "grit/generated_resources.h"
34#include "jni/ProfileSyncService_jni.h"
[email protected]9049a7b2013-03-07 22:22:0335#include "sync/internal_api/public/read_transaction.h"
[email protected]a7b16392013-11-26 22:46:2636#include "sync/notifier/object_id_invalidation_map.h"
[email protected]9049a7b2013-03-07 22:22:0337#include "ui/base/l10n/l10n_util.h"
38
39using base::android::AttachCurrentThread;
40using base::android::CheckException;
41using base::android::ConvertJavaStringToUTF8;
42using base::android::ConvertUTF8ToJavaString;
43using base::android::ScopedJavaLocalRef;
44using content::BrowserThread;
45
46namespace {
[email protected]9049a7b2013-03-07 22:22:0347
48enum {
49#define DEFINE_MODEL_TYPE_SELECTION(name,value) name = value,
50#include "chrome/browser/sync/profile_sync_service_model_type_selection_android.h"
51#undef DEFINE_MODEL_TYPE_SELECTION
52};
53
54} // namespace
55
56ProfileSyncServiceAndroid::ProfileSyncServiceAndroid(JNIEnv* env, jobject obj)
57 : profile_(NULL),
58 sync_service_(NULL),
59 weak_java_profile_sync_service_(env, obj) {
60 if (g_browser_process == NULL ||
61 g_browser_process->profile_manager() == NULL) {
62 NOTREACHED() << "Browser process or profile manager not initialized";
63 return;
64 }
65
[email protected]dd547a22013-12-12 18:37:4166 profile_ = ProfileManager::GetActiveUserProfile();
[email protected]9049a7b2013-03-07 22:22:0367 if (profile_ == NULL) {
68 NOTREACHED() << "Sync Init: Profile not found.";
69 return;
70 }
71
[email protected]aa5b2ece2013-05-17 00:37:3672 sync_prefs_.reset(new browser_sync::SyncPrefs(profile_->GetPrefs()));
73
[email protected]9049a7b2013-03-07 22:22:0374 sync_service_ =
75 ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile_);
76 DCHECK(sync_service_);
77}
78
79void ProfileSyncServiceAndroid::Init() {
80 sync_service_->AddObserver(this);
[email protected]9049a7b2013-03-07 22:22:0381}
82
83void ProfileSyncServiceAndroid::RemoveObserver() {
84 if (sync_service_->HasObserver(this)) {
85 sync_service_->RemoveObserver(this);
86 }
87}
88
89ProfileSyncServiceAndroid::~ProfileSyncServiceAndroid() {
90 RemoveObserver();
91}
92
93void ProfileSyncServiceAndroid::SendNudgeNotification(
[email protected]2fd6b7032013-09-11 00:20:2594 int object_source,
[email protected]9049a7b2013-03-07 22:22:0395 const std::string& str_object_id,
96 int64 version,
97 const std::string& state) {
98 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
99
100 // TODO(nileshagrawal): Merge this with ChromeInvalidationClient::Invalidate.
101 // Construct the ModelTypeStateMap and send it over with the notification.
[email protected]c56ab9022013-07-12 03:10:08102 invalidation::ObjectId object_id(
[email protected]2fd6b7032013-09-11 00:20:25103 object_source,
[email protected]c56ab9022013-07-12 03:10:08104 str_object_id);
[email protected]163d0632013-10-04 03:51:01105 syncer::ObjectIdInvalidationMap object_ids_with_states;
[email protected]2fd6b7032013-09-11 00:20:25106 if (version == ipc::invalidation::Constants::UNKNOWN) {
[email protected]163d0632013-10-04 03:51:01107 object_ids_with_states.Insert(
108 syncer::Invalidation::InitUnknownVersion(object_id));
[email protected]2fd6b7032013-09-11 00:20:25109 } else {
[email protected]c56ab9022013-07-12 03:10:08110 ObjectIdVersionMap::iterator it =
111 max_invalidation_versions_.find(object_id);
[email protected]9049a7b2013-03-07 22:22:03112 if ((it != max_invalidation_versions_.end()) &&
113 (version <= it->second)) {
114 DVLOG(1) << "Dropping redundant invalidation with version " << version;
115 return;
116 }
[email protected]c56ab9022013-07-12 03:10:08117 max_invalidation_versions_[object_id] = version;
[email protected]163d0632013-10-04 03:51:01118 object_ids_with_states.Insert(
119 syncer::Invalidation::Init(object_id, version, state));
[email protected]9049a7b2013-03-07 22:22:03120 }
121
[email protected]9049a7b2013-03-07 22:22:03122 content::NotificationService::current()->Notify(
123 chrome::NOTIFICATION_SYNC_REFRESH_REMOTE,
124 content::Source<Profile>(profile_),
[email protected]c56ab9022013-07-12 03:10:08125 content::Details<const syncer::ObjectIdInvalidationMap>(
126 &object_ids_with_states));
[email protected]9049a7b2013-03-07 22:22:03127}
128
[email protected]9049a7b2013-03-07 22:22:03129void ProfileSyncServiceAndroid::OnStateChanged() {
[email protected]9049a7b2013-03-07 22:22:03130 // Notify the java world that our sync state has changed.
131 JNIEnv* env = AttachCurrentThread();
132 Java_ProfileSyncService_syncStateChanged(
133 env, weak_java_profile_sync_service_.get(env).obj());
134}
135
[email protected]9049a7b2013-03-07 22:22:03136void ProfileSyncServiceAndroid::EnableSync(JNIEnv* env, jobject) {
137 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
138 // Don't need to do anything if we're already enabled.
[email protected]aa5b2ece2013-05-17 00:37:36139 if (sync_prefs_->IsStartSuppressed())
[email protected]9049a7b2013-03-07 22:22:03140 sync_service_->UnsuppressAndStart();
141 else
142 DVLOG(2) << "Ignoring call to EnableSync() because sync is already enabled";
143}
144
145void ProfileSyncServiceAndroid::DisableSync(JNIEnv* env, jobject) {
146 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]41e0f372013-06-05 19:58:42147 // Don't need to do anything if we're already disabled.
148 if (!sync_prefs_->IsStartSuppressed()) {
149 sync_service_->StopAndSuppress();
150 } else {
151 DVLOG(2)
152 << "Ignoring call to DisableSync() because sync is already disabled";
153 }
[email protected]9049a7b2013-03-07 22:22:03154}
155
[email protected]73da8582013-07-11 10:46:36156void ProfileSyncServiceAndroid::SignInSync(JNIEnv* env, jobject) {
[email protected]9049a7b2013-03-07 22:22:03157 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
158 // Just return if sync already has everything it needs to start up (sync
159 // should start up automatically as long as it has credentials). This can
160 // happen normally if (for example) the user closes and reopens the sync
161 // settings window quickly during initial startup.
162 if (sync_service_->IsSyncEnabledAndLoggedIn() &&
[email protected]b67c18c2013-06-13 23:52:03163 sync_service_->IsOAuthRefreshTokenAvailable() &&
[email protected]9049a7b2013-03-07 22:22:03164 sync_service_->HasSyncSetupCompleted()) {
165 return;
166 }
167
[email protected]9049a7b2013-03-07 22:22:03168 // Enable sync (if we don't have credentials yet, this will enable sync but
169 // will not start it up - sync will start once credentials arrive).
170 sync_service_->UnsuppressAndStart();
171}
172
173void ProfileSyncServiceAndroid::SignOutSync(JNIEnv* env, jobject) {
174 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
175 DCHECK(profile_);
176 sync_service_->DisableForUser();
177
[email protected]9049a7b2013-03-07 22:22:03178 // Need to clear suppress start flag manually
[email protected]aa5b2ece2013-05-17 00:37:36179 sync_prefs_->SetStartSuppressed(false);
[email protected]9049a7b2013-03-07 22:22:03180}
181
182ScopedJavaLocalRef<jstring> ProfileSyncServiceAndroid::QuerySyncStatusSummary(
183 JNIEnv* env, jobject) {
184 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
185 DCHECK(profile_);
[email protected]9e8df052013-09-18 10:47:18186 std::string status(sync_service_->QuerySyncStatusSummaryString());
[email protected]9049a7b2013-03-07 22:22:03187 return ConvertUTF8ToJavaString(env, status);
188}
189
190jboolean ProfileSyncServiceAndroid::SetSyncSessionsId(
191 JNIEnv* env, jobject obj, jstring tag) {
192 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
193 DCHECK(profile_);
194 std::string machine_tag = ConvertJavaStringToUTF8(env, tag);
[email protected]aa5b2ece2013-05-17 00:37:36195 sync_prefs_->SetSyncSessionsGUID(machine_tag);
[email protected]9049a7b2013-03-07 22:22:03196 return true;
197}
198
199jint ProfileSyncServiceAndroid::GetAuthError(JNIEnv* env, jobject) {
200 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
201 return sync_service_->GetAuthError().state();
202}
203
204jboolean ProfileSyncServiceAndroid::IsEncryptEverythingEnabled(
205 JNIEnv* env, jobject) {
206 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
207 return sync_service_->EncryptEverythingEnabled();
208}
209
210jboolean ProfileSyncServiceAndroid::IsSyncInitialized(JNIEnv* env, jobject) {
211 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
212 return sync_service_->sync_initialized();
213}
214
215jboolean ProfileSyncServiceAndroid::IsFirstSetupInProgress(
216 JNIEnv* env, jobject) {
217 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
218 return sync_service_->FirstSetupInProgress();
219}
220
221jboolean ProfileSyncServiceAndroid::IsPassphraseRequired(JNIEnv* env, jobject) {
222 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
223 return sync_service_->IsPassphraseRequired();
224}
225
226jboolean ProfileSyncServiceAndroid::IsPassphraseRequiredForDecryption(
227 JNIEnv* env, jobject obj) {
228 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
229 // In case of CUSTOM_PASSPHRASE we always sync passwords. Prompt the user for
230 // a passphrase if cryptographer has any pending keys.
231 if (sync_service_->GetPassphraseType() == syncer::CUSTOM_PASSPHRASE) {
232 return !IsCryptographerReady(env, obj);
233 }
234 if (sync_service_->IsPassphraseRequiredForDecryption()) {
235 // Passwords datatype should never prompt for a passphrase, except when
236 // user is using a custom passphrase. Do not prompt for a passphrase if
237 // passwords are the only encrypted datatype. This prevents a temporary
238 // notification for passphrase when PSS has not completed configuring
239 // DataTypeManager, after configuration password datatype shall be disabled.
240 const syncer::ModelTypeSet encrypted_types =
241 sync_service_->GetEncryptedDataTypes();
[email protected]1f51ad92013-06-07 02:30:24242 return !encrypted_types.Equals(syncer::ModelTypeSet(syncer::PASSWORDS));
[email protected]9049a7b2013-03-07 22:22:03243 }
244 return false;
245}
246
247jboolean ProfileSyncServiceAndroid::IsPassphraseRequiredForExternalType(
248 JNIEnv* env, jobject) {
249 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
250 return
251 sync_service_->passphrase_required_reason() == syncer::REASON_DECRYPTION;
252}
253
254jboolean ProfileSyncServiceAndroid::IsUsingSecondaryPassphrase(
255 JNIEnv* env, jobject) {
256 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
257 return sync_service_->IsUsingSecondaryPassphrase();
258}
259
260jboolean ProfileSyncServiceAndroid::SetDecryptionPassphrase(
261 JNIEnv* env, jobject obj, jstring passphrase) {
262 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
263 std::string key = ConvertJavaStringToUTF8(env, passphrase);
264 return sync_service_->SetDecryptionPassphrase(key);
265}
266
267void ProfileSyncServiceAndroid::SetEncryptionPassphrase(
268 JNIEnv* env, jobject obj, jstring passphrase, jboolean is_gaia) {
269 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
270 std::string key = ConvertJavaStringToUTF8(env, passphrase);
271 sync_service_->SetEncryptionPassphrase(
272 key,
273 is_gaia ? ProfileSyncService::IMPLICIT : ProfileSyncService::EXPLICIT);
274}
275
276jboolean ProfileSyncServiceAndroid::IsCryptographerReady(JNIEnv* env, jobject) {
277 syncer::ReadTransaction trans(FROM_HERE, sync_service_->GetUserShare());
278 return sync_service_->IsCryptographerReady(&trans);
279}
280
281jint ProfileSyncServiceAndroid::GetPassphraseType(JNIEnv* env, jobject) {
282 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
283 return sync_service_->GetPassphraseType();
284}
285
286jboolean ProfileSyncServiceAndroid::HasExplicitPassphraseTime(
287 JNIEnv* env, jobject) {
288 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
289 base::Time passphrase_time = sync_service_->GetExplicitPassphraseTime();
290 return !passphrase_time.is_null();
291}
292
293ScopedJavaLocalRef<jstring>
294 ProfileSyncServiceAndroid::GetSyncEnterGooglePassphraseBodyWithDateText(
295 JNIEnv* env, jobject) {
296 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
297 base::Time passphrase_time = sync_service_->GetExplicitPassphraseTime();
[email protected]a04db822013-12-11 19:14:40298 base::string16 passphrase_time_str =
299 base::TimeFormatShortDate(passphrase_time);
[email protected]9049a7b2013-03-07 22:22:03300 return base::android::ConvertUTF16ToJavaString(env,
301 l10n_util::GetStringFUTF16(
302 IDS_SYNC_ENTER_GOOGLE_PASSPHRASE_BODY_WITH_DATE,
303 passphrase_time_str));
304}
305
306ScopedJavaLocalRef<jstring>
307 ProfileSyncServiceAndroid::GetSyncEnterCustomPassphraseBodyWithDateText(
308 JNIEnv* env, jobject) {
309 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
310 base::Time passphrase_time = sync_service_->GetExplicitPassphraseTime();
[email protected]a04db822013-12-11 19:14:40311 base::string16 passphrase_time_str =
312 base::TimeFormatShortDate(passphrase_time);
[email protected]9049a7b2013-03-07 22:22:03313 return base::android::ConvertUTF16ToJavaString(env,
314 l10n_util::GetStringFUTF16(IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE,
315 passphrase_time_str));
316}
317
318ScopedJavaLocalRef<jstring>
[email protected]4faa9de02013-03-26 10:17:20319 ProfileSyncServiceAndroid::GetCurrentSignedInAccountText(
320 JNIEnv* env, jobject) {
321 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
322 const std::string& sync_username =
323 SigninManagerFactory::GetForProfile(profile_)->GetAuthenticatedUsername();
324 return base::android::ConvertUTF16ToJavaString(env,
325 l10n_util::GetStringFUTF16(
326 IDS_SYNC_ACCOUNT_SYNCING_TO_USER,
[email protected]f911df52013-12-24 23:24:23327 base::ASCIIToUTF16(sync_username)));
[email protected]4faa9de02013-03-26 10:17:20328}
329
330ScopedJavaLocalRef<jstring>
[email protected]9049a7b2013-03-07 22:22:03331 ProfileSyncServiceAndroid::GetSyncEnterCustomPassphraseBodyText(
332 JNIEnv* env, jobject) {
333 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
334 return ConvertUTF8ToJavaString(
335 env, l10n_util::GetStringUTF8(IDS_SYNC_ENTER_PASSPHRASE_BODY));
336}
337
338jboolean ProfileSyncServiceAndroid::IsSyncKeystoreMigrationDone(
339 JNIEnv* env, jobject) {
340 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
341 syncer::SyncStatus status;
342 bool is_status_valid = sync_service_->QueryDetailedSyncStatus(&status);
343 return is_status_valid && !status.keystore_migration_time.is_null();
344}
345
[email protected]6805b602013-03-27 21:18:18346jlong ProfileSyncServiceAndroid::GetEnabledDataTypes(JNIEnv* env,
347 jobject obj) {
348 jlong model_type_selection = 0;
[email protected]464d74a2013-06-04 07:36:46349 syncer::ModelTypeSet types = sync_service_->GetActiveDataTypes();
[email protected]6805b602013-03-27 21:18:18350 types.PutAll(syncer::ControlTypes());
351 if (types.Has(syncer::BOOKMARKS)) {
352 model_type_selection |= BOOKMARK;
353 }
354 if (types.Has(syncer::AUTOFILL)) {
355 model_type_selection |= AUTOFILL;
356 }
357 if (types.Has(syncer::AUTOFILL_PROFILE)) {
358 model_type_selection |= AUTOFILL_PROFILE;
359 }
360 if (types.Has(syncer::PASSWORDS)) {
361 model_type_selection |= PASSWORD;
362 }
363 if (types.Has(syncer::TYPED_URLS)) {
364 model_type_selection |= TYPED_URL;
365 }
366 if (types.Has(syncer::SESSIONS)) {
367 model_type_selection |= SESSION;
368 }
369 if (types.Has(syncer::HISTORY_DELETE_DIRECTIVES)) {
370 model_type_selection |= HISTORY_DELETE_DIRECTIVE;
371 }
372 if (types.Has(syncer::PROXY_TABS)) {
373 model_type_selection |= PROXY_TABS;
374 }
375 if (types.Has(syncer::FAVICON_IMAGES)) {
376 model_type_selection |= FAVICON_IMAGE;
377 }
378 if (types.Has(syncer::FAVICON_TRACKING)) {
379 model_type_selection |= FAVICON_TRACKING;
380 }
381 if (types.Has(syncer::DEVICE_INFO)) {
382 model_type_selection |= DEVICE_INFO;
383 }
384 if (types.Has(syncer::NIGORI)) {
385 model_type_selection |= NIGORI;
386 }
387 if (types.Has(syncer::EXPERIMENTS)) {
388 model_type_selection |= EXPERIMENTS;
389 }
390 return model_type_selection;
391}
392
[email protected]9049a7b2013-03-07 22:22:03393void ProfileSyncServiceAndroid::SetPreferredDataTypes(
394 JNIEnv* env, jobject obj,
395 jboolean sync_everything,
396 jlong model_type_selection) {
397 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
398 syncer::ModelTypeSet types;
[email protected]6805b602013-03-27 21:18:18399 // Note: only user selectable types should be included here.
[email protected]9049a7b2013-03-07 22:22:03400 if (model_type_selection & AUTOFILL)
401 types.Put(syncer::AUTOFILL);
402 if (model_type_selection & BOOKMARK)
403 types.Put(syncer::BOOKMARKS);
404 if (model_type_selection & PASSWORD)
405 types.Put(syncer::PASSWORDS);
[email protected]88dfd0e2013-04-02 20:55:02406 if (model_type_selection & PROXY_TABS)
407 types.Put(syncer::PROXY_TABS);
[email protected]9049a7b2013-03-07 22:22:03408 if (model_type_selection & TYPED_URL)
409 types.Put(syncer::TYPED_URLS);
[email protected]6805b602013-03-27 21:18:18410 DCHECK(syncer::UserSelectableTypes().HasAll(types));
[email protected]9049a7b2013-03-07 22:22:03411 sync_service_->OnUserChoseDatatypes(sync_everything, types);
412}
413
414void ProfileSyncServiceAndroid::SetSetupInProgress(
415 JNIEnv* env, jobject obj, jboolean in_progress) {
416 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
417 sync_service_->SetSetupInProgress(in_progress);
418}
419
420void ProfileSyncServiceAndroid::SetSyncSetupCompleted(
421 JNIEnv* env, jobject obj) {
422 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
423 sync_service_->SetSyncSetupCompleted();
424}
425
426jboolean ProfileSyncServiceAndroid::HasSyncSetupCompleted(
427 JNIEnv* env, jobject obj) {
428 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
429 return sync_service_->HasSyncSetupCompleted();
430}
431
[email protected]aa5b2ece2013-05-17 00:37:36432jboolean ProfileSyncServiceAndroid::IsStartSuppressed(
433 JNIEnv* env, jobject obj) {
434 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
435 return sync_prefs_->IsStartSuppressed();
436}
437
[email protected]9049a7b2013-03-07 22:22:03438void ProfileSyncServiceAndroid::EnableEncryptEverything(
439 JNIEnv* env, jobject obj) {
440 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
441 sync_service_->EnableEncryptEverything();
442}
443
444jboolean ProfileSyncServiceAndroid::HasKeepEverythingSynced(
445 JNIEnv* env, jobject) {
446 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]aa5b2ece2013-05-17 00:37:36447 return sync_prefs_->HasKeepEverythingSynced();
[email protected]9049a7b2013-03-07 22:22:03448}
449
[email protected]9049a7b2013-03-07 22:22:03450jboolean ProfileSyncServiceAndroid::HasUnrecoverableError(
451 JNIEnv* env, jobject) {
452 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
453 return sync_service_->HasUnrecoverableError();
454}
455
456ScopedJavaLocalRef<jstring> ProfileSyncServiceAndroid::GetAboutInfoForTest(
457 JNIEnv* env, jobject) {
458 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
459
[email protected]dbb9aa42013-12-23 20:08:21460 scoped_ptr<base::DictionaryValue> about_info =
[email protected]9049a7b2013-03-07 22:22:03461 sync_ui_util::ConstructAboutInformation(sync_service_);
462 std::string about_info_json;
463 base::JSONWriter::Write(about_info.get(), &about_info_json);
464
465 return ConvertUTF8ToJavaString(env, about_info_json);
466}
467
[email protected]ed4d7052013-09-04 19:01:37468jlong ProfileSyncServiceAndroid::GetLastSyncedTimeForTest(
469 JNIEnv* env, jobject obj) {
470 // Use profile preferences here instead of SyncPrefs to avoid an extra
471 // conversion, since SyncPrefs::GetLastSyncedTime() converts the stored value
472 // to to base::Time.
473 return static_cast<jlong>(
474 profile_->GetPrefs()->GetInt64(prefs::kSyncLastSyncedTime));
475}
476
[email protected]9049a7b2013-03-07 22:22:03477void ProfileSyncServiceAndroid::NudgeSyncer(JNIEnv* env,
478 jobject obj,
[email protected]2fd6b7032013-09-11 00:20:25479 jint objectSource,
[email protected]9049a7b2013-03-07 22:22:03480 jstring objectId,
481 jlong version,
482 jstring state) {
483 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]2fd6b7032013-09-11 00:20:25484 SendNudgeNotification(objectSource, ConvertJavaStringToUTF8(env, objectId),
485 version, ConvertJavaStringToUTF8(env, state));
[email protected]9049a7b2013-03-07 22:22:03486}
487
[email protected]8f63ef22013-07-17 02:09:37488void ProfileSyncServiceAndroid::NudgeSyncerForAllTypes(JNIEnv* env,
489 jobject obj) {
490 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
491 syncer::ObjectIdInvalidationMap object_ids_with_states;
492 content::NotificationService::current()->Notify(
493 chrome::NOTIFICATION_SYNC_REFRESH_REMOTE,
494 content::Source<Profile>(profile_),
495 content::Details<const syncer::ObjectIdInvalidationMap>(
496 &object_ids_with_states));
497}
498
[email protected]332a83362013-03-26 08:45:55499// static
500ProfileSyncServiceAndroid*
501 ProfileSyncServiceAndroid::GetProfileSyncServiceAndroid() {
502 return reinterpret_cast<ProfileSyncServiceAndroid*>(
503 Java_ProfileSyncService_getProfileSyncServiceAndroid(
504 AttachCurrentThread(), base::android::GetApplicationContext()));
505}
506
[email protected]d557b6042013-11-21 16:34:31507static jlong Init(JNIEnv* env, jobject obj) {
[email protected]9049a7b2013-03-07 22:22:03508 ProfileSyncServiceAndroid* profile_sync_service_android =
509 new ProfileSyncServiceAndroid(env, obj);
510 profile_sync_service_android->Init();
[email protected]d557b6042013-11-21 16:34:31511 return reinterpret_cast<intptr_t>(profile_sync_service_android);
[email protected]9049a7b2013-03-07 22:22:03512}
513
514// static
515bool ProfileSyncServiceAndroid::Register(JNIEnv* env) {
516 return RegisterNativesImpl(env);
517}