10b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin/*
20b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin * Copyright (C) 2014 The Android Open Source Project
30b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin *
40b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin * Licensed under the Apache License, Version 2.0 (the "License");
50b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin * you may not use this file except in compliance with the License.
60b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin * You may obtain a copy of the License at
70b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin *
80b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin *      http://www.apache.org/licenses/LICENSE-2.0
90b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin *
100b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin * Unless required by applicable law or agreed to in writing, software
110b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin * distributed under the License is distributed on an "AS IS" BASIS,
120b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin * See the License for the specific language governing permissions and
140b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin * limitations under the License.
150b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin */
160b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkinpackage android.hardware.camera2.dispatch;
170b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin
180b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin
190b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkinimport java.lang.reflect.Method;
200b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkinimport java.util.Arrays;
210b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkinimport java.util.List;
220b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin
230b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkinimport static com.android.internal.util.Preconditions.*;
240b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin
250b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin/**
260b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin * Broadcast a single dispatch into multiple other dispatchables.
270b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin *
280b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin * <p>Every time {@link #dispatch} is invoked, all the broadcast targets will
290b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin * see the same dispatch as well. The first target's return value is returned.</p>
300b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin *
310b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin * <p>This enables a single listener to be converted into a multi-listener.</p>
320b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin */
330b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkinpublic class BroadcastDispatcher<T> implements Dispatchable<T> {
340b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin
350b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin    private final List<Dispatchable<T>> mDispatchTargets;
360b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin
370b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin    /**
380b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin     * Create a broadcast dispatcher from the supplied dispatch targets.
390b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin     *
400b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin     * @param dispatchTargets one or more targets to dispatch to
410b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin     */
420b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin    @SafeVarargs
430b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin    public BroadcastDispatcher(Dispatchable<T>... dispatchTargets) {
440b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin        mDispatchTargets = Arrays.asList(
450b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin                checkNotNull(dispatchTargets, "dispatchTargets must not be null"));
460b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin    }
470b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin
480b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin    @Override
490b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin    public Object dispatch(Method method, Object[] args) throws Throwable {
500b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin        Object result = null;
510b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin        boolean gotResult = false;
520b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin
530b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin        for (Dispatchable<T> dispatchTarget : mDispatchTargets) {
540b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin            Object localResult = dispatchTarget.dispatch(method, args);
550b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin
560b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin            if (!gotResult) {
570b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin                gotResult = true;
580b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin                result = localResult;
590b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin            }
600b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin        }
610b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin
620b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin        return result;
630b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin    }
640b27d3453d5e257594792e9177c5fedb1bc6f9e9Igor Murashkin}
65