• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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