1 /*
2  * Copyright (C) 2020 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.telephony.ims.cts;
18 
19 import static org.junit.Assert.fail;
20 
21 import android.telephony.ims.DelegateMessageCallback;
22 import android.telephony.ims.DelegateRequest;
23 import android.telephony.ims.DelegateStateCallback;
24 import android.telephony.ims.stub.SipDelegate;
25 import android.telephony.ims.stub.SipTransportImplBase;
26 import android.util.Log;
27 
28 import androidx.annotation.NonNull;
29 
30 import java.util.ArrayList;
31 import java.util.List;
32 import java.util.concurrent.CountDownLatch;
33 import java.util.concurrent.Executor;
34 import java.util.concurrent.TimeUnit;
35 
36 public class TestSipTransport extends SipTransportImplBase {
37 
38     private static final String TAG = "TestSipTransport";
39     public static final String ONE_TO_ONE_CHAT_TAG =
40             "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gppservice.ims.icsi.oma.cpm.msg\"";
41     public static final String GROUP_CHAT_TAG =
42             "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gppservice.ims.icsi.oma.cpm.session\"";
43     public static final String FILE_TRANSFER_HTTP_TAG =
44             "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gppapplication.ims.iari.rcs.fthttp\"";
45 
46     public static final int LATCH_CREATE_DELEGATE = 0;
47     public static final int LATCH_DESTROY_DELEGATE = 1;
48     private static final int LATCH_MAX = 2;
49     protected static final CountDownLatch[] sLatches = new CountDownLatch[LATCH_MAX];
50     static {
51         for (int i = 0; i < LATCH_MAX; i++) {
52             sLatches[i] = new CountDownLatch(1);
53         }
54     }
55 
56     private final ArrayList<TestSipDelegate> mDelegates = new ArrayList<>();
57     private final Object mLock = new Object();
58 
TestSipTransport()59     public TestSipTransport() {
60         Log.d(TAG, "TestSipTransport with default constructor");
61     }
62 
TestSipTransport(Executor executor)63     public TestSipTransport(Executor executor) {
64         super(executor);
65         Log.d(TAG, "TestSipTransport with Executor constructor");
66     }
67 
68     @Override
createSipDelegate(int subscriptionId, @NonNull DelegateRequest request, @NonNull DelegateStateCallback dc, @NonNull DelegateMessageCallback mc)69     public void createSipDelegate(int subscriptionId, @NonNull DelegateRequest request,
70             @NonNull DelegateStateCallback dc, @NonNull DelegateMessageCallback mc) {
71         TestSipDelegate d = new TestSipDelegate(subscriptionId, request, dc, mc);
72         synchronized (mLock) {
73             mDelegates.add(d);
74         }
75         countDownLatch(LATCH_CREATE_DELEGATE);
76     }
77 
78     @Override
destroySipDelegate(@onNull SipDelegate delegate, int reason)79     public void destroySipDelegate(@NonNull SipDelegate delegate, int reason) {
80         if (delegate instanceof TestSipDelegate) {
81             synchronized (mLock) {
82                 mDelegates.remove(delegate);
83             }
84             countDownLatch(LATCH_DESTROY_DELEGATE);
85         } else {
86             fail("unknown delegate passed in!");
87         }
88     }
89 
getDelegates()90     public List<TestSipDelegate> getDelegates() {
91         synchronized (mLock) {
92             return mDelegates;
93         }
94     }
95 
getDelegate(DelegateRequest request)96     public TestSipDelegate getDelegate(DelegateRequest request) {
97         synchronized (mLock) {
98             return mDelegates.stream().filter((d) -> d.delegateRequest.equals(request))
99                     .findFirst().orElse(null);
100         }
101     }
102 
isLatchCountDownFinished(int latchIndex)103     public boolean isLatchCountDownFinished(int latchIndex) {
104         CountDownLatch latch;
105         synchronized (mLock) {
106             latch = sLatches[latchIndex];
107         }
108         return latch.getCount() <= 0;
109     }
110 
waitForLatchCountdownAndReset(int latchIndex)111     public boolean waitForLatchCountdownAndReset(int latchIndex) {
112         boolean complete = false;
113         try {
114             CountDownLatch latch;
115             synchronized (mLock) {
116                 latch = sLatches[latchIndex];
117             }
118             complete = latch.await(ImsUtils.TEST_TIMEOUT_MS, TimeUnit.MILLISECONDS);
119         } catch (InterruptedException e) {
120             // complete == false
121         }
122         synchronized (mLock) {
123             sLatches[latchIndex] = new CountDownLatch(1);
124         }
125         return complete;
126     }
127 
countDownLatch(int latchIndex)128     private void countDownLatch(int latchIndex) {
129         synchronized (mLock) {
130             sLatches[latchIndex].countDown();
131         }
132     }
133 }
134