1 /*
2  * Copyright (C) 2017 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.cts.verifier.telecom;
18 
19 import android.content.Intent;
20 import android.os.Bundle;
21 import android.telecom.Connection;
22 import android.telecom.ConnectionRequest;
23 import android.telecom.ConnectionService;
24 import android.telecom.PhoneAccountHandle;
25 import android.telecom.TelecomManager;
26 
27 import java.util.ArrayList;
28 import java.util.List;
29 import java.util.concurrent.CountDownLatch;
30 import java.util.concurrent.TimeUnit;
31 
32 /**
33  * CTS Verifier ConnectionService implementation.
34  */
35 public class CtsConnectionService extends ConnectionService {
36     static final int TIMEOUT_MILLIS = 10000;
37 
38     private CtsConnection.Listener mConnectionListener =
39             new CtsConnection.Listener() {
40                 @Override
41                 void onDestroyed(CtsConnection connection) {
42                     synchronized (mConnectionsLock) {
43                         mConnections.remove(connection);
44                     }
45                 }
46             };
47 
48     private static CtsConnectionService sConnectionService;
49     private static CountDownLatch sBindingLatch = new CountDownLatch(1);
50 
51     private List<CtsConnection> mConnections = new ArrayList<>();
52     private Object mConnectionsLock = new Object();
53     private CountDownLatch mConnectionLatch = new CountDownLatch(1);
54 
getConnectionService()55     public static CtsConnectionService getConnectionService() {
56         return sConnectionService;
57     }
58 
waitForAndGetConnectionService()59     public static CtsConnectionService waitForAndGetConnectionService() {
60         if (sConnectionService == null) {
61             try {
62                 sBindingLatch.await(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
63             } catch (InterruptedException e) {
64             }
65         }
66         return sConnectionService;
67     }
68 
CtsConnectionService()69     public CtsConnectionService() throws Exception {
70         super();
71         sConnectionService = this;
72         if (sBindingLatch != null) {
73             sBindingLatch.countDown();
74         }
75         sBindingLatch = new CountDownLatch(1);
76     }
77 
getConnections()78     public List<CtsConnection> getConnections() {
79         synchronized (mConnectionsLock) {
80             return new ArrayList<CtsConnection>(mConnections);
81         }
82     }
83 
waitForAndGetConnection()84     public CtsConnection waitForAndGetConnection() {
85         try {
86             mConnectionLatch.await(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
87         } catch (InterruptedException e) {
88         }
89         mConnectionLatch = new CountDownLatch(1);
90         synchronized (mConnectionsLock) {
91             if (mConnections.size() > 0) {
92                 return mConnections.get(0);
93             } else {
94                 return null;
95             }
96         }
97     }
98 
99     @Override
onUnbind(Intent intent)100     public boolean onUnbind(Intent intent) {
101         sConnectionService = null;
102         return super.onUnbind(intent);
103     }
104 
105     @Override
onCreateOutgoingConnection(PhoneAccountHandle connectionManagerAccount, final ConnectionRequest request)106     public Connection onCreateOutgoingConnection(PhoneAccountHandle connectionManagerAccount,
107                                                  final ConnectionRequest request) {
108 
109         return createManagedConnection(request, false);
110     }
111 
112     @Override
onCreateIncomingConnection(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request)113     public Connection onCreateIncomingConnection(PhoneAccountHandle connectionManagerPhoneAccount,
114                                                  ConnectionRequest request) {
115 
116         return createManagedConnection(request, true);
117     }
118 
119     @Override
onCreateIncomingConnectionFailed(PhoneAccountHandle connectionManagerHandle, ConnectionRequest request)120     public void onCreateIncomingConnectionFailed(PhoneAccountHandle connectionManagerHandle,
121                                                  ConnectionRequest request) {
122     }
123 
124     @Override
onCreateOutgoingConnectionFailed(PhoneAccountHandle connectionManagerHandle, ConnectionRequest request)125     public void onCreateOutgoingConnectionFailed(PhoneAccountHandle connectionManagerHandle,
126                                                  ConnectionRequest request) {
127     }
128 
createManagedConnection(ConnectionRequest request, boolean isIncoming)129     private Connection createManagedConnection(ConnectionRequest request, boolean isIncoming) {
130         boolean isSelfManaged = request.getAccountHandle().equals(
131                 PhoneAccountUtils.TEST_SELF_MANAGED_PHONE_ACCOUNT_HANDLE);
132 
133         boolean useAudioClip =
134                 request.getExtras().getBoolean(CtsConnection.EXTRA_PLAY_CS_AUDIO, false);
135         CtsConnection connection = new CtsConnection(getApplicationContext(), isIncoming,
136                 mConnectionListener, useAudioClip);
137         if (isSelfManaged) {
138             connection.setConnectionProperties(Connection.PROPERTY_SELF_MANAGED);
139         }
140         connection.setConnectionCapabilities(Connection.CAPABILITY_SUPPORT_HOLD |
141                 Connection.CAPABILITY_HOLD);
142         connection.setAddress(request.getAddress(), TelecomManager.PRESENTATION_ALLOWED);
143         connection.setExtras(request.getExtras());
144 
145         Bundle moreExtras = new Bundle();
146         moreExtras.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
147                 request.getAccountHandle());
148         connection.putExtras(moreExtras);
149         connection.setVideoState(request.getVideoState());
150 
151         synchronized (mConnectionsLock) {
152             mConnections.add(connection);
153         }
154         if (mConnectionLatch != null) {
155             mConnectionLatch.countDown();
156         }
157         return connection;
158     }
159 }
160