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.resource;
18
19import com.android.camera.async.RefCountBase;
20import com.android.camera.captureintent.PreviewTransformCalculator;
21import com.android.camera.util.AspectRatio;
22import com.android.camera.util.Size;
23
24import android.graphics.SurfaceTexture;
25
26import javax.annotation.ParametersAreNonnullByDefault;
27
28/**
29 * Workaround for TextureView/HAL issues in API1 / API2 Legacy Mode
30 * (b/19271661) for 16:9 preview streams on Nexus 4.
31 *
32 * This workaround for 16:9 consists of:
33 * 1) For any 16x9 resolution, the largest 4:3 preview size will be chosen for
34 *    SurfaceTexture default buffer. Noted that though the surface is 4:3, the
35 *    surface content (the preview) provided by HAL is 16:9.
36 * 2) Enable auto transform in TextureViewHelper rather than using
37 *    PreviewTransformCalculator. Since the preview content is still 16:9, we
38 *    still need to call {@link com.android.camera.TextureViewHelper#updateAspectRatio}
39 *    with 16:9 aspect ratio to get correct transform matrix.
40 */
41@ParametersAreNonnullByDefault
42public final class ResourceSurfaceTextureNexus4Impl extends ResourceSurfaceTextureImpl {
43    private static final Size LARGEST_4x3_PREVIEW_SIZE_NEXUS4 = new Size(1280, 960);
44
45    /**
46     * Creates a reference counted {@link ResourceSurfaceTextureNexus4Impl}
47     * object.
48     */
49    public static RefCountBase<ResourceSurfaceTexture> create(
50            RefCountBase<ResourceConstructed> resourceConstructed,
51            SurfaceTexture surfaceTexture) {
52        ResourceSurfaceTexture resourceSurfaceTexture = new ResourceSurfaceTextureNexus4Impl(
53                resourceConstructed,
54                surfaceTexture,
55                new PreviewTransformCalculator(resourceConstructed.get().getOrientationManager()));
56        return new RefCountBase<>(resourceSurfaceTexture);
57    }
58
59    private ResourceSurfaceTextureNexus4Impl(
60            RefCountBase<ResourceConstructed> resourceConstructed,
61            SurfaceTexture surfaceTexture,
62            PreviewTransformCalculator previewTransformCalculator) {
63        super(resourceConstructed, surfaceTexture, previewTransformCalculator);
64    }
65
66    @Override
67    public void setPreviewSize(Size previewSize) {
68        super.setPreviewSize(previewSize);
69
70        final AspectRatio previewAspectRatio = AspectRatio.of(previewSize);
71        getResourceConstructed().get().getMainThread().execute(new Runnable() {
72            @Override
73            public void run() {
74                getResourceConstructed().get().getModuleUI()
75                        .updatePreviewAspectRatio(previewAspectRatio.toFloat());
76            }
77        });
78
79        // Override the preview selection logic to the largest N4 4:3
80        // preview size but pass in 16:9 aspect ratio in
81        // updatePreviewTransform() later.
82        if (previewAspectRatio.equals(AspectRatio.of16x9())) {
83            updateSurfaceTextureDefaultBufferSize(LARGEST_4x3_PREVIEW_SIZE_NEXUS4);
84        }
85    }
86
87    @Override
88    public void updatePreviewTransform() {
89        // Override and let it be no-op since TextureViewHelper auto transform
90        // is enabled!
91    }
92}
93