1/*
2 * Copyright (C) 2012 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 android.webkit;
18
19import android.Manifest.permission;
20import android.content.pm.PackageManager;
21import android.graphics.SurfaceTexture;
22import android.webkit.HTML5VideoView;
23import android.webkit.HTML5VideoViewProxy;
24import android.view.Surface;
25import android.opengl.GLES20;
26import android.os.PowerManager;
27
28/**
29 * @hide This is only used by the browser
30 */
31public class HTML5VideoInline extends HTML5VideoView{
32
33    // Due to the fact that the decoder consume a lot of memory, we make the
34    // surface texture as singleton. But the GL texture (m_textureNames)
35    // associated with the surface texture can be used for showing the screen
36    // shot when paused, so they are not singleton.
37    private static SurfaceTexture mSurfaceTexture = null;
38    private static int[] mTextureNames = null;
39    // Every time when the VideoLayer Id change, we need to recreate the
40    // SurfaceTexture in order to delete the old video's decoder memory.
41    private static int mVideoLayerUsingSurfaceTexture = -1;
42
43    // Video control FUNCTIONS:
44    @Override
45    public void start() {
46        if (!getPauseDuringPreparing()) {
47            super.start();
48        }
49    }
50
51    HTML5VideoInline(int videoLayerId, int position, boolean skipPrepare) {
52        init(videoLayerId, position, skipPrepare);
53    }
54
55    @Override
56    public void decideDisplayMode() {
57        SurfaceTexture surfaceTexture = getSurfaceTexture(getVideoLayerId());
58        Surface surface = new Surface(surfaceTexture);
59        mPlayer.setSurface(surface);
60        surface.release();
61    }
62
63    // Normally called immediately after setVideoURI. But for full screen,
64    // this should be after surface holder created
65    @Override
66    public void prepareDataAndDisplayMode(HTML5VideoViewProxy proxy) {
67        super.prepareDataAndDisplayMode(proxy);
68        setFrameAvailableListener(proxy);
69        // TODO: This is a workaround, after b/5375681 fixed, we should switch
70        // to the better way.
71        if (mProxy.getContext().checkCallingOrSelfPermission(permission.WAKE_LOCK)
72                == PackageManager.PERMISSION_GRANTED) {
73            mPlayer.setWakeMode(proxy.getContext(), PowerManager.FULL_WAKE_LOCK);
74        }
75    }
76
77    // Pause the play and update the play/pause button
78    @Override
79    public void pauseAndDispatch(HTML5VideoViewProxy proxy) {
80        super.pauseAndDispatch(proxy);
81    }
82
83    // Inline Video specific FUNCTIONS:
84
85    public static SurfaceTexture getSurfaceTexture(int videoLayerId) {
86        // Create the surface texture.
87        if (videoLayerId != mVideoLayerUsingSurfaceTexture
88            || mSurfaceTexture == null
89            || mTextureNames == null) {
90            // The GL texture will store in the VideoLayerManager at native side.
91            // They will be clean up when requested.
92            // The reason we recreated GL texture name is for screen shot support.
93            mTextureNames = new int[1];
94            GLES20.glGenTextures(1, mTextureNames, 0);
95            mSurfaceTexture = new SurfaceTexture(mTextureNames[0]);
96        }
97        mVideoLayerUsingSurfaceTexture = videoLayerId;
98        return mSurfaceTexture;
99    }
100
101    public static boolean surfaceTextureDeleted() {
102        return (mSurfaceTexture == null);
103    }
104
105    @Override
106    public void deleteSurfaceTexture() {
107        cleanupSurfaceTexture();
108        return;
109    }
110
111    public static void cleanupSurfaceTexture() {
112        mSurfaceTexture = null;
113        mVideoLayerUsingSurfaceTexture = -1;
114        return;
115    }
116
117    @Override
118    public int getTextureName() {
119        if (mTextureNames != null) {
120            return mTextureNames[0];
121        } else {
122            return 0;
123        }
124    }
125
126    private void setFrameAvailableListener(SurfaceTexture.OnFrameAvailableListener l) {
127        if (mSurfaceTexture != null) {
128            mSurfaceTexture.setOnFrameAvailableListener(l);
129        }
130    }
131
132}
133