• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 android.telecom.cts;
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.DisconnectCause;
25 import android.telecom.PhoneAccountHandle;
26 import android.telecom.TelecomManager;
27 import android.util.Log;
28 
29 import androidx.annotation.Nullable;
30 
31 import java.util.ArrayList;
32 import java.util.Arrays;
33 import java.util.List;
34 import java.util.concurrent.CountDownLatch;
35 
36 /**
37  * CTS test self-managed {@link ConnectionService} implementation.
38  */
39 public class CtsSelfManagedConnectionService extends ConnectionService {
40     public static final String LOG_TAG = "CtsSMConnectionService";
41     // Constants used to address into the mLocks array.
42     public static int CONNECTION_CREATED_LOCK = 0;
43     public static int CREATE_INCOMING_CONNECTION_FAILED_LOCK = 1;
44     public static int CREATE_OUTGOING_CONNECTION_FAILED_LOCK = 2;
45     public static int HANDOVER_FAILED_LOCK = 3;
46     public static int FOCUS_GAINED_LOCK = 4;
47     public static int FOCUS_LOST_LOCK = 5;
48 
49     private static int NUM_LOCKS = FOCUS_LOST_LOCK + 1;
50     private static final String TAG = "CtsSelfManagedConnectionService";
51 
52     private static CtsSelfManagedConnectionService sConnectionService;
53 
54     // Lock used to determine when binding to CS is complete.
55     private static CountDownLatch sBindingLock = new CountDownLatch(1);
56 
57     private SelfManagedConnection.Listener mConnectionListener =
58             new SelfManagedConnection.Listener() {
59         @Override
60         void onDestroyed(SelfManagedConnection connection) {
61             mConnections.remove(connection);
62         }
63     };
64 
65     private CountDownLatch[] mLocks = new CountDownLatch[NUM_LOCKS];
66 
67     private final Object mLock = new Object();
68     private List<SelfManagedConnection> mConnections = new ArrayList<>();
69     private TestUtils.InvokeCounter mOnCreateIncomingHandoverConnectionCounter =
70             new TestUtils.InvokeCounter("incomingHandoverConnection");
71     private TestUtils.InvokeCounter mOnCreateOutgoingHandoverConnectionCounter =
72             new TestUtils.InvokeCounter("outgoingHandoverConnection");
73 
getConnectionService()74     public static CtsSelfManagedConnectionService getConnectionService() {
75         return sConnectionService;
76     }
77 
78     @Override
onBindClient(@ullable Intent intent)79     public void onBindClient(@Nullable Intent intent) {
80         Log.i(LOG_TAG, "onBindClient with intent: " + intent);
81         sConnectionService = this;
82         Arrays.setAll(mLocks, i -> new CountDownLatch(1));
83 
84         // Inform anyone waiting on binding that we're bound.
85         sBindingLock.countDown();
86     }
87 
88     @Override
onUnbind(Intent intent)89     public boolean onUnbind(Intent intent) {
90         Log.i(LOG_TAG, "onUnbind with intent: " + intent);
91         sBindingLock = new CountDownLatch(1);
92         return super.onUnbind(intent);
93     }
94 
95     @Override
onCreateOutgoingConnection(PhoneAccountHandle connectionManagerAccount, final ConnectionRequest request)96     public Connection onCreateOutgoingConnection(PhoneAccountHandle connectionManagerAccount,
97             final ConnectionRequest request) {
98 
99         return createSelfManagedConnection(request, false);
100     }
101 
102     @Override
onCreateIncomingConnection(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request)103     public Connection onCreateIncomingConnection(PhoneAccountHandle connectionManagerPhoneAccount,
104             ConnectionRequest request) {
105         return createSelfManagedConnection(request, true);
106     }
107 
108     @Override
onCreateIncomingConnectionFailed(PhoneAccountHandle connectionManagerHandle, ConnectionRequest request)109     public void onCreateIncomingConnectionFailed(PhoneAccountHandle connectionManagerHandle,
110                                                  ConnectionRequest request) {
111         mLocks[CREATE_INCOMING_CONNECTION_FAILED_LOCK].countDown();
112     }
113 
114     @Override
onCreateOutgoingConnectionFailed(PhoneAccountHandle connectionManagerHandle, ConnectionRequest request)115     public void onCreateOutgoingConnectionFailed(PhoneAccountHandle connectionManagerHandle,
116                                                  ConnectionRequest request) {
117         mLocks[CREATE_OUTGOING_CONNECTION_FAILED_LOCK].countDown();
118     }
119 
120     @Override
onCreateIncomingHandoverConnection(PhoneAccountHandle fromPhoneAccountHandle, ConnectionRequest request)121     public Connection onCreateIncomingHandoverConnection(PhoneAccountHandle fromPhoneAccountHandle,
122             ConnectionRequest request) {
123         mOnCreateIncomingHandoverConnectionCounter.invoke(fromPhoneAccountHandle, request);
124         return createSelfManagedConnection(request, true /* incoming */);
125     }
126 
127     @Override
onCreateOutgoingHandoverConnection(PhoneAccountHandle fromPhoneAccountHandle, ConnectionRequest request)128     public Connection onCreateOutgoingHandoverConnection(PhoneAccountHandle fromPhoneAccountHandle,
129             ConnectionRequest request) {
130         mOnCreateOutgoingHandoverConnectionCounter.invoke(fromPhoneAccountHandle, request);
131         return createSelfManagedConnection(request, false /* incoming */);
132     }
133 
134     @Override
onHandoverFailed(ConnectionRequest request, int error)135     public void onHandoverFailed(ConnectionRequest request, int error) {
136         mLocks[HANDOVER_FAILED_LOCK].countDown();
137     }
138 
139 
140     @Override
onConnectionServiceFocusGained()141     public void onConnectionServiceFocusGained() {
142         Log.i(TAG, "onConnectionServiceFocusGained");
143         mLocks[FOCUS_GAINED_LOCK].countDown();
144     }
145 
146     @Override
onConnectionServiceFocusLost()147     public void onConnectionServiceFocusLost() {
148         Log.i(TAG, "onConnectionServiceFocusLost");
149         mLocks[FOCUS_LOST_LOCK].countDown();
150         connectionServiceFocusReleased();
151     }
152 
tearDown()153     public void tearDown() {
154         synchronized(mLock) {
155             if (mConnections != null && mConnections.size() > 0) {
156                 Log.w(LOG_TAG, "disconnecting non-disconnected calls: " + mConnections);
157                 mConnections.forEach(connection -> {
158                             connection.setDisconnected(new DisconnectCause(DisconnectCause.LOCAL));
159                             connection.destroy();
160                         }
161                 );
162                 mConnections.clear();
163             }
164         }
165     }
166 
createSelfManagedConnection(ConnectionRequest request, boolean isIncoming)167     private Connection createSelfManagedConnection(ConnectionRequest request, boolean isIncoming) {
168         SelfManagedConnection connection = new SelfManagedConnection(isIncoming,
169                 mConnectionListener);
170         connection.setConnectionProperties(Connection.PROPERTY_SELF_MANAGED);
171         connection.setConnectionCapabilities(
172                 Connection.CAPABILITY_HOLD | Connection.CAPABILITY_SUPPORT_HOLD);
173         connection.setAddress(request.getAddress(), TelecomManager.PRESENTATION_ALLOWED);
174         connection.setExtras(request.getExtras());
175 
176         Bundle moreExtras = new Bundle();
177         moreExtras.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
178                 request.getAccountHandle());
179         connection.putExtras(moreExtras);
180         connection.setVideoState(request.getVideoState());
181 
182         if (isIncoming) {
183             connection.setRinging();
184         } else {
185             connection.setInitializing();
186         }
187 
188         synchronized(mLock) {
189             mConnections.add(connection);
190         }
191         mLocks[CONNECTION_CREATED_LOCK].countDown();
192         return connection;
193     }
194 
getConnections()195     public List<SelfManagedConnection> getConnections() {
196         synchronized(mLock) {
197             return new ArrayList<>(mConnections);
198         }
199     }
200 
201     /**
202      * Waits on a lock for maximum of 5 seconds.
203      *
204      * @param lock one of the {@code *_LOCK} constants defined above.
205      * @return {@code true} if the lock was released within the time limit, {@code false} if the
206      *      timeout expired without the lock being released.
207      */
waitForUpdate(int lock)208     public boolean waitForUpdate(int lock) {
209         mLocks[lock] = TestUtils.waitForLock(mLocks[lock]);
210         return mLocks[lock] != null;
211     }
212 
213     /**
214      * Waits for the {@link ConnectionService} to be found.
215      * @return {@code true} if binding happened within the time limit, or {@code false} otherwise.
216      */
waitForBinding()217     public static boolean waitForBinding() {
218         return TestUtils.waitForLatchCountDown(sBindingLock);
219     }
220 
getOnCreateIncomingHandoverConnectionCounter()221     public TestUtils.InvokeCounter getOnCreateIncomingHandoverConnectionCounter() {
222         return mOnCreateIncomingHandoverConnectionCounter;
223     }
224 
getOnCreateOutgoingHandoverConnectionCounter()225     public TestUtils.InvokeCounter getOnCreateOutgoingHandoverConnectionCounter() {
226         return mOnCreateOutgoingHandoverConnectionCounter;
227     }
228 }
229