public final class

UseCaseAttachState

extends java.lang.Object

 java.lang.Object

↳androidx.camera.core.impl.UseCaseAttachState

Gradle dependencies

compile group: 'androidx.camera', name: 'camera-core', version: '1.5.0-alpha01'

  • groupId: androidx.camera
  • artifactId: camera-core
  • version: 1.5.0-alpha01

Artifact androidx.camera:camera-core:1.5.0-alpha01 it located at Google repository (https://maven.google.com/)

Overview

Collection of use cases which are attached to a specific camera.

This class tracks the current state of activity for each use case. There are two states that the use case can be in: attached and active. Attached means the use case is currently ready for the camera capture, but not currently capturing. Active means the use case is either currently issuing a capture request or one has already been issued.

Summary

Constructors
publicUseCaseAttachState(java.lang.String cameraId)

Constructs an instance of the attach state which corresponds to the named camera.

Methods
public SessionConfig.ValidatingBuildergetActiveAndAttachedBuilder()

Returns a session configuration builder for use cases which are both active and attached.

public java.util.Collection<SessionConfig>getActiveAndAttachedSessionConfigs()

public SessionConfig.ValidatingBuildergetAttachedBuilder()

Returns a session configuration builder for use cases which are attached.

public java.util.Collection<SessionConfig>getAttachedSessionConfigs()

public java.util.Collection<UseCaseConfig>getAttachedUseCaseConfigs()

public java.util.Collection<UseCaseAttachState.UseCaseAttachInfo>getAttachedUseCaseInfo()

public booleanisUseCaseAttached(java.lang.String useCaseId)

Returns if the use case is attached or not.

public voidremoveUseCase(java.lang.String useCaseId)

Removes the item from the map.

public voidsetUseCaseActive(java.lang.String useCaseId, SessionConfig sessionConfig, UseCaseConfig<UseCase> useCaseConfig, StreamSpec streamSpec, java.util.List<UseCaseConfigFactory.CaptureType> captureTypes)

Sets the use case to an active state.

public voidsetUseCaseAttached(java.lang.String useCaseId, SessionConfig sessionConfig, UseCaseConfig<UseCase> useCaseConfig, StreamSpec streamSpec, java.util.List<UseCaseConfigFactory.CaptureType> captureTypes)

Sets the use case to an attached state.

public voidsetUseCaseDetached(java.lang.String useCaseId)

Sets the use case to an detached state.

public voidsetUseCaseInactive(java.lang.String useCaseId)

Sets the use case to an inactive state.

public voidupdateUseCase(java.lang.String useCaseId, SessionConfig sessionConfig, UseCaseConfig<UseCase> useCaseConfig, StreamSpec streamSpec, java.util.List<UseCaseConfigFactory.CaptureType> captureTypes)

Updates the session configuration for a use case.

from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Constructors

public UseCaseAttachState(java.lang.String cameraId)

Constructs an instance of the attach state which corresponds to the named camera.

Methods

public void setUseCaseActive(java.lang.String useCaseId, SessionConfig sessionConfig, UseCaseConfig<UseCase> useCaseConfig, StreamSpec streamSpec, java.util.List<UseCaseConfigFactory.CaptureType> captureTypes)

Sets the use case to an active state.

Adds the use case to the collection if not already in it.

public void setUseCaseInactive(java.lang.String useCaseId)

Sets the use case to an inactive state.

Removes the use case from the collection if also offline.

public void setUseCaseAttached(java.lang.String useCaseId, SessionConfig sessionConfig, UseCaseConfig<UseCase> useCaseConfig, StreamSpec streamSpec, java.util.List<UseCaseConfigFactory.CaptureType> captureTypes)

Sets the use case to an attached state.

Adds the use case to the collection if not already in it.

public void setUseCaseDetached(java.lang.String useCaseId)

Sets the use case to an detached state.

Removes the use case from the collection if also inactive.

public boolean isUseCaseAttached(java.lang.String useCaseId)

Returns if the use case is attached or not.

public java.util.Collection<UseCaseConfig> getAttachedUseCaseConfigs()

public java.util.Collection<SessionConfig> getAttachedSessionConfigs()

public java.util.Collection<UseCaseAttachState.UseCaseAttachInfo> getAttachedUseCaseInfo()

public java.util.Collection<SessionConfig> getActiveAndAttachedSessionConfigs()

public void updateUseCase(java.lang.String useCaseId, SessionConfig sessionConfig, UseCaseConfig<UseCase> useCaseConfig, StreamSpec streamSpec, java.util.List<UseCaseConfigFactory.CaptureType> captureTypes)

Updates the session configuration for a use case.

If the use case is not already in the collection, nothing is done.

public void removeUseCase(java.lang.String useCaseId)

Removes the item from the map.

public SessionConfig.ValidatingBuilder getActiveAndAttachedBuilder()

Returns a session configuration builder for use cases which are both active and attached.

public SessionConfig.ValidatingBuilder getAttachedBuilder()

Returns a session configuration builder for use cases which are attached.

Source

/*
 * Copyright 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 androidx.camera.core.impl;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.camera.core.Logger;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * Collection of use cases which are attached to a specific camera.
 *
 * <p>This class tracks the current state of activity for each use case. There are two states that
 * the use case can be in: attached and active. Attached means the use case is currently ready for
 * the camera capture, but not currently capturing. Active means the use case is either currently
 * issuing a capture request or one has already been issued.
 */
public final class UseCaseAttachState {
    private static final String TAG = "UseCaseAttachState";
    /** The name of the camera the use cases are attached to. */
    private final String mCameraId;
    /** A map of the use cases to the corresponding state information. */
    // Use LinkedHashMap to retain the attached order for bug fixing and unit testing.
    private final Map<String, UseCaseAttachInfo> mAttachedUseCasesToInfoMap = new LinkedHashMap<>();

    /** Constructs an instance of the attach state which corresponds to the named camera. */
    public UseCaseAttachState(@NonNull String cameraId) {
        mCameraId = cameraId;
    }

    /**
     * Sets the use case to an active state.
     *
     * <p>Adds the use case to the collection if not already in it.
     */
    public void setUseCaseActive(
            @NonNull String useCaseId,
            @NonNull SessionConfig sessionConfig,
            @NonNull UseCaseConfig<?> useCaseConfig,
            @Nullable StreamSpec streamSpec,
            @Nullable List<UseCaseConfigFactory.CaptureType> captureTypes) {
        UseCaseAttachInfo useCaseAttachInfo = getOrCreateUseCaseAttachInfo(useCaseId,
                sessionConfig, useCaseConfig, streamSpec, captureTypes);
        useCaseAttachInfo.setActive(true);
    }

    /**
     * Sets the use case to an inactive state.
     *
     * <p>Removes the use case from the collection if also offline.
     */
    public void setUseCaseInactive(@NonNull String useCaseId) {
        if (!mAttachedUseCasesToInfoMap.containsKey(useCaseId)) {
            return;
        }

        UseCaseAttachInfo useCaseAttachInfo = mAttachedUseCasesToInfoMap.get(useCaseId);
        useCaseAttachInfo.setActive(false);
        if (!useCaseAttachInfo.getAttached()) {
            mAttachedUseCasesToInfoMap.remove(useCaseId);
        }
    }

    /**
     * Sets the use case to an attached state.
     *
     * <p>Adds the use case to the collection if not already in it.
     */
    public void setUseCaseAttached(@NonNull String useCaseId,
            @NonNull SessionConfig sessionConfig,
            @NonNull UseCaseConfig<?> useCaseConfig,
            @Nullable StreamSpec streamSpec,
            @Nullable List<UseCaseConfigFactory.CaptureType> captureTypes) {
        UseCaseAttachInfo useCaseAttachInfo = getOrCreateUseCaseAttachInfo(useCaseId,
                sessionConfig, useCaseConfig, streamSpec, captureTypes);
        useCaseAttachInfo.setAttached(true);

        // use case may become active before being attached, some info may have changed after
        // the active state notification
        updateUseCase(useCaseId, sessionConfig, useCaseConfig, streamSpec, captureTypes);
    }

    /**
     * Sets the use case to an detached state.
     *
     * <p>Removes the use case from the collection if also inactive.
     */
    public void setUseCaseDetached(@NonNull String useCaseId) {
        if (!mAttachedUseCasesToInfoMap.containsKey(useCaseId)) {
            return;
        }
        UseCaseAttachInfo useCaseAttachInfo = mAttachedUseCasesToInfoMap.get(useCaseId);
        useCaseAttachInfo.setAttached(false);
        if (!useCaseAttachInfo.getActive()) {
            mAttachedUseCasesToInfoMap.remove(useCaseId);
        }
    }

    /** Returns if the use case is attached or not. */
    public boolean isUseCaseAttached(@NonNull String useCaseId) {
        if (!mAttachedUseCasesToInfoMap.containsKey(useCaseId)) {
            return false;
        }

        UseCaseAttachInfo useCaseAttachInfo = mAttachedUseCasesToInfoMap.get(useCaseId);
        return useCaseAttachInfo.getAttached();
    }

    @NonNull
    public Collection<UseCaseConfig<?>> getAttachedUseCaseConfigs() {
        return Collections.unmodifiableCollection(
                getUseCaseConfigs((useCaseAttachInfo) -> useCaseAttachInfo.getAttached()));
    }

    @NonNull
    public Collection<SessionConfig> getAttachedSessionConfigs() {
        return Collections.unmodifiableCollection(
                getSessionConfigs((useCaseAttachInfo) -> useCaseAttachInfo.getAttached()));
    }

    @NonNull
    public Collection<UseCaseAttachInfo> getAttachedUseCaseInfo() {
        return Collections.unmodifiableCollection(
                getUseCaseInfo((useCaseAttachInfo) -> useCaseAttachInfo.getAttached()));
    }

    @NonNull
    public Collection<SessionConfig> getActiveAndAttachedSessionConfigs() {
        return Collections.unmodifiableCollection(
                getSessionConfigs((useCaseAttachInfo) ->
                        useCaseAttachInfo.getActive() && useCaseAttachInfo.getAttached()));
    }

    /**
     * Updates the session configuration for a use case.
     *
     * <p>If the use case is not already in the collection, nothing is done.
     */
    public void updateUseCase(
            @NonNull String useCaseId,
            @NonNull SessionConfig sessionConfig,
            @NonNull UseCaseConfig<?> useCaseConfig,
            @Nullable StreamSpec streamSpec,
            @Nullable List<UseCaseConfigFactory.CaptureType> captureTypes) {
        if (!mAttachedUseCasesToInfoMap.containsKey(useCaseId)) {
            return;
        }

        // Rebuild the attach info from scratch to get the updated SessionConfig.
        UseCaseAttachInfo newUseCaseAttachInfo =
                new UseCaseAttachInfo(sessionConfig, useCaseConfig, streamSpec, captureTypes);

        // Retain the attached and active flags.
        UseCaseAttachInfo oldUseCaseAttachInfo = mAttachedUseCasesToInfoMap.get(useCaseId);
        newUseCaseAttachInfo.setAttached(oldUseCaseAttachInfo.getAttached());
        newUseCaseAttachInfo.setActive(oldUseCaseAttachInfo.getActive());
        mAttachedUseCasesToInfoMap.put(useCaseId, newUseCaseAttachInfo);
    }

    /**
     * Removes the item from the map.
     */
    public void removeUseCase(@NonNull String useCaseId) {
        mAttachedUseCasesToInfoMap.remove(useCaseId);
    }

    /** Returns a session configuration builder for use cases which are both active and attached. */
    @NonNull
    public SessionConfig.ValidatingBuilder getActiveAndAttachedBuilder() {
        SessionConfig.ValidatingBuilder validatingBuilder = new SessionConfig.ValidatingBuilder();

        List<String> list = new ArrayList<>();
        for (Map.Entry<String, UseCaseAttachInfo> attachedUseCase :
                mAttachedUseCasesToInfoMap.entrySet()) {
            UseCaseAttachInfo useCaseAttachInfo = attachedUseCase.getValue();
            if (useCaseAttachInfo.getActive() && useCaseAttachInfo.getAttached()) {
                String useCaseId = attachedUseCase.getKey();
                validatingBuilder.add(useCaseAttachInfo.getSessionConfig());
                list.add(useCaseId);
            }
        }
        Logger.d(TAG, "Active and attached use case: " + list + " for camera: " + mCameraId);
        return validatingBuilder;
    }

    /** Returns a session configuration builder for use cases which are attached. */
    @NonNull
    public SessionConfig.ValidatingBuilder getAttachedBuilder() {
        SessionConfig.ValidatingBuilder validatingBuilder = new SessionConfig.ValidatingBuilder();
        List<String> list = new ArrayList<>();
        for (Map.Entry<String, UseCaseAttachInfo> attachedUseCase :
                mAttachedUseCasesToInfoMap.entrySet()) {
            UseCaseAttachInfo useCaseAttachInfo = attachedUseCase.getValue();
            if (useCaseAttachInfo.getAttached()) {
                validatingBuilder.add(useCaseAttachInfo.getSessionConfig());
                String useCaseId = attachedUseCase.getKey();
                list.add(useCaseId);
            }
        }
        Logger.d(TAG, "All use case: " + list + " for camera: " + mCameraId);
        return validatingBuilder;
    }

    private UseCaseAttachInfo getOrCreateUseCaseAttachInfo(
            @NonNull String useCaseId,
            @NonNull SessionConfig sessionConfig,
            @NonNull UseCaseConfig<?> useCaseConfig,
            @Nullable StreamSpec streamSpec,
            @Nullable List<UseCaseConfigFactory.CaptureType> captureTypes) {
        UseCaseAttachInfo useCaseAttachInfo = mAttachedUseCasesToInfoMap.get(useCaseId);
        if (useCaseAttachInfo == null) {
            useCaseAttachInfo = new UseCaseAttachInfo(sessionConfig, useCaseConfig, streamSpec,
                    captureTypes);
            mAttachedUseCasesToInfoMap.put(useCaseId, useCaseAttachInfo);
        }
        return useCaseAttachInfo;
    }

    private Collection<SessionConfig> getSessionConfigs(AttachStateFilter attachStateFilter) {
        List<SessionConfig> sessionConfigs = new ArrayList<>();
        for (Map.Entry<String, UseCaseAttachInfo> attachedUseCase :
                mAttachedUseCasesToInfoMap.entrySet()) {
            if (attachStateFilter == null || attachStateFilter.filter(attachedUseCase.getValue())) {
                sessionConfigs.add(attachedUseCase.getValue().getSessionConfig());
            }
        }
        return sessionConfigs;
    }

    private Collection<UseCaseConfig<?>> getUseCaseConfigs(AttachStateFilter attachStateFilter) {
        List<UseCaseConfig<?>> useCaseConfigs = new ArrayList<>();
        for (Map.Entry<String, UseCaseAttachInfo> attachedUseCase :
                mAttachedUseCasesToInfoMap.entrySet()) {
            if (attachStateFilter == null || attachStateFilter.filter(attachedUseCase.getValue())) {
                useCaseConfigs.add(attachedUseCase.getValue().getUseCaseConfig());
            }
        }
        return useCaseConfigs;
    }

    private Collection<UseCaseAttachInfo> getUseCaseInfo(AttachStateFilter attachStateFilter) {
        List<UseCaseAttachInfo> useCaseAttachInfo = new ArrayList<>();
        for (Map.Entry<String, UseCaseAttachInfo> attachedUseCase :
                mAttachedUseCasesToInfoMap.entrySet()) {
            if (attachStateFilter == null || attachStateFilter.filter(attachedUseCase.getValue())) {
                useCaseAttachInfo.add(attachedUseCase.getValue());
            }
        }
        return useCaseAttachInfo;
    }

    private interface AttachStateFilter {
        boolean filter(UseCaseAttachInfo attachInfo);
    }

    /** The set of state and configuration information for an attached use case. */
    public static final class UseCaseAttachInfo {
        /** The configurations required of the camera for the use case. */
        @NonNull
        private final SessionConfig mSessionConfig;

        @NonNull
        private final UseCaseConfig<?> mUseCaseConfig;

        @Nullable
        private final StreamSpec mStreamSpec;

        @Nullable
        private final List<UseCaseConfigFactory.CaptureType> mCaptureTypes;

        /**
         * True if the use case is currently attached (i.e. camera should have a capture session
         * configured for it).
         */
        private boolean mAttached = false;

        /**
         * True if the use case is currently active (i.e. camera should be issuing capture requests
         * for it).
         */
        private boolean mActive = false;

        UseCaseAttachInfo(@NonNull SessionConfig sessionConfig,
                @NonNull UseCaseConfig<?> useCaseConfig,
                @Nullable StreamSpec streamSpec,
                @Nullable List<UseCaseConfigFactory.CaptureType> captureTypes) {
            mSessionConfig = sessionConfig;
            mUseCaseConfig = useCaseConfig;
            mStreamSpec = streamSpec;
            mCaptureTypes = captureTypes;
        }

        @NonNull
        public UseCaseConfig<?> getUseCaseConfig() {
            return mUseCaseConfig;
        }

        @NonNull
        public SessionConfig getSessionConfig() {
            return mSessionConfig;
        }

        @Nullable
        public StreamSpec getStreamSpec() {
            return mStreamSpec;
        }

        @Nullable
        public List<UseCaseConfigFactory.CaptureType> getCaptureTypes() {
            return mCaptureTypes;
        }

        boolean getAttached() {
            return mAttached;
        }

        void setAttached(boolean attached) {
            mAttached = attached;
        }

        boolean getActive() {
            return mActive;
        }

        void setActive(boolean active) {
            mActive = active;
        }

        @SuppressWarnings("ObjectToString")
        @NonNull
        @Override
        public String toString() {
            return "UseCaseAttachInfo{" + "mSessionConfig=" + mSessionConfig + ", mUseCaseConfig="
                    + mUseCaseConfig + ", mStreamSpec=" + mStreamSpec + ", mCaptureTypes="
                    + mCaptureTypes + ", mAttached=" + mAttached + ", mActive=" + mActive + '}';
        }
    }
}