Check USB device path access when prompting users to select a device.
[chromium-blink-merge.git] / chrome / browser / sync / profile_sync_service_android.cc
blobc7350a8cc0b5ee78c1b59fbc731a273b5c19b814
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/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/profiles/profile_manager.h"
19 #include "chrome/browser/signin/signin_manager_factory.h"
20 #include "chrome/browser/sync/about_sync_util.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/grit/generated_resources.h"
25 #include "components/signin/core/browser/signin_manager.h"
26 #include "components/sync_driver/pref_names.h"
27 #include "components/sync_driver/sync_prefs.h"
28 #include "content/public/browser/browser_thread.h"
29 #include "google/cacheinvalidation/types.pb.h"
30 #include "google_apis/gaia/gaia_constants.h"
31 #include "google_apis/gaia/google_service_auth_error.h"
32 #include "jni/ProfileSyncService_jni.h"
33 #include "sync/internal_api/public/network_resources.h"
34 #include "sync/internal_api/public/read_transaction.h"
35 #include "ui/base/l10n/l10n_util.h"
37 using base::android::AttachCurrentThread;
38 using base::android::CheckException;
39 using base::android::ConvertJavaStringToUTF8;
40 using base::android::ConvertUTF8ToJavaString;
41 using base::android::ScopedJavaLocalRef;
42 using content::BrowserThread;
44 namespace {
46 // This enum contains the list of sync ModelTypes that Android can register for
47 // invalidations for.
49 // A Java counterpart will be generated for this enum.
50 // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.sync
51 enum ModelTypeSelection {
52 AUTOFILL = 1 << 0,
53 BOOKMARK = 1 << 1,
54 PASSWORD = 1 << 2,
55 SESSION = 1 << 3,
56 TYPED_URL = 1 << 4,
57 AUTOFILL_PROFILE = 1 << 5,
58 HISTORY_DELETE_DIRECTIVE = 1 << 6,
59 PROXY_TABS = 1 << 7,
60 FAVICON_IMAGE = 1 << 8,
61 FAVICON_TRACKING = 1 << 9,
62 NIGORI = 1 << 10,
63 DEVICE_INFO = 1 << 11,
64 EXPERIMENTS = 1 << 12,
65 SUPERVISED_USER_SETTING = 1 << 13,
66 SUPERVISED_USER_WHITELIST = 1 << 14,
67 AUTOFILL_WALLET = 1 << 15,
70 } // namespace
72 ProfileSyncServiceAndroid::ProfileSyncServiceAndroid(JNIEnv* env, jobject obj)
73 : profile_(NULL),
74 sync_service_(NULL),
75 weak_java_profile_sync_service_(env, obj) {
76 if (g_browser_process == NULL ||
77 g_browser_process->profile_manager() == NULL) {
78 NOTREACHED() << "Browser process or profile manager not initialized";
79 return;
82 profile_ = ProfileManager::GetActiveUserProfile();
83 if (profile_ == NULL) {
84 NOTREACHED() << "Sync Init: Profile not found.";
85 return;
88 sync_prefs_.reset(new sync_driver::SyncPrefs(profile_->GetPrefs()));
90 sync_service_ =
91 ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile_);
92 DCHECK(sync_service_);
95 void ProfileSyncServiceAndroid::Init() {
96 sync_service_->AddObserver(this);
99 void ProfileSyncServiceAndroid::RemoveObserver() {
100 if (sync_service_->HasObserver(this)) {
101 sync_service_->RemoveObserver(this);
105 ProfileSyncServiceAndroid::~ProfileSyncServiceAndroid() {
106 RemoveObserver();
109 void ProfileSyncServiceAndroid::OnStateChanged() {
110 // Notify the java world that our sync state has changed.
111 JNIEnv* env = AttachCurrentThread();
112 Java_ProfileSyncService_syncStateChanged(
113 env, weak_java_profile_sync_service_.get(env).obj());
116 void ProfileSyncServiceAndroid::EnableSync(JNIEnv* env, jobject) {
117 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
118 // Don't need to do anything if we're already enabled.
119 if (sync_prefs_->IsStartSuppressed())
120 sync_service_->UnsuppressAndStart();
121 else
122 DVLOG(2) << "Ignoring call to EnableSync() because sync is already enabled";
125 void ProfileSyncServiceAndroid::DisableSync(JNIEnv* env, jobject) {
126 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
127 // Don't need to do anything if we're already disabled.
128 if (!sync_prefs_->IsStartSuppressed()) {
129 sync_service_->StopAndSuppress();
130 } else {
131 DVLOG(2)
132 << "Ignoring call to DisableSync() because sync is already disabled";
136 void ProfileSyncServiceAndroid::SignInSync(JNIEnv* env, jobject) {
137 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
138 // Just return if sync already has everything it needs to start up (sync
139 // should start up automatically as long as it has credentials). This can
140 // happen normally if (for example) the user closes and reopens the sync
141 // settings window quickly during initial startup.
142 if (sync_service_->IsSyncEnabledAndLoggedIn() &&
143 sync_service_->IsOAuthRefreshTokenAvailable() &&
144 sync_service_->HasSyncSetupCompleted()) {
145 return;
148 // Enable sync (if we don't have credentials yet, this will enable sync but
149 // will not start it up - sync will start once credentials arrive).
150 sync_service_->UnsuppressAndStart();
153 void ProfileSyncServiceAndroid::SignOutSync(JNIEnv* env, jobject) {
154 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
155 DCHECK(profile_);
156 sync_service_->DisableForUser();
158 // Need to clear suppress start flag manually
159 sync_prefs_->SetStartSuppressed(false);
162 void ProfileSyncServiceAndroid::FlushDirectory(JNIEnv* env, jobject) {
163 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
164 sync_service_->FlushDirectory();
167 ScopedJavaLocalRef<jstring> ProfileSyncServiceAndroid::QuerySyncStatusSummary(
168 JNIEnv* env, jobject) {
169 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
170 DCHECK(profile_);
171 std::string status(sync_service_->QuerySyncStatusSummaryString());
172 return ConvertUTF8ToJavaString(env, status);
175 jboolean ProfileSyncServiceAndroid::SetSyncSessionsId(
176 JNIEnv* env, jobject obj, jstring tag) {
177 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
178 DCHECK(profile_);
179 std::string machine_tag = ConvertJavaStringToUTF8(env, tag);
180 sync_prefs_->SetSyncSessionsGUID(machine_tag);
181 return true;
184 jint ProfileSyncServiceAndroid::GetAuthError(JNIEnv* env, jobject) {
185 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
186 return sync_service_->GetAuthError().state();
189 jboolean ProfileSyncServiceAndroid::IsEncryptEverythingEnabled(
190 JNIEnv* env, jobject) {
191 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
192 return sync_service_->EncryptEverythingEnabled();
195 jboolean ProfileSyncServiceAndroid::IsSyncInitialized(JNIEnv* env, jobject) {
196 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
197 return sync_service_->backend_initialized();
200 jboolean ProfileSyncServiceAndroid::IsFirstSetupInProgress(
201 JNIEnv* env, jobject) {
202 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
203 return sync_service_->FirstSetupInProgress();
206 jboolean ProfileSyncServiceAndroid::IsEncryptEverythingAllowed(
207 JNIEnv* env, jobject obj) {
208 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
209 return sync_service_->EncryptEverythingAllowed();
212 jboolean ProfileSyncServiceAndroid::IsPassphraseRequired(JNIEnv* env, jobject) {
213 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
214 return sync_service_->IsPassphraseRequired();
217 jboolean ProfileSyncServiceAndroid::IsPassphraseRequiredForDecryption(
218 JNIEnv* env, jobject obj) {
219 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
220 // In case of CUSTOM_PASSPHRASE we always sync passwords. Prompt the user for
221 // a passphrase if cryptographer has any pending keys.
222 if (sync_service_->GetPassphraseType() == syncer::CUSTOM_PASSPHRASE) {
223 return !IsCryptographerReady(env, obj);
225 if (sync_service_->IsPassphraseRequiredForDecryption()) {
226 // Passwords datatype should never prompt for a passphrase, except when
227 // user is using a custom passphrase. Do not prompt for a passphrase if
228 // passwords are the only encrypted datatype. This prevents a temporary
229 // notification for passphrase when PSS has not completed configuring
230 // DataTypeManager, after configuration password datatype shall be disabled.
231 const syncer::ModelTypeSet encrypted_types =
232 sync_service_->GetEncryptedDataTypes();
233 return !encrypted_types.Equals(syncer::ModelTypeSet(syncer::PASSWORDS));
235 return false;
238 jboolean ProfileSyncServiceAndroid::IsPassphraseRequiredForExternalType(
239 JNIEnv* env, jobject) {
240 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
241 return
242 sync_service_->passphrase_required_reason() == syncer::REASON_DECRYPTION;
245 jboolean ProfileSyncServiceAndroid::IsUsingSecondaryPassphrase(
246 JNIEnv* env, jobject) {
247 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
248 return sync_service_->IsUsingSecondaryPassphrase();
251 jboolean ProfileSyncServiceAndroid::SetDecryptionPassphrase(
252 JNIEnv* env, jobject obj, jstring passphrase) {
253 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
254 std::string key = ConvertJavaStringToUTF8(env, passphrase);
255 return sync_service_->SetDecryptionPassphrase(key);
258 void ProfileSyncServiceAndroid::SetEncryptionPassphrase(
259 JNIEnv* env, jobject obj, jstring passphrase, jboolean is_gaia) {
260 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
261 std::string key = ConvertJavaStringToUTF8(env, passphrase);
262 sync_service_->SetEncryptionPassphrase(
263 key,
264 is_gaia ? ProfileSyncService::IMPLICIT : ProfileSyncService::EXPLICIT);
267 jboolean ProfileSyncServiceAndroid::IsCryptographerReady(JNIEnv* env, jobject) {
268 syncer::ReadTransaction trans(FROM_HERE, sync_service_->GetUserShare());
269 return sync_service_->IsCryptographerReady(&trans);
272 jint ProfileSyncServiceAndroid::GetPassphraseType(JNIEnv* env, jobject) {
273 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
274 return sync_service_->GetPassphraseType();
277 jboolean ProfileSyncServiceAndroid::HasExplicitPassphraseTime(
278 JNIEnv* env, jobject) {
279 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
280 base::Time passphrase_time = sync_service_->GetExplicitPassphraseTime();
281 return !passphrase_time.is_null();
284 jlong ProfileSyncServiceAndroid::GetExplicitPassphraseTime(
285 JNIEnv* env, jobject) {
286 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
287 base::Time passphrase_time = sync_service_->GetExplicitPassphraseTime();
288 return passphrase_time.ToJavaTime();
291 ScopedJavaLocalRef<jstring>
292 ProfileSyncServiceAndroid::GetSyncEnterGooglePassphraseBodyWithDateText(
293 JNIEnv* env, jobject) {
294 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
295 base::Time passphrase_time = sync_service_->GetExplicitPassphraseTime();
296 base::string16 passphrase_time_str =
297 base::TimeFormatShortDate(passphrase_time);
298 return base::android::ConvertUTF16ToJavaString(env,
299 l10n_util::GetStringFUTF16(
300 IDS_SYNC_ENTER_GOOGLE_PASSPHRASE_BODY_WITH_DATE,
301 passphrase_time_str));
304 ScopedJavaLocalRef<jstring>
305 ProfileSyncServiceAndroid::GetSyncEnterCustomPassphraseBodyWithDateText(
306 JNIEnv* env, jobject) {
307 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
308 base::Time passphrase_time = sync_service_->GetExplicitPassphraseTime();
309 base::string16 passphrase_time_str =
310 base::TimeFormatShortDate(passphrase_time);
311 return base::android::ConvertUTF16ToJavaString(env,
312 l10n_util::GetStringFUTF16(IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE,
313 passphrase_time_str));
316 ScopedJavaLocalRef<jstring>
317 ProfileSyncServiceAndroid::GetCurrentSignedInAccountText(
318 JNIEnv* env, jobject) {
319 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
320 const std::string& sync_username =
321 SigninManagerFactory::GetForProfile(profile_)->GetAuthenticatedUsername();
322 return base::android::ConvertUTF16ToJavaString(env,
323 l10n_util::GetStringFUTF16(
324 IDS_SYNC_ACCOUNT_SYNCING_TO_USER,
325 base::ASCIIToUTF16(sync_username)));
328 ScopedJavaLocalRef<jstring>
329 ProfileSyncServiceAndroid::GetSyncEnterCustomPassphraseBodyText(
330 JNIEnv* env, jobject) {
331 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
332 return ConvertUTF8ToJavaString(
333 env, l10n_util::GetStringUTF8(IDS_SYNC_ENTER_PASSPHRASE_BODY));
336 jboolean ProfileSyncServiceAndroid::IsSyncKeystoreMigrationDone(
337 JNIEnv* env, jobject) {
338 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
339 syncer::SyncStatus status;
340 bool is_status_valid = sync_service_->QueryDetailedSyncStatus(&status);
341 return is_status_valid && !status.keystore_migration_time.is_null();
344 jlong ProfileSyncServiceAndroid::GetActiveDataTypes(
345 JNIEnv* env, jobject obj) {
346 syncer::ModelTypeSet types = sync_service_->GetActiveDataTypes();
347 types.PutAll(syncer::ControlTypes());
348 return ModelTypeSetToSelection(types);
351 jlong ProfileSyncServiceAndroid::GetPreferredDataTypes(
352 JNIEnv* env, jobject obj) {
353 syncer::ModelTypeSet types = sync_service_->GetPreferredDataTypes();
354 types.PutAll(syncer::ControlTypes());
355 return ModelTypeSetToSelection(types);
358 void ProfileSyncServiceAndroid::SetPreferredDataTypes(
359 JNIEnv* env, jobject obj,
360 jboolean sync_everything,
361 jlong model_type_selection) {
362 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
363 syncer::ModelTypeSet types;
364 // Note: only user selectable types should be included here.
365 if (model_type_selection & AUTOFILL)
366 types.Put(syncer::AUTOFILL);
367 if (model_type_selection & BOOKMARK)
368 types.Put(syncer::BOOKMARKS);
369 if (model_type_selection & PASSWORD)
370 types.Put(syncer::PASSWORDS);
371 if (model_type_selection & PROXY_TABS)
372 types.Put(syncer::PROXY_TABS);
373 if (model_type_selection & TYPED_URL)
374 types.Put(syncer::TYPED_URLS);
375 DCHECK(syncer::UserSelectableTypes().HasAll(types));
376 sync_service_->OnUserChoseDatatypes(sync_everything, types);
379 void ProfileSyncServiceAndroid::SetSetupInProgress(
380 JNIEnv* env, jobject obj, jboolean in_progress) {
381 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
382 sync_service_->SetSetupInProgress(in_progress);
385 void ProfileSyncServiceAndroid::SetSyncSetupCompleted(
386 JNIEnv* env, jobject obj) {
387 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
388 sync_service_->SetSyncSetupCompleted();
391 jboolean ProfileSyncServiceAndroid::HasSyncSetupCompleted(
392 JNIEnv* env, jobject obj) {
393 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
394 return sync_service_->HasSyncSetupCompleted();
397 jboolean ProfileSyncServiceAndroid::IsStartSuppressed(
398 JNIEnv* env, jobject obj) {
399 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
400 return sync_prefs_->IsStartSuppressed();
403 void ProfileSyncServiceAndroid::EnableEncryptEverything(
404 JNIEnv* env, jobject obj) {
405 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
406 sync_service_->EnableEncryptEverything();
409 jboolean ProfileSyncServiceAndroid::HasKeepEverythingSynced(
410 JNIEnv* env, jobject) {
411 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
412 return sync_prefs_->HasKeepEverythingSynced();
415 jboolean ProfileSyncServiceAndroid::HasUnrecoverableError(
416 JNIEnv* env, jobject) {
417 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
418 return sync_service_->HasUnrecoverableError();
421 ScopedJavaLocalRef<jstring> ProfileSyncServiceAndroid::GetAboutInfoForTest(
422 JNIEnv* env, jobject) {
423 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
425 scoped_ptr<base::DictionaryValue> about_info =
426 sync_ui_util::ConstructAboutInformation(sync_service_);
427 std::string about_info_json;
428 base::JSONWriter::Write(about_info.get(), &about_info_json);
430 return ConvertUTF8ToJavaString(env, about_info_json);
433 jlong ProfileSyncServiceAndroid::GetLastSyncedTimeForTest(
434 JNIEnv* env, jobject obj) {
435 // Use profile preferences here instead of SyncPrefs to avoid an extra
436 // conversion, since SyncPrefs::GetLastSyncedTime() converts the stored value
437 // to to base::Time.
438 return static_cast<jlong>(
439 profile_->GetPrefs()->GetInt64(sync_driver::prefs::kSyncLastSyncedTime));
442 void ProfileSyncServiceAndroid::OverrideNetworkResourcesForTest(
443 JNIEnv* env,
444 jobject obj,
445 jlong network_resources) {
446 syncer::NetworkResources* resources =
447 reinterpret_cast<syncer::NetworkResources*>(network_resources);
448 sync_service_->OverrideNetworkResourcesForTest(
449 make_scoped_ptr<syncer::NetworkResources>(resources));
452 // static
453 jlong ProfileSyncServiceAndroid::ModelTypeSetToSelection(
454 syncer::ModelTypeSet types) {
455 jlong model_type_selection = 0;
456 if (types.Has(syncer::BOOKMARKS)) {
457 model_type_selection |= BOOKMARK;
459 if (types.Has(syncer::AUTOFILL)) {
460 model_type_selection |= AUTOFILL;
462 if (types.Has(syncer::AUTOFILL_PROFILE)) {
463 model_type_selection |= AUTOFILL_PROFILE;
465 if (types.Has(syncer::AUTOFILL_WALLET_DATA)) {
466 model_type_selection |= AUTOFILL_WALLET;
468 if (types.Has(syncer::PASSWORDS)) {
469 model_type_selection |= PASSWORD;
471 if (types.Has(syncer::TYPED_URLS)) {
472 model_type_selection |= TYPED_URL;
474 if (types.Has(syncer::SESSIONS)) {
475 model_type_selection |= SESSION;
477 if (types.Has(syncer::HISTORY_DELETE_DIRECTIVES)) {
478 model_type_selection |= HISTORY_DELETE_DIRECTIVE;
480 if (types.Has(syncer::PROXY_TABS)) {
481 model_type_selection |= PROXY_TABS;
483 if (types.Has(syncer::FAVICON_IMAGES)) {
484 model_type_selection |= FAVICON_IMAGE;
486 if (types.Has(syncer::FAVICON_TRACKING)) {
487 model_type_selection |= FAVICON_TRACKING;
489 if (types.Has(syncer::DEVICE_INFO)) {
490 model_type_selection |= DEVICE_INFO;
492 if (types.Has(syncer::NIGORI)) {
493 model_type_selection |= NIGORI;
495 if (types.Has(syncer::EXPERIMENTS)) {
496 model_type_selection |= EXPERIMENTS;
498 if (types.Has(syncer::SUPERVISED_USER_SETTINGS)) {
499 model_type_selection |= SUPERVISED_USER_SETTING;
501 if (types.Has(syncer::SUPERVISED_USER_WHITELISTS)) {
502 model_type_selection |= SUPERVISED_USER_WHITELIST;
504 return model_type_selection;
507 // static
508 std::string ProfileSyncServiceAndroid::ModelTypeSelectionToStringForTest(
509 jlong model_type_selection) {
510 ScopedJavaLocalRef<jstring> string =
511 Java_ProfileSyncService_modelTypeSelectionToStringForTest(
512 AttachCurrentThread(), model_type_selection);
513 return ConvertJavaStringToUTF8(string);
516 // static
517 ProfileSyncServiceAndroid*
518 ProfileSyncServiceAndroid::GetProfileSyncServiceAndroid() {
519 return reinterpret_cast<ProfileSyncServiceAndroid*>(
520 Java_ProfileSyncService_getProfileSyncServiceAndroid(
521 AttachCurrentThread(), base::android::GetApplicationContext()));
524 static jlong Init(JNIEnv* env, jobject obj) {
525 ProfileSyncServiceAndroid* profile_sync_service_android =
526 new ProfileSyncServiceAndroid(env, obj);
527 profile_sync_service_android->Init();
528 return reinterpret_cast<intptr_t>(profile_sync_service_android);
531 // static
532 bool ProfileSyncServiceAndroid::Register(JNIEnv* env) {
533 return RegisterNativesImpl(env);