diff --git a/mobile/android/base/Makefile.in b/mobile/android/base/Makefile.in index d575b02da9bd..94b2f7db233e 100644 --- a/mobile/android/base/Makefile.in +++ b/mobile/android/base/Makefile.in @@ -234,6 +234,7 @@ FENNEC_JAVA_FILES = \ menu/MenuItemDefault.java \ menu/MenuPanel.java \ menu/MenuPopup.java \ + preferences/SearchPreferenceCategory.java \ widget/AboutHome.java \ widget/AboutHomeView.java \ widget/AboutHomeSection.java \ @@ -310,6 +311,7 @@ FENNEC_PP_JAVA_FILES = \ FENNEC_PP_XML_FILES = \ res/xml/preferences.xml \ + res/xml/preferences_customize.xml \ res/xml/searchable.xml \ $(NULL) @@ -573,14 +575,15 @@ RES_VALUES_V14 = \ $(NULL) RES_XML = \ - res/xml/preferences_customize.xml \ res/xml/preferences_display.xml \ + res/xml/preferences_search.xml \ res/xml/preferences_privacy.xml \ res/xml/preferences_vendor.xml \ $(SYNC_RES_XML) \ $(NULL) RES_XML_V11 = \ + res/xml-v11/preferences_customize.xml \ res/xml-v11/preference_headers.xml \ res/xml-v11/preferences_customize_tablet.xml \ res/xml-v11/preferences.xml \ diff --git a/mobile/android/base/locales/en-US/android_strings.dtd b/mobile/android/base/locales/en-US/android_strings.dtd index de7b3db80474..aeadc707ebf2 100644 --- a/mobile/android/base/locales/en-US/android_strings.dtd +++ b/mobile/android/base/locales/en-US/android_strings.dtd @@ -68,10 +68,12 @@ + + diff --git a/mobile/android/base/preferences/SearchPreferenceCategory.java b/mobile/android/base/preferences/SearchPreferenceCategory.java new file mode 100644 index 000000000000..313787485912 --- /dev/null +++ b/mobile/android/base/preferences/SearchPreferenceCategory.java @@ -0,0 +1,89 @@ +package org.mozilla.gecko.preferences; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.os.Build; +import android.preference.Preference; +import android.preference.PreferenceCategory; +import android.util.AttributeSet; +import android.util.Log; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.mozilla.gecko.GeckoAppShell; +import org.mozilla.gecko.GeckoEvent; +import org.mozilla.gecko.R; +import org.mozilla.gecko.gfx.BitmapUtils; +import org.mozilla.gecko.util.GeckoEventListener; + +public class SearchPreferenceCategory extends PreferenceCategory implements GeckoEventListener { + public static final String LOGTAG = "SearchPrefCategory"; + + private static int sIconSize; + + public SearchPreferenceCategory(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(); + } + public SearchPreferenceCategory(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + public SearchPreferenceCategory(Context context) { + super(context); + init(); + } + + private void init() { + sIconSize = getContext().getResources().getDimensionPixelSize(R.dimen.searchpreferences_icon_size); + } + + @Override + protected void onAttachedToActivity() { + super.onAttachedToActivity(); + + // Request list of search engines from Gecko + GeckoAppShell.registerEventListener("SearchEngines:Data", this); + GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("SearchEngines:Get", null)); + } + + @Override + public void handleMessage(String event, final JSONObject data) { + if (event.equals("SearchEngines:Data")) { + JSONArray engines; + try { + engines = data.getJSONArray("searchEngines"); + } catch (JSONException e) { + Log.e(LOGTAG, "Unable to decode search engine data from Gecko.", e); + return; + } + + // Create an element in this PreferenceCategory for each engine. + for (int i = 0; i < engines.length(); i++) { + try { + JSONObject engineJSON = engines.getJSONObject(i); + final String engineName = engineJSON.getString("name"); + + Preference engine = new Preference(getContext()); + engine.setTitle(engineName); + engine.setKey(engineName); + + // The setIcon feature is not available prior to API 11. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { + String iconURI = engineJSON.getString("iconURI"); + Bitmap iconBitmap = BitmapUtils.getBitmapFromDataURI(iconURI); + Bitmap scaledIconBitmap = Bitmap.createScaledBitmap(iconBitmap, sIconSize, sIconSize, false); + BitmapDrawable drawable = new BitmapDrawable(scaledIconBitmap); + engine.setIcon(drawable); + } + addPreference(engine); + // TODO: Bug 892113 - Add event listener here for tapping on each element. Produce a dialog to provide options. + } catch (JSONException e) { + Log.e(LOGTAG, "JSONException parsing engine at index " + i, e); + } + } + } + } +} diff --git a/mobile/android/base/resources/values/dimens.xml b/mobile/android/base/resources/values/dimens.xml index 592d6278a904..8d9670aa1b40 100644 --- a/mobile/android/base/resources/values/dimens.xml +++ b/mobile/android/base/resources/values/dimens.xml @@ -61,6 +61,7 @@ 48dp 64dp 26dp + 32dp 90dp 160dp 22sp diff --git a/mobile/android/base/resources/xml/preferences_customize.xml b/mobile/android/base/resources/xml-v11/preferences_customize.xml similarity index 85% rename from mobile/android/base/resources/xml/preferences_customize.xml rename to mobile/android/base/resources/xml-v11/preferences_customize.xml index a1494da03d12..3898b575ba7e 100644 --- a/mobile/android/base/resources/xml/preferences_customize.xml +++ b/mobile/android/base/resources/xml-v11/preferences_customize.xml @@ -7,6 +7,12 @@ xmlns:gecko="http://schemas.android.com/apk/res-auto" android:enabled="false"> + + + + - - + + + + - + + + + + + + + + + + + + + + + + + diff --git a/mobile/android/base/resources/xml/preferences_search.xml b/mobile/android/base/resources/xml/preferences_search.xml new file mode 100644 index 000000000000..721aefbfda00 --- /dev/null +++ b/mobile/android/base/resources/xml/preferences_search.xml @@ -0,0 +1,18 @@ + + + + + + + + + diff --git a/mobile/android/base/strings.xml.in b/mobile/android/base/strings.xml.in index efa1ec131cfb..428dc4e223ec 100644 --- a/mobile/android/base/strings.xml.in +++ b/mobile/android/base/strings.xml.in @@ -80,10 +80,12 @@ &settings; &settings_title; &pref_category_customize; + &pref_category_search; &pref_category_display; &pref_category_privacy_short; &pref_category_vendor; &pref_category_datareporting; + &pref_category_installed_search_engines; &pref_header_customize; &pref_header_display; diff --git a/mobile/android/base/tests/testSettingsMenuItems.java.in b/mobile/android/base/tests/testSettingsMenuItems.java.in index fc0165a791f7..b0e25d05ef94 100644 --- a/mobile/android/base/tests/testSettingsMenuItems.java.in +++ b/mobile/android/base/tests/testSettingsMenuItems.java.in @@ -24,8 +24,9 @@ public class testSettingsMenuItems extends PixelTest { // // This test assumes menu items are in order (scrolling down for off-screen items). String[][] OPTIONS_CUSTOMIZE = { + { "Search", "", "Show search suggestions", "Installed search engines" }, { "Import from Android", "", "Bookmarks", "History", "Import" }, - { "Show search suggestions" }, + { "Always restore tabs" }, { "Automatic updates", "Only over Wi-Fi", "Enabled", "Only over Wi-Fi", "Disabled" }, }; @@ -163,8 +164,12 @@ public class testSettingsMenuItems extends PixelTest { "The " + itemChoice + " choice is present in section " + section); } // Leave submenu after checking. - waitForText("^Cancel$"); - mSolo.clickOnText("^Cancel$"); + if (waitForText("^Cancel$")) { + mSolo.clickOnText("^Cancel$"); + } else { + // Some submenus aren't dialogs, but are nested screens; exit using "back". + mActions.sendSpecialKey(Actions.SpecialKey.BACK); + } } } // Navigate back a screen if on a phone.