ObservableFrameServer.java revision e4e15811211d6470a6182f4a1d080b962caa9ae4
1e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall/*
2e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall * Copyright (C) 2015 The Android Open Source Project
3e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall *
4e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall * Licensed under the Apache License, Version 2.0 (the "License");
5e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall * you may not use this file except in compliance with the License.
6e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall * You may obtain a copy of the License at
7e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall *
8e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall *      http://www.apache.org/licenses/LICENSE-2.0
9e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall *
10e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall * Unless required by applicable law or agreed to in writing, software
11e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall * distributed under the License is distributed on an "AS IS" BASIS,
12e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall * See the License for the specific language governing permissions and
14e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall * limitations under the License.
15e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall */
16e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall
17e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lallpackage com.android.camera.one.v2.core;
18e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall
19e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lallimport android.hardware.camera2.CameraAccessException;
20e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall
21e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lallimport com.android.camera.async.ConcurrentState;
22e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lallimport com.android.camera.async.Observable;
23e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lallimport com.android.camera.async.SafeCloseable;
24e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lallimport com.android.camera.one.v2.camera2proxy.CameraCaptureSessionClosedException;
25e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lallimport com.android.camera.util.Callback;
26e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall
27e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lallimport java.util.List;
28e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lallimport java.util.concurrent.Executor;
29e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lallimport java.util.concurrent.atomic.AtomicBoolean;
30e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall
31e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lallimport javax.annotation.Nonnull;
32e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lallimport javax.annotation.Nullable;
33e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lallimport javax.annotation.ParametersAreNonnullByDefault;
34e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall
35e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall/**
36e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall * Decorates a {@link FrameServer} to enable listening for changes to
37e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall * availability (whether or not an exclusive session can likely be acquired
38e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall * immediately).
39e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall */
40e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall@ParametersAreNonnullByDefault
41e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lallfinal class ObservableFrameServer implements FrameServer, Observable<Boolean> {
42e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall    private final ConcurrentState<Boolean> mAvailability;
43e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall    private final FrameServer mDelegate;
44e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall
45e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall    private class SessionImpl implements Session {
46e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall        private final AtomicBoolean mClosed;
47e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall        private final Session mDelegate;
48e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall
49e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall        private SessionImpl(Session delegate) {
50e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall            mClosed = new AtomicBoolean(false);
51e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall            mDelegate = delegate;
52e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall        }
53e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall
54e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall        @Override
55e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall        public void submitRequest(List<Request> burstRequests, RequestType type)
56e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall                throws CameraAccessException, InterruptedException,
57e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall                CameraCaptureSessionClosedException, ResourceAcquisitionFailedException {
58e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall            mDelegate.submitRequest(burstRequests, type);
59e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall        }
60e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall
61e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall        @Override
62e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall        public void close() {
63e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall            if (!mClosed.getAndSet(true)) {
64e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall                mAvailability.update(true);
65e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall                mDelegate.close();
66e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall            }
67e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall        }
68e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall    }
69e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall
70e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall    public ObservableFrameServer(FrameServer delegate) {
71e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall        mDelegate = delegate;
72e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall        mAvailability = new ConcurrentState<>(true);
73e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall    }
74e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall
75e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall    @Nonnull
76e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall    @Override
77e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall    public Session createExclusiveSession() throws InterruptedException {
78e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall        Session session = mDelegate.createExclusiveSession();
79e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall        mAvailability.update(false);
80e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall        return new SessionImpl(session);
81e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall    }
82e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall
83e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall    @Nullable
84e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall    @Override
85e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall    public Session tryCreateExclusiveSession() {
86e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall        Session session = mDelegate.tryCreateExclusiveSession();
87e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall        if (session == null) {
88e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall            return null;
89e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall        } else {
90e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall            mAvailability.update(false);
91e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall            return new SessionImpl(session);
92e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall        }
93e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall    }
94e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall
95e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall    @Nonnull
96e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall    @Override
97e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall    public SafeCloseable addCallback(Runnable callback, Executor executor) {
98e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall        return mAvailability.addCallback(callback, executor);
99e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall    }
100e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall
101e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall    @Nonnull
102e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall    @Override
103e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall    public Boolean get() {
104e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall        return mAvailability.get();
105e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall    }
106e4e15811211d6470a6182f4a1d080b962caa9ae4Puneet Lall}
107