Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(669)

Side by Side Diff: chrome/browser/android/preferences/pref_service_bridge.cc

Issue 2756173002: Move code about browsing data from PrefServiceBridge to BrowsingDataBridge. (Closed)
Patch Set: fix comments Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/android/chrome_jni_registrar.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/android/preferences/pref_service_bridge.h" 5 #include "chrome/browser/android/preferences/pref_service_bridge.h"
6 6
7 #include <jni.h> 7 #include <jni.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 9
10 #include <memory> 10 #include <memory>
11 #include <set> 11 #include <set>
12 #include <string> 12 #include <string>
13 #include <vector> 13 #include <vector>
14 14
15 #include "base/android/build_info.h" 15 #include "base/android/build_info.h"
16 #include "base/android/jni_android.h" 16 #include "base/android/jni_android.h"
17 #include "base/android/jni_array.h" 17 #include "base/android/jni_array.h"
18 #include "base/android/jni_string.h" 18 #include "base/android/jni_string.h"
19 #include "base/android/jni_weak_ref.h" 19 #include "base/android/jni_weak_ref.h"
20 #include "base/feature_list.h" 20 #include "base/feature_list.h"
21 #include "base/files/file_path.h" 21 #include "base/files/file_path.h"
22 #include "base/files/file_util.h" 22 #include "base/files/file_util.h"
23 #include "base/metrics/histogram_macros.h"
24 #include "base/scoped_observer.h" 23 #include "base/scoped_observer.h"
25 #include "base/strings/string_split.h" 24 #include "base/strings/string_split.h"
26 #include "base/strings/string_util.h" 25 #include "base/strings/string_util.h"
27 #include "base/values.h" 26 #include "base/values.h"
28 #include "chrome/browser/browser_process.h" 27 #include "chrome/browser/browser_process.h"
29 #include "chrome/browser/browsing_data/browsing_data_helper.h"
30 #include "chrome/browser/browsing_data/browsing_data_remover.h"
31 #include "chrome/browser/browsing_data/browsing_data_remover_factory.h"
32 #include "chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h"
33 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" 28 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
34 #include "chrome/browser/engagement/important_sites_util.h"
35 #include "chrome/browser/history/web_history_service_factory.h"
36 #include "chrome/browser/net/prediction_options.h" 29 #include "chrome/browser/net/prediction_options.h"
37 #include "chrome/browser/prefs/incognito_mode_prefs.h" 30 #include "chrome/browser/prefs/incognito_mode_prefs.h"
38 #include "chrome/browser/profiles/profile_manager.h" 31 #include "chrome/browser/profiles/profile_manager.h"
39 #include "chrome/browser/sync/profile_sync_service_factory.h"
40 #include "chrome/browser/translate/chrome_translate_client.h" 32 #include "chrome/browser/translate/chrome_translate_client.h"
41 #include "chrome/browser/ui/android/android_about_app_info.h" 33 #include "chrome/browser/ui/android/android_about_app_info.h"
42 #include "chrome/common/channel_info.h"
43 #include "chrome/common/chrome_features.h" 34 #include "chrome/common/chrome_features.h"
44 #include "chrome/common/pref_names.h" 35 #include "chrome/common/pref_names.h"
45 #include "chrome/grit/locale_settings.h" 36 #include "chrome/grit/locale_settings.h"
46 #include "components/browser_sync/profile_sync_service.h"
47 #include "components/browsing_data/core/browsing_data_utils.h" 37 #include "components/browsing_data/core/browsing_data_utils.h"
48 #include "components/browsing_data/core/history_notice_utils.h"
49 #include "components/browsing_data/core/pref_names.h" 38 #include "components/browsing_data/core/pref_names.h"
50 #include "components/content_settings/core/browser/host_content_settings_map.h" 39 #include "components/content_settings/core/browser/host_content_settings_map.h"
51 #include "components/content_settings/core/common/content_settings.h" 40 #include "components/content_settings/core/common/content_settings.h"
52 #include "components/content_settings/core/common/content_settings_pattern.h" 41 #include "components/content_settings/core/common/content_settings_pattern.h"
53 #include "components/content_settings/core/common/pref_names.h" 42 #include "components/content_settings/core/common/pref_names.h"
54 #include "components/metrics/metrics_pref_names.h" 43 #include "components/metrics/metrics_pref_names.h"
55 #include "components/password_manager/core/common/password_manager_pref_names.h" 44 #include "components/password_manager/core/common/password_manager_pref_names.h"
56 #include "components/prefs/pref_service.h" 45 #include "components/prefs/pref_service.h"
57 #include "components/safe_browsing_db/safe_browsing_prefs.h" 46 #include "components/safe_browsing_db/safe_browsing_prefs.h"
58 #include "components/signin/core/common/signin_pref_names.h" 47 #include "components/signin/core/common/signin_pref_names.h"
59 #include "components/strings/grit/components_locale_settings.h" 48 #include "components/strings/grit/components_locale_settings.h"
60 #include "components/translate/core/browser/translate_prefs.h" 49 #include "components/translate/core/browser/translate_prefs.h"
61 #include "components/translate/core/common/translate_pref_names.h" 50 #include "components/translate/core/common/translate_pref_names.h"
62 #include "components/version_info/version_info.h" 51 #include "components/version_info/version_info.h"
63 #include "components/web_resource/web_resource_pref_names.h" 52 #include "components/web_resource/web_resource_pref_names.h"
64 #include "content/public/browser/browser_thread.h" 53 #include "content/public/browser/browser_thread.h"
65 #include "content/public/browser/browsing_data_filter_builder.h"
66 #include "jni/PrefServiceBridge_jni.h" 54 #include "jni/PrefServiceBridge_jni.h"
67 #include "third_party/icu/source/common/unicode/uloc.h" 55 #include "third_party/icu/source/common/unicode/uloc.h"
68 #include "ui/base/l10n/l10n_util.h" 56 #include "ui/base/l10n/l10n_util.h"
69 57
70 using base::android::AttachCurrentThread; 58 using base::android::AttachCurrentThread;
71 using base::android::CheckException;
72 using base::android::ConvertJavaStringToUTF8; 59 using base::android::ConvertJavaStringToUTF8;
73 using base::android::ConvertUTF8ToJavaString; 60 using base::android::ConvertUTF8ToJavaString;
74 using base::android::JavaParamRef; 61 using base::android::JavaParamRef;
75 using base::android::JavaRef;
76 using base::android::ScopedJavaLocalRef; 62 using base::android::ScopedJavaLocalRef;
77 using base::android::ScopedJavaGlobalRef;
78 using content::BrowserThread;
79 63
80 namespace { 64 namespace {
81 65
82 const size_t kMaxImportantSites = 5;
83
84 Profile* GetOriginalProfile() { 66 Profile* GetOriginalProfile() {
85 return ProfileManager::GetActiveUserProfile()->GetOriginalProfile(); 67 return ProfileManager::GetActiveUserProfile()->GetOriginalProfile();
86 } 68 }
87 69
88 bool GetBooleanForContentSetting(ContentSettingsType type) { 70 bool GetBooleanForContentSetting(ContentSettingsType type) {
89 HostContentSettingsMap* content_settings = 71 HostContentSettingsMap* content_settings =
90 HostContentSettingsMapFactory::GetForProfile(GetOriginalProfile()); 72 HostContentSettingsMapFactory::GetForProfile(GetOriginalProfile());
91 switch (content_settings->GetDefaultContentSetting(type, NULL)) { 73 switch (content_settings->GetDefaultContentSetting(type, NULL)) {
92 case CONTENT_SETTING_BLOCK: 74 case CONTENT_SETTING_BLOCK:
93 return false; 75 return false;
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 } 485 }
504 486
505 static ScopedJavaLocalRef<jstring> GetLatestVersionWhenClickedUpdateMenuItem( 487 static ScopedJavaLocalRef<jstring> GetLatestVersionWhenClickedUpdateMenuItem(
506 JNIEnv* env, 488 JNIEnv* env,
507 const JavaParamRef<jobject>& obj) { 489 const JavaParamRef<jobject>& obj) {
508 return ConvertUTF8ToJavaString( 490 return ConvertUTF8ToJavaString(
509 env, GetPrefService()->GetString( 491 env, GetPrefService()->GetString(
510 prefs::kLatestVersionWhenClickedUpdateMenuItem)); 492 prefs::kLatestVersionWhenClickedUpdateMenuItem));
511 } 493 }
512 494
513 namespace {
514
515 // Merges |task_count| BrowsingDataRemover completion callbacks and redirects
516 // them back into Java.
517 class ClearBrowsingDataObserver : public BrowsingDataRemover::Observer {
518 public:
519 // |obj| is expected to be the object passed into ClearBrowsingData(); e.g. a
520 // ChromePreference.
521 ClearBrowsingDataObserver(JNIEnv* env,
522 jobject obj,
523 BrowsingDataRemover* browsing_data_remover,
524 int task_count)
525 : task_count_(task_count),
526 weak_chrome_native_preferences_(env, obj),
527 observer_(this) {
528 DCHECK_GT(task_count, 0);
529 observer_.Add(browsing_data_remover);
530 }
531
532 void OnBrowsingDataRemoverDone() override {
533 DCHECK(task_count_);
534 if (--task_count_)
535 return;
536
537 // We delete ourselves when done.
538 std::unique_ptr<ClearBrowsingDataObserver> auto_delete(this);
539
540 JNIEnv* env = AttachCurrentThread();
541 if (weak_chrome_native_preferences_.get(env).is_null())
542 return;
543
544 Java_PrefServiceBridge_browsingDataCleared(
545 env, weak_chrome_native_preferences_.get(env));
546 }
547
548 private:
549 int task_count_;
550 JavaObjectWeakGlobalRef weak_chrome_native_preferences_;
551 ScopedObserver<BrowsingDataRemover, BrowsingDataRemover::Observer> observer_;
552 };
553
554 } // namespace
555
556 static jboolean GetBrowsingDataDeletionPreference( 495 static jboolean GetBrowsingDataDeletionPreference(
557 JNIEnv* env, 496 JNIEnv* env,
558 const JavaParamRef<jobject>& obj, 497 const JavaParamRef<jobject>& obj,
559 jint data_type, 498 jint data_type,
560 jint clear_browsing_data_tab) { 499 jint clear_browsing_data_tab) {
561 DCHECK_GE(data_type, 0); 500 DCHECK_GE(data_type, 0);
562 DCHECK_LT(data_type, 501 DCHECK_LT(data_type,
563 static_cast<int>(browsing_data::BrowsingDataType::NUM_TYPES)); 502 static_cast<int>(browsing_data::BrowsingDataType::NUM_TYPES));
564 503
565 // If there is no corresponding preference for this |data_type|, pretend 504 // If there is no corresponding preference for this |data_type|, pretend
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
628 DCHECK_LT(tab_index, 2); 567 DCHECK_LT(tab_index, 2);
629 GetPrefService()->SetInteger(browsing_data::prefs::kLastClearBrowsingDataTab, 568 GetPrefService()->SetInteger(browsing_data::prefs::kLastClearBrowsingDataTab,
630 tab_index); 569 tab_index);
631 } 570 }
632 571
633 static void MigrateBrowsingDataPreferences(JNIEnv* env, 572 static void MigrateBrowsingDataPreferences(JNIEnv* env,
634 const JavaParamRef<jobject>& obj) { 573 const JavaParamRef<jobject>& obj) {
635 browsing_data::MigratePreferencesToBasic(GetOriginalProfile()->GetPrefs()); 574 browsing_data::MigratePreferencesToBasic(GetOriginalProfile()->GetPrefs());
636 } 575 }
637 576
638 static void ClearBrowsingData(
639 JNIEnv* env,
640 const JavaParamRef<jobject>& obj,
641 const JavaParamRef<jintArray>& data_types,
642 jint time_period,
643 const JavaParamRef<jobjectArray>& jexcluding_domains,
644 const JavaParamRef<jintArray>& jexcluding_domain_reasons,
645 const JavaParamRef<jobjectArray>& jignoring_domains,
646 const JavaParamRef<jintArray>& jignoring_domain_reasons) {
647 BrowsingDataRemover* browsing_data_remover =
648 BrowsingDataRemoverFactory::GetForBrowserContext(GetOriginalProfile());
649
650 std::vector<int> data_types_vector;
651 base::android::JavaIntArrayToIntVector(env, data_types, &data_types_vector);
652
653 int remove_mask = 0;
654 for (const int data_type : data_types_vector) {
655 switch (static_cast<browsing_data::BrowsingDataType>(data_type)) {
656 case browsing_data::BrowsingDataType::HISTORY:
657 remove_mask |= ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY;
658 break;
659 case browsing_data::BrowsingDataType::CACHE:
660 remove_mask |= BrowsingDataRemover::DATA_TYPE_CACHE;
661 break;
662 case browsing_data::BrowsingDataType::COOKIES:
663 remove_mask |= BrowsingDataRemover::DATA_TYPE_COOKIES;
664 remove_mask |= ChromeBrowsingDataRemoverDelegate::DATA_TYPE_SITE_DATA;
665 break;
666 case browsing_data::BrowsingDataType::PASSWORDS:
667 remove_mask |= ChromeBrowsingDataRemoverDelegate::DATA_TYPE_PASSWORDS;
668 break;
669 case browsing_data::BrowsingDataType::FORM_DATA:
670 remove_mask |= ChromeBrowsingDataRemoverDelegate::DATA_TYPE_FORM_DATA;
671 break;
672 case browsing_data::BrowsingDataType::BOOKMARKS:
673 // Bookmarks are deleted separately on the Java side.
674 NOTREACHED();
675 break;
676 case browsing_data::BrowsingDataType::NUM_TYPES:
677 NOTREACHED();
678 }
679 }
680 std::vector<std::string> excluding_domains;
681 std::vector<int32_t> excluding_domain_reasons;
682 std::vector<std::string> ignoring_domains;
683 std::vector<int32_t> ignoring_domain_reasons;
684 base::android::AppendJavaStringArrayToStringVector(
685 env, jexcluding_domains.obj(), &excluding_domains);
686 base::android::JavaIntArrayToIntVector(env, jexcluding_domain_reasons.obj(),
687 &excluding_domain_reasons);
688 base::android::AppendJavaStringArrayToStringVector(
689 env, jignoring_domains.obj(), &ignoring_domains);
690 base::android::JavaIntArrayToIntVector(env, jignoring_domain_reasons.obj(),
691 &ignoring_domain_reasons);
692 std::unique_ptr<content::BrowsingDataFilterBuilder> filter_builder(
693 content::BrowsingDataFilterBuilder::Create(
694 content::BrowsingDataFilterBuilder::BLACKLIST));
695 for (const std::string& domain : excluding_domains) {
696 filter_builder->AddRegisterableDomain(domain);
697 }
698
699 if (!excluding_domains.empty() || !ignoring_domains.empty()) {
700 ImportantSitesUtil::RecordBlacklistedAndIgnoredImportantSites(
701 GetOriginalProfile(), excluding_domains, excluding_domain_reasons,
702 ignoring_domains, ignoring_domain_reasons);
703 }
704
705 // Delete the types protected by Important Sites with a filter,
706 // and the rest completely.
707 int filterable_mask =
708 remove_mask &
709 ChromeBrowsingDataRemoverDelegate::IMPORTANT_SITES_DATA_TYPES;
710 int nonfilterable_mask =
711 remove_mask &
712 ~ChromeBrowsingDataRemoverDelegate::IMPORTANT_SITES_DATA_TYPES;
713
714 // ClearBrowsingDataObserver deletes itself when |browsing_data_remover| is
715 // done with both removal tasks.
716 ClearBrowsingDataObserver* observer = new ClearBrowsingDataObserver(
717 env, obj, browsing_data_remover, 2 /* tasks_count */);
718
719 browsing_data::TimePeriod period =
720 static_cast<browsing_data::TimePeriod>(time_period);
721 browsing_data::RecordDeletionForPeriod(period);
722
723 if (filterable_mask) {
724 browsing_data_remover->RemoveWithFilterAndReply(
725 browsing_data::CalculateBeginDeleteTime(period),
726 browsing_data::CalculateEndDeleteTime(period), filterable_mask,
727 BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
728 std::move(filter_builder), observer);
729 } else {
730 // Make sure |observer| doesn't wait for the filtered task.
731 observer->OnBrowsingDataRemoverDone();
732 }
733
734 if (nonfilterable_mask) {
735 browsing_data_remover->RemoveAndReply(
736 browsing_data::CalculateBeginDeleteTime(period),
737 browsing_data::CalculateEndDeleteTime(period), nonfilterable_mask,
738 BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB, observer);
739 } else {
740 // Make sure |observer| doesn't wait for the non-filtered task.
741 observer->OnBrowsingDataRemoverDone();
742 }
743 }
744
745 static jboolean CanDeleteBrowsingHistory(JNIEnv* env, 577 static jboolean CanDeleteBrowsingHistory(JNIEnv* env,
746 const JavaParamRef<jobject>& obj) { 578 const JavaParamRef<jobject>& obj) {
747 return GetPrefService()->GetBoolean(prefs::kAllowDeletingBrowserHistory); 579 return GetPrefService()->GetBoolean(prefs::kAllowDeletingBrowserHistory);
748 } 580 }
749 581
750 static void FetchImportantSites(JNIEnv* env,
751 const JavaParamRef<jclass>& clazz,
752 const JavaParamRef<jobject>& java_callback) {
753 Profile* profile = GetOriginalProfile();
754 std::vector<ImportantSitesUtil::ImportantDomainInfo> important_sites =
755 ImportantSitesUtil::GetImportantRegisterableDomains(profile,
756 kMaxImportantSites);
757 bool dialog_disabled = ImportantSitesUtil::IsDialogDisabled(profile);
758
759 std::vector<std::string> important_domains;
760 std::vector<int32_t> important_domain_reasons;
761 std::vector<std::string> important_domain_examples;
762 for (const ImportantSitesUtil::ImportantDomainInfo& info : important_sites) {
763 important_domains.push_back(info.registerable_domain);
764 important_domain_reasons.push_back(info.reason_bitfield);
765 important_domain_examples.push_back(info.example_origin.spec());
766 }
767
768 ScopedJavaLocalRef<jobjectArray> java_domains =
769 base::android::ToJavaArrayOfStrings(env, important_domains);
770 ScopedJavaLocalRef<jintArray> java_reasons =
771 base::android::ToJavaIntArray(env, important_domain_reasons);
772 ScopedJavaLocalRef<jobjectArray> java_origins =
773 base::android::ToJavaArrayOfStrings(env, important_domain_examples);
774
775 Java_ImportantSitesCallback_onImportantRegisterableDomainsReady(
776 env, java_callback.obj(), java_domains.obj(), java_origins.obj(),
777 java_reasons.obj(), dialog_disabled);
778 }
779
780 // This value should not change during a sessions, as it's used for UMA metrics.
781 static jint GetMaxImportantSites(JNIEnv* env,
782 const JavaParamRef<jclass>& clazz) {
783 return kMaxImportantSites;
784 }
785
786 static void MarkOriginAsImportantForTesting(
787 JNIEnv* env,
788 const JavaParamRef<jclass>& clazz,
789 const JavaParamRef<jstring>& jorigin) {
790 GURL origin(base::android::ConvertJavaStringToUTF8(jorigin));
791 CHECK(origin.is_valid());
792 ImportantSitesUtil::MarkOriginAsImportantForTesting(GetOriginalProfile(),
793 origin);
794 }
795
796 static void ShowNoticeAboutOtherFormsOfBrowsingHistory(
797 const JavaRef<jobject>& listener,
798 bool show) {
799 JNIEnv* env = AttachCurrentThread();
800 UMA_HISTOGRAM_BOOLEAN(
801 "History.ClearBrowsingData.HistoryNoticeShownInFooterWhenUpdated", show);
802 if (!show)
803 return;
804 Java_OtherFormsOfBrowsingHistoryListener_showNoticeAboutOtherFormsOfBrowsingHi story(
805 env, listener);
806 }
807
808 static void EnableDialogAboutOtherFormsOfBrowsingHistory(
809 const JavaRef<jobject>& listener,
810 bool enabled) {
811 JNIEnv* env = AttachCurrentThread();
812 if (!enabled)
813 return;
814 Java_OtherFormsOfBrowsingHistoryListener_enableDialogAboutOtherFormsOfBrowsing History(
815 env, listener);
816 }
817
818 static void RequestInfoAboutOtherFormsOfBrowsingHistory(
819 JNIEnv* env,
820 const JavaParamRef<jobject>& obj,
821 const JavaParamRef<jobject>& listener) {
822 // The permanent notice in the footer.
823 browsing_data::ShouldShowNoticeAboutOtherFormsOfBrowsingHistory(
824 ProfileSyncServiceFactory::GetForProfile(GetOriginalProfile()),
825 WebHistoryServiceFactory::GetForProfile(GetOriginalProfile()),
826 base::Bind(&ShowNoticeAboutOtherFormsOfBrowsingHistory,
827 ScopedJavaGlobalRef<jobject>(env, listener)));
828
829 // The one-time notice in the dialog.
830 browsing_data::ShouldPopupDialogAboutOtherFormsOfBrowsingHistory(
831 ProfileSyncServiceFactory::GetForProfile(GetOriginalProfile()),
832 WebHistoryServiceFactory::GetForProfile(GetOriginalProfile()),
833 chrome::GetChannel(),
834 base::Bind(&EnableDialogAboutOtherFormsOfBrowsingHistory,
835 ScopedJavaGlobalRef<jobject>(env, listener)));
836 }
837
838 static void SetAutoplayEnabled(JNIEnv* env, 582 static void SetAutoplayEnabled(JNIEnv* env,
839 const JavaParamRef<jobject>& obj, 583 const JavaParamRef<jobject>& obj,
840 jboolean allow) { 584 jboolean allow) {
841 HostContentSettingsMap* host_content_settings_map = 585 HostContentSettingsMap* host_content_settings_map =
842 HostContentSettingsMapFactory::GetForProfile(GetOriginalProfile()); 586 HostContentSettingsMapFactory::GetForProfile(GetOriginalProfile());
843 host_content_settings_map->SetDefaultContentSetting( 587 host_content_settings_map->SetDefaultContentSetting(
844 CONTENT_SETTINGS_TYPE_AUTOPLAY, 588 CONTENT_SETTINGS_TYPE_AUTOPLAY,
845 allow ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK); 589 allow ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK);
846 } 590 }
847 591
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
1266 .obj(), 1010 .obj(),
1267 out); 1011 out);
1268 } 1012 }
1269 1013
1270 static void SetSupervisedUserId(JNIEnv* env, 1014 static void SetSupervisedUserId(JNIEnv* env,
1271 const JavaParamRef<jobject>& obj, 1015 const JavaParamRef<jobject>& obj,
1272 const JavaParamRef<jstring>& pref) { 1016 const JavaParamRef<jstring>& pref) {
1273 GetPrefService()->SetString(prefs::kSupervisedUserId, 1017 GetPrefService()->SetString(prefs::kSupervisedUserId,
1274 ConvertJavaStringToUTF8(env, pref)); 1018 ConvertJavaStringToUTF8(env, pref));
1275 } 1019 }
OLDNEW
« no previous file with comments | « chrome/browser/android/chrome_jni_registrar.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698