author | Allison Naaktgeboren <ally@mozilla.com> |
Tue, 01 Sep 2015 15:32:33 -0700 | |
changeset 260404 | 5183c511ce583ee0ea00a6e057b2fa092a871290 |
parent 260396 | d9753d7da8dfaf7583bf777ed6ee5535cb9b4393 |
child 260405 | 26b367ff0033d5730f4cd66930a3866eb3c89994 |
push id | 29310 |
push user | cbook@mozilla.com |
push date | Wed, 02 Sep 2015 11:34:07 +0000 |
treeherder | mozilla-central@fb805e859b4a [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mcomella |
bugs | 1189719 |
milestone | 43.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/mobile/android/base/db/BrowserContract.java +++ b/mobile/android/base/db/BrowserContract.java @@ -470,16 +470,17 @@ public class BrowserContract { } @RobocopTarget public static final class SearchHistory implements CommonColumns, HistoryColumns { private SearchHistory() {} public static final String CONTENT_TYPE = "vnd.android.cursor.dir/searchhistory"; public static final String QUERY = "query"; + public static final String DATE = "date"; public static final String TABLE_NAME = "searchhistory"; public static final Uri CONTENT_URI = Uri.withAppendedPath(SEARCH_HISTORY_AUTHORITY_URI, "searchhistory"); } @RobocopTarget public static final class SuggestedSites implements CommonColumns, URLColumns { private SuggestedSites() {}
--- a/mobile/android/base/home/BrowserSearch.java +++ b/mobile/android/base/home/BrowserSearch.java @@ -906,17 +906,17 @@ public class BrowserSearch extends HomeF final SearchEngineRow row = (SearchEngineRow) view; row.setOnUrlOpenListener(mUrlOpenListener); row.setOnSearchListener(mSearchListener); row.setOnEditSuggestionListener(mEditSuggestionListener); row.setSearchTerm(mSearchTerm); final SearchEngine engine = mSearchEngines.get(position); final boolean animate = (mAnimateSuggestions && engine.hasSuggestions()); - row.updateFromSearchEngine(engine, animate); + row.updateSuggestions(mSuggestionsEnabled, engine, mSearchTerm, animate); if (animate) { // Only animate suggestions the first time they are shown mAnimateSuggestions = false; } } else { // Account for the search engines position -= getPrimaryEngineCount();
--- a/mobile/android/base/home/SearchEngineRow.java +++ b/mobile/android/base/home/SearchEngineRow.java @@ -1,26 +1,29 @@ /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.gecko.home; +import org.mozilla.gecko.db.BrowserContract.SearchHistory; import org.mozilla.gecko.R; import org.mozilla.gecko.Telemetry; import org.mozilla.gecko.TelemetryContract; import org.mozilla.gecko.home.BrowserSearch.OnEditSuggestionListener; import org.mozilla.gecko.home.BrowserSearch.OnSearchListener; import org.mozilla.gecko.home.HomePager.OnUrlOpenListener; import org.mozilla.gecko.util.StringUtils; import org.mozilla.gecko.widget.AnimatedHeightLayout; import org.mozilla.gecko.widget.FaviconView; import org.mozilla.gecko.widget.FlowLayout; +import android.database.Cursor; +import android.content.ContentResolver; import android.content.Context; import android.util.AttributeSet; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.animation.AlphaAnimation; import android.widget.ImageView; import android.widget.LinearLayout; @@ -128,17 +131,20 @@ class SearchEngineRow extends AnimatedHe mSearchEngine.name, suggestion)); } private String getSuggestionTextFromView(View v) { final TextView suggestionText = (TextView) v.findViewById(R.id.suggestion_text); return suggestionText.getText().toString(); } - private void setSuggestionOnView(View v, String suggestion) { + private void setSuggestionOnView(View v, String suggestion, boolean isUserSavedSearch) { + final ImageView historyIcon = (ImageView) v.findViewById(R.id.suggestion_item_icon); + historyIcon.setVisibility(isUserSavedSearch ? View.VISIBLE: View.GONE); + final TextView suggestionText = (TextView) v.findViewById(R.id.suggestion_text); suggestionText.setText(suggestion); setDescriptionOnSuggestion(suggestionText, suggestion); } /** * Perform a search for the user-entered term. */ @@ -167,74 +173,119 @@ class SearchEngineRow extends AnimatedHe public void setOnSearchListener(OnSearchListener listener) { mSearchListener = listener; } public void setOnEditSuggestionListener(OnEditSuggestionListener listener) { mEditSuggestionListener = listener; } - public void updateFromSearchEngine(SearchEngine searchEngine, boolean animate) { + private void bindSuggestionView(String suggestion, boolean animate, int recycledSuggestionCount, Integer previousSuggestionChildIndex, boolean isUserSavedSearch){ + final View suggestionItem; + + // Reuse suggestion views from recycled view, if possible. + if (previousSuggestionChildIndex + 1 < recycledSuggestionCount) { + suggestionItem = mSuggestionView.getChildAt(previousSuggestionChildIndex + 1); + suggestionItem.setVisibility(View.VISIBLE); + } else { + suggestionItem = mInflater.inflate(R.layout.suggestion_item, null); + + suggestionItem.setOnClickListener(mClickListener); + suggestionItem.setOnLongClickListener(mLongClickListener); + + // Store the position of the suggestion for telemetry. + suggestionItem.setTag(String.valueOf(previousSuggestionChildIndex)); + + mSuggestionView.addView(suggestionItem); + } + + setSuggestionOnView(suggestionItem, suggestion, isUserSavedSearch); + + if (animate) { + AlphaAnimation anim = new AlphaAnimation(0, 1); + anim.setDuration(ANIMATION_DURATION); + anim.setStartOffset(previousSuggestionChildIndex * ANIMATION_DURATION); + suggestionItem.startAnimation(anim); + } + } + + private void hideRecycledSuggestions(int lastVisibleChildIndex, int recycledSuggestionCount) { + // Hide extra suggestions that have been recycled. + for (int i = lastVisibleChildIndex + 1; i < recycledSuggestionCount; ++i) { + mSuggestionView.getChildAt(i).setVisibility(View.GONE); + } + } + + private void updateFromSavedSearches(String searchTerm, boolean animate, int suggestionCounter, int recycledSuggestionCount) { + final ContentResolver cr = getContext().getContentResolver(); + + String[] columns = new String[] { SearchHistory.QUERY }; + String sortOrderAndLimit = SearchHistory.DATE + " DESC"; + + final Cursor c = cr.query(SearchHistory.CONTENT_URI, columns, null, null, sortOrderAndLimit); + if (c == null) { + return; + } + try { + if (c.moveToFirst()) { + int counter = 0; + final int searchColumn = c.getColumnIndexOrThrow(SearchHistory.QUERY); + do { + final String savedSearch = c.getString(searchColumn); + if (counter == 4) { + break; + } + // Bug 1200371 will move the filtering/matching and limit into the sql query + if (savedSearch.startsWith(searchTerm)) { + bindSuggestionView(savedSearch, animate, recycledSuggestionCount, suggestionCounter, true); + ++suggestionCounter; + ++counter; + } + } while (c.moveToNext()); + } + } finally { + c.close(); + } + hideRecycledSuggestions(suggestionCounter, recycledSuggestionCount); + } + + private int updateFromSearchEngine(SearchEngine searchEngine, boolean animate, int recycledSuggestionCount) { // Update search engine reference. mSearchEngine = searchEngine; // Set the search engine icon (e.g., Google) for the row. mIconView.updateAndScaleImage(mSearchEngine.getIcon(), mSearchEngine.getEngineIdentifier()); // Set the initial content description. setDescriptionOnSuggestion(mUserEnteredTextView, mUserEnteredTextView.getText().toString()); - // Add additional suggestions given by this engine. - final int recycledSuggestionCount = mSuggestionView.getChildCount(); - int suggestionCounter = 0; + // Apply Search Engine's suggestions for (String suggestion : mSearchEngine.getSuggestions()) { - final View suggestionItem; - - // Reuse suggestion views from recycled view, if possible. - if (suggestionCounter + 1 < recycledSuggestionCount) { - suggestionItem = mSuggestionView.getChildAt(suggestionCounter + 1); - suggestionItem.setVisibility(View.VISIBLE); - } else { - suggestionItem = mInflater.inflate(R.layout.suggestion_item, null); - - suggestionItem.setOnClickListener(mClickListener); - suggestionItem.setOnLongClickListener(mLongClickListener); - - // Store the position of the suggestion for telemetry. - suggestionItem.setTag(String.valueOf(suggestionCounter)); - - final ImageView magnifier = - (ImageView) suggestionItem.findViewById(R.id.suggestion_magnifier); - magnifier.setVisibility(View.GONE); - - mSuggestionView.addView(suggestionItem); - } - - setSuggestionOnView(suggestionItem, suggestion); - - if (animate) { - AlphaAnimation anim = new AlphaAnimation(0, 1); - anim.setDuration(ANIMATION_DURATION); - anim.setStartOffset(suggestionCounter * ANIMATION_DURATION); - suggestionItem.startAnimation(anim); - } - + bindSuggestionView(suggestion, animate, recycledSuggestionCount, suggestionCounter, false); ++suggestionCounter; } - // Hide extra suggestions that have been recycled. - for (int i = suggestionCounter + 1; i < recycledSuggestionCount; ++i) { - mSuggestionView.getChildAt(i).setVisibility(View.GONE); - } + hideRecycledSuggestions(suggestionCounter, recycledSuggestionCount); // Make sure mSelectedView is still valid. if (mSelectedView >= mSuggestionView.getChildCount()) { mSelectedView = mSuggestionView.getChildCount() - 1; } + + return suggestionCounter; + } + + public void updateSuggestions(boolean suggestionsEnabled, SearchEngine searchEngine, String searchTerm, boolean animate) { + // This can be called before the opt-in permission prompt is shown or set. Check first. + if (suggestionsEnabled) { + final int recycledSuggestionCount = mSuggestionView.getChildCount(); + final int suggestionViewCount = updateFromSearchEngine(searchEngine, animate, recycledSuggestionCount); + updateFromSavedSearches(searchTerm, animate, suggestionViewCount, recycledSuggestionCount); + } } @Override public boolean onKeyDown(int keyCode, android.view.KeyEvent event) { final View suggestion = mSuggestionView.getChildAt(mSelectedView); if (event.getAction() != android.view.KeyEvent.ACTION_DOWN) { return false;
--- a/mobile/android/base/resources/layout/suggestion_item.xml +++ b/mobile/android/base/resources/layout/suggestion_item.xml @@ -7,21 +7,22 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:background="@drawable/suggestion_selector" android:gravity="center_vertical" android:clickable="true" android:padding="7dp"> - <ImageView android:id="@+id/suggestion_magnifier" - android:src="@drawable/search_icon_inactive" + <ImageView android:id="@+id/suggestion_item_icon" + android:src="@drawable/icon_most_recent_empty" android:layout_marginRight="3dip" - android:layout_width="16dip" - android:layout_height="16dip"/> + android:layout_width="18dip" + android:layout_height="18dip" + android:visibility="gone"/> <TextView android:id="@+id/suggestion_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="@color/placeholder_active_grey" android:textSize="14sp" android:gravity="center_vertical" android:layout_gravity="center_vertical"/>