Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / sync / profile_sync_service_android.cc
blobd88fd22c21aca43d6ea137f5a05c4c546cf3a7f8
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.
5 #include "chrome/browser/sync/profile_sync_service_android.h"
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/metrics/field_trial.h"
15 #include "base/prefs/pref_service.h"
16 #include "base/strings/utf_string_conversions.h"
17 #include "base/time/time.h"
18 #include "chrome/browser/browser_process.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/signin/core/browser/signin_manager.h"
27 #include "components/sync_driver/pref_names.h"
28 #include "components/sync_driver/sync_prefs.h"
29 #include "content/public/browser/browser_thread.h"
30 #include "google/cacheinvalidation/types.pb.h"
31 #include "google_apis/gaia/gaia_constants.h"
32 #include "google_apis/gaia/google_service_auth_error.h"
33 #include "jni/ProfileSyncService_jni.h"
34 #include "sync/internal_api/public/network_resources.h"
35 #include "sync/internal_api/public/read_transaction.h"
36 #include "ui/base/l10n/l10n_util.h"
38 using base::android::AttachCurrentThread;
39 using base::android::CheckException;
40 using base::android::ConvertJavaStringToUTF8;
41 using base::android::ConvertUTF8ToJavaString;
42 using base::android::ScopedJavaLocalRef;
43 using content::BrowserThread;
45 namespace {
47 // This enum contains the list of sync ModelTypes that Android can register for
48 // invalidations for.
50 // A Java counterpart will be generated for this enum.
51 // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.sync
52 enum ModelTypeSelection {
53 AUTOFILL = 1 << 0,
54 BOOKMARK = 1 << 1,
55 PASSWORD = 1 << 2,
56 SESSION = 1 << 3,
57 TYPED_URL = 1 << 4,
58 AUTOFILL_PROFILE = 1 << 5,
59 HISTORY_DELETE_DIRECTIVE = 1 << 6,
60 PROXY_TABS = 1 << 7,
61 FAVICON_IMAGE = 1 << 8,
62 FAVICON_TRACKING = 1 << 9,
63 NIGORI = 1 << 10,
64 DEVICE_INFO = 1 << 11,
65 EXPERIMENTS = 1 << 12,
66 SUPERVISED_USER_SETTING = 1 << 13,
67 SUPERVISED_USER_WHITELIST = 1 << 14,
68 AUTOFILL_WALLET = 1 << 15,
69 AUTOFILL_WALLET_METADATA = 1 << 16,
70 PREFERENCE = 1 << 17,
71 PRIORITY_PREFERENCE = 1 << 18,
74 // Native callback for the JNI GetAllNodes method. When
75 // ProfileSyncService::GetAllNodes completes, this method is called and the
76 // results are sent to the Java callback.
77 void NativeGetAllNodesCallback(
78 const base::android::ScopedJavaGlobalRef<jobject>& callback,
79 scoped_ptr<base::ListValue> result) {
80 JNIEnv* env = base::android::AttachCurrentThread();
81 std::string json_string;
82 if (!result.get() || !base::JSONWriter::Write(*result, &json_string)) {
83 DVLOG(1) << "Writing as JSON failed. Passing empty string to Java code.";
84 json_string = std::string();
87 ScopedJavaLocalRef<jstring> java_json_string =
88 ConvertUTF8ToJavaString(env, json_string);
89 Java_ProfileSyncService_onGetAllNodesResult(env,
90 callback.obj(),
91 java_json_string.obj());
94 } // namespace
96 ProfileSyncServiceAndroid::ProfileSyncServiceAndroid(JNIEnv* env, jobject obj)
97 : profile_(NULL),
98 sync_service_(NULL),
99 weak_java_profile_sync_service_(env, obj) {
100 if (g_browser_process == NULL ||
101 g_browser_process->profile_manager() == NULL) {
102 NOTREACHED() << "Browser process or profile manager not initialized";
103 return;
106 profile_ = ProfileManager::GetActiveUserProfile();
107 if (profile_ == NULL) {
108 NOTREACHED() << "Sync Init: Profile not found.";
109 return;
112 sync_prefs_.reset(new sync_driver::SyncPrefs(profile_->GetPrefs()));
114 sync_service_ =
115 ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile_);
116 DCHECK(sync_service_);
119 void ProfileSyncServiceAndroid::Init() {
120 sync_service_->AddObserver(this);
123 void ProfileSyncServiceAndroid::RemoveObserver() {
124 if (sync_service_->HasObserver(this)) {
125 sync_service_->RemoveObserver(this);
129 ProfileSyncServiceAndroid::~ProfileSyncServiceAndroid() {
130 RemoveObserver();
133 void ProfileSyncServiceAndroid::OnStateChanged() {
134 // Notify the java world that our sync state has changed.
135 JNIEnv* env = AttachCurrentThread();
136 Java_ProfileSyncService_syncStateChanged(
137 env, weak_java_profile_sync_service_.get(env).obj());
140 jboolean ProfileSyncServiceAndroid::IsPassphrasePrompted(JNIEnv* env,
141 jobject obj) {
142 const std::string group_name =
143 base::FieldTrialList::FindFullName("LimitSyncPassphrasePrompt");
144 if (group_name != "Enabled")
145 return false;
146 return sync_prefs_->IsPassphrasePrompted();
149 void ProfileSyncServiceAndroid::SetPassphrasePrompted(JNIEnv* env,
150 jobject obj,
151 jboolean prompted) {
152 sync_prefs_->SetPassphrasePrompted(prompted);
155 void ProfileSyncServiceAndroid::RequestStart(JNIEnv* env, jobject) {
156 DCHECK_CURRENTLY_ON(BrowserThread::UI);
157 sync_service_->RequestStart();
160 void ProfileSyncServiceAndroid::RequestStop(JNIEnv* env, jobject) {
161 DCHECK_CURRENTLY_ON(BrowserThread::UI);
162 sync_service_->RequestStop(ProfileSyncService::KEEP_DATA);
165 void ProfileSyncServiceAndroid::SignOutSync(JNIEnv* env, jobject) {
166 DCHECK_CURRENTLY_ON(BrowserThread::UI);
167 DCHECK(profile_);
168 sync_service_->RequestStop(ProfileSyncService::CLEAR_DATA);
171 void ProfileSyncServiceAndroid::FlushDirectory(JNIEnv* env, jobject) {
172 DCHECK_CURRENTLY_ON(BrowserThread::UI);
173 sync_service_->FlushDirectory();
176 ScopedJavaLocalRef<jstring> ProfileSyncServiceAndroid::QuerySyncStatusSummary(
177 JNIEnv* env, jobject) {
178 DCHECK_CURRENTLY_ON(BrowserThread::UI);
179 DCHECK(profile_);
180 std::string status(sync_service_->QuerySyncStatusSummaryString());
181 return ConvertUTF8ToJavaString(env, status);
184 void ProfileSyncServiceAndroid::GetAllNodes(JNIEnv* env,
185 jobject obj,
186 jobject callback) {
187 base::android::ScopedJavaGlobalRef<jobject> java_callback;
188 java_callback.Reset(env, callback);
190 base::Callback<void(scoped_ptr<base::ListValue>)> native_callback =
191 base::Bind(&NativeGetAllNodesCallback, java_callback);
192 sync_service_->GetAllNodes(native_callback);
195 jboolean ProfileSyncServiceAndroid::SetSyncSessionsId(
196 JNIEnv* env, jobject obj, jstring tag) {
197 DCHECK_CURRENTLY_ON(BrowserThread::UI);
198 DCHECK(profile_);
199 std::string machine_tag = ConvertJavaStringToUTF8(env, tag);
200 sync_prefs_->SetSyncSessionsGUID(machine_tag);
201 return true;
204 jint ProfileSyncServiceAndroid::GetAuthError(JNIEnv* env, jobject) {
205 DCHECK_CURRENTLY_ON(BrowserThread::UI);
206 return sync_service_->GetAuthError().state();
209 jboolean ProfileSyncServiceAndroid::IsEncryptEverythingEnabled(
210 JNIEnv* env, jobject) {
211 DCHECK_CURRENTLY_ON(BrowserThread::UI);
212 return sync_service_->EncryptEverythingEnabled();
215 jboolean ProfileSyncServiceAndroid::IsSyncInitialized(JNIEnv* env, jobject) {
216 DCHECK_CURRENTLY_ON(BrowserThread::UI);
217 return sync_service_->backend_initialized();
220 jboolean ProfileSyncServiceAndroid::IsFirstSetupInProgress(
221 JNIEnv* env, jobject) {
222 DCHECK_CURRENTLY_ON(BrowserThread::UI);
223 return sync_service_->FirstSetupInProgress();
226 jboolean ProfileSyncServiceAndroid::IsEncryptEverythingAllowed(
227 JNIEnv* env, jobject obj) {
228 DCHECK_CURRENTLY_ON(BrowserThread::UI);
229 return sync_service_->EncryptEverythingAllowed();
232 jboolean ProfileSyncServiceAndroid::IsPassphraseRequired(JNIEnv* env, jobject) {
233 DCHECK_CURRENTLY_ON(BrowserThread::UI);
234 return sync_service_->IsPassphraseRequired();
237 jboolean ProfileSyncServiceAndroid::IsPassphraseRequiredForDecryption(
238 JNIEnv* env, jobject obj) {
239 DCHECK_CURRENTLY_ON(BrowserThread::UI);
240 // In case of CUSTOM_PASSPHRASE we always sync passwords. Prompt the user for
241 // a passphrase if cryptographer has any pending keys.
242 if (sync_service_->GetPassphraseType() == syncer::CUSTOM_PASSPHRASE) {
243 return !IsCryptographerReady(env, obj);
245 if (sync_service_->IsPassphraseRequiredForDecryption()) {
246 // Passwords datatype should never prompt for a passphrase, except when
247 // user is using a custom passphrase. Do not prompt for a passphrase if
248 // passwords are the only encrypted datatype. This prevents a temporary
249 // notification for passphrase when PSS has not completed configuring
250 // DataTypeManager, after configuration password datatype shall be disabled.
251 const syncer::ModelTypeSet encrypted_types =
252 sync_service_->GetEncryptedDataTypes();
253 return !encrypted_types.Equals(syncer::ModelTypeSet(syncer::PASSWORDS));
255 return false;
258 jboolean ProfileSyncServiceAndroid::IsPassphraseRequiredForExternalType(
259 JNIEnv* env, jobject) {
260 DCHECK_CURRENTLY_ON(BrowserThread::UI);
261 return
262 sync_service_->passphrase_required_reason() == syncer::REASON_DECRYPTION;
265 jboolean ProfileSyncServiceAndroid::IsUsingSecondaryPassphrase(
266 JNIEnv* env, jobject) {
267 DCHECK_CURRENTLY_ON(BrowserThread::UI);
268 return sync_service_->IsUsingSecondaryPassphrase();
271 jboolean ProfileSyncServiceAndroid::SetDecryptionPassphrase(
272 JNIEnv* env, jobject obj, jstring passphrase) {
273 DCHECK_CURRENTLY_ON(BrowserThread::UI);
274 std::string key = ConvertJavaStringToUTF8(env, passphrase);
275 return sync_service_->SetDecryptionPassphrase(key);
278 void ProfileSyncServiceAndroid::SetEncryptionPassphrase(
279 JNIEnv* env, jobject obj, jstring passphrase, jboolean is_gaia) {
280 DCHECK_CURRENTLY_ON(BrowserThread::UI);
281 std::string key = ConvertJavaStringToUTF8(env, passphrase);
282 sync_service_->SetEncryptionPassphrase(
283 key,
284 is_gaia ? ProfileSyncService::IMPLICIT : ProfileSyncService::EXPLICIT);
287 jboolean ProfileSyncServiceAndroid::IsCryptographerReady(JNIEnv* env, jobject) {
288 syncer::ReadTransaction trans(FROM_HERE, sync_service_->GetUserShare());
289 return sync_service_->IsCryptographerReady(&trans);
292 jint ProfileSyncServiceAndroid::GetPassphraseType(JNIEnv* env, jobject) {
293 DCHECK_CURRENTLY_ON(BrowserThread::UI);
294 return sync_service_->GetPassphraseType();
297 jboolean ProfileSyncServiceAndroid::HasExplicitPassphraseTime(
298 JNIEnv* env, jobject) {
299 DCHECK_CURRENTLY_ON(BrowserThread::UI);
300 base::Time passphrase_time = sync_service_->GetExplicitPassphraseTime();
301 return !passphrase_time.is_null();
304 jlong ProfileSyncServiceAndroid::GetExplicitPassphraseTime(
305 JNIEnv* env, jobject) {
306 DCHECK_CURRENTLY_ON(BrowserThread::UI);
307 base::Time passphrase_time = sync_service_->GetExplicitPassphraseTime();
308 return passphrase_time.ToJavaTime();
311 ScopedJavaLocalRef<jstring>
312 ProfileSyncServiceAndroid::GetSyncEnterGooglePassphraseBodyWithDateText(
313 JNIEnv* env, jobject) {
314 DCHECK_CURRENTLY_ON(BrowserThread::UI);
315 base::Time passphrase_time = sync_service_->GetExplicitPassphraseTime();
316 base::string16 passphrase_time_str =
317 base::TimeFormatShortDate(passphrase_time);
318 return base::android::ConvertUTF16ToJavaString(env,
319 l10n_util::GetStringFUTF16(
320 IDS_SYNC_ENTER_GOOGLE_PASSPHRASE_BODY_WITH_DATE,
321 passphrase_time_str));
324 ScopedJavaLocalRef<jstring>
325 ProfileSyncServiceAndroid::GetSyncEnterCustomPassphraseBodyWithDateText(
326 JNIEnv* env, jobject) {
327 DCHECK_CURRENTLY_ON(BrowserThread::UI);
328 base::Time passphrase_time = sync_service_->GetExplicitPassphraseTime();
329 base::string16 passphrase_time_str =
330 base::TimeFormatShortDate(passphrase_time);
331 return base::android::ConvertUTF16ToJavaString(env,
332 l10n_util::GetStringFUTF16(IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE,
333 passphrase_time_str));
336 ScopedJavaLocalRef<jstring>
337 ProfileSyncServiceAndroid::GetCurrentSignedInAccountText(
338 JNIEnv* env, jobject) {
339 DCHECK_CURRENTLY_ON(BrowserThread::UI);
340 const std::string& sync_username =
341 SigninManagerFactory::GetForProfile(profile_)->GetAuthenticatedUsername();
342 return base::android::ConvertUTF16ToJavaString(env,
343 l10n_util::GetStringFUTF16(
344 IDS_SYNC_ACCOUNT_SYNCING_TO_USER,
345 base::ASCIIToUTF16(sync_username)));
348 ScopedJavaLocalRef<jstring>
349 ProfileSyncServiceAndroid::GetSyncEnterCustomPassphraseBodyText(
350 JNIEnv* env, jobject) {
351 DCHECK_CURRENTLY_ON(BrowserThread::UI);
352 return ConvertUTF8ToJavaString(
353 env, l10n_util::GetStringUTF8(IDS_SYNC_ENTER_PASSPHRASE_BODY));
356 jboolean ProfileSyncServiceAndroid::IsSyncKeystoreMigrationDone(
357 JNIEnv* env, jobject) {
358 DCHECK_CURRENTLY_ON(BrowserThread::UI);
359 syncer::SyncStatus status;
360 bool is_status_valid = sync_service_->QueryDetailedSyncStatus(&status);
361 return is_status_valid && !status.keystore_migration_time.is_null();
364 jlong ProfileSyncServiceAndroid::GetActiveDataTypes(
365 JNIEnv* env, jobject obj) {
366 syncer::ModelTypeSet types = sync_service_->GetActiveDataTypes();
367 types.PutAll(syncer::ControlTypes());
368 return ModelTypeSetToSelection(types);
371 jlong ProfileSyncServiceAndroid::GetPreferredDataTypes(
372 JNIEnv* env, jobject obj) {
373 syncer::ModelTypeSet types = sync_service_->GetPreferredDataTypes();
374 types.PutAll(syncer::ControlTypes());
375 return ModelTypeSetToSelection(types);
378 void ProfileSyncServiceAndroid::SetPreferredDataTypes(
379 JNIEnv* env, jobject obj,
380 jboolean sync_everything,
381 jlong model_type_selection) {
382 DCHECK_CURRENTLY_ON(BrowserThread::UI);
383 syncer::ModelTypeSet types;
384 // Note: only user selectable types should be included here.
385 if (model_type_selection & AUTOFILL)
386 types.Put(syncer::AUTOFILL);
387 if (model_type_selection & BOOKMARK)
388 types.Put(syncer::BOOKMARKS);
389 if (model_type_selection & PASSWORD)
390 types.Put(syncer::PASSWORDS);
391 if (model_type_selection & PROXY_TABS)
392 types.Put(syncer::PROXY_TABS);
393 if (model_type_selection & TYPED_URL)
394 types.Put(syncer::TYPED_URLS);
395 if (model_type_selection & PREFERENCE)
396 types.Put(syncer::PREFERENCES);
397 DCHECK(syncer::UserSelectableTypes().HasAll(types));
398 sync_service_->OnUserChoseDatatypes(sync_everything, types);
401 void ProfileSyncServiceAndroid::SetSetupInProgress(
402 JNIEnv* env, jobject obj, jboolean in_progress) {
403 DCHECK_CURRENTLY_ON(BrowserThread::UI);
404 sync_service_->SetSetupInProgress(in_progress);
407 void ProfileSyncServiceAndroid::SetSyncSetupCompleted(
408 JNIEnv* env, jobject obj) {
409 DCHECK_CURRENTLY_ON(BrowserThread::UI);
410 sync_service_->SetSyncSetupCompleted();
413 jboolean ProfileSyncServiceAndroid::HasSyncSetupCompleted(
414 JNIEnv* env, jobject obj) {
415 DCHECK_CURRENTLY_ON(BrowserThread::UI);
416 return sync_service_->HasSyncSetupCompleted();
419 jboolean ProfileSyncServiceAndroid::IsSyncRequested(
420 JNIEnv* env, jobject obj) {
421 DCHECK_CURRENTLY_ON(BrowserThread::UI);
422 return sync_service_->IsSyncRequested();
425 jboolean ProfileSyncServiceAndroid::IsSyncActive(JNIEnv* env, jobject obj) {
426 DCHECK_CURRENTLY_ON(BrowserThread::UI);
427 return sync_service_->IsSyncActive();
430 void ProfileSyncServiceAndroid::EnableEncryptEverything(
431 JNIEnv* env, jobject obj) {
432 DCHECK_CURRENTLY_ON(BrowserThread::UI);
433 sync_service_->EnableEncryptEverything();
436 jboolean ProfileSyncServiceAndroid::HasKeepEverythingSynced(
437 JNIEnv* env, jobject) {
438 DCHECK_CURRENTLY_ON(BrowserThread::UI);
439 return sync_prefs_->HasKeepEverythingSynced();
442 jboolean ProfileSyncServiceAndroid::HasUnrecoverableError(
443 JNIEnv* env, jobject) {
444 DCHECK_CURRENTLY_ON(BrowserThread::UI);
445 return sync_service_->HasUnrecoverableError();
448 ScopedJavaLocalRef<jstring> ProfileSyncServiceAndroid::GetAboutInfoForTest(
449 JNIEnv* env, jobject) {
450 DCHECK_CURRENTLY_ON(BrowserThread::UI);
452 scoped_ptr<base::DictionaryValue> about_info =
453 sync_ui_util::ConstructAboutInformation(sync_service_);
454 std::string about_info_json;
455 base::JSONWriter::Write(*about_info, &about_info_json);
457 return ConvertUTF8ToJavaString(env, about_info_json);
460 jlong ProfileSyncServiceAndroid::GetLastSyncedTimeForTest(
461 JNIEnv* env, jobject obj) {
462 // Use profile preferences here instead of SyncPrefs to avoid an extra
463 // conversion, since SyncPrefs::GetLastSyncedTime() converts the stored value
464 // to to base::Time.
465 return static_cast<jlong>(
466 profile_->GetPrefs()->GetInt64(sync_driver::prefs::kSyncLastSyncedTime));
469 void ProfileSyncServiceAndroid::OverrideNetworkResourcesForTest(
470 JNIEnv* env,
471 jobject obj,
472 jlong network_resources) {
473 syncer::NetworkResources* resources =
474 reinterpret_cast<syncer::NetworkResources*>(network_resources);
475 sync_service_->OverrideNetworkResourcesForTest(
476 make_scoped_ptr<syncer::NetworkResources>(resources));
479 // static
480 jlong ProfileSyncServiceAndroid::ModelTypeSetToSelection(
481 syncer::ModelTypeSet types) {
482 jlong model_type_selection = 0;
483 if (types.Has(syncer::BOOKMARKS)) {
484 model_type_selection |= BOOKMARK;
486 if (types.Has(syncer::AUTOFILL)) {
487 model_type_selection |= AUTOFILL;
489 if (types.Has(syncer::AUTOFILL_PROFILE)) {
490 model_type_selection |= AUTOFILL_PROFILE;
492 if (types.Has(syncer::AUTOFILL_WALLET_DATA)) {
493 model_type_selection |= AUTOFILL_WALLET;
495 if (types.Has(syncer::AUTOFILL_WALLET_METADATA)) {
496 model_type_selection |= AUTOFILL_WALLET_METADATA;
498 if (types.Has(syncer::PASSWORDS)) {
499 model_type_selection |= PASSWORD;
501 if (types.Has(syncer::PREFERENCES)) {
502 model_type_selection |= PREFERENCE;
504 if (types.Has(syncer::PRIORITY_PREFERENCES)) {
505 model_type_selection |= PRIORITY_PREFERENCE;
507 if (types.Has(syncer::TYPED_URLS)) {
508 model_type_selection |= TYPED_URL;
510 if (types.Has(syncer::SESSIONS)) {
511 model_type_selection |= SESSION;
513 if (types.Has(syncer::HISTORY_DELETE_DIRECTIVES)) {
514 model_type_selection |= HISTORY_DELETE_DIRECTIVE;
516 if (types.Has(syncer::PROXY_TABS)) {
517 model_type_selection |= PROXY_TABS;
519 if (types.Has(syncer::FAVICON_IMAGES)) {
520 model_type_selection |= FAVICON_IMAGE;
522 if (types.Has(syncer::FAVICON_TRACKING)) {
523 model_type_selection |= FAVICON_TRACKING;
525 if (types.Has(syncer::DEVICE_INFO)) {
526 model_type_selection |= DEVICE_INFO;
528 if (types.Has(syncer::NIGORI)) {
529 model_type_selection |= NIGORI;
531 if (types.Has(syncer::EXPERIMENTS)) {
532 model_type_selection |= EXPERIMENTS;
534 if (types.Has(syncer::SUPERVISED_USER_SETTINGS)) {
535 model_type_selection |= SUPERVISED_USER_SETTING;
537 if (types.Has(syncer::SUPERVISED_USER_WHITELISTS)) {
538 model_type_selection |= SUPERVISED_USER_WHITELIST;
540 return model_type_selection;
543 // static
544 std::string ProfileSyncServiceAndroid::ModelTypeSelectionToStringForTest(
545 jlong model_type_selection) {
546 ScopedJavaLocalRef<jstring> string =
547 Java_ProfileSyncService_modelTypeSelectionToStringForTest(
548 AttachCurrentThread(), model_type_selection);
549 return ConvertJavaStringToUTF8(string);
552 // static
553 ProfileSyncServiceAndroid*
554 ProfileSyncServiceAndroid::GetProfileSyncServiceAndroid() {
555 return reinterpret_cast<ProfileSyncServiceAndroid*>(
556 Java_ProfileSyncService_getProfileSyncServiceAndroid(
557 AttachCurrentThread(), base::android::GetApplicationContext()));
560 static jlong Init(JNIEnv* env, jobject obj) {
561 ProfileSyncServiceAndroid* profile_sync_service_android =
562 new ProfileSyncServiceAndroid(env, obj);
563 profile_sync_service_android->Init();
564 return reinterpret_cast<intptr_t>(profile_sync_service_android);
567 // static
568 bool ProfileSyncServiceAndroid::Register(JNIEnv* env) {
569 return RegisterNativesImpl(env);