diff options
author | android-build-prod (mdb) <android-build-team-robot@google.com> | 2018-05-04 07:50:16 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2018-05-04 07:50:16 +0000 |
commit | 64679377a2400a0d740230331ef6f791cc6063a1 (patch) | |
tree | 315bfa183f5d45b48b4118f60543dd226dac45b4 /java | |
parent | e36fd9d0e29f151f5289da2b44ffebb1a508a4be (diff) | |
parent | d95d0f6bec2b144ae89e5f6ae9fc453508536cd9 (diff) |
Merge changes I5e341af6,I4356d04c,I849352d8
* changes:
Save connection info in the DialerCall
Replace DuoConstants with interface.
Set active audio route selected.
Diffstat (limited to 'java')
23 files changed, 215 insertions, 173 deletions
diff --git a/java/com/android/dialer/app/calllog/CallLogAdapter.java b/java/com/android/dialer/app/calllog/CallLogAdapter.java index b9bd23300..b99cef11f 100644 --- a/java/com/android/dialer/app/calllog/CallLogAdapter.java +++ b/java/com/android/dialer/app/calllog/CallLogAdapter.java @@ -76,7 +76,6 @@ import com.android.dialer.compat.android.provider.VoicemailCompat; import com.android.dialer.configprovider.ConfigProviderBindings; import com.android.dialer.duo.Duo; import com.android.dialer.duo.DuoComponent; -import com.android.dialer.duo.DuoConstants; import com.android.dialer.duo.DuoListener; import com.android.dialer.enrichedcall.EnrichedCallCapabilities; import com.android.dialer.enrichedcall.EnrichedCallComponent; @@ -426,7 +425,10 @@ public class CallLogAdapter extends GroupingListAdapter if (intentProvider == null) { return false; } - return DuoConstants.PACKAGE_NAME.equals(intentProvider.getIntent(activity).getPackage()); + return DuoComponent.get(activity) + .getDuo() + .getIntentType(intentProvider.getIntent(activity)) + .isPresent(); } }; @@ -568,7 +570,7 @@ public class CallLogAdapter extends GroupingListAdapter new PhoneCallDetailsHelper(this.activity, resources, this.callLogCache); callLogListItemHelper = new CallLogListItemHelper(phoneCallDetailsHelper, resources, this.callLogCache); - callLogGroupBuilder = new CallLogGroupBuilder(this); + callLogGroupBuilder = new CallLogGroupBuilder(activity.getApplicationContext(), this); this.filteredNumberAsyncQueryHandler = Assert.isNotNull(filteredNumberAsyncQueryHandler); contactsPreferences = new ContactsPreferences(this.activity); @@ -1032,9 +1034,7 @@ public class CallLogAdapter extends GroupingListAdapter String phoneAccountComponentName = cursor.getString(CallLogQuery.ACCOUNT_COMPONENT_NAME); - if (DuoConstants.PHONE_ACCOUNT_COMPONENT_NAME - .flattenToString() - .equals(phoneAccountComponentName)) { + if (DuoComponent.get(activity).getDuo().isDuoAccount(phoneAccountComponentName)) { entry.setIsDuoCall(true); } diff --git a/java/com/android/dialer/app/calllog/CallLogGroupBuilder.java b/java/com/android/dialer/app/calllog/CallLogGroupBuilder.java index e4bae5e5f..26b3a6260 100644 --- a/java/com/android/dialer/app/calllog/CallLogGroupBuilder.java +++ b/java/com/android/dialer/app/calllog/CallLogGroupBuilder.java @@ -16,6 +16,7 @@ package com.android.dialer.app.calllog; +import android.content.Context; import android.database.Cursor; import android.support.annotation.Nullable; import android.support.annotation.VisibleForTesting; @@ -27,6 +28,7 @@ import com.android.dialer.calllogutils.CallbackActionHelper; import com.android.dialer.calllogutils.CallbackActionHelper.CallbackAction; import com.android.dialer.compat.AppCompatConstants; import com.android.dialer.compat.telephony.TelephonyManagerCompat; +import com.android.dialer.inject.ApplicationContext; import com.android.dialer.phonenumbercache.CallLogQuery; import com.android.dialer.phonenumberutil.PhoneNumberHelper; import java.util.Objects; @@ -55,10 +57,13 @@ public class CallLogGroupBuilder { public static final int DAY_GROUP_OTHER = 2; /** Instance of the time object used for time calculations. */ private static final Time TIME = new Time(); + + private final Context appContext; /** The object on which the groups are created. */ private final GroupCreator groupCreator; - public CallLogGroupBuilder(GroupCreator groupCreator) { + public CallLogGroupBuilder(@ApplicationContext Context appContext, GroupCreator groupCreator) { + this.appContext = appContext; this.groupCreator = groupCreator; } @@ -97,7 +102,7 @@ public class CallLogGroupBuilder { int groupFeatures = cursor.getInt(CallLogQuery.FEATURES); int groupCallbackAction = CallbackActionHelper.getCallbackAction( - groupNumber, groupFeatures, groupAccountComponentName); + appContext, groupNumber, groupFeatures, groupAccountComponentName); groupCreator.setCallbackAction(firstRowId, groupCallbackAction); // Instantiate other group values to those of the first call in the cursor. @@ -126,7 +131,8 @@ public class CallLogGroupBuilder { accountComponentName = cursor.getString(CallLogQuery.ACCOUNT_COMPONENT_NAME); accountId = cursor.getString(CallLogQuery.ACCOUNT_ID); callbackAction = - CallbackActionHelper.getCallbackAction(number, callFeatures, accountComponentName); + CallbackActionHelper.getCallbackAction( + appContext, number, callFeatures, accountComponentName); final boolean isSameNumber = equalNumbers(groupNumber, number); final boolean isSamePostDialDigits = groupPostDialDigits.equals(numberPostDialDigits); diff --git a/java/com/android/dialer/app/calllog/CallLogListItemViewHolder.java b/java/com/android/dialer/app/calllog/CallLogListItemViewHolder.java index 3f7def953..54748387e 100644 --- a/java/com/android/dialer/app/calllog/CallLogListItemViewHolder.java +++ b/java/com/android/dialer/app/calllog/CallLogListItemViewHolder.java @@ -78,7 +78,6 @@ import com.android.dialer.dialercontact.DialerContact; import com.android.dialer.dialercontact.SimDetails; import com.android.dialer.duo.Duo; import com.android.dialer.duo.DuoComponent; -import com.android.dialer.duo.DuoConstants; import com.android.dialer.lettertile.LetterTileDrawable; import com.android.dialer.lettertile.LetterTileDrawable.ContactType; import com.android.dialer.logging.ContactSource; @@ -97,6 +96,7 @@ import com.android.dialer.telecom.TelecomUtil; import com.android.dialer.util.CallUtil; import com.android.dialer.util.DialerUtils; import com.android.dialer.util.UriUtils; +import com.google.common.base.Optional; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; @@ -795,9 +795,10 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder } private boolean showDuoPrimaryButton() { + Duo duo = DuoComponent.get(context).getDuo(); return accountHandle != null - && accountHandle.getComponentName().equals(DuoConstants.PHONE_ACCOUNT_COMPONENT_NAME) - && DuoComponent.get(context).getDuo().isReachable(context, number); + && duo.isDuoAccount(accountHandle) + && duo.isReachable(context, number); } private static boolean hasDialableChar(CharSequence number) { @@ -1032,9 +1033,10 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder // We check to see if we are starting a Duo intent. The reason is Duo // intents need to be started using startActivityForResult instead of the usual startActivity - String packageName = intent.getPackage(); - if (DuoConstants.PACKAGE_NAME.equals(packageName)) { - startDuoActivity(intent); + Optional<Duo.IntentType> duoIntentType = + DuoComponent.get(context).getDuo().getIntentType(intent); + if (duoIntentType.isPresent()) { + startDuoActivity(intent, duoIntentType.get()); } else if (OldCallDetailsActivity.isLaunchIntent(intent)) { PerformanceReport.recordClick(UiAction.Type.OPEN_CALL_DETAIL); ((Activity) context) @@ -1044,8 +1046,8 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder && intent.getIntExtra(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, -1) == VideoProfile.STATE_BIDIRECTIONAL) { Logger.get(context).logImpression(DialerImpression.Type.IMS_VIDEO_REQUESTED_FROM_CALL_LOG); - } else if (intent.getDataString() != null - && intent.getDataString().contains(DuoConstants.PACKAGE_NAME)) { + } else if (intent.filterEquals( + DuoComponent.get(context).getDuo().getInstallDuoIntent().orNull())) { Logger.get(context).logImpression(DialerImpression.Type.DUO_CALL_LOG_SET_UP_INSTALL); } @@ -1060,24 +1062,24 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder return false; } - private void startDuoActivity(Intent intent) { - if (DuoConstants.DUO_ACTIVATE_ACTION.equals(intent.getAction())) { - Logger.get(context).logImpression(DialerImpression.Type.DUO_CALL_LOG_SET_UP_ACTIVATE); - } else if (DuoConstants.DUO_INVITE_ACTION.equals(intent.getAction())) { - Logger.get(context).logImpression(DialerImpression.Type.DUO_CALL_LOG_INVITE); - } else if (DuoConstants.DUO_CALL_ACTION.equals(intent.getAction())) { - Logger.get(context) - .logImpression(DialerImpression.Type.LIGHTBRINGER_VIDEO_REQUESTED_FROM_CALL_LOG); - if (isNonContactEntry(info)) { + private void startDuoActivity(Intent intent, Duo.IntentType intentType) { + switch (intentType) { + case CALL: Logger.get(context) - .logImpression( - DialerImpression.Type.LIGHTBRINGER_NON_CONTACT_VIDEO_REQUESTED_FROM_CALL_LOG); - } - } else { - throw Assert.createIllegalStateFailException( - "Duo intent with invalid action" + intent.getAction()); + .logImpression(DialerImpression.Type.LIGHTBRINGER_VIDEO_REQUESTED_FROM_CALL_LOG); + if (isNonContactEntry(info)) { + Logger.get(context) + .logImpression( + DialerImpression.Type.LIGHTBRINGER_NON_CONTACT_VIDEO_REQUESTED_FROM_CALL_LOG); + } + break; + case INVITE: + Logger.get(context).logImpression(DialerImpression.Type.DUO_CALL_LOG_INVITE); + break; + case ACTIVATE: + Logger.get(context).logImpression(DialerImpression.Type.DUO_CALL_LOG_SET_UP_ACTIVATE); + break; } - try { Activity activity = (Activity) context; activity.startActivityForResult(intent, ActivityRequestCodes.DIALTACTS_DUO); diff --git a/java/com/android/dialer/app/calllog/IntentProvider.java b/java/com/android/dialer/app/calllog/IntentProvider.java index a794c6290..1bc726f64 100644 --- a/java/com/android/dialer/app/calllog/IntentProvider.java +++ b/java/com/android/dialer/app/calllog/IntentProvider.java @@ -22,7 +22,6 @@ import android.content.Intent; import android.net.Uri; import android.provider.ContactsContract; import android.support.annotation.Nullable; -import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; import android.telephony.TelephonyManager; import com.android.contacts.common.model.Contact; @@ -33,7 +32,6 @@ import com.android.dialer.callintent.CallInitiationType; import com.android.dialer.callintent.CallIntentBuilder; import com.android.dialer.dialercontact.DialerContact; import com.android.dialer.duo.DuoComponent; -import com.android.dialer.duo.DuoConstants; import com.android.dialer.precall.PreCall; import com.android.dialer.util.IntentUtil; import java.util.ArrayList; @@ -99,7 +97,7 @@ public abstract class IntentProvider { return new IntentProvider() { @Override public Intent getIntent(Context context) { - return DuoComponent.get(context).getDuo().getIntent(context, number); + return DuoComponent.get(context).getDuo().getCallIntent(number).orNull(); } }; } @@ -108,18 +106,7 @@ public abstract class IntentProvider { return new IntentProvider() { @Override public Intent getIntent(Context context) { - return new Intent( - Intent.ACTION_VIEW, - new Uri.Builder() - .scheme("https") - .authority("play.google.com") - .appendEncodedPath("store/apps/details") - .appendQueryParameter("id", DuoConstants.PACKAGE_NAME) - .appendQueryParameter( - "referrer", - "utm_source=dialer&utm_medium=text&utm_campaign=product") // This string is from - // the Duo team - .build()); + return DuoComponent.get(context).getDuo().getInstallDuoIntent().orNull(); } }; } @@ -128,7 +115,7 @@ public abstract class IntentProvider { return new IntentProvider() { @Override public Intent getIntent(Context context) { - return new Intent(DuoConstants.DUO_ACTIVATE_ACTION).setPackage(DuoConstants.PACKAGE_NAME); + return DuoComponent.get(context).getDuo().getActivateIntent().orNull(); } }; } @@ -137,11 +124,7 @@ public abstract class IntentProvider { return new IntentProvider() { @Override public Intent getIntent(Context context) { - Intent intent = - new Intent(DuoConstants.DUO_INVITE_ACTION) - .setPackage(DuoConstants.PACKAGE_NAME) - .setData(Uri.fromParts(PhoneAccount.SCHEME_TEL, number, null /* fragment */)); - return intent; + return DuoComponent.get(context).getDuo().getInviteIntent(number).orNull(); } }; } diff --git a/java/com/android/dialer/app/calllog/MissedCallNotifier.java b/java/com/android/dialer/app/calllog/MissedCallNotifier.java index 772feed53..2cd0f775c 100644 --- a/java/com/android/dialer/app/calllog/MissedCallNotifier.java +++ b/java/com/android/dialer/app/calllog/MissedCallNotifier.java @@ -52,7 +52,7 @@ import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; import com.android.dialer.common.concurrent.DialerExecutor.Worker; import com.android.dialer.compat.android.provider.VoicemailCompat; -import com.android.dialer.duo.DuoConstants; +import com.android.dialer.duo.DuoComponent; import com.android.dialer.enrichedcall.FuzzyPhoneNumberMatcher; import com.android.dialer.notification.DialerNotificationManager; import com.android.dialer.notification.NotificationChannelId; @@ -275,7 +275,7 @@ public class MissedCallNotifier implements Worker<Pair<Integer, String>, Void> { if (phoneAccount == null) { continue; } - if (DuoConstants.PHONE_ACCOUNT_HANDLE.equals(phoneAccountHandle)) { + if (DuoComponent.get(context).getDuo().isDuoAccount(phoneAccountHandle)) { iterator.remove(); continue; } diff --git a/java/com/android/dialer/calldetails/CallDetailsActivity.java b/java/com/android/dialer/calldetails/CallDetailsActivity.java index f1d0d8487..36b830851 100644 --- a/java/com/android/dialer/calldetails/CallDetailsActivity.java +++ b/java/com/android/dialer/calldetails/CallDetailsActivity.java @@ -127,7 +127,7 @@ public final class CallDetailsActivity extends CallDetailsActivityCommon { @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { - updateCallDetailsEntries(CallDetailsCursorLoader.toCallDetailsEntries(data)); + updateCallDetailsEntries(CallDetailsCursorLoader.toCallDetailsEntries(activity, data)); activity.loadRttTranscriptAvailability(); } diff --git a/java/com/android/dialer/calldetails/CallDetailsActivityCommon.java b/java/com/android/dialer/calldetails/CallDetailsActivityCommon.java index 8f850ae25..80a41919d 100644 --- a/java/com/android/dialer/calldetails/CallDetailsActivityCommon.java +++ b/java/com/android/dialer/calldetails/CallDetailsActivityCommon.java @@ -63,6 +63,7 @@ import com.android.dialer.postcall.PostCall; import com.android.dialer.precall.PreCall; import com.android.dialer.rtt.RttTranscriptActivity; import com.android.dialer.rtt.RttTranscriptUtil; +import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableSet; import com.google.i18n.phonenumbers.NumberParseException; @@ -327,15 +328,15 @@ abstract class CallDetailsActivityCommon extends AppCompatActivity { Logger.get(getActivity()) .logImpression(DialerImpression.Type.CALL_DETAILS_LIGHTBRINGER_CALL_BACK); Duo duo = DuoComponent.get(getActivity()).getDuo(); - if (!duo.isReachable(getActivity(), phoneNumber)) { + Optional<Intent> intentOptional = duo.getCallIntent(phoneNumber); + if (!duo.isReachable(getActivity(), phoneNumber) || !intentOptional.isPresent()) { placeImsVideoCall(phoneNumber); return; } try { getActivity() - .startActivityForResult( - duo.getIntent(getActivity(), phoneNumber), ActivityRequestCodes.DIALTACTS_DUO); + .startActivityForResult(intentOptional.get(), ActivityRequestCodes.DIALTACTS_DUO); } catch (ActivityNotFoundException e) { Toast.makeText(getActivity(), R.string.activity_not_available, Toast.LENGTH_SHORT).show(); } diff --git a/java/com/android/dialer/calldetails/CallDetailsCursorLoader.java b/java/com/android/dialer/calldetails/CallDetailsCursorLoader.java index c22ec7318..0e6eb76f5 100644 --- a/java/com/android/dialer/calldetails/CallDetailsCursorLoader.java +++ b/java/com/android/dialer/calldetails/CallDetailsCursorLoader.java @@ -23,7 +23,7 @@ import com.android.dialer.CoalescedIds; import com.android.dialer.calldetails.CallDetailsEntries.CallDetailsEntry; import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.AnnotatedCallLog; import com.android.dialer.common.Assert; -import com.android.dialer.duo.DuoConstants; +import com.android.dialer.duo.DuoComponent; /** * A {@link CursorLoader} that loads call detail entries from {@link AnnotatedCallLog} for {@link @@ -117,21 +117,21 @@ public final class CallDetailsCursorLoader extends CursorLoader { * the cursor is not null and the data set it points to is not empty. * @return A {@link CallDetailsEntries} proto. */ - static CallDetailsEntries toCallDetailsEntries(Cursor cursor) { + static CallDetailsEntries toCallDetailsEntries(Context context, Cursor cursor) { Assert.isNotNull(cursor); Assert.checkArgument(cursor.moveToFirst()); CallDetailsEntries.Builder entries = CallDetailsEntries.newBuilder(); do { - entries.addEntries(toCallDetailsEntry(cursor)); + entries.addEntries(toCallDetailsEntry(context, cursor)); } while (cursor.moveToNext()); return entries.build(); } /** Creates a new {@link CallDetailsEntry} from the provided cursor using its current position. */ - private static CallDetailsEntry toCallDetailsEntry(Cursor cursor) { + private static CallDetailsEntry toCallDetailsEntry(Context context, Cursor cursor) { CallDetailsEntry.Builder entry = CallDetailsEntry.newBuilder(); entry .setCallId(cursor.getLong(ID)) @@ -145,10 +145,7 @@ public final class CallDetailsCursorLoader extends CursorLoader { String phoneAccountComponentName = cursor.getString(PHONE_ACCOUNT_COMPONENT_NAME); - entry.setIsDuoCall( - DuoConstants.PHONE_ACCOUNT_COMPONENT_NAME - .flattenToString() - .equals(phoneAccountComponentName)); + entry.setIsDuoCall(DuoComponent.get(context).getDuo().isDuoAccount(phoneAccountComponentName)); return entry.build(); } diff --git a/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java b/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java index 661b2495b..588e64c5c 100644 --- a/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java +++ b/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java @@ -47,7 +47,7 @@ import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; import com.android.dialer.common.concurrent.Annotations.BackgroundExecutor; import com.android.dialer.compat.android.provider.VoicemailCompat; -import com.android.dialer.duo.DuoConstants; +import com.android.dialer.duo.Duo; import com.android.dialer.inject.ApplicationContext; import com.android.dialer.phonenumberproto.DialerPhoneNumberUtil; import com.android.dialer.storage.Unencrypted; @@ -78,6 +78,7 @@ public class SystemCallLogDataSource implements CallLogDataSource { private final MarkDirtyObserver markDirtyObserver; private final SharedPreferences sharedPreferences; private final AnnotatedCallLogDatabaseHelper annotatedCallLogDatabaseHelper; + private final Duo duo; @Nullable private Long lastTimestampProcessed; @@ -87,12 +88,14 @@ public class SystemCallLogDataSource implements CallLogDataSource { @BackgroundExecutor ListeningExecutorService backgroundExecutorService, MarkDirtyObserver markDirtyObserver, @Unencrypted SharedPreferences sharedPreferences, - AnnotatedCallLogDatabaseHelper annotatedCallLogDatabaseHelper) { + AnnotatedCallLogDatabaseHelper annotatedCallLogDatabaseHelper, + Duo duo) { this.appContext = appContext; this.backgroundExecutorService = backgroundExecutorService; this.markDirtyObserver = markDirtyObserver; this.sharedPreferences = sharedPreferences; this.annotatedCallLogDatabaseHelper = annotatedCallLogDatabaseHelper; + this.duo = duo; } @Override @@ -384,18 +387,15 @@ public class SystemCallLogDataSource implements CallLogDataSource { * <p>Characteristics of a Duo audio call are as follows. * * <ul> - * <li>The phone account component name is {@link DuoConstants#PHONE_ACCOUNT_COMPONENT_NAME}; - * and + * <li>The phone account is {@link Duo#isDuoAccount(String)}; and * <li>The features don't include {@link Calls#FEATURES_VIDEO}. * </ul> * * <p>It is the caller's responsibility to ensure the phone account component name and the * features come from the same call log entry. */ - private static boolean isDuoAudioCall(@Nullable String phoneAccountComponentName, int features) { - return DuoConstants.PHONE_ACCOUNT_COMPONENT_NAME - .flattenToString() - .equals(phoneAccountComponentName) + private boolean isDuoAudioCall(@Nullable String phoneAccountComponentName, int features) { + return duo.isDuoAccount(phoneAccountComponentName) && ((features & Calls.FEATURES_VIDEO) != Calls.FEATURES_VIDEO); } diff --git a/java/com/android/dialer/calllog/ui/menu/Modules.java b/java/com/android/dialer/calllog/ui/menu/Modules.java index 2f6c1fb36..a56d6d5e2 100644 --- a/java/com/android/dialer/calllog/ui/menu/Modules.java +++ b/java/com/android/dialer/calllog/ui/menu/Modules.java @@ -30,7 +30,6 @@ import com.android.dialer.calllogutils.CallLogEntryText; import com.android.dialer.calllogutils.NumberAttributesConverter; import com.android.dialer.duo.Duo; import com.android.dialer.duo.DuoComponent; -import com.android.dialer.duo.DuoConstants; import com.android.dialer.glidephotomanager.PhotoInfo; import com.android.dialer.historyitemactions.DividerModule; import com.android.dialer.historyitemactions.DuoCallModule; @@ -127,9 +126,7 @@ final class Modules { } boolean isDuoCall = - DuoConstants.PHONE_ACCOUNT_COMPONENT_NAME - .flattenToString() - .equals(row.getPhoneAccountComponentName()); + DuoComponent.get(context).getDuo().isDuoAccount(row.getPhoneAccountComponentName()); List<HistoryItemActionModule> modules = new ArrayList<>(); diff --git a/java/com/android/dialer/calllogutils/CallLogEntryText.java b/java/com/android/dialer/calllogutils/CallLogEntryText.java index a1a2a3b48..1b7bb06fa 100644 --- a/java/com/android/dialer/calllogutils/CallLogEntryText.java +++ b/java/com/android/dialer/calllogutils/CallLogEntryText.java @@ -20,7 +20,7 @@ import android.content.Context; import android.provider.CallLog.Calls; import android.text.TextUtils; import com.android.dialer.calllog.model.CoalescedRow; -import com.android.dialer.duo.DuoConstants; +import com.android.dialer.duo.DuoComponent; import com.android.dialer.time.Clock; import com.google.common.base.Optional; import com.google.common.collect.Collections2; @@ -202,9 +202,7 @@ public final class CallLogEntryText { } boolean isDuoCall = - DuoConstants.PHONE_ACCOUNT_COMPONENT_NAME - .flattenToString() - .equals(row.getPhoneAccountComponentName()); + DuoComponent.get(context).getDuo().isDuoAccount(row.getPhoneAccountComponentName()); secondaryText.append( context.getText( isDuoCall ? R.string.new_call_log_duo_video : R.string.new_call_log_carrier_video)); diff --git a/java/com/android/dialer/calllogutils/CallbackActionHelper.java b/java/com/android/dialer/calllogutils/CallbackActionHelper.java index 1e219f144..838bc4f11 100644 --- a/java/com/android/dialer/calllogutils/CallbackActionHelper.java +++ b/java/com/android/dialer/calllogutils/CallbackActionHelper.java @@ -16,10 +16,11 @@ package com.android.dialer.calllogutils; +import android.content.Context; import android.provider.CallLog.Calls; import android.support.annotation.IntDef; import android.text.TextUtils; -import com.android.dialer.duo.DuoConstants; +import com.android.dialer.duo.DuoComponent; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -46,8 +47,8 @@ public class CallbackActionHelper { * @return One of the values in {@link CallbackAction} */ public static @CallbackAction int getCallbackAction( - String number, int features, String phoneAccountComponentName) { - return getCallbackAction(number, features, isDuoCall(phoneAccountComponentName)); + Context context, String number, int features, String phoneAccountComponentName) { + return getCallbackAction(number, features, isDuoCall(context, phoneAccountComponentName)); } /** @@ -75,9 +76,7 @@ public class CallbackActionHelper { return CallbackAction.VOICE; } - private static boolean isDuoCall(String phoneAccountComponentName) { - return DuoConstants.PHONE_ACCOUNT_COMPONENT_NAME - .flattenToString() - .equals(phoneAccountComponentName); + private static boolean isDuoCall(Context context, String phoneAccountComponentName) { + return DuoComponent.get(context).getDuo().isDuoAccount(phoneAccountComponentName); } } diff --git a/java/com/android/dialer/constants/ActivityRequestCodes.java b/java/com/android/dialer/constants/ActivityRequestCodes.java index c96fe9ed1..994508019 100644 --- a/java/com/android/dialer/constants/ActivityRequestCodes.java +++ b/java/com/android/dialer/constants/ActivityRequestCodes.java @@ -30,9 +30,7 @@ public final class ActivityRequestCodes { /** Request code for {@link com.android.dialer.callcomposer.CallComposerActivity} intent. */ public static final int DIALTACTS_CALL_COMPOSER = 2; - /** - * Request code for {@link com.android.dialer.duo.Duo#getIntent(android.content.Context, String)}. - */ + /** Request code for {@link com.android.dialer.duo.Duo#getCallIntent(String)}. */ public static final int DIALTACTS_DUO = 3; /** Request code for {@link com.android.dialer.calldetails.OldCallDetailsActivity} intent. */ diff --git a/java/com/android/dialer/duo/Duo.java b/java/com/android/dialer/duo/Duo.java index e020c80e6..06a3db063 100644 --- a/java/com/android/dialer/duo/Duo.java +++ b/java/com/android/dialer/duo/Duo.java @@ -30,6 +30,7 @@ import com.google.common.base.Optional; import java.util.List; /** Interface for Duo video call integration. */ +@SuppressWarnings("Guava") public interface Duo { /** @return true if the Duo integration is enabled on this device. */ @@ -70,11 +71,44 @@ public interface Duo { void reloadReachability(@NonNull Context context); /** + * Get the {@link PhoneAccountHandle} used by duo calls in the connection service and call log. + */ + Optional<PhoneAccountHandle> getPhoneAccountHandle(); + + boolean isDuoAccount(PhoneAccountHandle phoneAccountHandle); + + boolean isDuoAccount(String componentName); + + /** * @return an Intent to start a Duo video call with the parameter number. Must be started using * startActivityForResult. */ @MainThread - Intent getIntent(@NonNull Context context, @NonNull String number); + Optional<Intent> getCallIntent(@NonNull String number); + + /** @return an Intent to setup duo. Must be started using startActivityForResult. */ + Optional<Intent> getActivateIntent(); + + /** + * @return an Intent to invite the parameter number to use duo. Must be started using + * startActivityForResult. + */ + Optional<Intent> getInviteIntent(String number); + + /** Return value of {@link #getIntentType(Intent)} */ + enum IntentType { + /** The intent is returned by {@link #getCallIntent(String)} */ + CALL, + /** The intent is returned by {@link #getActivateIntent()} */ + ACTIVATE, + /** The intent is returned by {@link #getInviteIntent(String)} */ + INVITE + } + + /** Classifies a Duo intent. Absent if the intent is not a Duo intent. */ + Optional<IntentType> getIntentType(Intent intent); + + Optional<Intent> getInstallDuoIntent(); /** Requests upgrading the parameter ongoing call to a Duo video call. */ @MainThread diff --git a/java/com/android/dialer/duo/DuoConstants.java b/java/com/android/dialer/duo/DuoConstants.java deleted file mode 100644 index 6eb660de0..000000000 --- a/java/com/android/dialer/duo/DuoConstants.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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.duo; - -import android.content.ComponentName; -import android.telecom.PhoneAccountHandle; - -/** Constants to reference the Duo application. */ -public final class DuoConstants { - public static final String PACKAGE_NAME = "com.google.android.apps.tachyon"; - - public static final String CONNECTION_SERVICE = - "com.google.android.apps.tachyon.telecom.TachyonTelecomConnectionService"; - - public static final String PHONE_ACCOUNT_ID = "0"; - - public static final ComponentName PHONE_ACCOUNT_COMPONENT_NAME = - new ComponentName(PACKAGE_NAME, CONNECTION_SERVICE); - - public static final PhoneAccountHandle PHONE_ACCOUNT_HANDLE = - new PhoneAccountHandle(PHONE_ACCOUNT_COMPONENT_NAME, PHONE_ACCOUNT_ID); - - public static final String DUO_ACTIVATE_ACTION = - "com.google.android.apps.tachyon.action.REGISTER"; - - public static final String DUO_INVITE_ACTION = "com.google.android.apps.tachyon.action.INVITE"; - - public static final String DUO_CALL_ACTION = "com.google.android.apps.tachyon.action.CALL"; - - private DuoConstants() {} -} diff --git a/java/com/android/dialer/duo/PlaceDuoCallReceiver.java b/java/com/android/dialer/duo/PlaceDuoCallReceiver.java index 913132c88..f504aef57 100644 --- a/java/com/android/dialer/duo/PlaceDuoCallReceiver.java +++ b/java/com/android/dialer/duo/PlaceDuoCallReceiver.java @@ -72,6 +72,6 @@ public final class PlaceDuoCallReceiver extends BroadcastReceiver { Duo duo = DuoComponent.get(context).getDuo(); activity.startActivityForResult( - duo.getIntent(context, phoneNumber), ActivityRequestCodes.DIALTACTS_DUO); + duo.getCallIntent(phoneNumber).orNull(), ActivityRequestCodes.DIALTACTS_DUO); } } diff --git a/java/com/android/dialer/duo/stub/DuoStub.java b/java/com/android/dialer/duo/stub/DuoStub.java index ef78f8b90..b0867148f 100644 --- a/java/com/android/dialer/duo/stub/DuoStub.java +++ b/java/com/android/dialer/duo/stub/DuoStub.java @@ -81,12 +81,46 @@ public class DuoStub implements Duo { @Override public void reloadReachability(@NonNull Context context) {} + @Override + public Optional<PhoneAccountHandle> getPhoneAccountHandle() { + return Optional.absent(); + } + + @Override + public boolean isDuoAccount(PhoneAccountHandle phoneAccountHandle) { + return false; + } + + @Override + public boolean isDuoAccount(String componentName) { + return false; + } + @MainThread @Override - public Intent getIntent(@NonNull Context context, @NonNull String number) { + public Optional<Intent> getCallIntent(@NonNull String number) { Assert.isMainThread(); - Assert.isNotNull(context); Assert.isNotNull(number); + return Optional.absent(); + } + + @Override + public Optional<Intent> getActivateIntent() { + return Optional.absent(); + } + + @Override + public Optional<Intent> getInviteIntent(String number) { + return Optional.absent(); + } + + @Override + public Optional<IntentType> getIntentType(Intent intent) { + return Optional.absent(); + } + + @Override + public Optional<Intent> getInstallDuoIntent() { return null; } diff --git a/java/com/android/dialer/searchfragment/list/NewSearchFragment.java b/java/com/android/dialer/searchfragment/list/NewSearchFragment.java index 51befe822..f1eed91ba 100644 --- a/java/com/android/dialer/searchfragment/list/NewSearchFragment.java +++ b/java/com/android/dialer/searchfragment/list/NewSearchFragment.java @@ -549,7 +549,7 @@ public final class NewSearchFragment extends Fragment 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); + Intent intent = DuoComponent.get(getContext()).getDuo().getCallIntent(phoneNumber).orNull(); getActivity().startActivityForResult(intent, ActivityRequestCodes.DIALTACTS_DUO); FragmentUtils.getParentUnsafe(this, SearchFragmentListener.class).onCallPlacedFromSearch(); } diff --git a/java/com/android/dialer/speeddial/DisambigDialog.java b/java/com/android/dialer/speeddial/DisambigDialog.java index 0d29a9c84..a76f648ab 100644 --- a/java/com/android/dialer/speeddial/DisambigDialog.java +++ b/java/com/android/dialer/speeddial/DisambigDialog.java @@ -159,7 +159,7 @@ public class DisambigDialog extends DialogFragment { .logImpression( DialerImpression.Type.LIGHTBRINGER_VIDEO_REQUESTED_FOR_FAVORITE_CONTACT_DISAMBIG); Intent intent = - DuoComponent.get(getContext()).getDuo().getIntent(getContext(), channel.number()); + DuoComponent.get(getContext()).getDuo().getCallIntent(channel.number()).orNull(); getActivity().startActivityForResult(intent, ActivityRequestCodes.DIALTACTS_DUO); return; } diff --git a/java/com/android/dialer/speeddial/SpeedDialFragment.java b/java/com/android/dialer/speeddial/SpeedDialFragment.java index 702472c6a..526db09e3 100644 --- a/java/com/android/dialer/speeddial/SpeedDialFragment.java +++ b/java/com/android/dialer/speeddial/SpeedDialFragment.java @@ -129,9 +129,7 @@ public class SpeedDialFragment extends Fragment { contextMenu, contextMenuBackground, new SpeedDialContextMenuItemListener( - getActivity(), - new UpdateSpeedDialAdapterListener(), - speedDialLoaderListener), + getActivity(), new UpdateSpeedDialAdapterListener(), speedDialLoaderListener), layoutManager); adapter = new SpeedDialAdapter(getContext(), favoritesListener, suggestedListener, headerListener); @@ -278,7 +276,8 @@ public class SpeedDialFragment extends Fragment { if (channel.technology() == Channel.DUO) { Logger.get(activity) .logImpression(DialerImpression.Type.LIGHTBRINGER_VIDEO_REQUESTED_FOR_FAVORITE_CONTACT); - Intent intent = DuoComponent.get(activity).getDuo().getIntent(activity, channel.number()); + Intent intent = + DuoComponent.get(activity).getDuo().getCallIntent(channel.number()).orNull(); activity.startActivityForResult(intent, ActivityRequestCodes.DIALTACTS_DUO); return; } @@ -377,7 +376,7 @@ public class SpeedDialFragment extends Fragment { .logImpression( DialerImpression.Type.LIGHTBRINGER_VIDEO_REQUESTED_FOR_SUGGESTED_CONTACT); Intent intent = - DuoComponent.get(getContext()).getDuo().getIntent(getContext(), channel.number()); + DuoComponent.get(getContext()).getDuo().getCallIntent(channel.number()).orNull(); getActivity().startActivityForResult(intent, ActivityRequestCodes.DIALTACTS_DUO); return; } @@ -461,7 +460,8 @@ public class SpeedDialFragment extends Fragment { if (channel.technology() == Channel.DUO) { Logger.get(activity) .logImpression(DialerImpression.Type.LIGHTBRINGER_VIDEO_REQUESTED_FOR_FAVORITE_CONTACT); - Intent intent = DuoComponent.get(activity).getDuo().getIntent(activity, channel.number()); + Intent intent = + DuoComponent.get(activity).getDuo().getCallIntent(channel.number()).orNull(); activity.startActivityForResult(intent, ActivityRequestCodes.DIALTACTS_DUO); return; } diff --git a/java/com/android/incallui/audioroute/AudioRouteSelectorDialogFragment.java b/java/com/android/incallui/audioroute/AudioRouteSelectorDialogFragment.java index 8d0c9525e..d6946d8de 100644 --- a/java/com/android/incallui/audioroute/AudioRouteSelectorDialogFragment.java +++ b/java/com/android/incallui/audioroute/AudioRouteSelectorDialogFragment.java @@ -149,6 +149,7 @@ public class AudioRouteSelectorDialogFragment extends BottomSheetDialogFragment if ((audioState.getSupportedRouteMask() & itemRoute) == 0) { item.setVisibility(View.GONE); } else if (audioState.getRoute() == itemRoute) { + item.setSelected(true); item.setTextColor(selectedColor); item.setCompoundDrawableTintList(ColorStateList.valueOf(selectedColor)); item.setCompoundDrawableTintMode(Mode.SRC_ATOP); @@ -169,6 +170,7 @@ public class AudioRouteSelectorDialogFragment extends BottomSheetDialogFragment (TextView) getLayoutInflater().inflate(R.layout.audioroute_item, null, false); textView.setText(getAliasName(bluetoothDevice)); if (selected) { + textView.setSelected(true); textView.setTextColor(selectedColor); textView.setCompoundDrawableTintList(ColorStateList.valueOf(selectedColor)); textView.setCompoundDrawableTintMode(Mode.SRC_ATOP); diff --git a/java/com/android/incallui/call/DialerCall.java b/java/com/android/incallui/call/DialerCall.java index 1c2744644..1a0de1960 100644 --- a/java/com/android/incallui/call/DialerCall.java +++ b/java/com/android/incallui/call/DialerCall.java @@ -27,6 +27,7 @@ import android.os.Build.VERSION; import android.os.Build.VERSION_CODES; import android.os.Bundle; import android.os.PersistableBundle; +import android.os.SystemClock; import android.os.Trace; import android.support.annotation.IntDef; import android.support.annotation.NonNull; @@ -79,6 +80,7 @@ import com.android.dialer.rtt.RttTranscriptUtil; import com.android.dialer.telecom.TelecomCallUtil; import com.android.dialer.telecom.TelecomUtil; import com.android.dialer.theme.R; +import com.android.dialer.time.Clock; import com.android.dialer.util.PermissionsUtil; import com.android.incallui.audiomode.AudioModeProvider; import com.android.incallui.call.state.DialerCallState; @@ -194,6 +196,8 @@ public class DialerCall implements VideoTechListener, StateChangedListener, Capa private volatile boolean feedbackRequested = false; + private Clock clock = System::currentTimeMillis; + @Nullable private PreferredAccountRecorder preferredAccountRecorder; private boolean isCallRemoved; @@ -415,18 +419,6 @@ public class DialerCall implements VideoTechListener, StateChangedListener, Capa updateEnrichedCallSession(); } - /** Test only constructor to avoid initializing dependencies. */ - @VisibleForTesting - DialerCall(Context context) { - this.context = context; - telecomCall = null; - latencyReport = null; - id = null; - hiddenId = 0; - dialerCallDelegate = null; - videoTechManager = null; - } - private static int translateState(int state) { switch (state) { case Call.STATE_NEW: @@ -863,21 +855,49 @@ public class DialerCall implements VideoTechListener, StateChangedListener, Capa public void setState(int state) { if (state == DialerCallState.INCOMING) { logState.isIncoming = true; - } else if (state == DialerCallState.DISCONNECTED) { + } + updateCallTiming(state); + + this.state = state; + } + + private void updateCallTiming(int newState) { + if (newState == DialerCallState.ACTIVE) { + if (this.state == DialerCallState.ACTIVE) { + LogUtil.i("DialerCall.updateCallTiming", "state is already active"); + return; + } + logState.dialerConnectTimeMillis = clock.currentTimeMillis(); + logState.dialerConnectTimeMillisElapsedRealtime = SystemClock.elapsedRealtime(); + } + + if (newState == DialerCallState.DISCONNECTED) { long newDuration = - getConnectTimeMillis() == 0 ? 0 : System.currentTimeMillis() - getConnectTimeMillis(); - if (this.state != state) { - logState.duration = newDuration; - } else { + getConnectTimeMillis() == 0 ? 0 : clock.currentTimeMillis() - getConnectTimeMillis(); + if (this.state == DialerCallState.DISCONNECTED) { LogUtil.i( "DialerCall.setState", "ignoring state transition from DISCONNECTED to DISCONNECTED." + " Duration would have changed from %s to %s", - logState.duration, + logState.telecomDurationMillis, newDuration); + return; } + logState.telecomDurationMillis = newDuration; + logState.dialerDurationMillis = + logState.dialerConnectTimeMillis == 0 + ? 0 + : clock.currentTimeMillis() - logState.dialerConnectTimeMillis; + logState.dialerDurationMillisElapsedRealtime = + logState.dialerConnectTimeMillisElapsedRealtime == 0 + ? 0 + : SystemClock.elapsedRealtime() - logState.dialerConnectTimeMillisElapsedRealtime; } - this.state = state; + } + + @VisibleForTesting + void setClock(Clock clock) { + this.clock = clock; } public int getNumberPresentation() { @@ -1735,9 +1755,25 @@ public class DialerCall implements VideoTechListener, StateChangedListener, Capa public CallSpecificAppData callSpecificAppData; // If this was a conference call, the total number of calls involved in the conference. public int conferencedCalls = 0; - public long duration = 0; public boolean isLogged = false; + // Result of subtracting android.telecom.Call.Details#getConnectTimeMillis from the current time + public long telecomDurationMillis = 0; + + // Result of a call to System.currentTimeMillis when Dialer sees that a call + // moves to the ACTIVE state + long dialerConnectTimeMillis = 0; + + // Same as dialer_connect_time_millis, using SystemClock.elapsedRealtime + // instead + long dialerConnectTimeMillisElapsedRealtime = 0; + + // Result of subtracting dialer_connect_time_millis from System.currentTimeMillis + public long dialerDurationMillis = 0; + + // Same as dialerDurationMillis, using SystemClock.elapsedRealtime instead + public long dialerDurationMillisElapsedRealtime = 0; + private static String lookupToString(ContactLookupResult.Type lookupType) { switch (lookupType) { case LOCAL_CONTACT: @@ -1806,7 +1842,7 @@ public class DialerCall implements VideoTechListener, StateChangedListener, Capa isIncoming, lookupToString(contactLookupResult), initiationToString(callSpecificAppData), - duration); + telecomDurationMillis); } } diff --git a/java/com/android/incallui/spam/SpamCallListListener.java b/java/com/android/incallui/spam/SpamCallListListener.java index e852f3d2c..350dd60fc 100644 --- a/java/com/android/incallui/spam/SpamCallListListener.java +++ b/java/com/android/incallui/spam/SpamCallListListener.java @@ -219,7 +219,7 @@ public class SpamCallListListener implements CallList.Listener { return false; } - if (logState.duration <= 0) { + if (logState.telecomDurationMillis <= 0) { return false; } |