diff options
15 files changed, 281 insertions, 90 deletions
diff --git a/assets/quantum/res/drawable/quantum_ic_phone_locked_vd_theme_24.xml b/assets/quantum/res/drawable/quantum_ic_phone_locked_vd_theme_24.xml new file mode 100644 index 000000000..a249774b2 --- /dev/null +++ b/assets/quantum/res/drawable/quantum_ic_phone_locked_vd_theme_24.xml @@ -0,0 +1,10 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0" + android:tint="?attr/colorControlNormal"> + <path + android:fillColor="@android:color/white" + android:pathData="M20,15.5c-1.25,0 -2.45,-0.2 -3.57,-0.57 -0.35,-0.11 -0.74,-0.03 -1.02,0.24l-2.2,2.2c-2.83,-1.44 -5.15,-3.75 -6.59,-6.59l2.2,-2.21c0.28,-0.26 0.36,-0.65 0.25,-1C8.7,6.45 8.5,5.25 8.5,4c0,-0.55 -0.45,-1 -1,-1L4,3c-0.55,0 -1,0.45 -1,1 0,9.39 7.61,17 17,17 0.55,0 1,-0.45 1,-1v-3.5c0,-0.55 -0.45,-1 -1,-1zM20,4v-0.5C20,2.12 18.88,1 17.5,1S15,2.12 15,3.5L15,4c-0.55,0 -1,0.45 -1,1v4c0,0.55 0.45,1 1,1h5c0.55,0 1,-0.45 1,-1L21,5c0,-0.55 -0.45,-1 -1,-1zM19.2,4h-3.4v-0.5c0,-0.94 0.76,-1.7 1.7,-1.7s1.7,0.76 1.7,1.7L19.2,4z"/> +</vector> diff --git a/assets/quantum/res/drawable/quantum_ic_phone_paused_vd_theme_24.xml b/assets/quantum/res/drawable/quantum_ic_phone_paused_vd_theme_24.xml new file mode 100644 index 000000000..99d25c10d --- /dev/null +++ b/assets/quantum/res/drawable/quantum_ic_phone_paused_vd_theme_24.xml @@ -0,0 +1,10 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0" + android:tint="?attr/colorControlNormal"> + <path + android:fillColor="@android:color/white" + android:pathData="M17,3h-2v7h2L17,3zM20,15.5c-1.25,0 -2.45,-0.2 -3.57,-0.57 -0.35,-0.11 -0.74,-0.03 -1.02,0.24l-2.2,2.2c-2.83,-1.44 -5.15,-3.75 -6.59,-6.59l2.2,-2.21c0.28,-0.26 0.36,-0.65 0.25,-1C8.7,6.45 8.5,5.25 8.5,4c0,-0.55 -0.45,-1 -1,-1L4,3c-0.55,0 -1,0.45 -1,1 0,9.39 7.61,17 17,17 0.55,0 1,-0.45 1,-1v-3.5c0,-0.55 -0.45,-1 -1,-1zM19,3v7h2L21,3h-2z"/> +</vector> diff --git a/java/com/android/dialer/app/DialtactsActivity.java b/java/com/android/dialer/app/DialtactsActivity.java index b9ca67f62..b5ec20246 100644 --- a/java/com/android/dialer/app/DialtactsActivity.java +++ b/java/com/android/dialer/app/DialtactsActivity.java @@ -124,7 +124,7 @@ import com.android.dialer.performancereport.PerformanceReport; import com.android.dialer.postcall.PostCall; import com.android.dialer.proguard.UsedByReflection; import com.android.dialer.searchfragment.list.NewSearchFragment; -import com.android.dialer.searchfragment.list.NewSearchFragment.SearchFragmentListTouchListener; +import com.android.dialer.searchfragment.list.NewSearchFragment.SearchFragmentListener; import com.android.dialer.simulator.Simulator; import com.android.dialer.simulator.SimulatorComponent; import com.android.dialer.smartdial.SmartDialNameMatcher; @@ -164,7 +164,7 @@ public class DialtactsActivity extends TransactionSafeActivity PhoneNumberInteraction.DisambigDialogDismissedListener, ActivityCompat.OnRequestPermissionsResultCallback, DialpadListener, - SearchFragmentListTouchListener { + SearchFragmentListener { public static final boolean DEBUG = false; @VisibleForTesting public static final String TAG_DIALPAD_FRAGMENT = "dialpad"; @@ -1664,6 +1664,14 @@ public class DialtactsActivity extends TransactionSafeActivity return false; } + @Override + public void onCallPlaced() { + if (mIsDialpadShown) { + hideDialpadFragment(false, true); + } + exitSearchUi(); + } + /** Popup menu accessible from the search bar */ protected class OptionsPopupMenu extends PopupMenu { diff --git a/java/com/android/dialer/logging/LoggingBindings.java b/java/com/android/dialer/logging/LoggingBindings.java index ca9a0533e..7682c767d 100644 --- a/java/com/android/dialer/logging/LoggingBindings.java +++ b/java/com/android/dialer/logging/LoggingBindings.java @@ -20,6 +20,13 @@ import android.widget.QuickContactBadge; /** Allows the container application to gather analytics. */ public interface LoggingBindings { + String ON_CREATE_PRIMES_EVENT_NAME = "Application.onCreate"; + String ON_CREATE_TO_ACTIVITY_ON_CREATE_PRIMES_EVENT_NAME = + "Application.onCreate_To_GoogleDialtactsActivity.onCreate"; + String ON_CALL_ADDED_TO_ON_INCALL_UI_SHOWN_INCOMING = + "CallList.onCallAdded_To_InCallActivity.onCreate_Incoming"; + String ON_CALL_ADDED_TO_ON_INCALL_UI_SHOWN_OUTGOING = + "CallList.onCallAdded_To_InCallActivity.onCreate_Outgoing"; /** * Logs an DialerImpression event that's not associated with a specific call. * @@ -87,4 +94,10 @@ public interface LoggingBindings { /** Logs successful People Api lookup result */ void logSuccessfulPeopleApiLookupReport(long latency, int httpResponseCode); + + /** Log start a latency timer */ + void logStartLatencyTimer(String timerEventName); + + /** Log end a latency timer */ + void logStopLatencyTimer(String timerEventName); } diff --git a/java/com/android/dialer/logging/LoggingBindingsStub.java b/java/com/android/dialer/logging/LoggingBindingsStub.java index 2dbcc3ffb..ab6872cf4 100644 --- a/java/com/android/dialer/logging/LoggingBindingsStub.java +++ b/java/com/android/dialer/logging/LoggingBindingsStub.java @@ -61,4 +61,10 @@ public class LoggingBindingsStub implements LoggingBindings { @Override public void logSuccessfulPeopleApiLookupReport(long latency, int httpResponseCode) {} + + @Override + public void logStartLatencyTimer(String timerEventName) {} + + @Override + public void logStopLatencyTimer(String timerEventName) {} } diff --git a/java/com/android/dialer/phonelookup/cp2/Cp2PhoneLookup.java b/java/com/android/dialer/phonelookup/cp2/Cp2PhoneLookup.java index 323ec7c65..a3d97c64e 100644 --- a/java/com/android/dialer/phonelookup/cp2/Cp2PhoneLookup.java +++ b/java/com/android/dialer/phonelookup/cp2/Cp2PhoneLookup.java @@ -16,21 +16,138 @@ package com.android.dialer.phonelookup.cp2; +import android.content.Context; +import android.database.Cursor; +import android.provider.ContactsContract.CommonDataKinds.Phone; +import android.provider.ContactsContract.Contacts; +import android.provider.ContactsContract.DeletedContacts; +import android.support.v4.util.ArraySet; import com.android.dialer.DialerPhoneNumber; +import com.android.dialer.common.concurrent.DialerExecutors; import com.android.dialer.phonelookup.PhoneLookup; import com.android.dialer.phonelookup.PhoneLookupInfo; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.MoreExecutors; +import java.util.Set; -/** TODO(calderwoodra) */ -final class Cp2PhoneLookup implements PhoneLookup { +/** PhoneLookup implementation for local contacts. */ +public final class Cp2PhoneLookup implements PhoneLookup { + + private final Context context; + + Cp2PhoneLookup(Context context) { + this.context = context; + } @Override public ListenableFuture<Boolean> isDirty( ImmutableSet<DialerPhoneNumber> phoneNumbers, long lastModified) { - // TODO(calderwoodra) - return null; + // TODO(calderwoodra): consider a different thread pool + return MoreExecutors.listeningDecorator(DialerExecutors.getLowPriorityThreadPool(context)) + .submit(() -> isDirtyInternal(phoneNumbers, lastModified)); + } + + private boolean isDirtyInternal(ImmutableSet<DialerPhoneNumber> phoneNumbers, long lastModified) { + return contactsUpdated(getContactIdsFromPhoneNumbers(phoneNumbers), lastModified) + || contactsDeleted(lastModified); + } + + /** Returns set of contact ids that correspond to {@code phoneNumbers} if the contact exists. */ + private Set<Long> getContactIdsFromPhoneNumbers(ImmutableSet<DialerPhoneNumber> phoneNumbers) { + Set<Long> contactIds = new ArraySet<>(); + try (Cursor cursor = + context + .getContentResolver() + .query( + Phone.CONTENT_URI, + new String[] {Phone.CONTACT_ID}, + columnInSetWhereStatement(Phone.NORMALIZED_NUMBER, phoneNumbers.size()), + contactIdsSelectionArgs(phoneNumbers), + null)) { + cursor.moveToPosition(-1); + while (cursor.moveToNext()) { + contactIds.add(cursor.getLong(0 /* columnIndex */)); + } + } + return contactIds; + } + + private static String[] contactIdsSelectionArgs(ImmutableSet<DialerPhoneNumber> phoneNumbers) { + String[] args = new String[phoneNumbers.size()]; + int i = 0; + for (DialerPhoneNumber phoneNumber : phoneNumbers) { + args[i++] = getNormalizedNumber(phoneNumber); + } + return args; + } + + private static String getNormalizedNumber(DialerPhoneNumber phoneNumber) { + // TODO(calderwoodra): implement normalization logic that matches contacts. + return phoneNumber.getRawInput().getNumber(); + } + + /** Returns true if any contacts were modified after {@code lastModified}. */ + private boolean contactsUpdated(Set<Long> contactIds, long lastModified) { + try (Cursor cursor = + context + .getContentResolver() + .query( + Contacts.CONTENT_URI, + new String[] {Contacts._ID}, + contactsIsDirtyWhereStatement(contactIds.size()), + contactsIsDirtySelectionArgs(lastModified, contactIds), + null)) { + return cursor.getCount() > 0; + } + } + + private static String contactsIsDirtyWhereStatement(int numberOfContactIds) { + StringBuilder where = new StringBuilder(); + // Filter to after last modified time + where.append(Contacts.CONTACT_LAST_UPDATED_TIMESTAMP).append(" > ?"); + + // Filter based only on contacts we care about + where.append(" AND ").append(columnInSetWhereStatement(Contacts._ID, numberOfContactIds)); + return where.toString(); + } + + private String[] contactsIsDirtySelectionArgs(long lastModified, Set<Long> contactIds) { + String[] args = new String[contactIds.size() + 1]; + args[0] = Long.toString(lastModified); + int i = 1; + for (Long contactId : contactIds) { + args[i++] = Long.toString(contactId); + } + return args; + } + + /** Returns true if any contacts were deleted after {@code lastModified}. */ + private boolean contactsDeleted(long lastModified) { + try (Cursor cursor = + context + .getContentResolver() + .query( + DeletedContacts.CONTENT_URI, + new String[] {DeletedContacts.CONTACT_DELETED_TIMESTAMP}, + DeletedContacts.CONTACT_DELETED_TIMESTAMP + " > ?", + new String[] {Long.toString(lastModified)}, + null)) { + return cursor.getCount() > 0; + } + } + + private static String columnInSetWhereStatement(String columnName, int setSize) { + StringBuilder where = new StringBuilder(); + where.append(columnName).append(" IN ("); + for (int i = 0; i < setSize; i++) { + if (i != 0) { + where.append(", "); + } + where.append("?"); + } + return where.append(")").toString(); } @Override diff --git a/java/com/android/dialer/searchfragment/list/NewSearchFragment.java b/java/com/android/dialer/searchfragment/list/NewSearchFragment.java index ef1b4fc19..c200b946c 100644 --- a/java/com/android/dialer/searchfragment/list/NewSearchFragment.java +++ b/java/com/android/dialer/searchfragment/list/NewSearchFragment.java @@ -20,6 +20,7 @@ import static android.Manifest.permission.ACCESS_FINE_LOCATION; import android.app.Fragment; import android.app.LoaderManager.LoaderCallbacks; +import android.content.Intent; import android.content.Loader; import android.content.pm.PackageManager; import android.database.Cursor; @@ -31,6 +32,7 @@ import android.support.annotation.VisibleForTesting; import android.support.v13.app.FragmentCompat; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; +import android.telephony.TelephonyManager; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.MotionEvent; @@ -42,13 +44,23 @@ import android.widget.FrameLayout; import android.widget.FrameLayout.LayoutParams; import com.android.contacts.common.extensions.PhoneDirectoryExtenderAccessor; import com.android.dialer.animation.AnimUtils; +import com.android.dialer.assisteddialing.ConcreteCreator; +import com.android.dialer.callcomposer.CallComposerActivity; import com.android.dialer.callintent.CallInitiationType; +import com.android.dialer.callintent.CallIntentBuilder; +import com.android.dialer.callintent.CallSpecificAppData; import com.android.dialer.common.Assert; import com.android.dialer.common.FragmentUtils; import com.android.dialer.common.LogUtil; import com.android.dialer.common.concurrent.ThreadUtil; +import com.android.dialer.constants.ActivityRequestCodes; +import com.android.dialer.dialercontact.DialerContact; +import com.android.dialer.duo.DuoComponent; import com.android.dialer.enrichedcall.EnrichedCallComponent; import com.android.dialer.enrichedcall.EnrichedCallManager.CapabilitiesListener; +import com.android.dialer.logging.DialerImpression; +import com.android.dialer.logging.Logger; +import com.android.dialer.searchfragment.common.RowClickListener; import com.android.dialer.searchfragment.common.SearchCursor; import com.android.dialer.searchfragment.cp2.SearchContactsCursorLoader; import com.android.dialer.searchfragment.list.SearchActionViewHolder.Action; @@ -72,7 +84,8 @@ public final class NewSearchFragment extends Fragment implements LoaderCallbacks<Cursor>, OnEmptyViewActionButtonClickedListener, CapabilitiesListener, - OnTouchListener { + OnTouchListener, + RowClickListener { // Since some of our queries can generate network requests, we should delay them until the user // stops typing to prevent generating too much network traffic. @@ -124,9 +137,8 @@ public final class NewSearchFragment extends Fragment public View onCreateView( LayoutInflater inflater, @Nullable ViewGroup parent, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_search, parent, false); - adapter = new SearchAdapter(getActivity(), new SearchCursorManager()); + adapter = new SearchAdapter(getContext(), new SearchCursorManager(), this); adapter.setQuery(query); - adapter.setCallInitiationType(callInitiationType); adapter.setSearchActions(getActions()); adapter.setZeroSuggestVisible(getArguments().getBoolean(KEY_SHOW_ZERO_SUGGEST)); emptyContentView = view.findViewById(R.id.empty_view); @@ -241,7 +253,6 @@ public final class NewSearchFragment extends Fragment this.callInitiationType = callInitiationType; if (adapter != null) { adapter.setQuery(query); - adapter.setCallInitiationType(callInitiationType); adapter.setSearchActions(getActions()); adapter.setZeroSuggestVisible(isRegularSearch()); loadNearbyPlacesCursor(); @@ -449,12 +460,59 @@ public final class NewSearchFragment extends Fragment if (event.getAction() == MotionEvent.ACTION_UP) { v.performClick(); } - return FragmentUtils.getParentUnsafe(this, SearchFragmentListTouchListener.class) + return FragmentUtils.getParentUnsafe(this, SearchFragmentListener.class) .onSearchListTouch(event); } - /** Callback to {@link NewSearchFragment}'s parent to notify when the list is touched. */ - public interface SearchFragmentListTouchListener { + @Override + public void placeVoiceCall(String phoneNumber, int ranking) { + placeCall(phoneNumber, ranking, false, true); + } + + @Override + public void placeVideoCall(String phoneNumber, int ranking) { + placeCall(phoneNumber, ranking, true, false); + } + + private void placeCall( + String phoneNumber, int position, boolean isVideoCall, boolean allowAssistedDial) { + CallSpecificAppData callSpecificAppData = + CallSpecificAppData.newBuilder() + .setCallInitiationType(callInitiationType) + .setPositionOfSelectedSearchResult(position) + .setCharactersInSearchString(query == null ? 0 : query.length()) + .setAllowAssistedDialing(allowAssistedDial) + .build(); + Intent intent = + new CallIntentBuilder(phoneNumber, callSpecificAppData) + .setIsVideoCall(isVideoCall) + .setAllowAssistedDial( + allowAssistedDial, + ConcreteCreator.createNewAssistedDialingMediator( + getContext().getSystemService(TelephonyManager.class), + getContext().getApplicationContext())) + .build(); + DialerUtils.startActivityWithErrorToast(getActivity(), intent); + FragmentUtils.getParentUnsafe(this, SearchFragmentListener.class).onCallPlaced(); + } + + @Override + public void placeDuoCall(String phoneNumber) { + Logger.get(getContext()) + .logImpression(DialerImpression.Type.LIGHTBRINGER_VIDEO_REQUESTED_FROM_SEARCH); + Intent intent = DuoComponent.get(getContext()).getDuo().getIntent(getContext(), phoneNumber); + getActivity().startActivityForResult(intent, ActivityRequestCodes.DIALTACTS_DUO); + FragmentUtils.getParentUnsafe(this, SearchFragmentListener.class).onCallPlaced(); + } + + @Override + public void openCallAndShare(DialerContact contact) { + Intent intent = CallComposerActivity.newIntent(getContext(), contact); + DialerUtils.startActivityWithErrorToast(getContext(), intent); + } + + /** Callback to {@link NewSearchFragment}'s parent to be notified of important events. */ + public interface SearchFragmentListener { /** * Called when the list view in {@link NewSearchFragment} is touched. @@ -462,5 +520,8 @@ public final class NewSearchFragment extends Fragment * @see OnTouchListener#onTouch(View, MotionEvent) */ boolean onSearchListTouch(MotionEvent event); + + /** Called when a call is placed from the search fragment. */ + void onCallPlaced(); } } diff --git a/java/com/android/dialer/searchfragment/list/SearchAdapter.java b/java/com/android/dialer/searchfragment/list/SearchAdapter.java index 949c2a2c5..dc78953b5 100644 --- a/java/com/android/dialer/searchfragment/list/SearchAdapter.java +++ b/java/com/android/dialer/searchfragment/list/SearchAdapter.java @@ -16,55 +16,43 @@ package com.android.dialer.searchfragment.list; -import android.app.Activity; -import android.content.Intent; +import android.content.Context; import android.support.annotation.VisibleForTesting; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView.ViewHolder; -import android.telephony.TelephonyManager; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; -import com.android.dialer.assisteddialing.ConcreteCreator; -import com.android.dialer.callcomposer.CallComposerActivity; -import com.android.dialer.callintent.CallInitiationType; -import com.android.dialer.callintent.CallIntentBuilder; -import com.android.dialer.callintent.CallSpecificAppData; import com.android.dialer.common.Assert; -import com.android.dialer.constants.ActivityRequestCodes; -import com.android.dialer.dialercontact.DialerContact; -import com.android.dialer.duo.DuoComponent; -import com.android.dialer.logging.DialerImpression; -import com.android.dialer.logging.Logger; import com.android.dialer.searchfragment.common.RowClickListener; import com.android.dialer.searchfragment.common.SearchCursor; import com.android.dialer.searchfragment.cp2.SearchContactViewHolder; import com.android.dialer.searchfragment.list.SearchCursorManager.RowType; import com.android.dialer.searchfragment.nearbyplaces.NearbyPlaceViewHolder; import com.android.dialer.searchfragment.remote.RemoteContactViewHolder; -import com.android.dialer.util.DialerUtils; import java.util.List; /** RecyclerView adapter for {@link NewSearchFragment}. */ @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) -public final class SearchAdapter extends RecyclerView.Adapter<ViewHolder> - implements RowClickListener { +public final class SearchAdapter extends RecyclerView.Adapter<ViewHolder> { private final SearchCursorManager searchCursorManager; - private final Activity activity; + private final Context context; private boolean showZeroSuggest; private String query; - private CallInitiationType.Type callInitiationType = CallInitiationType.Type.UNKNOWN_INITIATION; private OnClickListener allowClickListener; private OnClickListener dismissClickListener; + private RowClickListener rowClickListener; @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) - public SearchAdapter(Activity activity, SearchCursorManager searchCursorManager) { - this.activity = activity; + public SearchAdapter( + Context context, SearchCursorManager searchCursorManager, RowClickListener rowClickListener) { + this.context = context; this.searchCursorManager = searchCursorManager; + this.rowClickListener = rowClickListener; } @Override @@ -72,24 +60,25 @@ public final class SearchAdapter extends RecyclerView.Adapter<ViewHolder> switch (rowType) { case RowType.CONTACT_ROW: return new SearchContactViewHolder( - LayoutInflater.from(activity).inflate(R.layout.search_contact_row, root, false), this); + LayoutInflater.from(context).inflate(R.layout.search_contact_row, root, false), + rowClickListener); case RowType.NEARBY_PLACES_ROW: return new NearbyPlaceViewHolder( - LayoutInflater.from(activity).inflate(R.layout.search_contact_row, root, false)); + LayoutInflater.from(context).inflate(R.layout.search_contact_row, root, false)); case RowType.CONTACT_HEADER: case RowType.DIRECTORY_HEADER: case RowType.NEARBY_PLACES_HEADER: return new HeaderViewHolder( - LayoutInflater.from(activity).inflate(R.layout.header_layout, root, false)); + LayoutInflater.from(context).inflate(R.layout.header_layout, root, false)); case RowType.DIRECTORY_ROW: return new RemoteContactViewHolder( - LayoutInflater.from(activity).inflate(R.layout.search_contact_row, root, false)); + LayoutInflater.from(context).inflate(R.layout.search_contact_row, root, false)); case RowType.SEARCH_ACTION: return new SearchActionViewHolder( - LayoutInflater.from(activity).inflate(R.layout.search_action_layout, root, false)); + LayoutInflater.from(context).inflate(R.layout.search_action_layout, root, false)); case RowType.LOCATION_REQUEST: return new LocationPermissionViewHolder( - LayoutInflater.from(activity).inflate(R.layout.location_permission_row, root, false), + LayoutInflater.from(context).inflate(R.layout.location_permission_row, root, false), allowClickListener, dismissClickListener); case RowType.INVALID: @@ -168,10 +157,6 @@ public final class SearchAdapter extends RecyclerView.Adapter<ViewHolder> } } - void setCallInitiationType(CallInitiationType.Type callInitiationType) { - this.callInitiationType = callInitiationType; - } - public void setNearbyPlacesCursor(SearchCursor nearbyPlacesCursor) { if (searchCursorManager.setNearbyPlacesCursor(nearbyPlacesCursor)) { notifyDataSetChanged(); @@ -209,51 +194,6 @@ public final class SearchAdapter extends RecyclerView.Adapter<ViewHolder> } } - @Override - public void placeVoiceCall(String phoneNumber, int ranking) { - placeCall(phoneNumber, ranking, false, true); - } - - @Override - public void placeVideoCall(String phoneNumber, int ranking) { - placeCall(phoneNumber, ranking, true, false); - } - - private void placeCall( - String phoneNumber, int position, boolean isVideoCall, boolean allowAssistedDial) { - CallSpecificAppData callSpecificAppData = - CallSpecificAppData.newBuilder() - .setCallInitiationType(callInitiationType) - .setPositionOfSelectedSearchResult(position) - .setCharactersInSearchString(query == null ? 0 : query.length()) - .setAllowAssistedDialing(allowAssistedDial) - .build(); - Intent intent = - new CallIntentBuilder(phoneNumber, callSpecificAppData) - .setIsVideoCall(isVideoCall) - .setAllowAssistedDial( - allowAssistedDial, - ConcreteCreator.createNewAssistedDialingMediator( - activity.getSystemService(TelephonyManager.class), - activity.getApplicationContext())) - .build(); - DialerUtils.startActivityWithErrorToast(activity, intent); - } - - @Override - public void placeDuoCall(String phoneNumber) { - Logger.get(activity) - .logImpression(DialerImpression.Type.LIGHTBRINGER_VIDEO_REQUESTED_FROM_SEARCH); - Intent intent = DuoComponent.get(activity).getDuo().getIntent(activity, phoneNumber); - activity.startActivityForResult(intent, ActivityRequestCodes.DIALTACTS_DUO); - } - - @Override - public void openCallAndShare(DialerContact contact) { - Intent intent = CallComposerActivity.newIntent(activity, contact); - DialerUtils.startActivityWithErrorToast(activity, intent); - } - /** Viewholder for R.layout.location_permission_row that requests the location permission. */ private static class LocationPermissionViewHolder extends RecyclerView.ViewHolder { diff --git a/java/com/android/incallui/InCallActivity.java b/java/com/android/incallui/InCallActivity.java index c3a68c021..c509e4890 100644 --- a/java/com/android/incallui/InCallActivity.java +++ b/java/com/android/incallui/InCallActivity.java @@ -40,6 +40,8 @@ import com.android.dialer.compat.ActivityCompat; import com.android.dialer.configprovider.ConfigProviderBindings; import com.android.dialer.logging.DialerImpression; import com.android.dialer.logging.Logger; +import com.android.dialer.logging.LoggingBindings; +import com.android.dialer.logging.LoggingBindingsFactory; import com.android.dialer.logging.ScreenEvent; import com.android.incallui.answer.bindings.AnswerBindings; import com.android.incallui.answer.protocol.AnswerScreen; @@ -145,6 +147,14 @@ public class InCallActivity extends TransactionSafeFragmentActivity pseudoBlackScreenOverlay = findViewById(R.id.psuedo_black_screen_overlay); sendBroadcast(CallPendingActivity.getFinishBroadcast()); Trace.endSection(); + if (getApplicationContext() instanceof LoggingBindingsFactory) { + LoggingBindings loggingBindings = + ((LoggingBindingsFactory) getApplicationContext()).newLoggingBindings(); + loggingBindings.logStopLatencyTimer( + LoggingBindings.ON_CALL_ADDED_TO_ON_INCALL_UI_SHOWN_INCOMING); + loggingBindings.logStopLatencyTimer( + LoggingBindings.ON_CALL_ADDED_TO_ON_INCALL_UI_SHOWN_OUTGOING); + } } @Override diff --git a/java/com/android/incallui/StatusBarNotifier.java b/java/com/android/incallui/StatusBarNotifier.java index 4ce43935e..bb3ef4333 100644 --- a/java/com/android/incallui/StatusBarNotifier.java +++ b/java/com/android/incallui/StatusBarNotifier.java @@ -624,7 +624,8 @@ public class StatusBarNotifier * Returns the appropriate icon res Id to display based on the call for which we want to display * information. */ - private int getIconToDisplay(DialerCall call) { + @VisibleForTesting + public int getIconToDisplay(DialerCall call) { // Even if both lines are in use, we only show a single item in // the expanded Notifications UI. It's labeled "Ongoing call" // (or "On hold" if there's only one call, and it's on hold.) @@ -633,7 +634,7 @@ public class StatusBarNotifier // from the foreground call. And if there's a ringing call, // display that regardless of the state of the other calls. if (call.getState() == DialerCall.State.ONHOLD) { - return R.drawable.ic_phone_paused_white_24dp; + return R.drawable.quantum_ic_phone_paused_vd_theme_24; } else if (call.getVideoTech().getSessionModificationState() == SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST || call.isVideoCall()) { @@ -644,6 +645,8 @@ public class StatusBarNotifier // helpful hint for users so they know how to get back to the call. For Sprint HD calls, we // replace this icon with an icon of a phone with a HD badge. This is a carrier requirement. return R.drawable.ic_hd_call; + } else if (call.hasProperty(Details.PROPERTY_HAS_CDMA_VOICE_PRIVACY)) { + return R.drawable.quantum_ic_phone_locked_vd_theme_24; } // If ReturnToCall is enabled, use the static icon. The animated one will show in the bubble. if (ReturnToCallController.isEnabled(mContext) diff --git a/java/com/android/incallui/call/CallList.java b/java/com/android/incallui/call/CallList.java index 59f38349a..4f1dfd43f 100644 --- a/java/com/android/incallui/call/CallList.java +++ b/java/com/android/incallui/call/CallList.java @@ -36,6 +36,8 @@ import com.android.dialer.enrichedcall.EnrichedCallComponent; import com.android.dialer.enrichedcall.EnrichedCallManager; import com.android.dialer.logging.DialerImpression; import com.android.dialer.logging.Logger; +import com.android.dialer.logging.LoggingBindings; +import com.android.dialer.logging.LoggingBindingsFactory; import com.android.dialer.shortcuts.ShortcutUsageReporter; import com.android.dialer.spam.Spam; import com.android.dialer.spam.SpamBindings; @@ -117,6 +119,17 @@ public class CallList implements DialerCallDelegate { public void onCallAdded( final Context context, final android.telecom.Call telecomCall, LatencyReport latencyReport) { Trace.beginSection("CallList.onCallAdded"); + if (context.getApplicationContext() instanceof LoggingBindingsFactory) { + if (telecomCall.getState() == Call.STATE_CONNECTING) { + ((LoggingBindingsFactory) context.getApplicationContext()) + .newLoggingBindings() + .logStartLatencyTimer(LoggingBindings.ON_CALL_ADDED_TO_ON_INCALL_UI_SHOWN_OUTGOING); + } else if (telecomCall.getState() == Call.STATE_RINGING) { + ((LoggingBindingsFactory) context.getApplicationContext()) + .newLoggingBindings() + .logStartLatencyTimer(LoggingBindings.ON_CALL_ADDED_TO_ON_INCALL_UI_SHOWN_INCOMING); + } + } if (mUiListeners != null) { mUiListeners.onCallAdded(); } diff --git a/java/com/android/incallui/res/drawable-hdpi/ic_phone_paused_white_24dp.png b/java/com/android/incallui/res/drawable-hdpi/ic_phone_paused_white_24dp.png Binary files differdeleted file mode 100644 index a2177f58a..000000000 --- a/java/com/android/incallui/res/drawable-hdpi/ic_phone_paused_white_24dp.png +++ /dev/null diff --git a/java/com/android/incallui/res/drawable-mdpi/ic_phone_paused_white_24dp.png b/java/com/android/incallui/res/drawable-mdpi/ic_phone_paused_white_24dp.png Binary files differdeleted file mode 100644 index 7dc920b2b..000000000 --- a/java/com/android/incallui/res/drawable-mdpi/ic_phone_paused_white_24dp.png +++ /dev/null diff --git a/java/com/android/incallui/res/drawable-xhdpi/ic_phone_paused_white_24dp.png b/java/com/android/incallui/res/drawable-xhdpi/ic_phone_paused_white_24dp.png Binary files differdeleted file mode 100644 index a8becf485..000000000 --- a/java/com/android/incallui/res/drawable-xhdpi/ic_phone_paused_white_24dp.png +++ /dev/null diff --git a/java/com/android/incallui/res/drawable-xxhdpi/ic_phone_paused_white_24dp.png b/java/com/android/incallui/res/drawable-xxhdpi/ic_phone_paused_white_24dp.png Binary files differdeleted file mode 100644 index baf0cf27f..000000000 --- a/java/com/android/incallui/res/drawable-xxhdpi/ic_phone_paused_white_24dp.png +++ /dev/null |