• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.os.Handler;
20 import android.os.HandlerThread;
21 import android.telecom.Log;
22 
23 import com.android.server.telecom.LoggedHandlerExecutor;
24 import com.android.server.telecom.TelecomSystem;
25 
26 import java.util.List;
27 import java.util.concurrent.CompletableFuture;
28 import java.util.concurrent.CompletionStage;
29 import java.util.concurrent.atomic.AtomicBoolean;
30 import java.util.function.Function;
31 
32 public class VoipCallTransaction {
33     //TODO: add log events
34     protected static final long TIMEOUT_LIMIT = 5000L;
35     protected final AtomicBoolean mCompleted = new AtomicBoolean(false);
36     protected String mTransactionName = this.getClass().getSimpleName();
37     private HandlerThread mHandlerThread;
38     protected Handler mHandler;
39     protected TransactionManager.TransactionCompleteListener mCompleteListener;
40     protected List<VoipCallTransaction> mSubTransactions;
41     protected TelecomSystem.SyncRoot mLock;
42 
VoipCallTransaction( List<VoipCallTransaction> subTransactions, TelecomSystem.SyncRoot lock)43     public VoipCallTransaction(
44             List<VoipCallTransaction> subTransactions, TelecomSystem.SyncRoot lock) {
45         mSubTransactions = subTransactions;
46         mHandlerThread = new HandlerThread(this.toString());
47         mHandlerThread.start();
48         mHandler = new Handler(mHandlerThread.getLooper());
49         mLock = lock;
50     }
51 
VoipCallTransaction(TelecomSystem.SyncRoot lock)52     public VoipCallTransaction(TelecomSystem.SyncRoot lock) {
53         this(null /** mSubTransactions */, lock);
54     }
55 
start()56     public void start() {
57         // post timeout work
58         CompletableFuture<Void> future = new CompletableFuture<>();
59         mHandler.postDelayed(() -> future.complete(null), TIMEOUT_LIMIT);
60         future.thenApplyAsync((x) -> {
61             if (mCompleted.getAndSet(true)) {
62                 return null;
63             }
64             if (mCompleteListener != null) {
65                 mCompleteListener.onTransactionTimeout(mTransactionName);
66             }
67             finish();
68             return null;
69         }, new LoggedHandlerExecutor(mHandler, mTransactionName + "@" + hashCode()
70                 + ".s", mLock));
71 
72         scheduleTransaction();
73     }
74 
scheduleTransaction()75     protected void scheduleTransaction() {
76         LoggedHandlerExecutor executor = new LoggedHandlerExecutor(mHandler,
77                 mTransactionName + "@" + hashCode() + ".pT", mLock);
78         CompletableFuture<Void> future = CompletableFuture.completedFuture(null);
79         future.thenComposeAsync(this::processTransaction, executor)
80                 .thenApplyAsync((Function<VoipCallTransactionResult, Void>) result -> {
81                     mCompleted.set(true);
82                     if (mCompleteListener != null) {
83                         mCompleteListener.onTransactionCompleted(result, mTransactionName);
84                     }
85                     finish();
86                     return null;
87                     }, executor)
88                 .exceptionallyAsync((throwable -> {
89                     Log.e(this, throwable, "Error while executing transaction.");
90                     return null;
91                 }), executor);
92     }
93 
processTransaction(Void v)94     public CompletionStage<VoipCallTransactionResult> processTransaction(Void v) {
95         return CompletableFuture.completedFuture(
96                 new VoipCallTransactionResult(VoipCallTransactionResult.RESULT_SUCCEED, null));
97     }
98 
setCompleteListener(TransactionManager.TransactionCompleteListener listener)99     public void setCompleteListener(TransactionManager.TransactionCompleteListener listener) {
100         mCompleteListener = listener;
101     }
102 
finish()103     public void finish() {
104         // finish all sub transactions
105         if (mSubTransactions != null && mSubTransactions.size() > 0) {
106             mSubTransactions.forEach(VoipCallTransaction::finish);
107         }
108         mHandlerThread.quit();
109     }
110 }
111