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