diff options
Diffstat (limited to 'chromium/components/browser_ui/http_auth')
6 files changed, 240 insertions, 0 deletions
diff --git a/chromium/components/browser_ui/http_auth/android/BUILD.gn b/chromium/components/browser_ui/http_auth/android/BUILD.gn new file mode 100644 index 00000000000..0184556b59c --- /dev/null +++ b/chromium/components/browser_ui/http_auth/android/BUILD.gn @@ -0,0 +1,33 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/config/android/rules.gni") + +android_library("java") { + sources = [ + "java/src/org/chromium/components/browser_ui/http_auth/LoginPrompt.java", + ] + + deps = [ + ":java_resources", + "//base:base_java", + "//components/browser_ui/widget/android:java", + "//components/strings:components_strings_grd", + "//third_party/android_deps:androidx_appcompat_appcompat_java", + "//third_party/android_deps:com_google_android_material_material_java", + "//ui/android:ui_java", + ] +} + +android_resources("java_resources") { + custom_package = "org.chromium.components.browser_ui.http_auth" + sources = [ "java/res/layout/http_auth_dialog.xml" ] + + deps = [ + "//components/browser_ui/styles/android:java_resources", + "//components/browser_ui/widget/android:java_resources", + "//components/strings:components_strings_grd", + "//ui/android:ui_java_resources", + ] +} diff --git a/chromium/components/browser_ui/http_auth/android/DEPS b/chromium/components/browser_ui/http_auth/android/DEPS new file mode 100644 index 00000000000..d21e0729f9c --- /dev/null +++ b/chromium/components/browser_ui/http_auth/android/DEPS @@ -0,0 +1,3 @@ +include_rules = [ + "+ui/android", +] diff --git a/chromium/components/browser_ui/http_auth/android/OWNERS b/chromium/components/browser_ui/http_auth/android/OWNERS new file mode 100644 index 00000000000..697c69edec7 --- /dev/null +++ b/chromium/components/browser_ui/http_auth/android/OWNERS @@ -0,0 +1 @@ +file://chrome/android/OWNERS diff --git a/chromium/components/browser_ui/http_auth/android/java/res/OWNERS b/chromium/components/browser_ui/http_auth/android/java/res/OWNERS new file mode 100644 index 00000000000..7bb5d6933c5 --- /dev/null +++ b/chromium/components/browser_ui/http_auth/android/java/res/OWNERS @@ -0,0 +1,9 @@ +# This restriction is in place to avoid accidential addition to our top level +# layout files, such as add duplicated assets, or introducing new colors when +# we don't want them. +set noparent + +file://ui/android/java/res/LAYOUT_OWNERS + +# COMPONENT: UI>Browser>Mobile +# OS: Android diff --git a/chromium/components/browser_ui/http_auth/android/java/res/layout/http_auth_dialog.xml b/chromium/components/browser_ui/http_auth/android/java/res/layout/http_auth_dialog.xml new file mode 100644 index 00000000000..f55df1e32a5 --- /dev/null +++ b/chromium/components/browser_ui/http_auth/android/java/res/layout/http_auth_dialog.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2014 The Chromium Authors. All rights reserved. + + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. +--> +<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" + style="@style/AlertDialogContent"> + + <LinearLayout + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <TextView + android:id="@+id/explanation" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + + <com.google.android.material.textfield.TextInputLayout + android:id="@+id/username_label" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:hint="@string/login_dialog_username_field" > + <org.chromium.components.browser_ui.widget.text.AlertDialogEditText + android:id="@+id/username" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:hint="@string/login_dialog_username_field" + android:inputType="textNoSuggestions" + android:imeOptions="flagNoExtractUi" + android:importantForAutofill="no" /> + </com.google.android.material.textfield.TextInputLayout> + + <com.google.android.material.textfield.TextInputLayout + android:id="@+id/password_label" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:hint="@string/login_dialog_password_field" > + <org.chromium.components.browser_ui.widget.text.AlertDialogEditText + android:id="@+id/password" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:hint="@string/login_dialog_password_field" + android:inputType="textPassword" + android:imeOptions="flagNoExtractUi" + android:importantForAutofill="no" /> + </com.google.android.material.textfield.TextInputLayout> + + </LinearLayout> + +</ScrollView> diff --git a/chromium/components/browser_ui/http_auth/android/java/src/org/chromium/components/browser_ui/http_auth/LoginPrompt.java b/chromium/components/browser_ui/http_auth/android/java/src/org/chromium/components/browser_ui/http_auth/LoginPrompt.java new file mode 100644 index 00000000000..a97b221d24d --- /dev/null +++ b/chromium/components/browser_ui/http_auth/android/java/src/org/chromium/components/browser_ui/http_auth/LoginPrompt.java @@ -0,0 +1,142 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.components.browser_ui.http_auth; + +import android.content.Context; +import android.content.DialogInterface; +import android.os.Build; +import android.view.LayoutInflater; +import android.view.View; +import android.view.WindowManager; +import android.view.inputmethod.EditorInfo; +import android.widget.TextView; + +import androidx.appcompat.app.AlertDialog; + +import org.chromium.components.browser_ui.widget.text.AlertDialogEditText; +import org.chromium.ui.UiUtils; + +/** + * HTTP Authentication Dialog + * + * This borrows liberally from android.browser.HttpAuthenticationDialog. + */ +public class LoginPrompt { + private final Context mContext; + private final String mMessageBody; + private final Observer mObserver; + + private AlertDialog mDialog; + private AlertDialogEditText mUsernameView; + private AlertDialogEditText mPasswordView; + + /** + * This is a public interface that provides the result of the prompt. + */ + public static interface Observer { + /** + * Cancel the authorization request. + */ + public void cancel(); + + /** + * Proceed with the authorization with the given credentials. + */ + public void proceed(String username, String password); + } + + /** + * Constructs an http auth prompt. + * + * @param context The Context to use. + * @param messageBody The text to show to the user. + * @param autofillUrl If not null, Android Autofill support is enabled for the form with the + * given url being set as the web domain for the View control. + * @param observer An interface to receive the result of the prompt. + */ + public LoginPrompt(Context context, String messageBody, String autofillUrl, Observer observer) { + mContext = context; + mMessageBody = messageBody; + mObserver = observer; + createDialog(autofillUrl); + } + + private void createDialog(String autofillUrl) { + View v = LayoutInflater.from(mContext).inflate(R.layout.http_auth_dialog, null); + mUsernameView = (AlertDialogEditText) v.findViewById(R.id.username); + mPasswordView = (AlertDialogEditText) v.findViewById(R.id.password); + if (autofillUrl != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + // By default Android Autofill support is turned off for these controls because Chrome + // uses its own autofill provider (Chrome Sync). If an app is using Android Autofill + // then we need to enable Android Autofill for the controls. + mUsernameView.setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_YES); + mPasswordView.setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_YES); + mUsernameView.setUrl(autofillUrl); + mPasswordView.setUrl(autofillUrl); + } + mPasswordView.setOnEditorActionListener((v1, actionId, event) -> { + if (actionId == EditorInfo.IME_ACTION_DONE) { + mDialog.getButton(AlertDialog.BUTTON_POSITIVE).performClick(); + return true; + } + return false; + }); + + TextView explanationView = (TextView) v.findViewById(R.id.explanation); + explanationView.setText(mMessageBody); + + mDialog = + new UiUtils + .CompatibleAlertDialogBuilder(mContext, R.style.Theme_Chromium_AlertDialog) + .setTitle(R.string.login_dialog_title) + .setView(v) + .setPositiveButton(R.string.login_dialog_ok_button_label, + (DialogInterface.OnClickListener) (dialog, whichButton) + -> mObserver.proceed(getUsername(), getPassword())) + .setNegativeButton(R.string.cancel, + (DialogInterface.OnClickListener) (dialog, + whichButton) -> mObserver.cancel()) + .setOnCancelListener(dialog -> mObserver.cancel()) + .create(); + mDialog.getDelegate().setHandleNativeActionModesEnabled(false); + + // Make the IME appear when the dialog is displayed if applicable. + mDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); + } + + /** + * Shows the dialog. + */ + public void show() { + mDialog.show(); + mUsernameView.requestFocus(); + } + + /** + * Dismisses the dialog. + */ + public void dismiss() { + mDialog.dismiss(); + } + + /** Return whether the dialog is being shown. */ + public boolean isShowing() { + return mDialog != null && mDialog.isShowing(); + } + + private String getUsername() { + return mUsernameView.getText().toString(); + } + + private String getPassword() { + return mPasswordView.getText().toString(); + } + + public void onAutofillDataAvailable(String username, String password) { + mUsernameView.setText(username); + mPasswordView.setText(password); + mUsernameView.selectAll(); + } +} |