1 /* 2 * Copyright (C) 2022 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.server.telecom.callsequencing.voip; 18 19 import android.telecom.CallException; 20 21 import com.android.server.telecom.LoggedHandlerExecutor; 22 import com.android.server.telecom.TelecomSystem; 23 import com.android.server.telecom.callsequencing.CallTransaction; 24 import com.android.server.telecom.callsequencing.CallTransactionResult; 25 import com.android.server.telecom.callsequencing.TransactionManager; 26 27 import java.util.List; 28 import java.util.concurrent.CompletableFuture; 29 import java.util.concurrent.atomic.AtomicInteger; 30 31 /** 32 * A CallTransaction implementation that its sub transactions will be executed in parallel 33 */ 34 public class ParallelTransaction extends CallTransaction { ParallelTransaction(List<CallTransaction> subTransactions, TelecomSystem.SyncRoot lock)35 public ParallelTransaction(List<CallTransaction> subTransactions, 36 TelecomSystem.SyncRoot lock) { 37 super(subTransactions, lock); 38 } 39 40 @Override processTransactions()41 public void processTransactions() { 42 if (mSubTransactions == null || mSubTransactions.isEmpty()) { 43 scheduleTransaction(); 44 return; 45 } 46 TransactionManager.TransactionCompleteListener subTransactionListener = 47 new TransactionManager.TransactionCompleteListener() { 48 private final AtomicInteger mCount = new AtomicInteger(mSubTransactions.size()); 49 50 @Override 51 public void onTransactionCompleted(CallTransactionResult result, 52 String transactionName) { 53 if (result.getResult() != CallTransactionResult.RESULT_SUCCEED) { 54 CompletableFuture.completedFuture(null).thenApplyAsync( 55 (x) -> { 56 finish(result); 57 mCompleteListener.onTransactionCompleted(result, 58 mTransactionName); 59 return null; 60 }, new LoggedHandlerExecutor(mHandler, 61 mTransactionName + "@" + hashCode() 62 + ".oTC", mLock)); 63 } else { 64 if (mCount.decrementAndGet() == 0) { 65 scheduleTransaction(); 66 } 67 } 68 } 69 70 @Override 71 public void onTransactionTimeout(String transactionName) { 72 CompletableFuture.completedFuture(null).thenApplyAsync( 73 (x) -> { 74 CallTransactionResult mainResult = 75 new CallTransactionResult( 76 CallException.CODE_OPERATION_TIMED_OUT, 77 String.format("sub transaction %s timed out", 78 transactionName)); 79 finish(mainResult); 80 mCompleteListener.onTransactionCompleted(mainResult, 81 mTransactionName); 82 return null; 83 }, new LoggedHandlerExecutor(mHandler, 84 mTransactionName + "@" + hashCode() 85 + ".oTT", mLock)); 86 } 87 }; 88 for (CallTransaction transaction : mSubTransactions) { 89 transaction.setCompleteListener(subTransactionListener); 90 transaction.start(); 91 } 92 } 93 } 94