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_array.h"
9 #include "base/android/jni_string.h"
10 #include "base/bind.h"
11 #include "base/i18n/time_formatting.h"
12 #include "base/json/json_writer.h"
13 #include "base/logging.h"
14 #include "base/memory/scoped_ptr.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/profile_sync_service.h"
22 #include "chrome/browser/sync/profile_sync_service_factory.h"
23 #include "chrome/browser/sync/sync_ui_util.h"
24 #include "chrome/common/channel_info.h"
25 #include "chrome/grit/generated_resources.h"
26 #include "components/signin/core/browser/signin_manager.h"
27 #include "components/sync_driver/about_sync_util.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 "google/cacheinvalidation/types.pb.h"
32 #include "google_apis/gaia/gaia_constants.h"
33 #include "google_apis/gaia/google_service_auth_error.h"
34 #include "jni/ProfileSyncService_jni.h"
35 #include "sync/internal_api/public/network_resources.h"
36 #include "sync/internal_api/public/read_transaction.h"
37 #include "ui/base/l10n/l10n_util.h"
39 using base::android::AttachCurrentThread
;
40 using base::android::CheckException
;
41 using base::android::ConvertJavaStringToUTF8
;
42 using base::android::ConvertUTF8ToJavaString
;
43 using base::android::ScopedJavaLocalRef
;
44 using content::BrowserThread
;
48 // Native callback for the JNI GetAllNodes method. When
49 // ProfileSyncService::GetAllNodes completes, this method is called and the
50 // results are sent to the Java callback.
51 void NativeGetAllNodesCallback(
52 const base::android::ScopedJavaGlobalRef
<jobject
>& callback
,
53 scoped_ptr
<base::ListValue
> result
) {
54 JNIEnv
* env
= base::android::AttachCurrentThread();
55 std::string json_string
;
56 if (!result
.get() || !base::JSONWriter::Write(*result
, &json_string
)) {
57 DVLOG(1) << "Writing as JSON failed. Passing empty string to Java code.";
58 json_string
= std::string();
61 ScopedJavaLocalRef
<jstring
> java_json_string
=
62 ConvertUTF8ToJavaString(env
, json_string
);
63 Java_ProfileSyncService_onGetAllNodesResult(env
,
65 java_json_string
.obj());
70 ProfileSyncServiceAndroid::ProfileSyncServiceAndroid(JNIEnv
* env
, jobject obj
)
73 weak_java_profile_sync_service_(env
, obj
) {
74 if (g_browser_process
== NULL
||
75 g_browser_process
->profile_manager() == NULL
) {
76 NOTREACHED() << "Browser process or profile manager not initialized";
80 profile_
= ProfileManager::GetActiveUserProfile();
81 if (profile_
== NULL
) {
82 NOTREACHED() << "Sync Init: Profile not found.";
86 sync_prefs_
.reset(new sync_driver::SyncPrefs(profile_
->GetPrefs()));
89 ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile_
);
90 DCHECK(sync_service_
);
93 void ProfileSyncServiceAndroid::Init() {
94 sync_service_
->AddObserver(this);
97 void ProfileSyncServiceAndroid::RemoveObserver() {
98 if (sync_service_
->HasObserver(this)) {
99 sync_service_
->RemoveObserver(this);
103 ProfileSyncServiceAndroid::~ProfileSyncServiceAndroid() {
107 void ProfileSyncServiceAndroid::OnStateChanged() {
108 // Notify the java world that our sync state has changed.
109 JNIEnv
* env
= AttachCurrentThread();
110 Java_ProfileSyncService_syncStateChanged(
111 env
, weak_java_profile_sync_service_
.get(env
).obj());
114 jboolean
ProfileSyncServiceAndroid::IsPassphrasePrompted(JNIEnv
* env
,
116 return sync_prefs_
->IsPassphrasePrompted();
119 void ProfileSyncServiceAndroid::SetPassphrasePrompted(JNIEnv
* env
,
122 sync_prefs_
->SetPassphrasePrompted(prompted
);
125 void ProfileSyncServiceAndroid::RequestStart(JNIEnv
* env
, jobject
) {
126 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
127 sync_service_
->RequestStart();
130 void ProfileSyncServiceAndroid::RequestStop(JNIEnv
* env
, jobject
) {
131 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
132 sync_service_
->RequestStop(ProfileSyncService::KEEP_DATA
);
135 void ProfileSyncServiceAndroid::SignOutSync(JNIEnv
* env
, jobject
) {
136 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
138 sync_service_
->RequestStop(ProfileSyncService::CLEAR_DATA
);
141 void ProfileSyncServiceAndroid::FlushDirectory(JNIEnv
* env
, jobject
) {
142 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
143 sync_service_
->FlushDirectory();
146 ScopedJavaLocalRef
<jstring
> ProfileSyncServiceAndroid::QuerySyncStatusSummary(
147 JNIEnv
* env
, jobject
) {
148 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
150 std::string
status(sync_service_
->QuerySyncStatusSummaryString());
151 return ConvertUTF8ToJavaString(env
, status
);
154 void ProfileSyncServiceAndroid::GetAllNodes(JNIEnv
* env
,
157 base::android::ScopedJavaGlobalRef
<jobject
> java_callback
;
158 java_callback
.Reset(env
, callback
);
160 base::Callback
<void(scoped_ptr
<base::ListValue
>)> native_callback
=
161 base::Bind(&NativeGetAllNodesCallback
, java_callback
);
162 sync_service_
->GetAllNodes(native_callback
);
165 void ProfileSyncServiceAndroid::SetSyncSessionsId(
166 JNIEnv
* env
, jobject obj
, jstring tag
) {
167 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
169 std::string machine_tag
= ConvertJavaStringToUTF8(env
, tag
);
170 sync_prefs_
->SetSyncSessionsGUID(machine_tag
);
173 jint
ProfileSyncServiceAndroid::GetAuthError(JNIEnv
* env
, jobject
) {
174 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
175 return sync_service_
->GetAuthError().state();
178 jboolean
ProfileSyncServiceAndroid::IsEncryptEverythingEnabled(
179 JNIEnv
* env
, jobject
) {
180 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
181 return sync_service_
->IsEncryptEverythingEnabled();
184 jboolean
ProfileSyncServiceAndroid::IsBackendInitialized(JNIEnv
* env
, jobject
) {
185 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
186 return sync_service_
->IsBackendInitialized();
189 jboolean
ProfileSyncServiceAndroid::IsFirstSetupInProgress(
190 JNIEnv
* env
, jobject
) {
191 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
192 return sync_service_
->IsFirstSetupInProgress();
195 jboolean
ProfileSyncServiceAndroid::IsEncryptEverythingAllowed(
196 JNIEnv
* env
, jobject obj
) {
197 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
198 return sync_service_
->IsEncryptEverythingAllowed();
201 jboolean
ProfileSyncServiceAndroid::IsPassphraseRequired(JNIEnv
* env
, jobject
) {
202 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
203 return sync_service_
->IsPassphraseRequired();
206 jboolean
ProfileSyncServiceAndroid::IsPassphraseRequiredForDecryption(
207 JNIEnv
* env
, jobject obj
) {
208 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
209 return sync_service_
->IsPassphraseRequiredForDecryption();
212 jboolean
ProfileSyncServiceAndroid::IsUsingSecondaryPassphrase(
213 JNIEnv
* env
, jobject
) {
214 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
215 return sync_service_
->IsUsingSecondaryPassphrase();
218 jboolean
ProfileSyncServiceAndroid::SetDecryptionPassphrase(
219 JNIEnv
* env
, jobject obj
, jstring passphrase
) {
220 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
221 std::string key
= ConvertJavaStringToUTF8(env
, passphrase
);
222 return sync_service_
->SetDecryptionPassphrase(key
);
225 void ProfileSyncServiceAndroid::SetEncryptionPassphrase(
226 JNIEnv
* env
, jobject obj
, jstring passphrase
) {
227 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
228 std::string key
= ConvertJavaStringToUTF8(env
, passphrase
);
229 sync_service_
->SetEncryptionPassphrase(key
, ProfileSyncService::EXPLICIT
);
232 jboolean
ProfileSyncServiceAndroid::IsCryptographerReady(JNIEnv
* env
, jobject
) {
233 syncer::ReadTransaction
trans(FROM_HERE
, sync_service_
->GetUserShare());
234 return sync_service_
->IsCryptographerReady(&trans
);
237 jint
ProfileSyncServiceAndroid::GetPassphraseType(JNIEnv
* env
, jobject
) {
238 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
239 return sync_service_
->GetPassphraseType();
242 jboolean
ProfileSyncServiceAndroid::HasExplicitPassphraseTime(
243 JNIEnv
* env
, jobject
) {
244 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
245 base::Time passphrase_time
= sync_service_
->GetExplicitPassphraseTime();
246 return !passphrase_time
.is_null();
249 jlong
ProfileSyncServiceAndroid::GetExplicitPassphraseTime(
250 JNIEnv
* env
, jobject
) {
251 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
252 base::Time passphrase_time
= sync_service_
->GetExplicitPassphraseTime();
253 return passphrase_time
.ToJavaTime();
256 ScopedJavaLocalRef
<jstring
>
257 ProfileSyncServiceAndroid::GetSyncEnterGooglePassphraseBodyWithDateText(
258 JNIEnv
* env
, jobject
) {
259 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
260 base::Time passphrase_time
= sync_service_
->GetExplicitPassphraseTime();
261 base::string16 passphrase_time_str
=
262 base::TimeFormatShortDate(passphrase_time
);
263 return base::android::ConvertUTF16ToJavaString(env
,
264 l10n_util::GetStringFUTF16(
265 IDS_SYNC_ENTER_GOOGLE_PASSPHRASE_BODY_WITH_DATE
,
266 passphrase_time_str
));
269 ScopedJavaLocalRef
<jstring
>
270 ProfileSyncServiceAndroid::GetSyncEnterCustomPassphraseBodyWithDateText(
271 JNIEnv
* env
, jobject
) {
272 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
273 base::Time passphrase_time
= sync_service_
->GetExplicitPassphraseTime();
274 base::string16 passphrase_time_str
=
275 base::TimeFormatShortDate(passphrase_time
);
276 return base::android::ConvertUTF16ToJavaString(env
,
277 l10n_util::GetStringFUTF16(IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE
,
278 passphrase_time_str
));
281 ScopedJavaLocalRef
<jstring
>
282 ProfileSyncServiceAndroid::GetCurrentSignedInAccountText(
283 JNIEnv
* env
, jobject
) {
284 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
285 const std::string
& sync_username
=
286 SigninManagerFactory::GetForProfile(profile_
)
287 ->GetAuthenticatedAccountInfo()
289 return base::android::ConvertUTF16ToJavaString(env
,
290 l10n_util::GetStringFUTF16(
291 IDS_SYNC_ACCOUNT_SYNCING_TO_USER
,
292 base::ASCIIToUTF16(sync_username
)));
295 ScopedJavaLocalRef
<jstring
>
296 ProfileSyncServiceAndroid::GetSyncEnterCustomPassphraseBodyText(
297 JNIEnv
* env
, jobject
) {
298 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
299 return ConvertUTF8ToJavaString(
300 env
, l10n_util::GetStringUTF8(IDS_SYNC_ENTER_PASSPHRASE_BODY
));
303 jboolean
ProfileSyncServiceAndroid::IsSyncKeystoreMigrationDone(
304 JNIEnv
* env
, jobject
) {
305 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
306 syncer::SyncStatus status
;
307 bool is_status_valid
= sync_service_
->QueryDetailedSyncStatus(&status
);
308 return is_status_valid
&& !status
.keystore_migration_time
.is_null();
311 ScopedJavaLocalRef
<jintArray
> ProfileSyncServiceAndroid::GetActiveDataTypes(
312 JNIEnv
* env
, jobject obj
) {
313 syncer::ModelTypeSet types
= sync_service_
->GetActiveDataTypes();
314 types
.PutAll(syncer::ControlTypes());
315 return ModelTypeSetToJavaIntArray(env
, types
);
318 ScopedJavaLocalRef
<jintArray
> ProfileSyncServiceAndroid::GetPreferredDataTypes(
319 JNIEnv
* env
, jobject obj
) {
320 syncer::ModelTypeSet types
= sync_service_
->GetPreferredDataTypes();
321 types
.PutAll(syncer::ControlTypes());
322 return ModelTypeSetToJavaIntArray(env
, types
);
325 void ProfileSyncServiceAndroid::SetPreferredDataTypes(
326 JNIEnv
* env
, jobject obj
,
327 jboolean sync_everything
,
328 jintArray model_type_array
) {
329 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
330 std::vector
<int> types_vector
;
331 base::android::JavaIntArrayToIntVector(env
, model_type_array
, &types_vector
);
332 syncer::ModelTypeSet types
;
333 for (size_t i
= 0; i
< types_vector
.size(); i
++) {
334 types
.Put(static_cast<syncer::ModelType
>(types_vector
[i
]));
336 types
.RetainAll(syncer::UserSelectableTypes());
337 sync_service_
->OnUserChoseDatatypes(sync_everything
, types
);
340 void ProfileSyncServiceAndroid::SetSetupInProgress(
341 JNIEnv
* env
, jobject obj
, jboolean in_progress
) {
342 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
343 sync_service_
->SetSetupInProgress(in_progress
);
346 void ProfileSyncServiceAndroid::SetSyncSetupCompleted(
347 JNIEnv
* env
, jobject obj
) {
348 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
349 sync_service_
->SetSyncSetupCompleted();
352 jboolean
ProfileSyncServiceAndroid::HasSyncSetupCompleted(
353 JNIEnv
* env
, jobject obj
) {
354 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
355 return sync_service_
->HasSyncSetupCompleted();
358 jboolean
ProfileSyncServiceAndroid::IsSyncRequested(
359 JNIEnv
* env
, jobject obj
) {
360 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
361 return sync_service_
->IsSyncRequested();
364 jboolean
ProfileSyncServiceAndroid::IsSyncActive(JNIEnv
* env
, jobject obj
) {
365 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
366 return sync_service_
->IsSyncActive();
369 void ProfileSyncServiceAndroid::EnableEncryptEverything(
370 JNIEnv
* env
, jobject obj
) {
371 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
372 sync_service_
->EnableEncryptEverything();
375 jboolean
ProfileSyncServiceAndroid::HasKeepEverythingSynced(
376 JNIEnv
* env
, jobject
) {
377 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
378 return sync_prefs_
->HasKeepEverythingSynced();
381 jboolean
ProfileSyncServiceAndroid::HasUnrecoverableError(
382 JNIEnv
* env
, jobject
) {
383 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
384 return sync_service_
->HasUnrecoverableError();
387 ScopedJavaLocalRef
<jstring
> ProfileSyncServiceAndroid::GetAboutInfoForTest(
388 JNIEnv
* env
, jobject
) {
389 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
391 scoped_ptr
<base::DictionaryValue
> about_info
=
392 sync_driver::sync_ui_util::ConstructAboutInformation(
393 sync_service_
, sync_service_
->signin(), chrome::GetChannel());
394 std::string about_info_json
;
395 base::JSONWriter::Write(*about_info
, &about_info_json
);
397 return ConvertUTF8ToJavaString(env
, about_info_json
);
400 jlong
ProfileSyncServiceAndroid::GetLastSyncedTimeForTest(
401 JNIEnv
* env
, jobject obj
) {
402 // Use profile preferences here instead of SyncPrefs to avoid an extra
403 // conversion, since SyncPrefs::GetLastSyncedTime() converts the stored value
405 return static_cast<jlong
>(
406 profile_
->GetPrefs()->GetInt64(sync_driver::prefs::kSyncLastSyncedTime
));
409 void ProfileSyncServiceAndroid::OverrideNetworkResourcesForTest(
412 jlong network_resources
) {
413 syncer::NetworkResources
* resources
=
414 reinterpret_cast<syncer::NetworkResources
*>(network_resources
);
415 sync_service_
->OverrideNetworkResourcesForTest(
416 make_scoped_ptr
<syncer::NetworkResources
>(resources
));
420 ScopedJavaLocalRef
<jintArray
>
421 ProfileSyncServiceAndroid::ModelTypeSetToJavaIntArray(
423 syncer::ModelTypeSet types
) {
424 std::vector
<int> type_vector
;
425 for (syncer::ModelTypeSet::Iterator it
= types
.First(); it
.Good(); it
.Inc()) {
426 type_vector
.push_back(it
.Get());
428 return base::android::ToJavaIntArray(env
, type_vector
);
432 ProfileSyncServiceAndroid
*
433 ProfileSyncServiceAndroid::GetProfileSyncServiceAndroid() {
434 return reinterpret_cast<ProfileSyncServiceAndroid
*>(
435 Java_ProfileSyncService_getProfileSyncServiceAndroid(
436 AttachCurrentThread()));
439 static jlong
Init(JNIEnv
* env
, const JavaParamRef
<jobject
>& obj
) {
440 ProfileSyncServiceAndroid
* profile_sync_service_android
=
441 new ProfileSyncServiceAndroid(env
, obj
);
442 profile_sync_service_android
->Init();
443 return reinterpret_cast<intptr_t>(profile_sync_service_android
);
447 bool ProfileSyncServiceAndroid::Register(JNIEnv
* env
) {
448 return RegisterNativesImpl(env
);