Commit 03cf97f6 authored by Ted Choc's avatar Ted Choc Committed by Commit Bot

Convert omnibox suggestion list to an MVC component.

This simplifies "some" of the dependencies from the
AutocompleteCoordinator to the list view itself.  The
key handling is going to get a bit gnarly, but this
is closer to being able to move the bulk of the coordinator
into the existing AutocompleteMediator.

NOPRESUBMIT=true
BUG=898522

Change-Id: I71f6458220d4ba48c80db4aa18a3e78fe910872e
Reviewed-on: https://chromium-review.googlesource.com/c/1316832
Commit-Queue: Ted Choc <tedchoc@chromium.org>
Reviewed-by: default avatarPedro Amaral <amaralp@chromium.org>
Cr-Commit-Position: refs/heads/master@{#605818}
parent f25e13c0
......@@ -166,11 +166,6 @@ public class LocationBarLayout extends FrameLayout
return mIsTablet;
}
@Override
public boolean isIncognito() {
return mToolbarDataProvider.isIncognito();
}
@Override
public WindowDelegate getWindowDelegate() {
return mWindowDelegate;
......@@ -371,7 +366,6 @@ public class LocationBarLayout extends FrameLayout
* @return Whether the URL focus change is taking place, e.g. a focus animation is running on
* a phone device.
*/
@Override
public boolean isUrlFocusChangeInProgress() {
return mUrlFocusChangeInProgress;
}
......
......@@ -15,7 +15,6 @@ import android.util.TypedValue;
import android.view.View;
import android.widget.TextView;
import org.chromium.base.Callback;
import org.chromium.base.ThreadUtils;
import org.chromium.base.VisibleForTesting;
import org.chromium.chrome.R;
......@@ -42,7 +41,7 @@ import java.util.Map;
class AutocompleteMediator implements OnSuggestionsReceivedListener {
private final Context mContext;
private final UrlBarEditingTextStateProvider mUrlBarEditingTextProvider;
private final Callback<List<PropertyModel>> mModelsChangedCallback;
private final PropertyModel mListPropertyModel;
private final List<Pair<OmniboxSuggestion, PropertyModel>> mCurrentModels;
private final Map<String, List<PropertyModel>> mPendingAnswerRequestUrls;
private final AnswersImageFetcher mImageFetcher;
......@@ -54,10 +53,10 @@ class AutocompleteMediator implements OnSuggestionsReceivedListener {
private boolean mPreventSuggestionListPropertyChanges;
public AutocompleteMediator(Context context, UrlBarEditingTextStateProvider textProvider,
Callback<List<PropertyModel>> onModelsChanged) {
PropertyModel listPropertyModel) {
mContext = context;
mUrlBarEditingTextProvider = textProvider;
mModelsChangedCallback = onModelsChanged;
mListPropertyModel = listPropertyModel;
mCurrentModels = new ArrayList<>();
mPendingAnswerRequestUrls = new HashMap<>();
mImageFetcher = new AnswersImageFetcher();
......@@ -113,7 +112,7 @@ class AutocompleteMediator implements OnSuggestionsReceivedListener {
if (mPreventSuggestionListPropertyChanges) return;
List<PropertyModel> models = new ArrayList<>(mCurrentModels.size());
for (int i = 0; i < mCurrentModels.size(); i++) models.add(mCurrentModels.get(i).second);
mModelsChangedCallback.onResult(models);
mListPropertyModel.set(SuggestionListProperties.SUGGESTION_MODELS, models);
}
private void populateModelForSuggestion(
......@@ -425,6 +424,7 @@ class AutocompleteMediator implements OnSuggestionsReceivedListener {
*/
public void setUseDarkColors(boolean useDarkColors) {
mUseDarkColors = useDarkColors;
mListPropertyModel.set(SuggestionListProperties.USE_DARK_BACKGROUND, !useDarkColors);
for (int i = 0; i < mCurrentModels.size(); i++) {
PropertyModel model = mCurrentModels.get(i).second;
model.set(SuggestionViewProperties.USE_DARK_COLORS, mUseDarkColors);
......
......@@ -8,7 +8,6 @@ import android.content.Context;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.support.annotation.Nullable;
import android.support.v4.view.ViewCompat;
import android.view.View;
......@@ -29,18 +28,17 @@ import java.util.ArrayList;
*/
@VisibleForTesting
public class OmniboxSuggestionsList extends ListView {
private static final int OMNIBOX_RESULTS_BG_COLOR = 0xFFFFFFFF;
private static final int OMNIBOX_INCOGNITO_RESULTS_BG_COLOR = 0xFF3C4043;
private final OmniboxSuggestionListEmbedder mEmbedder;
private final View mAnchorView;
private final View mAlignmentView;
private static final int LIGHT_BG_COLOR = 0xFFFFFFFF;
private static final int DARK_BG_COLOR = 0xFF3C4043;
private final int[] mTempPosition = new int[2];
private final Rect mTempRect = new Rect();
private final OnGlobalLayoutListener mAnchorViewLayoutListener;
private final OnLayoutChangeListener mAlignmentViewLayoutListener;
private OmniboxSuggestionListEmbedder mEmbedder;
private View mAnchorView;
private View mAlignmentView;
private OnGlobalLayoutListener mAnchorViewLayoutListener;
private OnLayoutChangeListener mAlignmentViewLayoutListener;
/**
* Provides the capabilities required to embed the omnibox suggestion list into the UI.
......@@ -62,20 +60,14 @@ public class OmniboxSuggestionsList extends ListView {
/** Return whether the suggestions are being rendered in the tablet UI. */
boolean isTablet();
/** Return whether the current state is viewing incognito. */
boolean isIncognito();
}
/**
* Constructs a new list designed for containing omnibox suggestions.
* @param context Context used for contained views.
* @param embedder The embedder for the omnibox list providing access to external views and
* services.
*/
public OmniboxSuggestionsList(Context context, OmniboxSuggestionListEmbedder embedder) {
public OmniboxSuggestionsList(Context context) {
super(context, null, android.R.attr.dropDownListViewStyle);
mEmbedder = embedder;
setDivider(null);
setFocusable(true);
setFocusableInTouchMode(true);
......@@ -83,9 +75,12 @@ public class OmniboxSuggestionsList extends ListView {
int paddingBottom = context.getResources().getDimensionPixelOffset(
R.dimen.omnibox_suggestion_list_padding_bottom);
ViewCompat.setPaddingRelative(this, 0, 0, 0, paddingBottom);
}
refreshPopupBackground();
/** Set the embedder for the list view. */
void setEmbedder(OmniboxSuggestionListEmbedder embedder) {
assert mEmbedder == null;
mEmbedder = embedder;
mAnchorView = mEmbedder.getAnchorView();
// Prior to Android M, the contextual actions associated with the omnibox were anchored to
// the top of the screen and not a floating copy/paste menu like on newer versions. As a
......@@ -146,19 +141,8 @@ public class OmniboxSuggestionsList extends ListView {
/**
* Update the suggestion popup background to reflect the current state.
*/
void refreshPopupBackground() {
setBackground(getSuggestionPopupBackground());
}
/**
* @return The background for the omnibox suggestions popup.
*/
private Drawable getSuggestionPopupBackground() {
int omniboxResultsColorForNonIncognito = OMNIBOX_RESULTS_BG_COLOR;
int omniboxResultsColorForIncognito = OMNIBOX_INCOGNITO_RESULTS_BG_COLOR;
int color = mEmbedder.isIncognito() ? omniboxResultsColorForIncognito
: omniboxResultsColorForNonIncognito;
void refreshPopupBackground(boolean useDarkBackground) {
int color = useDarkBackground ? DARK_BG_COLOR : LIGHT_BG_COLOR;
if (!isHardwareAccelerated()) {
// When HW acceleration is disabled, changing mSuggestionList' items somehow erases
// mOmniboxResultsContainer' background from the area not covered by mSuggestionList.
......@@ -169,7 +153,7 @@ public class OmniboxSuggestionsList extends ListView {
color = Color.argb(254, Color.red(color), Color.green(color), Color.blue(color));
}
}
return new ColorDrawable(color);
setBackground(new ColorDrawable(color));
}
@Override
......
// Copyright 2018 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.omnibox.suggestions;
import org.chromium.chrome.browser.modelutil.PropertyKey;
import org.chromium.chrome.browser.modelutil.PropertyModel;
import org.chromium.chrome.browser.modelutil.PropertyModel.WritableBooleanPropertyKey;
import org.chromium.chrome.browser.modelutil.PropertyModel.WritableObjectPropertyKey;
import org.chromium.chrome.browser.omnibox.suggestions.OmniboxSuggestionsList.OmniboxSuggestionListEmbedder;
import java.util.List;
/**
* The properties controlling the state of the list of suggestion items.
*/
public class SuggestionListProperties {
/** Whether the suggestion list is visible. */
public static final WritableBooleanPropertyKey VISIBLE = new WritableBooleanPropertyKey();
/** The embedder for the suggestion list. */
public static final WritableObjectPropertyKey<OmniboxSuggestionListEmbedder> EMBEDDER =
new WritableObjectPropertyKey<>();
/** The list of models controlling the state of the suggestion items. */
public static final WritableObjectPropertyKey<List<PropertyModel>> SUGGESTION_MODELS =
new WritableObjectPropertyKey<>();
/** Whether the suggestion list should have a dark background. */
public static final WritableBooleanPropertyKey USE_DARK_BACKGROUND =
new WritableBooleanPropertyKey();
public static final PropertyKey[] ALL_KEYS =
new PropertyKey[] {VISIBLE, EMBEDDER, SUGGESTION_MODELS, USE_DARK_BACKGROUND};
}
// Copyright 2018 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.omnibox.suggestions;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewStub;
import org.chromium.base.StrictModeContext;
import org.chromium.base.Supplier;
import org.chromium.chrome.browser.modelutil.PropertyKey;
import org.chromium.chrome.browser.modelutil.PropertyModel;
import org.chromium.chrome.browser.omnibox.suggestions.OmniboxSuggestionsList.OmniboxSuggestionListEmbedder;
import org.chromium.ui.UiUtils;
/**
* Handles property updates to the suggestion list component.
*/
class SuggestionListViewBinder {
/**
* Holds the view components needed to renderer the suggestion list.
*/
public static class SuggestionListViewHolder {
public final Context context;
public final Supplier<ViewStub> containerStubSupplier;
public final OmniboxResultsAdapter adapter;
OmniboxSuggestionsList mListView;
ViewGroup mContainer;
public SuggestionListViewHolder(Context context, Supplier<ViewStub> containerStubSupplier,
OmniboxResultsAdapter adapter) {
this.context = context;
this.containerStubSupplier = containerStubSupplier;
this.adapter = adapter;
}
}
/**
* @see
* org.chromium.chrome.browser.modelutil.PropertyModelChangeProcessor.ViewBinder#bind(Object,
* Object, Object)
*/
public static void bind(
PropertyModel model, SuggestionListViewHolder view, PropertyKey propertyKey) {
if (SuggestionListProperties.VISIBLE.equals(propertyKey)) {
boolean visible = model.get(SuggestionListProperties.VISIBLE);
if (visible) {
if (view.mContainer == null) {
view.mContainer = (ViewGroup) view.containerStubSupplier.get().inflate();
}
initializeSuggestionList(view, model);
view.mContainer.setVisibility(View.VISIBLE);
if (view.mListView.getParent() == null) view.mContainer.addView(view.mListView);
view.mListView.show();
} else {
if (view.mContainer == null) return;
view.mListView.setVisibility(View.GONE);
UiUtils.removeViewFromParent(view.mListView);
view.mContainer.setVisibility(View.INVISIBLE);
}
} else if (SuggestionListProperties.EMBEDDER.equals(propertyKey)) {
if (view.mListView == null) return;
view.mListView.setEmbedder(model.get(SuggestionListProperties.EMBEDDER));
} else if (SuggestionListProperties.SUGGESTION_MODELS.equals(propertyKey)) {
view.adapter.updateSuggestions(model.get(SuggestionListProperties.SUGGESTION_MODELS));
} else if (SuggestionListProperties.USE_DARK_BACKGROUND.equals(propertyKey)) {
if (view.mListView == null) return;
view.mListView.refreshPopupBackground(
model.get(SuggestionListProperties.USE_DARK_BACKGROUND));
}
}
private static void initializeSuggestionList(
SuggestionListViewHolder view, PropertyModel model) {
if (view.mListView != null) return;
// TODO(tedchoc): Investigate lazily building the suggestion list off of the UI thread.
try (StrictModeContext unused = StrictModeContext.allowDiskReads()) {
view.mListView = new OmniboxSuggestionsList(view.context);
}
// Start with visibility GONE to ensure that show() is called. http://crbug.com/517438
view.mListView.setVisibility(View.GONE);
view.mListView.setAdapter(view.adapter);
view.mListView.setClipToPadding(false);
OmniboxSuggestionListEmbedder embedder = model.get(SuggestionListProperties.EMBEDDER);
if (embedder != null) view.mListView.setEmbedder(embedder);
view.mListView.refreshPopupBackground(
model.get(SuggestionListProperties.USE_DARK_BACKGROUND));
}
}
......@@ -1105,6 +1105,8 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestion.java",
"java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsList.java",
"java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionAnswer.java",
"java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionListProperties.java",
"java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionListViewBinder.java",
"java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionView.java",
"java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionViewProperties.java",
"java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionViewViewBinder.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