Commit 2474fd40 authored by Friedrich Horschig's avatar Friedrich Horschig Committed by Commit Bot

[PwdCheckAndroid] Create coordinator when frame is attached

Instead of using the factory directly in the fragment, the parent
activity will now check whether the newly attached fragment has a known
component and creates it using the factory.

The functionality and visible behavior is unchanged.

Bug: 1101256, 1092444
Change-Id: If430d33d9c895eeed1503253ff5a279cfeae394c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2315149
Commit-Queue: Ioana Pandele <ioanap@chromium.org>
Reviewed-by: default avatarIoana Pandele <ioanap@chromium.org>
Reviewed-by: default avatarNatalie Chouinard <chouinard@chromium.org>
Cr-Commit-Position: refs/heads/master@{#791754}
parent 4b1e8b52
...@@ -29,6 +29,8 @@ import org.chromium.chrome.R; ...@@ -29,6 +29,8 @@ import org.chromium.chrome.R;
import org.chromium.chrome.browser.ChromeBaseAppCompatActivity; import org.chromium.chrome.browser.ChromeBaseAppCompatActivity;
import org.chromium.chrome.browser.help.HelpAndFeedback; import org.chromium.chrome.browser.help.HelpAndFeedback;
import org.chromium.chrome.browser.init.ChromeBrowserInitializer; import org.chromium.chrome.browser.init.ChromeBrowserInitializer;
import org.chromium.chrome.browser.password_check.PasswordCheckComponentUiFactory;
import org.chromium.chrome.browser.password_check.PasswordCheckFragmentView;
import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.profiles.ProfileManagerUtils; import org.chromium.chrome.browser.profiles.ProfileManagerUtils;
import org.chromium.chrome.browser.safety_check.SafetyCheckCoordinator; import org.chromium.chrome.browser.safety_check.SafetyCheckCoordinator;
...@@ -280,6 +282,8 @@ public class SettingsActivity extends ChromeBaseAppCompatActivity ...@@ -280,6 +282,8 @@ public class SettingsActivity extends ChromeBaseAppCompatActivity
} else if (fragment instanceof SafetyCheckSettingsFragment) { } else if (fragment instanceof SafetyCheckSettingsFragment) {
SafetyCheckCoordinator.create((SafetyCheckSettingsFragment) fragment, SafetyCheckCoordinator.create((SafetyCheckSettingsFragment) fragment,
new SafetyCheckUpdatesDelegateImpl(this)); new SafetyCheckUpdatesDelegateImpl(this));
} else if (fragment instanceof PasswordCheckFragmentView) {
PasswordCheckComponentUiFactory.create((PasswordCheckFragmentView) fragment);
} }
} }
......
...@@ -78,6 +78,7 @@ android_library("test_java") { ...@@ -78,6 +78,7 @@ android_library("test_java") {
":public_java", ":public_java",
":public_ui_java", ":public_ui_java",
"internal:internal_java", "internal:internal_java",
"internal:internal_ui_factory_java",
"//base:base_java", "//base:base_java",
"//base:base_java_test_support", "//base:base_java_test_support",
"//chrome/android:chrome_java", "//chrome/android:chrome_java",
......
...@@ -39,6 +39,7 @@ android_library_factory("public_ui_factory_java") { ...@@ -39,6 +39,7 @@ android_library_factory("public_ui_factory_java") {
android_library("internal_ui_factory_java") { android_library("internal_ui_factory_java") {
deps = [ deps = [
":internal_java", ":internal_java",
"//third_party/android_deps:androidx_annotation_annotation_java",
_public_target, _public_target,
] ]
sources = _ui_factory_sources sources = _ui_factory_sources
...@@ -60,6 +61,7 @@ android_library("internal_java") { ...@@ -60,6 +61,7 @@ android_library("internal_java") {
"//components/embedder_support/android:util_java", "//components/embedder_support/android:util_java",
"//third_party/android_deps:androidx_annotation_annotation_java", "//third_party/android_deps:androidx_annotation_annotation_java",
"//third_party/android_deps:androidx_fragment_fragment_java", "//third_party/android_deps:androidx_fragment_fragment_java",
"//third_party/android_deps:androidx_lifecycle_lifecycle_common_java",
"//third_party/android_deps:androidx_preference_preference_java", "//third_party/android_deps:androidx_preference_preference_java",
"//third_party/android_deps:androidx_recyclerview_recyclerview_java", "//third_party/android_deps:androidx_recyclerview_recyclerview_java",
"//ui/android:ui_full_java", "//ui/android:ui_full_java",
......
...@@ -4,12 +4,26 @@ ...@@ -4,12 +4,26 @@
package org.chromium.chrome.browser.password_check; package org.chromium.chrome.browser.password_check;
import androidx.annotation.VisibleForTesting;
import androidx.preference.PreferenceFragmentCompat; import androidx.preference.PreferenceFragmentCompat;
/** /**
* Use {@link #create()} to instantiate a {@link PasswordCheckComponentUi}. * Use {@link #create()} to instantiate a {@link PasswordCheckComponentUi}.
*/ */
class PasswordCheckComponentUiFactory { public class PasswordCheckComponentUiFactory {
/**
* The factory used to create components that connect to this fragment and provide data.
*/
interface CreationStrategy {
/**
* Returns a component that connects to the given fragment and manipulates its data.
* @param fragmentView A {@link PasswordCheckFragmentView}.
* @return A non-null {@link PasswordCheckComponentUi}.
*/
PasswordCheckComponentUi create(PasswordCheckFragmentView fragmentView);
}
private static CreationStrategy sCreationStrategy = PasswordCheckCoordinator::new;
private PasswordCheckComponentUiFactory() {} private PasswordCheckComponentUiFactory() {}
/** /**
...@@ -18,6 +32,11 @@ class PasswordCheckComponentUiFactory { ...@@ -18,6 +32,11 @@ class PasswordCheckComponentUiFactory {
* @return A {@link PasswordCheckComponentUi}. * @return A {@link PasswordCheckComponentUi}.
*/ */
public static PasswordCheckComponentUi create(PreferenceFragmentCompat fragmentView) { public static PasswordCheckComponentUi create(PreferenceFragmentCompat fragmentView) {
return new PasswordCheckCoordinator((PasswordCheckFragmentView) fragmentView); return sCreationStrategy.create((PasswordCheckFragmentView) fragmentView);
}
@VisibleForTesting
static void setCreationStrategy(CreationStrategy creationStrategy) {
sCreationStrategy = creationStrategy;
} }
} }
\ No newline at end of file
...@@ -7,6 +7,9 @@ package org.chromium.chrome.browser.password_check; ...@@ -7,6 +7,9 @@ package org.chromium.chrome.browser.password_check;
import android.view.MenuItem; import android.view.MenuItem;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.OnLifecycleEvent;
import org.chromium.chrome.browser.help.HelpAndFeedback; import org.chromium.chrome.browser.help.HelpAndFeedback;
import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.profiles.Profile;
...@@ -17,8 +20,9 @@ import org.chromium.ui.modelutil.PropertyModelChangeProcessor; ...@@ -17,8 +20,9 @@ import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
* Creates the PasswordCheckComponentUi. This class is responsible for managing the UI for the check * Creates the PasswordCheckComponentUi. This class is responsible for managing the UI for the check
* of the leaked password. * of the leaked password.
*/ */
class PasswordCheckCoordinator implements PasswordCheckComponentUi { class PasswordCheckCoordinator implements PasswordCheckComponentUi, LifecycleObserver {
private final PasswordCheckFragmentView mFragmentView; private final PasswordCheckFragmentView mFragmentView;
private PropertyModel mModel;
/** /**
* Blueprint for a class that handles interactions with credentials. * Blueprint for a class that handles interactions with credentials.
...@@ -33,10 +37,20 @@ class PasswordCheckCoordinator implements PasswordCheckComponentUi { ...@@ -33,10 +37,20 @@ class PasswordCheckCoordinator implements PasswordCheckComponentUi {
PasswordCheckCoordinator(PasswordCheckFragmentView fragmentView) { PasswordCheckCoordinator(PasswordCheckFragmentView fragmentView) {
mFragmentView = fragmentView; mFragmentView = fragmentView;
PropertyModel model = PasswordCheckProperties.createDefaultModel(); // TODO(crbug.com/1101256): If help is part of the view, make mediator the delegate.
PasswordCheckMediator mediator = new PasswordCheckMediator(); mFragmentView.setComponentDelegate(this);
PasswordCheckCoordinator.setUpModelChangeProcessors(model, mFragmentView); mFragmentView.getLifecycle().addObserver(this);
mediator.initialize(model, PasswordCheckFactory.create()); }
@OnLifecycleEvent(Lifecycle.Event.ON_START)
public void connectToModelWhenViewIsReady() {
// In the rare case of a restarted activity, don't recreate the model and mediator.
if (mModel == null) {
mModel = PasswordCheckProperties.createDefaultModel();
PasswordCheckMediator mediator = new PasswordCheckMediator();
PasswordCheckCoordinator.setUpModelChangeProcessors(mModel, mFragmentView);
mediator.initialize(mModel, PasswordCheckFactory.create());
}
} }
// TODO(crbug.com/1101256): Move to view code. // TODO(crbug.com/1101256): Move to view code.
......
...@@ -8,8 +8,6 @@ import android.content.Context; ...@@ -8,8 +8,6 @@ import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.view.MenuItem; import android.view.MenuItem;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.preference.PreferenceFragmentCompat; import androidx.preference.PreferenceFragmentCompat;
/** /**
...@@ -19,18 +17,12 @@ public class PasswordCheckFragmentView extends PreferenceFragmentCompat { ...@@ -19,18 +17,12 @@ public class PasswordCheckFragmentView extends PreferenceFragmentCompat {
private PasswordCheckComponentUi mComponentDelegate; private PasswordCheckComponentUi mComponentDelegate;
/** /**
* The factory used to create components that connect to this fragment and provide data. It * Set the delegate that handles view events which affect the state of the component.
* defaults to the {@link PasswordCheckComponentUiFactory} but can be replaced in tests. * @param componentDelegate The {@link PasswordCheckComponentUi} delegate.
*/ */
interface ComponentFactory { void setComponentDelegate(PasswordCheckComponentUi componentDelegate) {
/** mComponentDelegate = componentDelegate;
* Returns a component that is connected to the given fragment and manipulates its data.
* @param fragmentView The fragment (usually {@code this}).
* @return A non-null {@link PasswordCheckComponentUi}.
*/
PasswordCheckComponentUi create(PreferenceFragmentCompat fragmentView);
} }
private static ComponentFactory sComponentFactory = PasswordCheckComponentUiFactory::create;
@Override @Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
...@@ -38,12 +30,6 @@ public class PasswordCheckFragmentView extends PreferenceFragmentCompat { ...@@ -38,12 +30,6 @@ public class PasswordCheckFragmentView extends PreferenceFragmentCompat {
setPreferenceScreen(getPreferenceManager().createPreferenceScreen(getStyledContext())); setPreferenceScreen(getPreferenceManager().createPreferenceScreen(getStyledContext()));
} }
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mComponentDelegate = sComponentFactory.create(this);
}
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
return mComponentDelegate.handleHelp(item); return mComponentDelegate.handleHelp(item);
...@@ -53,8 +39,4 @@ public class PasswordCheckFragmentView extends PreferenceFragmentCompat { ...@@ -53,8 +39,4 @@ public class PasswordCheckFragmentView extends PreferenceFragmentCompat {
return getPreferenceManager().getContext(); return getPreferenceManager().getContext();
} }
@VisibleForTesting
static void setComponentFactory(ComponentFactory factory) {
sComponentFactory = factory;
}
} }
\ No newline at end of file
...@@ -77,8 +77,9 @@ public class PasswordCheckViewTest { ...@@ -77,8 +77,9 @@ public class PasswordCheckViewTest {
@Before @Before
public void setUp() throws InterruptedException { public void setUp() throws InterruptedException {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
PasswordCheckFragmentView.setComponentFactory(fragmentView -> { PasswordCheckComponentUiFactory.setCreationStrategy(fragmentView -> {
mPasswordCheckView = (PasswordCheckFragmentView) fragmentView; mPasswordCheckView = (PasswordCheckFragmentView) fragmentView;
mPasswordCheckView.setComponentDelegate(mComponentUi);
return mComponentUi; return mComponentUi;
}); });
mTestRule.startSettingsActivity(); mTestRule.startSettingsActivity();
......
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