From d7c058c4e1bfd772e514f6d09deb21d7893d28c8 Mon Sep 17 00:00:00 2001 From: Android Dialer Date: Mon, 7 May 2018 14:03:11 -0700 Subject: Creating CallIntent, AutoValue builder, to replace CallIntentBuilder. Bug: 78243194 Test: CallIntentTest PiperOrigin-RevId: 195718047 Change-Id: I09134e13c9c5a811dba313cb4415a36aba7d7262 --- java/com/android/dialer/callintent/CallIntent.java | 314 +++++++++++++++++++++ 1 file changed, 314 insertions(+) create mode 100644 java/com/android/dialer/callintent/CallIntent.java (limited to 'java/com/android/dialer/callintent') diff --git a/java/com/android/dialer/callintent/CallIntent.java b/java/com/android/dialer/callintent/CallIntent.java new file mode 100644 index 000000000..ba61d5619 --- /dev/null +++ b/java/com/android/dialer/callintent/CallIntent.java @@ -0,0 +1,314 @@ +/* + * 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 + */ + +package com.android.dialer.callintent; + +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.os.Parcel; +import android.os.Parcelable; +import android.os.SystemClock; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.annotation.VisibleForTesting; +import android.telecom.PhoneAccount; +import android.telecom.PhoneAccountHandle; +import android.telecom.TelecomManager; +import android.telecom.VideoProfile; +import android.text.TextUtils; +import com.android.dialer.common.Assert; +import com.android.dialer.performancereport.PerformanceReport; +import com.android.dialer.util.CallUtil; +import com.google.auto.value.AutoValue; +import com.google.common.collect.ImmutableMap; +import com.google.protobuf.InvalidProtocolBufferException; + +/** Creates an intent to start a new outgoing call. */ +@AutoValue +public abstract class CallIntent implements Parcelable { + private static int lightbringerButtonAppearInExpandedCallLogItemCount = 0; + private static int lightbringerButtonAppearInCollapsedCallLogItemCount = 0; + private static int lightbringerButtonAppearInSearchCount = 0; + + abstract Uri number(); + + abstract CallSpecificAppData callSpecificAppData(); + + @Nullable + abstract PhoneAccountHandle phoneAccountHandle(); + + abstract boolean isVideoCall(); + + @Nullable + abstract String callSubject(); + + abstract boolean allowAssistedDial(); + + abstract ImmutableMap stringInCallUiIntentExtras(); + + abstract ImmutableMap longInCallUiIntentExtras(); + + abstract ImmutableMap stringPlaceCallExtras(); + + abstract ImmutableMap longPlaceCallExtras(); + + public static Builder builder() { + return new AutoValue_CallIntent.Builder().setIsVideoCall(false).setAllowAssistedDial(false); + } + + public abstract Builder toBuilder(); + + /** Builder class for CallIntent info. */ + @AutoValue.Builder + public abstract static class Builder { + public Builder setTelNumber(String number) { + return setNumber(CallUtil.getCallUri(Assert.isNotNull(number))); + } + + public Builder setVoicemailNumber(@Nullable PhoneAccountHandle phoneAccountHandle) { + return setNumber(Uri.fromParts(PhoneAccount.SCHEME_VOICEMAIL, "", null)) + .setPhoneAccountHandle(phoneAccountHandle); + } + + public abstract Builder setNumber(@NonNull Uri number); + + public Builder setCallInitiationType(CallInitiationType.Type callInitiationType) { + return setCallSpecificAppData( + CallSpecificAppData.newBuilder().setCallInitiationType(callInitiationType).build()); + } + + abstract CallSpecificAppData callSpecificAppData(); + + public abstract Builder setCallSpecificAppData( + @NonNull CallSpecificAppData callSpecificAppData); + + public abstract Builder setPhoneAccountHandle(PhoneAccountHandle phoneAccountHandle); + + public abstract Builder setIsVideoCall(boolean isVideoCall); + + public abstract Builder setCallSubject(String callSubject); + + public abstract Builder setAllowAssistedDial(boolean allowAssistedDial); + + abstract ImmutableMap.Builder stringInCallUiIntentExtrasBuilder(); + + abstract ImmutableMap.Builder longInCallUiIntentExtrasBuilder(); + + public Builder addInCallUiIntentExtra(String key, String value) { + stringInCallUiIntentExtrasBuilder().put(key, value); + return this; + } + + public Builder addInCallUiIntentExtra(String key, Long value) { + longInCallUiIntentExtrasBuilder().put(key, value); + return this; + } + + abstract ImmutableMap.Builder stringPlaceCallExtrasBuilder(); + + abstract ImmutableMap.Builder longPlaceCallExtrasBuilder(); + + public Builder addPlaceCallExtra(String key, String value) { + stringPlaceCallExtrasBuilder().put(key, value); + return this; + } + + public Builder addPlaceCallExtra(String key, Long value) { + longPlaceCallExtrasBuilder().put(key, value); + return this; + } + + abstract CallIntent autoBuild(); + + public Intent build() { + CallSpecificAppData.Builder builder = + CallSpecificAppData.newBuilder(callSpecificAppData()) + .setLightbringerButtonAppearInExpandedCallLogItemCount( + lightbringerButtonAppearInExpandedCallLogItemCount) + .setLightbringerButtonAppearInCollapsedCallLogItemCount( + lightbringerButtonAppearInCollapsedCallLogItemCount) + .setLightbringerButtonAppearInSearchCount(lightbringerButtonAppearInSearchCount); + lightbringerButtonAppearInExpandedCallLogItemCount = 0; + lightbringerButtonAppearInCollapsedCallLogItemCount = 0; + lightbringerButtonAppearInSearchCount = 0; + + if (PerformanceReport.isRecording()) { + builder + .setTimeSinceAppLaunch(PerformanceReport.getTimeSinceAppLaunch()) + .setTimeSinceFirstClick(PerformanceReport.getTimeSinceFirstClick()) + .addAllUiActionsSinceAppLaunch(PerformanceReport.getActions()) + .addAllUiActionTimestampsSinceAppLaunch(PerformanceReport.getActionTimestamps()) + .setStartingTabIndex(PerformanceReport.getStartingTabIndex()) + .build(); + PerformanceReport.stopRecording(); + } + + setCallSpecificAppData(builder.build()); + + // Validate CallIntent. + CallIntent callIntent = autoBuild(); + Assert.isNotNull(callIntent.number()); + Assert.isNotNull(callIntent.callSpecificAppData()); + Assert.checkArgument( + callIntent.callSpecificAppData().getCallInitiationType() + != CallInitiationType.Type.UNKNOWN_INITIATION); + + return autoBuild().newIntent(); + } + } + + // Creates the intent which can start a call + private Intent newIntent() { + Intent intent = new Intent(Intent.ACTION_CALL, number()); + + intent.putExtra( + TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, + isVideoCall() ? VideoProfile.STATE_BIDIRECTIONAL : VideoProfile.STATE_AUDIO_ONLY); + + Bundle inCallUiIntentExtras = createInCallUiIntentExtras(); + inCallUiIntentExtras.putLong( + Constants.EXTRA_CALL_CREATED_TIME_MILLIS, SystemClock.elapsedRealtime()); + + intent.putExtra(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, inCallUiIntentExtras); + + if (phoneAccountHandle() != null) { + intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle()); + } + + if (!TextUtils.isEmpty(callSubject())) { + intent.putExtra(TelecomManager.EXTRA_CALL_SUBJECT, callSubject()); + } + + intent.putExtras(createPlaceCallExtras()); + + return intent; + } + + @SuppressWarnings("AndroidApiChecker") // Use of Java 8 APIs. + private Bundle createInCallUiIntentExtras() { + Bundle bundle = new Bundle(); + stringInCallUiIntentExtras().forEach(bundle::putString); + longInCallUiIntentExtras().forEach(bundle::putLong); + CallIntentParser.putCallSpecificAppData(bundle, callSpecificAppData()); + return bundle; + } + + @SuppressWarnings("AndroidApiChecker") // Use of Java 8 APIs. + private Bundle createPlaceCallExtras() { + Bundle bundle = new Bundle(); + stringPlaceCallExtras().forEach(bundle::putString); + longPlaceCallExtras().forEach(bundle::putLong); + CallIntentParser.putCallSpecificAppData(bundle, callSpecificAppData()); + return bundle; + } + + public static void increaseLightbringerCallButtonAppearInExpandedCallLogItemCount() { + CallIntent.lightbringerButtonAppearInExpandedCallLogItemCount++; + } + + public static void increaseLightbringerCallButtonAppearInCollapsedCallLogItemCount() { + CallIntent.lightbringerButtonAppearInCollapsedCallLogItemCount++; + } + + public static void increaseLightbringerCallButtonAppearInSearchCount() { + CallIntent.lightbringerButtonAppearInSearchCount++; + } + + @VisibleForTesting + public static int getLightbringerButtonAppearInExpandedCallLogItemCount() { + return lightbringerButtonAppearInExpandedCallLogItemCount; + } + + @VisibleForTesting + public static int getLightbringerButtonAppearInCollapsedCallLogItemCount() { + return lightbringerButtonAppearInCollapsedCallLogItemCount; + } + + @VisibleForTesting + public static int getLightbringerButtonAppearInSearchCount() { + return lightbringerButtonAppearInSearchCount; + } + + @VisibleForTesting(otherwise = VisibleForTesting.NONE) + public static void clearLightbringerCounts() { + lightbringerButtonAppearInCollapsedCallLogItemCount = 0; + lightbringerButtonAppearInExpandedCallLogItemCount = 0; + lightbringerButtonAppearInSearchCount = 0; + } + + @Override + public int describeContents() { + return 0; + } + + @SuppressWarnings("AndroidApiChecker") // Use of Java 8 APIs. + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeParcelable(number(), flags); + dest.writeByteArray(callSpecificAppData().toByteArray()); + dest.writeParcelable(phoneAccountHandle(), flags); + dest.writeInt(isVideoCall() ? 1 : 0); + dest.writeString(callSubject()); + dest.writeInt(allowAssistedDial() ? 1 : 0); + Bundle stringInCallUiIntentExtrasBundle = new Bundle(); + stringInCallUiIntentExtras().forEach(stringInCallUiIntentExtrasBundle::putString); + dest.writeBundle(stringInCallUiIntentExtrasBundle); + Bundle longInCallUiIntentExtrasBundle = new Bundle(); + longInCallUiIntentExtras().forEach(longInCallUiIntentExtrasBundle::putLong); + dest.writeBundle(longInCallUiIntentExtrasBundle); + } + + // @TODO(justinmcclain): Investigate deleting the parcelable logic and instead switching + // to using an internal proto for serialization. + public static final Creator CREATOR = + new Creator() { + @Override + public CallIntent createFromParcel(Parcel source) { + CallIntent.Builder callIntentBuilder = builder(); + ClassLoader classLoader = CallIntent.class.getClassLoader(); + callIntentBuilder.setNumber(source.readParcelable(classLoader)); + CallSpecificAppData data; + try { + data = CallSpecificAppData.parseFrom(source.createByteArray()); + } catch (InvalidProtocolBufferException e) { + data = CallSpecificAppData.getDefaultInstance(); + } + callIntentBuilder + .setCallSpecificAppData(data) + .setPhoneAccountHandle(source.readParcelable(classLoader)) + .setIsVideoCall(source.readInt() != 0) + .setCallSubject(source.readString()) + .setAllowAssistedDial(source.readInt() != 0); + Bundle stringInCallUiIntentExtrasBundle = source.readBundle(classLoader); + for (String key : stringInCallUiIntentExtrasBundle.keySet()) { + callIntentBuilder.addInCallUiIntentExtra( + key, stringInCallUiIntentExtrasBundle.getString(key)); + } + Bundle longInCallUiIntentExtrasBundle = source.readBundle(classLoader); + for (String key : longInCallUiIntentExtrasBundle.keySet()) { + callIntentBuilder.addInCallUiIntentExtra( + key, longInCallUiIntentExtrasBundle.getLong(key)); + } + return callIntentBuilder.autoBuild(); + } + + @Override + public CallIntent[] newArray(int size) { + return new CallIntent[0]; + } + }; +} -- cgit v1.2.3 From b2b6365629aed422a006529fe7940612f778baed Mon Sep 17 00:00:00 2001 From: twyen Date: Mon, 7 May 2018 16:36:17 -0700 Subject: Place Duo calls with PreCall This CL consolidates common duo calling operations into precall, including checking reachability, falling back to carrier video call, placing the call to duo with startActivityForResult. TEST=TAP Bug: 78783816 Test: TAP PiperOrigin-RevId: 195742478 Change-Id: I9fea1e4999f604e1f3a153b28079cd0db77b7393 --- java/com/android/dialer/callintent/CallIntentBuilder.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'java/com/android/dialer/callintent') diff --git a/java/com/android/dialer/callintent/CallIntentBuilder.java b/java/com/android/dialer/callintent/CallIntentBuilder.java index 92efd392b..613fdf6a3 100644 --- a/java/com/android/dialer/callintent/CallIntentBuilder.java +++ b/java/com/android/dialer/callintent/CallIntentBuilder.java @@ -43,6 +43,7 @@ public class CallIntentBuilder implements Parcelable { private final CallSpecificAppData callSpecificAppData; @Nullable private PhoneAccountHandle phoneAccountHandle; private boolean isVideoCall; + private boolean isDuoCall; private String callSubject; private boolean allowAssistedDial; @@ -109,6 +110,7 @@ public class CallIntentBuilder implements Parcelable { callSpecificAppData = data; phoneAccountHandle = parcel.readParcelable(classLoader); isVideoCall = parcel.readInt() != 0; + isDuoCall = parcel.readInt() != 0; callSubject = parcel.readString(); allowAssistedDial = parcel.readInt() != 0; inCallUiIntentExtras.putAll(parcel.readBundle(classLoader)); @@ -152,6 +154,15 @@ public class CallIntentBuilder implements Parcelable { return isVideoCall; } + public CallIntentBuilder setIsDuoCall(boolean isDuoCall) { + this.isDuoCall = isDuoCall; + return this; + } + + public boolean isDuoCall() { + return isDuoCall; + } + /** Default false. Should only be set to true if the number has a lookup URI. */ public CallIntentBuilder setAllowAssistedDial(boolean allowAssistedDial) { this.allowAssistedDial = allowAssistedDial; @@ -267,6 +278,7 @@ public class CallIntentBuilder implements Parcelable { dest.writeByteArray(callSpecificAppData.toByteArray()); dest.writeParcelable(phoneAccountHandle, flags); dest.writeInt(isVideoCall ? 1 : 0); + dest.writeInt(isDuoCall ? 1 : 0); dest.writeString(callSubject); dest.writeInt(allowAssistedDial ? 1 : 0); dest.writeBundle(inCallUiIntentExtras); -- cgit v1.2.3