blob: 4812fa6097db90a9959b50d17032bf3b39e2d64b [file] [log] [blame]
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.server.wm.backgroundactivity.common;
import static com.google.common.base.Preconditions.checkState;
import android.os.Bundle;
import android.os.ConditionVariable;
import android.os.Handler;
import android.os.Looper;
import android.os.ResultReceiver;
import android.server.wm.backgroundactivity.common.CommonComponents.Event;
import java.util.concurrent.TimeoutException;
/**
* Class used to register for events sent via IPC using {@link #getNotifier()} parcelable.
*
* Create an instance for the event of interest, pass {@link #getNotifier()} to the target, either
* via some AIDL or intent extra, have the caller call {@link ResultReceiver#send(int, Bundle)},
* then finally wait for the event with {@link #waitForEventOrThrow(long)}.
*/
public class EventReceiver {
private final Handler mHandler = new Handler(Looper.getMainLooper());
private final ConditionVariable mEventReceivedVariable = new ConditionVariable(false);
@Event
private final int mEvent;
public EventReceiver(@Event int event) {
mEvent = event;
}
public ResultReceiver getNotifier() {
return new ResultReceiver(mHandler) {
@Override
protected void onReceiveResult(@Event int event, Bundle data) {
if (event == mEvent) {
mEventReceivedVariable.open();
}
}
};
}
/**
* Waits for registered event or throws {@link TimeoutException}.
*/
public void waitForEventOrThrow(long timeoutMs) throws TimeoutException {
// Avoid deadlocks
checkState(Thread.currentThread() != mHandler.getLooper().getThread());
if (!mEventReceivedVariable.block(timeoutMs)) {
throw new TimeoutException("Timed out waiting for event " + mEvent);
}
}
}