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.voip; 18 19 import com.android.server.telecom.LoggedHandlerExecutor; 20 import com.android.server.telecom.TelecomSystem; 21 22 import java.util.List; 23 import java.util.concurrent.CompletableFuture; 24 25 /** 26 * A VoipCallTransaction implementation that its sub transactions will be executed in serial 27 */ 28 public class SerialTransaction extends VoipCallTransaction { SerialTransaction(List<VoipCallTransaction> subTransactions, TelecomSystem.SyncRoot lock)29 public SerialTransaction(List<VoipCallTransaction> subTransactions, 30 TelecomSystem.SyncRoot lock) { 31 super(subTransactions, lock); 32 } 33 appendTransaction(VoipCallTransaction transaction)34 public void appendTransaction(VoipCallTransaction transaction){ 35 mSubTransactions.add(transaction); 36 } 37 38 @Override start()39 public void start() { 40 // post timeout work 41 CompletableFuture<Void> future = new CompletableFuture<>(); 42 mHandler.postDelayed(() -> future.complete(null), TIMEOUT_LIMIT); 43 future.thenApplyAsync((x) -> { 44 if (mCompleted.getAndSet(true)) { 45 return null; 46 } 47 if (mCompleteListener != null) { 48 mCompleteListener.onTransactionTimeout(mTransactionName); 49 } 50 finish(); 51 return null; 52 }, new LoggedHandlerExecutor(mHandler, mTransactionName + "@" + hashCode() 53 + ".s", mLock)); 54 55 if (mSubTransactions != null && mSubTransactions.size() > 0) { 56 TransactionManager.TransactionCompleteListener subTransactionListener = 57 new TransactionManager.TransactionCompleteListener() { 58 59 @Override 60 public void onTransactionCompleted(VoipCallTransactionResult result, 61 String transactionName) { 62 if (result.getResult() != VoipCallTransactionResult.RESULT_SUCCEED) { 63 handleTransactionFailure(); 64 CompletableFuture.completedFuture(null).thenApplyAsync( 65 (x) -> { 66 VoipCallTransactionResult mainResult = 67 new VoipCallTransactionResult( 68 VoipCallTransactionResult.RESULT_FAILED, 69 String.format( 70 "sub transaction %s failed", 71 transactionName)); 72 mCompleteListener.onTransactionCompleted(mainResult, 73 mTransactionName); 74 finish(); 75 return null; 76 }, new LoggedHandlerExecutor(mHandler, 77 mTransactionName + "@" + hashCode() 78 + ".oTC", mLock)); 79 } else { 80 if (mSubTransactions.size() > 0) { 81 VoipCallTransaction transaction = mSubTransactions.remove(0); 82 transaction.setCompleteListener(this); 83 transaction.start(); 84 } else { 85 scheduleTransaction(); 86 } 87 } 88 } 89 90 @Override 91 public void onTransactionTimeout(String transactionName) { 92 handleTransactionFailure(); 93 CompletableFuture.completedFuture(null).thenApplyAsync( 94 (x) -> { 95 VoipCallTransactionResult mainResult = 96 new VoipCallTransactionResult( 97 VoipCallTransactionResult.RESULT_FAILED, 98 String.format("sub transaction %s timed out", 99 transactionName)); 100 mCompleteListener.onTransactionCompleted(mainResult, 101 mTransactionName); 102 finish(); 103 return null; 104 }, new LoggedHandlerExecutor(mHandler, 105 mTransactionName + "@" + hashCode() 106 + ".oTT", mLock)); 107 } 108 }; 109 VoipCallTransaction transaction = mSubTransactions.remove(0); 110 transaction.setCompleteListener(subTransactionListener); 111 transaction.start(); 112 } else { 113 scheduleTransaction(); 114 } 115 } 116 handleTransactionFailure()117 public void handleTransactionFailure() {} 118 } 119