1 /* 2 * Copyright (C) 2018 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.precall.impl; 18 19 import android.content.Context; 20 import android.content.Intent; 21 import com.android.dialer.callintent.CallIntentBuilder; 22 import com.android.dialer.common.LogUtil; 23 import com.android.dialer.common.concurrent.Annotations.Ui; 24 import com.android.dialer.duo.Duo.ReachabilityData; 25 import com.android.dialer.duo.DuoComponent; 26 import com.android.dialer.precall.PreCallAction; 27 import com.android.dialer.precall.PreCallCoordinator; 28 import com.android.dialer.precall.PreCallCoordinator.PendingAction; 29 import com.google.common.collect.ImmutableList; 30 import com.google.common.collect.ImmutableMap; 31 import com.google.common.util.concurrent.FutureCallback; 32 import com.google.common.util.concurrent.Futures; 33 import com.google.common.util.concurrent.ListenableFuture; 34 import com.google.common.util.concurrent.ListeningExecutorService; 35 import javax.inject.Inject; 36 37 /** 38 * Checks if a duo call is actually callable, and request an activity for {@link 39 * android.app.Activity#startActivityForResult(Intent, int)} 40 */ 41 public class DuoAction implements PreCallAction { 42 43 private final ListeningExecutorService uiExecutor; 44 45 @Inject DuoAction(@i ListeningExecutorService uiExecutor)46 DuoAction(@Ui ListeningExecutorService uiExecutor) { 47 this.uiExecutor = uiExecutor; 48 } 49 50 @Override requiresUi(Context context, CallIntentBuilder builder)51 public boolean requiresUi(Context context, CallIntentBuilder builder) { 52 // Duo call must be started with startActivityForResult() which needs a activity. 53 return builder.isDuoCall(); 54 } 55 56 @Override runWithoutUi(Context context, CallIntentBuilder builder)57 public void runWithoutUi(Context context, CallIntentBuilder builder) {} 58 59 @Override runWithUi(PreCallCoordinator coordinator)60 public void runWithUi(PreCallCoordinator coordinator) { 61 if (!requiresUi(coordinator.getActivity(), coordinator.getBuilder())) { 62 return; 63 } 64 String number = coordinator.getBuilder().getUri().getSchemeSpecificPart(); 65 ListenableFuture<ImmutableMap<String, ReachabilityData>> reachabilities = 66 DuoComponent.get(coordinator.getActivity()) 67 .getDuo() 68 .updateReachability(coordinator.getActivity(), ImmutableList.of(number)); 69 PendingAction pendingAction = coordinator.startPendingAction(); 70 71 Futures.addCallback( 72 reachabilities, 73 new FutureCallback<ImmutableMap<String, ReachabilityData>>() { 74 @Override 75 public void onSuccess(ImmutableMap<String, ReachabilityData> result) { 76 if (!result.containsKey(number) || !result.get(number).videoCallable()) { 77 LogUtil.w( 78 "DuoAction.runWithUi", 79 number + " number no longer duo reachable, falling back to carrier video call"); 80 coordinator.getBuilder().setIsDuoCall(false); 81 } 82 pendingAction.finish(); 83 } 84 85 @Override 86 public void onFailure(Throwable throwable) { 87 LogUtil.e("DuoAction.runWithUi", "reachability query failed", throwable); 88 coordinator.getBuilder().setIsDuoCall(false); 89 pendingAction.finish(); 90 } 91 }, 92 uiExecutor); 93 } 94 95 @Override onDiscard()96 public void onDiscard() {} 97 } 98