Home | History | Annotate | Download | only in callintent
      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 
     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 
     85   public CallIntentBuilder(@NonNull Uri uri, CallInitiationType.Type callInitiationType) {
     86     this(uri, createCallSpecificAppData(callInitiationType));
     87   }
     88 
     89   public CallIntentBuilder(
     90       @NonNull String number, @NonNull CallSpecificAppData callSpecificAppData) {
     91     this(CallUtil.getCallUri(Assert.isNotNull(number)), callSpecificAppData);
     92   }
     93 
     94   public CallIntentBuilder(@NonNull String number, CallInitiationType.Type callInitiationType) {
     95     this(CallUtil.getCallUri(Assert.isNotNull(number)), callInitiationType);
     96   }
     97 
     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 
    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 
    122   public void setUri(@NonNull Uri uri) {
    123     this.uri = Assert.isNotNull(uri);
    124   }
    125 
    126   public Uri getUri() {
    127     return uri;
    128   }
    129 
    130   public CallSpecificAppData getCallSpecificAppData() {
    131     return callSpecificAppData;
    132   }
    133 
    134   public CallIntentBuilder setPhoneAccountHandle(@Nullable PhoneAccountHandle accountHandle) {
    135     this.phoneAccountHandle = accountHandle;
    136     return this;
    137   }
    138 
    139   @Nullable
    140   public PhoneAccountHandle getPhoneAccountHandle() {
    141     return phoneAccountHandle;
    142   }
    143 
    144   public CallIntentBuilder setIsVideoCall(boolean isVideoCall) {
    145     this.isVideoCall = isVideoCall;
    146     return this;
    147   }
    148 
    149   public boolean isVideoCall() {
    150     return isVideoCall;
    151   }
    152 
    153   public CallIntentBuilder setAllowAssistedDial(boolean allowAssistedDial) {
    154     this.allowAssistedDial = allowAssistedDial;
    155     return this;
    156   }
    157 
    158   public boolean isAssistedDialAllowed() {
    159     return allowAssistedDial;
    160   }
    161 
    162   public CallIntentBuilder setCallSubject(String callSubject) {
    163     this.callSubject = callSubject;
    164     return this;
    165   }
    166 
    167   public String getCallSubject() {
    168     return callSubject;
    169   }
    170 
    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
    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 
    204   private static @NonNull CallSpecificAppData createCallSpecificAppData(
    205       CallInitiationType.Type callInitiationType) {
    206     CallSpecificAppData callSpecificAppData =
    207         CallSpecificAppData.newBuilder().setCallInitiationType(callInitiationType).build();
    208     return callSpecificAppData;
    209   }
    210 
    211   public static void increaseLightbringerCallButtonAppearInExpandedCallLogItemCount() {
    212     CallIntentBuilder.lightbringerButtonAppearInExpandedCallLogItemCount++;
    213   }
    214 
    215   public static void increaseLightbringerCallButtonAppearInCollapsedCallLogItemCount() {
    216     CallIntentBuilder.lightbringerButtonAppearInCollapsedCallLogItemCount++;
    217   }
    218 
    219   public static void increaseLightbringerCallButtonAppearInSearchCount() {
    220     CallIntentBuilder.lightbringerButtonAppearInSearchCount++;
    221   }
    222 
    223   @VisibleForTesting
    224   public static int getLightbringerButtonAppearInExpandedCallLogItemCount() {
    225     return lightbringerButtonAppearInExpandedCallLogItemCount;
    226   }
    227 
    228   @VisibleForTesting
    229   public static int getLightbringerButtonAppearInCollapsedCallLogItemCount() {
    230     return lightbringerButtonAppearInCollapsedCallLogItemCount;
    231   }
    232 
    233   @VisibleForTesting
    234   public static int getLightbringerButtonAppearInSearchCount() {
    235     return lightbringerButtonAppearInSearchCount;
    236   }
    237 
    238   @VisibleForTesting(otherwise = VisibleForTesting.NONE)
    239   public static void clearLightbringerCounts() {
    240     lightbringerButtonAppearInCollapsedCallLogItemCount = 0;
    241     lightbringerButtonAppearInExpandedCallLogItemCount = 0;
    242     lightbringerButtonAppearInSearchCount = 0;
    243   }
    244 
    245   @Override
    246   public int describeContents() {
    247     return 0;
    248   }
    249 
    250   @Override
    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