diff options
Diffstat (limited to 'java')
32 files changed, 261 insertions, 256 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 a7e17717f..9d55b9fda 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 @@ -119,21 +119,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 { .setCallMappingId(cursor.getString(CALL_MAPPING_ID)); 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 fb18e8927..b5067daac 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 @@ -387,18 +390,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/glidephotomanager/impl/GlidePhotoManagerImpl.java b/java/com/android/dialer/glidephotomanager/impl/GlidePhotoManagerImpl.java index 562177c48..515a3ccbb 100644 --- a/java/com/android/dialer/glidephotomanager/impl/GlidePhotoManagerImpl.java +++ b/java/com/android/dialer/glidephotomanager/impl/GlidePhotoManagerImpl.java @@ -62,6 +62,10 @@ public class GlidePhotoManagerImpl implements GlidePhotoManager { @Override public void loadContactPhoto(ImageView imageView, PhotoInfo photoInfo) { Assert.isMainThread(); + imageView.setContentDescription( + appContext.getString( + com.android.dialer.contactphoto.R.string.description_quick_contact_for, + photoInfo.getName())); GlideRequest<Drawable> request = buildRequest(GlideApp.with(imageView), photoInfo); request.into(imageView); } 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/spam/promo/SpamBlockingPromoHelper.java b/java/com/android/dialer/spam/promo/SpamBlockingPromoHelper.java index 6a8cde864..a117e1908 100644 --- a/java/com/android/dialer/spam/promo/SpamBlockingPromoHelper.java +++ b/java/com/android/dialer/spam/promo/SpamBlockingPromoHelper.java @@ -168,7 +168,9 @@ public class SpamBlockingPromoHelper { .setPriority(Notification.PRIORITY_DEFAULT) .setColor(context.getColor(R.color.dialer_theme_color)) .setSmallIcon(R.drawable.quantum_ic_call_vd_theme_24) - .setContentText(context.getString(R.string.spam_blocking_promo_text)) + .setStyle( + new Notification.BigTextStyle() + .bigText(context.getString(R.string.spam_blocking_promo_text))) .addAction( new Notification.Action.Builder( R.drawable.quantum_ic_block_vd_theme_24, 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/FavoritesViewHolder.java b/java/com/android/dialer/speeddial/FavoritesViewHolder.java index 474516ef2..f06672d8d 100644 --- a/java/com/android/dialer/speeddial/FavoritesViewHolder.java +++ b/java/com/android/dialer/speeddial/FavoritesViewHolder.java @@ -68,10 +68,15 @@ public class FavoritesViewHolder extends RecyclerView.ViewHolder Assert.checkArgument(speedDialUiItem.isStarred()); nameView.setText(speedDialUiItem.name()); - if (speedDialUiItem.defaultChannel() != null) { - phoneType.setText(speedDialUiItem.defaultChannel().label()); - videoCallIcon.setVisibility( - speedDialUiItem.defaultChannel().isVideoTechnology() ? View.VISIBLE : View.GONE); + + Channel channel = speedDialUiItem.defaultChannel(); + if (channel == null) { + channel = speedDialUiItem.getDefaultVoiceChannel(); + } + + if (channel != null) { + phoneType.setText(channel.label()); + videoCallIcon.setVisibility(channel.isVideoTechnology() ? View.VISIBLE : View.GONE); } else { phoneType.setText(""); videoCallIcon.setVisibility(View.GONE); diff --git a/java/com/android/dialer/speeddial/SpeedDialFragment.java b/java/com/android/dialer/speeddial/SpeedDialFragment.java index f0ba186cd..db4c0245e 100644 --- a/java/com/android/dialer/speeddial/SpeedDialFragment.java +++ b/java/com/android/dialer/speeddial/SpeedDialFragment.java @@ -114,9 +114,7 @@ public class SpeedDialFragment extends Fragment { getActivity(), getChildFragmentManager(), new SpeedDialContextMenuItemListener( - getActivity(), - new UpdateSpeedDialAdapterListener(), - speedDialLoaderListener), + getActivity(), new UpdateSpeedDialAdapterListener(), speedDialLoaderListener), layoutManager); adapter = new SpeedDialAdapter(getContext(), favoritesListener, suggestedListener, headerListener); @@ -246,7 +244,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; } @@ -346,7 +345,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; } @@ -430,7 +429,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/dialer/speeddial/loader/SpeedDialUiItem.java b/java/com/android/dialer/speeddial/loader/SpeedDialUiItem.java index f730d12a0..365b88f8c 100644 --- a/java/com/android/dialer/speeddial/loader/SpeedDialUiItem.java +++ b/java/com/android/dialer/speeddial/loader/SpeedDialUiItem.java @@ -16,6 +16,7 @@ package com.android.dialer.speeddial.loader; +import android.content.res.Resources; import android.database.Cursor; import android.provider.ContactsContract.CommonDataKinds.Phone; import android.provider.ContactsContract.Contacts; @@ -102,7 +103,7 @@ public abstract class SpeedDialUiItem { * <p>If the cursor started at row X, this method will advance to row Y s.t. rows X, X + 1, ... Y * - 1 all belong to the same contact (that is, share the same contact id and lookup key). */ - public static SpeedDialUiItem fromCursor(Cursor cursor) { + public static SpeedDialUiItem fromCursor(Resources resources, Cursor cursor) { Assert.checkArgument(cursor != null); Assert.checkArgument(cursor.getCount() != 0); String lookupKey = cursor.getString(LOOKUP_KEY); @@ -125,7 +126,7 @@ public abstract class SpeedDialUiItem { Channel.builder() .setNumber(cursor.getString(NUMBER)) .setPhoneType(cursor.getInt(TYPE)) - .setLabel(TextUtils.isEmpty(cursor.getString(LABEL)) ? "" : cursor.getString(LABEL)) + .setLabel(getLabel(resources, cursor)) .setTechnology(Channel.VOICE) .build(); channels.add(channel); @@ -141,6 +142,17 @@ public abstract class SpeedDialUiItem { return builder.build(); } + private static String getLabel(Resources resources, Cursor cursor) { + int numberType = cursor.getInt(TYPE); + String numberLabel = cursor.getString(LABEL); + + // Returns empty label instead of "custom" if the custom label is empty. + if (numberType == Phone.TYPE_CUSTOM && TextUtils.isEmpty(numberLabel)) { + return ""; + } + return (String) Phone.getTypeLabel(resources, numberType, numberLabel); + } + public PhotoInfo getPhotoInfo() { return PhotoInfo.newBuilder() .setPhotoId(photoId()) diff --git a/java/com/android/dialer/speeddial/loader/SpeedDialUiItemMutator.java b/java/com/android/dialer/speeddial/loader/SpeedDialUiItemMutator.java index 0a2a241b3..1ad37dc2a 100644 --- a/java/com/android/dialer/speeddial/loader/SpeedDialUiItemMutator.java +++ b/java/com/android/dialer/speeddial/loader/SpeedDialUiItemMutator.java @@ -205,7 +205,7 @@ public final class SpeedDialUiItemMutator { return loadSpeedDialUiItemsInternal(); } Assert.checkArgument(cursor.moveToFirst(), "Cursor should never be empty"); - SpeedDialUiItem item = SpeedDialUiItem.fromCursor(cursor); + SpeedDialUiItem item = SpeedDialUiItem.fromCursor(appContext.getResources(), cursor); // Star the contact if it isn't starred already, then return. if (!item.isStarred()) { @@ -410,7 +410,7 @@ public final class SpeedDialUiItemMutator { null)) { Map<SpeedDialEntry, SpeedDialUiItem> map = new ArrayMap<>(); for (cursor.moveToFirst(); !cursor.isAfterLast(); /* Iterate in the loop */ ) { - SpeedDialUiItem item = SpeedDialUiItem.fromCursor(cursor); + SpeedDialUiItem item = SpeedDialUiItem.fromCursor(appContext.getResources(), cursor); for (SpeedDialEntry entry : entries) { if (entry.contactId() == item.contactId()) { // Update the id and pinned position to match it's corresponding SpeedDialEntry. @@ -513,7 +513,7 @@ public final class SpeedDialUiItemMutator { return contacts; } for (cursor.moveToFirst(); !cursor.isAfterLast(); /* Iterate in the loop */ ) { - contacts.add(SpeedDialUiItem.fromCursor(cursor)); + contacts.add(SpeedDialUiItem.fromCursor(appContext.getResources(), cursor)); } return contacts; } diff --git a/java/com/android/incallui/AndroidManifest.xml b/java/com/android/incallui/AndroidManifest.xml index f20b21d38..7091d6038 100644 --- a/java/com/android/incallui/AndroidManifest.xml +++ b/java/com/android/incallui/AndroidManifest.xml @@ -43,6 +43,9 @@ <!-- Set Bluetooth device --> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> + <!-- Set audio selector window type TYPE_APPLICATION_OVERLAY --> + <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> + <!-- Set android:taskAffinity="com.android.incallui" for all activities to ensure proper navigation. Otherwise system could bring up DialtactsActivity instead, e.g. when user unmerge a call. diff --git a/java/com/android/incallui/audioroute/AudioRouteSelectorDialogFragment.java b/java/com/android/incallui/audioroute/AudioRouteSelectorDialogFragment.java index cd17c25da..d6946d8de 100644 --- a/java/com/android/incallui/audioroute/AudioRouteSelectorDialogFragment.java +++ b/java/com/android/incallui/audioroute/AudioRouteSelectorDialogFragment.java @@ -24,8 +24,10 @@ import android.content.DialogInterface; import android.content.res.ColorStateList; import android.graphics.PorterDuff.Mode; import android.os.Bundle; +import android.provider.Settings; import android.support.annotation.Nullable; import android.support.design.widget.BottomSheetDialogFragment; +import android.support.v4.os.BuildCompat; import android.telecom.CallAudioState; import android.view.LayoutInflater; import android.view.View; @@ -76,6 +78,14 @@ public class AudioRouteSelectorDialogFragment extends BottomSheetDialogFragment LogUtil.i("AudioRouteSelectorDialogFragment.onCreateDialog", null); Dialog dialog = super.onCreateDialog(savedInstanceState); dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); + if (Settings.canDrawOverlays(getContext())) { + dialog + .getWindow() + .setType( + BuildCompat.isAtLeastO() + ? WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY + : WindowManager.LayoutParams.TYPE_PHONE); + } return dialog; } @@ -139,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); @@ -159,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; } diff --git a/java/com/android/incallui/speakeasy/AndroidManifest.xml b/java/com/android/incallui/speakeasy/AndroidManifest.xml deleted file mode 100644 index e56b2e744..000000000 --- a/java/com/android/incallui/speakeasy/AndroidManifest.xml +++ /dev/null @@ -1,26 +0,0 @@ -<!-- - ~ Copyright (C) 2018 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 - --> -<manifest - package="com.android.incallui.speakeasy" - xmlns:android="http://schemas.android.com/apk/res/android"> - <application android:theme="@style/Theme.AppCompat"> - <activity - android:name=".SpeakEasyActivity" - android:exported="false" - android:theme="@style/DialerThemeBase.NoActionBar" - android:windowSoftInputMode="adjustResize"/> - </application> -</manifest> diff --git a/java/com/android/incallui/speakeasy/res/layout/activity_speakeasy.xml b/java/com/android/incallui/speakeasy/res/layout/activity_speakeasy.xml deleted file mode 100644 index 5271d629e..000000000 --- a/java/com/android/incallui/speakeasy/res/layout/activity_speakeasy.xml +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - ~ Copyright (C) 2016 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 - --> - -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:orientation="vertical" - android:layout_width="match_parent" - android:layout_height="match_parent"> - <FrameLayout - android:id="@+id/fragment_speakeasy" - android:layout_width="match_parent" - android:layout_height="match_parent"/> - -</LinearLayout> diff --git a/java/com/android/incallui/speakeasy/res/values/colors.xml b/java/com/android/incallui/speakeasy/res/values/colors.xml deleted file mode 100644 index fc4790e70..000000000 --- a/java/com/android/incallui/speakeasy/res/values/colors.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - ~ 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 - --> - -<resources> - <color name="speakeasy_status_bar_color">#E0E0E0</color> -</resources> |