| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "android_webview/native/aw_autofill_client.h" | |
| 6 | |
| 7 #include "android_webview/browser/aw_browser_context.h" | |
| 8 #include "android_webview/browser/aw_content_browser_client.h" | |
| 9 #include "android_webview/browser/aw_form_database_service.h" | |
| 10 #include "android_webview/native/aw_contents.h" | |
| 11 #include "base/android/jni_android.h" | |
| 12 #include "base/android/jni_string.h" | |
| 13 #include "base/android/scoped_java_ref.h" | |
| 14 #include "base/logging.h" | |
| 15 #include "components/autofill/core/browser/autofill_popup_delegate.h" | |
| 16 #include "components/autofill/core/browser/suggestion.h" | |
| 17 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" | |
| 18 #include "components/autofill/core/common/autofill_pref_names.h" | |
| 19 #include "components/prefs/pref_registry_simple.h" | |
| 20 #include "components/prefs/pref_service.h" | |
| 21 #include "components/prefs/pref_service_factory.h" | |
| 22 #include "components/user_prefs/user_prefs.h" | |
| 23 #include "content/public/browser/android/content_view_core.h" | |
| 24 #include "content/public/browser/navigation_entry.h" | |
| 25 #include "content/public/browser/ssl_status.h" | |
| 26 #include "content/public/browser/web_contents.h" | |
| 27 #include "jni/AwAutofillClient_jni.h" | |
| 28 #include "ui/android/view_android.h" | |
| 29 #include "ui/gfx/geometry/rect_f.h" | |
| 30 | |
| 31 using base::android::AttachCurrentThread; | |
| 32 using base::android::ConvertUTF16ToJavaString; | |
| 33 using base::android::JavaParamRef; | |
| 34 using base::android::ScopedJavaLocalRef; | |
| 35 using content::WebContents; | |
| 36 | |
| 37 DEFINE_WEB_CONTENTS_USER_DATA_KEY(android_webview::AwAutofillClient); | |
| 38 | |
| 39 namespace android_webview { | |
| 40 | |
| 41 // Ownership: The native object is created (if autofill enabled) and owned by | |
| 42 // AwContents. The native object creates the java peer which handles most | |
| 43 // autofill functionality at the java side. The java peer is owned by Java | |
| 44 // AwContents. The native object only maintains a weak ref to it. | |
| 45 AwAutofillClient::AwAutofillClient(WebContents* contents) | |
| 46 : web_contents_(contents), save_form_data_(false) { | |
| 47 JNIEnv* env = AttachCurrentThread(); | |
| 48 ScopedJavaLocalRef<jobject> delegate; | |
| 49 delegate.Reset( | |
| 50 Java_AwAutofillClient_create(env, reinterpret_cast<intptr_t>(this))); | |
| 51 | |
| 52 AwContents* aw_contents = AwContents::FromWebContents(web_contents_); | |
| 53 aw_contents->SetAwAutofillClient(delegate); | |
| 54 java_ref_ = JavaObjectWeakGlobalRef(env, delegate); | |
| 55 } | |
| 56 | |
| 57 AwAutofillClient::~AwAutofillClient() { | |
| 58 HideAutofillPopup(); | |
| 59 } | |
| 60 | |
| 61 void AwAutofillClient::SetSaveFormData(bool enabled) { | |
| 62 save_form_data_ = enabled; | |
| 63 } | |
| 64 | |
| 65 bool AwAutofillClient::GetSaveFormData() { | |
| 66 return save_form_data_; | |
| 67 } | |
| 68 | |
| 69 PrefService* AwAutofillClient::GetPrefs() { | |
| 70 return user_prefs::UserPrefs::Get( | |
| 71 AwContentBrowserClient::GetAwBrowserContext()); | |
| 72 } | |
| 73 | |
| 74 syncer::SyncService* AwAutofillClient::GetSyncService() { | |
| 75 return nullptr; | |
| 76 } | |
| 77 | |
| 78 IdentityProvider* AwAutofillClient::GetIdentityProvider() { | |
| 79 return nullptr; | |
| 80 } | |
| 81 | |
| 82 rappor::RapporServiceImpl* AwAutofillClient::GetRapporServiceImpl() { | |
| 83 return nullptr; | |
| 84 } | |
| 85 | |
| 86 ukm::UkmService* AwAutofillClient::GetUkmService() { | |
| 87 return nullptr; | |
| 88 } | |
| 89 | |
| 90 autofill::SaveCardBubbleController* | |
| 91 AwAutofillClient::GetSaveCardBubbleController() { | |
| 92 return nullptr; | |
| 93 } | |
| 94 | |
| 95 autofill::PersonalDataManager* AwAutofillClient::GetPersonalDataManager() { | |
| 96 return nullptr; | |
| 97 } | |
| 98 | |
| 99 scoped_refptr<autofill::AutofillWebDataService> | |
| 100 AwAutofillClient::GetDatabase() { | |
| 101 android_webview::AwFormDatabaseService* service = | |
| 102 static_cast<android_webview::AwBrowserContext*>( | |
| 103 web_contents_->GetBrowserContext())->GetFormDatabaseService(); | |
| 104 return service->get_autofill_webdata_service(); | |
| 105 } | |
| 106 | |
| 107 void AwAutofillClient::ShowAutofillPopup( | |
| 108 const gfx::RectF& element_bounds, | |
| 109 base::i18n::TextDirection text_direction, | |
| 110 const std::vector<autofill::Suggestion>& suggestions, | |
| 111 base::WeakPtr<autofill::AutofillPopupDelegate> delegate) { | |
| 112 suggestions_ = suggestions; | |
| 113 delegate_ = delegate; | |
| 114 | |
| 115 // Convert element_bounds to be in screen space. | |
| 116 gfx::Rect client_area = web_contents_->GetContainerBounds(); | |
| 117 gfx::RectF element_bounds_in_screen_space = | |
| 118 element_bounds + client_area.OffsetFromOrigin(); | |
| 119 | |
| 120 ShowAutofillPopupImpl(element_bounds_in_screen_space, | |
| 121 text_direction == base::i18n::RIGHT_TO_LEFT, | |
| 122 suggestions); | |
| 123 } | |
| 124 | |
| 125 void AwAutofillClient::ShowAutofillPopupImpl( | |
| 126 const gfx::RectF& element_bounds, | |
| 127 bool is_rtl, | |
| 128 const std::vector<autofill::Suggestion>& suggestions) { | |
| 129 JNIEnv* env = AttachCurrentThread(); | |
| 130 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); | |
| 131 if (obj.is_null()) | |
| 132 return; | |
| 133 | |
| 134 // We need an array of AutofillSuggestion. | |
| 135 size_t count = suggestions.size(); | |
| 136 | |
| 137 ScopedJavaLocalRef<jobjectArray> data_array = | |
| 138 Java_AwAutofillClient_createAutofillSuggestionArray(env, count); | |
| 139 | |
| 140 for (size_t i = 0; i < count; ++i) { | |
| 141 ScopedJavaLocalRef<jstring> name = | |
| 142 ConvertUTF16ToJavaString(env, suggestions[i].value); | |
| 143 ScopedJavaLocalRef<jstring> label = | |
| 144 ConvertUTF16ToJavaString(env, suggestions[i].label); | |
| 145 Java_AwAutofillClient_addToAutofillSuggestionArray( | |
| 146 env, data_array, i, name, label, suggestions[i].frontend_id); | |
| 147 } | |
| 148 ui::ViewAndroid* view_android = web_contents_->GetNativeView(); | |
| 149 if (!view_android) | |
| 150 return; | |
| 151 | |
| 152 const ScopedJavaLocalRef<jobject> current_view = anchor_view_.view(); | |
| 153 if (current_view.is_null()) | |
| 154 anchor_view_ = view_android->AcquireAnchorView(); | |
| 155 | |
| 156 const ScopedJavaLocalRef<jobject> view = anchor_view_.view(); | |
| 157 if (view.is_null()) | |
| 158 return; | |
| 159 | |
| 160 view_android->SetAnchorRect(view, element_bounds); | |
| 161 Java_AwAutofillClient_showAutofillPopup(env, obj, view, is_rtl, data_array); | |
| 162 } | |
| 163 | |
| 164 void AwAutofillClient::UpdateAutofillPopupDataListValues( | |
| 165 const std::vector<base::string16>& values, | |
| 166 const std::vector<base::string16>& labels) { | |
| 167 // Leaving as an empty method since updating autofill popup window | |
| 168 // dynamically does not seem to be a useful feature for android webview. | |
| 169 // See crrev.com/18102002 if need to implement. | |
| 170 } | |
| 171 | |
| 172 void AwAutofillClient::HideAutofillPopup() { | |
| 173 JNIEnv* env = AttachCurrentThread(); | |
| 174 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); | |
| 175 if (obj.is_null()) | |
| 176 return; | |
| 177 delegate_.reset(); | |
| 178 Java_AwAutofillClient_hideAutofillPopup(env, obj); | |
| 179 } | |
| 180 | |
| 181 bool AwAutofillClient::IsAutocompleteEnabled() { | |
| 182 return GetSaveFormData(); | |
| 183 } | |
| 184 | |
| 185 void AwAutofillClient::PropagateAutofillPredictions( | |
| 186 content::RenderFrameHost* rfh, | |
| 187 const std::vector<autofill::FormStructure*>& forms) {} | |
| 188 | |
| 189 void AwAutofillClient::DidFillOrPreviewField( | |
| 190 const base::string16& autofilled_value, | |
| 191 const base::string16& profile_full_name) {} | |
| 192 | |
| 193 bool AwAutofillClient::IsContextSecure() { | |
| 194 content::SSLStatus ssl_status; | |
| 195 content::NavigationEntry* navigation_entry = | |
| 196 web_contents_->GetController().GetLastCommittedEntry(); | |
| 197 if (!navigation_entry) | |
| 198 return false; | |
| 199 | |
| 200 ssl_status = navigation_entry->GetSSL(); | |
| 201 // Note: The implementation below is a copy of the one in | |
| 202 // ChromeAutofillClient::IsContextSecure, and should be kept in sync | |
| 203 // until crbug.com/505388 gets implemented. | |
| 204 return navigation_entry->GetURL().SchemeIsCryptographic() && | |
| 205 ssl_status.certificate && | |
| 206 (!net::IsCertStatusError(ssl_status.cert_status) || | |
| 207 net::IsCertStatusMinorError(ssl_status.cert_status)) && | |
| 208 !(ssl_status.content_status & | |
| 209 content::SSLStatus::RAN_INSECURE_CONTENT); | |
| 210 } | |
| 211 | |
| 212 bool AwAutofillClient::ShouldShowSigninPromo() { | |
| 213 return false; | |
| 214 } | |
| 215 | |
| 216 void AwAutofillClient::StartSigninFlow() {} | |
| 217 | |
| 218 void AwAutofillClient::ShowHttpNotSecureExplanation() {} | |
| 219 | |
| 220 void AwAutofillClient::Dismissed(JNIEnv* env, | |
| 221 const JavaParamRef<jobject>& obj) { | |
| 222 anchor_view_.Reset(); | |
| 223 } | |
| 224 | |
| 225 void AwAutofillClient::SuggestionSelected(JNIEnv* env, | |
| 226 const JavaParamRef<jobject>& object, | |
| 227 jint position) { | |
| 228 if (delegate_) { | |
| 229 delegate_->DidAcceptSuggestion(suggestions_[position].value, | |
| 230 suggestions_[position].frontend_id, | |
| 231 position); | |
| 232 } | |
| 233 } | |
| 234 | |
| 235 void AwAutofillClient::ShowAutofillSettings() { | |
| 236 NOTIMPLEMENTED(); | |
| 237 } | |
| 238 | |
| 239 void AwAutofillClient::ShowUnmaskPrompt( | |
| 240 const autofill::CreditCard& card, | |
| 241 UnmaskCardReason reason, | |
| 242 base::WeakPtr<autofill::CardUnmaskDelegate> delegate) { | |
| 243 NOTIMPLEMENTED(); | |
| 244 } | |
| 245 | |
| 246 void AwAutofillClient::OnUnmaskVerificationResult(PaymentsRpcResult result) { | |
| 247 NOTIMPLEMENTED(); | |
| 248 } | |
| 249 | |
| 250 void AwAutofillClient::ConfirmSaveCreditCardLocally( | |
| 251 const autofill::CreditCard& card, | |
| 252 const base::Closure& callback) { | |
| 253 NOTIMPLEMENTED(); | |
| 254 } | |
| 255 | |
| 256 void AwAutofillClient::ConfirmSaveCreditCardToCloud( | |
| 257 const autofill::CreditCard& card, | |
| 258 std::unique_ptr<base::DictionaryValue> legal_message, | |
| 259 bool should_cvc_be_requested, | |
| 260 const base::Closure& callback) { | |
| 261 NOTIMPLEMENTED(); | |
| 262 } | |
| 263 | |
| 264 void AwAutofillClient::ConfirmCreditCardFillAssist( | |
| 265 const autofill::CreditCard& card, | |
| 266 const base::Closure& callback) { | |
| 267 NOTIMPLEMENTED(); | |
| 268 } | |
| 269 | |
| 270 void AwAutofillClient::LoadRiskData( | |
| 271 const base::Callback<void(const std::string&)>& callback) { | |
| 272 NOTIMPLEMENTED(); | |
| 273 } | |
| 274 | |
| 275 bool AwAutofillClient::HasCreditCardScanFeature() { | |
| 276 return false; | |
| 277 } | |
| 278 | |
| 279 void AwAutofillClient::ScanCreditCard(const CreditCardScanCallback& callback) { | |
| 280 NOTIMPLEMENTED(); | |
| 281 } | |
| 282 | |
| 283 bool RegisterAwAutofillClient(JNIEnv* env) { | |
| 284 return RegisterNativesImpl(env); | |
| 285 } | |
| 286 | |
| 287 } // namespace android_webview | |
| OLD | NEW |