Commit 60d592d3 authored by Ivana Zuzic's avatar Ivana Zuzic Committed by Commit Bot

[PWD Editing Android] Enable saving changes by clicking the save button

The changes of password data are saved by clicking on the save button in PasswordentryEditor.
After that, PasswordEntryEditor gets closed and the changes are visible in PasswordEntryViewer
and on the list of passwords.


Bug: 377410
Change-Id: Ia0e9707d508b6a6449fb97263e31e5747016a945
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1736685
Commit-Queue: Ivana Zuzic <izuzic@google.com>
Reviewed-by: default avatarFriedrich [CET] <fhorschig@chromium.org>
Reviewed-by: default avatarVasilii Sukhanov <vasilii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#685541}
parent 88179435
......@@ -9,6 +9,7 @@ import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
......@@ -19,6 +20,9 @@ import org.chromium.chrome.R;
* Password entry editor that allows editing passwords stored in Chrome.
*/
public class PasswordEntryEditor extends Fragment {
// ID of this name/password or exception.
private int mID;
private EditText mSiteText;
private EditText mUsernameText;
private EditText mPasswordText;
......@@ -36,10 +40,10 @@ public class PasswordEntryEditor extends Fragment {
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Editing action in PasswordEntryViewer sets extras and launches PasswordEntryEditor.
mID = getArguments().getInt(SavePasswordsPreferences.PASSWORD_LIST_ID);
mSavedPasswordEntry = PasswordManagerHandlerProvider.getInstance()
.getPasswordManagerHandler()
.getSavedPasswordEntry(getArguments().getInt(
SavePasswordsPreferences.PASSWORD_LIST_ID));
.getSavedPasswordEntry(mID);
mSiteText = (EditText) view.findViewById(R.id.site_edit);
mUsernameText = (EditText) view.findViewById(R.id.username_edit);
mPasswordText = (EditText) view.findViewById(R.id.password_edit);
......@@ -52,4 +56,18 @@ public class PasswordEntryEditor extends Fragment {
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.password_entry_editor_action_bar_menu, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_save_edited_password) {
PasswordManagerHandlerProvider.getInstance()
.getPasswordManagerHandler()
.changeSavedPasswordEntry(mID, mUsernameText.getText().toString(),
mPasswordText.getText().toString());
getActivity().finish();
return true;
}
return super.onOptionsItemSelected(item);
}
}
\ No newline at end of file
......@@ -10,6 +10,7 @@ import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.IdRes;
import android.support.annotation.StringRes;
import android.support.v4.app.Fragment;
import android.support.v7.content.res.AppCompatResources;
......@@ -44,7 +45,8 @@ import org.chromium.ui.widget.Toast;
/**
* Password entry viewer that allows to view and delete passwords stored in Chrome.
*/
public class PasswordEntryViewer extends Fragment {
public class PasswordEntryViewer
extends Fragment implements PasswordManagerHandler.PasswordListObserver {
// Constants used to log UMA enum histogram, must stay in sync with
// PasswordManagerAndroidPasswordEntryActions. Further actions can only be appended, existing
// entries must not be overwritten.
......@@ -123,20 +125,15 @@ public class PasswordEntryViewer extends Fragment {
getActivity().setTitle(R.string.password_entry_viewer_title);
mClipboard = (ClipboardManager) getActivity().getApplicationContext().getSystemService(
Context.CLIPBOARD_SERVICE);
View urlRowsView = mView.findViewById(R.id.url_row);
TextView dataView = urlRowsView.findViewById(R.id.password_entry_viewer_row_data);
dataView.setText(url);
setRowText(R.id.url_row, url);
mView.getViewTreeObserver().addOnScrollChangedListener(
PreferenceUtils.getShowShadowOnScrollListener(
mView, inflatedView.findViewById(R.id.shadow)));
hookupCopySiteButton(urlRowsView);
hookupCopySiteButton(mView.findViewById(R.id.url_row));
if (!mException) {
View usernameView = mView.findViewById(R.id.username_row);
TextView usernameDataView =
usernameView.findViewById(R.id.password_entry_viewer_row_data);
usernameDataView.setText(name);
hookupCopyUsernameButton(usernameView);
setRowText(R.id.username_row, name);
hookupCopyUsernameButton(mView.findViewById(R.id.username_row));
if (ReauthenticationManager.isReauthenticationApiAvailable()) {
hidePassword();
hookupPasswordButtons();
......@@ -186,6 +183,7 @@ public class PasswordEntryViewer extends Fragment {
"PasswordManager.Android.PasswordExceptionEntry", PASSWORD_ENTRY_ACTION_VIEWED,
PASSWORD_ENTRY_ACTION_BOUNDARY);
}
PasswordManagerHandlerProvider.getInstance().addObserver(this);
return inflatedView;
}
......@@ -200,6 +198,12 @@ public class PasswordEntryViewer extends Fragment {
}
}
@Override
public void onDestroy() {
super.onDestroy();
PasswordManagerHandlerProvider.getInstance().removeObserver(this);
}
private boolean isPasswordSyncingUser() {
ProfileSyncService syncService = ProfileSyncService.get();
return (AndroidSyncSettings.get().isSyncEnabled() && syncService.isEngineInitialized()
......@@ -416,4 +420,24 @@ public class PasswordEntryViewer extends Fragment {
}
});
}
private void setRowText(@IdRes int rowId, String text) {
View rowView = mView.findViewById(rowId);
TextView dataView = rowView.findViewById(R.id.password_entry_viewer_row_data);
dataView.setText(text);
}
@Override
public void passwordListAvailable(int count) {
TextView passwordsLinkTextView = mView.findViewById(R.id.passwords_link);
SavedPasswordEntry SavedPasswordEntry = PasswordManagerHandlerProvider.getInstance()
.getPasswordManagerHandler()
.getSavedPasswordEntry(mID);
setRowText(R.id.url_row, SavedPasswordEntry.getUrl());
setRowText(R.id.username_row, SavedPasswordEntry.getUserName());
passwordsLinkTextView.setText(SavedPasswordEntry.getPassword());
}
@Override
public void passwordExceptionListAvailable(int count) {}
}
......@@ -48,8 +48,10 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.ColorFilter;
import android.graphics.drawable.Drawable;
import android.support.annotation.IdRes;
import android.support.annotation.IntDef;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.test.InstrumentationRegistry;
import android.support.test.espresso.Espresso;
import android.support.test.espresso.intent.Intents;
......@@ -187,7 +189,10 @@ public class SavePasswordsPreferencesTest {
@Override
public void changeSavedPasswordEntry(int index, String newUsername, String newPassword) {
assert false : "Define this method before starting to use it in tests.";
mSavedPasswords.set(index,
new SavedPasswordEntry(
mSavedPasswords.get(index).getUrl(), newUsername, newPassword));
updatePasswordLists();
}
@Override
......@@ -301,38 +306,45 @@ public class SavePasswordsPreferencesTest {
}
/**
* Looks for the search icon by id. If it cannot be found, it's probably hidden in the overflow
* Looks for the icon by id. If it cannot be found, it's probably hidden in the overflow
* menu. In that case, open the menu and search for its title.
* @return Returns either the search icon button or the search menu option.
* @return Returns either the icon button or the menu option.
*/
public static Matcher<View> withSearchMenuIdOrText() {
Matcher<View> matcher = withId(R.id.menu_id_search);
public static Matcher<View> withMenuIdOrText(@IdRes int actionId, @StringRes int actionLabel) {
Matcher<View> matcher = withId(actionId);
try {
Espresso.onView(matcher).check(matches(isDisplayed()));
return matcher;
} catch (Exception NoMatchingViewException) {
openActionBarOverflowOrOptionsMenu(
InstrumentationRegistry.getInstrumentation().getTargetContext());
return withText(R.string.search);
return withText(actionLabel);
}
}
/**
* Looks for the edit saved password icon by id. If it cannot be found, it's probably hidden in
* the overflow menu. In that case, open the menu and search for its title.
* @return Returns either the edit saved password icon button or the edit saved password menu
* option.
* Looks for the search icon by id or by its title.
* @return Returns either the icon button or the menu option.
*/
public static Matcher<View> withSearchMenuIdOrText() {
return withMenuIdOrText(R.id.menu_id_search, R.string.search);
}
/**
* Looks for the edit saved password icon by id or by its title.
* @return Returns either the icon button or the menu option.
*/
public static Matcher<View> withEditMenuIdOrText() {
Matcher<View> matcher = withId(R.id.action_edit_saved_password);
try {
Espresso.onView(matcher).check(matches(isDisplayed()));
return matcher;
} catch (Exception NoMatchingViewException) {
openActionBarOverflowOrOptionsMenu(
InstrumentationRegistry.getInstrumentation().getTargetContext());
return withText(R.string.password_entry_viewer_edit_stored_password_action_title);
}
return withMenuIdOrText(R.id.action_edit_saved_password,
R.string.password_entry_viewer_edit_stored_password_action_title);
}
/**
* Looks for the save edited password icon by id or by its title.
* @return Returns either the icon button or the menu option.
*/
public static Matcher<View> withSaveMenuIdOrText() {
return withMenuIdOrText(R.id.action_save_edited_password, R.string.save);
}
/**
......@@ -682,6 +694,37 @@ public class SavePasswordsPreferencesTest {
Espresso.onView(withId(R.id.site_edit)).check(matches(withText("https://test.com")));
}
/**
* Check that the changes of password data in the password editing activity are preserved and
* shown in the password viewing activity and in the list of passwords after the save button
* was clicked.
*/
@Test
@SmallTest
@Feature({"Preferences"})
@Features.EnableFeatures(ChromeFeatureList.PASSWORD_EDITING_ANDROID)
public void testChangeOfStoredPasswordDataIsPreserved() throws Exception {
setPasswordSource(new SavedPasswordEntry("https://example.com", "test user", "password"));
PreferencesTest.startPreferences(InstrumentationRegistry.getInstrumentation(),
SavePasswordsPreferences.class.getName());
Espresso.onView(withText(containsString("test user"))).perform(click());
Espresso.onView(withEditMenuIdOrText()).perform(click());
Espresso.onView(withId(R.id.username_edit)).perform(typeText(" new"));
Espresso.onView(withSaveMenuIdOrText()).perform(click());
// Check if the password viewing activity has the updated data.
Espresso.onView(withText("test user new")).check(matches(isDisplayed()));
Espresso.pressBack();
// Check if the password preferences activity has the updated data in the list of passwords.
Espresso.onView(withText("test user new")).check(matches(isDisplayed()));
}
/**
* Check that if there are no saved passwords, the export menu item is disabled.
*/
......
......@@ -40,7 +40,9 @@ using base::android::JavaRef;
using base::android::ScopedJavaLocalRef;
PasswordUIViewAndroid::PasswordUIViewAndroid(JNIEnv* env, jobject obj)
: password_manager_presenter_(this), weak_java_ui_controller_(env, obj) {}
: password_manager_presenter_(this), weak_java_ui_controller_(env, obj) {
password_manager_presenter_.Initialize();
}
PasswordUIViewAndroid::~PasswordUIViewAndroid() {}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment