• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License
15  */
16 
17 package com.android.dialer.callintent;
18 
19 import android.content.Intent;
20 import android.net.Uri;
21 import android.os.Bundle;
22 import android.os.Parcel;
23 import android.os.Parcelable;
24 import android.os.SystemClock;
25 import android.support.annotation.NonNull;
26 import android.support.annotation.Nullable;
27 import android.support.annotation.VisibleForTesting;
28 import android.telecom.PhoneAccount;
29 import android.telecom.PhoneAccountHandle;
30 import android.telecom.TelecomManager;
31 import android.telecom.VideoProfile;
32 import android.text.TextUtils;
33 import com.android.dialer.callintent.CallInitiationType.Type;
34 import com.android.dialer.common.Assert;
35 import com.android.dialer.performancereport.PerformanceReport;
36 import com.android.dialer.util.CallUtil;
37 import com.google.protobuf.InvalidProtocolBufferException;
38 
39 /** Creates an intent to start a new outgoing call. */
40 public class CallIntentBuilder implements Parcelable {
41   private Uri uri;
42   private final CallSpecificAppData callSpecificAppData;
43   @Nullable private PhoneAccountHandle phoneAccountHandle;
44   private boolean isVideoCall;
45   private String callSubject;
46   private boolean allowAssistedDial;
47 
48   private final Bundle outgoingCallExtras = new Bundle();
49 
50   private static int lightbringerButtonAppearInExpandedCallLogItemCount = 0;
51   private static int lightbringerButtonAppearInCollapsedCallLogItemCount = 0;
52   private static int lightbringerButtonAppearInSearchCount = 0;
53 
CallIntentBuilder(@onNull Uri uri, @NonNull CallSpecificAppData callSpecificAppData)54   public CallIntentBuilder(@NonNull Uri uri, @NonNull CallSpecificAppData callSpecificAppData) {
55     this.uri = Assert.isNotNull(uri);
56     Assert.isNotNull(callSpecificAppData);
57     Assert.checkArgument(
58         callSpecificAppData.getCallInitiationType() != CallInitiationType.Type.UNKNOWN_INITIATION);
59 
60     CallSpecificAppData.Builder builder =
61         CallSpecificAppData.newBuilder(callSpecificAppData)
62             .setLightbringerButtonAppearInExpandedCallLogItemCount(
63                 lightbringerButtonAppearInExpandedCallLogItemCount)
64             .setLightbringerButtonAppearInCollapsedCallLogItemCount(
65                 lightbringerButtonAppearInCollapsedCallLogItemCount)
66             .setLightbringerButtonAppearInSearchCount(lightbringerButtonAppearInSearchCount);
67     lightbringerButtonAppearInExpandedCallLogItemCount = 0;
68     lightbringerButtonAppearInCollapsedCallLogItemCount = 0;
69     lightbringerButtonAppearInSearchCount = 0;
70 
71     if (PerformanceReport.isRecording()) {
72       builder
73           .setTimeSinceAppLaunch(PerformanceReport.getTimeSinceAppLaunch())
74           .setTimeSinceFirstClick(PerformanceReport.getTimeSinceFirstClick())
75           .addAllUiActionsSinceAppLaunch(PerformanceReport.getActions())
76           .addAllUiActionTimestampsSinceAppLaunch(PerformanceReport.getActionTimestamps())
77           .setStartingTabIndex(PerformanceReport.getStartingTabIndex())
78           .build();
79       PerformanceReport.stopRecording();
80     }
81 
82     this.callSpecificAppData = builder.build();
83   }
84 
CallIntentBuilder(@onNull Uri uri, CallInitiationType.Type callInitiationType)85   public CallIntentBuilder(@NonNull Uri uri, CallInitiationType.Type callInitiationType) {
86     this(uri, createCallSpecificAppData(callInitiationType));
87   }
88 
CallIntentBuilder( @onNull String number, @NonNull CallSpecificAppData callSpecificAppData)89   public CallIntentBuilder(
90       @NonNull String number, @NonNull CallSpecificAppData callSpecificAppData) {
91     this(CallUtil.getCallUri(Assert.isNotNull(number)), callSpecificAppData);
92   }
93 
CallIntentBuilder(@onNull String number, CallInitiationType.Type callInitiationType)94   public CallIntentBuilder(@NonNull String number, CallInitiationType.Type callInitiationType) {
95     this(CallUtil.getCallUri(Assert.isNotNull(number)), callInitiationType);
96   }
97 
CallIntentBuilder(@onNull Parcel parcel)98   public CallIntentBuilder(@NonNull Parcel parcel) {
99     ClassLoader classLoader = CallIntentBuilder.class.getClassLoader();
100     uri = parcel.readParcelable(classLoader);
101     CallSpecificAppData data;
102     try {
103       data = CallSpecificAppData.parseFrom(parcel.createByteArray());
104     } catch (InvalidProtocolBufferException e) {
105       data = createCallSpecificAppData(Type.UNKNOWN_INITIATION);
106     }
107     callSpecificAppData = data;
108     phoneAccountHandle = parcel.readParcelable(classLoader);
109     isVideoCall = parcel.readInt() != 0;
110     callSubject = parcel.readString();
111     allowAssistedDial = parcel.readInt() != 0;
112     outgoingCallExtras.putAll(parcel.readBundle(classLoader));
113   }
114 
forVoicemail( @ullable PhoneAccountHandle phoneAccountHandle, CallInitiationType.Type callInitiationType)115   public static CallIntentBuilder forVoicemail(
116       @Nullable PhoneAccountHandle phoneAccountHandle, CallInitiationType.Type callInitiationType) {
117     return new CallIntentBuilder(
118             Uri.fromParts(PhoneAccount.SCHEME_VOICEMAIL, "", null), callInitiationType)
119         .setPhoneAccountHandle(phoneAccountHandle);
120   }
121 
setUri(@onNull Uri uri)122   public void setUri(@NonNull Uri uri) {
123     this.uri = Assert.isNotNull(uri);
124   }
125 
getUri()126   public Uri getUri() {
127     return uri;
128   }
129 
getCallSpecificAppData()130   public CallSpecificAppData getCallSpecificAppData() {
131     return callSpecificAppData;
132   }
133 
setPhoneAccountHandle(@ullable PhoneAccountHandle accountHandle)134   public CallIntentBuilder setPhoneAccountHandle(@Nullable PhoneAccountHandle accountHandle) {
135     this.phoneAccountHandle = accountHandle;
136     return this;
137   }
138 
139   @Nullable
getPhoneAccountHandle()140   public PhoneAccountHandle getPhoneAccountHandle() {
141     return phoneAccountHandle;
142   }
143 
setIsVideoCall(boolean isVideoCall)144   public CallIntentBuilder setIsVideoCall(boolean isVideoCall) {
145     this.isVideoCall = isVideoCall;
146     return this;
147   }
148 
isVideoCall()149   public boolean isVideoCall() {
150     return isVideoCall;
151   }
152 
setAllowAssistedDial(boolean allowAssistedDial)153   public CallIntentBuilder setAllowAssistedDial(boolean allowAssistedDial) {
154     this.allowAssistedDial = allowAssistedDial;
155     return this;
156   }
157 
isAssistedDialAllowed()158   public boolean isAssistedDialAllowed() {
159     return allowAssistedDial;
160   }
161 
setCallSubject(String callSubject)162   public CallIntentBuilder setCallSubject(String callSubject) {
163     this.callSubject = callSubject;
164     return this;
165   }
166 
getCallSubject()167   public String getCallSubject() {
168     return callSubject;
169   }
170 
getOutgoingCallExtras()171   public Bundle getOutgoingCallExtras() {
172     return outgoingCallExtras;
173   }
174 
175   /**
176    * @deprecated Use {@link com.android.dialer.precall.PreCall#getIntent(android.content.Context,
177    *     CallIntentBuilder)} instead.
178    */
179   @Deprecated
build()180   public Intent build() {
181     Intent intent = new Intent(Intent.ACTION_CALL, uri);
182 
183     intent.putExtra(
184         TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE,
185         isVideoCall ? VideoProfile.STATE_BIDIRECTIONAL : VideoProfile.STATE_AUDIO_ONLY);
186 
187     outgoingCallExtras.putLong(
188         Constants.EXTRA_CALL_CREATED_TIME_MILLIS, SystemClock.elapsedRealtime());
189     CallIntentParser.putCallSpecificAppData(outgoingCallExtras, callSpecificAppData);
190 
191     intent.putExtra(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, outgoingCallExtras);
192 
193     if (phoneAccountHandle != null) {
194       intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);
195     }
196 
197     if (!TextUtils.isEmpty(callSubject)) {
198       intent.putExtra(TelecomManager.EXTRA_CALL_SUBJECT, callSubject);
199     }
200 
201     return intent;
202   }
203 
createCallSpecificAppData( CallInitiationType.Type callInitiationType)204   private static @NonNull CallSpecificAppData createCallSpecificAppData(
205       CallInitiationType.Type callInitiationType) {
206     CallSpecificAppData callSpecificAppData =
207         CallSpecificAppData.newBuilder().setCallInitiationType(callInitiationType).build();
208     return callSpecificAppData;
209   }
210 
increaseLightbringerCallButtonAppearInExpandedCallLogItemCount()211   public static void increaseLightbringerCallButtonAppearInExpandedCallLogItemCount() {
212     CallIntentBuilder.lightbringerButtonAppearInExpandedCallLogItemCount++;
213   }
214 
increaseLightbringerCallButtonAppearInCollapsedCallLogItemCount()215   public static void increaseLightbringerCallButtonAppearInCollapsedCallLogItemCount() {
216     CallIntentBuilder.lightbringerButtonAppearInCollapsedCallLogItemCount++;
217   }
218 
increaseLightbringerCallButtonAppearInSearchCount()219   public static void increaseLightbringerCallButtonAppearInSearchCount() {
220     CallIntentBuilder.lightbringerButtonAppearInSearchCount++;
221   }
222 
223   @VisibleForTesting
getLightbringerButtonAppearInExpandedCallLogItemCount()224   public static int getLightbringerButtonAppearInExpandedCallLogItemCount() {
225     return lightbringerButtonAppearInExpandedCallLogItemCount;
226   }
227 
228   @VisibleForTesting
getLightbringerButtonAppearInCollapsedCallLogItemCount()229   public static int getLightbringerButtonAppearInCollapsedCallLogItemCount() {
230     return lightbringerButtonAppearInCollapsedCallLogItemCount;
231   }
232 
233   @VisibleForTesting
getLightbringerButtonAppearInSearchCount()234   public static int getLightbringerButtonAppearInSearchCount() {
235     return lightbringerButtonAppearInSearchCount;
236   }
237 
238   @VisibleForTesting(otherwise = VisibleForTesting.NONE)
clearLightbringerCounts()239   public static void clearLightbringerCounts() {
240     lightbringerButtonAppearInCollapsedCallLogItemCount = 0;
241     lightbringerButtonAppearInExpandedCallLogItemCount = 0;
242     lightbringerButtonAppearInSearchCount = 0;
243   }
244 
245   @Override
describeContents()246   public int describeContents() {
247     return 0;
248   }
249 
250   @Override
writeToParcel(Parcel dest, int flags)251   public void writeToParcel(Parcel dest, int flags) {
252     dest.writeParcelable(uri, flags);
253     dest.writeByteArray(callSpecificAppData.toByteArray());
254     dest.writeParcelable(phoneAccountHandle, flags);
255     dest.writeInt(isVideoCall ? 1 : 0);
256     dest.writeString(callSubject);
257     dest.writeInt(allowAssistedDial ? 1 : 0);
258     dest.writeBundle(outgoingCallExtras);
259   }
260 
261   public static final Creator<CallIntentBuilder> CREATOR =
262       new Creator<CallIntentBuilder>() {
263         @Override
264         public CallIntentBuilder createFromParcel(Parcel source) {
265           return new CallIntentBuilder(source);
266         }
267 
268         @Override
269         public CallIntentBuilder[] newArray(int size) {
270           return new CallIntentBuilder[0];
271         }
272       };
273 }
274