19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.widget; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.HandlerThread; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Looper; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>A filter constrains data with a filtering pattern.</p> 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Filters are usually created by {@link android.widget.Filterable} 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * classes.</p> 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Filtering operations performed by calling {@link #filter(CharSequence)} or 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #filter(CharSequence, android.widget.Filter.FilterListener)} are 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * performed asynchronously. When these methods are called, a filtering request 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is posted in a request queue and processed later. Any call to one of these 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * methods will cancel any previous non-executed filtering request.</p> 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.widget.Filterable 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic abstract class Filter { 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String LOG_TAG = "Filter"; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String THREAD_NAME = "Filter"; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int FILTER_TOKEN = 0xD0D0F00D; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int FINISH_TOKEN = 0xDEADBEEF; 45b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Handler mThreadHandler; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Handler mResultHandler; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 498bf92e003d89be00c7cb9209b3ffba2658523734Karl Rosaen private Delayer mDelayer; 508bf92e003d89be00c7cb9209b3ffba2658523734Karl Rosaen 51b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project private final Object mLock = new Object(); 52b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Creates a new asynchronous filter.</p> 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Filter() { 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mResultHandler = new ResultsHandler(); 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 618bf92e003d89be00c7cb9209b3ffba2658523734Karl Rosaen * Provide an interface that decides how long to delay the message for a given query. Useful 628bf92e003d89be00c7cb9209b3ffba2658523734Karl Rosaen * for heuristics such as posting a delay for the delete key to avoid doing any work while the 638bf92e003d89be00c7cb9209b3ffba2658523734Karl Rosaen * user holds down the delete key. 648bf92e003d89be00c7cb9209b3ffba2658523734Karl Rosaen * 658bf92e003d89be00c7cb9209b3ffba2658523734Karl Rosaen * @param delayer The delayer. 668bf92e003d89be00c7cb9209b3ffba2658523734Karl Rosaen * @hide 678bf92e003d89be00c7cb9209b3ffba2658523734Karl Rosaen */ 688bf92e003d89be00c7cb9209b3ffba2658523734Karl Rosaen public void setDelayer(Delayer delayer) { 698bf92e003d89be00c7cb9209b3ffba2658523734Karl Rosaen synchronized (mLock) { 708bf92e003d89be00c7cb9209b3ffba2658523734Karl Rosaen mDelayer = delayer; 718bf92e003d89be00c7cb9209b3ffba2658523734Karl Rosaen } 728bf92e003d89be00c7cb9209b3ffba2658523734Karl Rosaen } 738bf92e003d89be00c7cb9209b3ffba2658523734Karl Rosaen 748bf92e003d89be00c7cb9209b3ffba2658523734Karl Rosaen /** 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Starts an asynchronous filtering operation. Calling this method 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * cancels all previous non-executed filtering requests and posts a new 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * filtering request that will be executed later.</p> 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param constraint the constraint used to filter the data 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #filter(CharSequence, android.widget.Filter.FilterListener) 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final void filter(CharSequence constraint) { 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project filter(constraint, null); 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Starts an asynchronous filtering operation. Calling this method 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * cancels all previous non-executed filtering requests and posts a new 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * filtering request that will be executed later.</p> 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Upon completion, the listener is notified.</p> 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param constraint the constraint used to filter the data 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param listener a listener notified upon completion of the operation 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #filter(CharSequence) 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #performFiltering(CharSequence) 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #publishResults(CharSequence, android.widget.Filter.FilterResults) 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final void filter(CharSequence constraint, FilterListener listener) { 102b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project synchronized (mLock) { 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mThreadHandler == null) { 104ab3ef104cd507c06eac34fc436b39340f6e9d680Karl Rosaen HandlerThread thread = new HandlerThread( 105ab3ef104cd507c06eac34fc436b39340f6e9d680Karl Rosaen THREAD_NAME, android.os.Process.THREAD_PRIORITY_BACKGROUND); 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project thread.start(); 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mThreadHandler = new RequestHandler(thread.getLooper()); 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1098bf92e003d89be00c7cb9209b3ffba2658523734Karl Rosaen 1108bf92e003d89be00c7cb9209b3ffba2658523734Karl Rosaen final long delay = (mDelayer == null) ? 0 : mDelayer.getPostingDelay(constraint); 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message message = mThreadHandler.obtainMessage(FILTER_TOKEN); 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RequestArguments args = new RequestArguments(); 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // make sure we use an immutable copy of the constraint, so that 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // it doesn't change while the filter operation is in progress 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project args.constraint = constraint != null ? constraint.toString() : null; 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project args.listener = listener; 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project message.obj = args; 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mThreadHandler.removeMessages(FILTER_TOKEN); 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mThreadHandler.removeMessages(FINISH_TOKEN); 1238bf92e003d89be00c7cb9209b3ffba2658523734Karl Rosaen mThreadHandler.sendMessageDelayed(message, delay); 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Invoked in a worker thread to filter the data according to the 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * constraint. Subclasses must implement this method to perform the 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * filtering operation. Results computed by the filtering operation 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * must be returned as a {@link android.widget.Filter.FilterResults} that 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will then be published in the UI thread through 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #publishResults(CharSequence, 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * android.widget.Filter.FilterResults)}.</p> 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p><strong>Contract:</strong> When the constraint is null, the original 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * data must be restored.</p> 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param constraint the constraint used to filter the data 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the results of the filtering operation 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #filter(CharSequence, android.widget.Filter.FilterListener) 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #publishResults(CharSequence, android.widget.Filter.FilterResults) 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.widget.Filter.FilterResults 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected abstract FilterResults performFiltering(CharSequence constraint); 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Invoked in the UI thread to publish the filtering results in the 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * user interface. Subclasses must implement this method to display the 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * results computed in {@link #performFiltering}.</p> 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param constraint the constraint used to filter the data 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param results the results of the filtering operation 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #filter(CharSequence, android.widget.Filter.FilterListener) 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #performFiltering(CharSequence) 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.widget.Filter.FilterResults 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected abstract void publishResults(CharSequence constraint, 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FilterResults results); 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Converts a value from the filtered set into a CharSequence. Subclasses 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should override this method to convert their results. The default 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * implementation returns an empty String for null values or the default 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * String representation of the value.</p> 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param resultValue the value to convert to a CharSequence 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return a CharSequence representing the value 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public CharSequence convertResultToString(Object resultValue) { 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return resultValue == null ? "" : resultValue.toString(); 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Holds the results of a filtering operation. The results are the values 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * computed by the filtering operation and the number of these values.</p> 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected static class FilterResults { 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public FilterResults() { 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // nothing to see here 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Contains all the values computed by the filtering operation.</p> 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Object values; 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Contains the number of values computed by the filtering 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * operation.</p> 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int count; 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Listener used to receive a notification upon completion of a filtering 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * operation.</p> 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static interface FilterListener { 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Notifies the end of a filtering operation.</p> 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param count the number of values computed by the filter 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onFilterComplete(int count); 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Worker thread handler. When a new filtering request is posted from 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.widget.Filter#filter(CharSequence, android.widget.Filter.FilterListener)}, 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * it is sent to this handler.</p> 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class RequestHandler extends Handler { 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public RequestHandler(Looper looper) { 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(looper); 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Handles filtering requests by calling 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link Filter#performFiltering} and then sending a message 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * with the results to the results handler.</p> 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param msg the filtering request 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void handleMessage(Message msg) { 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int what = msg.what; 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message message; 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (what) { 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case FILTER_TOKEN: 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RequestArguments args = (RequestArguments) msg.obj; 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project args.results = performFiltering(args.constraint); 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project args.results = new FilterResults(); 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(LOG_TAG, "An exception occured during performFiltering()!", e); 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project message = mResultHandler.obtainMessage(what); 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project message.obj = args; 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project message.sendToTarget(); 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 244b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project synchronized (mLock) { 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mThreadHandler != null) { 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message finishMessage = mThreadHandler.obtainMessage(FINISH_TOKEN); 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mThreadHandler.sendMessageDelayed(finishMessage, 3000); 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case FINISH_TOKEN: 252b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project synchronized (mLock) { 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mThreadHandler != null) { 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mThreadHandler.getLooper().quit(); 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mThreadHandler = null; 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Handles the results of a filtering operation. The results are 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * handled in the UI thread.</p> 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class ResultsHandler extends Handler { 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Messages received from the request handler are processed in the 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * UI thread. The processing involves calling 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link Filter#publishResults(CharSequence, 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * android.widget.Filter.FilterResults)} 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to post the results back in the UI and then notifying the listener, 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * if any.</p> 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param msg the filtering results 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void handleMessage(Message msg) { 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RequestArguments args = (RequestArguments) msg.obj; 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project publishResults(args.constraint, args.results); 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (args.listener != null) { 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int count = args.results != null ? args.results.count : -1; 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project args.listener.onFilterComplete(count); 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Holds the arguments of a filtering request as well as the results 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the request.</p> 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static class RequestArguments { 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The constraint used to filter the data.</p> 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CharSequence constraint; 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The listener to notify upon completion. Can be null.</p> 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FilterListener listener; 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The results of the filtering operation.</p> 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FilterResults results; 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3108bf92e003d89be00c7cb9209b3ffba2658523734Karl Rosaen 3118bf92e003d89be00c7cb9209b3ffba2658523734Karl Rosaen /** 3128bf92e003d89be00c7cb9209b3ffba2658523734Karl Rosaen * @hide 3138bf92e003d89be00c7cb9209b3ffba2658523734Karl Rosaen */ 3148bf92e003d89be00c7cb9209b3ffba2658523734Karl Rosaen public interface Delayer { 3158bf92e003d89be00c7cb9209b3ffba2658523734Karl Rosaen 3168bf92e003d89be00c7cb9209b3ffba2658523734Karl Rosaen /** 3178bf92e003d89be00c7cb9209b3ffba2658523734Karl Rosaen * @param constraint The constraint passed to {@link Filter#filter(CharSequence)} 3188bf92e003d89be00c7cb9209b3ffba2658523734Karl Rosaen * @return The delay that should be used for 3198bf92e003d89be00c7cb9209b3ffba2658523734Karl Rosaen * {@link Handler#sendMessageDelayed(android.os.Message, long)} 3208bf92e003d89be00c7cb9209b3ffba2658523734Karl Rosaen */ 3218bf92e003d89be00c7cb9209b3ffba2658523734Karl Rosaen long getPostingDelay(CharSequence constraint); 3228bf92e003d89be00c7cb9209b3ffba2658523734Karl Rosaen } 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 324