1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.camera.captureintent.state;
18
19import com.google.common.base.Optional;
20
21import com.android.camera.async.RefCountBase;
22import com.android.camera.captureintent.CaptureIntentConfig;
23import com.android.camera.captureintent.resource.ResourceConstructed;
24import com.android.camera.captureintent.resource.ResourceSurfaceTexture;
25import com.android.camera.captureintent.resource.ResourceSurfaceTextureImpl;
26import com.android.camera.captureintent.resource.ResourceSurfaceTextureNexus4Impl;
27import com.android.camera.captureintent.stateful.EventHandler;
28import com.android.camera.captureintent.event.EventOnSurfaceTextureAvailable;
29import com.android.camera.captureintent.event.EventPause;
30import com.android.camera.captureintent.stateful.State;
31import com.android.camera.captureintent.stateful.StateImpl;
32
33/**
34 * Represents a state that module is active in foreground but waiting for
35 * surface texture being available.
36 */
37public final class StateForeground extends StateImpl {
38    private final RefCountBase<ResourceConstructed> mResourceConstructed;
39
40    // Can be used to transition from Background on resume.
41    public static StateForeground from(
42            State previousState,
43            RefCountBase<ResourceConstructed> resourceConstructed) {
44        return new StateForeground(previousState, resourceConstructed);
45    }
46
47    private StateForeground(
48            State previousState,
49            RefCountBase<ResourceConstructed> resourceConstructed) {
50        super(previousState);
51        mResourceConstructed = resourceConstructed;
52        mResourceConstructed.addRef();  // Will be balanced in onLeave().
53        registerEventHandlers();
54    }
55
56    private void registerEventHandlers() {
57        /** Handles EventPause. */
58        EventHandler<EventPause> pauseHandler = new EventHandler<EventPause>() {
59            @Override
60            public Optional<State> processEvent(EventPause event) {
61                return Optional.of((State) StateBackground.from(
62                        StateForeground.this, mResourceConstructed));
63            }
64        };
65        setEventHandler(EventPause.class, pauseHandler);
66
67        /** Handles EventOnSurfaceTextureAvailable */
68        EventHandler<EventOnSurfaceTextureAvailable> surfaceTextureAvailableHandler =
69                new EventHandler<EventOnSurfaceTextureAvailable>() {
70                    @Override
71                    public Optional<State> processEvent(EventOnSurfaceTextureAvailable event) {
72                        RefCountBase<ResourceSurfaceTexture> resourceSurfaceTexture;
73                        if (CaptureIntentConfig.WORKAROUND_PREVIEW_STRETCH_BUG_NEXUS4) {
74                            resourceSurfaceTexture = ResourceSurfaceTextureNexus4Impl.create(
75                                    mResourceConstructed,
76                                    event.getSurfaceTexture());
77                        } else {
78                            resourceSurfaceTexture = ResourceSurfaceTextureImpl.create(
79                                    mResourceConstructed,
80                                    event.getSurfaceTexture());
81                        }
82                        State nextState = StateForegroundWithSurfaceTexture.from(
83                                StateForeground.this,
84                                mResourceConstructed,
85                                resourceSurfaceTexture);
86                        // Release ResourceSurfaceTexture after it was handed
87                        // over to StateForegroundWithSurfaceTexture.
88                        resourceSurfaceTexture.close();
89                        return Optional.of(nextState);
90                    }
91                };
92        setEventHandler(
93                EventOnSurfaceTextureAvailable.class, surfaceTextureAvailableHandler);
94    }
95
96    @Override
97    public Optional<State> onEnter() {
98        return NO_CHANGE;
99    }
100
101    @Override
102    public void onLeave() {
103        mResourceConstructed.close();
104    }
105}