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 
17 package com.android.camera.captureintent.state;
18 
19 import com.google.common.base.Optional;
20 
21 import com.android.camera.async.RefCountBase;
22 import com.android.camera.captureintent.CaptureIntentConfig;
23 import com.android.camera.captureintent.resource.ResourceConstructed;
24 import com.android.camera.captureintent.resource.ResourceSurfaceTexture;
25 import com.android.camera.captureintent.resource.ResourceSurfaceTextureImpl;
26 import com.android.camera.captureintent.resource.ResourceSurfaceTextureNexus4Impl;
27 import com.android.camera.captureintent.stateful.EventHandler;
28 import com.android.camera.captureintent.event.EventOnSurfaceTextureAvailable;
29 import com.android.camera.captureintent.event.EventPause;
30 import com.android.camera.captureintent.stateful.State;
31 import 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  */
37 public final class StateForeground extends StateImpl {
38     private final RefCountBase<ResourceConstructed> mResourceConstructed;
39 
40     // Can be used to transition from Background on resume.
from( State previousState, RefCountBase<ResourceConstructed> resourceConstructed)41     public static StateForeground from(
42             State previousState,
43             RefCountBase<ResourceConstructed> resourceConstructed) {
44         return new StateForeground(previousState, resourceConstructed);
45     }
46 
StateForeground( State previousState, RefCountBase<ResourceConstructed> resourceConstructed)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 
registerEventHandlers()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
onEnter()97     public Optional<State> onEnter() {
98         return NO_CHANGE;
99     }
100 
101     @Override
onLeave()102     public void onLeave() {
103         mResourceConstructed.close();
104     }
105 }