• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
41     // Delegates the completion of call state transition operations to potentially another entity
42     // to control the completion.
43     private Consumer<CallStateTransitionOperation> mOperationConsumer;
44 
getCallResources()45     public CallResources getCallResources() {
46         return mCallResources;
47     }
48 
isOutgoingCall()49     public boolean isOutgoingCall() {
50         return mIsOutgoingCall;
51     }
52 
TransactionalCall(Context context, CallResources callResources)53     public TransactionalCall(Context context, CallResources callResources) {
54         mContext = context;
55         mIsOutgoingCall = callResources.getCallAttributes().getDirection()
56                 == CallAttributes.DIRECTION_OUTGOING;
57         mCallResources = callResources;
58         mPhoneAccountHandle = callResources.getCallAttributes().getPhoneAccountHandle();
59     }
60 
getId()61     public String getId() {
62         return mId;
63     }
64 
setId(String id)65     public void setId(String id) {
66         mId = id;
67     }
68 
getCallControl()69     public CallControl getCallControl() {
70         return mCallControl;
71     }
72 
getPhoneAccountHandle()73     public PhoneAccountHandle getPhoneAccountHandle() {
74         return mPhoneAccountHandle;
75     }
76 
setCallControl(CallControl callControl)77     public void setCallControl(CallControl callControl) {
78         mCallControl = callControl;
79     }
80 
81     /**
82      * Delegate operation completion to the test process so that it can control completion of the
83      * request.
84      */
setOperationConsumer(Consumer<CallStateTransitionOperation> consumer)85     public void setOperationConsumer(Consumer<CallStateTransitionOperation> consumer) {
86         mOperationConsumer = consumer;
87     }
88 
setCallControlAndId(CallControl callControl)89     public void setCallControlAndId(CallControl callControl) {
90         mCallControl = callControl;
91         mId = callControl.getCallId().toString();
92         mCallResources.setCallId(mId);
93         Log.i(TAG, String.format("setCallControlAndId: id=[%s], cc=[%s]", mId, callControl));
94     }
95 
setActive(LatchedOutcomeReceiver outcome, Bundle extras )96     public void setActive(LatchedOutcomeReceiver outcome, Bundle extras ){
97         if (mIsOutgoingCall) {
98             Log.i(TAG, "transitionCallStateTo: setActive");
99             mCallControl.setActive(Runnable::run, outcome);
100         } else {
101             Log.i(TAG, "transitionCallStateTo: setAnswer");
102             int videoState = CallAttributes.AUDIO_CALL;
103             if (CallControlExtras.hasVideoStateExtra(extras)) {
104                 CallControlExtras.getVideoStateFromExtras(extras);
105             }
106             mCallControl.answer(videoState, Runnable::run, outcome);
107             mCallResources.updateNotificationToOngoing(mContext);
108         }
109     }
110 
setInactive(LatchedOutcomeReceiver outcome)111     public void setInactive(LatchedOutcomeReceiver outcome){
112         Log.i(TAG, "transitionCallStateTo: setInactive");
113         mCallControl.setInactive(Runnable::run, outcome);
114     }
115 
disconnect(LatchedOutcomeReceiver outcome, Bundle extras )116     public void disconnect(LatchedOutcomeReceiver outcome, Bundle extras ) {
117         Log.i(TAG, "transitionCallStateTo: disconnect");
118         int disconnectCause = DisconnectCause.LOCAL;
119         if (CallControlExtras.hasDisconnectCauseExtra(extras)) {
120             disconnectCause = CallControlExtras.getDisconnectCauseFromExtras(
121                     extras);
122         }
123         mCallControl.disconnect(
124                 new DisconnectCause(disconnectCause),
125                 Runnable::run,
126                 outcome);
127         mCallResources.destroyResources(mContext);
128     }
129 
130     public CallControlCallback mHandshakes = new CallControlCallback() {
131         @Override
132         public void onSetActive(@NonNull Consumer<Boolean> wasCompleted) {
133             if (mOperationConsumer != null) {
134                 mOperationConsumer.accept(new CallStateTransitionOperation(
135                         CallStateTransitionOperation.OPERATION_UNHOLD, System.currentTimeMillis()));
136             }
137             wasCompleted.accept(true);
138         }
139 
140         @Override
141         public void onSetInactive(@NonNull Consumer<Boolean> wasCompleted) {
142             Log.i(TAG, "onSetInactive: stopped recording ; callId"+ mId);
143             if (mOperationConsumer != null) {
144                 mOperationConsumer.accept(new CallStateTransitionOperation(
145                         CallStateTransitionOperation.OPERATION_HOLD, System.currentTimeMillis()));
146             }
147             wasCompleted.accept(true);
148         }
149 
150         @Override
151         public void onAnswer(int videoState, @NonNull Consumer<Boolean> wasCompleted) {
152             Log.i(TAG, "onAnswer: started recording; callId" + mId);
153             if (mOperationConsumer != null) {
154                 mOperationConsumer.accept(new CallStateTransitionOperation(
155                         CallStateTransitionOperation.OPERATION_ANSWER, System.currentTimeMillis()));
156             }
157             mCallResources.updateNotificationToOngoing(mContext);
158             wasCompleted.accept(true);
159         }
160 
161         @Override
162         public void onDisconnect(@NonNull DisconnectCause cause,
163                 @NonNull Consumer<Boolean> wasCompleted) {
164             if (mOperationConsumer != null) {
165                 mOperationConsumer.accept(new CallStateTransitionOperation(
166                         CallStateTransitionOperation.OPERATION_DISCONNECT,
167                         System.currentTimeMillis()));
168             }
169             mCallResources.destroyResources(mContext);
170             wasCompleted.accept(true);
171         }
172 
173         @Override
174         public void onCallStreamingStarted(@NonNull Consumer<Boolean> wasCompleted) {
175         }
176     };
177 
178     public TransactionalCallEvents mEvents = new TransactionalCallEvents();
179 }
180