Commit 0db267e9 authored by Vaclav Brozek's avatar Vaclav Brozek Committed by Commit Bot

Allow mocking PasswordUIView.java

Tests are needed for viewing passwords in settings. Those tests need
an easy way to mock PasswordUIView, which communicates with C++ in the
production version.

Therefore this CL does:
(1) Define an interface, PasswordManagerHandler, for the public methods of
    PasswordUIView to be mocked in the tests (coming in
    https://crrev.com/c/797453).
(2) Create PasswordManagerHandlerProvider which encapsulates the logic
    for managing observers, life-time and test-replacement of the
    PasswordManagerHandler implementations.
(3) Lift SavedPasswordEntry to top level for reasons explained in its
    class comment.

This CL should not change any functionality, so current test coverage
is assumed to be sufficient for the new code.
The new tests are postponed until https://crrev.com/c/797453, which
also introduces other test utilities to make writing them less of a
pain.

Bug: 788701
Change-Id: I2b90a613065df50cad85de85ffa620a88df61a6e
Reviewed-on: https://chromium-review.googlesource.com/806155
Commit-Queue: Vaclav Brozek <vabr@chromium.org>
Reviewed-by: default avatarTommy Nyquist <nyquist@chromium.org>
Cr-Commit-Position: refs/heads/master@{#522059}
parent 8dea498d
// Copyright 2017 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.chrome.browser;
/**
* Interface for retrieving passwords and password exceptions (websites for which Chrome should not
* save password) from native code.
*/
public interface PasswordManagerHandler {
/**
* An interface which a client can use to listen to changes to password and password exception
* lists.
*/
public interface PasswordListObserver {
/**
* Called when passwords list is updated.
* @param count Number of entries in the password list.
*/
void passwordListAvailable(int count);
/**
* Called when password exceptions list is updated.
* @param count Number of entries in the password exception list.
*/
void passwordExceptionListAvailable(int count);
}
/**
* Called to start fetching password and exception lists.
*/
public void updatePasswordLists();
/**
* Get the saved password entry at index.
*
* @param index Index of Password.
* @return SavedPasswordEntry at index.
*/
public SavedPasswordEntry getSavedPasswordEntry(int index);
/**
* Get saved password exception at index.
*
* @param index of exception
* @return Origin of password exception.
*/
public String getSavedPasswordException(int index);
/**
* Remove saved password entry at index.
*
* @param index of password entry to remove.
*/
public void removeSavedPasswordEntry(int index);
/**
* Remove saved exception entry at index.
*
* @param index of exception entry.
*/
public void removeSavedPasswordException(int index);
}
...@@ -4,147 +4,77 @@ ...@@ -4,147 +4,77 @@
package org.chromium.chrome.browser; package org.chromium.chrome.browser;
import org.chromium.base.ObserverList;
import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.CalledByNative;
/** /**
* Class for retrieving passwords and password exceptions (websites for which Chrome should not save * Production implementation of PasswordManagerHandler, making calls to native C++ code to retrieve
* password) from native code. * the data.
*/ */
public final class PasswordUIView { public final class PasswordUIView implements PasswordManagerHandler {
/**
* Class representing information about a saved password entry.
*/
public static final class SavedPasswordEntry {
private final String mUrl;
private final String mName;
private final String mPassword;
private SavedPasswordEntry(String url, String name, String password) {
mUrl = url;
mName = name;
mPassword = password;
}
public String getUrl() {
return mUrl;
}
public String getUserName() {
return mName;
}
public String getPassword() {
return mPassword;
}
}
@CalledByNative @CalledByNative
private static SavedPasswordEntry createSavedPasswordEntry( private static SavedPasswordEntry createSavedPasswordEntry(
String url, String name, String password) { String url, String name, String password) {
return new SavedPasswordEntry(url, name, password); return new SavedPasswordEntry(url, name, password);
} }
/**
* Interface which client can use to listen to changes to password and password exception lists.
* Clients can register and unregister themselves with addObserver and removeObserver.
*/
public interface PasswordListObserver {
/**
* Called when passwords list is updated.
* @param count Number of entries in the password list.
*/
void passwordListAvailable(int count);
/**
* Called when password exceptions list is updated.
* @param count Number of entries in the password exception list.
*/
void passwordExceptionListAvailable(int count);
}
private ObserverList<PasswordListObserver> mObservers =
new ObserverList<PasswordListObserver>();
// Pointer to native implementation, set to 0 in destroy(). // Pointer to native implementation, set to 0 in destroy().
private long mNativePasswordUIViewAndroid; private long mNativePasswordUIViewAndroid;
// This class has exactly one observer, set on construction and expected to last at least as
// long as this object (a good candidate is the owner of this object).
private final PasswordListObserver mObserver;
/** /**
* Constructor creates the native object as well. Callers should call destroy() after usage. * Constructor creates the native object as well. Callers should call destroy() after usage.
* @param PasswordListObserver The only observer.
*/ */
public PasswordUIView() { public PasswordUIView(PasswordListObserver observer) {
mNativePasswordUIViewAndroid = nativeInit(); mNativePasswordUIViewAndroid = nativeInit();
mObserver = observer;
} }
@CalledByNative @CalledByNative
private void passwordListAvailable(int count) { private void passwordListAvailable(int count) {
for (PasswordListObserver observer : mObservers) { mObserver.passwordListAvailable(count);
observer.passwordListAvailable(count);
}
} }
@CalledByNative @CalledByNative
private void passwordExceptionListAvailable(int count) { private void passwordExceptionListAvailable(int count) {
for (PasswordListObserver observer : mObservers) { mObserver.passwordExceptionListAvailable(count);
observer.passwordExceptionListAvailable(count);
}
}
public void addObserver(PasswordListObserver observer) {
mObservers.addObserver(observer);
}
public void removeObserver(PasswordListObserver observer) {
mObservers.removeObserver(observer);
} }
/** // Calls native to refresh password and exception lists. The native code calls back into
* Calls native to refresh password and exception lists. Observers are notified when fetch to // passwordListAvailable and passwordExceptionListAvailable.
* passwords is complete. @Override
*/
public void updatePasswordLists() { public void updatePasswordLists() {
nativeUpdatePasswordLists(mNativePasswordUIViewAndroid); nativeUpdatePasswordLists(mNativePasswordUIViewAndroid);
} }
/** @Override
* Get the saved password entry at index.
*
* @param index Index of Password.
* @return SavedPasswordEntry at index.
*/
public SavedPasswordEntry getSavedPasswordEntry(int index) { public SavedPasswordEntry getSavedPasswordEntry(int index) {
return nativeGetSavedPasswordEntry(mNativePasswordUIViewAndroid, index); return nativeGetSavedPasswordEntry(mNativePasswordUIViewAndroid, index);
} }
/** @Override
* Get saved password exception at index.
*
* @param index of exception
* @return Origin of password exception.
*/
public String getSavedPasswordException(int index) { public String getSavedPasswordException(int index) {
return nativeGetSavedPasswordException(mNativePasswordUIViewAndroid, index); return nativeGetSavedPasswordException(mNativePasswordUIViewAndroid, index);
} }
/** @Override
* Remove saved password entry at index.
*
* @param index of password entry to remove.
*/
public void removeSavedPasswordEntry(int index) { public void removeSavedPasswordEntry(int index) {
nativeHandleRemoveSavedPasswordEntry(mNativePasswordUIViewAndroid, index); nativeHandleRemoveSavedPasswordEntry(mNativePasswordUIViewAndroid, index);
} }
/** @Override
* Remove saved exception entry at index.
*
* @param index of exception entry.
*/
public void removeSavedPasswordException(int index) { public void removeSavedPasswordException(int index) {
nativeHandleRemoveSavedPasswordException(mNativePasswordUIViewAndroid, index); nativeHandleRemoveSavedPasswordException(mNativePasswordUIViewAndroid, index);
} }
/**
* Returns the URL for the website for managing one's passwords without the need to use Chrome
* with the user's profile signed in.
* @return The string with the URL.
*/
public static String getAccountDashboardURL() { public static String getAccountDashboardURL() {
return nativeGetAccountDashboardURL(); return nativeGetAccountDashboardURL();
} }
...@@ -157,7 +87,6 @@ public final class PasswordUIView { ...@@ -157,7 +87,6 @@ public final class PasswordUIView {
nativeDestroy(mNativePasswordUIViewAndroid); nativeDestroy(mNativePasswordUIViewAndroid);
mNativePasswordUIViewAndroid = 0; mNativePasswordUIViewAndroid = 0;
} }
mObservers.clear();
} }
private native long nativeInit(); private native long nativeInit();
...@@ -165,8 +94,7 @@ public final class PasswordUIView { ...@@ -165,8 +94,7 @@ public final class PasswordUIView {
private native void nativeUpdatePasswordLists(long nativePasswordUIViewAndroid); private native void nativeUpdatePasswordLists(long nativePasswordUIViewAndroid);
private native SavedPasswordEntry nativeGetSavedPasswordEntry( private native SavedPasswordEntry nativeGetSavedPasswordEntry(
long nativePasswordUIViewAndroid, long nativePasswordUIViewAndroid, int index);
int index);
private native String nativeGetSavedPasswordException(long nativePasswordUIViewAndroid, private native String nativeGetSavedPasswordException(long nativePasswordUIViewAndroid,
int index); int index);
......
// Copyright 2017 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.chrome.browser;
/**
* A class representing information about a saved password entry in Chrome's settngs.
*
* Note: This could be a nested class in the PasswordManagerHandler interface, but that would mean
* that PasswordUIView, which implements that interface and references SavedPasswordEntry in some of
* its JNI-registered methods, would need an explicit import of PasswordManagerHandler. That again
* would violate our presubmit checks, and https://crbug.com/424792 indicates that the preferred
* solution is to move the nested class to top-level.
*/
public final class SavedPasswordEntry {
private final String mUrl;
private final String mName;
private final String mPassword;
public SavedPasswordEntry(String url, String name, String password) {
mUrl = url;
mName = name;
mPassword = password;
}
public String getUrl() {
return mUrl;
}
public String getUserName() {
return mName;
}
public String getPassword() {
return mPassword;
}
}
...@@ -34,8 +34,8 @@ import org.chromium.base.ApiCompatibilityUtils; ...@@ -34,8 +34,8 @@ import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.base.VisibleForTesting; import org.chromium.base.VisibleForTesting;
import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordHistogram;
import org.chromium.chrome.R; import org.chromium.chrome.R;
import org.chromium.chrome.browser.PasswordManagerHandler.PasswordListObserver;
import org.chromium.chrome.browser.PasswordUIView; import org.chromium.chrome.browser.PasswordUIView;
import org.chromium.chrome.browser.PasswordUIView.PasswordListObserver;
import org.chromium.chrome.browser.sync.ProfileSyncService; import org.chromium.chrome.browser.sync.ProfileSyncService;
import org.chromium.components.sync.AndroidSyncSettings; import org.chromium.components.sync.AndroidSyncSettings;
import org.chromium.ui.text.SpanApplier; import org.chromium.ui.text.SpanApplier;
...@@ -214,7 +214,6 @@ public class PasswordEntryEditor extends Fragment { ...@@ -214,7 +214,6 @@ public class PasswordEntryEditor extends Fragment {
// Delete was clicked. // Delete was clicked.
private void removeItem() { private void removeItem() {
final PasswordUIView passwordUIView = new PasswordUIView();
final PasswordListObserver passwordDeleter = new PasswordListObserver() { final PasswordListObserver passwordDeleter = new PasswordListObserver() {
@Override @Override
public void passwordListAvailable(int count) { public void passwordListAvailable(int count) {
...@@ -222,8 +221,10 @@ public class PasswordEntryEditor extends Fragment { ...@@ -222,8 +221,10 @@ public class PasswordEntryEditor extends Fragment {
RecordHistogram.recordEnumeratedHistogram( RecordHistogram.recordEnumeratedHistogram(
"PasswordManager.Android.PasswordCredentialEntry", "PasswordManager.Android.PasswordCredentialEntry",
PASSWORD_ENTRY_ACTION_DELETED, PASSWORD_ENTRY_ACTION_BOUNDARY); PASSWORD_ENTRY_ACTION_DELETED, PASSWORD_ENTRY_ACTION_BOUNDARY);
passwordUIView.removeSavedPasswordEntry(mID); PasswordManagerHandlerProvider.getInstance()
passwordUIView.destroy(); .getPasswordManagerHandler()
.removeSavedPasswordEntry(mID);
PasswordManagerHandlerProvider.getInstance().removeObserver(this);
Toast.makeText(getActivity().getApplicationContext(), R.string.deleted, Toast.makeText(getActivity().getApplicationContext(), R.string.deleted,
Toast.LENGTH_SHORT) Toast.LENGTH_SHORT)
.show(); .show();
...@@ -237,8 +238,10 @@ public class PasswordEntryEditor extends Fragment { ...@@ -237,8 +238,10 @@ public class PasswordEntryEditor extends Fragment {
RecordHistogram.recordEnumeratedHistogram( RecordHistogram.recordEnumeratedHistogram(
"PasswordManager.Android.PasswordExceptionEntry", "PasswordManager.Android.PasswordExceptionEntry",
PASSWORD_ENTRY_ACTION_DELETED, PASSWORD_ENTRY_ACTION_BOUNDARY); PASSWORD_ENTRY_ACTION_DELETED, PASSWORD_ENTRY_ACTION_BOUNDARY);
passwordUIView.removeSavedPasswordException(mID); PasswordManagerHandlerProvider.getInstance()
passwordUIView.destroy(); .getPasswordManagerHandler()
.removeSavedPasswordException(mID);
PasswordManagerHandlerProvider.getInstance().removeObserver(this);
Toast.makeText(getActivity().getApplicationContext(), R.string.deleted, Toast.makeText(getActivity().getApplicationContext(), R.string.deleted,
Toast.LENGTH_SHORT) Toast.LENGTH_SHORT)
.show(); .show();
...@@ -247,8 +250,10 @@ public class PasswordEntryEditor extends Fragment { ...@@ -247,8 +250,10 @@ public class PasswordEntryEditor extends Fragment {
} }
}; };
passwordUIView.addObserver(passwordDeleter); PasswordManagerHandlerProvider.getInstance().addObserver(passwordDeleter);
passwordUIView.updatePasswordLists(); PasswordManagerHandlerProvider.getInstance()
.getPasswordManagerHandler()
.updatePasswordLists();
} }
private void hookupCopyUsernameButton(View usernameView) { private void hookupCopyUsernameButton(View usernameView) {
......
// Copyright 2017 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.chrome.browser.preferences.password;
import org.chromium.base.ObserverList;
import org.chromium.base.ThreadUtils;
import org.chromium.base.VisibleForTesting;
import org.chromium.chrome.browser.PasswordManagerHandler;
import org.chromium.chrome.browser.PasswordUIView;
/**
* A provider for PasswordManagerHandler implementations, handling the choice of the proper one
* (production vs. testing), its lifetime and multiple observers.
*
* This class is used by the code responsible for Chrome's passwords settings. There can only be one
* instance of Chrome's passwords settings opened at a time (although more clients of
* PasswordManagerHandler can live as nested settings pages). Therefore, the provider can be just
* one. However, it cannot be just a collection of static data members and methods, because the
* managed PasswordManagerHandler instances need to refer to it as an observer. For that reason, the
* provider is a singleton.
*/
public class PasswordManagerHandlerProvider implements PasswordManagerHandler.PasswordListObserver {
private static final class LazyHolder {
private static final PasswordManagerHandlerProvider INSTANCE =
new PasswordManagerHandlerProvider();
}
/** Private constructor, use GetInstance() instead. */
private PasswordManagerHandlerProvider() {}
public static PasswordManagerHandlerProvider getInstance() {
return LazyHolder.INSTANCE;
}
// The production implementation of PasswordManagerHandler is |sPasswordUIView|, instantiated on
// demand. Tests might want to override that by providing a fake implementation through
// setPasswordManagerHandlerForTest, which is then kept in |mTestPasswordManagerHandler|.
private PasswordUIView mPasswordUIView;
private PasswordManagerHandler mTestPasswordManagerHandler;
// This class is itself a PasswordListObserver, listening directly to a PasswordManagerHandler
// implementation. But it also keeps a list of other observers, to which it forwards the events.
private final ObserverList<PasswordManagerHandler.PasswordListObserver> mObservers =
new ObserverList<PasswordManagerHandler.PasswordListObserver>();
/**
* Sets a testing implementation of PasswordManagerHandler to be used. It overrides the
* production one even if it exists. The caller needs to ensure that |this| becomes an observer
* of |passwordManagerHandler|. Also, this must not be called when there are already some
* observers in |mObservers|, because of special handling of the production implementation of
* PasswordManagerHandler on removing the last observer.
*/
@VisibleForTesting
public void setPasswordManagerHandlerForTest(PasswordManagerHandler passwordManagerHandler) {
ThreadUtils.assertOnUiThread();
assert mObservers.isEmpty();
mTestPasswordManagerHandler = passwordManagerHandler;
}
/**
* A convenience function to choose between the production and test PasswordManagerHandler
* implementation.
*/
public PasswordManagerHandler getPasswordManagerHandler() {
ThreadUtils.assertOnUiThread();
if (mTestPasswordManagerHandler != null) return mTestPasswordManagerHandler;
return mPasswordUIView;
}
/**
* This method creates the production implementation of PasswordManagerHandler and saves it into
* mPasswordUIView.
*/
private void createPasswordManagerHandler() {
ThreadUtils.assertOnUiThread();
assert mPasswordUIView == null;
mPasswordUIView = new PasswordUIView(this);
}
/**
* Starts forwarding events from the PasswordManagerHandler implementation to |observer|.
*/
public void addObserver(PasswordManagerHandler.PasswordListObserver observer) {
ThreadUtils.assertOnUiThread();
if (getPasswordManagerHandler() == null) createPasswordManagerHandler();
mObservers.addObserver(observer);
}
public void removeObserver(PasswordManagerHandler.PasswordListObserver observer) {
ThreadUtils.assertOnUiThread();
mObservers.removeObserver(observer);
// If this was the last observer of the production implementation of PasswordManagerHandler,
// call destroy on it to close the connection to the native C++ code.
if (mObservers.isEmpty() && mTestPasswordManagerHandler == null) {
mPasswordUIView.destroy();
mPasswordUIView = null;
}
}
@Override
public void passwordListAvailable(int count) {
ThreadUtils.assertOnUiThread();
for (PasswordManagerHandler.PasswordListObserver observer : mObservers) {
observer.passwordListAvailable(count);
}
}
@Override
public void passwordExceptionListAvailable(int count) {
ThreadUtils.assertOnUiThread();
for (PasswordManagerHandler.PasswordListObserver observer : mObservers) {
observer.passwordExceptionListAvailable(count);
}
}
}
...@@ -21,8 +21,9 @@ import android.view.MenuItem; ...@@ -21,8 +21,9 @@ import android.view.MenuItem;
import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.chrome.R; import org.chromium.chrome.R;
import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.ChromeFeatureList;
import org.chromium.chrome.browser.PasswordManagerHandler;
import org.chromium.chrome.browser.PasswordUIView; import org.chromium.chrome.browser.PasswordUIView;
import org.chromium.chrome.browser.PasswordUIView.PasswordListObserver; import org.chromium.chrome.browser.SavedPasswordEntry;
import org.chromium.chrome.browser.preferences.ChromeBaseCheckBoxPreference; import org.chromium.chrome.browser.preferences.ChromeBaseCheckBoxPreference;
import org.chromium.chrome.browser.preferences.ChromeBasePreference; import org.chromium.chrome.browser.preferences.ChromeBasePreference;
import org.chromium.chrome.browser.preferences.ChromeSwitchPreference; import org.chromium.chrome.browser.preferences.ChromeSwitchPreference;
...@@ -37,8 +38,9 @@ import org.chromium.ui.text.SpanApplier; ...@@ -37,8 +38,9 @@ import org.chromium.ui.text.SpanApplier;
* The "Save passwords" screen in Settings, which allows the user to enable or disable password * The "Save passwords" screen in Settings, which allows the user to enable or disable password
* saving, to view saved passwords (just the username and URL), and to delete saved passwords. * saving, to view saved passwords (just the username and URL), and to delete saved passwords.
*/ */
public class SavePasswordsPreferences extends PreferenceFragment public class SavePasswordsPreferences
implements PasswordListObserver, Preference.OnPreferenceClickListener { extends PreferenceFragment implements PasswordManagerHandler.PasswordListObserver,
Preference.OnPreferenceClickListener {
// Keys for name/password dictionaries. // Keys for name/password dictionaries.
public static final String PASSWORD_LIST_URL = "url"; public static final String PASSWORD_LIST_URL = "url";
public static final String PASSWORD_LIST_NAME = "name"; public static final String PASSWORD_LIST_NAME = "name";
...@@ -65,7 +67,6 @@ public class SavePasswordsPreferences extends PreferenceFragment ...@@ -65,7 +67,6 @@ public class SavePasswordsPreferences extends PreferenceFragment
private static final int ORDER_EXCEPTIONS = 4; private static final int ORDER_EXCEPTIONS = 4;
private static final int ORDER_SAVED_PASSWORDS_NO_TEXT = 5; private static final int ORDER_SAVED_PASSWORDS_NO_TEXT = 5;
private final PasswordUIView mPasswordManagerHandler = new PasswordUIView();
private boolean mNoPasswords; private boolean mNoPasswords;
private boolean mNoPasswordExceptions; private boolean mNoPasswordExceptions;
private Preference mLinkPref; private Preference mLinkPref;
...@@ -78,7 +79,7 @@ public class SavePasswordsPreferences extends PreferenceFragment ...@@ -78,7 +79,7 @@ public class SavePasswordsPreferences extends PreferenceFragment
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
getActivity().setTitle(R.string.prefs_saved_passwords); getActivity().setTitle(R.string.prefs_saved_passwords);
setPreferenceScreen(getPreferenceManager().createPreferenceScreen(getActivity())); setPreferenceScreen(getPreferenceManager().createPreferenceScreen(getActivity()));
mPasswordManagerHandler.addObserver(this); PasswordManagerHandlerProvider.getInstance().addObserver(this);
if (ChromeFeatureList.isEnabled(EXPORT_PASSWORDS)) { if (ChromeFeatureList.isEnabled(EXPORT_PASSWORDS)) {
setHasOptionsMenu(true); setHasOptionsMenu(true);
} }
...@@ -123,7 +124,9 @@ public class SavePasswordsPreferences extends PreferenceFragment ...@@ -123,7 +124,9 @@ public class SavePasswordsPreferences extends PreferenceFragment
getPreferenceScreen().removeAll(); getPreferenceScreen().removeAll();
createSavePasswordsSwitch(); createSavePasswordsSwitch();
createAutoSignInCheckbox(); createAutoSignInCheckbox();
mPasswordManagerHandler.updatePasswordLists(); PasswordManagerHandlerProvider.getInstance()
.getPasswordManagerHandler()
.updatePasswordLists();
} }
/** /**
...@@ -168,8 +171,9 @@ public class SavePasswordsPreferences extends PreferenceFragment ...@@ -168,8 +171,9 @@ public class SavePasswordsPreferences extends PreferenceFragment
profileCategory.setOrder(ORDER_SAVED_PASSWORDS); profileCategory.setOrder(ORDER_SAVED_PASSWORDS);
getPreferenceScreen().addPreference(profileCategory); getPreferenceScreen().addPreference(profileCategory);
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
PasswordUIView.SavedPasswordEntry saved = SavedPasswordEntry saved = PasswordManagerHandlerProvider.getInstance()
mPasswordManagerHandler.getSavedPasswordEntry(i); .getPasswordManagerHandler()
.getSavedPasswordEntry(i);
PreferenceScreen screen = getPreferenceManager().createPreferenceScreen(getActivity()); PreferenceScreen screen = getPreferenceManager().createPreferenceScreen(getActivity());
String url = saved.getUrl(); String url = saved.getUrl();
String name = saved.getUserName(); String name = saved.getUserName();
...@@ -205,7 +209,9 @@ public class SavePasswordsPreferences extends PreferenceFragment ...@@ -205,7 +209,9 @@ public class SavePasswordsPreferences extends PreferenceFragment
profileCategory.setOrder(ORDER_EXCEPTIONS); profileCategory.setOrder(ORDER_EXCEPTIONS);
getPreferenceScreen().addPreference(profileCategory); getPreferenceScreen().addPreference(profileCategory);
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
String exception = mPasswordManagerHandler.getSavedPasswordException(i); String exception = PasswordManagerHandlerProvider.getInstance()
.getPasswordManagerHandler()
.getSavedPasswordException(i);
PreferenceScreen screen = getPreferenceManager().createPreferenceScreen(getActivity()); PreferenceScreen screen = getPreferenceManager().createPreferenceScreen(getActivity());
screen.setTitle(exception); screen.setTitle(exception);
screen.setOnPreferenceClickListener(this); screen.setOnPreferenceClickListener(this);
...@@ -225,7 +231,7 @@ public class SavePasswordsPreferences extends PreferenceFragment ...@@ -225,7 +231,7 @@ public class SavePasswordsPreferences extends PreferenceFragment
@Override @Override
public void onDestroy() { public void onDestroy() {
super.onDestroy(); super.onDestroy();
mPasswordManagerHandler.destroy(); PasswordManagerHandlerProvider.getInstance().removeObserver(this);
} }
/** /**
......
...@@ -56,9 +56,11 @@ chrome_java_sources = [ ...@@ -56,9 +56,11 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/NativePageHost.java", "java/src/org/chromium/chrome/browser/NativePageHost.java",
"java/src/org/chromium/chrome/browser/NavigationPopup.java", "java/src/org/chromium/chrome/browser/NavigationPopup.java",
"java/src/org/chromium/chrome/browser/NearOomMonitor.java", "java/src/org/chromium/chrome/browser/NearOomMonitor.java",
"java/src/org/chromium/chrome/browser/PasswordManagerHandler.java",
"java/src/org/chromium/chrome/browser/PasswordUIView.java", "java/src/org/chromium/chrome/browser/PasswordUIView.java",
"java/src/org/chromium/chrome/browser/PowerBroadcastReceiver.java", "java/src/org/chromium/chrome/browser/PowerBroadcastReceiver.java",
"java/src/org/chromium/chrome/browser/RepostFormWarningDialog.java", "java/src/org/chromium/chrome/browser/RepostFormWarningDialog.java",
"java/src/org/chromium/chrome/browser/SavedPasswordEntry.java",
"java/src/org/chromium/chrome/browser/SearchGeolocationDisclosureTabHelper.java", "java/src/org/chromium/chrome/browser/SearchGeolocationDisclosureTabHelper.java",
"java/src/org/chromium/chrome/browser/ServiceTabLauncher.java", "java/src/org/chromium/chrome/browser/ServiceTabLauncher.java",
"java/src/org/chromium/chrome/browser/SingleTabActivity.java", "java/src/org/chromium/chrome/browser/SingleTabActivity.java",
...@@ -967,11 +969,12 @@ chrome_java_sources = [ ...@@ -967,11 +969,12 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/preferences/languages/LanguageListBaseAdapter.java", "java/src/org/chromium/chrome/browser/preferences/languages/LanguageListBaseAdapter.java",
"java/src/org/chromium/chrome/browser/preferences/languages/LanguageListPreference.java", "java/src/org/chromium/chrome/browser/preferences/languages/LanguageListPreference.java",
"java/src/org/chromium/chrome/browser/preferences/password/PasswordEntryEditor.java", "java/src/org/chromium/chrome/browser/preferences/password/PasswordEntryEditor.java",
"java/src/org/chromium/chrome/browser/preferences/password/PasswordManagerHandlerProvider.java",
"java/src/org/chromium/chrome/browser/preferences/password/PasswordReauthenticationFragment.java",
"java/src/org/chromium/chrome/browser/preferences/password/ReauthenticationManager.java",
"java/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferences.java", "java/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferences.java",
"java/src/org/chromium/chrome/browser/preferences/privacy/BandwidthType.java", "java/src/org/chromium/chrome/browser/preferences/privacy/BandwidthType.java",
"java/src/org/chromium/chrome/browser/preferences/privacy/BrowsingDataBridge.java", "java/src/org/chromium/chrome/browser/preferences/privacy/BrowsingDataBridge.java",
"java/src/org/chromium/chrome/browser/preferences/password/PasswordReauthenticationFragment.java",
"java/src/org/chromium/chrome/browser/preferences/password/ReauthenticationManager.java",
"java/src/org/chromium/chrome/browser/preferences/privacy/BrowsingDataCounterBridge.java", "java/src/org/chromium/chrome/browser/preferences/privacy/BrowsingDataCounterBridge.java",
"java/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferences.java", "java/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferences.java",
"java/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferencesAdvanced.java", "java/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferencesAdvanced.java",
......
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