Bug 1022105 - Support a menu and settings. r=liuche,margaret
authorEric Edens <eedens@mozilla.com>
Fri, 25 Jul 2014 15:45:10 -0700
changeset 196503 72cf0099adb6e80346e9f504ffa0da6d8f1274ce
parent 196502 571e039d0de08a7c50f6d173c5ef4f820f850fb4
child 196504 877cd1bb991222fa8266d44acfe6e69ea14e2f0c
push id27216
push usercbook@mozilla.com
push dateTue, 29 Jul 2014 13:22:19 +0000
treeherdermozilla-central@32f22aa8d02d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersliuche, margaret
bugs1022105
milestone34.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
Bug 1022105 - Support a menu and settings. r=liuche,margaret
mobile/android/search/java/org/mozilla/search/PreSearchFragment.java
mobile/android/search/java/org/mozilla/search/SearchPreferenceActivity.java
mobile/android/search/manifests/SearchAndroidManifest_activities.xml.in
mobile/android/search/res/drawable-hdpi/ic_action_overflow.png
mobile/android/search/res/drawable-mdpi/ic_action_overflow.png
mobile/android/search/res/drawable-xhdpi/ic_action_overflow.png
mobile/android/search/res/layout/search_fragment_pre_search.xml
mobile/android/search/res/values-v13/search_styles.xml
mobile/android/search/res/values/search_styles.xml
mobile/android/search/res/xml/search_preferences.xml
mobile/android/search/search_activity_sources.mozbuild
mobile/android/search/strings/search_strings.dtd
mobile/android/search/strings/search_strings.xml.in
--- a/mobile/android/search/java/org/mozilla/search/PreSearchFragment.java
+++ b/mobile/android/search/java/org/mozilla/search/PreSearchFragment.java
@@ -1,15 +1,16 @@
 /* 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.search;
 
 import android.app.Activity;
+import android.content.Intent;
 import android.database.Cursor;
 import android.os.Bundle;
 import android.support.v4.app.Fragment;
 import android.support.v4.app.LoaderManager;
 import android.support.v4.content.CursorLoader;
 import android.support.v4.content.Loader;
 import android.support.v4.widget.SimpleCursorAdapter;
 import android.text.TextUtils;
@@ -71,32 +72,43 @@ public class PreSearchFragment extends F
         super.onDestroy();
         getLoaderManager().destroyLoader(LOADER_ID_SEARCH_HISTORY);
         cursorAdapter.swapCursor(null);
         cursorAdapter = null;
     }
 
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
-        listView = (ListView) inflater.inflate(R.layout.search_fragment_pre_search, container, false);
+        final View mainView = inflater.inflate(R.layout.search_fragment_pre_search, container, false);
+
+        // Initialize listview.
+        listView = (ListView) mainView.findViewById(R.id.list_view);
         listView.setAdapter(cursorAdapter);
         listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
             @Override
             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                 final Cursor c = cursorAdapter.getCursor();
                 if (c == null || !c.moveToPosition(position)) {
                     return;
                 }
                 final String query = c.getString(c.getColumnIndexOrThrow(SearchHistory.QUERY));
                 if (!TextUtils.isEmpty(query)) {
                     searchListener.onSearch(query);
                 }
             }
         });
-        return listView;
+
+        // Apply click handler to settings button.
+        mainView.findViewById(R.id.settings_button).setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                startActivity(new Intent(getActivity(), SearchPreferenceActivity.class));
+            }
+        });
+        return mainView;
     }
 
     @Override
     public void onDestroyView() {
         super.onDestroyView();
         listView.setAdapter(null);
         listView = null;
     }
new file mode 100644
--- /dev/null
+++ b/mobile/android/search/java/org/mozilla/search/SearchPreferenceActivity.java
@@ -0,0 +1,96 @@
+/* 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.search;
+
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.os.AsyncTask;
+import android.os.Build;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.util.Log;
+import android.widget.Toast;
+
+import org.mozilla.gecko.db.BrowserContract;
+
+/**
+ * This activity allows users to modify the settings for the search activity.
+ *
+ * A note on implementation: At the moment, we don't have tablet-specific designs.
+ * Therefore, this implementation uses the old-style PreferenceActivity. When
+ * we start optimizing for tablets, we can migrate to Fennec's PreferenceFragment
+ * implementation.
+ *
+ * TODO: Change this to PreferenceFragment when we stop supporting devices older than SDK 11.
+ */
+public class SearchPreferenceActivity extends PreferenceActivity {
+
+    private static final String LOGTAG = "SearchPreferenceActivity";
+
+    private static final String CLEAR_SEARCH_HISTORY_BUTTON_KEY = "clear_search_history_button";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+            if (getActionBar() != null) {
+                getActionBar().setDisplayHomeAsUpEnabled(true);
+            }
+        }
+    }
+
+    @Override
+    protected void onPostCreate(Bundle savedInstanceState) {
+        super.onPostCreate(savedInstanceState);
+        setupPrefsScreen();
+    }
+
+    @SuppressWarnings("deprecation")
+    private void setupPrefsScreen() {
+        addPreferencesFromResource(R.xml.search_preferences);
+
+        final Preference clearHistoryButton = findPreference(CLEAR_SEARCH_HISTORY_BUTTON_KEY);
+        clearHistoryButton.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
+            @Override
+            public boolean onPreferenceClick(Preference preference) {
+                final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(SearchPreferenceActivity.this);
+                dialogBuilder.setNegativeButton(android.R.string.cancel, null);
+                dialogBuilder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                        clearHistory();
+                    }
+                });
+                dialogBuilder.setMessage(R.string.search_pref_clear_history_dialog_message);
+                dialogBuilder.show();
+                return false;
+            }
+        });
+    }
+
+    private void clearHistory() {
+        final AsyncTask<Void, Void, Boolean> clearHistoryTask = new AsyncTask<Void, Void, Boolean>() {
+            @Override
+            protected Boolean doInBackground(Void... params) {
+                final int numDeleted = getContentResolver().delete(
+                        BrowserContract.SearchHistory.CONTENT_URI, null, null);
+                return numDeleted >= 0;
+            }
+
+            @Override
+            protected void onPostExecute(Boolean success) {
+                if (success) {
+                    getContentResolver().notifyChange(BrowserContract.SearchHistory.CONTENT_URI, null);
+                    Toast.makeText(SearchPreferenceActivity.this, SearchPreferenceActivity.this.getResources()
+                            .getString(R.string.search_pref_clear_history_confirmation), Toast.LENGTH_SHORT).show();
+                } else {
+                    Log.e(LOGTAG, "Error clearing search history.");
+                }
+            }
+        };
+        clearHistoryTask.execute();
+    }
+}
--- a/mobile/android/search/manifests/SearchAndroidManifest_activities.xml.in
+++ b/mobile/android/search/manifests/SearchAndroidManifest_activities.xml.in
@@ -1,20 +1,26 @@
         <activity
             android:name="org.mozilla.search.MainActivity"
             android:label="@string/search_app_name"
             android:theme="@style/AppTheme"
             android:screenOrientation="portrait">
