summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Bird <sbird@cyngn.com>2016-01-25 11:39:30 -0800
committerStephen Bird <sbird@cyngn.com>2016-04-08 10:17:16 -0700
commit89368cb71de559787ae15e4c682e592c0705cc97 (patch)
tree5f3fd0bcaba8953cd5c790a2d602b607118bb61f
parent07defe6ff597d8f258c96508f000dfcd69383f31 (diff)
downloadandroid_packages_apps_Dialer-89368cb71de559787ae15e4c682e592c0705cc97.tar.gz
android_packages_apps_Dialer-89368cb71de559787ae15e4c682e592c0705cc97.tar.bz2
android_packages_apps_Dialer-89368cb71de559787ae15e4c682e592c0705cc97.zip
Initial T9 search bringup
This T9 search implementation is a little different than previous ones. It now also supports incall username searching. Change-Id: I6d31e721aeb2e21dda4f12e8d31f7dfa539b8859
-rw-r--r--src/com/android/dialer/DialtactsActivity.java22
-rw-r--r--src/com/android/dialer/database/DialerDatabaseHelper.java102
-rw-r--r--src/com/android/dialer/dialpad/DialpadFragment.java2
-rw-r--r--src/com/android/dialer/dialpad/SmartDialCursorLoader.java95
-rw-r--r--src/com/android/dialer/dialpad/SmartDialNameMatcher.java5
-rw-r--r--src/com/android/dialer/list/DialerPhoneNumberListAdapter.java42
-rw-r--r--src/com/android/dialer/list/RegularSearchListAdapter.java2
-rw-r--r--src/com/android/dialer/list/SearchFragment.java24
-rw-r--r--src/com/android/dialer/list/SmartDialNumberListAdapter.java14
-rw-r--r--src/com/android/dialer/list/SmartDialSearchFragment.java52
-rw-r--r--tests/src/com/android/dialer/database/SmartDialPrefixTest.java8
11 files changed, 307 insertions, 61 deletions
diff --git a/src/com/android/dialer/DialtactsActivity.java b/src/com/android/dialer/DialtactsActivity.java
index a03e0cb0b..c1f39bb35 100644
--- a/src/com/android/dialer/DialtactsActivity.java
+++ b/src/com/android/dialer/DialtactsActivity.java
@@ -100,6 +100,7 @@ import com.android.internal.telephony.TelephonyIntents;
import com.android.phone.common.animation.AnimUtils;
import com.android.phone.common.ambient.AmbientConnection;
import com.android.phone.common.incall.CallMethodInfo;
+import com.android.phone.common.incall.CallMethodHelper;
import com.android.phone.common.util.SettingsUtil;
import com.android.phone.common.animation.AnimationListenerAdapter;
@@ -267,6 +268,15 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
private String mVoiceSearchQuery;
private CallMethodInfo mCurrentCallMethod;
+ private String AMBIENT_SUBSCRIPTION_ID = "DialtactsActivity";
+
+ private CallMethodHelper.CallMethodReceiver pluginsUpdatedReceiver =
+ new CallMethodHelper.CallMethodReceiver() {
+ @Override
+ public void onChanged(HashMap<ComponentName, CallMethodInfo> callMethodInfos) {
+ providersUpdated(callMethodInfos);
+ }
+ };
@Override
public void onCallMethodChangedListener(CallMethodInfo cmi) {
@@ -293,11 +303,13 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
}
};
- @Override
- public void onCallMethodsAvailable(HashMap<ComponentName, CallMethodInfo> availableCallMethods) {
+ private void providersUpdated(HashMap<ComponentName, CallMethodInfo> availableCallMethods) {
if (mSmartDialSearchFragment != null) {
mSmartDialSearchFragment.setAvailableCallMethods(availableCallMethods);
}
+ // We don't want to update this until we know that our providers are loaded. otherwise
+ // we may miss some data.
+ updateSmartDialDatabase();
}
protected class OptionsPopupMenu extends PopupMenu {
@@ -563,7 +575,9 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
// make this call on resume in case user changed t9 locale in settings
SmartDialPrefix.initializeNanpSettings(this);
+ }
+ private void updateSmartDialDatabase() {
// if locale has changed since last time, refresh the smart dial db
Locale locale = SettingsUtil.getT9SearchInputLocale(this);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
@@ -586,6 +600,10 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
Trace.beginSection(TAG + " onResume");
super.onResume();
+ if (CallMethodHelper.subscribe(AMBIENT_SUBSCRIPTION_ID, pluginsUpdatedReceiver)) {
+ CallMethodHelper.refreshDynamic();
+ }
+
mStateSaved = false;
if (mFirstLaunch) {
displayFragment(getIntent());
diff --git a/src/com/android/dialer/database/DialerDatabaseHelper.java b/src/com/android/dialer/database/DialerDatabaseHelper.java
index f22ad7c9c..ffd0db732 100644
--- a/src/com/android/dialer/database/DialerDatabaseHelper.java
+++ b/src/com/android/dialer/database/DialerDatabaseHelper.java
@@ -36,6 +36,7 @@ import android.provider.ContactsContract.Directory;
import android.text.TextUtils;
import android.util.Log;
+import com.android.contacts.common.list.PhoneNumberListAdapter;
import com.android.contacts.common.util.PermissionsUtil;
import com.android.contacts.common.util.StopWatch;
import com.android.dialer.R;
@@ -50,7 +51,9 @@ import com.google.common.collect.Lists;
import java.lang.reflect.Method;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -81,7 +84,7 @@ public class DialerDatabaseHelper extends SQLiteOpenHelper {
* 0-98 KitKat
* </pre>
*/
- public static final int DATABASE_VERSION = 70004;
+ public static final int DATABASE_VERSION = 70005;
public static final String DATABASE_NAME = "dialer.db";
/**
@@ -120,6 +123,7 @@ public class DialerDatabaseHelper extends SQLiteOpenHelper {
static final String IN_VISIBLE_GROUP = "in_visible_group";
static final String IS_PRIMARY = "is_primary";
static final String LAST_SMARTDIAL_UPDATE_TIME = "last_smartdial_update_time";
+ static final String MIMETYPE = "mimetype";
}
public static interface PrefixColumns extends BaseColumns {
@@ -134,7 +138,7 @@ public class DialerDatabaseHelper extends SQLiteOpenHelper {
/** Query options for querying the contact database.*/
public static class PhoneQuery {
- static final Uri URI = Phone.CONTENT_URI.buildUpon().
+ static final Uri URI = ContactsContract.CommonDataKinds.Callable.CONTENT_URI.buildUpon().
appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY,
String.valueOf(Directory.DEFAULT)).
appendQueryParameter(ContactsContract.REMOVE_DUPLICATE_ENTRIES, "true").
@@ -172,6 +176,7 @@ public class DialerDatabaseHelper extends SQLiteOpenHelper {
static final int PHONE_IS_SUPER_PRIMARY = 11;
static final int PHONE_IN_VISIBLE_GROUP = 12;
static final int PHONE_IS_PRIMARY = 13;
+ static final int PHONE_NUMBER_MIMETYPE = 14;
/** Selects only rows that have been updated after a certain time stamp.*/
static final String SELECT_UPDATED_CLAUSE =
@@ -262,20 +267,23 @@ public class DialerDatabaseHelper extends SQLiteOpenHelper {
public final String phoneNumber;
public final String lookupKey;
public final long photoId;
+ public final String mimeType;
public ContactNumber(long id, long dataID, String displayName, String phoneNumber,
- String lookupKey, long photoId) {
+ String lookupKey, long photoId, String mimeType) {
this.dataId = dataID;
this.id = id;
this.displayName = displayName;
this.phoneNumber = phoneNumber;
this.lookupKey = lookupKey;
this.photoId = photoId;
+ this.mimeType = mimeType;
}
@Override
public int hashCode() {
- return Objects.hashCode(id, dataId, displayName, phoneNumber, lookupKey, photoId);
+ return Objects.hashCode(id, dataId, displayName, phoneNumber, lookupKey, photoId,
+ mimeType);
}
@Override
@@ -290,7 +298,9 @@ public class DialerDatabaseHelper extends SQLiteOpenHelper {
&& Objects.equal(this.displayName, that.displayName)
&& Objects.equal(this.phoneNumber, that.phoneNumber)
&& Objects.equal(this.lookupKey, that.lookupKey)
- && Objects.equal(this.photoId, that.photoId);
+ && Objects.equal(this.photoId, that.photoId)
+ && Objects.equal(this.mimeType, that.mimeType);
+
}
return false;
}
@@ -414,7 +424,8 @@ public class DialerDatabaseHelper extends SQLiteOpenHelper {
SmartDialDbColumns.STARRED + " INTEGER, " +
SmartDialDbColumns.IS_SUPER_PRIMARY + " INTEGER, " +
SmartDialDbColumns.IN_VISIBLE_GROUP + " INTEGER, " +
- SmartDialDbColumns.IS_PRIMARY + " INTEGER" +
+ SmartDialDbColumns.IS_PRIMARY + " INTEGER, " +
+ SmartDialDbColumns.MIMETYPE + " TEXT" +
");");
db.execSQL("CREATE TABLE " + Tables.PREFIX_TABLE + " (" +
@@ -725,8 +736,9 @@ public class DialerDatabaseHelper extends SQLiteOpenHelper {
SmartDialDbColumns.IS_SUPER_PRIMARY + ", " +
SmartDialDbColumns.IN_VISIBLE_GROUP+ ", " +
SmartDialDbColumns.IS_PRIMARY + ", " +
- SmartDialDbColumns.LAST_SMARTDIAL_UPDATE_TIME + ") " +
- " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+ SmartDialDbColumns.LAST_SMARTDIAL_UPDATE_TIME + ", " +
+ SmartDialDbColumns.MIMETYPE + ") " +
+ " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
final SQLiteStatement insert = db.compileStatement(sqlInsert);
final String numberSqlInsert = "INSERT INTO " + Tables.PREFIX_TABLE + " (" +
@@ -774,11 +786,18 @@ public class DialerDatabaseHelper extends SQLiteOpenHelper {
insert.bindLong(11, updatedContactCursor.getInt(PhoneQuery.PHONE_IN_VISIBLE_GROUP));
insert.bindLong(12, updatedContactCursor.getInt(PhoneQuery.PHONE_IS_PRIMARY));
insert.bindLong(13, currentMillis);
+
+ final String mimetype =
+ updatedContactCursor.getString(PhoneQuery.PHONE_NUMBER_MIMETYPE);
+ insert.bindString(14, mimetype);
+
insert.executeInsert();
final String contactPhoneNumber =
updatedContactCursor.getString(PhoneQuery.PHONE_NUMBER);
final ArrayList<String> numberPrefixes =
- SmartDialPrefix.parseToNumberTokens(contactPhoneNumber);
+ (TextUtils.equals(mimetype, Phone.CONTENT_ITEM_TYPE)) ?
+ SmartDialPrefix.parseToNumberTokens(contactPhoneNumber) :
+ SmartDialPrefix.generateNamePrefixes(contactPhoneNumber);
for (String numberPrefix : numberPrefixes) {
numberInsert.bindLong(1, updatedContactCursor.getLong(
@@ -1007,7 +1026,7 @@ public class DialerDatabaseHelper extends SQLiteOpenHelper {
* @return A list of top candidate contacts that will be suggested to user to match their input.
*/
public ArrayList<ContactNumber> getLooseMatches(String query,
- SmartDialNameMatcher nameMatcher) {
+ SmartDialNameMatcher nameMatcher, String usernameMimeType) {
final boolean inUpdate = sInUpdate.get();
if (inUpdate) {
return Lists.newArrayList();
@@ -1031,7 +1050,8 @@ public class DialerDatabaseHelper extends SQLiteOpenHelper {
SmartDialDbColumns.PHOTO_ID + ", " +
SmartDialDbColumns.NUMBER + ", " +
SmartDialDbColumns.CONTACT_ID + ", " +
- SmartDialDbColumns.LOOKUP_KEY +
+ SmartDialDbColumns.LOOKUP_KEY + ", " +
+ SmartDialDbColumns.MIMETYPE +
" FROM " + Tables.SMARTDIAL_TABLE +
" ORDER BY " + SmartDialSortingOrder.SORT_ORDER,
new String[] {currentTimeStamp});
@@ -1050,6 +1070,7 @@ public class DialerDatabaseHelper extends SQLiteOpenHelper {
final int columnNumber = 3;
final int columnId = 4;
final int columnLookupKey = 5;
+ final int columnMimetype = 6;
if (DEBUG) {
stopWatch.lap("Found column IDs");
}
@@ -1067,6 +1088,7 @@ public class DialerDatabaseHelper extends SQLiteOpenHelper {
final long id = cursor.getLong(columnId);
final long photoId = cursor.getLong(columnPhotoId);
final String lookupKey = cursor.getString(columnLookupKey);
+ final String mimeType = cursor.getString(columnMimetype);
/** If a contact already exists and another phone number of the contact is being
* processed, skip the second instance.
@@ -1076,18 +1098,31 @@ public class DialerDatabaseHelper extends SQLiteOpenHelper {
continue;
}
+ boolean usernameMatches = false;
+ if (!TextUtils.isEmpty(usernameMimeType)) {
+ HashMap<String, String> allCallableNumbers = getCallableMimeTypeForContact(id);
+
+ if (allCallableNumbers.containsKey(usernameMimeType)) {
+ String extraContactNumber = allCallableNumbers.get(usernameMimeType);
+ if (extraContactNumber != null) {
+ usernameMatches = nameMatcher.matches(extraContactNumber);
+ }
+ }
+
+ }
+
/**
- * If the contact has either the name or number that matches the query, add to the
- * result.
+ * If the contact has either the name or number OR a username
+ * that matches the query, add to the result.
*/
final boolean nameMatches = nameMatcher.matches(displayName);
final boolean numberMatches =
(nameMatcher.matchesNumber(phoneNumber, query) != null);
- if (nameMatches || numberMatches) {
+ if (nameMatches || numberMatches || usernameMatches) {
/** If a contact has not been added, add it to the result and the hash set.*/
duplicates.add(contactMatch);
result.add(new ContactNumber(id, dataID, displayName, phoneNumber, lookupKey,
- photoId));
+ photoId, mimeType));
counter++;
if (DEBUG) {
stopWatch.lap("Added one result: Name: " + displayName);
@@ -1103,4 +1138,41 @@ public class DialerDatabaseHelper extends SQLiteOpenHelper {
}
return result;
}
+
+ public HashMap<String, String> getCallableMimeTypeForContact(long contactId) {
+ final SQLiteDatabase db = getReadableDatabase();
+
+ final Cursor cursor = db.rawQuery("SELECT " +
+ SmartDialDbColumns.NUMBER + ", " +
+ SmartDialDbColumns.MIMETYPE +
+ " FROM " + Tables.SMARTDIAL_TABLE +
+ " WHERE " + SmartDialDbColumns.CONTACT_ID + " = ?",
+ new String[] {Long.toString(contactId)});
+
+ try {
+ if (cursor != null) {
+ HashMap<String, String> numbers = new HashMap<>();
+ while(cursor.moveToNext()) {
+
+ /** Gets the column ID from the cursor.*/
+ final int columnNumber = 0;
+ final int columnMimetype = 1;
+
+ final String phoneNumber = cursor.getString(columnNumber);
+ final String mimetype = cursor.getString(columnMimetype);
+
+ if (phoneNumber != null) {
+ numbers.put(mimetype, phoneNumber);
+ }
+ }
+ return numbers;
+ }
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+
+ return null;
+ }
}
diff --git a/src/com/android/dialer/dialpad/DialpadFragment.java b/src/com/android/dialer/dialpad/DialpadFragment.java
index b90e54bc5..d9fcbf059 100644
--- a/src/com/android/dialer/dialpad/DialpadFragment.java
+++ b/src/com/android/dialer/dialpad/DialpadFragment.java
@@ -150,7 +150,6 @@ public class DialpadFragment extends Fragment
public interface OnCallMethodChangedListener {
void onCallMethodChangedListener(CallMethodInfo cmi);
- void onCallMethodsAvailable(HashMap<ComponentName, CallMethodInfo> availableProviders);
}
public interface HostInterface {
@@ -544,7 +543,6 @@ public class DialpadFragment extends Fragment
private void providersUpdated(HashMap<ComponentName, CallMethodInfo> callMethodInfos) {
mAllAvailableProviders.clear();
CallMethodHelper.removeDisabled(callMethodInfos, mAllAvailableProviders);
- mCallMethodChangedListener.onCallMethodsAvailable(mAllAvailableProviders);
updateCallMethodSpinner();
}
diff --git a/src/com/android/dialer/dialpad/SmartDialCursorLoader.java b/src/com/android/dialer/dialpad/SmartDialCursorLoader.java
index 0a8c22370..fcfe3ae09 100644
--- a/src/com/android/dialer/dialpad/SmartDialCursorLoader.java
+++ b/src/com/android/dialer/dialpad/SmartDialCursorLoader.java
@@ -17,20 +17,28 @@
package com.android.dialer.dialpad;
import android.content.AsyncTaskLoader;
+import android.content.ContentUris;
import android.content.Context;
import android.content.Loader.ForceLoadContentObserver;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.net.Uri;
+import android.provider.ContactsContract;
+import android.text.TextUtils;
import android.util.Log;
import com.android.contacts.common.list.PhoneNumberListAdapter.PhoneQuery;
import com.android.contacts.common.util.PermissionsUtil;
+
+import com.android.phone.common.incall.CallMethodHelper;
+
import com.android.dialer.database.DialerDatabaseHelper;
import com.android.dialer.database.DialerDatabaseHelper.ContactNumber;
import com.android.dialerbind.DatabaseHelperManager;
import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
/**
* Implements a Loader<Cursor> class to asynchronously load SmartDial search results.
@@ -49,6 +57,9 @@ public class SmartDialCursorLoader extends AsyncTaskLoader<Cursor> {
private ForceLoadContentObserver mObserver;
+ private String mCallableMimetype;
+ public static final String CALLABLE_EXTRA_NUMBER = "callable_extra_number";
+
public SmartDialCursorLoader(Context context) {
super(context);
mContext = context;
@@ -58,7 +69,7 @@ public class SmartDialCursorLoader extends AsyncTaskLoader<Cursor> {
* Configures the query string to be used to find SmartDial matches.
* @param query The query string user typed.
*/
- public void configureQuery(String query) {
+ public void configureQuery(String query, String callableMimetype) {
if (DEBUG) {
Log.v(TAG, "Configure new query to be " + query);
}
@@ -66,6 +77,7 @@ public class SmartDialCursorLoader extends AsyncTaskLoader<Cursor> {
/** Constructs a name matcher object for matching names. */
mNameMatcher = new SmartDialNameMatcher(mQuery, SmartDialPrefix.getMap(), mContext);
+ mCallableMimetype = callableMimetype;
}
/**
@@ -86,23 +98,84 @@ public class SmartDialCursorLoader extends AsyncTaskLoader<Cursor> {
final DialerDatabaseHelper dialerDatabaseHelper = DatabaseHelperManager.getDatabaseHelper(
mContext);
final ArrayList<ContactNumber> allMatches = dialerDatabaseHelper.getLooseMatches(mQuery,
- mNameMatcher);
+ mNameMatcher, mCallableMimetype);
if (DEBUG) {
Log.v(TAG, "Loaded matches " + String.valueOf(allMatches.size()));
}
+ int projectionLength = PhoneQuery.PROJECTION_PRIMARY.length;
+ String [] projection = new String[projectionLength + 1];
+ System.arraycopy(PhoneQuery.PROJECTION_PRIMARY, 0, projection, 0, projectionLength);
+ projection[projectionLength] = CALLABLE_EXTRA_NUMBER;
+
/** Constructs a cursor for the returned array of results. */
- final MatrixCursor cursor = new MatrixCursor(PhoneQuery.PROJECTION_PRIMARY);
- Object[] row = new Object[PhoneQuery.PROJECTION_PRIMARY.length];
+ final MatrixCursor cursor = new MatrixCursor(projection);
+ Object[] row = new Object[projectionLength + 1];
for (ContactNumber contact : allMatches) {
- row[PhoneQuery.PHONE_ID] = contact.dataId;
- row[PhoneQuery.PHONE_NUMBER] = contact.phoneNumber;
- row[PhoneQuery.CONTACT_ID] = contact.id;
- row[PhoneQuery.LOOKUP_KEY] = contact.lookupKey;
- row[PhoneQuery.PHOTO_ID] = contact.photoId;
- row[PhoneQuery.DISPLAY_NAME] = contact.displayName;
- cursor.addRow(row);
+ if (TextUtils.equals(contact.mimeType, mCallableMimetype) ||
+ TextUtils.equals(contact.mimeType,
+ ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)) {
+ row[PhoneQuery.CONTACT_ID] = contact.id;
+ row[PhoneQuery.LOOKUP_KEY] = contact.lookupKey;
+ row[PhoneQuery.PHOTO_ID] = contact.photoId;
+ row[PhoneQuery.DISPLAY_NAME] = contact.displayName;
+ row[PhoneQuery.PHONE_ID] = contact.dataId;
+
+ // The row object is resued, so explicitly set this to null in case the contact
+ // doesn't have extra numbers
+ row[projectionLength] = null;
+
+ String accountType = null;
+ String accountName = null;
+ Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI,
+ contact.id);
+ Cursor c = mContext.getContentResolver().query(
+ contactUri,
+ new String[]{ContactsContract.RawContacts.ACCOUNT_TYPE,
+ ContactsContract.RawContacts.ACCOUNT_NAME},
+ null, null, null);
+ if (c != null && c.moveToFirst()) {
+ accountType = c.getString(0);
+ accountName = c.getString(1);
+ c.close();
+ }
+ row[PhoneQuery.PHONE_ACCOUNT_TYPE] = accountType;
+ row[PhoneQuery.PHONE_ACCOUNT_NAME] = accountName;
+
+ HashMap<String, String> allCallableNumbers = dialerDatabaseHelper
+ .getCallableMimeTypeForContact(contact.id);
+
+ // Add the phone number as the primary option ALWAYS
+ // IF we don't do this, things often show up strange (only a UN w/o PN)
+ // if the user has no phone number tied to their account, then we can show other
+ // items. We do this for consistencies sake.
+ String extraContactNumber;
+ boolean gotStandardNumber = false;
+ if (allCallableNumbers.containsKey(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)) {
+ extraContactNumber = allCallableNumbers.get(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
+
+ row[PhoneQuery.PHONE_NUMBER] = extraContactNumber;
+ row[PhoneQuery.PHONE_MIME_TYPE] =
+ ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE;
+
+ gotStandardNumber = true;
+ }
+
+ if (allCallableNumbers.containsKey(mCallableMimetype)) {
+ extraContactNumber = allCallableNumbers.get(mCallableMimetype);
+ // Make sure the extra number is not the same as the main number
+ if (gotStandardNumber) {
+ row[projectionLength] = extraContactNumber;
+ } else {
+ row[PhoneQuery.PHONE_NUMBER] = extraContactNumber;
+ row[PhoneQuery.PHONE_MIME_TYPE] = mCallableMimetype;
+ }
+ }
+
+
+ cursor.addRow(row);
+ }
}
return cursor;
}
diff --git a/src/com/android/dialer/dialpad/SmartDialNameMatcher.java b/src/com/android/dialer/dialpad/SmartDialNameMatcher.java
index 4daf0c837..38ee947cd 100644
--- a/src/com/android/dialer/dialpad/SmartDialNameMatcher.java
+++ b/src/com/android/dialer/dialpad/SmartDialNameMatcher.java
@@ -261,6 +261,11 @@ public class SmartDialNameMatcher {
@VisibleForTesting
boolean matchesCombination(String displayName, String query,
ArrayList<SmartDialMatchPosition> matchList) {
+
+ if (displayName == null) {
+ return false;
+ }
+
StringBuilder builder = new StringBuilder();
constructEmptyMask(builder, displayName.length());
mNameMatchMask = builder.toString();
diff --git a/src/com/android/dialer/list/DialerPhoneNumberListAdapter.java b/src/com/android/dialer/list/DialerPhoneNumberListAdapter.java
index 401b0b641..0ca8e56f6 100644
--- a/src/com/android/dialer/list/DialerPhoneNumberListAdapter.java
+++ b/src/com/android/dialer/list/DialerPhoneNumberListAdapter.java
@@ -5,9 +5,11 @@ import android.content.res.Resources;
import android.telephony.PhoneNumberUtils;
import android.text.BidiFormatter;
import android.text.TextDirectionHeuristics;
+import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.TextView;
import com.android.contacts.common.GeoUtil;
import com.android.contacts.common.list.ContactListItemView;
import com.android.contacts.common.list.PhoneNumberListAdapter;
@@ -27,25 +29,35 @@ public class DialerPhoneNumberListAdapter extends PhoneNumberListAdapter {
private String mFormattedQueryString;
private String mCountryIso;
+ public final static int SHORTCUT_INVALID_PROVIDER = -2;
public final static int SHORTCUT_INVALID = -1;
public final static int SHORTCUT_DIRECT_CALL = 0;
public final static int SHORTCUT_CREATE_NEW_CONTACT = 1;
public final static int SHORTCUT_ADD_TO_EXISTING_CONTACT = 2;
public final static int SHORTCUT_SEND_SMS_MESSAGE = 3;
public final static int SHORTCUT_MAKE_VIDEO_CALL = 4;
+ public final static int SHORTCUT_MAKE_INCALL_PROVIDER_CALL = 5;
- public final static int SHORTCUT_COUNT = 5;
+ public static int SHORTCUT_COUNT = 6;
private final boolean[] mShortcutEnabled = new boolean[SHORTCUT_COUNT];
+ private int mShortcutCurrent = SHORTCUT_INVALID;
+
private final BidiFormatter mBidiFormatter = BidiFormatter.getInstance();
+ private searchMethodClicked mSearchMethodListener = null;
+
public DialerPhoneNumberListAdapter(Context context) {
super(context);
mCountryIso = GeoUtil.getCurrentCountryIso(context);
}
+ public void setSearchListner(searchMethodClicked clickedListener) {
+ mSearchMethodListener = clickedListener;
+ }
+
@Override
public int getCount() {
return super.getCount() + getShortcutCount();
@@ -121,7 +133,11 @@ public class DialerPhoneNumberListAdapter extends PhoneNumberListAdapter {
throw new IllegalArgumentException("Invalid position - greater than cursor count "
+ " but not a shortcut.");
}
- return SHORTCUT_INVALID;
+
+ int returningShortcut = mShortcutCurrent;
+ mShortcutCurrent = SHORTCUT_INVALID;
+
+ return returningShortcut;
}
@Override
@@ -167,6 +183,12 @@ public class DialerPhoneNumberListAdapter extends PhoneNumberListAdapter {
text = resources.getString(R.string.search_shortcut_make_video_call);
drawableId = R.drawable.ic_videocam;
break;
+ case SHORTCUT_MAKE_INCALL_PROVIDER_CALL:
+ text = resources.getString(
+ R.string.search_shortcut_call_number,
+ mBidiFormatter.unicodeWrap(number, TextDirectionHeuristics.LTR));
+ drawableId = R.drawable.ic_videocam;
+ break;
default:
throw new IllegalArgumentException("Invalid shortcut type");
}
@@ -176,6 +198,22 @@ public class DialerPhoneNumberListAdapter extends PhoneNumberListAdapter {
v.setAdjustSelectionBoundsEnabled(false);
}
+ public interface searchMethodClicked {
+ void onItemClick(int position, long id);
+ }
+
+ @Override
+ public View.OnClickListener bindExtraCallActionOnClick(TextView v, String text,
+ final int position) {
+ return new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ mShortcutCurrent = SHORTCUT_INVALID_PROVIDER;
+ mSearchMethodListener.onItemClick(position, 0L);
+ }
+ };
+ }
+
/**
* @return True if the shortcut state (disabled vs enabled) was changed by this operation
*/
diff --git a/src/com/android/dialer/list/RegularSearchListAdapter.java b/src/com/android/dialer/list/RegularSearchListAdapter.java
index 944fec64f..fe5040f3a 100644
--- a/src/com/android/dialer/list/RegularSearchListAdapter.java
+++ b/src/com/android/dialer/list/RegularSearchListAdapter.java
@@ -104,6 +104,8 @@ public class RegularSearchListAdapter extends DialerPhoneNumberListAdapter {
changed |= setShortcutEnabled(SHORTCUT_SEND_SMS_MESSAGE, showNumberShortcuts);
changed |= setShortcutEnabled(SHORTCUT_MAKE_VIDEO_CALL,
showNumberShortcuts && CallUtil.isVideoEnabled(getContext()));
+ changed |= setShortcutEnabled(SHORTCUT_MAKE_INCALL_PROVIDER_CALL, showNumberShortcuts);
+
if (changed) {
notifyDataSetChanged();
}
diff --git a/src/com/android/dialer/list/SearchFragment.java b/src/com/android/dialer/list/SearchFragment.java
index 9f9ea7bb6..eb5c13bd1 100644
--- a/src/com/android/dialer/list/SearchFragment.java
+++ b/src/com/android/dialer/list/SearchFragment.java
@@ -54,8 +54,10 @@ import com.android.dialer.util.DialerUtils;
import com.android.dialer.util.IntentUtil;
import com.android.dialer.widget.EmptyContentView;
import com.android.phone.common.animation.AnimUtils;
+import com.android.phone.common.incall.CallMethodInfo;
-public class SearchFragment extends PhoneNumberPickerFragment {
+public class SearchFragment extends PhoneNumberPickerFragment
+ implements DialerPhoneNumberListAdapter.searchMethodClicked {
private static final String TAG = SearchFragment.class.getSimpleName();
private OnListFragmentScrolledListener mActivityScrollListener;
@@ -84,6 +86,8 @@ public class SearchFragment extends PhoneNumberPickerFragment {
protected EmptyContentView mEmptyView;
+ public CallMethodInfo mCurrentCallMethodInfo;
+
public interface HostInterface {
public boolean isActionBarShowing();
public boolean isDialpadShown();
@@ -229,13 +233,15 @@ public class SearchFragment extends PhoneNumberPickerFragment {
DialerPhoneNumberListAdapter adapter = new DialerPhoneNumberListAdapter(getActivity());
adapter.setDisplayPhotos(true);
adapter.setUseCallableUri(super.usesCallableUri());
+ adapter.setSearchListner(this);
return adapter;
}
@Override
- protected void onItemClick(int position, long id) {
+ public void onItemClick(int position, long id) {
final DialerPhoneNumberListAdapter adapter = (DialerPhoneNumberListAdapter) getAdapter();
final int shortcutType = adapter.getShortcutTypeFromPosition(position);
+
final OnPhoneNumberPickerActionListener listener;
final Intent intent;
final String number;
@@ -243,6 +249,9 @@ public class SearchFragment extends PhoneNumberPickerFragment {
Log.i(TAG, "onItemClick: shortcutType=" + shortcutType);
switch (shortcutType) {
+ case DialerPhoneNumberListAdapter.SHORTCUT_INVALID_PROVIDER:
+ super.onProviderClick(position, id, getCurrentCallMethod());
+ break;
case DialerPhoneNumberListAdapter.SHORTCUT_INVALID:
super.onItemClick(position, id);
break;
@@ -283,6 +292,15 @@ public class SearchFragment extends PhoneNumberPickerFragment {
}
}
+ public void setCurrentCallMethod(CallMethodInfo cmi) {
+ mCurrentCallMethodInfo = cmi;
+ setupEmptyView();
+ }
+
+ public CallMethodInfo getCurrentCallMethod() {
+ return mCurrentCallMethodInfo;
+ }
+
/**
* Updates the position and padding of the search fragment, depending on whether the dialpad is
* shown. This can be optionally animated.
@@ -355,7 +373,7 @@ public class SearchFragment extends PhoneNumberPickerFragment {
@Override
protected void startLoading() {
- if (PermissionsUtil.hasPermission(getActivity(), READ_CONTACTS)) {
+ if (isAdded() && PermissionsUtil.hasPermission(getActivity(), READ_CONTACTS)) {
super.startLoading();
} else if (TextUtils.isEmpty(getQueryString())) {
// Clear out any existing call shortcuts.
diff --git a/src/com/android/dialer/list/SmartDialNumberListAdapter.java b/src/com/android/dialer/list/SmartDialNumberListAdapter.java
index 5563b0f91..00dbd017b 100644
--- a/src/com/android/dialer/list/SmartDialNumberListAdapter.java
+++ b/src/com/android/dialer/list/SmartDialNumberListAdapter.java
@@ -44,6 +44,7 @@ public class SmartDialNumberListAdapter extends DialerPhoneNumberListAdapter {
private final Context mContext;
private SmartDialNameMatcher mNameMatcher;
+ SmartDialCursorLoader mLoader;
public SmartDialNumberListAdapter(Context context) {
super(context);
@@ -55,10 +56,15 @@ public class SmartDialNumberListAdapter extends DialerPhoneNumberListAdapter {
}
}
+ public SmartDialCursorLoader getLoader() {
+ return mLoader;
+ }
+
/**
* Sets query for the SmartDialCursorLoader.
*/
- public void configureLoader(SmartDialCursorLoader loader) {
+ public void configureLoader(SmartDialCursorLoader loader, String mimeType) {
+ mLoader = loader;
if (DEBUG) {
Log.v(TAG, "Configure Loader with query" + getQueryString());
}
@@ -66,10 +72,10 @@ public class SmartDialNumberListAdapter extends DialerPhoneNumberListAdapter {
mNameMatcher = new SmartDialNameMatcher("", SmartDialPrefix.getMap(), mContext);
if (getQueryString() == null) {
- loader.configureQuery("");
+ mLoader.configureQuery("", mimeType);
mNameMatcher.setQuery("");
} else {
- loader.configureQuery(getQueryString());
+ mLoader.configureQuery(getQueryString(), mimeType);
mNameMatcher.setQuery(PhoneNumberUtils.normalizeNumber(getQueryString()));
}
}
@@ -126,6 +132,8 @@ public class SmartDialNumberListAdapter extends DialerPhoneNumberListAdapter {
changed |= setShortcutEnabled(SHORTCUT_SEND_SMS_MESSAGE, showNumberShortcuts);
changed |= setShortcutEnabled(SHORTCUT_MAKE_VIDEO_CALL,
showNumberShortcuts && CallUtil.isVideoEnabled(getContext()));
+ changed |= setShortcutEnabled(SHORTCUT_MAKE_INCALL_PROVIDER_CALL, showNumberShortcuts);
+
if (changed) {
notifyDataSetChanged();
}
diff --git a/src/com/android/dialer/list/SmartDialSearchFragment.java b/src/com/android/dialer/list/SmartDialSearchFragment.java
index 6d638e323..08fc2be27 100644
--- a/src/com/android/dialer/list/SmartDialSearchFragment.java
+++ b/src/com/android/dialer/list/SmartDialSearchFragment.java
@@ -57,12 +57,12 @@ import java.util.Random;
* Implements a fragment to load and display SmartDial search results.
*/
public class SmartDialSearchFragment extends SearchFragment
- implements EmptyContentView.OnEmptyViewActionButtonClickedListener {
+ implements EmptyContentView.OnEmptyViewActionButtonClickedListener,
+ DialerPhoneNumberListAdapter.searchMethodClicked {
private static final String TAG = SmartDialSearchFragment.class.getSimpleName();
private static final int CALL_PHONE_PERMISSION_REQUEST_CODE = 1;
- private CallMethodInfo mCurrentCallMethod;
private HashMap<ComponentName, CallMethodInfo> mAvailableCallMethods;
/**
@@ -75,6 +75,8 @@ public class SmartDialSearchFragment extends SearchFragment
adapter.setQuickContactEnabled(true);
// Set adapter's query string to restore previous instance state.
adapter.setQueryString(getQueryString());
+ adapter.setSearchListner(this);
+
return adapter;
}
@@ -87,10 +89,7 @@ public class SmartDialSearchFragment extends SearchFragment
if (id == getDirectoryLoaderId()) {
return super.onCreateLoader(id, args);
} else {
- final SmartDialNumberListAdapter adapter = (SmartDialNumberListAdapter) getAdapter();
- SmartDialCursorLoader loader = new SmartDialCursorLoader(super.getContext());
- adapter.configureLoader(loader);
- return loader;
+ return updateData();
}
}
@@ -105,13 +104,27 @@ public class SmartDialSearchFragment extends SearchFragment
return adapter.getDataUri(position);
}
+ private Loader<Cursor> updateData() {
+ final SmartDialNumberListAdapter adapter = (SmartDialNumberListAdapter) getAdapter();
+
+ SmartDialCursorLoader loader = new SmartDialCursorLoader(super.getContext());
+
+ if (mCurrentCallMethodInfo != null) {
+ adapter.configureLoader(loader, mCurrentCallMethodInfo.mMimeType);
+ } else {
+ adapter.configureLoader(loader, null);
+ }
+
+ return loader;
+ }
+
@Override
public void setupEmptyView() {
final SmartDialNumberListAdapter adapter = (SmartDialNumberListAdapter) getAdapter();
adapter.getCount();
- if (mCurrentCallMethod == null) {
- mCurrentCallMethod = ((DialtactsActivity) getActivity()).getCurrentCallMethod();
+ if (mCurrentCallMethodInfo == null) {
+ mCurrentCallMethodInfo = ((DialtactsActivity) getActivity()).getCurrentCallMethod();
}
if (mEmptyView != null && getActivity() != null) {
@@ -130,10 +143,10 @@ public class SmartDialSearchFragment extends SearchFragment
// the currently available ones are fine.
mAvailableCallMethods = CallMethodHelper.getAllCallMethods();
- if (mCurrentCallMethod == null && mAvailableCallMethods.isEmpty()) {
+ if (mCurrentCallMethodInfo == null && mAvailableCallMethods.isEmpty()) {
showNormalT9Hint(r);
} else {
- if (mCurrentCallMethod != null && mCurrentCallMethod.mIsInCallProvider) {
+ if (mCurrentCallMethodInfo != null && mCurrentCallMethodInfo.mIsInCallProvider) {
showProviderHint(r);
} else {
showSuggestion(r);
@@ -165,14 +178,14 @@ public class SmartDialSearchFragment extends SearchFragment
public void showProviderHint(Resources r) {
String text;
- if (!mCurrentCallMethod.mIsAuthenticated) {
+ if (!mCurrentCallMethodInfo.mIsAuthenticated) {
// Sign into current selected call method to make calls
- text = getString(R.string.sign_in_hint_text, mCurrentCallMethod.mName);
+ text = getString(R.string.sign_in_hint_text, mCurrentCallMethodInfo.mName);
} else {
// InCallApi provider specified hint
- text = mCurrentCallMethod.mT9HintDescription;
+ text = mCurrentCallMethodInfo.mT9HintDescription;
}
- Drawable heroImage = mCurrentCallMethod.mSingleColorBrandIcon;
+ Drawable heroImage = mCurrentCallMethodInfo.mSingleColorBrandIcon;
heroImage.setTint(r.getColor(R.color.hint_image_color));
mEmptyView.setImage(heroImage);
mEmptyView.setDescription(text);
@@ -186,17 +199,17 @@ public class SmartDialSearchFragment extends SearchFragment
NetworkInfo mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
- if (mWifi.isConnected() && !mAvailableCallMethods.isEmpty() && mCurrentCallMethod != null) {
+ if (mWifi.isConnected() && !mAvailableCallMethods.isEmpty() && mCurrentCallMethodInfo != null) {
String template;
Drawable heroImage;
String text;
TelephonyManager tm =
(TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE);
- if (tm.isNetworkRoaming(mCurrentCallMethod.mSubId)) {
+ if (tm.isNetworkRoaming(mCurrentCallMethodInfo.mSubId)) {
heroImage = r.getDrawable(R.drawable.ic_roaming);
template = r.getString(R.string.roaming_hint_text);
- text = String.format(template, mCurrentCallMethod.mName, hintTextRequest());
+ text = String.format(template, mCurrentCallMethodInfo.mName, hintTextRequest());
} else {
heroImage = r.getDrawable(R.drawable.ic_signal_wifi_3_bar);
template = r.getString(R.string.wifi_hint_text);
@@ -219,9 +232,10 @@ public class SmartDialSearchFragment extends SearchFragment
return valuesList.get(randomIndex).mName;
}
+ @Override
public void setCurrentCallMethod(CallMethodInfo cmi) {
- mCurrentCallMethod = cmi;
- setupEmptyView();
+ super.setCurrentCallMethod(cmi);
+ reloadData();
}
public void setAvailableCallMethods(HashMap<ComponentName, CallMethodInfo> callMethods) {
diff --git a/tests/src/com/android/dialer/database/SmartDialPrefixTest.java b/tests/src/com/android/dialer/database/SmartDialPrefixTest.java
index 796303d78..4588ac727 100644
--- a/tests/src/com/android/dialer/database/SmartDialPrefixTest.java
+++ b/tests/src/com/android/dialer/database/SmartDialPrefixTest.java
@@ -137,13 +137,13 @@ public class SmartDialPrefixTest extends AndroidTestCase {
private ContactNumber constructNewContactWithDummyIds(MatrixCursor contactCursor,
MatrixCursor nameCursor, String number, int id, String displayName) {
return constructNewContact(contactCursor, nameCursor, id, number, id, String.valueOf(id),
- displayName, 0, 0, 0, 0, 0, 0, 0);
+ displayName, 0, 0, 0, 0, 0, 0, 0, null);
}
private ContactNumber constructNewContact(MatrixCursor contactCursor, MatrixCursor nameCursor,
int id, String number, int contactId, String lookupKey, String displayName, int photoId,
int lastTimeUsed, int timesUsed, int starred, int isSuperPrimary, int inVisibleGroup,
- int isPrimary) {
+ int isPrimary, String mimetype) {
assertNotNull(contactCursor);
assertNotNull(nameCursor);
@@ -158,13 +158,13 @@ public class SmartDialPrefixTest extends AndroidTestCase {
isPrimary});
nameCursor.addRow(new Object[]{displayName, contactId});
- return new ContactNumber(contactId, id, displayName, number, lookupKey, 0);
+ return new ContactNumber(contactId, id, displayName, number, lookupKey, 0, mimetype);
}
private ArrayList<ContactNumber> getLooseMatchesFromDb(String query) {
final SmartDialNameMatcher nameMatcher = new SmartDialNameMatcher(query,
SmartDialPrefix.getMap(), getContext());
- return mTestHelper.getLooseMatches(query, nameMatcher);
+ return mTestHelper.getLooseMatches(query, nameMatcher, null);
}
public void testPutForFullName() {