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 c8e15c135c052bed3f06f81827f1f293741510b8..e998c6062cc6afca914fe97df0b179123528ae81 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,17 +5,27 @@ |
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.Bundle; |
+import android.text.InputType; |
import android.view.LayoutInflater; |
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. |
@@ -29,8 +39,23 @@ 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 final int mValidReauthenticationTimeIntervalMillis = 60000; |
Bernhard Bauer
2016/08/03 16:07:36
This should be static, and then SHOUTING_STYLE.
dozsa
2016/08/04 10:40:51
Done.
|
+ |
+ private ClipboardManager mClipboard; |
+ |
+ private KeyguardManager mKeyguardManager; |
+ |
+ private Bundle mExtras; |
+ |
+ private View mView; |
+ |
+ private boolean mViewButtonPressed; |
+ |
+ private boolean mCopyButtonPressed; |
+ |
@Override |
public void onCreate(Bundle savedInstanceState) { |
super.onCreate(savedInstanceState); |
@@ -40,36 +65,78 @@ 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 (!ChromeFeatureList.isEnabled(VIEW_PASSWORDS)) { |
Bernhard Bauer
2016/08/03 16:07:36
Why is this check now flipped?
dozsa
2016/08/04 10:40:51
Sorry, for some reason I wasn't able to change the
|
+ 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); |
+ if (!ChromeFeatureList.isEnabled(VIEW_PASSWORDS)) { |
+ mKeyguardManager = (KeyguardManager) getActivity() |
+ .getApplicationContext().getSystemService(Context.KEYGUARD_SERVICE); |
+ ImageButton copyPasswordButton = (ImageButton) mView.findViewById( |
+ R.id.password_entry_editor_copy_password); |
+ ImageButton viewPasswordButton = (ImageButton) mView.findViewById( |
+ R.id.password_entry_editor_view_password); |
+ } |
// Extras are set on this intent in class SavePasswordsPreferences. |
- Bundle extras = getArguments(); |
- assert extras != null; |
- mID = extras.getInt(SavePasswordsPreferences.PASSWORD_LIST_ID); |
+ mExtras = getArguments(); |
+ mID = mExtras.getInt(SavePasswordsPreferences.PASSWORD_LIST_ID); |
String name = null; |
- if (extras.containsKey(SavePasswordsPreferences.PASSWORD_LIST_NAME)) { |
- name = extras.getString(SavePasswordsPreferences.PASSWORD_LIST_NAME); |
+ if (mExtras.containsKey(SavePasswordsPreferences.PASSWORD_LIST_NAME)) { |
+ name = mExtras.getString(SavePasswordsPreferences.PASSWORD_LIST_NAME); |
} |
- TextView nameView = (TextView) v.findViewById(R.id.password_entry_editor_name); |
+ 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); |
+ 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); |
+ String password = mExtras.getString(SavePasswordsPreferences.PASSWORD_LIST_PASSWORD); |
+ TextView passwordView = (TextView) |
+ mView.findViewById(R.id.password_entry_editor_password); |
+ passwordView.setText(password); |
+ passwordView.setInputType(InputType.TYPE_CLASS_TEXT |
+ | InputType.TYPE_TEXT_VARIATION_PASSWORD); |
} |
- return v; |
+ if (ChromeFeatureList.isEnabled(VIEW_PASSWORDS)) { |
+ hookupCancelDeleteButtons(); |
+ } else { |
+ hookupPasswordButtons(); |
+ hookupCopyUsernameButton(); |
+ hookupCopySiteButton(); |
+ } |
+ return mView; |
+ } |
+ |
+ @Override |
+ public void onResume() { |
+ super.onResume(); |
+ |
+ if (mViewButtonPressed) { |
+ displayPassword(); |
+ } |
+ |
+ if (mCopyButtonPressed) { |
+ copyPassword(); |
+ } |
+ } |
+ |
+ /** |
+ * 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() |
+ < mValidReauthenticationTimeIntervalMillis; |
} |
// Delete was clicked. |
@@ -99,24 +166,142 @@ 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 displayPassword() { |
+ if (!authenticationStillValid()) { |
Bernhard Bauer
2016/08/03 16:07:36
Inline the return?
dozsa
2016/08/04 10:40:51
Done.
|
+ return; |
+ } |
+ ImageButton viewPasswordButton = (ImageButton) mView.findViewById( |
+ R.id.password_entry_editor_view_password); |
+ TextView passwordView = (TextView) mView.findViewById( |
+ R.id.password_entry_editor_password); |
+ passwordView.setText(mExtras.getString( |
+ SavePasswordsPreferences.PASSWORD_LIST_PASSWORD)); |
+ passwordView.setInputType(InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD); |
+ viewPasswordButton.setImageResource(R.drawable.ic_visibility_off); |
+ } |
+ |
+ private void copyPassword() { |
+ if (!authenticationStillValid()) { |
+ return; |
+ } |
+ 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 PasswordReauthentication(); |
+ 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 |
+ && authenticationStillValid()) { |
Bernhard Bauer
2016/08/03 16:07:36
Why do we require the authentication to still be v
dozsa
2016/08/04 10:40:51
I set this condition in the case in which a user v
Bernhard Bauer
2016/08/05 09:14:20
Sorry, I don't understand. If we navigate to this
dozsa
2016/08/05 13:53:53
Sorry, I just realized this controls something els
Bernhard Bauer
2016/08/05 14:29:38
Yes. My question is: Why do we require authenticat
dozsa
2016/08/05 14:52:42
Ah, sorry, that makes sense. I've removed the auth
|
+ viewPasswordButton.setImageResource(R.drawable.ic_visibility); |
+ passwordView.setInputType(InputType.TYPE_CLASS_TEXT |
+ | InputType.TYPE_TEXT_VARIATION_PASSWORD); |
+ } else if (authenticationStillValid()) { |
+ passwordView.setText(mExtras.getString( |
Bernhard Bauer
2016/08/03 16:07:36
You might want to extract this to a method you can
dozsa
2016/08/04 10:40:51
Done.
|
+ SavePasswordsPreferences.PASSWORD_LIST_PASSWORD)); |
+ passwordView.setInputType(InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD); |
+ viewPasswordButton.setImageResource(R.drawable.ic_visibility_off); |
+ } else { |
+ mViewButtonPressed = true; |
+ displayReauthenticationFragment(); |
} |
- }); |
+ } |
+ }); |
} |
+ |
} |