blob: c2cf934218c2dcb1abb41a278d6eee7f8583dc34 [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]9049a7b2013-03-07 22:22:0315#include "base/time.h"
[email protected]4faa9de02013-03-26 10:17:2016#include "base/utf_string_conversions.h"
[email protected]9049a7b2013-03-07 22:22:0317#include "chrome/browser/browser_process.h"
18#include "chrome/browser/profiles/profile_manager.h"
[email protected]332a83362013-03-26 08:45:5519#include "chrome/browser/signin/oauth2_token_service.h"
[email protected]9049a7b2013-03-07 22:22:0320#include "chrome/browser/signin/signin_manager.h"
21#include "chrome/browser/signin/signin_manager_factory.h"
22#include "chrome/browser/signin/token_service.h"
23#include "chrome/browser/signin/token_service_factory.h"
24#include "chrome/browser/sync/about_sync_util.h"
25#include "chrome/browser/sync/profile_sync_service.h"
26#include "chrome/browser/sync/profile_sync_service_factory.h"
27#include "chrome/browser/sync/sync_prefs.h"
28#include "chrome/browser/sync/sync_ui_util.h"
29#include "chrome/common/chrome_notification_types.h"
30#include "chrome/common/pref_names.h"
31#include "content/public/browser/notification_service.h"
32#include "google/cacheinvalidation/types.pb.h"
33#include "google_apis/gaia/gaia_constants.h"
34#include "google_apis/gaia/google_service_auth_error.h"
35#include "grit/generated_resources.h"
36#include "jni/ProfileSyncService_jni.h"
37#include "sync/internal_api/public/base/model_type_invalidation_map.h"
38#include "sync/internal_api/public/read_transaction.h"
39#include "ui/base/l10n/l10n_util.h"
40
41using base::android::AttachCurrentThread;
42using base::android::CheckException;
43using base::android::ConvertJavaStringToUTF8;
44using base::android::ConvertUTF8ToJavaString;
45using base::android::ScopedJavaLocalRef;
46using content::BrowserThread;
47
48namespace {
49const char kSyncDisabledStatus[] = "OFFLINE_DISABLED";
50
51enum {
52#define DEFINE_MODEL_TYPE_SELECTION(name,value) name = value,
53#include "chrome/browser/sync/profile_sync_service_model_type_selection_android.h"
54#undef DEFINE_MODEL_TYPE_SELECTION
55};
56
57} // namespace
58
59ProfileSyncServiceAndroid::ProfileSyncServiceAndroid(JNIEnv* env, jobject obj)
60 : profile_(NULL),
61 sync_service_(NULL),
62 weak_java_profile_sync_service_(env, obj) {
63 if (g_browser_process == NULL ||
64 g_browser_process->profile_manager() == NULL) {
65 NOTREACHED() << "Browser process or profile manager not initialized";
66 return;
67 }
68
69 profile_ = g_browser_process->profile_manager()->GetDefaultProfile();
70 if (profile_ == NULL) {
71 NOTREACHED() << "Sync Init: Profile not found.";
72 return;
73 }
74
75 sync_service_ =
76 ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile_);
77 DCHECK(sync_service_);
78}
79
80void ProfileSyncServiceAndroid::Init() {
81 sync_service_->AddObserver(this);
82
83 std::string signed_in_username =
84 SigninManagerFactory::GetForProfile(profile_)->GetAuthenticatedUsername();
85 if (!signed_in_username.empty()) {
86 // If the user is logged in, see if he has a valid token - if not, fetch
87 // a new one.
88 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_);
89 if (!token_service->HasTokenForService(GaiaConstants::kSyncService) ||
90 (sync_service_->GetAuthError().state() ==
91 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)) {
92 DVLOG(2) << "Trying to update token for user " << signed_in_username;
93 InvalidateAuthToken();
94 }
95 }
96}
97
98void ProfileSyncServiceAndroid::RemoveObserver() {
99 if (sync_service_->HasObserver(this)) {
100 sync_service_->RemoveObserver(this);
101 }
102}
103
104ProfileSyncServiceAndroid::~ProfileSyncServiceAndroid() {
105 RemoveObserver();
106}
107
108void ProfileSyncServiceAndroid::SendNudgeNotification(
109 const std::string& str_object_id,
110 int64 version,
111 const std::string& state) {
112 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
113
114 // TODO(nileshagrawal): Merge this with ChromeInvalidationClient::Invalidate.
115 // Construct the ModelTypeStateMap and send it over with the notification.
116 syncer::ModelType model_type;
117 if (!syncer::NotificationTypeToRealModelType(str_object_id, &model_type)) {
118 DVLOG(1) << "Could not get invalidation model type; "
119 << "Sending notification with empty state map.";
120 syncer::ModelTypeInvalidationMap model_types_with_states;
121 content::NotificationService::current()->Notify(
122 chrome::NOTIFICATION_SYNC_REFRESH_REMOTE,
123 content::Source<Profile>(profile_),
124 content::Details<const syncer::ModelTypeInvalidationMap>(
125 &model_types_with_states));
126 return;
127 }
128
129 if (version != ipc::invalidation::Constants::UNKNOWN) {
130 std::map<syncer::ModelType, int64>::const_iterator it =
131 max_invalidation_versions_.find(model_type);
132 if ((it != max_invalidation_versions_.end()) &&
133 (version <= it->second)) {
134 DVLOG(1) << "Dropping redundant invalidation with version " << version;
135 return;
136 }
137 max_invalidation_versions_[model_type] = version;
138 }
139
140 syncer::ModelTypeSet types;
141 types.Put(model_type);
142 syncer::ModelTypeInvalidationMap model_types_with_states =
143 syncer::ModelTypeSetToInvalidationMap(types, state);
144
145 content::NotificationService::current()->Notify(
146 chrome::NOTIFICATION_SYNC_REFRESH_REMOTE,
147 content::Source<Profile>(profile_),
148 content::Details<const syncer::ModelTypeInvalidationMap>(
149 &model_types_with_states));
150}
151
152
153void ProfileSyncServiceAndroid::OnStateChanged() {
154 // Check for auth errors.
155 const GoogleServiceAuthError& auth_error = sync_service_->GetAuthError();
156 if (auth_error.state() == GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS) {
157 DVLOG(2) << "Updating auth token.";
158 InvalidateAuthToken();
159 }
160
161 // Notify the java world that our sync state has changed.
162 JNIEnv* env = AttachCurrentThread();
163 Java_ProfileSyncService_syncStateChanged(
164 env, weak_java_profile_sync_service_.get(env).obj());
165}
166
167void ProfileSyncServiceAndroid::TokenAvailable(
168 JNIEnv* env, jobject, jstring username, jstring auth_token) {
169 std::string token = ConvertJavaStringToUTF8(env, auth_token);
170 TokenServiceFactory::GetForProfile(profile_)->OnIssueAuthTokenSuccess(
171 GaiaConstants::kSyncService, token);
172}
173
[email protected]332a83362013-03-26 08:45:55174void ProfileSyncServiceAndroid::InvalidateOAuth2Token(
175 const std::string& scope, const std::string& invalid_token) {
176 JNIEnv* env = AttachCurrentThread();
177 ScopedJavaLocalRef<jstring> j_scope =
178 ConvertUTF8ToJavaString(env, scope);
179 ScopedJavaLocalRef<jstring> j_invalid_token =
180 ConvertUTF8ToJavaString(env, invalid_token);
181 Java_ProfileSyncService_invalidateOAuth2AuthToken(
182 env, weak_java_profile_sync_service_.get(env).obj(),
183 j_scope.obj(),
184 j_invalid_token.obj());
185}
186
187void ProfileSyncServiceAndroid::FetchOAuth2Token(
188 const std::string& scope, const FetchOAuth2TokenCallback& callback) {
189 const std::string& sync_username =
190 SigninManagerFactory::GetForProfile(profile_)->GetAuthenticatedUsername();
191
192 JNIEnv* env = AttachCurrentThread();
193 ScopedJavaLocalRef<jstring> j_sync_username =
194 ConvertUTF8ToJavaString(env, sync_username);
195 ScopedJavaLocalRef<jstring> j_scope =
196 ConvertUTF8ToJavaString(env, scope);
197
198 // Allocate a copy of the callback on the heap, because the callback
199 // needs to be passed through JNI as an int.
200 // It will be passed back to OAuth2TokenFetched(), where it will be freed.
201 scoped_ptr<FetchOAuth2TokenCallback> heap_callback(
202 new FetchOAuth2TokenCallback(callback));
203
204 // Call into Java to get a new token.
205 Java_ProfileSyncService_getOAuth2AuthToken(
206 env, weak_java_profile_sync_service_.get(env).obj(),
207 j_sync_username.obj(),
208 j_scope.obj(),
209 reinterpret_cast<int>(heap_callback.release()));
210}
211
212void ProfileSyncServiceAndroid::OAuth2TokenFetched(
213 JNIEnv* env, jobject, int callback, jstring auth_token, jboolean result) {
214 std::string token = ConvertJavaStringToUTF8(env, auth_token);
215 scoped_ptr<FetchOAuth2TokenCallback> heap_callback(
216 reinterpret_cast<FetchOAuth2TokenCallback*>(callback));
217 GoogleServiceAuthError err(result ?
218 GoogleServiceAuthError::NONE :
219 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
220 heap_callback->Run(err, token, base::Time());
221}
222
[email protected]9049a7b2013-03-07 22:22:03223void ProfileSyncServiceAndroid::EnableSync(JNIEnv* env, jobject) {
224 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
225 // Don't need to do anything if we're already enabled.
226 browser_sync::SyncPrefs prefs(profile_->GetPrefs());
227 if (prefs.IsStartSuppressed())
228 sync_service_->UnsuppressAndStart();
229 else
230 DVLOG(2) << "Ignoring call to EnableSync() because sync is already enabled";
231}
232
233void ProfileSyncServiceAndroid::DisableSync(JNIEnv* env, jobject) {
234 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
235 sync_service_->StopAndSuppress();
236}
237
238void ProfileSyncServiceAndroid::SignInSync(
239 JNIEnv* env, jobject, jstring username, jstring auth_token) {
240 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
241 // Just return if sync already has everything it needs to start up (sync
242 // should start up automatically as long as it has credentials). This can
243 // happen normally if (for example) the user closes and reopens the sync
244 // settings window quickly during initial startup.
245 if (sync_service_->IsSyncEnabledAndLoggedIn() &&
246 sync_service_->IsSyncTokenAvailable() &&
247 sync_service_->HasSyncSetupCompleted()) {
248 return;
249 }
250
251 if (!sync_service_->IsSyncEnabledAndLoggedIn() ||
252 !sync_service_->IsSyncTokenAvailable()) {
253 // Set the currently-signed-in username, fetch an auth token if necessary,
254 // and enable sync.
255 std::string name = ConvertJavaStringToUTF8(env, username);
[email protected]34ee0512013-03-12 17:49:54256 // TODO(tim) It should be enough to only call
257 // SigninManager::SetAuthenticatedUsername here. See
258 // http://crbug.com/107160.
259 profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername, name);
[email protected]9049a7b2013-03-07 22:22:03260 SigninManagerFactory::GetForProfile(profile_)->
261 SetAuthenticatedUsername(name);
262 std::string token = ConvertJavaStringToUTF8(env, auth_token);
263 if (token.empty()) {
264 // No credentials passed in - request an auth token.
265 // If fetching the auth token is successful, this will cause
266 // ProfileSyncService to start sync when it receives
267 // NOTIFICATION_TOKEN_AVAILABLE.
268 DVLOG(2) << "Fetching auth token for " << name;
269 InvalidateAuthToken();
270 } else {
271 // OnIssueAuthTokenSuccess will send out a notification to the sync
272 // service that will cause the sync backend to initialize.
273 TokenService* token_service =
274 TokenServiceFactory::GetForProfile(profile_);
275 token_service->OnIssueAuthTokenSuccess(GaiaConstants::kSyncService,
276 token);
277 }
278 }
279
280 // Enable sync (if we don't have credentials yet, this will enable sync but
281 // will not start it up - sync will start once credentials arrive).
282 sync_service_->UnsuppressAndStart();
283}
284
285void ProfileSyncServiceAndroid::SignOutSync(JNIEnv* env, jobject) {
286 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
287 DCHECK(profile_);
288 sync_service_->DisableForUser();
289
290 // Clear the tokens.
291 SigninManagerFactory::GetForProfile(profile_)->SignOut();
292
293 // Need to clear suppress start flag manually
294 browser_sync::SyncPrefs prefs(profile_->GetPrefs());
295 prefs.SetStartSuppressed(false);
296}
297
298ScopedJavaLocalRef<jstring> ProfileSyncServiceAndroid::QuerySyncStatusSummary(
299 JNIEnv* env, jobject) {
300 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
301 DCHECK(profile_);
302 std::string status(sync_service_->QuerySyncStatusSummary());
303 return ConvertUTF8ToJavaString(env, status);
304}
305
306jboolean ProfileSyncServiceAndroid::SetSyncSessionsId(
307 JNIEnv* env, jobject obj, jstring tag) {
308 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
309 DCHECK(profile_);
310 std::string machine_tag = ConvertJavaStringToUTF8(env, tag);
311 browser_sync::SyncPrefs prefs(profile_->GetPrefs());
312 prefs.SetSyncSessionsGUID(machine_tag);
313 return true;
314}
315
316jint ProfileSyncServiceAndroid::GetAuthError(JNIEnv* env, jobject) {
317 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
318 return sync_service_->GetAuthError().state();
319}
320
321jboolean ProfileSyncServiceAndroid::IsEncryptEverythingEnabled(
322 JNIEnv* env, jobject) {
323 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
324 return sync_service_->EncryptEverythingEnabled();
325}
326
327jboolean ProfileSyncServiceAndroid::IsSyncInitialized(JNIEnv* env, jobject) {
328 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
329 return sync_service_->sync_initialized();
330}
331
332jboolean ProfileSyncServiceAndroid::IsFirstSetupInProgress(
333 JNIEnv* env, jobject) {
334 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
335 return sync_service_->FirstSetupInProgress();
336}
337
338jboolean ProfileSyncServiceAndroid::IsPassphraseRequired(JNIEnv* env, jobject) {
339 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
340 return sync_service_->IsPassphraseRequired();
341}
342
343jboolean ProfileSyncServiceAndroid::IsPassphraseRequiredForDecryption(
344 JNIEnv* env, jobject obj) {
345 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
346 // In case of CUSTOM_PASSPHRASE we always sync passwords. Prompt the user for
347 // a passphrase if cryptographer has any pending keys.
348 if (sync_service_->GetPassphraseType() == syncer::CUSTOM_PASSPHRASE) {
349 return !IsCryptographerReady(env, obj);
350 }
351 if (sync_service_->IsPassphraseRequiredForDecryption()) {
352 // Passwords datatype should never prompt for a passphrase, except when
353 // user is using a custom passphrase. Do not prompt for a passphrase if
354 // passwords are the only encrypted datatype. This prevents a temporary
355 // notification for passphrase when PSS has not completed configuring
356 // DataTypeManager, after configuration password datatype shall be disabled.
357 const syncer::ModelTypeSet encrypted_types =
358 sync_service_->GetEncryptedDataTypes();
359 const bool are_passwords_the_only_encrypted_type =
360 encrypted_types.Has(syncer::PASSWORDS) && encrypted_types.Size() == 1 &&
361 !sync_service_->ShouldEnablePasswordSyncForAndroid();
362 return !are_passwords_the_only_encrypted_type;
363 }
364 return false;
365}
366
367jboolean ProfileSyncServiceAndroid::IsPassphraseRequiredForExternalType(
368 JNIEnv* env, jobject) {
369 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
370 return
371 sync_service_->passphrase_required_reason() == syncer::REASON_DECRYPTION;
372}
373
374jboolean ProfileSyncServiceAndroid::IsUsingSecondaryPassphrase(
375 JNIEnv* env, jobject) {
376 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
377 return sync_service_->IsUsingSecondaryPassphrase();
378}
379
380jboolean ProfileSyncServiceAndroid::SetDecryptionPassphrase(
381 JNIEnv* env, jobject obj, jstring passphrase) {
382 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
383 std::string key = ConvertJavaStringToUTF8(env, passphrase);
384 return sync_service_->SetDecryptionPassphrase(key);
385}
386
387void ProfileSyncServiceAndroid::SetEncryptionPassphrase(
388 JNIEnv* env, jobject obj, jstring passphrase, jboolean is_gaia) {
389 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
390 std::string key = ConvertJavaStringToUTF8(env, passphrase);
391 sync_service_->SetEncryptionPassphrase(
392 key,
393 is_gaia ? ProfileSyncService::IMPLICIT : ProfileSyncService::EXPLICIT);
394}
395
396jboolean ProfileSyncServiceAndroid::IsCryptographerReady(JNIEnv* env, jobject) {
397 syncer::ReadTransaction trans(FROM_HERE, sync_service_->GetUserShare());
398 return sync_service_->IsCryptographerReady(&trans);
399}
400
401jint ProfileSyncServiceAndroid::GetPassphraseType(JNIEnv* env, jobject) {
402 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
403 return sync_service_->GetPassphraseType();
404}
405
406jboolean ProfileSyncServiceAndroid::HasExplicitPassphraseTime(
407 JNIEnv* env, jobject) {
408 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
409 base::Time passphrase_time = sync_service_->GetExplicitPassphraseTime();
410 return !passphrase_time.is_null();
411}
412
413ScopedJavaLocalRef<jstring>
414 ProfileSyncServiceAndroid::GetSyncEnterGooglePassphraseBodyWithDateText(
415 JNIEnv* env, jobject) {
416 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
417 base::Time passphrase_time = sync_service_->GetExplicitPassphraseTime();
418 string16 passphrase_time_str = base::TimeFormatShortDate(passphrase_time);
419 return base::android::ConvertUTF16ToJavaString(env,
420 l10n_util::GetStringFUTF16(
421 IDS_SYNC_ENTER_GOOGLE_PASSPHRASE_BODY_WITH_DATE,
422 passphrase_time_str));
423}
424
425ScopedJavaLocalRef<jstring>
426 ProfileSyncServiceAndroid::GetSyncEnterCustomPassphraseBodyWithDateText(
427 JNIEnv* env, jobject) {
428 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
429 base::Time passphrase_time = sync_service_->GetExplicitPassphraseTime();
430 string16 passphrase_time_str = base::TimeFormatShortDate(passphrase_time);
431 return base::android::ConvertUTF16ToJavaString(env,
432 l10n_util::GetStringFUTF16(IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE,
433 passphrase_time_str));
434}
435
436ScopedJavaLocalRef<jstring>
[email protected]4faa9de02013-03-26 10:17:20437 ProfileSyncServiceAndroid::GetCurrentSignedInAccountText(
438 JNIEnv* env, jobject) {
439 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
440 const std::string& sync_username =
441 SigninManagerFactory::GetForProfile(profile_)->GetAuthenticatedUsername();
442 return base::android::ConvertUTF16ToJavaString(env,
443 l10n_util::GetStringFUTF16(
444 IDS_SYNC_ACCOUNT_SYNCING_TO_USER,
445 ASCIIToUTF16(sync_username)));
446}
447
448ScopedJavaLocalRef<jstring>
[email protected]9049a7b2013-03-07 22:22:03449 ProfileSyncServiceAndroid::GetSyncEnterCustomPassphraseBodyText(
450 JNIEnv* env, jobject) {
451 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
452 return ConvertUTF8ToJavaString(
453 env, l10n_util::GetStringUTF8(IDS_SYNC_ENTER_PASSPHRASE_BODY));
454}
455
456jboolean ProfileSyncServiceAndroid::IsSyncKeystoreMigrationDone(
457 JNIEnv* env, jobject) {
458 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
459 syncer::SyncStatus status;
460 bool is_status_valid = sync_service_->QueryDetailedSyncStatus(&status);
461 return is_status_valid && !status.keystore_migration_time.is_null();
462}
463
464void ProfileSyncServiceAndroid::SetPreferredDataTypes(
465 JNIEnv* env, jobject obj,
466 jboolean sync_everything,
467 jlong model_type_selection) {
468 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
469 syncer::ModelTypeSet types;
470 if (model_type_selection & AUTOFILL)
471 types.Put(syncer::AUTOFILL);
472 if (model_type_selection & BOOKMARK)
473 types.Put(syncer::BOOKMARKS);
474 if (model_type_selection & PASSWORD)
475 types.Put(syncer::PASSWORDS);
476 if (model_type_selection & SESSION)
477 types.Put(syncer::SESSIONS);
478 if (model_type_selection & TYPED_URL)
479 types.Put(syncer::TYPED_URLS);
480 sync_service_->OnUserChoseDatatypes(sync_everything, types);
481}
482
483void ProfileSyncServiceAndroid::SetSetupInProgress(
484 JNIEnv* env, jobject obj, jboolean in_progress) {
485 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
486 sync_service_->SetSetupInProgress(in_progress);
487}
488
489void ProfileSyncServiceAndroid::SetSyncSetupCompleted(
490 JNIEnv* env, jobject obj) {
491 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
492 sync_service_->SetSyncSetupCompleted();
493}
494
495jboolean ProfileSyncServiceAndroid::HasSyncSetupCompleted(
496 JNIEnv* env, jobject obj) {
497 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
498 return sync_service_->HasSyncSetupCompleted();
499}
500
501void ProfileSyncServiceAndroid::EnableEncryptEverything(
502 JNIEnv* env, jobject obj) {
503 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
504 sync_service_->EnableEncryptEverything();
505}
506
507jboolean ProfileSyncServiceAndroid::HasKeepEverythingSynced(
508 JNIEnv* env, jobject) {
509 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
510 browser_sync::SyncPrefs prefs(profile_->GetPrefs());
511 return prefs.HasKeepEverythingSynced();
512}
513
514jboolean ProfileSyncServiceAndroid::IsAutofillSyncEnabled(
515 JNIEnv* env, jobject obj) {
516 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
517 return HasKeepEverythingSynced(env, obj) ||
518 sync_service_->GetPreferredDataTypes().Has(syncer::AUTOFILL);
519}
520
521jboolean ProfileSyncServiceAndroid::IsBookmarkSyncEnabled(
522 JNIEnv* env, jobject obj) {
523 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
524 return HasKeepEverythingSynced(env, obj) ||
525 sync_service_->GetPreferredDataTypes().Has(syncer::BOOKMARKS);
526}
527
528jboolean ProfileSyncServiceAndroid::IsPasswordSyncEnabled(
529 JNIEnv* env, jobject obj) {
530 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
531 return HasKeepEverythingSynced(env, obj) ||
532 sync_service_->GetPreferredDataTypes().Has(syncer::PASSWORDS);
533}
534
535jboolean ProfileSyncServiceAndroid::IsTypedUrlSyncEnabled(
536 JNIEnv* env, jobject obj) {
537 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
538 return HasKeepEverythingSynced(env, obj) ||
539 sync_service_->GetPreferredDataTypes().Has(syncer::TYPED_URLS);
540}
541
542jboolean ProfileSyncServiceAndroid::IsSessionSyncEnabled(
543 JNIEnv* env, jobject obj) {
544 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
545 return HasKeepEverythingSynced(env, obj) ||
546 sync_service_->GetPreferredDataTypes().Has(syncer::SESSIONS);
547}
548
549jboolean ProfileSyncServiceAndroid::HasUnrecoverableError(
550 JNIEnv* env, jobject) {
551 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
552 return sync_service_->HasUnrecoverableError();
553}
554
555ScopedJavaLocalRef<jstring> ProfileSyncServiceAndroid::GetAboutInfoForTest(
556 JNIEnv* env, jobject) {
557 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
558
559 scoped_ptr<DictionaryValue> about_info =
560 sync_ui_util::ConstructAboutInformation(sync_service_);
561 std::string about_info_json;
562 base::JSONWriter::Write(about_info.get(), &about_info_json);
563
564 return ConvertUTF8ToJavaString(env, about_info_json);
565}
566
567void ProfileSyncServiceAndroid::InvalidateAuthToken() {
568 // Get the token from token-db. If there's no token yet, this must be the
569 // the first time the user is signing in so we don't need to invalidate
570 // anything.
571 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_);
572 std::string invalid_token;
573 if (token_service->HasTokenForService(GaiaConstants::kSyncService)) {
574 invalid_token = token_service->GetTokenForService(
575 GaiaConstants::kSyncService);
576 }
577 const std::string& sync_username =
578 SigninManagerFactory::GetForProfile(profile_)->GetAuthenticatedUsername();
579 // Call into java to invalidate the current token and get a new one.
580 JNIEnv* env = AttachCurrentThread();
581 ScopedJavaLocalRef<jstring> j_sync_username =
582 ConvertUTF8ToJavaString(env, sync_username);
583 ScopedJavaLocalRef<jstring> j_invalid_token =
584 ConvertUTF8ToJavaString(env, invalid_token);
585 Java_ProfileSyncService_getNewAuthToken(
586 env, weak_java_profile_sync_service_.get(env).obj(),
587 j_sync_username.obj(), j_invalid_token.obj());
588}
589
590void ProfileSyncServiceAndroid::NudgeSyncer(JNIEnv* env,
591 jobject obj,
592 jstring objectId,
593 jlong version,
594 jstring state) {
595 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
596 SendNudgeNotification(ConvertJavaStringToUTF8(env, objectId), version,
597 ConvertJavaStringToUTF8(env, state));
598}
599
[email protected]332a83362013-03-26 08:45:55600// static
601ProfileSyncServiceAndroid*
602 ProfileSyncServiceAndroid::GetProfileSyncServiceAndroid() {
603 return reinterpret_cast<ProfileSyncServiceAndroid*>(
604 Java_ProfileSyncService_getProfileSyncServiceAndroid(
605 AttachCurrentThread(), base::android::GetApplicationContext()));
606}
607
[email protected]9049a7b2013-03-07 22:22:03608static int Init(JNIEnv* env, jobject obj) {
609 ProfileSyncServiceAndroid* profile_sync_service_android =
610 new ProfileSyncServiceAndroid(env, obj);
611 profile_sync_service_android->Init();
612 return reinterpret_cast<jint>(profile_sync_service_android);
613}
614
615// static
616bool ProfileSyncServiceAndroid::Register(JNIEnv* env) {
617 return RegisterNativesImpl(env);
618}