1 /*
2  * Copyright (C) 2021 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;
18 
19 import android.content.Intent;
20 import android.telecom.BluetoothCallQualityReport;
21 import android.telecom.Call;
22 import android.telecom.CallAudioState;
23 import android.telecom.CallDiagnosticService;
24 import android.telecom.CallDiagnostics;
25 import android.telephony.CallQuality;
26 import android.telephony.ims.ImsReasonInfo;
27 import android.util.Log;
28 
29 import androidx.annotation.NonNull;
30 import androidx.annotation.Nullable;
31 
32 import java.util.ArrayList;
33 import java.util.List;
34 import java.util.concurrent.CountDownLatch;
35 
36 public class CtsCallDiagnosticService extends CallDiagnosticService {
37     private static final String LOG_TAG = "CtsCallDiagnosticService";
38     private static CtsCallDiagnosticService sCtsCallDiagnosticService;
39     private CallAudioState mCallAudioState;
40     private BluetoothCallQualityReport mBluetoothCallQualityReport;
41     private static CountDownLatch sBindLatch = new CountDownLatch(1);
42     private CountDownLatch mChangeLatch = new CountDownLatch(1);
43     private CountDownLatch mBluetoothCallQualityReportLatch = new CountDownLatch(1);
44     private CountDownLatch mCallAudioStateLatch = new CountDownLatch(1);
45     private List<CtsCallDiagnostics> mCalls = new ArrayList<>();
46     private CharSequence mDisconnectMessage = null;
47 
48     public class CtsCallDiagnostics extends CallDiagnostics {
49         private Call.Details mCallDetails;
50         private int mMessageType;
51         private int mMessageValue;
52         private CallQuality mCallQuality;
53         private CountDownLatch mCallQualityReceivedLatch = new CountDownLatch(1);
54         private CountDownLatch mReceivedMessageLatch = new CountDownLatch(1);
55         private CountDownLatch mCallDetailsReceivedLatch = new CountDownLatch(1);
56         private CountDownLatch mDisconnectLatch = new CountDownLatch(1);
57 
58         @Override
onCallDetailsChanged(@onNull Call.Details details)59         public void onCallDetailsChanged(@NonNull Call.Details details) {
60             mCallDetails = details;
61             mCallDetailsReceivedLatch.countDown();
62         }
63 
64         @Override
onReceiveDeviceToDeviceMessage(int message, int value)65         public void onReceiveDeviceToDeviceMessage(int message, int value) {
66             mMessageType = message;
67             mMessageValue = value;
68             mReceivedMessageLatch.countDown();
69         }
70 
71         @Nullable
72         @Override
onCallDisconnected(int disconnectCause, int preciseDisconnectCause)73         public CharSequence onCallDisconnected(int disconnectCause, int preciseDisconnectCause) {
74             mDisconnectLatch.countDown();
75             return mDisconnectMessage;
76         }
77 
78         @Nullable
79         @Override
onCallDisconnected(@onNull ImsReasonInfo disconnectReason)80         public CharSequence onCallDisconnected(@NonNull ImsReasonInfo disconnectReason) {
81             mDisconnectLatch.countDown();
82             return mDisconnectMessage;
83         }
84 
85         @Override
onCallQualityReceived(@onNull CallQuality callQuality)86         public void onCallQualityReceived(@NonNull CallQuality callQuality) {
87             mCallQuality = callQuality;
88             mReceivedMessageLatch.countDown();
89         }
90 
getCallDetails()91         public Call.Details getCallDetails() {
92             return mCallDetails;
93         }
94 
getMessageType()95         public int getMessageType() {
96             return mMessageType;
97         }
98 
setMessageType(int messageType)99         public void setMessageType(int messageType) {
100             this.mMessageType = messageType;
101         }
102 
getMessageValue()103         public int getMessageValue() {
104             return mMessageValue;
105         }
106 
getCallQualityReceivedLatch()107         public CountDownLatch getCallQualityReceivedLatch() {
108             return mCallQualityReceivedLatch;
109         }
110 
getReceivedMessageLatch()111         public CountDownLatch getReceivedMessageLatch() {
112             return mReceivedMessageLatch;
113         }
114 
getCallQuality()115         public CallQuality getCallQuality() {
116             return mCallQuality;
117         }
118 
getCallDetailsReceivedLatch()119         public CountDownLatch getCallDetailsReceivedLatch() {
120             return mCallDetailsReceivedLatch;
121         }
122 
getDisconnectLatch()123         public CountDownLatch getDisconnectLatch() {
124             return mDisconnectLatch;
125         }
126     }
127 
128     @Override
onBind(android.content.Intent intent)129     public android.os.IBinder onBind(android.content.Intent intent) {
130         Log.i(LOG_TAG, "Service bound.");
131         sCtsCallDiagnosticService = this;
132         android.os.IBinder binder = super.onBind(intent);
133         sBindLatch.countDown();
134         return binder;
135     }
136 
137     @Override
onUnbind(Intent intent)138     public boolean onUnbind(Intent intent) {
139         Log.i(LOG_TAG, "Service unbound");
140         sCtsCallDiagnosticService = null;
141         return super.onUnbind(intent);
142     }
143 
144     @NonNull
145     @Override
onInitializeCallDiagnostics(@onNull Call.Details call)146     public CallDiagnostics onInitializeCallDiagnostics(@NonNull Call.Details call) {
147         CtsCallDiagnostics diagCall = new CtsCallDiagnostics();
148         diagCall.mCallDetails = call;
149         mCalls.add(diagCall);
150         mChangeLatch.countDown();
151         mChangeLatch = new CountDownLatch(1);
152         return diagCall;
153     }
154 
155     @Override
onRemoveCallDiagnostics(@onNull CallDiagnostics call)156     public void onRemoveCallDiagnostics(@NonNull CallDiagnostics call) {
157         Log.i(LOG_TAG, "onRemoveDiagnosticCall: " + call);
158         mCalls.remove(call);
159         mChangeLatch.countDown();
160         mChangeLatch = new CountDownLatch(1);
161     }
162 
163     @Override
onCallAudioStateChanged(@onNull CallAudioState audioState)164     public void onCallAudioStateChanged(@NonNull CallAudioState audioState) {
165         mCallAudioState = audioState;
166         mCallAudioStateLatch.countDown();
167     }
168 
169     @Override
onBluetoothCallQualityReportReceived( @onNull BluetoothCallQualityReport qualityReport)170     public void onBluetoothCallQualityReportReceived(
171             @NonNull BluetoothCallQualityReport qualityReport) {
172         mBluetoothCallQualityReport = qualityReport;
173         mBluetoothCallQualityReportLatch.countDown();
174     }
175 
getInstance()176     public static CtsCallDiagnosticService getInstance() {
177         return sCtsCallDiagnosticService;
178     }
179 
getBindLatch()180     public static CountDownLatch getBindLatch() {
181         return sBindLatch;
182     }
183 
getCallAudioState()184     public CallAudioState getCallAudioState() {
185         return mCallAudioState;
186     }
187 
getCallAudioStateLatch()188     public CountDownLatch getCallAudioStateLatch() {
189         return mCallAudioStateLatch;
190     }
191 
getBluetoothCallQualityReport()192     public BluetoothCallQualityReport getBluetoothCallQualityReport() {
193         return mBluetoothCallQualityReport;
194     }
195 
getCallChangeLatch()196     public CountDownLatch getCallChangeLatch() {
197         return mChangeLatch;
198     }
199 
getBluetoothCallQualityReportLatch()200     public CountDownLatch getBluetoothCallQualityReportLatch() {
201         return mBluetoothCallQualityReportLatch;
202     }
203 
getCalls()204     public List<CtsCallDiagnostics> getCalls() {
205         return mCalls;
206     }
207 
setDisconnectMessage(CharSequence charSequence)208     public void setDisconnectMessage(CharSequence charSequence) {
209         mDisconnectMessage = charSequence;
210     }
211 }
212