summaryrefslogtreecommitdiff
path: root/java/com/android/dialer/app/list
diff options
context:
space:
mode:
Diffstat (limited to 'java/com/android/dialer/app/list')
-rw-r--r--java/com/android/dialer/app/list/AllContactsFragment.java20
-rw-r--r--java/com/android/dialer/app/list/DialerPhoneNumberListAdapter.java34
-rw-r--r--java/com/android/dialer/app/list/DialerViewPager.java55
-rw-r--r--java/com/android/dialer/app/list/DialtactsPagerAdapter.java31
-rw-r--r--java/com/android/dialer/app/list/ListsFragment.java44
-rw-r--r--java/com/android/dialer/app/list/OldSpeedDialFragment.java31
-rw-r--r--java/com/android/dialer/app/list/PhoneFavoriteListView.java19
-rw-r--r--java/com/android/dialer/app/list/PhoneFavoriteSquareTileView.java4
-rw-r--r--java/com/android/dialer/app/list/PhoneFavoriteTileView.java72
-rw-r--r--java/com/android/dialer/app/list/PhoneFavoritesTileAdapter.java82
-rw-r--r--java/com/android/dialer/app/list/RegularSearchFragment.java63
-rw-r--r--java/com/android/dialer/app/list/RemoveView.java2
-rw-r--r--java/com/android/dialer/app/list/SearchFragment.java29
-rw-r--r--java/com/android/dialer/app/list/SmartDialNumberListAdapter.java10
-rw-r--r--java/com/android/dialer/app/list/SmartDialSearchFragment.java22
15 files changed, 388 insertions, 130 deletions
diff --git a/java/com/android/dialer/app/list/AllContactsFragment.java b/java/com/android/dialer/app/list/AllContactsFragment.java
index 04609970a..32a99e795 100644
--- a/java/com/android/dialer/app/list/AllContactsFragment.java
+++ b/java/com/android/dialer/app/list/AllContactsFragment.java
@@ -38,12 +38,16 @@ import com.android.contacts.common.list.ContactEntryListFragment;
import com.android.contacts.common.list.ContactListFilter;
import com.android.contacts.common.list.DefaultContactListAdapter;
import com.android.dialer.app.R;
-import com.android.dialer.app.widget.EmptyContentView;
-import com.android.dialer.app.widget.EmptyContentView.OnEmptyViewActionButtonClickedListener;
+import com.android.dialer.common.LogUtil;
import com.android.dialer.compat.CompatUtils;
+import com.android.dialer.logging.InteractionEvent;
+import com.android.dialer.logging.Logger;
import com.android.dialer.util.DialerUtils;
import com.android.dialer.util.IntentUtil;
import com.android.dialer.util.PermissionsUtil;
+import com.android.dialer.widget.EmptyContentView;
+import com.android.dialer.widget.EmptyContentView.OnEmptyViewActionButtonClickedListener;
+import java.util.Arrays;
/** Fragments to show all contacts with phone numbers. */
public class AllContactsFragment extends ContactEntryListFragment<ContactEntryListAdapter>
@@ -149,6 +153,8 @@ public class AllContactsFragment extends ContactEntryListFragment<ContactEntryLi
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final Uri uri = (Uri) view.getTag();
if (uri != null) {
+ Logger.get(getContext())
+ .logInteraction(InteractionEvent.Type.OPEN_QUICK_CONTACT_FROM_ALL_CONTACTS_GENERAL);
if (CompatUtils.hasPrioritizedMimeType()) {
QuickContact.showQuickContact(getContext(), view, uri, null, Phone.CONTENT_ITEM_TYPE);
} else {
@@ -169,9 +175,15 @@ public class AllContactsFragment extends ContactEntryListFragment<ContactEntryLi
return;
}
- if (!PermissionsUtil.hasPermission(activity, READ_CONTACTS)) {
+ String[] deniedPermissions =
+ PermissionsUtil.getPermissionsCurrentlyDenied(
+ getContext(), PermissionsUtil.allContactsGroupPermissionsUsedInDialer);
+ if (deniedPermissions.length > 0) {
+ LogUtil.i(
+ "AllContactsFragment.onEmptyViewActionButtonClicked",
+ "Requesting permissions: " + Arrays.toString(deniedPermissions));
FragmentCompat.requestPermissions(
- this, new String[] {READ_CONTACTS}, READ_CONTACTS_PERMISSION_REQUEST_CODE);
+ this, deniedPermissions, READ_CONTACTS_PERMISSION_REQUEST_CODE);
} else {
// Add new contact
DialerUtils.startActivityWithErrorToast(
diff --git a/java/com/android/dialer/app/list/DialerPhoneNumberListAdapter.java b/java/com/android/dialer/app/list/DialerPhoneNumberListAdapter.java
index 537f488d5..fc0bd3ccf 100644
--- a/java/com/android/dialer/app/list/DialerPhoneNumberListAdapter.java
+++ b/java/com/android/dialer/app/list/DialerPhoneNumberListAdapter.java
@@ -19,6 +19,8 @@ package com.android.dialer.app.list;
import android.content.Context;
import android.content.res.Resources;
import android.database.Cursor;
+import android.graphics.drawable.Drawable;
+import android.support.v4.content.ContextCompat;
import android.telephony.PhoneNumberUtils;
import android.text.BidiFormatter;
import android.text.TextDirectionHeuristics;
@@ -29,7 +31,6 @@ import com.android.contacts.common.list.PhoneNumberListAdapter;
import com.android.contacts.common.util.ContactDisplayUtils;
import com.android.dialer.app.R;
import com.android.dialer.location.GeoUtil;
-import com.android.dialer.util.CallUtil;
/**
* {@link PhoneNumberListAdapter} with the following added shortcuts, that are displayed as list
@@ -50,7 +51,6 @@ public class DialerPhoneNumberListAdapter extends PhoneNumberListAdapter {
private final boolean[] mShortcutEnabled = new boolean[SHORTCUT_COUNT];
private final BidiFormatter mBidiFormatter = BidiFormatter.getInstance();
- private final boolean mVideoCallingEnabled;
private final String mCountryIso;
private String mFormattedQueryString;
@@ -59,7 +59,6 @@ public class DialerPhoneNumberListAdapter extends PhoneNumberListAdapter {
super(context);
mCountryIso = GeoUtil.getCurrentCountryIso(context);
- mVideoCallingEnabled = CallUtil.isVideoEnabled(context);
}
@Override
@@ -110,8 +109,7 @@ public class DialerPhoneNumberListAdapter extends PhoneNumberListAdapter {
return convertView;
} else {
final ContactListItemView v =
- new ContactListItemView(
- getContext(), null, mVideoCallingEnabled, isCallAndShareEnabled());
+ new ContactListItemView(getContext(), null, mIsImsVideoEnabled);
assignShortcutToView(v, shortcutType);
return v;
}
@@ -125,8 +123,7 @@ public class DialerPhoneNumberListAdapter extends PhoneNumberListAdapter {
Context context, int partition, Cursor cursor, int position, ViewGroup parent) {
final ContactListItemView view = super.newView(context, partition, cursor, position, parent);
- view.setSupportVideoCallIcon(mVideoCallingEnabled);
- view.setSupportCallAndShareIcon(isCallAndShareEnabled());
+ view.setSupportVideoCallIcon(mIsImsVideoEnabled);
return view;
}
@@ -171,7 +168,7 @@ public class DialerPhoneNumberListAdapter extends PhoneNumberListAdapter {
private void assignShortcutToView(ContactListItemView v, int shortcutType) {
final CharSequence text;
- final int drawableId;
+ final Drawable drawable;
final Resources resources = getContext().getResources();
final String number = getFormattedQueryString();
switch (shortcutType) {
@@ -181,34 +178,39 @@ public class DialerPhoneNumberListAdapter extends PhoneNumberListAdapter {
resources,
R.string.search_shortcut_call_number,
mBidiFormatter.unicodeWrap(number, TextDirectionHeuristics.LTR));
- drawableId = R.drawable.ic_search_phone;
+ drawable = ContextCompat.getDrawable(getContext(), R.drawable.quantum_ic_call_vd_theme_24);
break;
case SHORTCUT_CREATE_NEW_CONTACT:
text = resources.getString(R.string.search_shortcut_create_new_contact);
- drawableId = R.drawable.ic_search_add_contact;
+ drawable =
+ ContextCompat.getDrawable(getContext(), R.drawable.quantum_ic_person_add_vd_theme_24);
+ drawable.setAutoMirrored(true);
break;
case SHORTCUT_ADD_TO_EXISTING_CONTACT:
text = resources.getString(R.string.search_shortcut_add_to_contact);
- drawableId = R.drawable.quantum_ic_person_white_24;
+ drawable =
+ ContextCompat.getDrawable(getContext(), R.drawable.quantum_ic_person_add_vd_theme_24);
break;
case SHORTCUT_SEND_SMS_MESSAGE:
text = resources.getString(R.string.search_shortcut_send_sms_message);
- drawableId = R.drawable.quantum_ic_message_white_24;
+ drawable =
+ ContextCompat.getDrawable(getContext(), R.drawable.quantum_ic_message_vd_theme_24);
break;
case SHORTCUT_MAKE_VIDEO_CALL:
text = resources.getString(R.string.search_shortcut_make_video_call);
- drawableId = R.drawable.quantum_ic_videocam_white_24;
+ drawable =
+ ContextCompat.getDrawable(getContext(), R.drawable.quantum_ic_videocam_vd_theme_24);
break;
case SHORTCUT_BLOCK_NUMBER:
text = resources.getString(R.string.search_shortcut_block_number);
- drawableId = R.drawable.ic_not_interested_googblue_24dp;
+ drawable =
+ ContextCompat.getDrawable(getContext(), R.drawable.ic_not_interested_googblue_24dp);
break;
default:
throw new IllegalArgumentException("Invalid shortcut type");
}
- v.setDrawableResource(drawableId);
+ v.setDrawable(drawable);
v.setDisplayName(text);
- v.setPhotoPosition(super.getPhotoPosition());
v.setAdjustSelectionBoundsEnabled(false);
}
diff --git a/java/com/android/dialer/app/list/DialerViewPager.java b/java/com/android/dialer/app/list/DialerViewPager.java
new file mode 100644
index 000000000..ae99f0521
--- /dev/null
+++ b/java/com/android/dialer/app/list/DialerViewPager.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2017 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.dialer.app.list;
+
+import android.content.Context;
+import android.support.v4.view.ViewPager;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+
+/** Class that handles enabling/disabling swiping between @{ViewPagerTabs}. */
+public class DialerViewPager extends ViewPager {
+
+ private boolean enableSwipingPages;
+
+ public DialerViewPager(Context context, AttributeSet attributeSet) {
+ super(context, attributeSet);
+ enableSwipingPages = true;
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent event) {
+ if (enableSwipingPages) {
+ return super.onInterceptTouchEvent(event);
+ }
+
+ return false;
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ if (enableSwipingPages) {
+ return super.onTouchEvent(event);
+ }
+
+ return false;
+ }
+
+ public void setEnableSwipingPages(boolean enabled) {
+ enableSwipingPages = enabled;
+ }
+}
diff --git a/java/com/android/dialer/app/list/DialtactsPagerAdapter.java b/java/com/android/dialer/app/list/DialtactsPagerAdapter.java
index dba3d3a93..1fbf0f01a 100644
--- a/java/com/android/dialer/app/list/DialtactsPagerAdapter.java
+++ b/java/com/android/dialer/app/list/DialtactsPagerAdapter.java
@@ -24,13 +24,12 @@ import android.support.v13.app.FragmentPagerAdapter;
import android.view.ViewGroup;
import com.android.dialer.app.calllog.CallLogFragment;
import com.android.dialer.app.calllog.VisualVoicemailCallLogFragment;
-import com.android.dialer.calllog.CallLogComponent;
-import com.android.dialer.calllog.CallLogFramework;
-import com.android.dialer.calllog.ui.NewCallLogFragment;
import com.android.dialer.common.Assert;
-import com.android.dialer.common.ConfigProviderBindings;
import com.android.dialer.common.LogUtil;
+import com.android.dialer.configprovider.ConfigProviderBindings;
import com.android.dialer.contactsfragment.ContactsFragment;
+import com.android.dialer.contactsfragment.ContactsFragment.ClickAction;
+import com.android.dialer.contactsfragment.ContactsFragment.Header;
import com.android.dialer.database.CallLogQueryHandler;
import com.android.dialer.speeddial.SpeedDialFragment;
import com.android.dialer.util.ViewUtil;
@@ -58,12 +57,10 @@ public class DialtactsPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> fragments = new ArrayList<>();
private final String[] tabTitles;
private final boolean useNewSpeedDialTab;
- private final boolean useNewCallLogTab;
private final boolean useNewContactsTab;
private OldSpeedDialFragment oldSpeedDialFragment;
private SpeedDialFragment speedDialFragment;
private CallLogFragment callLogFragment;
- private NewCallLogFragment newCallLogFragment;
private AllContactsFragment oldContactsFragment;
private ContactsFragment contactsFragment;
private CallLogFragment voicemailFragment;
@@ -75,10 +72,8 @@ public class DialtactsPagerAdapter extends FragmentPagerAdapter {
super(fm);
useNewSpeedDialTab =
ConfigProviderBindings.get(context).getBoolean("enable_new_favorites_tab", false);
- CallLogFramework callLogFramework = CallLogComponent.get(context).callLogFramework();
- useNewCallLogTab = callLogFramework.isNewCallLogEnabled(context);
useNewContactsTab =
- ConfigProviderBindings.get(context).getBoolean("enable_new_contacts_tab", false);
+ ConfigProviderBindings.get(context).getBoolean("enable_new_contacts_tab", true);
this.tabTitles = tabTitles;
hasActiveVoicemailProvider = hasVoicemailProvider;
fragments.addAll(Collections.nCopies(TAB_COUNT_WITH_VOICEMAIL, null));
@@ -106,21 +101,15 @@ public class DialtactsPagerAdapter extends FragmentPagerAdapter {
return oldSpeedDialFragment;
}
case TAB_INDEX_HISTORY:
- if (useNewCallLogTab) {
- if (newCallLogFragment == null) {
- newCallLogFragment = new NewCallLogFragment();
- }
- return newCallLogFragment;
- } else {
- if (callLogFragment == null) {
- callLogFragment = new CallLogFragment(CallLogQueryHandler.CALL_TYPE_ALL);
- }
- return callLogFragment;
+ if (callLogFragment == null) {
+ callLogFragment = new CallLogFragment(CallLogQueryHandler.CALL_TYPE_ALL);
}
+ return callLogFragment;
case TAB_INDEX_ALL_CONTACTS:
if (useNewContactsTab) {
if (contactsFragment == null) {
- contactsFragment = new ContactsFragment();
+ contactsFragment =
+ ContactsFragment.newInstance(Header.ADD_CONTACT, ClickAction.OPEN_CONTACT_CARD);
}
return contactsFragment;
} else {
@@ -156,8 +145,6 @@ public class DialtactsPagerAdapter extends FragmentPagerAdapter {
speedDialFragment = (SpeedDialFragment) fragment;
} else if (fragment instanceof CallLogFragment && position == TAB_INDEX_HISTORY) {
callLogFragment = (CallLogFragment) fragment;
- } else if (fragment instanceof NewCallLogFragment) {
- newCallLogFragment = (NewCallLogFragment) fragment;
} else if (fragment instanceof ContactsFragment) {
contactsFragment = (ContactsFragment) fragment;
} else if (fragment instanceof AllContactsFragment) {
diff --git a/java/com/android/dialer/app/list/ListsFragment.java b/java/com/android/dialer/app/list/ListsFragment.java
index 8dd52a9d4..86a3d2fbb 100644
--- a/java/com/android/dialer/app/list/ListsFragment.java
+++ b/java/com/android/dialer/app/list/ListsFragment.java
@@ -31,7 +31,6 @@ import android.os.Handler;
import android.os.Trace;
import android.preference.PreferenceManager;
import android.provider.VoicemailContract;
-import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.LayoutInflater;
import android.view.View;
@@ -44,9 +43,12 @@ import com.android.dialer.app.voicemail.error.VoicemailStatusCorruptionHandler;
import com.android.dialer.app.voicemail.error.VoicemailStatusCorruptionHandler.Source;
import com.android.dialer.common.LogUtil;
import com.android.dialer.database.CallLogQueryHandler;
+import com.android.dialer.database.CallLogQueryHandler.Listener;
import com.android.dialer.logging.DialerImpression;
import com.android.dialer.logging.Logger;
import com.android.dialer.logging.ScreenEvent;
+import com.android.dialer.logging.UiAction;
+import com.android.dialer.performancereport.PerformanceReport;
import com.android.dialer.speeddial.SpeedDialFragment;
import com.android.dialer.util.PermissionsUtil;
import com.android.dialer.voicemailstatus.VisualVoicemailEnabledChecker;
@@ -60,11 +62,11 @@ import java.util.ArrayList;
* Contacts list. This will also eventually contain the logic that allows sliding the ViewPager
* containing the lists up above the search bar and pin it against the top of the screen.
*/
-public class ListsFragment extends Fragment
- implements ViewPager.OnPageChangeListener, CallLogQueryHandler.Listener {
+public class ListsFragment extends Fragment implements OnPageChangeListener, Listener {
private static final String TAG = "ListsFragment";
- private ViewPager mViewPager;
+
+ private DialerViewPager mViewPager;
private ViewPagerTabs mViewPagerTabs;
private DialtactsPagerAdapter mAdapter;
private RemoveView mRemoveView;
@@ -73,14 +75,15 @@ public class ListsFragment extends Fragment
private SharedPreferences mPrefs;
private boolean mHasFetchedVoicemailStatus;
private boolean mShowVoicemailTabAfterVoicemailStatusIsFetched;
- private VoicemailStatusHelper mVoicemailStatusHelper;
private final ArrayList<OnPageChangeListener> mOnPageChangeListeners = new ArrayList<>();
/** The position of the currently selected tab. */
private int mTabIndex = TAB_INDEX_SPEED_DIAL;
- private boolean mPaused;
+ private boolean mPaused;
private CallLogQueryHandler mCallLogQueryHandler;
+ private UiAction.Type[] actionTypeList;
+
private final ContentObserver mVoicemailStatusObserver =
new ContentObserver(new Handler()) {
@Override
@@ -95,8 +98,7 @@ public class ListsFragment extends Fragment
LogUtil.d("ListsFragment.onCreate", null);
Trace.beginSection(TAG + " onCreate");
super.onCreate(savedInstanceState);
- mVoicemailStatusHelper = new VoicemailStatusHelper();
- mPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
+ mPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext());
Trace.endSection();
}
@@ -151,6 +153,12 @@ public class ListsFragment extends Fragment
Trace.endSection();
Trace.beginSection(TAG + " setup views");
+ actionTypeList = new UiAction.Type[TAB_COUNT_WITH_VOICEMAIL];
+ actionTypeList[TAB_INDEX_SPEED_DIAL] = UiAction.Type.CHANGE_TAB_TO_FAVORITE;
+ actionTypeList[TAB_INDEX_HISTORY] = UiAction.Type.CHANGE_TAB_TO_CALL_LOG;
+ actionTypeList[TAB_INDEX_ALL_CONTACTS] = UiAction.Type.CHANGE_TAB_TO_CONTACTS;
+ actionTypeList[TAB_INDEX_VOICEMAIL] = UiAction.Type.CHANGE_TAB_TO_VOICEMAIL;
+
String[] tabTitles = new String[TAB_COUNT_WITH_VOICEMAIL];
tabTitles[TAB_INDEX_SPEED_DIAL] = getResources().getString(R.string.tab_speed_dial);
tabTitles[TAB_INDEX_HISTORY] = getResources().getString(R.string.tab_history);
@@ -163,7 +171,7 @@ public class ListsFragment extends Fragment
tabIcons[TAB_INDEX_ALL_CONTACTS] = R.drawable.quantum_ic_people_white_24;
tabIcons[TAB_INDEX_VOICEMAIL] = R.drawable.quantum_ic_voicemail_white_24;
- mViewPager = (ViewPager) parentView.findViewById(R.id.lists_pager);
+ mViewPager = (DialerViewPager) parentView.findViewById(R.id.lists_pager);
mAdapter =
new DialtactsPagerAdapter(
getContext(),
@@ -180,7 +188,6 @@ public class ListsFragment extends Fragment
mViewPagerTabs.configureTabIcons(tabIcons);
mViewPagerTabs.setViewPager(mViewPager);
addOnPageChangeListener(mViewPagerTabs);
-
mRemoveView = (RemoveView) parentView.findViewById(R.id.remove_view);
mRemoveViewContent = parentView.findViewById(R.id.remove_view_content);
@@ -191,7 +198,7 @@ public class ListsFragment extends Fragment
.registerContentObserver(
VoicemailContract.Status.CONTENT_URI, true, mVoicemailStatusObserver);
} else {
- LogUtil.w("ListsFragment.onCreateView", "no voicemail read/add permissions");
+ LogUtil.w("ListsFragment.onCreateView", "no voicemail read permissions");
}
Trace.endSection();
@@ -213,8 +220,8 @@ public class ListsFragment extends Fragment
/**
* Shows the tab with the specified index. If the voicemail tab index is specified, but the
- * voicemail status hasn't been fetched, it will try to show the tab after the voicemail status
- * has been fetched.
+ * voicemail status hasn't been fetched, it will show the speed dial tab and try to show the
+ * voicemail tab after the voicemail status has been fetched.
*/
public void showTab(int index) {
if (index == TAB_INDEX_VOICEMAIL) {
@@ -241,6 +248,8 @@ public class ListsFragment extends Fragment
@Override
public void onPageSelected(int position) {
+ PerformanceReport.recordClick(actionTypeList[position]);
+
LogUtil.i("ListsFragment.onPageSelected", "position: %d", position);
mTabIndex = mAdapter.getRtlPosition(position);
@@ -283,7 +292,7 @@ public class ListsFragment extends Fragment
// Update hasActiveVoicemailProvider, which controls the number of tabs displayed.
boolean hasActiveVoicemailProvider =
- mVoicemailStatusHelper.getNumberActivityVoicemailSources(statusCursor) > 0;
+ VoicemailStatusHelper.getNumberActivityVoicemailSources(statusCursor) > 0;
if (hasActiveVoicemailProvider != mAdapter.hasActiveVoicemailProvider()) {
mAdapter.setHasActiveVoicemailProvider(hasActiveVoicemailProvider);
mAdapter.notifyDataSetChanged();
@@ -375,7 +384,7 @@ public class ListsFragment extends Fragment
public void markMissedCallsAsReadAndRemoveNotifications() {
if (mCallLogQueryHandler != null) {
mCallLogQueryHandler.markMissedCallsAsRead();
- CallLogNotificationsService.markNewMissedCallsAsOld(getContext(), null);
+ CallLogNotificationsService.cancelAllMissedCalls(getContext());
}
}
@@ -385,6 +394,11 @@ public class ListsFragment extends Fragment
mRemoveView.animate().alpha(show ? 1 : 0).start();
}
+ public void showMultiSelectRemoveView(boolean show) {
+ mViewPagerTabs.setVisibility(show ? View.GONE : View.VISIBLE);
+ mViewPager.setEnableSwipingPages(!show);
+ }
+
public boolean hasFrequents() {
Fragment page = mAdapter.getItem(mAdapter.getRtlPosition(TAB_INDEX_SPEED_DIAL));
return page instanceof OldSpeedDialFragment
diff --git a/java/com/android/dialer/app/list/OldSpeedDialFragment.java b/java/com/android/dialer/app/list/OldSpeedDialFragment.java
index 40fe74565..afc7c133b 100644
--- a/java/com/android/dialer/app/list/OldSpeedDialFragment.java
+++ b/java/com/android/dialer/app/list/OldSpeedDialFragment.java
@@ -45,18 +45,18 @@ import android.widget.FrameLayout;
import android.widget.FrameLayout.LayoutParams;
import android.widget.ImageView;
import android.widget.ListView;
-import com.android.contacts.common.ContactPhotoManager;
import com.android.contacts.common.ContactTileLoaderFactory;
import com.android.contacts.common.list.ContactTileView;
import com.android.contacts.common.list.OnPhoneNumberPickerActionListener;
import com.android.dialer.app.R;
-import com.android.dialer.app.widget.EmptyContentView;
-import com.android.dialer.callintent.CallInitiationType;
import com.android.dialer.callintent.CallSpecificAppData;
import com.android.dialer.common.LogUtil;
+import com.android.dialer.contactphoto.ContactPhotoManager;
import com.android.dialer.util.PermissionsUtil;
import com.android.dialer.util.ViewUtil;
+import com.android.dialer.widget.EmptyContentView;
import java.util.ArrayList;
+import java.util.Arrays;
/** This fragment displays the user's favorite/frequent contacts in a grid. */
public class OldSpeedDialFragment extends Fragment
@@ -404,9 +404,15 @@ public class OldSpeedDialFragment extends Fragment
return;
}
- if (!PermissionsUtil.hasPermission(activity, READ_CONTACTS)) {
+ String[] deniedPermissions =
+ PermissionsUtil.getPermissionsCurrentlyDenied(
+ getContext(), PermissionsUtil.allContactsGroupPermissionsUsedInDialer);
+ if (deniedPermissions.length > 0) {
+ LogUtil.i(
+ "OldSpeedDialFragment.onEmptyViewActionButtonClicked",
+ "Requesting permissions: " + Arrays.toString(deniedPermissions));
FragmentCompat.requestPermissions(
- this, new String[] {READ_CONTACTS}, READ_CONTACTS_PERMISSION_REQUEST_CODE);
+ this, deniedPermissions, READ_CONTACTS_PERMISSION_REQUEST_CODE);
} else {
// Switch tabs
((HostInterface) activity).showAllContactsTab();
@@ -430,7 +436,7 @@ public class OldSpeedDialFragment extends Fragment
void showAllContactsTab();
}
- private class ContactTileLoaderListener implements LoaderManager.LoaderCallbacks<Cursor> {
+ class ContactTileLoaderListener implements LoaderManager.LoaderCallbacks<Cursor> {
@Override
public CursorLoader onCreateLoader(int id, Bundle args) {
@@ -460,24 +466,17 @@ public class OldSpeedDialFragment extends Fragment
private class ContactTileAdapterListener implements ContactTileView.Listener {
@Override
- public void onContactSelected(Uri contactUri, Rect targetRect) {
+ public void onContactSelected(
+ Uri contactUri, Rect targetRect, CallSpecificAppData callSpecificAppData) {
if (mPhoneNumberPickerActionListener != null) {
- CallSpecificAppData callSpecificAppData =
- CallSpecificAppData.newBuilder()
- .setCallInitiationType(CallInitiationType.Type.SPEED_DIAL)
- .build();
mPhoneNumberPickerActionListener.onPickDataUri(
contactUri, false /* isVideoCall */, callSpecificAppData);
}
}
@Override
- public void onCallNumberDirectly(String phoneNumber) {
+ public void onCallNumberDirectly(String phoneNumber, CallSpecificAppData callSpecificAppData) {
if (mPhoneNumberPickerActionListener != null) {
- CallSpecificAppData callSpecificAppData =
- CallSpecificAppData.newBuilder()
- .setCallInitiationType(CallInitiationType.Type.SPEED_DIAL)
- .build();
mPhoneNumberPickerActionListener.onPickPhoneNumber(
phoneNumber, false /* isVideoCall */, callSpecificAppData);
}
diff --git a/java/com/android/dialer/app/list/PhoneFavoriteListView.java b/java/com/android/dialer/app/list/PhoneFavoriteListView.java
index 9516f0611..f4f395ff0 100644
--- a/java/com/android/dialer/app/list/PhoneFavoriteListView.java
+++ b/java/com/android/dialer/app/list/PhoneFavoriteListView.java
@@ -1,6 +1,5 @@
/*
- * Copyright (C) 2012 Google Inc.
- * Licensed to The Android Open Source Project.
+ * Copyright (C) 2017 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.
@@ -24,7 +23,6 @@ import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.os.Handler;
import android.util.AttributeSet;
-import android.util.Log;
import android.view.DragEvent;
import android.view.MotionEvent;
import android.view.View;
@@ -33,6 +31,7 @@ import android.widget.GridView;
import android.widget.ImageView;
import com.android.dialer.app.R;
import com.android.dialer.app.list.DragDropController.DragItemContainer;
+import com.android.dialer.common.LogUtil;
/** Viewgroup that presents the user's speed dial contacts in a grid. */
public class PhoneFavoriteListView extends GridView
@@ -40,14 +39,14 @@ public class PhoneFavoriteListView extends GridView
public static final String LOG_TAG = PhoneFavoriteListView.class.getSimpleName();
final int[] mLocationOnScreen = new int[2];
- private final long SCROLL_HANDLER_DELAY_MILLIS = 5;
- private final int DRAG_SCROLL_PX_UNIT = 25;
- private final float DRAG_SHADOW_ALPHA = 0.7f;
+ private static final long SCROLL_HANDLER_DELAY_MILLIS = 5;
+ private static final int DRAG_SCROLL_PX_UNIT = 25;
+ private static final float DRAG_SHADOW_ALPHA = 0.7f;
/**
* {@link #mTopScrollBound} and {@link mBottomScrollBound} will be offseted to the top / bottom by
* {@link #getHeight} * {@link #BOUND_GAP_RATIO} pixels.
*/
- private final float BOUND_GAP_RATIO = 0.2f;
+ private static final float BOUND_GAP_RATIO = 0.2f;
private float mTouchSlop;
private int mTopScrollBound;
@@ -67,7 +66,6 @@ public class PhoneFavoriteListView extends GridView
}
};
private boolean mIsDragScrollerRunning = false;
- private int mTouchDownForDragStartX;
private int mTouchDownForDragStartY;
private Bitmap mDragShadowBitmap;
private ImageView mDragShadowOverlay;
@@ -98,7 +96,7 @@ public class PhoneFavoriteListView extends GridView
}
public PhoneFavoriteListView(Context context, AttributeSet attrs) {
- this(context, attrs, -1);
+ this(context, attrs, 0);
}
public PhoneFavoriteListView(Context context, AttributeSet attrs, int defStyle) {
@@ -121,7 +119,6 @@ public class PhoneFavoriteListView extends GridView
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
- mTouchDownForDragStartX = (int) ev.getX();
mTouchDownForDragStartY = (int) ev.getY();
}
@@ -287,7 +284,7 @@ public class PhoneFavoriteListView extends GridView
try {
bitmap = cache.copy(Bitmap.Config.ARGB_8888, false);
} catch (final OutOfMemoryError e) {
- Log.w(LOG_TAG, "Failed to copy bitmap from Drawing cache", e);
+ LogUtil.w(LOG_TAG, "Failed to copy bitmap from Drawing cache", e);
bitmap = null;
}
}
diff --git a/java/com/android/dialer/app/list/PhoneFavoriteSquareTileView.java b/java/com/android/dialer/app/list/PhoneFavoriteSquareTileView.java
index 5a18d039b..40f23ea6f 100644
--- a/java/com/android/dialer/app/list/PhoneFavoriteSquareTileView.java
+++ b/java/com/android/dialer/app/list/PhoneFavoriteSquareTileView.java
@@ -26,6 +26,8 @@ import android.widget.TextView;
import com.android.contacts.common.list.ContactEntry;
import com.android.dialer.app.R;
import com.android.dialer.compat.CompatUtils;
+import com.android.dialer.logging.InteractionEvent;
+import com.android.dialer.logging.Logger;
/** Displays the contact's picture overlaid with their name and number type in a tile. */
public class PhoneFavoriteSquareTileView extends PhoneFavoriteTileView {
@@ -87,6 +89,8 @@ public class PhoneFavoriteSquareTileView extends PhoneFavoriteTileView {
new OnClickListener() {
@Override
public void onClick(View v) {
+ Logger.get(getContext())
+ .logInteraction(InteractionEvent.Type.SPEED_DIAL_OPEN_CONTACT_CARD);
launchQuickContact();
}
});
diff --git a/java/com/android/dialer/app/list/PhoneFavoriteTileView.java b/java/com/android/dialer/app/list/PhoneFavoriteTileView.java
index db89cf3dc..e0961be4b 100644
--- a/java/com/android/dialer/app/list/PhoneFavoriteTileView.java
+++ b/java/com/android/dialer/app/list/PhoneFavoriteTileView.java
@@ -18,16 +18,25 @@ package com.android.dialer.app.list;
import android.content.ClipData;
import android.content.Context;
+import android.net.Uri;
+import android.provider.ContactsContract.PinnedPositions;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
-import com.android.contacts.common.ContactPhotoManager;
-import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest;
import com.android.contacts.common.MoreContactUtils;
import com.android.contacts.common.list.ContactEntry;
import com.android.contacts.common.list.ContactTileView;
+import com.android.contacts.common.model.ContactLoader;
import com.android.dialer.app.R;
+import com.android.dialer.callintent.CallInitiationType;
+import com.android.dialer.callintent.CallSpecificAppData;
+import com.android.dialer.callintent.SpeedDialContactType;
+import com.android.dialer.common.LogUtil;
+import com.android.dialer.contactphoto.ContactPhotoManager.DefaultImageRequest;
+import com.android.dialer.lettertile.LetterTileDrawable;
+import com.android.dialer.logging.InteractionEvent;
+import com.android.dialer.logging.Logger;
/**
* A light version of the {@link com.android.contacts.common.list.ContactTileView} that is used in
@@ -42,7 +51,6 @@ public abstract class PhoneFavoriteTileView extends ContactTileView {
// tile is long pressed.
static final String DRAG_PHONE_FAVORITE_TILE = "PHONE_FAVORITE_TILE";
private static final String TAG = PhoneFavoriteTileView.class.getSimpleName();
- private static final boolean DEBUG = false;
// These parameters instruct the photo manager to display the default image/letter at 70% of
// its normal size, and vertically offset upwards 12% towards the top of the letter tile, to
// make room for the contact name and number label at the bottom of the image.
@@ -55,6 +63,9 @@ public abstract class PhoneFavoriteTileView extends ContactTileView {
private View mShadowOverlay;
/** Users' most frequent phone number. */
private String mPhoneNumberString;
+ private boolean isPinned;
+ private boolean isStarred;
+ private int position = -1;
public PhoneFavoriteTileView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -83,12 +94,14 @@ public abstract class PhoneFavoriteTileView extends ContactTileView {
super.loadFromContact(entry);
// Set phone number to null in case we're reusing the view.
mPhoneNumberString = null;
+ isPinned = (entry.pinned != PinnedPositions.UNPINNED);
+ isStarred = entry.isFavorite;
if (entry != null) {
+ sendViewNotification(getContext(), entry.lookupUri);
// Grab the phone-number to call directly. See {@link onClick()}.
mPhoneNumberString = entry.phoneNumber;
- // If this is a blank entry, don't show anything.
- // TODO krelease: Just hide the view for now. For this to truly look like an empty row
+ // If this is a blank entry, don't show anything. For this to truly look like an empty row
// the entire ContactTileRow needs to be hidden.
if (entry == ContactEntry.BLANK_ENTRY) {
setVisibility(View.INVISIBLE);
@@ -113,16 +126,37 @@ public abstract class PhoneFavoriteTileView extends ContactTileView {
if (mListener == null) {
return;
}
+
+ CallSpecificAppData.Builder callSpecificAppData =
+ CallSpecificAppData.newBuilder()
+ .setAllowAssistedDialing(true)
+ .setCallInitiationType(CallInitiationType.Type.SPEED_DIAL)
+ .setSpeedDialContactPosition(position);
+ if (isStarred) {
+ callSpecificAppData.addSpeedDialContactType(SpeedDialContactType.Type.STARRED_CONTACT);
+ } else {
+ callSpecificAppData.addSpeedDialContactType(SpeedDialContactType.Type.FREQUENT_CONTACT);
+ }
+ if (isPinned) {
+ callSpecificAppData.addSpeedDialContactType(SpeedDialContactType.Type.PINNED_CONTACT);
+ }
+
if (TextUtils.isEmpty(mPhoneNumberString)) {
+ // Don't set performance report now, since user may spend some time on picking a number
+
// Copy "superclass" implementation
+ Logger.get(getContext())
+ .logInteraction(InteractionEvent.Type.SPEED_DIAL_CLICK_CONTACT_WITH_AMBIGUOUS_NUMBER);
mListener.onContactSelected(
- getLookupUri(), MoreContactUtils.getTargetRectFromView(PhoneFavoriteTileView.this));
+ getLookupUri(),
+ MoreContactUtils.getTargetRectFromView(PhoneFavoriteTileView.this),
+ callSpecificAppData.build());
} else {
// When you tap a frequently-called contact, you want to
// call them at the number that you usually talk to them
// at (i.e. the one displayed in the UI), regardless of
// whether that's their default number.
- mListener.onCallNumberDirectly(mPhoneNumberString);
+ mListener.onCallNumberDirectly(mPhoneNumberString, callSpecificAppData.build());
}
}
};
@@ -133,7 +167,7 @@ public abstract class PhoneFavoriteTileView extends ContactTileView {
return new DefaultImageRequest(
displayName,
lookupKey,
- ContactPhotoManager.TYPE_DEFAULT,
+ LetterTileDrawable.TYPE_DEFAULT,
DEFAULT_IMAGE_LETTER_SCALE,
DEFAULT_IMAGE_LETTER_OFFSET,
false);
@@ -152,4 +186,26 @@ public abstract class PhoneFavoriteTileView extends ContactTileView {
// Unlike Contacts' tiles, the Dialer's favorites tiles are square.
return false;
}
+
+ public void setPosition(int position) {
+ this.position = position;
+ }
+
+ /**
+ * Send a notification using a {@link ContactLoader} to inform the sync adapter that we are
+ * viewing a particular contact, so that it can download the high-res photo.
+ */
+ private static void sendViewNotification(Context context, Uri contactUri) {
+ ContactLoader loader = new ContactLoader(context, contactUri, true /* postViewNotification */);
+ loader.registerListener(
+ 0,
+ (loader1, contact) -> {
+ try {
+ loader1.reset();
+ } catch (RuntimeException e) {
+ LogUtil.e("PhoneFavoriteTileView.onLoadComplete", "error resetting loader", e);
+ }
+ });
+ loader.startLoading();
+ }
}
diff --git a/java/com/android/dialer/app/list/PhoneFavoritesTileAdapter.java b/java/com/android/dialer/app/list/PhoneFavoritesTileAdapter.java
index c692ecac7..cd5712eed 100644
--- a/java/com/android/dialer/app/list/PhoneFavoritesTileAdapter.java
+++ b/java/com/android/dialer/app/list/PhoneFavoritesTileAdapter.java
@@ -30,17 +30,21 @@ import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.PinnedPositions;
import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
-import android.util.Log;
import android.util.LongSparseArray;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
-import com.android.contacts.common.ContactPhotoManager;
import com.android.contacts.common.ContactTileLoaderFactory;
import com.android.contacts.common.list.ContactEntry;
import com.android.contacts.common.list.ContactTileView;
import com.android.contacts.common.preference.ContactsPreferences;
import com.android.dialer.app.R;
+import com.android.dialer.common.LogUtil;
+import com.android.dialer.contactphoto.ContactPhotoManager;
+import com.android.dialer.lightbringer.Lightbringer;
+import com.android.dialer.lightbringer.LightbringerComponent;
+import com.android.dialer.logging.InteractionEvent;
+import com.android.dialer.logging.Logger;
import com.android.dialer.shortcuts.ShortcutRefresher;
import com.google.common.collect.ComparisonChain;
import java.util.ArrayList;
@@ -190,6 +194,14 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements OnDragDrop
// Track the length of {@link #mContactEntries} and compare to {@link #TILES_SOFT_LIMIT}.
int counter = 0;
+ // Data for logging
+ int starredContactsCount = 0;
+ int pinnedContactsCount = 0;
+ int multipleNumbersContactsCount = 0;
+ int contactsWithPhotoCount = 0;
+ int contactsWithNameCount = 0;
+ int lightbringerReachableContactsCount = 0;
+
// The cursor should not be closed since this is invoked from a CursorLoader.
if (cursor.moveToFirst()) {
int starredColumn = cursor.getColumnIndexOrThrow(Contacts.STARRED);
@@ -262,6 +274,22 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements OnDragDrop
contact.pinned = pinned;
mContactEntries.add(contact);
+ // Set counts for logging
+ if (isStarred) {
+ // mNumStarred might be larger than the number of visible starred contact,
+ // since it includes invisible ones (starred contact with no phone number).
+ starredContactsCount++;
+ }
+ if (pinned != PinnedPositions.UNPINNED) {
+ pinnedContactsCount++;
+ }
+ if (!TextUtils.isEmpty(name)) {
+ contactsWithNameCount++;
+ }
+ if (photoUri != null) {
+ contactsWithPhotoCount++;
+ }
+
duplicates.put(id, contact);
counter++;
@@ -274,6 +302,47 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements OnDragDrop
ShortcutRefresher.refresh(mContext, mContactEntries);
notifyDataSetChanged();
+
+ Lightbringer lightbringer = LightbringerComponent.get(mContext).getLightbringer();
+ for (ContactEntry contact : mContactEntries) {
+ if (contact.phoneNumber == null) {
+ multipleNumbersContactsCount++;
+ } else if (lightbringer.isReachable(mContext, contact.phoneNumber)) {
+ lightbringerReachableContactsCount++;
+ }
+ }
+
+ Logger.get(mContext)
+ .logSpeedDialContactComposition(
+ counter,
+ starredContactsCount,
+ pinnedContactsCount,
+ multipleNumbersContactsCount,
+ contactsWithPhotoCount,
+ contactsWithNameCount,
+ lightbringerReachableContactsCount);
+ // Logs for manual testing
+ LogUtil.v("PhoneFavoritesTileAdapter.saveCursorToCache", "counter: %d", counter);
+ LogUtil.v(
+ "PhoneFavoritesTileAdapter.saveCursorToCache",
+ "starredContactsCount: %d",
+ starredContactsCount);
+ LogUtil.v(
+ "PhoneFavoritesTileAdapter.saveCursorToCache",
+ "pinnedContactsCount: %d",
+ pinnedContactsCount);
+ LogUtil.v(
+ "PhoneFavoritesTileAdapter.saveCursorToCache",
+ "multipleNumbersContactsCount: %d",
+ multipleNumbersContactsCount);
+ LogUtil.v(
+ "PhoneFavoritesTileAdapter.saveCursorToCache",
+ "contactsWithPhotoCount: %d",
+ contactsWithPhotoCount);
+ LogUtil.v(
+ "PhoneFavoritesTileAdapter.saveCursorToCache",
+ "contactsWithNameCount: %d",
+ contactsWithNameCount);
}
/** Iterates over the {@link Cursor} Returns position of the first NON Starred Contact */
@@ -347,7 +416,7 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements OnDragDrop
@Override
public void notifyDataSetChanged() {
if (DEBUG) {
- Log.v(TAG, "notifyDataSetChanged");
+ LogUtil.v(TAG, "notifyDataSetChanged");
}
super.notifyDataSetChanged();
}
@@ -355,7 +424,7 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements OnDragDrop
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (DEBUG) {
- Log.v(TAG, "get view for " + String.valueOf(position));
+ LogUtil.v(TAG, "get view for " + position);
}
PhoneFavoriteTileView tileView = null;
@@ -371,6 +440,7 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements OnDragDrop
tileView.setPhotoManager(mPhotoManager);
tileView.setListener(mListener);
tileView.loadFromContact(getItem(position));
+ tileView.setPosition(position);
return tileView;
}
@@ -455,8 +525,9 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements OnDragDrop
// update the database here with the new pinned positions
try {
mContext.getContentResolver().applyBatch(ContactsContract.AUTHORITY, operations);
+ Logger.get(mContext).logInteraction(InteractionEvent.Type.SPEED_DIAL_PIN_CONTACT);
} catch (RemoteException | OperationApplicationException e) {
- Log.e(TAG, "Exception thrown when pinning contacts", e);
+ LogUtil.e(TAG, "Exception thrown when pinning contacts", e);
}
}
}
@@ -609,6 +680,7 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements OnDragDrop
if (mDraggedEntry != null) {
unstarAndUnpinContact(mDraggedEntry.lookupUri);
mAwaitingRemove = true;
+ Logger.get(mContext).logInteraction(InteractionEvent.Type.SPEED_DIAL_REMOVE_CONTACT);
}
}
diff --git a/java/com/android/dialer/app/list/RegularSearchFragment.java b/java/com/android/dialer/app/list/RegularSearchFragment.java
index 02896793b..73120c547 100644
--- a/java/com/android/dialer/app/list/RegularSearchFragment.java
+++ b/java/com/android/dialer/app/list/RegularSearchFragment.java
@@ -18,19 +18,28 @@ package com.android.dialer.app.list;
import static android.Manifest.permission.READ_CONTACTS;
import android.app.Activity;
+import android.content.Context;
import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
import android.support.v13.app.FragmentCompat;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import com.android.contacts.common.list.ContactEntryListAdapter;
import com.android.contacts.common.list.PinnedHeaderListView;
import com.android.dialer.app.R;
-import com.android.dialer.app.widget.EmptyContentView;
-import com.android.dialer.app.widget.EmptyContentView.OnEmptyViewActionButtonClickedListener;
import com.android.dialer.callintent.CallInitiationType;
+import com.android.dialer.common.LogUtil;
+import com.android.dialer.common.concurrent.DialerExecutor;
+import com.android.dialer.common.concurrent.DialerExecutor.Worker;
+import com.android.dialer.common.concurrent.DialerExecutors;
import com.android.dialer.phonenumbercache.CachedNumberLookupService;
+import com.android.dialer.phonenumbercache.CachedNumberLookupService.CachedContactInfo;
import com.android.dialer.phonenumbercache.PhoneNumberCache;
import com.android.dialer.util.PermissionsUtil;
+import com.android.dialer.widget.EmptyContentView;
+import com.android.dialer.widget.EmptyContentView.OnEmptyViewActionButtonClickedListener;
+import java.util.Arrays;
public class RegularSearchFragment extends SearchFragment
implements OnEmptyViewActionButtonClickedListener,
@@ -41,6 +50,8 @@ public class RegularSearchFragment extends SearchFragment
private static final int SEARCH_DIRECTORY_RESULT_LIMIT = 5;
protected String mPermissionToRequest;
+ private DialerExecutor<CachedContactInfo> addContactTask;
+
public RegularSearchFragment() {
configureDirectorySearch();
}
@@ -51,6 +62,18 @@ public class RegularSearchFragment extends SearchFragment
}
@Override
+ public void onCreate(Bundle savedState) {
+ super.onCreate(savedState);
+
+ addContactTask =
+ DialerExecutors.createUiTaskBuilder(
+ getFragmentManager(),
+ "RegularSearchFragment.addContact",
+ new AddContactWorker(getContext().getApplicationContext()))
+ .build();
+ }
+
+ @Override
protected void onCreateView(LayoutInflater inflater, ViewGroup container) {
super.onCreateView(inflater, container);
((PinnedHeaderListView) getListView()).setScrollToSectionOnHeaderTouch(true);
@@ -71,8 +94,9 @@ public class RegularSearchFragment extends SearchFragment
PhoneNumberCache.get(getContext()).getCachedNumberLookupService();
if (cachedNumberLookupService != null) {
final RegularSearchListAdapter adapter = (RegularSearchListAdapter) getAdapter();
- cachedNumberLookupService.addContact(
- getContext(), adapter.getContactInfo(cachedNumberLookupService, position));
+ CachedContactInfo cachedContactInfo =
+ adapter.getContactInfo(cachedNumberLookupService, position);
+ addContactTask.executeSerial(cachedContactInfo);
}
}
@@ -114,8 +138,15 @@ public class RegularSearchFragment extends SearchFragment
}
if (READ_CONTACTS.equals(mPermissionToRequest)) {
- FragmentCompat.requestPermissions(
- this, new String[] {mPermissionToRequest}, PERMISSION_REQUEST_CODE);
+ String[] deniedPermissions =
+ PermissionsUtil.getPermissionsCurrentlyDenied(
+ getContext(), PermissionsUtil.allContactsGroupPermissionsUsedInDialer);
+ if (deniedPermissions.length > 0) {
+ LogUtil.i(
+ "RegularSearchFragment.onEmptyViewActionButtonClicked",
+ "Requesting permissions: " + Arrays.toString(deniedPermissions));
+ FragmentCompat.requestPermissions(this, deniedPermissions, PERMISSION_REQUEST_CODE);
+ }
}
}
@@ -143,4 +174,24 @@ public class RegularSearchFragment extends SearchFragment
boolean isNearbyPlacesSearchEnabled();
}
+
+ private static class AddContactWorker implements Worker<CachedContactInfo, Void> {
+
+ private final Context appContext;
+
+ private AddContactWorker(Context appContext) {
+ this.appContext = appContext;
+ }
+
+ @Nullable
+ @Override
+ public Void doInBackground(@Nullable CachedContactInfo contactInfo) throws Throwable {
+ CachedNumberLookupService cachedNumberLookupService =
+ PhoneNumberCache.get(appContext).getCachedNumberLookupService();
+ if (cachedNumberLookupService != null) {
+ cachedNumberLookupService.addContact(appContext, contactInfo);
+ }
+ return null;
+ }
+ }
}
diff --git a/java/com/android/dialer/app/list/RemoveView.java b/java/com/android/dialer/app/list/RemoveView.java
index 3b917db43..1d566c5a0 100644
--- a/java/com/android/dialer/app/list/RemoveView.java
+++ b/java/com/android/dialer/app/list/RemoveView.java
@@ -41,7 +41,7 @@ public class RemoveView extends FrameLayout {
}
public RemoveView(Context context, AttributeSet attrs) {
- this(context, attrs, -1);
+ this(context, attrs, 0);
}
public RemoveView(Context context, AttributeSet attrs, int defStyle) {
diff --git a/java/com/android/dialer/app/list/SearchFragment.java b/java/com/android/dialer/app/list/SearchFragment.java
index fcf8236e3..e21e073bd 100644
--- a/java/com/android/dialer/app/list/SearchFragment.java
+++ b/java/com/android/dialer/app/list/SearchFragment.java
@@ -34,19 +34,20 @@ import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Space;
import com.android.contacts.common.list.ContactEntryListAdapter;
-import com.android.contacts.common.list.ContactListItemView;
import com.android.contacts.common.list.OnPhoneNumberPickerActionListener;
import com.android.contacts.common.list.PhoneNumberPickerFragment;
import com.android.dialer.animation.AnimUtils;
import com.android.dialer.app.R;
-import com.android.dialer.app.dialpad.DialpadFragment.ErrorDialogFragment;
import com.android.dialer.app.widget.DialpadSearchEmptyContentView;
-import com.android.dialer.app.widget.EmptyContentView;
import com.android.dialer.callintent.CallSpecificAppData;
import com.android.dialer.common.LogUtil;
+import com.android.dialer.dialpadview.DialpadFragment.ErrorDialogFragment;
+import com.android.dialer.logging.DialerImpression;
+import com.android.dialer.logging.Logger;
import com.android.dialer.util.DialerUtils;
import com.android.dialer.util.IntentUtil;
import com.android.dialer.util.PermissionsUtil;
+import com.android.dialer.widget.EmptyContentView;
public class SearchFragment extends PhoneNumberPickerFragment {
@@ -80,7 +81,6 @@ public class SearchFragment extends PhoneNumberPickerFragment {
setQuickContactEnabled(true);
setAdjustSelectionBoundsEnabled(false);
setDarkTheme(false);
- setPhotoPosition(ContactListItemView.getDefaultPhotoPosition(false /* opposite */));
setUseCallableUri(true);
try {
@@ -98,9 +98,6 @@ public class SearchFragment extends PhoneNumberPickerFragment {
public void onStart() {
LogUtil.d("SearchFragment.onStart", "");
super.onStart();
- if (isSearchMode()) {
- getAdapter().setHasHeader(0, false);
- }
mActivity = (HostInterface) getActivity();
@@ -172,16 +169,6 @@ public class SearchFragment extends PhoneNumberPickerFragment {
return animator;
}
- @Override
- protected void setSearchMode(boolean flag) {
- super.setSearchMode(flag);
- // This hides the "All contacts with phone numbers" header in the search fragment
- final ContactEntryListAdapter adapter = getAdapter();
- if (adapter != null) {
- adapter.setHasHeader(0, false);
- }
- }
-
public void setAddToContactNumber(String addToContactNumber) {
mAddToContactNumber = addToContactNumber;
}
@@ -249,6 +236,10 @@ public class SearchFragment extends PhoneNumberPickerFragment {
}
break;
case DialerPhoneNumberListAdapter.SHORTCUT_CREATE_NEW_CONTACT:
+ if (this instanceof SmartDialSearchFragment) {
+ Logger.get(getContext())
+ .logImpression(DialerImpression.Type.CREATE_NEW_CONTACT_FROM_DIALPAD);
+ }
number =
TextUtils.isEmpty(mAddToContactNumber)
? adapter.getFormattedQueryString()
@@ -257,6 +248,10 @@ public class SearchFragment extends PhoneNumberPickerFragment {
DialerUtils.startActivityWithErrorToast(getActivity(), intent);
break;
case DialerPhoneNumberListAdapter.SHORTCUT_ADD_TO_EXISTING_CONTACT:
+ if (this instanceof SmartDialSearchFragment) {
+ Logger.get(getContext())
+ .logImpression(DialerImpression.Type.ADD_TO_A_CONTACT_FROM_DIALPAD);
+ }
number =
TextUtils.isEmpty(mAddToContactNumber)
? adapter.getFormattedQueryString()
diff --git a/java/com/android/dialer/app/list/SmartDialNumberListAdapter.java b/java/com/android/dialer/app/list/SmartDialNumberListAdapter.java
index 566a15d53..3b00c7643 100644
--- a/java/com/android/dialer/app/list/SmartDialNumberListAdapter.java
+++ b/java/com/android/dialer/app/list/SmartDialNumberListAdapter.java
@@ -20,9 +20,9 @@ import android.database.Cursor;
import android.support.annotation.NonNull;
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
-import android.util.Log;
import com.android.contacts.common.list.ContactListItemView;
-import com.android.dialer.app.dialpad.SmartDialCursorLoader;
+import com.android.dialer.common.LogUtil;
+import com.android.dialer.dialpadview.SmartDialCursorLoader;
import com.android.dialer.smartdial.SmartDialMatchPosition;
import com.android.dialer.smartdial.SmartDialNameMatcher;
import com.android.dialer.smartdial.SmartDialPrefix;
@@ -43,14 +43,14 @@ public class SmartDialNumberListAdapter extends DialerPhoneNumberListAdapter {
setShortcutEnabled(SmartDialNumberListAdapter.SHORTCUT_DIRECT_CALL, false);
if (DEBUG) {
- Log.v(TAG, "Constructing List Adapter");
+ LogUtil.v(TAG, "Constructing List Adapter");
}
}
/** Sets query for the SmartDialCursorLoader. */
public void configureLoader(SmartDialCursorLoader loader) {
if (DEBUG) {
- Log.v(TAG, "Configure Loader with query" + getQueryString());
+ LogUtil.v(TAG, "Configure Loader with query" + getQueryString());
}
if (getQueryString() == null) {
@@ -77,7 +77,7 @@ public class SmartDialNumberListAdapter extends DialerPhoneNumberListAdapter {
for (SmartDialMatchPosition match : nameMatches) {
view.addNameHighlightSequence(match.start, match.end);
if (DEBUG) {
- Log.v(
+ LogUtil.v(
TAG,
cursor.getString(PhoneQuery.DISPLAY_NAME)
+ " "
diff --git a/java/com/android/dialer/app/list/SmartDialSearchFragment.java b/java/com/android/dialer/app/list/SmartDialSearchFragment.java
index eb1508c72..e97a16c19 100644
--- a/java/com/android/dialer/app/list/SmartDialSearchFragment.java
+++ b/java/com/android/dialer/app/list/SmartDialSearchFragment.java
@@ -28,12 +28,13 @@ import android.os.Bundle;
import android.support.v13.app.FragmentCompat;
import com.android.contacts.common.list.ContactEntryListAdapter;
import com.android.dialer.app.R;
-import com.android.dialer.app.dialpad.SmartDialCursorLoader;
-import com.android.dialer.app.widget.EmptyContentView;
import com.android.dialer.callintent.CallInitiationType;
import com.android.dialer.common.LogUtil;
import com.android.dialer.database.DialerDatabaseHelper;
+import com.android.dialer.dialpadview.SmartDialCursorLoader;
import com.android.dialer.util.PermissionsUtil;
+import com.android.dialer.widget.EmptyContentView;
+import java.util.Arrays;
/** Implements a fragment to load and display SmartDial search results. */
public class SmartDialSearchFragment extends SearchFragment
@@ -80,6 +81,11 @@ public class SmartDialSearchFragment extends SearchFragment
}
@Override
+ public boolean getShowEmptyListForNullQuery() {
+ return true;
+ }
+
+ @Override
protected void setupEmptyView() {
if (mEmptyView != null && getActivity() != null) {
if (!PermissionsUtil.hasPermission(getActivity(), CALL_PHONE)) {
@@ -123,8 +129,16 @@ public class SmartDialSearchFragment extends SearchFragment
return;
}
- FragmentCompat.requestPermissions(
- this, new String[] {CALL_PHONE}, CALL_PHONE_PERMISSION_REQUEST_CODE);
+ String[] deniedPermissions =
+ PermissionsUtil.getPermissionsCurrentlyDenied(
+ getContext(), PermissionsUtil.allPhoneGroupPermissionsUsedInDialer);
+ if (deniedPermissions.length > 0) {
+ LogUtil.i(
+ "SmartDialSearchFragment.onEmptyViewActionButtonClicked",
+ "Requesting permissions: " + Arrays.toString(deniedPermissions));
+ FragmentCompat.requestPermissions(
+ this, deniedPermissions, CALL_PHONE_PERMISSION_REQUEST_CODE);
+ }
}
@Override