summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AndroidManifest.xml11
-rw-r--r--res/drawable-hdpi/ic_arrow_back_24dp.pngbin0 -> 2977 bytes
-rw-r--r--res/drawable-hdpi/ic_close_24dp.pngbin0 -> 3033 bytes
-rw-r--r--res/drawable-hdpi/ic_history_24dp.pngbin0 -> 4068 bytes
-rw-r--r--res/drawable-hdpi/ic_history_holo_light.pngbin749 -> 0 bytes
-rw-r--r--res/drawable-hdpi/ic_mic_24dp.pngbin0 -> 3243 bytes
-rw-r--r--res/drawable-mdpi/ic_arrow_back_24dp.pngbin0 -> 2884 bytes
-rw-r--r--res/drawable-mdpi/ic_close_24dp.pngbin0 -> 2937 bytes
-rw-r--r--res/drawable-mdpi/ic_history_24dp.pngbin0 -> 3480 bytes
-rw-r--r--res/drawable-mdpi/ic_history_holo_light.pngbin507 -> 0 bytes
-rw-r--r--res/drawable-mdpi/ic_mic_24dp.pngbin0 -> 3029 bytes
-rw-r--r--res/drawable-xhdpi/ic_arrow_back_24dp.pngbin0 -> 3017 bytes
-rw-r--r--res/drawable-xhdpi/ic_close_24dp.pngbin0 -> 3141 bytes
-rw-r--r--res/drawable-xhdpi/ic_history_24dp.pngbin0 -> 4360 bytes
-rw-r--r--res/drawable-xhdpi/ic_history_holo_light.pngbin916 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/ic_mic_24dp.pngbin0 -> 3416 bytes
-rw-r--r--res/drawable-xxhdpi/ic_arrow_back_24dp.pngbin0 -> 3152 bytes
-rw-r--r--res/drawable-xxhdpi/ic_close_24dp.pngbin0 -> 3316 bytes
-rw-r--r--res/drawable-xxhdpi/ic_history_24dp.pngbin0 -> 5270 bytes
-rw-r--r--res/drawable-xxhdpi/ic_history_holo_light.pngbin2915 -> 0 bytes
-rw-r--r--res/drawable-xxhdpi/ic_mic_24dp.pngbin0 -> 3804 bytes
-rw-r--r--res/drawable-xxxhdpi/ic_arrow_back_24dp.pngbin0 -> 3355 bytes
-rw-r--r--res/drawable-xxxhdpi/ic_close_24dp.pngbin0 -> 3504 bytes
-rw-r--r--res/drawable-xxxhdpi/ic_history_24dp.pngbin0 -> 6501 bytes
-rw-r--r--res/drawable-xxxhdpi/ic_mic_24dp.pngbin0 -> 4215 bytes
-rw-r--r--res/drawable/action_bar_shadow.xml (renamed from res/values-sw600dp-land/dimen.xml)12
-rw-r--r--res/layout/mail_actionbar_searchview.xml48
-rw-r--r--res/layout/one_pane_activity.xml13
-rw-r--r--res/layout/search_suggestion_item.xml47
-rw-r--r--res/layout/search_suggestion_list.xml54
-rw-r--r--res/layout/toolbar_with_search.xml33
-rw-r--r--res/layout/two_pane_activity.xml87
-rw-r--r--res/menu-sw600dp-land/conversation_actions.xml3
-rw-r--r--res/menu-sw600dp-land/conversation_list_search_results_actions.xml3
-rw-r--r--res/menu/conversation_list_menu.xml3
-rw-r--r--res/menu/conversation_list_search_results_actions.xml3
-rw-r--r--res/values-ldrtl/styles-ldrtl.xml7
-rw-r--r--res/values-sw600dp/themes.xml2
-rw-r--r--res/values/colors.xml3
-rw-r--r--res/values/dimen.xml4
-rw-r--r--res/values/strings.xml8
-rw-r--r--res/values/styles.xml10
-rw-r--r--res/values/themes.xml7
-rw-r--r--res/xml/searchable.xml28
-rw-r--r--src/com/android/mail/providers/SearchRecentSuggestionsProvider.java175
-rw-r--r--src/com/android/mail/providers/SuggestionsProvider.java19
-rw-r--r--src/com/android/mail/ui/AbstractActivityController.java54
-rw-r--r--src/com/android/mail/ui/ActionBarController.java152
-rw-r--r--src/com/android/mail/ui/ActivityController.java2
-rw-r--r--src/com/android/mail/ui/ControllableActivity.java3
-rw-r--r--src/com/android/mail/ui/ConversationListFragment.java1
-rw-r--r--src/com/android/mail/ui/FolderSelectionActivity.java9
-rw-r--r--src/com/android/mail/ui/MailActivity.java7
-rw-r--r--src/com/android/mail/ui/MaterialSearchActionView.java148
-rw-r--r--src/com/android/mail/ui/MaterialSearchSuggestionsList.java214
-rw-r--r--src/com/android/mail/ui/MaterialSearchViewController.java197
-rw-r--r--src/com/android/mail/ui/OnePaneController.java6
-rw-r--r--src/com/android/mail/ui/SearchActionBarController.java120
-rw-r--r--src/com/android/mail/ui/TwoPaneController.java9
-rw-r--r--src/com/android/mail/ui/settings/GeneralPrefsFragment.java9
-rw-r--r--unified_src/com/android/mail/providers/UnifiedAccountCacheProvider.java12
61 files changed, 951 insertions, 572 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index a8dd8d764..3c5b30e2d 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -43,7 +43,8 @@
android:label="@string/app_name"
android:name=".ui.MailActivity"
android:launchMode="singleTop"
- android:theme="@style/MailActivityTheme" >
+ android:theme="@style/MailActivityTheme"
+ android:windowSoftInputMode="stateHidden">
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
@@ -58,7 +59,6 @@
<action android:name="android.intent.action.SEARCH" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
- <meta-data android:name="android.app.searchable" android:resource="@xml/searchable" />
</activity>
<activity android:name=".compose.ComposeActivity"
android:theme="@style/ComposeTheme">
@@ -159,13 +159,6 @@
<grant-uri-permission android:pathPattern=".*" />
</provider>
- <!-- The android:name is the name of the Provider class which is stored in
- UnifiedEmail, and has package name com.android.mail.providers and the class is
- called SuggestionsProvider. The authority name is specified in the MailAppProvider
- which is specific to the two apps separately. -->
- <provider android:name="com.android.mail.providers.SuggestionsProvider"
- android:authorities="com.android.mail.suggestionsprovider" />
-
<service android:name=".compose.EmptyService"/>
<!-- Widget -->
diff --git a/res/drawable-hdpi/ic_arrow_back_24dp.png b/res/drawable-hdpi/ic_arrow_back_24dp.png
new file mode 100644
index 000000000..9b5f436f6
--- /dev/null
+++ b/res/drawable-hdpi/ic_arrow_back_24dp.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_close_24dp.png b/res/drawable-hdpi/ic_close_24dp.png
new file mode 100644
index 000000000..33db9eef6
--- /dev/null
+++ b/res/drawable-hdpi/ic_close_24dp.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_history_24dp.png b/res/drawable-hdpi/ic_history_24dp.png
new file mode 100644
index 000000000..b93e92940
--- /dev/null
+++ b/res/drawable-hdpi/ic_history_24dp.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_history_holo_light.png b/res/drawable-hdpi/ic_history_holo_light.png
deleted file mode 100644
index d3feeac20..000000000
--- a/res/drawable-hdpi/ic_history_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_mic_24dp.png b/res/drawable-hdpi/ic_mic_24dp.png
new file mode 100644
index 000000000..143ccc43a
--- /dev/null
+++ b/res/drawable-hdpi/ic_mic_24dp.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_arrow_back_24dp.png b/res/drawable-mdpi/ic_arrow_back_24dp.png
new file mode 100644
index 000000000..3a5800d1e
--- /dev/null
+++ b/res/drawable-mdpi/ic_arrow_back_24dp.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_close_24dp.png b/res/drawable-mdpi/ic_close_24dp.png
new file mode 100644
index 000000000..bd39f9332
--- /dev/null
+++ b/res/drawable-mdpi/ic_close_24dp.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_history_24dp.png b/res/drawable-mdpi/ic_history_24dp.png
new file mode 100644
index 000000000..76b0a9178
--- /dev/null
+++ b/res/drawable-mdpi/ic_history_24dp.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_history_holo_light.png b/res/drawable-mdpi/ic_history_holo_light.png
deleted file mode 100644
index 2b6eec4f5..000000000
--- a/res/drawable-mdpi/ic_history_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_mic_24dp.png b/res/drawable-mdpi/ic_mic_24dp.png
new file mode 100644
index 000000000..81d0c21ad
--- /dev/null
+++ b/res/drawable-mdpi/ic_mic_24dp.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_arrow_back_24dp.png b/res/drawable-xhdpi/ic_arrow_back_24dp.png
new file mode 100644
index 000000000..73395b0ac
--- /dev/null
+++ b/res/drawable-xhdpi/ic_arrow_back_24dp.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_close_24dp.png b/res/drawable-xhdpi/ic_close_24dp.png
new file mode 100644
index 000000000..81efb7040
--- /dev/null
+++ b/res/drawable-xhdpi/ic_close_24dp.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_history_24dp.png b/res/drawable-xhdpi/ic_history_24dp.png
new file mode 100644
index 000000000..61c0bfe34
--- /dev/null
+++ b/res/drawable-xhdpi/ic_history_24dp.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_history_holo_light.png b/res/drawable-xhdpi/ic_history_holo_light.png
deleted file mode 100644
index 83d61fa68..000000000
--- a/res/drawable-xhdpi/ic_history_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_mic_24dp.png b/res/drawable-xhdpi/ic_mic_24dp.png
new file mode 100644
index 000000000..1dcf56c4e
--- /dev/null
+++ b/res/drawable-xhdpi/ic_mic_24dp.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_arrow_back_24dp.png b/res/drawable-xxhdpi/ic_arrow_back_24dp.png
new file mode 100644
index 000000000..650351d06
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_arrow_back_24dp.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_close_24dp.png b/res/drawable-xxhdpi/ic_close_24dp.png
new file mode 100644
index 000000000..0924e29a2
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_close_24dp.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_history_24dp.png b/res/drawable-xxhdpi/ic_history_24dp.png
new file mode 100644
index 000000000..4fe0a7efe
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_history_24dp.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_history_holo_light.png b/res/drawable-xxhdpi/ic_history_holo_light.png
deleted file mode 100644
index b5e82bc69..000000000
--- a/res/drawable-xxhdpi/ic_history_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_mic_24dp.png b/res/drawable-xxhdpi/ic_mic_24dp.png
new file mode 100644
index 000000000..ce9890478
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_mic_24dp.png
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_arrow_back_24dp.png b/res/drawable-xxxhdpi/ic_arrow_back_24dp.png
new file mode 100644
index 000000000..8068c1b57
--- /dev/null
+++ b/res/drawable-xxxhdpi/ic_arrow_back_24dp.png
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_close_24dp.png b/res/drawable-xxxhdpi/ic_close_24dp.png
new file mode 100644
index 000000000..cb7a27ca8
--- /dev/null
+++ b/res/drawable-xxxhdpi/ic_close_24dp.png
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_history_24dp.png b/res/drawable-xxxhdpi/ic_history_24dp.png
new file mode 100644
index 000000000..420576b08
--- /dev/null
+++ b/res/drawable-xxxhdpi/ic_history_24dp.png
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_mic_24dp.png b/res/drawable-xxxhdpi/ic_mic_24dp.png
new file mode 100644
index 000000000..c586bb535
--- /dev/null
+++ b/res/drawable-xxxhdpi/ic_mic_24dp.png
Binary files differ
diff --git a/res/values-sw600dp-land/dimen.xml b/res/drawable/action_bar_shadow.xml
index 92359cbf0..32501171d 100644
--- a/res/values-sw600dp-land/dimen.xml
+++ b/res/drawable/action_bar_shadow.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright (C) 2012 Google Inc.
+ Copyright (C) 2014 Google Inc.
Licensed to The Android Open Source Project.
Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,6 +15,10 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<resources>
- <dimen name="search_view_width">500dip</dimen>
-</resources>
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <gradient
+ android:angle="270"
+ android:startColor="#3D000000"
+ android:endColor="#00000000" />
+</shape>
diff --git a/res/layout/mail_actionbar_searchview.xml b/res/layout/mail_actionbar_searchview.xml
index 730f1708a..b7bc1e662 100644
--- a/res/layout/mail_actionbar_searchview.xml
+++ b/res/layout/mail_actionbar_searchview.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright (C) 2011 Google Inc.
+ Copyright (C) 2014 Google Inc.
Licensed to The Android Open Source Project.
Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,12 +16,44 @@
limitations under the License.
-->
-<android.support.v7.widget.SearchView
+<com.android.mail.ui.MaterialSearchActionView
xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/search_layout"
- android:gravity="center_vertical"
- android:layout_height="match_parent"
+ android:id="@+id/search_actionbar_view"
android:layout_width="match_parent"
- android:hint="@string/search_hint"
- android:imeOptions="actionSearch"
- android:maxWidth="@dimen/search_view_width" />
+ android:layout_height="match_parent"
+ android:background="@android:color/white">
+
+ <ImageView
+ android:id="@+id/search_actionbar_back_button"
+ android:layout_width="@dimen/search_leading_button_width"
+ android:layout_height="match_parent"
+ android:background="?android:attr/selectableItemBackground"
+ android:src="@drawable/ic_arrow_back_24dp"
+ style="@style/SearchViewLeadingButton" />
+
+ <EditText
+ android:id="@+id/search_actionbar_query_text"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:background="@android:color/transparent"
+ android:gravity="center_vertical"
+ android:hint="@string/search_hint"
+ android:imeOptions="actionSearch|flagNoExtractUi"
+ android:inputType="text|textNoSuggestions"
+ android:singleLine="true"
+ android:textColor="@color/search_query_text"
+ android:textColorHint="@color/search_query_hint_text"
+ android:textSize="16sp" />
+
+ <ImageView
+ android:id="@+id/search_actionbar_ending_button"
+ android:layout_width="@dimen/search_ending_button_width"
+ android:layout_height="match_parent"
+ android:background="?android:attr/selectableItemBackground"
+ android:paddingLeft="16dp"
+ android:paddingRight="16dp"
+ android:scaleType="center"
+ android:src="@drawable/ic_mic_24dp" />
+
+</com.android.mail.ui.MaterialSearchActionView> \ No newline at end of file
diff --git a/res/layout/one_pane_activity.xml b/res/layout/one_pane_activity.xml
index 478edb9a9..40072a2a8 100644
--- a/res/layout/one_pane_activity.xml
+++ b/res/layout/one_pane_activity.xml
@@ -16,7 +16,6 @@
-->
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
@@ -27,12 +26,8 @@
android:layout_height="match_parent"
android:orientation="vertical">
- <android.support.v7.widget.Toolbar
- android:id="@+id/mail_toolbar"
- android:layout_width="match_parent"
- android:layout_height="?attr/actionBarSize"
- android:background="?attr/colorPrimary"
- app:theme="?attr/actionBarTheme" />
+ <!-- Custom toolbar/search overlay -->
+ <include layout="@layout/toolbar_with_search" />
<FrameLayout
android:layout_width="match_parent"
@@ -47,6 +42,8 @@
<include layout="@layout/floating_actions" />
+ <include layout="@layout/search_suggestion_list" />
+
</FrameLayout>
</LinearLayout>
@@ -57,4 +54,4 @@
android:layout_height="match_parent"
android:layout_gravity="start" />
-</android.support.v4.widget.DrawerLayout>
+</android.support.v4.widget.DrawerLayout> \ No newline at end of file
diff --git a/res/layout/search_suggestion_item.xml b/res/layout/search_suggestion_item.xml
new file mode 100644
index 000000000..49b0256c9
--- /dev/null
+++ b/res/layout/search_suggestion_item.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 Google Inc.
+ Licensed to The Android Open Source Project.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/search_suggestion_height"
+ android:orientation="vertical">
+
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:gravity="center_vertical"
+ android:paddingRight="16dp">
+
+ <ImageView
+ android:id="@+id/search_overlay_item_icon"
+ android:layout_width="@dimen/search_leading_button_width"
+ android:layout_height="match_parent"
+ style="@style/SearchViewLeadingButton" />
+
+ <TextView
+ android:id="@+id/search_overlay_item_text"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:layout_weight="1"
+ android:textColor="@color/search_suggestion_item_text"
+ android:textSize="16sp" />
+
+ </LinearLayout>
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/search_suggestion_list.xml b/res/layout/search_suggestion_list.xml
new file mode 100644
index 000000000..d024ccfe5
--- /dev/null
+++ b/res/layout/search_suggestion_list.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 Google Inc.
+ Licensed to The Android Open Source Project.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <com.android.mail.ui.MaterialSearchSuggestionsList
+ android:id="@+id/search_overlay_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:visibility="gone">
+
+ <ListView
+ android:id="@+id/search_overlay_suggestion_list"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@android:color/white"
+ android:divider="@null" />
+
+ <!-- Scrim to fade the background -->
+ <View
+ android:id="@+id/search_overlay_scrim"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:background="#88000000" />
+
+ </com.android.mail.ui.MaterialSearchSuggestionsList>
+
+ <!-- Search bar shadow -->
+ <View
+ android:id="@+id/search_actionbar_shadow"
+ android:layout_width="match_parent"
+ android:layout_height="7dp"
+ android:background="@drawable/action_bar_shadow"
+ android:visibility="gone" />
+</FrameLayout> \ No newline at end of file
diff --git a/res/layout/toolbar_with_search.xml b/res/layout/toolbar_with_search.xml
new file mode 100644
index 000000000..4e5abda14
--- /dev/null
+++ b/res/layout/toolbar_with_search.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 Google Inc.
+ Licensed to The Android Open Source Project.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="?attr/actionBarSize">
+
+ <android.support.v7.widget.Toolbar
+ android:id="@+id/mail_toolbar"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="?attr/colorPrimary"
+ app:theme="?attr/actionBarTheme" />
+
+ <include layout="@layout/mail_actionbar_searchview" />
+
+</FrameLayout> \ No newline at end of file
diff --git a/res/layout/two_pane_activity.xml b/res/layout/two_pane_activity.xml
index 2f8f6db6e..eb194c96c 100644
--- a/res/layout/two_pane_activity.xml
+++ b/res/layout/two_pane_activity.xml
@@ -15,49 +15,68 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.mail.ui.TwoPaneLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/two_pane_activity"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="@color/tablet_background_gray">
+ android:orientation="vertical">
+ <!-- Custom toolbar/search overlay -->
+ <include layout="@layout/toolbar_with_search" />
+
+ <!-- Main content -->
<FrameLayout
- android:id="@+id/drawer"
- android:layout_width="@dimen/two_pane_drawer_width_open"
- android:layout_height="match_parent"
- android:layout_gravity="left">
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
- <include layout="@layout/drawer_fragment"
+ <com.android.mail.ui.TwoPaneLayout
+ android:id="@+id/two_pane_activity"
android:layout_width="match_parent"
- android:layout_height="match_parent" />
+ android:layout_height="match_parent"
+ android:background="@color/tablet_background_gray">
- </FrameLayout>
+ <FrameLayout
+ android:id="@+id/drawer"
+ android:layout_width="@dimen/two_pane_drawer_width_open"
+ android:layout_height="match_parent"
+ android:layout_gravity="left">
- <FrameLayout
- android:id="@+id/conversation_list_pane"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_gravity="left"
- style="@style/TwoPaneConversationList" />
-
- <com.android.mail.ui.ConversationViewFrame
- android:id="@+id/conversation_pane"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_gravity="left">
-
- <include layout="@layout/conversation_pager"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
+ <include layout="@layout/drawer_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ </FrameLayout>
+
+ <FrameLayout
+ android:id="@+id/conversation_list_pane"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_gravity="left"
+ style="@style/TwoPaneConversationList" />
- </com.android.mail.ui.ConversationViewFrame>
+ <com.android.mail.ui.ConversationViewFrame
+ android:id="@+id/conversation_pane"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_gravity="left">
- <com.android.mail.ui.ConversationViewFrame
- android:id="@+id/miscellaneous_pane"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_gravity="left" />
+ <include layout="@layout/conversation_pager"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
- <include layout="@layout/floating_actions" />
+ </com.android.mail.ui.ConversationViewFrame>
+
+ <com.android.mail.ui.ConversationViewFrame
+ android:id="@+id/miscellaneous_pane"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_gravity="left" />
+
+ <include layout="@layout/floating_actions" />
+
+ </com.android.mail.ui.TwoPaneLayout>
+
+ <include layout="@layout/search_suggestion_list" />
+
+ </FrameLayout>
-</com.android.mail.ui.TwoPaneLayout>
+</LinearLayout> \ No newline at end of file
diff --git a/res/menu-sw600dp-land/conversation_actions.xml b/res/menu-sw600dp-land/conversation_actions.xml
index 78325b8ce..af888ddde 100644
--- a/res/menu-sw600dp-land/conversation_actions.xml
+++ b/res/menu-sw600dp-land/conversation_actions.xml
@@ -22,8 +22,7 @@
<item android:id="@+id/search"
android:title="@string/menu_search"
app:showAsAction="always|collapseActionView"
- android:icon="@drawable/ic_menu_search"
- app:actionLayout="@layout/mail_actionbar_searchview" />
+ android:icon="@drawable/ic_menu_search" />
<item
android:id="@+id/archive"
diff --git a/res/menu-sw600dp-land/conversation_list_search_results_actions.xml b/res/menu-sw600dp-land/conversation_list_search_results_actions.xml
index 1b784bc56..1e465722d 100644
--- a/res/menu-sw600dp-land/conversation_list_search_results_actions.xml
+++ b/res/menu-sw600dp-land/conversation_list_search_results_actions.xml
@@ -21,8 +21,7 @@
<item android:id="@+id/search"
android:title="@string/menu_search"
app:showAsAction="always|collapseActionView"
- android:icon="@drawable/ic_menu_search"
- app:actionLayout="@layout/mail_actionbar_searchview" />
+ android:icon="@drawable/ic_menu_search" />
<item
android:id="@+id/delete"
diff --git a/res/menu/conversation_list_menu.xml b/res/menu/conversation_list_menu.xml
index 05568bc0d..8b7c59377 100644
--- a/res/menu/conversation_list_menu.xml
+++ b/res/menu/conversation_list_menu.xml
@@ -35,8 +35,7 @@
that supports FOLDER_SERVER_SEARCH -->
<item android:id="@+id/search" android:title="@string/menu_search"
app:showAsAction="ifRoom|collapseActionView"
- android:icon="@drawable/ic_menu_search"
- app:actionLayout="@layout/mail_actionbar_searchview" />
+ android:icon="@drawable/ic_menu_search" />
<!-- These invisible menu item are used to enable keyboard shortcuts -->
<item
diff --git a/res/menu/conversation_list_search_results_actions.xml b/res/menu/conversation_list_search_results_actions.xml
index 6708c8366..1205e9066 100644
--- a/res/menu/conversation_list_search_results_actions.xml
+++ b/res/menu/conversation_list_search_results_actions.xml
@@ -22,8 +22,7 @@
<item android:id="@+id/search"
android:title="@string/menu_search"
app:showAsAction="ifRoom|collapseActionView"
- android:icon="@drawable/ic_menu_search"
- app:actionLayout="@layout/mail_actionbar_searchview" />
+ android:icon="@drawable/ic_menu_search" />
<!-- This invisible menu item is used to map CTRL-C to the compose action -->
<item
diff --git a/res/values-ldrtl/styles-ldrtl.xml b/res/values-ldrtl/styles-ldrtl.xml
index 047db0a6e..20b69bf32 100644
--- a/res/values-ldrtl/styles-ldrtl.xml
+++ b/res/values-ldrtl/styles-ldrtl.xml
@@ -396,6 +396,13 @@
<item name="android:paddingEnd">@dimen/undo_icon_padding_end</item>
</style>
+ <style name="SearchViewLeadingButton">
+ <item name="android:layout_gravity">center_vertical</item>
+ <item name="android:paddingStart">16dp</item>
+ <item name="android:paddingEnd">32dp</item>
+ <item name="android:scaleType">center</item>
+ </style>
+
<style name="AccountItemNameStyle">
<item name="android:paddingStart">@dimen/account_item_name_start_padding</item>
<item name="android:paddingEnd">@dimen/account_item_name_end_padding</item>
diff --git a/res/values-sw600dp/themes.xml b/res/values-sw600dp/themes.xml
index 4909a9d81..d6babb92f 100644
--- a/res/values-sw600dp/themes.xml
+++ b/res/values-sw600dp/themes.xml
@@ -1,7 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <style name="MailActivityTheme" parent="@style/UnifiedEmailTheme.Appcompat" />
-
<!-- todo - comment out when theme exists -->
<!--<style name="ShortcutWidgetTheme" parent="@style/Theme.Appcompat.Light.Dialog.MinWidth">-->
<!--<item name="actionOverflowButtonStyle">@style/ActionBarOverflowButtonStyle</item>-->
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 73f685b3f..c3834a84d 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -103,6 +103,9 @@
<color name="notification_icon_gmail_red">#da4336</color>
<!-- Search colors -->
+ <color name="search_query_hint_text">@color/light_gray</color>
+ <color name="search_query_text">@color/text_color_black</color>
+ <color name="search_suggestion_item_text">@color/text_color_grey</color>
<color name="search_banner_bg">#f6f6f6</color>
<color name="search_banner_text">@color/text_color_grey</color>
diff --git a/res/values/dimen.xml b/res/values/dimen.xml
index 458ae243b..6be9b7114 100644
--- a/res/values/dimen.xml
+++ b/res/values/dimen.xml
@@ -112,7 +112,6 @@
<dimen name="widget_margin_left">0dip</dimen>
<dimen name="widget_margin_right">0dip</dimen>
<dimen name="widget_margin_bottom">0dip</dimen>
- <dimen name="search_view_width">400dip</dimen>
<dimen name="wait_padding">16dp</dimen>
<integer name="chips_max_lines">2</integer>
<dimen name="tile_letter_font_size">24dp</dimen>
@@ -154,6 +153,9 @@
<dimen name="widget_senders_padding_end">16dip</dimen>
<dimen name="widget_attachment_padding_end">8dp</dimen>
+ <dimen name="search_leading_button_width">72dp</dimen>
+ <dimen name="search_ending_button_width">56dp</dimen>
+ <dimen name="search_suggestion_height">56dp</dimen>
<dimen name="search_results_padding">16dp</dimen>
<dimen name="search_banner_text_size">12sp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 4b66b05f2..f0ce86f04 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -19,10 +19,6 @@
<!-- Names of packages and authorities that are common to all apps
and read from resources -->
- <!-- Name of the search suggestions authority that looks up recent suggestions. This
- needs to be modified in AndroidManifest.xml and res/xml/searchable.xml as well. -->
- <string name="suggestions_authority" translatable="false">com.android.mail.suggestionsprovider</string>
-
<!-- Layout tests strings -->
<string name="mock_content_provider" translatable="false">Mock Content Provider</string>
<string name="conversation_content_provider" translatable="false">Conversation Content Provider</string>
@@ -607,9 +603,11 @@
<!-- Title of the search dialog -->
<string name="search_title" translatable="false">Unified Email</string>
<!-- Shown in light gray in the Search box when no text has been entered [CHAR LIMIT=20]-->
- <string name="search_hint">Search mail</string>
+ <string name="search_hint">Search</string>
<!-- Search Results: Text for status of the search when the results are completely loaded [CHAR LIMIT=10] -->
<string name="search_results_loaded"><xliff:g id="searchCount">%1$d</xliff:g></string>
+ <!-- Voice search is not supported on this device [CHAR LIMIT=100] -->
+ <string name="voice_search_not_supported">Voice search is not supported on this device.</string>
<!-- Shown in conversation list footer when application cannot make a connection [CHAR LIMIT=20]-->
<string name="network_error">No connection</string>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 544fd24a0..4fca44e70 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -975,11 +975,11 @@
<item name="android:paddingRight">@dimen/undo_icon_padding_end</item>
</style>
- <style name="Theme.AppCompat.Translucent">
- <item name="android:windowBackground">@android:color/transparent</item>
- <item name="android:colorBackgroundCacheHint">@null</item>
- <item name="android:windowIsTranslucent">true</item>
- <item name="android:windowAnimationStyle">@android:style/Animation</item>
+ <style name="SearchViewLeadingButton">
+ <item name="android:layout_gravity">center_vertical</item>
+ <item name="android:paddingLeft">16dp</item>
+ <item name="android:paddingRight">32dp</item>
+ <item name="android:scaleType">center</item>
</style>
<style name="AccountItemNameStyle">
diff --git a/res/values/themes.xml b/res/values/themes.xml
index c2edf9f5e..7fd779e47 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -45,4 +45,11 @@
<item name="android:windowNoDisplay">true</item>
</style>
+ <style name="Theme.AppCompat.Translucent">
+ <item name="android:windowBackground">@android:color/transparent</item>
+ <item name="android:colorBackgroundCacheHint">@null</item>
+ <item name="android:windowIsTranslucent">true</item>
+ <item name="android:windowAnimationStyle">@android:style/Animation</item>
+ </style>
+
</resources> \ No newline at end of file
diff --git a/res/xml/searchable.xml b/res/xml/searchable.xml
deleted file mode 100644
index 5607f16cb..000000000
--- a/res/xml/searchable.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2012 Google Inc.
- Licensed to The Android Open Source Project.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<!-- Override the searchSuggestAuthority in the inheriting applications to point to the
- correct package name.-->
-<searchable xmlns:android="http://schemas.android.com/apk/res/android"
- android:label="@string/search_title"
- android:hint="@string/search_hint"
- android:icon="@drawable/ic_menu_search"
- android:searchSuggestIntentAction="android.intent.action.SEARCH"
- android:searchSuggestAuthority="com.android.mail"
- android:imeOptions="actionSearch"
- android:voiceSearchMode="showVoiceSearchButton|launchRecognizer" />
diff --git a/src/com/android/mail/providers/SearchRecentSuggestionsProvider.java b/src/com/android/mail/providers/SearchRecentSuggestionsProvider.java
index 99ac4dfa4..0581869ba 100644
--- a/src/com/android/mail/providers/SearchRecentSuggestionsProvider.java
+++ b/src/com/android/mail/providers/SearchRecentSuggestionsProvider.java
@@ -18,37 +18,30 @@
package com.android.mail.providers;
import android.app.SearchManager;
-import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
-import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
-import android.net.Uri;
+import android.os.SystemClock;
import android.text.TextUtils;
import com.android.mail.R;
import java.util.ArrayList;
-public class SearchRecentSuggestionsProvider extends ContentProvider {
+public class SearchRecentSuggestionsProvider {
/*
* String used to delimit different parts of a query.
*/
public static final String QUERY_TOKEN_SEPARATOR = " ";
- // client-provided configuration values
- private String mAuthority;
- private int mMode;
-
// general database configuration and tables
private SQLiteOpenHelper mOpenHelper;
private static final String sDatabaseName = "suggestions.db";
private static final String sSuggestions = "suggestions";
private static final String ORDER_BY = "date DESC";
- private static final String NULL_COLUMN = "query";
// Table of database versions. Don't forget to update!
// NOTE: These version values are shifted left 8 bits (x 256) in order to create space for
@@ -56,24 +49,28 @@ public class SearchRecentSuggestionsProvider extends ContentProvider {
//
// 1 original implementation with queries, and 1 or 2 display columns
// 1->2 added UNIQUE constraint to display1 column
- private static final int DATABASE_VERSION = 2 * 256;
+ private static final int DATABASE_VERSION = 3 * 256;
/**
* This mode bit configures the database to record recent queries. <i>required</i>
- *
- * @see #setupSuggestions(String, int)
+ * @see #setupSuggestions(int)
*/
public static final int DATABASE_MODE_QUERIES = 1;
- // Uri and query support
- private static final int URI_MATCH_SUGGEST = 1;
-
- private Uri mSuggestionsUri;
- private UriMatcher mUriMatcher;
-
private String mSuggestSuggestionClause;
private String[] mSuggestionProjection;
+ protected final Context mContext;
+
+ public SearchRecentSuggestionsProvider(Context context) {
+ mContext = context;
+ mOpenHelper = new DatabaseHelper(mContext, DATABASE_VERSION);
+ }
+
+ public void cleanup() {
+ mOpenHelper.close();
+ }
+
/**
* Builds the database. This version has extra support for using the version field
* as a mode flags field, and configures the database columns depending on the mode bits
@@ -110,31 +107,20 @@ public class SearchRecentSuggestionsProvider extends ContentProvider {
* constructor. In your application or activities, you must provide the same values when
* you create the {@link android.provider.SearchRecentSuggestions} helper.
*
- * @param authority This must match the authority that you've declared in your manifest.
* @param mode You can use mode flags here to determine certain functional aspects of your
* database. Note, this value should not change from run to run, because when it does change,
* your suggestions database may be wiped.
*
* @see #DATABASE_MODE_QUERIES
*/
- protected void setupSuggestions(String authority, int mode) {
- if (TextUtils.isEmpty(authority) ||
- ((mode & DATABASE_MODE_QUERIES) == 0)) {
+ protected void setupSuggestions(int mode) {
+ if ((mode & DATABASE_MODE_QUERIES) == 0) {
throw new IllegalArgumentException();
}
- // saved values
- mAuthority = new String(authority);
- mMode = mode;
-
- // derived values
- mSuggestionsUri = Uri.parse("content://" + mAuthority + "/suggestions");
- mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
- mUriMatcher.addURI(mAuthority, SearchManager.SUGGEST_URI_PATH_QUERY, URI_MATCH_SUGGEST);
-
// The URI of the icon that we will include on every suggestion here.
final String historicalIcon = ContentResolver.SCHEME_ANDROID_RESOURCE + "://"
- + getContext().getPackageName() + "/" + R.drawable.ic_history_holo_light;
+ + mContext.getPackageName() + "/" + R.drawable.ic_history_24dp;
mSuggestSuggestionClause = "display1 LIKE ?";
mSuggestionProjection = new String [] {
@@ -145,99 +131,6 @@ public class SearchRecentSuggestionsProvider extends ContentProvider {
};
}
- /**
- * This method is provided for use by the ContentResolver. Do not override, or directly
- * call from your own code.
- */
- @Override
- public int delete(Uri uri, String selection, String[] selectionArgs) {
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-
- final int length = uri.getPathSegments().size();
- if (length != 1) {
- throw new IllegalArgumentException("Unknown Uri");
- }
-
- final String base = uri.getPathSegments().get(0);
- int count = 0;
- if (base.equals(sSuggestions)) {
- count = db.delete(sSuggestions, selection, selectionArgs);
- } else {
- throw new IllegalArgumentException("Unknown Uri");
- }
- getContext().getContentResolver().notifyChange(uri, null);
- return count;
- }
-
- /**
- * This method is provided for use by the ContentResolver. Do not override, or directly
- * call from your own code.
- */
- @Override
- public String getType(Uri uri) {
- if (mUriMatcher.match(uri) == URI_MATCH_SUGGEST) {
- return SearchManager.SUGGEST_MIME_TYPE;
- }
- int length = uri.getPathSegments().size();
- if (length >= 1) {
- String base = uri.getPathSegments().get(0);
- if (base.equals(sSuggestions)) {
- if (length == 1) {
- return "vnd.android.cursor.dir/suggestion";
- } else if (length == 2) {
- return "vnd.android.cursor.item/suggestion";
- }
- }
- }
- throw new IllegalArgumentException("Unknown Uri");
- }
-
- /**
- * This method is provided for use by the ContentResolver. Do not override, or directly
- * call from your own code.
- */
- @Override
- public Uri insert(Uri uri, ContentValues values) {
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-
- int length = uri.getPathSegments().size();
- if (length < 1) {
- throw new IllegalArgumentException("Unknown Uri");
- }
- // Note: This table has on-conflict-replace semantics, so insert() may actually replace()
- long rowID = -1;
- String base = uri.getPathSegments().get(0);
- Uri newUri = null;
- if (base.equals(sSuggestions)) {
- if (length == 1) {
- rowID = db.insert(sSuggestions, NULL_COLUMN, values);
- if (rowID > 0) {
- newUri = Uri.withAppendedPath(mSuggestionsUri, String.valueOf(rowID));
- }
- }
- }
- if (rowID < 0) {
- throw new IllegalArgumentException("Unknown Uri");
- }
- getContext().getContentResolver().notifyChange(newUri, null);
- return newUri;
- }
-
- /**
- * This method is provided for use by the ContentResolver. Do not override, or directly
- * call from your own code.
- */
- @Override
- public boolean onCreate() {
- if (mAuthority == null || mMode == 0) {
- throw new IllegalArgumentException("Provider not configured");
- }
- int mWorkingDbVersion = DATABASE_VERSION + mMode;
- mOpenHelper = new DatabaseHelper(getContext(), mWorkingDbVersion);
-
- return true;
- }
-
private ArrayList<String> mFullQueryTerms;
/**
@@ -278,13 +171,8 @@ public class SearchRecentSuggestionsProvider extends ContentProvider {
mFullQueryTerms = terms;
}
- /**
- * This method is provided for use by the ContentResolver. Do not override,
- * or directly call from your own code.
- */
// TODO: Confirm no injection attacks here, or rewrite.
- @Override
- public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+ public Cursor query(String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
SQLiteDatabase db = mOpenHelper.getReadableDatabase();
@@ -300,22 +188,27 @@ public class SearchRecentSuggestionsProvider extends ContentProvider {
suggestSelection = mSuggestSuggestionClause;
}
// Suggestions are always performed with the default sort order
- // Add this to the query:
- // "select 'real_query' as SearchManager.SUGGEST_COLUMN_QUERY.
- // rest of query
- // real query will then show up in the suggestion
Cursor c = db.query(sSuggestions, createProjection(selectionArgs), suggestSelection, myArgs,
null, null, ORDER_BY, null);
- c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
/**
- * This method is provided for use by the ContentResolver. Do not override, or directly
- * call from your own code.
+ * We are going to keep track of recent suggestions ourselves and not depend on the framework.
+ * Note that this writes to disk. DO NOT CALL FROM MAIN THREAD.
*/
- @Override
- public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
- throw new UnsupportedOperationException("Not implemented");
+ public void saveRecentQuery(String query) {
+ SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ ContentValues values = new ContentValues(3);
+ values.put("display1", query);
+ values.put("query", query);
+ values.put("date", SystemClock.elapsedRealtime());
+ // Note: This table has on-conflict-replace semantics, so insert() may actually replace()
+ db.insert(sSuggestions, null, values);
+ }
+
+ public void clearHistory() {
+ SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+ db.delete(sSuggestions, null, null);
}
} \ No newline at end of file
diff --git a/src/com/android/mail/providers/SuggestionsProvider.java b/src/com/android/mail/providers/SuggestionsProvider.java
index 92c7bccf9..7efaed3f6 100644
--- a/src/com/android/mail/providers/SuggestionsProvider.java
+++ b/src/com/android/mail/providers/SuggestionsProvider.java
@@ -65,20 +65,13 @@ public class SuggestionsProvider extends SearchRecentSuggestionsProvider {
*/
static private final int MIN_QUERY_LENGTH_FOR_CONTACTS = 2;
- public SuggestionsProvider() {
- super();
+ public SuggestionsProvider(Context context) {
+ super(context);
+ setupSuggestions(MODE);
}
@Override
- public boolean onCreate() {
- final String authority = getContext().getString(R.string.suggestions_authority);
- setupSuggestions(authority, MODE);
- super.onCreate();
- return true;
- }
-
- @Override
- public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+ public Cursor query(String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
String query = selectionArgs[0];
MergeCursor mergeCursor = null;
@@ -110,7 +103,7 @@ public class SuggestionsProvider extends SearchRecentSuggestionsProvider {
ArrayList<Cursor> cursors = new ArrayList<Cursor>();
// Pass query; at this point it is either the last term OR the
// only term.
- cursors.add(super.query(uri, projection, selection, new String[] { query }, sortOrder));
+ cursors.add(super.query(projection, selection, new String[] { query }, sortOrder));
if (query.length() >= MIN_QUERY_LENGTH_FOR_CONTACTS) {
cursors.add(new ContactsCursor().query(query));
@@ -124,10 +117,8 @@ public class SuggestionsProvider extends SearchRecentSuggestionsProvider {
* Utility class to return a cursor over the contacts database
*/
private final class ContactsCursor extends MatrixCursorWithCachedColumns {
- private final Context mContext;
public ContactsCursor() {
super(CONTACTS_COLUMNS);
- mContext = getContext();
}
/**
diff --git a/src/com/android/mail/ui/AbstractActivityController.java b/src/com/android/mail/ui/AbstractActivityController.java
index d619474c8..ee2e3b104 100644
--- a/src/com/android/mail/ui/AbstractActivityController.java
+++ b/src/com/android/mail/ui/AbstractActivityController.java
@@ -46,7 +46,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Parcelable;
import android.os.SystemClock;
-import android.provider.SearchRecentSuggestions;
+import android.speech.RecognizerIntent;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
@@ -87,7 +87,6 @@ import com.android.mail.providers.Folder;
import com.android.mail.providers.FolderWatcher;
import com.android.mail.providers.MailAppProvider;
import com.android.mail.providers.Settings;
-import com.android.mail.providers.SuggestionsProvider;
import com.android.mail.providers.UIProvider;
import com.android.mail.providers.UIProvider.AccountCapabilities;
import com.android.mail.providers.UIProvider.AccountCursorExtraKeys;
@@ -196,6 +195,7 @@ public abstract class AbstractActivityController implements ActivityController,
protected final RecentFolderList mRecentFolderList;
protected ConversationListContext mConvListContext;
protected Conversation mCurrentConversation;
+ protected MaterialSearchViewController mSearchViewController;
/**
* The hash of {@link #mCurrentConversation} in detached mode. 0 if we are not in detached mode.
*/
@@ -610,12 +610,9 @@ public abstract class AbstractActivityController implements ActivityController,
return;
}
- final boolean isSearch = mActivity.getIntent() != null
- && Intent.ACTION_SEARCH.equals(mActivity.getIntent().getAction());
- mActionBarController = isSearch ?
- new SearchActionBarController(mContext) :
- new ActionBarController(mContext);
+ mActionBarController = new ActionBarController(mContext);
mActionBarController.initialize(mActivity, this, actionBar);
+ actionBar.setShowHideAnimationEnabled(false);
// init the action bar to allow the 'up' affordance.
// any configurations that disallow 'up' should do that later.
@@ -1117,7 +1114,10 @@ public abstract class AbstractActivityController implements ActivityController,
}
break;
case CHANGE_NAVIGATION_REQUEST_CODE:
- if (resultCode == Activity.RESULT_OK && data != null) {
+ if (ViewMode.isSearchMode(mViewMode.getMode())) {
+ mActivity.setResult(resultCode, data);
+ mActivity.finish();
+ } else if (resultCode == Activity.RESULT_OK && data != null) {
// We have have received a result that indicates we need to navigate to a
// different folder or account. This happens if someone navigates using the
// drawer on the search results activity.
@@ -1132,6 +1132,17 @@ public abstract class AbstractActivityController implements ActivityController,
}
}
break;
+ case MaterialSearchViewController.VOICE_SEARCH_REQUEST_CODE:
+ if (resultCode == Activity.RESULT_OK) {
+ final ArrayList<String> matches = data.getStringArrayListExtra(
+ RecognizerIntent.EXTRA_RESULTS);
+ if (!matches.isEmpty()) {
+ // not sure how dependable the API is, but it's all we have.
+ // take the top choice.
+ mSearchViewController.onSearchPerformed(matches.get(0));
+ }
+ }
+ break;
}
}
@@ -1306,6 +1317,9 @@ public abstract class AbstractActivityController implements ActivityController,
final Intent intent = mActivity.getIntent();
+ mSearchViewController = new MaterialSearchViewController(mActivity, this, intent,
+ savedState);
+
// Immediately handle a clean launch with intent, and any state restoration
// that does not rely on restored fragments or loader data
// any state restoration that relies on those can be done later in
@@ -1596,6 +1610,9 @@ public abstract class AbstractActivityController implements ActivityController,
showEmptyDialog();
} else if (id == R.id.empty_spam) {
showEmptyDialog();
+ } else if (id == R.id.search) {
+ mSearchViewController.showSearchActionBar(
+ MaterialSearchViewController.SEARCH_VIEW_STATE_VISIBLE);
} else {
handled = false;
}
@@ -1665,6 +1682,8 @@ public abstract class AbstractActivityController implements ActivityController,
if (isDrawerEnabled() && mDrawerContainer.isDrawerVisible(mDrawerPullout)) {
mDrawerContainer.closeDrawers();
return true;
+ } else if (mSearchViewController.handleBackPress()) {
+ return true;
}
return handleBackPress();
@@ -2124,6 +2143,8 @@ public abstract class AbstractActivityController implements ActivityController,
outState.putBundle(SAVED_CONVERSATION_LIST_SCROLL_POSITIONS,
mConversationListScrollPositions);
+
+ mSearchViewController.saveState(outState);
}
/**
@@ -2141,7 +2162,8 @@ public abstract class AbstractActivityController implements ActivityController,
intent.putExtra(ConversationListContext.EXTRA_SEARCH_QUERY, query);
intent.putExtra(Utils.EXTRA_ACCOUNT, mAccount);
intent.setComponent(mActivity.getComponentName());
- mActionBarController.collapseSearch();
+ mSearchViewController.showSearchActionBar(
+ MaterialSearchViewController.SEARCH_VIEW_STATE_GONE);
// Call startActivityForResult here so we can tell if we have navigated to a different folder
// or account from search results.
mActivity.startActivityForResult(intent, CHANGE_NAVIGATION_REQUEST_CODE);
@@ -2167,6 +2189,7 @@ public abstract class AbstractActivityController implements ActivityController,
mDestroyed = true;
mHandler.removeCallbacks(mLogServiceChecker);
mLogServiceChecker = null;
+ mSearchViewController.onDestroy();
}
/**
@@ -2403,12 +2426,9 @@ public abstract class AbstractActivityController implements ActivityController,
} else if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
if (intent.hasExtra(Utils.EXTRA_ACCOUNT)) {
mHaveSearchResults = false;
- // Save this search query for future suggestions.
+ // Save this search query for future suggestions
final String query = intent.getStringExtra(SearchManager.QUERY);
- final String authority = mContext.getString(R.string.suggestions_authority);
- final SearchRecentSuggestions suggestions = new SearchRecentSuggestions(
- mContext, authority, SuggestionsProvider.MODE);
- suggestions.saveRecentQuery(query, null);
+ mSearchViewController.saveRecentQuery(query);
setAccount((Account) intent.getParcelableExtra(Utils.EXTRA_ACCOUNT));
fetchSearchFolder(intent);
if (shouldEnterSearchConvMode()) {
@@ -3239,7 +3259,8 @@ public abstract class AbstractActivityController implements ActivityController,
return;
}
if (mAccount.supportsSearch()) {
- mActionBarController.expandSearch();
+ mSearchViewController.showSearchActionBar(
+ MaterialSearchViewController.SEARCH_VIEW_STATE_VISIBLE);
} else {
Toast.makeText(mActivity.getActivityContext(), mActivity.getActivityContext()
.getString(R.string.search_unsupported), Toast.LENGTH_SHORT).show();
@@ -4559,10 +4580,9 @@ public abstract class AbstractActivityController implements ActivityController,
// TODO: Fold this into the outer class when b/16627877 is fixed
private class HomeButtonListener implements View.OnClickListener {
-
@Override
public void onClick(View v) {
onUpPressed();
}
}
-}
+} \ No newline at end of file
diff --git a/src/com/android/mail/ui/ActionBarController.java b/src/com/android/mail/ui/ActionBarController.java
index c73ebd0f5..f0b51afbe 100644
--- a/src/com/android/mail/ui/ActionBarController.java
+++ b/src/com/android/mail/ui/ActionBarController.java
@@ -17,31 +17,22 @@
package com.android.mail.ui;
-import android.app.SearchManager;
-import android.app.SearchableInfo;
import android.content.ContentResolver;
import android.content.Context;
-import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
-import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBar;
-import android.support.v7.widget.SearchView;
-import android.support.v7.widget.SearchView.OnQueryTextListener;
-import android.support.v7.widget.SearchView.OnSuggestionListener;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
-import com.android.mail.ConversationListContext;
import com.android.mail.R;
import com.android.mail.providers.Account;
import com.android.mail.providers.AccountObserver;
import com.android.mail.providers.Conversation;
import com.android.mail.providers.Folder;
import com.android.mail.providers.FolderObserver;
-import com.android.mail.providers.SearchRecentSuggestionsProvider;
import com.android.mail.providers.UIProvider;
import com.android.mail.providers.UIProvider.AccountCapabilities;
import com.android.mail.providers.UIProvider.FolderCapabilities;
@@ -53,8 +44,7 @@ import com.android.mail.utils.Utils;
/**
* Controller to manage the various states of the {@link android.app.ActionBar}.
*/
-public class ActionBarController implements ViewMode.ModeChangeListener,
- OnQueryTextListener, OnSuggestionListener, MenuItemCompat.OnActionExpandListener {
+public class ActionBarController implements ViewMode.ModeChangeListener {
private final Context mContext;
@@ -75,8 +65,6 @@ public class ActionBarController implements ViewMode.ModeChangeListener,
*/
private Folder mFolder;
- private SearchView mSearchWidget;
- private MenuItem mSearch;
private MenuItem mEmptyTrashItem;
private MenuItem mEmptySpamItem;
@@ -117,46 +105,9 @@ public class ActionBarController implements ViewMode.ModeChangeListener,
mIsOnTablet = Utils.useTabletUI(context.getResources());
}
- public void expandSearch() {
- if (mSearch != null) {
- MenuItemCompat.expandActionView(mSearch);
- }
- }
-
- /**
- * Close the search view if it is expanded.
- */
- public void collapseSearch() {
- if (mSearch != null) {
- MenuItemCompat.collapseActionView(mSearch);
- }
- }
-
- /**
- * Get the search menu item.
- */
- protected MenuItem getSearch() {
- return mSearch;
- }
-
public boolean onCreateOptionsMenu(Menu menu) {
mEmptyTrashItem = menu.findItem(R.id.empty_trash);
mEmptySpamItem = menu.findItem(R.id.empty_spam);
- mSearch = menu.findItem(R.id.search);
-
- if (mSearch != null) {
- mSearchWidget = (SearchView) MenuItemCompat.getActionView(mSearch);
- MenuItemCompat.setOnActionExpandListener(mSearch, this);
- SearchManager searchManager = (SearchManager) mActivity.getActivityContext()
- .getSystemService(Context.SEARCH_SERVICE);
- if (searchManager != null && mSearchWidget != null) {
- SearchableInfo info = searchManager.getSearchableInfo(mActivity.getComponentName());
- mSearchWidget.setSearchableInfo(info);
- mSearchWidget.setOnQueryTextListener(this);
- mSearchWidget.setOnSuggestionListener(this);
- mSearchWidget.setIconifiedByDefault(true);
- }
- }
// the menu should be displayed if the mode is known
return getMode() != ViewMode.UNKNOWN;
@@ -245,7 +196,6 @@ public class ActionBarController implements ViewMode.ModeChangeListener,
break;
case ViewMode.CONVERSATION:
case ViewMode.AD:
- closeSearchField();
mActionBar.setDisplayHomeAsUpEnabled(true);
setEmptyMode();
break;
@@ -257,17 +207,6 @@ public class ActionBarController implements ViewMode.ModeChangeListener,
}
}
- /**
- * Close the search query entry field to avoid keyboard events, and to restore the actionbar
- * to non-search mode.
- */
- private void closeSearchField() {
- if (mSearch == null) {
- return;
- }
- mSearch.collapseActionView();
- }
-
protected int getMode() {
if (mViewModeController != null) {
return mViewModeController.getMode();
@@ -382,71 +321,6 @@ public class ActionBarController implements ViewMode.ModeChangeListener,
mActionBar.setHomeButtonEnabled(true);
}
- @Override
- public boolean onQueryTextSubmit(String query) {
- if (mSearch != null) {
- MenuItemCompat.collapseActionView(mSearch);
- mSearchWidget.setQuery("", false);
- }
- mController.executeSearch(query.trim());
- return true;
- }
-
- @Override
- public boolean onQueryTextChange(String newText) {
- return false;
- }
-
- // Next two methods are called when search suggestions are clicked.
- @Override
- public boolean onSuggestionSelect(int position) {
- return onSuggestionClick(position);
- }
-
- @Override
- public boolean onSuggestionClick(int position) {
- final Cursor c = mSearchWidget.getSuggestionsAdapter().getCursor();
- final boolean haveValidQuery = (c != null) && c.moveToPosition(position);
- if (!haveValidQuery) {
- LogUtils.d(LOG_TAG, "onSuggestionClick: Couldn't get a search query");
- // We haven't handled this query, but the default behavior will
- // leave EXTRA_ACCOUNT un-populated, leading to a crash. So claim
- // that we have handled the event.
- return true;
- }
- collapseSearch();
- // what is in the text field
- String queryText = mSearchWidget.getQuery().toString();
- // What the suggested query is
- String query = c.getString(c.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_1));
- // If the text the user typed in is a prefix of what is in the search
- // widget suggestion query, just take the search widget suggestion
- // query. Otherwise, it is a suffix and we want to remove matching
- // prefix portions.
- if (!TextUtils.isEmpty(queryText) && query.indexOf(queryText) != 0) {
- final int queryTokenIndex = queryText
- .lastIndexOf(SearchRecentSuggestionsProvider.QUERY_TOKEN_SEPARATOR);
- if (queryTokenIndex > -1) {
- queryText = queryText.substring(0, queryTokenIndex);
- }
- // Since we auto-complete on each token in a query, if the query the
- // user typed up until the last token is a substring of the
- // suggestion they click, make sure we don't double include the
- // query text. For example:
- // user types john, that matches john palo alto
- // User types john p, that matches john john palo alto
- // Remove the first john
- // Only do this if we have multiple query tokens.
- if (queryTokenIndex > -1 && !TextUtils.isEmpty(query) && query.contains(queryText)
- && queryText.length() < query.length()) {
- int start = query.indexOf(queryText);
- query = query.substring(0, start) + query.substring(start + queryText.length());
- }
- }
- mController.executeSearch(query.trim());
- return true;
- }
-
/**
* Uses the current state to update the current folder {@link #mFolder} and the current
* account {@link #mAccount} shown in the actionbar. Also updates the actionbar subtitle to
@@ -487,36 +361,12 @@ public class ActionBarController implements ViewMode.ModeChangeListener,
return;
}
/** True if we are changing folders. */
- final boolean changingFolders = (mFolder == null || !mFolder.equals(folder));
mFolder = folder;
setFolderAndAccount();
- final ConversationListContext listContext = mController == null ? null :
- mController.getCurrentListContext();
- if (changingFolders && !ConversationListContext.isSearchResult(listContext)) {
- closeSearchField();
- }
// make sure that we re-validate the optional menu items
validateVolatileMenuOptionVisibility();
}
- @Override
- public boolean onMenuItemActionExpand(MenuItem item) {
- // Do nothing. Required as part of the interface, we ar only interested in
- // onMenuItemActionCollapse(MenuItem).
- // Have to return true here. Unlike other callbacks, the return value here is whether
- // we want to suppress the action (rather than consume the action). We don't want to
- // suppress the action.
- return true;
- }
-
- @Override
- public boolean onMenuItemActionCollapse(MenuItem item) {
- // Have to return true here. Unlike other callbacks, the return value
- // here is whether we want to suppress the action (rather than consume the action). We
- // don't want to suppress the action.
- return true;
- }
-
/**
* Sets the actionbar mode: Pass it an integer which contains each of these values, perhaps
* OR'd together: {@link ActionBar#DISPLAY_SHOW_CUSTOM} and
diff --git a/src/com/android/mail/ui/ActivityController.java b/src/com/android/mail/ui/ActivityController.java
index fec109b4b..1b0809e2d 100644
--- a/src/com/android/mail/ui/ActivityController.java
+++ b/src/com/android/mail/ui/ActivityController.java
@@ -337,4 +337,6 @@ public interface ActivityController extends LayoutListener,
@LayoutRes int getContentViewResource();
View.OnClickListener getNavigationViewClickListener();
+
+ boolean isSearchBarShowing();
}
diff --git a/src/com/android/mail/ui/ControllableActivity.java b/src/com/android/mail/ui/ControllableActivity.java
index b9995b947..c899d34dd 100644
--- a/src/com/android/mail/ui/ControllableActivity.java
+++ b/src/com/android/mail/ui/ControllableActivity.java
@@ -24,6 +24,7 @@ import com.android.mail.bitmap.ContactResolver;
import com.android.mail.browse.ConversationListFooterView;
import com.android.mail.providers.Account;
import com.android.mail.providers.Folder;
+import com.android.mail.providers.SearchRecentSuggestionsProvider;
/**
* A controllable activity is an Activity that has a Controller attached. This activity must be
@@ -130,4 +131,6 @@ public interface ControllableActivity extends RestrictedActivity,
* Shows help to user, could be in browser or another activity.
*/
void showHelp(Account account, int viewMode);
+
+ SearchRecentSuggestionsProvider getSuggestionsProvider();
}
diff --git a/src/com/android/mail/ui/ConversationListFragment.java b/src/com/android/mail/ui/ConversationListFragment.java
index 77e286861..dd0fda701 100644
--- a/src/com/android/mail/ui/ConversationListFragment.java
+++ b/src/com/android/mail/ui/ConversationListFragment.java
@@ -722,7 +722,6 @@ public final class ConversationListFragment extends Fragment implements
// Set default navigation
if (ViewMode.isListMode(newMode)) {
mListView.setNextFocusRightId(R.id.conversation_list_view);
- mListView.requestFocus();
} else if (ViewMode.isConversationMode(newMode)) {
// This would only happen in two_pane
mListView.setNextFocusRightId(R.id.conversation_pager);
diff --git a/src/com/android/mail/ui/FolderSelectionActivity.java b/src/com/android/mail/ui/FolderSelectionActivity.java
index 96b06496f..045311449 100644
--- a/src/com/android/mail/ui/FolderSelectionActivity.java
+++ b/src/com/android/mail/ui/FolderSelectionActivity.java
@@ -39,6 +39,7 @@ import com.android.mail.bitmap.ContactResolver;
import com.android.mail.providers.Account;
import com.android.mail.providers.Folder;
import com.android.mail.providers.FolderWatcher;
+import com.android.mail.providers.SearchRecentSuggestionsProvider;
import com.android.mail.utils.LogTag;
import com.android.mail.utils.LogUtils;
import com.android.mail.utils.MailObservable;
@@ -485,6 +486,12 @@ public class FolderSelectionActivity extends ActionBarActivity implements OnClic
@Override
public void showHelp(Account account, int viewMode) {
- //Unsupported
+ // Unsupported
+ }
+
+ @Override
+ public SearchRecentSuggestionsProvider getSuggestionsProvider() {
+ // Unsupported;
+ return null;
}
}
diff --git a/src/com/android/mail/ui/MailActivity.java b/src/com/android/mail/ui/MailActivity.java
index 78507dad1..bd640c563 100644
--- a/src/com/android/mail/ui/MailActivity.java
+++ b/src/com/android/mail/ui/MailActivity.java
@@ -45,6 +45,8 @@ import com.android.mail.bitmap.ContactResolver;
import com.android.mail.compose.ComposeActivity;
import com.android.mail.providers.Account;
import com.android.mail.providers.Folder;
+import com.android.mail.providers.SearchRecentSuggestionsProvider;
+import com.android.mail.providers.SuggestionsProvider;
import com.android.mail.utils.StorageLowState;
import com.android.mail.utils.Utils;
@@ -497,6 +499,11 @@ public class MailActivity extends AbstractMailActivity implements ControllableAc
Utils.showHelp(this, account, getString(helpContext));
}
+ @Override
+ public SearchRecentSuggestionsProvider getSuggestionsProvider() {
+ return new SuggestionsProvider(this);
+ }
+
/**
* Returns the loader callback that can create a
* {@link AbstractActivityController#LOADER_WELCOME_TOUR_ACCOUNTS} followed by a
diff --git a/src/com/android/mail/ui/MaterialSearchActionView.java b/src/com/android/mail/ui/MaterialSearchActionView.java
new file mode 100644
index 000000000..80e301600
--- /dev/null
+++ b/src/com/android/mail/ui/MaterialSearchActionView.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2014 Google Inc.
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.mail.ui;
+
+import android.content.Context;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.util.AttributeSet;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.mail.R;
+
+/**
+ * Custom view for the action bar when search is displayed.
+ */
+public class MaterialSearchActionView extends LinearLayout implements TextWatcher,
+ View.OnClickListener, TextView.OnEditorActionListener {
+ private MaterialSearchViewController mController;
+ private InputMethodManager mImm;
+ private boolean mShowingClose;
+ private boolean mSupportVoice;
+
+ private View mBackButton;
+ private EditText mQueryText;
+ private ImageView mEndingButton;
+
+ public MaterialSearchActionView(Context context) {
+ super(context);
+ }
+
+ public MaterialSearchActionView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ // PUBLIC API
+ public void setController(MaterialSearchViewController controller, String initialQuery,
+ boolean supportVoice) {
+ mController = controller;
+ mQueryText.setText(initialQuery);
+ mSupportVoice = supportVoice;
+ }
+
+ public void clearSearchQuery() {
+ mQueryText.setText("");
+ }
+
+ public void focusSearchBar(boolean hasFocus) {
+ mQueryText.requestFocus();
+ if (hasFocus) {
+ mImm.showSoftInput(mQueryText, 0);
+ } else {
+ mImm.hideSoftInputFromWindow(mQueryText.getWindowToken(), 0);
+ }
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+
+ mImm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+ mBackButton = findViewById(R.id.search_actionbar_back_button);
+ mBackButton.setOnClickListener(this);
+ mQueryText = (EditText) findViewById(R.id.search_actionbar_query_text);
+ mQueryText.addTextChangedListener(this);
+ mQueryText.setOnClickListener(this);
+ mQueryText.setOnEditorActionListener(this);
+ mEndingButton = (ImageView) findViewById(R.id.search_actionbar_ending_button);
+ mEndingButton.setOnClickListener(this);
+ }
+
+ @Override
+ public void setVisibility(int visibility) {
+ if (visibility != VISIBLE) {
+ mQueryText.setText("");
+ }
+ super.setVisibility(visibility);
+ }
+
+ @Override
+ public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
+ // Only care about onTextChanged
+ }
+
+ @Override
+ public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
+ mController.onQueryTextChanged(charSequence.toString());
+ if (!mSupportVoice || charSequence.length() > 0) {
+ mShowingClose = true;
+ mEndingButton.setImageResource(R.drawable.ic_close_24dp);
+ } else {
+ mShowingClose = false;
+ mEndingButton.setImageResource(R.drawable.ic_mic_24dp);
+ }
+ }
+
+ @Override
+ public void afterTextChanged(Editable editable) {
+ // Only care about onTextChanged
+ }
+
+ @Override
+ public void onClick(View view) {
+ if (view == mBackButton) {
+ mController.onSearchCanceled();
+ mQueryText.setText("");
+ } else if (view == mEndingButton) {
+ if (mShowingClose) {
+ mQueryText.setText("");
+ mController.showSearchActionBar(
+ MaterialSearchViewController.SEARCH_VIEW_STATE_VISIBLE);
+ } else {
+ mController.onVoiceSearch();
+ }
+ } else if (view == mQueryText) {
+ mController.showSearchActionBar(MaterialSearchViewController.SEARCH_VIEW_STATE_VISIBLE);
+ }
+ }
+
+ @Override
+ public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) {
+ if (actionId == EditorInfo.IME_ACTION_SEARCH) {
+ mController.onSearchPerformed(mQueryText.getText().toString());
+ }
+ return false;
+ }
+}
diff --git a/src/com/android/mail/ui/MaterialSearchSuggestionsList.java b/src/com/android/mail/ui/MaterialSearchSuggestionsList.java
new file mode 100644
index 000000000..30d469687
--- /dev/null
+++ b/src/com/android/mail/ui/MaterialSearchSuggestionsList.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2014 Google Inc.
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.mail.ui;
+
+import android.app.SearchManager;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.android.mail.R;
+import com.android.mail.providers.SearchRecentSuggestionsProvider;
+import com.google.common.collect.Lists;
+
+import java.util.List;
+
+/**
+ * Custom quantum-styled search view that overlays the main activity.
+ */
+public class MaterialSearchSuggestionsList extends LinearLayout
+ implements AdapterView.OnItemClickListener, View.OnClickListener {
+ private MaterialSearchViewController mController;
+ private SearchRecentSuggestionsProvider mSuggestionsProvider;
+ private List<SuggestionItem> mSuggestions = Lists.newArrayList();
+ private String mQuery;
+
+ private View mDummyHolder;
+ private ListView mListView;
+ private QuantumSearchViewListAdapter mAdapter;
+ private QuerySuggestionsTask mQueryTask;
+
+ public MaterialSearchSuggestionsList(Context context) {
+ super(context);
+ }
+
+ public MaterialSearchSuggestionsList(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ // PUBLIC API
+ public void setController(MaterialSearchViewController controller,
+ SearchRecentSuggestionsProvider suggestionsProvider) {
+ mController = controller;
+ mSuggestionsProvider = suggestionsProvider;
+ }
+
+ public void setQuery(String query) {
+ mQuery = query;
+ if (mQueryTask != null) {
+ mQueryTask.cancel(true);
+ }
+ mQueryTask = new QuerySuggestionsTask();
+ mQueryTask.execute(query);
+ }
+
+ // PRIVATE API
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+
+ mListView = (ListView) findViewById(R.id.search_overlay_suggestion_list);
+ mListView.setOnItemClickListener(this);
+ mDummyHolder = findViewById(R.id.search_overlay_scrim);
+ mDummyHolder.setOnClickListener(this);
+
+ // set up the adapter
+ mAdapter = new QuantumSearchViewListAdapter(getContext(), R.layout.search_suggestion_item);
+ mListView.setAdapter(mAdapter);
+ }
+
+ @Override
+ public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
+ mController.onSearchPerformed(mSuggestions.get(position).suggestion);
+ }
+
+ @Override
+ public void onClick(View view) {
+ mController.showSearchActionBar(
+ MaterialSearchViewController.SEARCH_VIEW_STATE_ONLY_ACTIONBAR);
+ }
+
+ // Background task for querying the suggestions list
+ private class QuerySuggestionsTask extends AsyncTask<String, Void, List<SuggestionItem>> {
+ @Override
+ protected List<SuggestionItem> doInBackground(String... strings) {
+ String query = strings[0];
+ if (query == null) {
+ query = "";
+ }
+
+ Cursor c = null;
+ final List<SuggestionItem> result = Lists.newArrayList();
+ try {
+ c = mSuggestionsProvider.query(null, "query LIKE ?",
+ new String[] { query }, null);
+
+ if (c != null && c.moveToFirst()) {
+ final int textIndex = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_QUERY);
+ final int iconIndex = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_ICON_1);
+ do {
+ final String suggestion = c.getString(textIndex);
+ final Uri iconUri = Uri.parse(c.getString(iconIndex));
+ result.add(new SuggestionItem(suggestion, iconUri));
+ } while (c.moveToNext());
+ }
+ } finally {
+ if (c != null) {
+ c.close();
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ protected void onPostExecute(List<SuggestionItem> strings) {
+ if (!isCancelled()) {
+ // Should not have any race conditions here since we cancel the previous asynctask
+ // before starting the new one. It's unlikely that the new task finishes fast enough
+ // to get to onPostExecute when this one is in addAll.
+ mSuggestions.clear();
+ mSuggestions.addAll(strings);
+ mAdapter.notifyDataSetChanged();
+ }
+ }
+ }
+
+ private static class SuggestionItem {
+ final String suggestion;
+ final Uri icon;
+
+ public SuggestionItem(String s, Uri i) {
+ suggestion = s;
+ icon = i;
+ }
+ }
+
+ // Custom adapter to populate our list
+ private class QuantumSearchViewListAdapter extends BaseAdapter {
+ private final Context mContext;
+ private final int mResId;
+ private LayoutInflater mInflater;
+
+ public QuantumSearchViewListAdapter(Context context, int resource) {
+ super();
+ mContext = context;
+ mResId = resource;
+ }
+
+ private LayoutInflater getInflater() {
+ if (mInflater == null) {
+ mInflater = LayoutInflater.from(mContext);
+ }
+ return mInflater;
+ }
+
+ @Override
+ public int getCount() {
+ return mSuggestions.size();
+ }
+
+ @Override
+ public Object getItem(int i) {
+ return mSuggestions.get(i);
+ }
+
+ @Override
+ public long getItemId(int i) {
+ return 0;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ if (convertView == null) {
+ convertView = getInflater().inflate(mResId, parent, false);
+ }
+
+ final SuggestionItem item = mSuggestions.get(position);
+ ((TextView) convertView.findViewById(R.id.search_overlay_item_text))
+ .setText(item.suggestion);
+ ((ImageView) convertView.findViewById(R.id.search_overlay_item_icon))
+ .setImageURI(item.icon);
+
+ return convertView;
+ }
+ }
+}
diff --git a/src/com/android/mail/ui/MaterialSearchViewController.java b/src/com/android/mail/ui/MaterialSearchViewController.java
new file mode 100644
index 000000000..d382754b7
--- /dev/null
+++ b/src/com/android/mail/ui/MaterialSearchViewController.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2014 Google Inc.
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.mail.ui;
+
+import android.app.Activity;
+import android.content.ActivityNotFoundException;
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.speech.RecognizerIntent;
+import android.view.View;
+import android.widget.Toast;
+
+import com.android.mail.ConversationListContext;
+import com.android.mail.R;
+import com.android.mail.providers.SearchRecentSuggestionsProvider;
+
+import java.util.Locale;
+
+/**
+ * Controller for interactions between ActivityController and our custom search views.
+ */
+public class MaterialSearchViewController implements ViewMode.ModeChangeListener {
+ // The controller is not in search mode. Both search action bar and the suggestion list
+ // are not visible to the user.
+ public static final int SEARCH_VIEW_STATE_GONE = 0;
+ // The controller is actively in search (as in the action bar is focused and the user can type
+ // into the search query). Both the search action bar and the suggestion list are visible.
+ public static final int SEARCH_VIEW_STATE_VISIBLE = 1;
+ // The controller is in a search ViewMode but not actively searching. This is relevant when
+ // we have to show the search actionbar on top while the user is not interacting with it.
+ public static final int SEARCH_VIEW_STATE_ONLY_ACTIONBAR = 2;
+
+ /** Code returned from voice search intent */
+ public static final int VOICE_SEARCH_REQUEST_CODE = 4;
+
+ private static final String EXTRA_VIEW_STATE = "extraSearchViewControllerViewState";
+
+ private final MailActivity mActivity;
+ private final ActivityController mController;
+
+ protected SearchRecentSuggestionsProvider mSuggestionsProvider;
+ protected View mSearchActionViewShadow;
+ protected MaterialSearchActionView mSearchActionView;
+ protected MaterialSearchSuggestionsList mSearchSuggestionList;
+
+ private int mViewMode;
+ private int mViewState;
+
+ public MaterialSearchViewController(MailActivity activity, ActivityController controller,
+ Intent intent, Bundle savedInstanceState) {
+ mActivity = activity;
+ mController = controller;
+
+ final Intent voiceIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
+ final boolean supportVoice =
+ voiceIntent.resolveActivity(mActivity.getPackageManager()) != null;
+
+ mSuggestionsProvider = mActivity.getSuggestionsProvider();
+ mSearchSuggestionList = (MaterialSearchSuggestionsList) mActivity.findViewById(
+ R.id.search_overlay_view);
+ mSearchSuggestionList.setController(this, mSuggestionsProvider);
+ mSearchActionView = (MaterialSearchActionView) mActivity.findViewById(
+ R.id.search_actionbar_view);
+ mSearchActionView.setController(this, intent.getStringExtra(
+ ConversationListContext.EXTRA_SEARCH_QUERY), supportVoice);
+ mSearchActionViewShadow = mActivity.findViewById(R.id.search_actionbar_shadow);
+
+ if (savedInstanceState != null && savedInstanceState.containsKey(EXTRA_VIEW_STATE)) {
+ mViewState = savedInstanceState.getInt(EXTRA_VIEW_STATE);
+ }
+
+ mActivity.getViewMode().addListener(this);
+ }
+
+ public void onDestroy() {
+ mSuggestionsProvider.cleanup();
+ mSuggestionsProvider = null;
+ mActivity.getViewMode().removeListener(this);
+ }
+
+ public void saveState(Bundle outState) {
+ outState.putInt(EXTRA_VIEW_STATE, mViewState);
+ }
+
+ @Override
+ public void onViewModeChanged(int newMode) {
+ if (mController.isSearchBarShowing()) {
+ showSearchActionBar(MaterialSearchViewController.SEARCH_VIEW_STATE_ONLY_ACTIONBAR);
+ } else if (mViewMode == 0) {
+ showSearchActionBar(mViewState);
+ } else {
+ showSearchActionBar(MaterialSearchViewController.SEARCH_VIEW_STATE_GONE);
+ }
+ mViewMode = newMode;
+ }
+
+ public boolean handleBackPress() {
+ if (mController.isSearchBarShowing() && mSearchSuggestionList.isShown()) {
+ showSearchActionBar(MaterialSearchViewController.SEARCH_VIEW_STATE_ONLY_ACTIONBAR);
+ return true;
+ } else if (mSearchActionView.isShown()) {
+ showSearchActionBar(MaterialSearchViewController.SEARCH_VIEW_STATE_GONE);
+ return true;
+ }
+ return false;
+ }
+
+ // Should use the view states specified in MaterialSearchViewController
+ public void showSearchActionBar(int state) {
+ mViewState = state;
+ switch (state) {
+ case MaterialSearchViewController.SEARCH_VIEW_STATE_ONLY_ACTIONBAR:
+ // Only actionbar is only applicable in search mode
+ if (mController.isSearchBarShowing()) {
+ mSearchActionView.setVisibility(View.VISIBLE);
+ mSearchActionViewShadow.setVisibility(View.VISIBLE);
+ mSearchSuggestionList.setVisibility(View.GONE);
+ mSearchActionView.focusSearchBar(false);
+ break;
+ }
+ // Fallthrough to setting everything invisible
+ case MaterialSearchViewController.SEARCH_VIEW_STATE_GONE:
+ mSearchActionView.setVisibility(View.GONE);
+ mSearchActionViewShadow.setVisibility(View.GONE);
+ mSearchSuggestionList.setVisibility(View.GONE);
+ mSearchActionView.focusSearchBar(false);
+ break;
+ case MaterialSearchViewController.SEARCH_VIEW_STATE_VISIBLE:
+ mSearchActionView.setVisibility(View.VISIBLE);
+ mSearchActionViewShadow.setVisibility(View.VISIBLE);
+ mSearchSuggestionList.setVisibility(View.VISIBLE);
+ mSearchActionView.focusSearchBar(true);
+ break;
+ }
+ }
+
+ public void onQueryTextChanged(String query) {
+ mSearchSuggestionList.setQuery(query);
+ }
+
+ public void onSearchCanceled() {
+ // Special case search mode
+ if (mActivity.getViewMode().isSearchMode()) {
+ mActivity.setResult(Activity.RESULT_OK);
+ mActivity.finish();
+ } else {
+ showSearchActionBar(MaterialSearchViewController.SEARCH_VIEW_STATE_GONE);
+ }
+ }
+
+ public void onSearchPerformed(String query) {
+ mSearchActionView.clearSearchQuery();
+ mController.executeSearch(query);
+ }
+
+ public void onVoiceSearch() {
+ final Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
+ intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
+ RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
+ intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault().getLanguage());
+
+ // Some devices do not support the voice-to-speech functionality.
+ try {
+ mActivity.startActivityForResult(intent, VOICE_SEARCH_REQUEST_CODE);
+ } catch (ActivityNotFoundException e) {
+ final String toast =
+ mActivity.getResources().getString(R.string.voice_search_not_supported);
+ Toast.makeText(mActivity, toast, Toast.LENGTH_LONG).show();
+ }
+ }
+
+ public void saveRecentQuery(final String query) {
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... voids) {
+ mSuggestionsProvider.saveRecentQuery(query);
+ return null;
+ }
+ }.execute();
+ }
+}
diff --git a/src/com/android/mail/ui/OnePaneController.java b/src/com/android/mail/ui/OnePaneController.java
index 0d0e58dec..1030b0c11 100644
--- a/src/com/android/mail/ui/OnePaneController.java
+++ b/src/com/android/mail/ui/OnePaneController.java
@@ -174,6 +174,7 @@ public final class OnePaneController extends AbstractActivityController {
if (ViewMode.isListMode(newMode)) {
mPagerController.hide(true /* changeVisibility */);
}
+
// When we step away from the conversation mode, we don't have a current conversation
// anymore. Let's blank it out so clients calling getCurrentConversation are not misled.
if (!ViewMode.isConversationMode(newMode)) {
@@ -513,4 +514,9 @@ public final class OnePaneController extends AbstractActivityController {
public boolean isTwoPaneLandscape() {
return false;
}
+
+ @Override
+ public boolean isSearchBarShowing() {
+ return mViewMode.getMode() == ViewMode.SEARCH_RESULTS_LIST;
+ }
}
diff --git a/src/com/android/mail/ui/SearchActionBarController.java b/src/com/android/mail/ui/SearchActionBarController.java
deleted file mode 100644
index 97f1fbedc..000000000
--- a/src/com/android/mail/ui/SearchActionBarController.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc.
- * Licensed to The Android Open Source Project.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mail.ui;
-
-import android.content.Context;
-import android.support.v4.view.MenuItemCompat;
-import android.support.v7.widget.SearchView;
-import android.text.TextUtils;
-import android.view.Menu;
-import android.view.MenuItem;
-
-import com.android.mail.ConversationListContext;
-import com.android.mail.utils.Utils;
-
-/**
- * This class is used to control the actionbar for the search activity.
- * It shows/hides various menu items based on the viewmode.
- */
-public class SearchActionBarController extends ActionBarController {
-
- public SearchActionBarController(Context context) {
- super(context);
- }
-
- @Override
- public boolean onPrepareOptionsMenu(Menu menu) {
- super.onPrepareOptionsMenu(menu);
- switch (getMode()) {
- case ViewMode.SEARCH_RESULTS_LIST:
- setSearchQueryTerm();
- mActionBar.setDisplayHomeAsUpEnabled(true);
- // And immediately give up focus to avoid keyboard popping and suggestions.
- clearSearchFocus();
- break;
- case ViewMode.SEARCH_RESULTS_CONVERSATION:
- if (mIsOnTablet) {
- setSearchQueryTerm();
- }
- mActionBar.setDisplayHomeAsUpEnabled(true);
- // And immediately give up focus to avoid keyboard popping and suggestions.
- clearSearchFocus();
- break;
- }
- return false;
- }
-
- @Override
- public void onViewModeChanged(int newMode) {
- super.onViewModeChanged(newMode);
- switch (getMode()) {
- case ViewMode.SEARCH_RESULTS_LIST:
- setEmptyMode();
- break;
- }
- }
-
- /**
- * Remove focus from the search field to avoid
- * 1. The keyboard popping in and out.
- * 2. The search suggestions shown up.
- */
- private void clearSearchFocus() {
- // Remove focus from the search action menu in search results mode so
- // the IME and the suggestions don't get in the way.
- final MenuItem search = getSearch();
- if (search != null) {
- final SearchView searchWidget = (SearchView) MenuItemCompat.getActionView(search);
- searchWidget.clearFocus();
- }
- }
-
- /**
- * Sets the query term in the text field, so the user can see what was searched for.
- */
- private void setSearchQueryTerm() {
- final MenuItem search = getSearch();
- if (search != null) {
- MenuItemCompat.expandActionView(search);
- final String query = mActivity.getIntent().getStringExtra(
- ConversationListContext.EXTRA_SEARCH_QUERY);
- final SearchView searchWidget = (SearchView) MenuItemCompat.getActionView(search);
- if (!TextUtils.isEmpty(query)) {
- searchWidget.setQuery(query, false);
- }
- }
- }
-
- @Override
- public boolean onMenuItemActionCollapse(MenuItem item) {
- // When we are in the search activity, back closes the search action mode. At that point
- // we want to quit the activity entirely.
- final int mode = getMode();
- if (mode == ViewMode.SEARCH_RESULTS_LIST
- || (Utils.showTwoPaneSearchResults(getContext())
- && mode == ViewMode.SEARCH_RESULTS_CONVERSATION)) {
-
- // When the action menu is collapsed, the search activity has finished. We should exit
- // search at this point
- mController.exitSearchMode();
- }
- // The return value here is whether we want to collapse the action mode. Since we want to
- // collapse the action mode, we should return true.
- return true;
- }
-}
diff --git a/src/com/android/mail/ui/TwoPaneController.java b/src/com/android/mail/ui/TwoPaneController.java
index 3be51ff22..bb9b4fa33 100644
--- a/src/com/android/mail/ui/TwoPaneController.java
+++ b/src/com/android/mail/ui/TwoPaneController.java
@@ -153,7 +153,7 @@ public final class TwoPaneController extends AbstractActivityController implemen
@Override
public boolean onCreate(Bundle savedState) {
mLayout = (TwoPaneLayout) mActivity.findViewById(R.id.two_pane_activity);
- if (mLayout == null) {
+ if (mLayout == null) {
// We need the layout for everything. Crash/Return early if it is null.
LogUtils.wtf(LOG_TAG, "mLayout is null!");
return false;
@@ -632,4 +632,11 @@ public final class TwoPaneController extends AbstractActivityController implemen
public boolean isTwoPaneLandscape() {
return mIsTabletLandscape;
}
+
+ @Override
+ public boolean isSearchBarShowing() {
+ final int mode = mViewMode.getMode();
+ return mode == ViewMode.SEARCH_RESULTS_LIST ||
+ (mIsTabletLandscape && mode == ViewMode.SEARCH_RESULTS_CONVERSATION);
+ }
}
diff --git a/src/com/android/mail/ui/settings/GeneralPrefsFragment.java b/src/com/android/mail/ui/settings/GeneralPrefsFragment.java
index b33ec6db7..a5e41c91e 100644
--- a/src/com/android/mail/ui/settings/GeneralPrefsFragment.java
+++ b/src/com/android/mail/ui/settings/GeneralPrefsFragment.java
@@ -27,7 +27,6 @@ import android.preference.CheckBoxPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
-import android.provider.SearchRecentSuggestions;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
@@ -167,12 +166,10 @@ public class GeneralPrefsFragment extends MailPreferenceFragment
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
- final String authority = context.getString(
- com.android.mail.R.string.suggestions_authority);
- final SearchRecentSuggestions suggestions =
- new SearchRecentSuggestions(context, authority,
- SuggestionsProvider.MODE);
+ final SuggestionsProvider suggestions =
+ new SuggestionsProvider(context);
suggestions.clearHistory();
+ suggestions.cleanup();
return null;
}
}.execute();
diff --git a/unified_src/com/android/mail/providers/UnifiedAccountCacheProvider.java b/unified_src/com/android/mail/providers/UnifiedAccountCacheProvider.java
index b1c131362..57f1fe8f3 100644
--- a/unified_src/com/android/mail/providers/UnifiedAccountCacheProvider.java
+++ b/unified_src/com/android/mail/providers/UnifiedAccountCacheProvider.java
@@ -24,11 +24,6 @@ public class UnifiedAccountCacheProvider extends MailAppProvider {
// The authority of our conversation provider (a forwarding provider)
// This string must match the declaration in AndroidManifest.xml
private static final String sAuthority = "com.android.mail.accountcache";
- /**
- * Authority for the suggestions provider. This is specified in AndroidManifest.xml and
- * res/xml/searchable.xml.
- */
- private static final String sSuggestionsAuthority = "com.android.mail.suggestionsprovider";
@Override
protected String getAuthority() {
@@ -36,12 +31,13 @@ public class UnifiedAccountCacheProvider extends MailAppProvider {
}
@Override
- protected Intent getNoAccountsIntent(Context context) {
+ public String getSuggestionAuthority() {
+ // UnifiedEmail does not use the default search.
return null;
}
@Override
- public String getSuggestionAuthority() {
- return sSuggestionsAuthority;
+ protected Intent getNoAccountsIntent(Context context) {
+ return null;
}
}