-
-            <!-- Add this to activity declaration to hide keyboard on launch -->
-            <!-- android:windowSoftInputMode="stateHidden" -->
-
             <intent-filter>
                 <action android:name="android.intent.action.MAIN"/>
 
                 <category android:name="android.intent.category.LAUNCHER"/>
             </intent-filter>
             <intent-filter>
                 <action android:name="android.intent.action.ASSIST"/>
 
                 <category android:name="android.intent.category.DEFAULT"/>
             </intent-filter>
         </activity>
+
+        <activity
+            android:name="org.mozilla.search.SearchPreferenceActivity"
+            android:label="@string/search_pref_title"
+            android:parentActivityName="org.mozilla.search.MainActivity"
+            android:theme="@style/SettingsTheme" >
+            <meta-data
+                android:name="android.support.PARENT_ACTIVITY"
+                android:value="org.mozilla.search.MainActivity"/>
+        </activity>
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..002fc4bfbcc2642a760905df80f4cb9ddfb476f1
GIT binary patch
literal 225
zc%17D@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpTC$r9IylHmNblJdl&R0hYC{G?O`
z&)mfH)S%SFl*+=BsWw1G&7LlfAr-gYT-(dpU?9SfC@Ni@UeFk_YXb9*scVZ<xWo;)
zXE-VS`yksQ;&e#xNo*)1L&NhG?=4JPHY~}t_$`+_$NTQpn!l_Z0tz1rZ_Pe;*H^=X
zQ`515fl*UYRY7&#vLiFL*-aL@eY^gV=5?peB&KH!j7%*5ZaQU0%{Am^SpQrgfq~1C
W|A^-#t7f2c7(8A5T-G@yGywp04^8d>
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..6f0fb23f4d9a2bad32b82ee41e079395e27f51a3
GIT binary patch
literal 197
zc%17D@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz$r9IylHmNblJdl&R0hYC{G?O`
z&)mfH)S%SFl*+=BsWw1G>7Fi*Ar-fh5+qm`CoExhD>9Xmmj0b2Xjk^_&CTsgW*l~E
zd|bPs<1S0mB$)#y7Xl4lF?d}%psSN~-~F?x?disu5iQk?PY<lU7z324n##O4;>f(7
ru;Yube#|hFS=;A+P(wkKfklEL|BXbla<!H&&`JhRS3j3^P6<r_j^;-b
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..7ba4e10ea218fd516a1106a72e709b91c6bd359a
GIT binary patch
literal 267
zc%17D@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=k|nMYCBgY=CFO}lsSJ)O`AMk?
zp1FzXsX?iUDV2pMQ*D5X)_S@)hE&{ob8{o_Ap-%2z~)N^E>U71^deQFFCOCYe9Cx;
z?~TCbgQhAc>inHdrg6kO-8rer$iPtYqUa0zvpLIunX&chEuHf9`g!9y0)Kx$ecxF8
zURmzht>69*42&!SK*Fl*n8Fs8_Bm%4@NL<_cm81RhtTT}m+yCk$O4ImwrdaFYwt2W
zw___^aJ2Ns+kztN904Jyq~G<#?S~l{{xrrmFfuG?l@MES`qW0C!x=nX{an^LB{Ts5
D2LxpZ
--- a/mobile/android/search/res/layout/search_fragment_pre_search.xml
+++ b/mobile/android/search/res/layout/search_fragment_pre_search.xml
@@ -1,10 +1,27 @@
 <!-- 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/. -->
 
