1 // 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"
14 #include "base/prefs/pref_service.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "base/time/time.h"
17 #include "chrome/browser/browser_process.h"
18 #include "chrome/browser/chrome_notification_types.h"
19 #include "chrome/browser/profiles/profile_manager.h"
20 #include "chrome/browser/signin/signin_manager_factory.h"
21 #include "chrome/browser/sync/about_sync_util.h"
22 #include "chrome/browser/sync/profile_sync_service.h"
23 #include "chrome/browser/sync/profile_sync_service_factory.h"
24 #include "chrome/browser/sync/sync_ui_util.h"
25 #include "chrome/grit/generated_resources.h"
26 #include "components/invalidation/object_id_invalidation_map.h"
27 #include "components/signin/core/browser/signin_manager.h"
28 #include "components/sync_driver/pref_names.h"
29 #include "components/sync_driver/sync_prefs.h"
30 #include "content/public/browser/browser_thread.h"
31 #include "content/public/browser/notification_service.h"
32 #include "content/public/browser/notification_source.h"
33 #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 "jni/ProfileSyncService_jni.h"
37 #include "sync/internal_api/public/network_resources.h"
38 #include "sync/internal_api/public/read_transaction.h"
39 #include "ui/base/l10n/l10n_util.h"
40
41 using base::android::AttachCurrentThread;
42 using base::android::CheckException;
43 using base::android::ConvertJavaStringToUTF8;
44 using base::android::ConvertUTF8ToJavaString;
45 using base::android::ScopedJavaLocalRef;
46 using content::BrowserThread;
47
48 namespace {
49
50 enum {
51 #define DEFINE_MODEL_TYPE_SELECTION(name,value) name = value,
52 #include "chrome/browser/sync/profile_sync_service_model_type_selection_android.h"
53 #undef DEFINE_MODEL_TYPE_SELECTION
54 };
55
56 } // namespace
57
ProfileSyncServiceAndroid(JNIEnv * env,jobject obj)58 ProfileSyncServiceAndroid::ProfileSyncServiceAndroid(JNIEnv* env, jobject obj)
59 : profile_(NULL),
60 sync_service_(NULL),
61 weak_java_profile_sync_service_(env, obj) {
62 if (g_browser_process == NULL ||
63 g_browser_process->profile_manager() == NULL) {
64 NOTREACHED() << "Browser process or profile manager not initialized";
65 return;
66 }
67
68 profile_ = ProfileManager::GetActiveUserProfile();
69 if (profile_ == NULL) {
70 NOTREACHED() << "Sync Init: Profile not found.";
71 return;
72 }
73
74 sync_prefs_.reset(new sync_driver::SyncPrefs(profile_->GetPrefs()));
75
76 sync_service_ =
77 ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile_);
78 DCHECK(sync_service_);
79 }
80
Init()81 void ProfileSyncServiceAndroid::Init() {
82 sync_service_->AddObserver(this);
83 }
84
RemoveObserver()85 void ProfileSyncServiceAndroid::RemoveObserver() {
86 if (sync_service_->HasObserver(this)) {
87 sync_service_->RemoveObserver(this);
88 }
89 }
90
~ProfileSyncServiceAndroid()91 ProfileSyncServiceAndroid::~ProfileSyncServiceAndroid() {
92 RemoveObserver();
93 }
94
SendNudgeNotification(int object_source,const std::string & str_object_id,int64 version,const std::string & state)95 void ProfileSyncServiceAndroid::SendNudgeNotification(
96 int object_source,
97 const std::string& str_object_id,
98 int64 version,
99 const std::string& state) {
100 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
101
102 // TODO(nileshagrawal): Merge this with ChromeInvalidationClient::Invalidate.
103 // Construct the ModelTypeStateMap and send it over with the notification.
104 invalidation::ObjectId object_id(
105 object_source,
106 str_object_id);
107 syncer::ObjectIdInvalidationMap object_ids_with_states;
108 if (version == ipc::invalidation::Constants::UNKNOWN) {
109 object_ids_with_states.Insert(
110 syncer::Invalidation::InitUnknownVersion(object_id));
111 } else {
112 ObjectIdVersionMap::iterator it =
113 max_invalidation_versions_.find(object_id);
114 if ((it != max_invalidation_versions_.end()) &&
115 (version <= it->second)) {
116 DVLOG(1) << "Dropping redundant invalidation with version " << version;
117 return;
118 }
119 max_invalidation_versions_[object_id] = version;
120 object_ids_with_states.Insert(
121 syncer::Invalidation::Init(object_id, version, state));
122 }
123
124 content::NotificationService::current()->Notify(
125 chrome::NOTIFICATION_SYNC_REFRESH_REMOTE,
126 content::Source<Profile>(profile_),
127 content::Details<const syncer::ObjectIdInvalidationMap>(
128 &object_ids_with_states));
129 }
130
OnStateChanged()131 void ProfileSyncServiceAndroid::OnStateChanged() {
132 // Notify the java world that our sync state has changed.
133 JNIEnv* env = AttachCurrentThread();
134 Java_ProfileSyncService_syncStateChanged(
135 env, weak_java_profile_sync_service_.get(env).obj());
136 }
137
EnableSync(JNIEnv * env,jobject)138 void ProfileSyncServiceAndroid::EnableSync(JNIEnv* env, jobject) {
139 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
140 // Don't need to do anything if we're already enabled.
141 if (sync_prefs_->IsStartSuppressed())
142 sync_service_->UnsuppressAndStart();
143 else
144 DVLOG(2) << "Ignoring call to EnableSync() because sync is already enabled";
145 }
146
DisableSync(JNIEnv * env,jobject)147 void ProfileSyncServiceAndroid::DisableSync(JNIEnv* env, jobject) {
148 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
149 // Don't need to do anything if we're already disabled.
150 if (!sync_prefs_->IsStartSuppressed()) {
151 sync_service_->StopAndSuppress();
152 } else {
153 DVLOG(2)
154 << "Ignoring call to DisableSync() because sync is already disabled";
155 }
156 }
157
SignInSync(JNIEnv * env,jobject)158 void ProfileSyncServiceAndroid::SignInSync(JNIEnv* env, jobject) {
159 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
160 // Just return if sync already has everything it needs to start up (sync
161 // should start up automatically as long as it has credentials). This can
162 // happen normally if (for example) the user closes and reopens the sync
163 // settings window quickly during initial startup.
164 if (sync_service_->IsSyncEnabledAndLoggedIn() &&
165 sync_service_->IsOAuthRefreshTokenAvailable() &&
166 sync_service_->HasSyncSetupCompleted()) {
167 return;
168 }
169
170 // Enable sync (if we don't have credentials yet, this will enable sync but
171 // will not start it up - sync will start once credentials arrive).
172 sync_service_->UnsuppressAndStart();
173 }
174
SignOutSync(JNIEnv * env,jobject)175 void ProfileSyncServiceAndroid::SignOutSync(JNIEnv* env, jobject) {
176 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
177 DCHECK(profile_);
178 sync_service_->DisableForUser();
179
180 // Need to clear suppress start flag manually
181 sync_prefs_->SetStartSuppressed(false);
182 }
183
QuerySyncStatusSummary(JNIEnv * env,jobject)184 ScopedJavaLocalRef<jstring> ProfileSyncServiceAndroid::QuerySyncStatusSummary(
185 JNIEnv* env, jobject) {
186 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
187 DCHECK(profile_);
188 std::string status(sync_service_->QuerySyncStatusSummaryString());
189 return ConvertUTF8ToJavaString(env, status);
190 }
191
SetSyncSessionsId(JNIEnv * env,jobject obj,jstring tag)192 jboolean ProfileSyncServiceAndroid::SetSyncSessionsId(
193 JNIEnv* env, jobject obj, jstring tag) {
194 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
195 DCHECK(profile_);
196 std::string machine_tag = ConvertJavaStringToUTF8(env, tag);
197 sync_prefs_->SetSyncSessionsGUID(machine_tag);
198 return true;
199 }
200
GetAuthError(JNIEnv * env,jobject)201 jint ProfileSyncServiceAndroid::GetAuthError(JNIEnv* env, jobject) {
202 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
203 return sync_service_->GetAuthError().state();
204 }
205
IsEncryptEverythingEnabled(JNIEnv * env,jobject)206 jboolean ProfileSyncServiceAndroid::IsEncryptEverythingEnabled(
207 JNIEnv* env, jobject) {
208 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
209 return sync_service_->EncryptEverythingEnabled();
210 }
211
IsSyncInitialized(JNIEnv * env,jobject)212 jboolean ProfileSyncServiceAndroid::IsSyncInitialized(JNIEnv* env, jobject) {
213 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
214 return sync_service_->sync_initialized();
215 }
216
IsFirstSetupInProgress(JNIEnv * env,jobject)217 jboolean ProfileSyncServiceAndroid::IsFirstSetupInProgress(
218 JNIEnv* env, jobject) {
219 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
220 return sync_service_->FirstSetupInProgress();
221 }
222
IsEncryptEverythingAllowed(JNIEnv * env,jobject obj)223 jboolean ProfileSyncServiceAndroid::IsEncryptEverythingAllowed(
224 JNIEnv* env, jobject obj) {
225 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
226 return sync_service_->EncryptEverythingAllowed();
227 }
228
IsPassphraseRequired(JNIEnv * env,jobject)229 jboolean ProfileSyncServiceAndroid::IsPassphraseRequired(JNIEnv* env, jobject) {
230 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
231 return sync_service_->IsPassphraseRequired();
232 }
233
IsPassphraseRequiredForDecryption(JNIEnv * env,jobject obj)234 jboolean ProfileSyncServiceAndroid::IsPassphraseRequiredForDecryption(
235 JNIEnv* env, jobject obj) {
236 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
237 // In case of CUSTOM_PASSPHRASE we always sync passwords. Prompt the user for
238 // a passphrase if cryptographer has any pending keys.
239 if (sync_service_->GetPassphraseType() == syncer::CUSTOM_PASSPHRASE) {
240 return !IsCryptographerReady(env, obj);
241 }
242 if (sync_service_->IsPassphraseRequiredForDecryption()) {
243 // Passwords datatype should never prompt for a passphrase, except when
244 // user is using a custom passphrase. Do not prompt for a passphrase if
245 // passwords are the only encrypted datatype. This prevents a temporary
246 // notification for passphrase when PSS has not completed configuring
247 // DataTypeManager, after configuration password datatype shall be disabled.
248 const syncer::ModelTypeSet encrypted_types =
249 sync_service_->GetEncryptedDataTypes();
250 return !encrypted_types.Equals(syncer::ModelTypeSet(syncer::PASSWORDS));
251 }
252 return false;
253 }
254
IsPassphraseRequiredForExternalType(JNIEnv * env,jobject)255 jboolean ProfileSyncServiceAndroid::IsPassphraseRequiredForExternalType(
256 JNIEnv* env, jobject) {
257 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
258 return
259 sync_service_->passphrase_required_reason() == syncer::REASON_DECRYPTION;
260 }
261
IsUsingSecondaryPassphrase(JNIEnv * env,jobject)262 jboolean ProfileSyncServiceAndroid::IsUsingSecondaryPassphrase(
263 JNIEnv* env, jobject) {
264 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
265 return sync_service_->IsUsingSecondaryPassphrase();
266 }
267
SetDecryptionPassphrase(JNIEnv * env,jobject obj,jstring passphrase)268 jboolean ProfileSyncServiceAndroid::SetDecryptionPassphrase(
269 JNIEnv* env, jobject obj, jstring passphrase) {
270 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
271 std::string key = ConvertJavaStringToUTF8(env, passphrase);
272 return sync_service_->SetDecryptionPassphrase(key);
273 }
274
SetEncryptionPassphrase(JNIEnv * env,jobject obj,jstring passphrase,jboolean is_gaia)275 void ProfileSyncServiceAndroid::SetEncryptionPassphrase(
276 JNIEnv* env, jobject obj, jstring passphrase, jboolean is_gaia) {
277 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
278 std::string key = ConvertJavaStringToUTF8(env, passphrase);
279 sync_service_->SetEncryptionPassphrase(
280 key,
281 is_gaia ? ProfileSyncService::IMPLICIT : ProfileSyncService::EXPLICIT);
282 }
283
IsCryptographerReady(JNIEnv * env,jobject)284 jboolean ProfileSyncServiceAndroid::IsCryptographerReady(JNIEnv* env, jobject) {
285 syncer::ReadTransaction trans(FROM_HERE, sync_service_->GetUserShare());
286 return sync_service_->IsCryptographerReady(&trans);
287 }
288
GetPassphraseType(JNIEnv * env,jobject)289 jint ProfileSyncServiceAndroid::GetPassphraseType(JNIEnv* env, jobject) {
290 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
291 return sync_service_->GetPassphraseType();
292 }
293
HasExplicitPassphraseTime(JNIEnv * env,jobject)294 jboolean ProfileSyncServiceAndroid::HasExplicitPassphraseTime(
295 JNIEnv* env, jobject) {
296 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
297 base::Time passphrase_time = sync_service_->GetExplicitPassphraseTime();
298 return !passphrase_time.is_null();
299 }
300
GetExplicitPassphraseTime(JNIEnv * env,jobject)301 jlong ProfileSyncServiceAndroid::GetExplicitPassphraseTime(
302 JNIEnv* env, jobject) {
303 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
304 base::Time passphrase_time = sync_service_->GetExplicitPassphraseTime();
305 return passphrase_time.ToJavaTime();
306 }
307
308 ScopedJavaLocalRef<jstring>
GetSyncEnterGooglePassphraseBodyWithDateText(JNIEnv * env,jobject)309 ProfileSyncServiceAndroid::GetSyncEnterGooglePassphraseBodyWithDateText(
310 JNIEnv* env, jobject) {
311 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
312 base::Time passphrase_time = sync_service_->GetExplicitPassphraseTime();
313 base::string16 passphrase_time_str =
314 base::TimeFormatShortDate(passphrase_time);
315 return base::android::ConvertUTF16ToJavaString(env,
316 l10n_util::GetStringFUTF16(
317 IDS_SYNC_ENTER_GOOGLE_PASSPHRASE_BODY_WITH_DATE,
318 passphrase_time_str));
319 }
320
321 ScopedJavaLocalRef<jstring>
GetSyncEnterCustomPassphraseBodyWithDateText(JNIEnv * env,jobject)322 ProfileSyncServiceAndroid::GetSyncEnterCustomPassphraseBodyWithDateText(
323 JNIEnv* env, jobject) {
324 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
325 base::Time passphrase_time = sync_service_->GetExplicitPassphraseTime();
326 base::string16 passphrase_time_str =
327 base::TimeFormatShortDate(passphrase_time);
328 return base::android::ConvertUTF16ToJavaString(env,
329 l10n_util::GetStringFUTF16(IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE,
330 passphrase_time_str));
331 }
332
333 ScopedJavaLocalRef<jstring>
GetCurrentSignedInAccountText(JNIEnv * env,jobject)334 ProfileSyncServiceAndroid::GetCurrentSignedInAccountText(
335 JNIEnv* env, jobject) {
336 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
337 const std::string& sync_username =
338 SigninManagerFactory::GetForProfile(profile_)->GetAuthenticatedUsername();
339 return base::android::ConvertUTF16ToJavaString(env,
340 l10n_util::GetStringFUTF16(
341 IDS_SYNC_ACCOUNT_SYNCING_TO_USER,
342 base::ASCIIToUTF16(sync_username)));
343 }
344
345 ScopedJavaLocalRef<jstring>
GetSyncEnterCustomPassphraseBodyText(JNIEnv * env,jobject)346 ProfileSyncServiceAndroid::GetSyncEnterCustomPassphraseBodyText(
347 JNIEnv* env, jobject) {
348 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
349 return ConvertUTF8ToJavaString(
350 env, l10n_util::GetStringUTF8(IDS_SYNC_ENTER_PASSPHRASE_BODY));
351 }
352
IsSyncKeystoreMigrationDone(JNIEnv * env,jobject)353 jboolean ProfileSyncServiceAndroid::IsSyncKeystoreMigrationDone(
354 JNIEnv* env, jobject) {
355 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
356 syncer::SyncStatus status;
357 bool is_status_valid = sync_service_->QueryDetailedSyncStatus(&status);
358 return is_status_valid && !status.keystore_migration_time.is_null();
359 }
360
GetEnabledDataTypes(JNIEnv * env,jobject obj)361 jlong ProfileSyncServiceAndroid::GetEnabledDataTypes(JNIEnv* env,
362 jobject obj) {
363 syncer::ModelTypeSet types = sync_service_->GetActiveDataTypes();
364 types.PutAll(syncer::ControlTypes());
365 return ModelTypeSetToSelection(types);
366 }
367
SetPreferredDataTypes(JNIEnv * env,jobject obj,jboolean sync_everything,jlong model_type_selection)368 void ProfileSyncServiceAndroid::SetPreferredDataTypes(
369 JNIEnv* env, jobject obj,
370 jboolean sync_everything,
371 jlong model_type_selection) {
372 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
373 syncer::ModelTypeSet types;
374 // Note: only user selectable types should be included here.
375 if (model_type_selection & AUTOFILL)
376 types.Put(syncer::AUTOFILL);
377 if (model_type_selection & BOOKMARK)
378 types.Put(syncer::BOOKMARKS);
379 if (model_type_selection & PASSWORD)
380 types.Put(syncer::PASSWORDS);
381 if (model_type_selection & PROXY_TABS)
382 types.Put(syncer::PROXY_TABS);
383 if (model_type_selection & TYPED_URL)
384 types.Put(syncer::TYPED_URLS);
385 DCHECK(syncer::UserSelectableTypes().HasAll(types));
386 sync_service_->OnUserChoseDatatypes(sync_everything, types);
387 }
388
SetSetupInProgress(JNIEnv * env,jobject obj,jboolean in_progress)389 void ProfileSyncServiceAndroid::SetSetupInProgress(
390 JNIEnv* env, jobject obj, jboolean in_progress) {
391 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
392 sync_service_->SetSetupInProgress(in_progress);
393 }
394
SetSyncSetupCompleted(JNIEnv * env,jobject obj)395 void ProfileSyncServiceAndroid::SetSyncSetupCompleted(
396 JNIEnv* env, jobject obj) {
397 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
398 sync_service_->SetSyncSetupCompleted();
399 }
400
HasSyncSetupCompleted(JNIEnv * env,jobject obj)401 jboolean ProfileSyncServiceAndroid::HasSyncSetupCompleted(
402 JNIEnv* env, jobject obj) {
403 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
404 return sync_service_->HasSyncSetupCompleted();
405 }
406
IsStartSuppressed(JNIEnv * env,jobject obj)407 jboolean ProfileSyncServiceAndroid::IsStartSuppressed(
408 JNIEnv* env, jobject obj) {
409 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
410 return sync_prefs_->IsStartSuppressed();
411 }
412
EnableEncryptEverything(JNIEnv * env,jobject obj)413 void ProfileSyncServiceAndroid::EnableEncryptEverything(
414 JNIEnv* env, jobject obj) {
415 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
416 sync_service_->EnableEncryptEverything();
417 }
418
HasKeepEverythingSynced(JNIEnv * env,jobject)419 jboolean ProfileSyncServiceAndroid::HasKeepEverythingSynced(
420 JNIEnv* env, jobject) {
421 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
422 return sync_prefs_->HasKeepEverythingSynced();
423 }
424
HasUnrecoverableError(JNIEnv * env,jobject)425 jboolean ProfileSyncServiceAndroid::HasUnrecoverableError(
426 JNIEnv* env, jobject) {
427 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
428 return sync_service_->HasUnrecoverableError();
429 }
430
GetAboutInfoForTest(JNIEnv * env,jobject)431 ScopedJavaLocalRef<jstring> ProfileSyncServiceAndroid::GetAboutInfoForTest(
432 JNIEnv* env, jobject) {
433 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
434
435 scoped_ptr<base::DictionaryValue> about_info =
436 sync_ui_util::ConstructAboutInformation(sync_service_);
437 std::string about_info_json;
438 base::JSONWriter::Write(about_info.get(), &about_info_json);
439
440 return ConvertUTF8ToJavaString(env, about_info_json);
441 }
442
GetLastSyncedTimeForTest(JNIEnv * env,jobject obj)443 jlong ProfileSyncServiceAndroid::GetLastSyncedTimeForTest(
444 JNIEnv* env, jobject obj) {
445 // Use profile preferences here instead of SyncPrefs to avoid an extra
446 // conversion, since SyncPrefs::GetLastSyncedTime() converts the stored value
447 // to to base::Time.
448 return static_cast<jlong>(
449 profile_->GetPrefs()->GetInt64(sync_driver::prefs::kSyncLastSyncedTime));
450 }
451
OverrideNetworkResourcesForTest(JNIEnv * env,jobject obj,jlong network_resources)452 void ProfileSyncServiceAndroid::OverrideNetworkResourcesForTest(
453 JNIEnv* env,
454 jobject obj,
455 jlong network_resources) {
456 syncer::NetworkResources* resources =
457 reinterpret_cast<syncer::NetworkResources*>(network_resources);
458 sync_service_->OverrideNetworkResourcesForTest(
459 make_scoped_ptr<syncer::NetworkResources>(resources));
460 }
461
462 // static
ModelTypeSetToSelection(syncer::ModelTypeSet types)463 jlong ProfileSyncServiceAndroid::ModelTypeSetToSelection(
464 syncer::ModelTypeSet types) {
465 jlong model_type_selection = 0;
466 if (types.Has(syncer::BOOKMARKS)) {
467 model_type_selection |= BOOKMARK;
468 }
469 if (types.Has(syncer::AUTOFILL)) {
470 model_type_selection |= AUTOFILL;
471 }
472 if (types.Has(syncer::AUTOFILL_PROFILE)) {
473 model_type_selection |= AUTOFILL_PROFILE;
474 }
475 if (types.Has(syncer::PASSWORDS)) {
476 model_type_selection |= PASSWORD;
477 }
478 if (types.Has(syncer::TYPED_URLS)) {
479 model_type_selection |= TYPED_URL;
480 }
481 if (types.Has(syncer::SESSIONS)) {
482 model_type_selection |= SESSION;
483 }
484 if (types.Has(syncer::HISTORY_DELETE_DIRECTIVES)) {
485 model_type_selection |= HISTORY_DELETE_DIRECTIVE;
486 }
487 if (types.Has(syncer::PROXY_TABS)) {
488 model_type_selection |= PROXY_TABS;
489 }
490 if (types.Has(syncer::FAVICON_IMAGES)) {
491 model_type_selection |= FAVICON_IMAGE;
492 }
493 if (types.Has(syncer::FAVICON_TRACKING)) {
494 model_type_selection |= FAVICON_TRACKING;
495 }
496 if (types.Has(syncer::DEVICE_INFO)) {
497 model_type_selection |= DEVICE_INFO;
498 }
499 if (types.Has(syncer::NIGORI)) {
500 model_type_selection |= NIGORI;
501 }
502 if (types.Has(syncer::EXPERIMENTS)) {
503 model_type_selection |= EXPERIMENTS;
504 }
505 if (types.Has(syncer::SUPERVISED_USER_SETTINGS)) {
506 model_type_selection |= SUPERVISED_USER_SETTING;
507 }
508 return model_type_selection;
509 }
510
511 // static
ModelTypeSelectionToStringForTest(jlong model_type_selection)512 std::string ProfileSyncServiceAndroid::ModelTypeSelectionToStringForTest(
513 jlong model_type_selection) {
514 ScopedJavaLocalRef<jstring> string =
515 Java_ProfileSyncService_modelTypeSelectionToStringForTest(
516 AttachCurrentThread(), model_type_selection);
517 return ConvertJavaStringToUTF8(string);
518 }
519
NudgeSyncer(JNIEnv * env,jobject obj,jint objectSource,jstring objectId,jlong version,jstring state)520 void ProfileSyncServiceAndroid::NudgeSyncer(JNIEnv* env,
521 jobject obj,
522 jint objectSource,
523 jstring objectId,
524 jlong version,
525 jstring state) {
526 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
527 SendNudgeNotification(objectSource, ConvertJavaStringToUTF8(env, objectId),
528 version, ConvertJavaStringToUTF8(env, state));
529 }
530
NudgeSyncerForAllTypes(JNIEnv * env,jobject obj)531 void ProfileSyncServiceAndroid::NudgeSyncerForAllTypes(JNIEnv* env,
532 jobject obj) {
533 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
534 syncer::ObjectIdInvalidationMap object_ids_with_states;
535 content::NotificationService::current()->Notify(
536 chrome::NOTIFICATION_SYNC_REFRESH_REMOTE,
537 content::Source<Profile>(profile_),
538 content::Details<const syncer::ObjectIdInvalidationMap>(
539 &object_ids_with_states));
540 }
541
542 // static
543 ProfileSyncServiceAndroid*
GetProfileSyncServiceAndroid()544 ProfileSyncServiceAndroid::GetProfileSyncServiceAndroid() {
545 return reinterpret_cast<ProfileSyncServiceAndroid*>(
546 Java_ProfileSyncService_getProfileSyncServiceAndroid(
547 AttachCurrentThread(), base::android::GetApplicationContext()));
548 }
549
Init(JNIEnv * env,jobject obj)550 static jlong Init(JNIEnv* env, jobject obj) {
551 ProfileSyncServiceAndroid* profile_sync_service_android =
552 new ProfileSyncServiceAndroid(env, obj);
553 profile_sync_service_android->Init();
554 return reinterpret_cast<intptr_t>(profile_sync_service_android);
555 }
556
557 // static
Register(JNIEnv * env)558 bool ProfileSyncServiceAndroid::Register(JNIEnv* env) {
559 return RegisterNativesImpl(env);
560 }
561