11d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde/*
21d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde * Copyright (C) 2015 The Android Open Source Project
31d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde *
41d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde * Licensed under the Apache License, Version 2.0 (the "License");
51d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde * you may not use this file except in compliance with the License.
61d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde * You may obtain a copy of the License at
71d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde *
81d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde *      http://www.apache.org/licenses/LICENSE-2.0
91d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde *
101d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde * Unless required by applicable law or agreed to in writing, software
111d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde * distributed under the License is distributed on an "AS IS" BASIS,
121d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde * See the License for the specific language governing permissions and
141d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde * limitations under the License.
151d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde */
161d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde
171d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdepackage com.android.camera.device;
181d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde
191d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.debug.Log;
201d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.debug.Log.Tag;
211d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.google.common.annotations.VisibleForTesting;
221d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde
231d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport javax.annotation.ParametersAreNonnullByDefault;
241d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport javax.annotation.concurrent.GuardedBy;
251d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde
261d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde/**
271d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde * Shared object for tracking the active camera device across multiple
281d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde * implementations.
291d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde */
301d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde@ParametersAreNonnullByDefault
311d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdepublic class ActiveCameraDeviceTracker {
321d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde    private static final Tag TAG = new Tag("ActvCamDevTrckr");
331d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde
341d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde    /**
351d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde     * Singleton instance.
361d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde     */
371d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde    private static class Singleton {
381d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde        public static final ActiveCameraDeviceTracker INSTANCE = new ActiveCameraDeviceTracker();
391d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde    }
401d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde
411d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde    public static ActiveCameraDeviceTracker instance() {
421d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde        return Singleton.INSTANCE;
431d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde    }
441d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde
451d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde    private final Object mLock;
461d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde
471d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde    @GuardedBy("mLock")
481d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde    private CameraId mActiveCamera;
491d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde
501d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde    @GuardedBy("mLock")
511d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde    private CameraId mPreviousCamera;
521d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde
531d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde    @VisibleForTesting
541d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde    ActiveCameraDeviceTracker() {
551d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde        mLock = new Object();
561d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde    }
571d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde
581d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde    public CameraId getActiveCamera() {
591d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde        synchronized (mLock) {
601d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde            return mActiveCamera;
611d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde        }
621d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde    }
631d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde
641d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde    public CameraId getActiveOrPreviousCamera() {
651d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde        synchronized (mLock) {
661d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde            if (mActiveCamera != null) {
671d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde
681d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde                return mActiveCamera;
691d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde            }
701d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde            Log.v(TAG, "Returning previously active camera: " + mPreviousCamera);
711d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde            return mPreviousCamera;
721d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde        }
731d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde    }
741d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde
751d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde    public void onCameraOpening(CameraId key) {
761d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde        synchronized (mLock) {
771d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde            if (mActiveCamera != null && !mActiveCamera.equals(key)) {
781d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde                mPreviousCamera = mActiveCamera;
791d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde            }
801d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde
811d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde            Log.v(TAG, "Tracking active camera: " + mActiveCamera);
821d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde            mActiveCamera = key;
831d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde        }
841d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde    }
851d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde
861d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde    public void onCameraClosed(CameraId key) {
871d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde        synchronized (mLock) {
881d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde            if (mActiveCamera != null && mActiveCamera.equals(key)) {
891d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde                mPreviousCamera = mActiveCamera;
901d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde                mActiveCamera = null;
911d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde            }
921d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde        }
931d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde    }
941d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde}
95