-<ListView
+<FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:divider="@null"
-    android:dividerHeight="0dp"/>
+    android:layout_height="match_parent">
+
+    <ListView
+        android:id="@+id/list_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:divider="@null"
+        android:dividerHeight="0dp"/>
+
+    <ImageButton
+        android:id="@+id/settings_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:background="@android:color/transparent"
+        android:padding="15dp"
+        android:src="@drawable/ic_action_overflow"
+        android:text="@string/search_settings_icon"
+        android:layout_gravity="bottom|right"/>
+
+</FrameLayout>
--- a/mobile/android/search/res/values-v13/search_styles.xml
+++ b/mobile/android/search/res/values-v13/search_styles.xml
@@ -5,9 +5,11 @@
 <resources>
 
     <!-- Base application theme. -->
     <style name="AppTheme" parent="@android:style/Theme.Holo.Light.NoActionBar">
         <item name="android:windowBackground">@color/global_background_color</item>
         <item name="android:colorBackground">@color/global_background_color</item>
     </style>
 
+    <style name="SettingsTheme" parent="@android:style/Theme.Holo.Light"/>
+
 </resources>
--- a/mobile/android/search/res/values/search_styles.xml
+++ b/mobile/android/search/res/values/search_styles.xml
@@ -5,9 +5,11 @@
 <resources>
 
     <!-- Base application theme. -->
     <style name="AppTheme" parent="@android:style/Theme.Light.NoTitleBar">
         <item name="android:windowBackground">@color/global_background_color</item>
         <item name="android:colorBackground">@color/global_background_color</item>
     </style>
 
+    <style name="SettingsTheme" parent="@android:style/Theme.Light"/>
+
 </resources>
new file mode 100644
--- /dev/null
+++ b/mobile/android/search/res/xml/search_preferences.xml
@@ -0,0 +1,9 @@
+<!-- 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/. -->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+    <Preference
+        android:key="clear_search_history_button"
+        android:title="@string/search_pref_clear_history_title"/>
+</PreferenceScreen>
--- a/mobile/android/search/search_activity_sources.mozbuild
+++ b/mobile/android/search/search_activity_sources.mozbuild
@@ -10,9 +10,10 @@ search_activity_sources = [
     'java/org/mozilla/search/autocomplete/AutoCompleteAdapter.java',
     'java/org/mozilla/search/autocomplete/ClearableEditText.java',
     'java/org/mozilla/search/autocomplete/SearchFragment.java',
     'java/org/mozilla/search/autocomplete/SuggestClient.java',
     'java/org/mozilla/search/Constants.java',
     'java/org/mozilla/search/MainActivity.java',
     'java/org/mozilla/search/PostSearchFragment.java',
     'java/org/mozilla/search/PreSearchFragment.java',
+    'java/org/mozilla/search/SearchPreferenceActivity.java',
 ]
--- a/mobile/android/search/strings/search_strings.dtd
+++ b/mobile/android/search/strings/search_strings.dtd
@@ -1,8 +1,14 @@
 <!-- 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/. -->
 
 <!ENTITY search_jump_arrow '&#8598;'>
+<!ENTITY search_settings_icon '&#8942;'>
+
 <!ENTITY search_app_name 'Firefox Search'>
-<!ENTITY search_header_image_content_description 'Firefox Search Header Image'>
 <!ENTITY search_for_something 'Search for something'>
+
+<!ENTITY search_pref_title 'Settings'>
+<!ENTITY search_pref_clear_history_confirmation 'History cleared'>
+<!ENTITY search_pref_clear_history_dialog_message 'Delete all search history from this device?'>
+<!ENTITY search_pref_clear_history_title 'Clear search history'>
--- a/mobile/android/search/strings/search_strings.xml.in
+++ b/mobile/android/search/strings/search_strings.xml.in
@@ -1,4 +1,10 @@
+    <string name="search_jump_arrow">&search_jump_arrow;</string>
+    <string name="search_settings_icon">&search_settings_icon;</string>
+
     <string name="search_app_name">&search_app_name;</string>
-    <string name="search_jump_arrow">&search_jump_arrow;</string>
-    <string name="search_header_image_content_description">&search_header_image_content_description;</string>
     <string name="search_for_something">&search_for_something;</string>
+
+    <string name="search_pref_title">&search_pref_title;</string>
+    <string name="search_pref_clear_history_confirmation">&search_pref_clear_history_confirmation;</string>
+    <string name="search_pref_clear_history_dialog_message">&search_pref_clear_history_dialog_message;</string>
+    <string name="search_pref_clear_history_title">&search_pref_clear_history_title;</string>