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"
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
;
47 // This enum contains the list of sync ModelTypes that Android can register for
50 // A Java counterpart will be generated for this enum.
51 // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.sync
52 enum ModelTypeSelection
{
58 AUTOFILL_PROFILE
= 1 << 5,
59 HISTORY_DELETE_DIRECTIVE
= 1 << 6,
61 FAVICON_IMAGE
= 1 << 8,
62 FAVICON_TRACKING
= 1 << 9,
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,
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
,
91 java_json_string
.obj());
96 ProfileSyncServiceAndroid::ProfileSyncServiceAndroid(JNIEnv
* env
, jobject obj
)
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";
106 profile_
= ProfileManager::GetActiveUserProfile();
107 if (profile_
== NULL
) {
108 NOTREACHED() << "Sync Init: Profile not found.";
112 sync_prefs_
.reset(new sync_driver::SyncPrefs(profile_
->GetPrefs()));
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() {
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
,
142 const std::string group_name
=
143 base::FieldTrialList::FindFullName("LimitSyncPassphrasePrompt");
144 if (group_name
!= "Enabled")
146 return sync_prefs_
->IsPassphrasePrompted();
149 void ProfileSyncServiceAndroid::SetPassphrasePrompted(JNIEnv
* env
,
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
);
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
);
180 std::string
status(sync_service_
->QuerySyncStatusSummaryString());
181 return ConvertUTF8ToJavaString(env
, status
);
184 void ProfileSyncServiceAndroid::GetAllNodes(JNIEnv
* env
,
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
);
199 std::string machine_tag
= ConvertJavaStringToUTF8(env
, tag
);
200 sync_prefs_
->SetSyncSessionsGUID(machine_tag
);
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
));
258 jboolean
ProfileSyncServiceAndroid::IsPassphraseRequiredForExternalType(
259 JNIEnv
* env
, jobject
) {
260 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
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(
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
465 return static_cast<jlong
>(
466 profile_
->GetPrefs()->GetInt64(sync_driver::prefs::kSyncLastSyncedTime
));
469 void ProfileSyncServiceAndroid::OverrideNetworkResourcesForTest(
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
));
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
;
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
);
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
);
568 bool ProfileSyncServiceAndroid::Register(JNIEnv
* env
) {
569 return RegisterNativesImpl(env
);