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