1 /*
2  * Copyright (C) 2023 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 android.telecom.cts.apps;
18 
19 import android.content.Context;
20 import android.os.Bundle;
21 import android.telecom.CallAttributes;
22 import android.telecom.CallControl;
23 import android.telecom.CallControlCallback;
24 import android.telecom.DisconnectCause;
25 import android.telecom.PhoneAccountHandle;
26 import android.util.Log;
27 
28 import androidx.annotation.NonNull;
29 
30 import java.util.function.Consumer;
31 
32 public class TransactionalCall {
33     private static final String TAG = TransactionalCall.class.getSimpleName();
34     private String mId = "";
35     private Context mContext;
36     private boolean mIsOutgoingCall;
37     private CallResources mCallResources;
38     private final PhoneAccountHandle mPhoneAccountHandle;
39     private CallControl mCallControl;
40 
getCallResources()41     public CallResources getCallResources() {
42         return mCallResources;
43     }
44 
isOutgoingCall()45     public boolean isOutgoingCall() {
46         return mIsOutgoingCall;
47     }
48 
TransactionalCall(Context context, CallResources callResources)49     public TransactionalCall(Context context, CallResources callResources) {
50         mContext = context;
51         mIsOutgoingCall = callResources.getCallAttributes().getDirection()
52                 == CallAttributes.DIRECTION_OUTGOING;
53         mCallResources = callResources;
54         mPhoneAccountHandle = callResources.getCallAttributes().getPhoneAccountHandle();
55     }
56 
getId()57     public String getId() {
58         return mId;
59     }
60 
setId(String id)61     public void setId(String id) {
62         mId = id;
63     }
64 
getCallControl()65     public CallControl getCallControl() {
66         return mCallControl;
67     }
68 
getPhoneAccountHandle()69     public PhoneAccountHandle getPhoneAccountHandle() {
70         return mPhoneAccountHandle;
71     }
72 
setCallControl(CallControl callControl)73     public void setCallControl(CallControl callControl) {
74         mCallControl = callControl;
75     }
76 
setCallControlAndId(CallControl callControl)77     public void setCallControlAndId(CallControl callControl) {
78         mCallControl = callControl;
79         mId = callControl.getCallId().toString();
80         mCallResources.setCallId(mId);
81         Log.i(TAG, String.format("setCallControlAndId: id=[%s], cc=[%s]", mId, callControl));
82     }
83 
setActive(LatchedOutcomeReceiver outcome, Bundle extras )84     public void setActive(LatchedOutcomeReceiver outcome, Bundle extras ){
85         if (mIsOutgoingCall) {
86             Log.i(TAG, "transitionCallStateTo: setActive");
87             mCallControl.setActive(Runnable::run, outcome);
88         } else {
89             Log.i(TAG, "transitionCallStateTo: setAnswer");
90             int videoState = CallAttributes.AUDIO_CALL;
91             if (CallControlExtras.hasVideoStateExtra(extras)) {
92                 CallControlExtras.getVideoStateFromExtras(extras);
93             }
94             mCallControl.answer(videoState, Runnable::run, outcome);
95             mCallResources.updateNotificationToOngoing(mContext);
96         }
97     }
98 
setInactive(LatchedOutcomeReceiver outcome)99     public void setInactive(LatchedOutcomeReceiver outcome){
100         Log.i(TAG, "transitionCallStateTo: setInactive");
101         mCallControl.setInactive(Runnable::run, outcome);
102     }
103 
disconnect(LatchedOutcomeReceiver outcome, Bundle extras )104     public void disconnect(LatchedOutcomeReceiver outcome, Bundle extras ) {
105         Log.i(TAG, "transitionCallStateTo: disconnect");
106         int disconnectCause = DisconnectCause.LOCAL;
107         if (CallControlExtras.hasDisconnectCauseExtra(extras)) {
108             disconnectCause = CallControlExtras.getDisconnectCauseFromExtras(
109                     extras);
110         }
111         mCallControl.disconnect(
112                 new DisconnectCause(disconnectCause),
113                 Runnable::run,
114                 outcome);
115         mCallResources.destroyResources(mContext);
116     }
117 
118     public CallControlCallback mHandshakes = new CallControlCallback() {
119         @Override
120         public void onSetActive(@NonNull Consumer<Boolean> wasCompleted) {
121             wasCompleted.accept(true);
122         }
123 
124         @Override
125         public void onSetInactive(@NonNull Consumer<Boolean> wasCompleted) {
126             wasCompleted.accept(true);
127             Log.i(TAG, "onSetInactive: stopped recording ; callId"+ mId);
128         }
129 
130         @Override
131         public void onAnswer(int videoState, @NonNull Consumer<Boolean> wasCompleted) {
132             mCallResources.updateNotificationToOngoing(mContext);
133             wasCompleted.accept(true);
134             Log.i(TAG, "onAnswer: started recording; callId" + mId);
135         }
136 
137         @Override
138         public void onDisconnect(@NonNull DisconnectCause cause,
139                 @NonNull Consumer<Boolean> wasCompleted) {
140             mCallResources.destroyResources(mContext);
141             wasCompleted.accept(true);
142         }
143 
144         @Override
145         public void onCallStreamingStarted(@NonNull Consumer<Boolean> wasCompleted) {
146         }
147     };
148 
149     public TransactionalCallEvents mEvents = new TransactionalCallEvents();
150 }
151