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.resource;
18 
19 import com.android.camera.async.MainThread;
20 import com.android.camera.async.RefCountBase;
21 import com.android.camera.captureintent.PreviewTransformCalculator;
22 import com.android.camera.debug.Log;
23 import com.android.camera.util.Size;
24 
25 import android.graphics.Matrix;
26 import android.graphics.SurfaceTexture;
27 import android.view.Surface;
28 
29 import javax.annotation.ParametersAreNonnullByDefault;
30 
31 @ParametersAreNonnullByDefault
32 public class ResourceSurfaceTextureImpl implements ResourceSurfaceTexture {
33     private static final Log.Tag TAG = new Log.Tag("ResSurfaceTexture");
34 
35     private final RefCountBase<ResourceConstructed> mResourceConstructed;
36 
37     /** The surface texture. */
38     private final SurfaceTexture mSurfaceTexture;
39 
40     /** The preview stream size. */
41     private Size mPreviewSize;
42 
43     /** The preview layout size. */
44     private Size mPreviewLayoutSize;
45 
46     /** The default buffer size in SurfaceTexture. */
47     private Size mSurfaceTextureDefaultBufferSize;
48 
49     private final PreviewTransformCalculator mPreviewTransformCalculator;
50 
51     /**
52      * Creates a reference counted {@link ResourceSurfaceTextureImpl} object.
53      */
create( RefCountBase<ResourceConstructed> resourceConstructed, SurfaceTexture surfaceTexture)54     public static RefCountBase<ResourceSurfaceTexture> create(
55             RefCountBase<ResourceConstructed> resourceConstructed,
56             SurfaceTexture surfaceTexture) {
57         ResourceSurfaceTexture resourceSurfaceTexture = new ResourceSurfaceTextureImpl(
58                 resourceConstructed,
59                 surfaceTexture,
60                 new PreviewTransformCalculator(resourceConstructed.get().getOrientationManager()));
61         return new RefCountBase<>(resourceSurfaceTexture);
62     }
63 
ResourceSurfaceTextureImpl( RefCountBase<ResourceConstructed> resourceConstructed, SurfaceTexture surfaceTexture, PreviewTransformCalculator previewTransformCalculator)64     protected ResourceSurfaceTextureImpl(
65             RefCountBase<ResourceConstructed> resourceConstructed,
66             SurfaceTexture surfaceTexture,
67             PreviewTransformCalculator previewTransformCalculator) {
68         mResourceConstructed = resourceConstructed;
69         mResourceConstructed.addRef();
70         mSurfaceTexture = surfaceTexture;
71         mPreviewTransformCalculator = previewTransformCalculator;
72         mPreviewSize = new Size(0, 0);
73         mPreviewLayoutSize = new Size(0, 0);
74         mSurfaceTextureDefaultBufferSize = new Size(0, 0);
75     }
76 
getResourceConstructed()77     public RefCountBase<ResourceConstructed> getResourceConstructed() {
78         return mResourceConstructed;
79     }
80 
81     @Override
createPreviewSurface()82     public Surface createPreviewSurface() {
83         return new Surface(mSurfaceTexture);
84     }
85 
86     @Override
getPreviewSize()87     public Size getPreviewSize() {
88         return mPreviewSize;
89     }
90 
91     @Override
getPreviewLayoutSize()92     public Size getPreviewLayoutSize() {
93         return mPreviewLayoutSize;
94     }
95 
96     @Override
setPreviewSize(Size previewSize)97     public void setPreviewSize(Size previewSize) {
98         // Update preview transform when preview stream size is changed.
99         if (!mPreviewSize.equals(previewSize)) {
100             mPreviewSize = previewSize;
101 
102             /**
103              * Update transform here since preview size might change when
104              * switching between back and front camera.
105              */
106             mResourceConstructed.get().getMainThread().execute(new Runnable() {
107                 @Override
108                 public void run() {
109                     updatePreviewTransform();
110                 }
111             });
112         }
113 
114         // Update surface texture's default buffer size. See b/17286155.
115         mSurfaceTexture.setDefaultBufferSize(mPreviewSize.width(), mPreviewSize.height());
116     }
117 
118     @Override
setPreviewLayoutSize(Size previewLayoutSize)119     public void setPreviewLayoutSize(Size previewLayoutSize) {
120         MainThread.checkMainThread();
121 
122         // Update preview transform when preview layout size is changed.
123         if (!mPreviewLayoutSize.equals(previewLayoutSize)) {
124             mPreviewLayoutSize = previewLayoutSize;
125             updatePreviewTransform();
126         }
127     }
128 
129     /**
130      * Updates the default buffer size in SurfaceTexture with the configured
131      * preview stream size.
132      */
updateSurfaceTextureDefaultBufferSize(Size defaultBufferSize)133     protected void updateSurfaceTextureDefaultBufferSize(Size defaultBufferSize) {
134         mSurfaceTexture.setDefaultBufferSize(defaultBufferSize.width(), defaultBufferSize.height());
135     }
136 
137     @Override
updatePreviewTransform()138     public void updatePreviewTransform() {
139         MainThread.checkMainThread();
140         if (mPreviewSize.getWidth() == 0 || mPreviewSize.getHeight() == 0) {
141             Log.w(TAG, "Do nothing since mPreviewSize is 0");
142             return;
143         }
144         if (mPreviewLayoutSize.getWidth() == 0 || mPreviewLayoutSize.getHeight() == 0) {
145             Log.w(TAG, "Do nothing since mPreviewLayoutSize is 0");
146             return;
147         }
148 
149         Matrix transformMatrix = mPreviewTransformCalculator.toTransformMatrix(
150                 mPreviewLayoutSize, mPreviewSize);
151         mResourceConstructed.get().getModuleUI().updatePreviewTransform(transformMatrix);
152     }
153 
154     @Override
close()155     public void close() {
156         mResourceConstructed.close();
157     }
158 }
159