1 /*
2  * Copyright (C) 2023 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.car.test;
18 
19 import android.annotation.NonNull;
20 import android.car.hardware.property.CarPropertyManager;
21 
22 import com.android.internal.annotations.GuardedBy;
23 
24 import java.util.ArrayList;
25 import java.util.List;
26 import java.util.Set;
27 import java.util.concurrent.CountDownLatch;
28 import java.util.concurrent.TimeUnit;
29 
30 public final class TestPropertyAsyncCallback implements CarPropertyManager.GetPropertyCallback,
31         CarPropertyManager.SetPropertyCallback {
32     private final int mNumberOfRequests;
33     private final CountDownLatch mCountDownLatch;
34     private final Set<Integer> mPendingRequests;
35     private final Object mLock = new Object();
36     @GuardedBy("mLock")
37     private final List<String> mTestErrors = new ArrayList<>();
38     @GuardedBy("mLock")
39     private final List<CarPropertyManager.GetPropertyResult<?>> mGetResultList =
40             new ArrayList<>();
41     @GuardedBy("mLock")
42     private final List<CarPropertyManager.SetPropertyResult> mSetResultList = new ArrayList<>();
43     @GuardedBy("mLock")
44     private final List<CarPropertyManager.PropertyAsyncError> mErrorList = new ArrayList<>();
45 
TestPropertyAsyncCallback(Set<Integer> pendingRequests)46     public TestPropertyAsyncCallback(Set<Integer> pendingRequests) {
47         mNumberOfRequests = pendingRequests.size();
48         mCountDownLatch = new CountDownLatch(mNumberOfRequests);
49         mPendingRequests = pendingRequests;
50     }
51 
52     @Override
onSuccess(@onNull CarPropertyManager.GetPropertyResult<?> getPropertyResult)53     public void onSuccess(@NonNull CarPropertyManager.GetPropertyResult<?> getPropertyResult) {
54         int requestId = getPropertyResult.getRequestId();
55         synchronized (mLock) {
56             if (!mPendingRequests.contains(requestId)) {
57                 mTestErrors.add("Request ID: " + requestId + " not present");
58                 return;
59             } else {
60                 mGetResultList.add(getPropertyResult);
61                 mPendingRequests.remove(Integer.valueOf(requestId));
62             }
63         }
64         mCountDownLatch.countDown();
65     }
66 
67     @Override
onSuccess(@onNull CarPropertyManager.SetPropertyResult setPropertyResult)68     public void onSuccess(@NonNull CarPropertyManager.SetPropertyResult setPropertyResult) {
69         int requestId = setPropertyResult.getRequestId();
70         synchronized (mLock) {
71             if (!mPendingRequests.contains(requestId)) {
72                 mTestErrors.add("Request ID: " + requestId + " not present");
73                 return;
74             } else {
75                 mSetResultList.add(setPropertyResult);
76                 mPendingRequests.remove(Integer.valueOf(requestId));
77             }
78         }
79         mCountDownLatch.countDown();
80     }
81 
82     @Override
onFailure(@onNull CarPropertyManager.PropertyAsyncError propertyAsyncError)83     public void onFailure(@NonNull CarPropertyManager.PropertyAsyncError propertyAsyncError) {
84         int requestId = propertyAsyncError.getRequestId();
85         synchronized (mLock) {
86             if (!mPendingRequests.contains(requestId)) {
87                 mTestErrors.add("Request ID: " + requestId + " not present");
88                 return;
89             } else {
90                 mErrorList.add(propertyAsyncError);
91                 mPendingRequests.remove(Integer.valueOf(requestId));
92             }
93         }
94         mCountDownLatch.countDown();
95     }
96 
waitAndFinish(int timeoutInMs)97     public void waitAndFinish(int timeoutInMs) throws InterruptedException {
98         boolean res = mCountDownLatch.await(timeoutInMs, TimeUnit.MILLISECONDS);
99         synchronized (mLock) {
100             if (!res) {
101                 int gotRequestsCount = mNumberOfRequests - mPendingRequests.size();
102                 mTestErrors.add(
103                         "Not enough responses received before timeout "
104                                 + "(" + timeoutInMs
105                                 + "ms), expected " + mNumberOfRequests + " responses, got "
106                                 + gotRequestsCount);
107             }
108         }
109     }
110 
getTestErrors()111     public List<String> getTestErrors() {
112         synchronized (mLock) {
113             return new ArrayList<>(mTestErrors);
114         }
115     }
116 
getGetResultList()117     public List<CarPropertyManager.GetPropertyResult<?>> getGetResultList() {
118         synchronized (mLock) {
119             return new ArrayList<>(mGetResultList);
120         }
121     }
122 
getSetResultList()123     public List<CarPropertyManager.SetPropertyResult> getSetResultList() {
124         synchronized (mLock) {
125             return new ArrayList<>(mSetResultList);
126         }
127     }
128 
getErrorList()129     public List<CarPropertyManager.PropertyAsyncError> getErrorList() {
130         synchronized (mLock) {
131             return new ArrayList<>(mErrorList);
132         }
133     }
134 }
135