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.telecom.Call;
21 import android.telecom.InCallService;
22 import android.util.ArrayMap;
23 import android.util.Log;
24 
25 import java.util.ArrayList;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.concurrent.CountDownLatch;
29 
30 /**
31  * InCallService implementation which declares in its manifest that it wants to be informed of
32  * self-maanged connections.
33  */
34 public class SelfManagedAwareInCallService extends InCallService {
35 
36     public static class CallCallback extends Call.Callback {
37         public static int INVALID_STATE = -1;
38 
39         private CountDownLatch mStateChangeLatch = new CountDownLatch(1);
40         private CountDownLatch mDetailsChangeLatch = new CountDownLatch(1);
41         private int mNewState;
42 
43         @Override
onStateChanged(Call call, int state)44         public void onStateChanged(Call call, int state) {
45             mNewState = state;
46             mStateChangeLatch.countDown();
47         }
48 
49         @Override
onDetailsChanged(Call call, Call.Details details)50         public void onDetailsChanged(Call call, Call.Details details) {
51             mDetailsChangeLatch.countDown();
52         }
53 
54         @Override
onCallDestroyed(Call call)55         public void onCallDestroyed(Call call) {
56 
57         }
58 
waitOnStateChanged()59         public int waitOnStateChanged() {
60             mStateChangeLatch = TestUtils.waitForLock(mStateChangeLatch);
61             if (mStateChangeLatch != null) {
62                 return mNewState;
63             } else {
64                 mStateChangeLatch = new CountDownLatch(1);
65                 return INVALID_STATE;
66             }
67         }
68 
waitDialingState()69         public int waitDialingState() {
70             while (true) {
71                 int state = waitOnStateChanged();
72                 if (state == Call.STATE_DIALING || state == INVALID_STATE) {
73                     return state;
74                 }
75             }
76         }
77     }
78 
79     private static final String LOG_TAG="SelfMgAwareICS";
80     private static CountDownLatch sServiceBoundLatch = new CountDownLatch(1);
81     private static CountDownLatch sServiceUnBoundLatch = new CountDownLatch(1);
82     private static SelfManagedAwareInCallService sInCallService;
83 
84     private List<Call> mCalls = new ArrayList<Call>();
85     private Map<Call, CallCallback> mCallCallbacks = new ArrayMap<>();
86     private CountDownLatch mCallAddedLatch = new CountDownLatch(1);
87 
SelfManagedAwareInCallService()88     public SelfManagedAwareInCallService() throws Exception {
89         super();
90         sInCallService = this;
91     }
92 
93     @Override
onBind(android.content.Intent intent)94     public android.os.IBinder onBind(android.content.Intent intent) {
95         Log.i(LOG_TAG, "Service bound");
96 
97         sServiceBoundLatch.countDown();
98         sServiceUnBoundLatch = new CountDownLatch(1);
99         return super.onBind(intent);
100     }
101 
102     @Override
onUnbind(Intent intent)103     public boolean onUnbind(Intent intent) {
104         sServiceBoundLatch = new CountDownLatch(1);
105         sServiceUnBoundLatch.countDown();
106         return super.onUnbind(intent);
107     }
108 
tearDown()109     public void tearDown() {
110         sServiceBoundLatch = new CountDownLatch(1);
111     }
112 
113     @Override
onCallAdded(Call call)114     public void onCallAdded(Call call) {
115         super.onCallAdded(call);
116         if (!mCalls.contains(call)) {
117             mCalls.add(call);
118             CallCallback callback = new CallCallback();
119             call.registerCallback(callback);
120             mCallCallbacks.put(call, callback);
121             mCallAddedLatch.countDown();
122         }
123     }
124 
125     @Override
onCallRemoved(Call call)126     public void onCallRemoved(Call call) {
127         super.onCallRemoved(call);
128         call.unregisterCallback(mCallCallbacks.get(call));
129         mCallCallbacks.remove(call);
130         mCalls.remove(call);
131     }
132 
getInCallService()133     public static SelfManagedAwareInCallService getInCallService() {
134         return sInCallService;
135     }
136 
waitForCallAdded()137     public Call waitForCallAdded() {
138         mCallAddedLatch = TestUtils.waitForLock(mCallAddedLatch);
139         if (mCallAddedLatch != null) {
140             return mCalls.get(mCalls.size() - 1);
141         } else {
142             return null;
143         }
144     }
145 
waitForBinding()146     public static boolean waitForBinding() {
147         sServiceBoundLatch = TestUtils.waitForLock(sServiceBoundLatch);
148         return sServiceBoundLatch != null;
149     }
150 
waitForUnBinding()151     public static boolean waitForUnBinding() {
152         sServiceUnBoundLatch = TestUtils.waitForLock(sServiceUnBoundLatch);
153         return sServiceUnBoundLatch != null;
154     }
155 
getCallCallback(Call call)156     public CallCallback getCallCallback(Call call) {
157         return mCallCallbacks.get(call);
158     }
159 }
160