Chromium Code Reviews| Index: chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordEntryEditor.java |
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordEntryEditor.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordEntryEditor.java |
| index fc894c30947f1f7215739bd6dcf50b32c1053267..d50f9a00345daa3ea3b5925444780a6efd4283d7 100644 |
| --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordEntryEditor.java |
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordEntryEditor.java |
| @@ -5,7 +5,15 @@ |
| package org.chromium.chrome.browser.preferences.password; |
| import android.app.Fragment; |
| +import android.app.FragmentManager; |
| +import android.app.FragmentTransaction; |
| +import android.app.KeyguardManager; |
| +import android.content.ClipData; |
| +import android.content.ClipboardManager; |
| +import android.content.Context; |
| +import android.os.Build; |
| import android.os.Bundle; |
| +import android.text.InputType; |
| import android.view.LayoutInflater; |
| import android.view.Menu; |
| import android.view.MenuInflater; |
| @@ -13,12 +21,15 @@ import android.view.MenuItem; |
| import android.view.View; |
| import android.view.ViewGroup; |
| import android.widget.Button; |
| +import android.widget.ImageButton; |
| import android.widget.TextView; |
| +import org.chromium.base.VisibleForTesting; |
| import org.chromium.chrome.R; |
| import org.chromium.chrome.browser.ChromeFeatureList; |
| import org.chromium.chrome.browser.PasswordUIView; |
| import org.chromium.chrome.browser.PasswordUIView.PasswordListObserver; |
| +import org.chromium.ui.widget.Toast; |
| /** |
| * Password entry editor that allows to view and delete passwords stored in Chrome. |
| @@ -32,7 +43,16 @@ public class PasswordEntryEditor extends Fragment { |
| // If false this represents a saved name/password. |
| private boolean mException; |
| + @VisibleForTesting |
| public static final String VIEW_PASSWORDS = "view-passwords"; |
| + private static final int VALID_REAUTHENTICATION_TIME_INTERVAL_MILLIS = 60000; |
| + |
| + private ClipboardManager mClipboard; |
| + private KeyguardManager mKeyguardManager; |
| + private Bundle mExtras; |
| + private View mView; |
| + private boolean mViewButtonPressed; |
| + private boolean mCopyButtonPressed; |
| @Override |
| public void onCreate(Bundle savedInstanceState) { |
| @@ -46,36 +66,69 @@ public class PasswordEntryEditor extends Fragment { |
| public View onCreateView(LayoutInflater inflater, ViewGroup container, |
| Bundle savedInstanceState) { |
| super.onCreate(savedInstanceState); |
| - View v; |
| - if (ChromeFeatureList.isEnabled(VIEW_PASSWORDS)) { |
| - v = inflater.inflate(R.layout.password_entry_editor_interactive, container, false); |
| + if (shouldDisplayInteractivePasswordEntryEditor()) { |
| + mView = inflater.inflate(R.layout.password_entry_editor_interactive, container, false); |
| } else { |
| - v = inflater.inflate(R.layout.password_entry_editor, container, false); |
| + mView = inflater.inflate(R.layout.password_entry_editor, container, false); |
| } |
| getActivity().setTitle(R.string.password_entry_editor_title); |
| - |
| + mClipboard = (ClipboardManager) getActivity().getApplicationContext().getSystemService( |
| + Context.CLIPBOARD_SERVICE); |
| // Extras are set on this intent in class SavePasswordsPreferences. |
|
gone
2017/06/01 20:46:37
does {@link SavePasswordsPreferences} work here?
melandory
2017/06/09 15:09:27
Done.
|
| - Bundle extras = getArguments(); |
| - assert extras != null; |
| - mID = extras.getInt(SavePasswordsPreferences.PASSWORD_LIST_ID); |
| - String name = null; |
| - if (extras.containsKey(SavePasswordsPreferences.PASSWORD_LIST_NAME)) { |
| - name = extras.getString(SavePasswordsPreferences.PASSWORD_LIST_NAME); |
| - } |
| - TextView nameView = (TextView) v.findViewById(R.id.password_entry_editor_name); |
| + mExtras = getArguments(); |
|
gone
2017/06/01 20:46:37
Why'd you remove the assert?
melandory
2017/06/09 15:09:27
Accidentally, fixed
|
| + mID = mExtras.getInt(SavePasswordsPreferences.PASSWORD_LIST_ID); |
| + final String name = mExtras.containsKey(SavePasswordsPreferences.PASSWORD_LIST_NAME) |
| + ? mExtras.getString(SavePasswordsPreferences.PASSWORD_LIST_NAME) |
| + : null; |
| + TextView nameView = (TextView) mView.findViewById(R.id.password_entry_editor_name); |
| if (name != null) { |
| nameView.setText(name); |
| } else { |
| nameView.setText(R.string.section_saved_passwords_exceptions); |
| mException = true; |
| } |
| - String url = extras.getString(SavePasswordsPreferences.PASSWORD_LIST_URL); |
| - TextView urlView = (TextView) v.findViewById(R.id.password_entry_editor_url); |
| + final String url = mExtras.getString(SavePasswordsPreferences.PASSWORD_LIST_URL); |
| + TextView urlView = (TextView) mView.findViewById(R.id.password_entry_editor_url); |
| urlView.setText(url); |
| - if (!ChromeFeatureList.isEnabled(VIEW_PASSWORDS)) { |
| - hookupCancelDeleteButtons(v); |
| + if (shouldDisplayInteractivePasswordEntryEditor()) { |
| + mKeyguardManager = |
| + (KeyguardManager) getActivity().getApplicationContext().getSystemService( |
| + Context.KEYGUARD_SERVICE); |
|
gone
2017/06/01 20:46:37
what happens if the user doesn't have a lock scree
melandory
2017/06/09 15:09:27
mKeyguardManager will not be null, but mKeyguardMa
|
| + hidePassword(); |
| + hookupPasswordButtons(); |
| + hookupCopyUsernameButton(); |
| + hookupCopySiteButton(); |
| + } else { |
| + hookupCancelDeleteButtons(); |
| } |
| - return v; |
| + return mView; |
| + } |
| + |
| + public boolean shouldDisplayInteractivePasswordEntryEditor() { |
| + return ChromeFeatureList.isEnabled(VIEW_PASSWORDS) |
| + && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; |
| + } |
| + |
| + @Override |
| + public void onResume() { |
| + super.onResume(); |
| + if (mViewButtonPressed && authenticationStillValid()) { |
| + displayPassword(); |
| + } |
| + |
| + if (mCopyButtonPressed && authenticationStillValid()) { |
| + copyPassword(); |
| + } |
|
gone
2017/06/01 20:46:37
if (authenticationStillValid()) {
everything e
melandory
2017/06/09 15:09:27
Done.
|
| + } |
| + |
| + /** |
| + * Verifies if authentication is still valid (the user authenticated less than 60 seconds ago |
| + * and the startTime is not equal to 0. |
| + */ |
| + private boolean authenticationStillValid() { |
| + return SavePasswordsPreferences.getLastReauthTimeMillis() != 0 |
| + && System.currentTimeMillis() - SavePasswordsPreferences.getLastReauthTimeMillis() |
| + < VALID_REAUTHENTICATION_TIME_INTERVAL_MILLIS; |
| } |
| @Override |
| @@ -120,24 +173,139 @@ public class PasswordEntryEditor extends Fragment { |
| passwordUIView.updatePasswordLists(); |
| } |
| - private void hookupCancelDeleteButtons(View v) { |
| - final Button deleteButton = (Button) v.findViewById(R.id.password_entry_editor_delete); |
| - final Button cancelButton = (Button) v.findViewById(R.id.password_entry_editor_cancel); |
| + private void hookupCancelDeleteButtons() { |
| + final Button deleteButton = (Button) mView.findViewById(R.id.password_entry_editor_delete); |
| + final Button cancelButton = (Button) mView.findViewById(R.id.password_entry_editor_cancel); |
| deleteButton.setOnClickListener(new View.OnClickListener() { |
| - @Override |
| - public void onClick(View v) { |
| - removeItem(); |
| - deleteButton.setEnabled(false); |
| - cancelButton.setEnabled(false); |
| - } |
| - }); |
| + @Override |
| + public void onClick(View v) { |
| + removeItem(); |
| + deleteButton.setEnabled(false); |
| + cancelButton.setEnabled(false); |
| + } |
| + }); |
| cancelButton.setOnClickListener(new View.OnClickListener() { |
| - @Override |
| - public void onClick(View v) { |
| - getActivity().finish(); |
| + @Override |
| + public void onClick(View v) { |
| + getActivity().finish(); |
| + } |
| + }); |
| + } |
| + |
| + private void hookupCopyUsernameButton() { |
| + final ImageButton copyUsernameButton = |
| + (ImageButton) mView.findViewById(R.id.password_entry_editor_copy_username); |
| + copyUsernameButton.setOnClickListener(new View.OnClickListener() { |
| + @Override |
| + public void onClick(View v) { |
| + ClipData clip = ClipData.newPlainText("username", |
| + getArguments().getString(SavePasswordsPreferences.PASSWORD_LIST_NAME)); |
| + mClipboard.setPrimaryClip(clip); |
| + Toast.makeText(getActivity().getApplicationContext(), |
| + R.string.password_entry_editor_username_copied_into_clipboard, |
| + Toast.LENGTH_SHORT) |
| + .show(); |
| + } |
| + }); |
| + } |
| + |
| + private void hookupCopySiteButton() { |
| + final ImageButton copySiteButton = |
| + (ImageButton) mView.findViewById(R.id.password_entry_editor_copy_site); |
| + copySiteButton.setOnClickListener(new View.OnClickListener() { |
| + @Override |
| + public void onClick(View v) { |
| + ClipData clip = ClipData.newPlainText("site", |
| + getArguments().getString(SavePasswordsPreferences.PASSWORD_LIST_URL)); |
| + mClipboard.setPrimaryClip(clip); |
| + Toast.makeText(getActivity().getApplicationContext(), |
| + R.string.password_entry_editor_site_copied_into_clipboard, |
| + Toast.LENGTH_SHORT) |
| + .show(); |
| + } |
| + }); |
| + } |
| + |
| + private void changeHowPasswordDisplayed(int visibilityIcon, int inputType) { |
|
gone
2017/06/01 20:46:37
changeHowPasswordIsDisplayed
melandory
2017/06/09 15:09:27
Done.
|
| + TextView passwordView = (TextView) mView.findViewById(R.id.password_entry_editor_password); |
| + ImageButton viewPasswordButton = |
| + (ImageButton) mView.findViewById(R.id.password_entry_editor_view_password); |
| + passwordView.setText(mExtras.getString(SavePasswordsPreferences.PASSWORD_LIST_PASSWORD)); |
| + passwordView.setInputType(inputType); |
| + viewPasswordButton.setImageResource(visibilityIcon); |
| + } |
| + |
| + private void displayPassword() { |
| + changeHowPasswordDisplayed( |
| + R.drawable.ic_visibility_off, InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD); |
| + } |
| + |
| + private void hidePassword() { |
| + changeHowPasswordDisplayed(R.drawable.ic_visibility, |
| + InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); |
| + } |
| + |
| + private void copyPassword() { |
| + ClipData clip = ClipData.newPlainText("password", |
| + getArguments().getString(SavePasswordsPreferences.PASSWORD_LIST_PASSWORD)); |
| + mClipboard.setPrimaryClip(clip); |
| + Toast.makeText(getActivity().getApplicationContext(), |
| + R.string.password_entry_editor_password_copied_into_clipboard, |
| + Toast.LENGTH_SHORT) |
| + .show(); |
| + } |
| + |
| + private void displayReauthenticationFragment() { |
| + Fragment passwordReauthentication = new PasswordReauthenticationFragment(); |
| + FragmentManager fragmentManager = getFragmentManager(); |
| + FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); |
| + fragmentTransaction.replace( |
| + R.id.password_entry_editor_interactive, passwordReauthentication); |
| + fragmentTransaction.addToBackStack(null); |
| + fragmentTransaction.commit(); |
| + } |
| + |
| + private void hookupPasswordButtons() { |
| + final ImageButton copyPasswordButton = |
| + (ImageButton) mView.findViewById(R.id.password_entry_editor_copy_password); |
| + final ImageButton viewPasswordButton = |
| + (ImageButton) mView.findViewById(R.id.password_entry_editor_view_password); |
| + copyPasswordButton.setOnClickListener(new View.OnClickListener() { |
| + @Override |
| + public void onClick(View v) { |
| + if (!mKeyguardManager.isKeyguardSecure()) { |
| + Toast.makeText(getActivity().getApplicationContext(), |
| + R.string.password_entry_editor_set_lock_screen, Toast.LENGTH_LONG) |
| + .show(); |
| + } else if (authenticationStillValid()) { |
| + copyPassword(); |
| + } else { |
| + mCopyButtonPressed = true; |
| + displayReauthenticationFragment(); |
| } |
| - }); |
| + } |
| + }); |
| + viewPasswordButton.setOnClickListener(new View.OnClickListener() { |
| + @Override |
| + public void onClick(View v) { |
| + TextView passwordView = |
| + (TextView) mView.findViewById(R.id.password_entry_editor_password); |
| + if (!mKeyguardManager.isKeyguardSecure()) { |
| + Toast.makeText(getActivity().getApplicationContext(), |
| + R.string.password_entry_editor_set_lock_screen, Toast.LENGTH_LONG) |
| + .show(); |
| + } else if (passwordView.getInputType() |
| + == InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) { |
| + hidePassword(); |
| + } else if (authenticationStillValid()) { |
| + displayPassword(); |
| + } else { |
| + mViewButtonPressed = true; |
| + displayReauthenticationFragment(); |
| + } |
| + } |
| + }); |
| } |
| } |