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 package android.car.test.util; 17 18 import android.annotation.Nullable; 19 import android.os.Bundle; 20 import android.util.Log; 21 22 import com.android.internal.os.IResultReceiver; 23 import com.android.internal.util.Preconditions; 24 25 import java.util.concurrent.CountDownLatch; 26 import java.util.concurrent.TimeUnit; 27 28 /** 29 * Implementation of {@link IResultReceiver} that blocks waiting for the result. 30 */ 31 public final class BlockingResultReceiver extends IResultReceiver.Stub { 32 33 private static final String TAG = BlockingResultReceiver.class.getSimpleName(); 34 35 private final CountDownLatch mLatch = new CountDownLatch(1); 36 private final long mTimeoutMs; 37 38 private int mResultCode; 39 @Nullable private Bundle mResultData; 40 41 /** 42 * Default constructor. 43 * 44 * @param timeoutMs how long to wait for before failing. 45 */ BlockingResultReceiver(long timeoutMs)46 public BlockingResultReceiver(long timeoutMs) { 47 mTimeoutMs = timeoutMs; 48 } 49 50 @Override send(int resultCode, Bundle resultData)51 public void send(int resultCode, Bundle resultData) { 52 Log.d(TAG, "send() received: code=" + resultCode + ", data=" + resultData + ", count=" 53 + mLatch.getCount()); 54 Preconditions.checkState(mLatch.getCount() == 1, 55 "send() already called (code=" + mResultCode + ", data=" + mResultData); 56 mResultCode = resultCode; 57 mResultData = resultData; 58 mLatch.countDown(); 59 } 60 assertCalled()61 private void assertCalled() throws InterruptedException { 62 boolean called = mLatch.await(mTimeoutMs, TimeUnit.MILLISECONDS); 63 Log.d(TAG, "assertCalled(): " + called); 64 Preconditions.checkState(called, "receiver not called in " + mTimeoutMs + " ms"); 65 } 66 67 /** 68 * Gets the {@code resultCode} or fails if it times out before {@code send()} is called. 69 */ getResultCode()70 public int getResultCode() throws InterruptedException { 71 assertCalled(); 72 return mResultCode; 73 } 74 75 /** 76 * Gets the {@code resultData} or fails if it times out before {@code send()} is called. 77 */ 78 @Nullable getResultData()79 public Bundle getResultData() throws InterruptedException { 80 assertCalled(); 81 return mResultData; 82 } 83 } 84