1778029e5c62c414c958d2bc15e35c301a92c95cdTeng-Hui Zhu/*
2778029e5c62c414c958d2bc15e35c301a92c95cdTeng-Hui Zhu * Copyright (C) 2012 The Android Open Source Project
3778029e5c62c414c958d2bc15e35c301a92c95cdTeng-Hui Zhu *
4778029e5c62c414c958d2bc15e35c301a92c95cdTeng-Hui Zhu * Licensed under the Apache License, Version 2.0 (the "License");
5778029e5c62c414c958d2bc15e35c301a92c95cdTeng-Hui Zhu * you may not use this file except in compliance with the License.
6778029e5c62c414c958d2bc15e35c301a92c95cdTeng-Hui Zhu * You may obtain a copy of the License at
7778029e5c62c414c958d2bc15e35c301a92c95cdTeng-Hui Zhu *
8778029e5c62c414c958d2bc15e35c301a92c95cdTeng-Hui Zhu *      http://www.apache.org/licenses/LICENSE-2.0
9778029e5c62c414c958d2bc15e35c301a92c95cdTeng-Hui Zhu *
10778029e5c62c414c958d2bc15e35c301a92c95cdTeng-Hui Zhu * Unless required by applicable law or agreed to in writing, software
11778029e5c62c414c958d2bc15e35c301a92c95cdTeng-Hui Zhu * distributed under the License is distributed on an "AS IS" BASIS,
12778029e5c62c414c958d2bc15e35c301a92c95cdTeng-Hui Zhu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13778029e5c62c414c958d2bc15e35c301a92c95cdTeng-Hui Zhu * See the License for the specific language governing permissions and
14778029e5c62c414c958d2bc15e35c301a92c95cdTeng-Hui Zhu * limitations under the License.
15778029e5c62c414c958d2bc15e35c301a92c95cdTeng-Hui Zhu */
1610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
1710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhupackage android.webkit;
1810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
19fb2fd5f52c3de68ea8395eb0b5e5543e8ab26763Teng-Hui Zhuimport android.Manifest.permission;
20fb2fd5f52c3de68ea8395eb0b5e5543e8ab26763Teng-Hui Zhuimport android.content.pm.PackageManager;
2110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhuimport android.graphics.SurfaceTexture;
2210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhuimport android.webkit.HTML5VideoView;
2310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhuimport android.webkit.HTML5VideoViewProxy;
24fd8feeef498be4adf4830b8f39d55a2653ecc21bJamie Gennisimport android.view.Surface;
2510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhuimport android.opengl.GLES20;
26690ad5409000ba8a40046e29516cfd4c7612b320Teng-Hui Zhuimport android.os.PowerManager;
2710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
2810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu/**
2910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu * @hide This is only used by the browser
3010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu */
3110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhupublic class HTML5VideoInline extends HTML5VideoView{
3210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
333fafd39d0776a15c3613795183043a2c28277691Teng-Hui Zhu    // Due to the fact that the decoder consume a lot of memory, we make the
343fafd39d0776a15c3613795183043a2c28277691Teng-Hui Zhu    // surface texture as singleton. But the GL texture (m_textureNames)
353fafd39d0776a15c3613795183043a2c28277691Teng-Hui Zhu    // associated with the surface texture can be used for showing the screen
363fafd39d0776a15c3613795183043a2c28277691Teng-Hui Zhu    // shot when paused, so they are not singleton.
3710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    private static SurfaceTexture mSurfaceTexture = null;
38c2b06d5a83f8f118eaf46f093126da08a28715ebTeng-Hui Zhu    private static int[] mTextureNames = null;
393fafd39d0776a15c3613795183043a2c28277691Teng-Hui Zhu    // Every time when the VideoLayer Id change, we need to recreate the
403fafd39d0776a15c3613795183043a2c28277691Teng-Hui Zhu    // SurfaceTexture in order to delete the old video's decoder memory.
413fafd39d0776a15c3613795183043a2c28277691Teng-Hui Zhu    private static int mVideoLayerUsingSurfaceTexture = -1;
4210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
4310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    // Video control FUNCTIONS:
4410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    @Override
4510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    public void start() {
46158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu        if (!getPauseDuringPreparing()) {
47158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu            super.start();
48158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu        }
4910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    }
5010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
51c3a2858de909145a382e7932d5fb044e1388c0b3Teng-Hui Zhu    HTML5VideoInline(int videoLayerId, int position, boolean skipPrepare) {
52c3a2858de909145a382e7932d5fb044e1388c0b3Teng-Hui Zhu        init(videoLayerId, position, skipPrepare);
5310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    }
5410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
5510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    @Override
5610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    public void decideDisplayMode() {
57fd8feeef498be4adf4830b8f39d55a2653ecc21bJamie Gennis        SurfaceTexture surfaceTexture = getSurfaceTexture(getVideoLayerId());
58fd8feeef498be4adf4830b8f39d55a2653ecc21bJamie Gennis        Surface surface = new Surface(surfaceTexture);
59fd8feeef498be4adf4830b8f39d55a2653ecc21bJamie Gennis        mPlayer.setSurface(surface);
60fd8feeef498be4adf4830b8f39d55a2653ecc21bJamie Gennis        surface.release();
6110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    }
6210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
6310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    // Normally called immediately after setVideoURI. But for full screen,
6410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    // this should be after surface holder created
6510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    @Override
6610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    public void prepareDataAndDisplayMode(HTML5VideoViewProxy proxy) {
6710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        super.prepareDataAndDisplayMode(proxy);
6810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        setFrameAvailableListener(proxy);
69fb2fd5f52c3de68ea8395eb0b5e5543e8ab26763Teng-Hui Zhu        // TODO: This is a workaround, after b/5375681 fixed, we should switch
70fb2fd5f52c3de68ea8395eb0b5e5543e8ab26763Teng-Hui Zhu        // to the better way.
71fb2fd5f52c3de68ea8395eb0b5e5543e8ab26763Teng-Hui Zhu        if (mProxy.getContext().checkCallingOrSelfPermission(permission.WAKE_LOCK)
72fb2fd5f52c3de68ea8395eb0b5e5543e8ab26763Teng-Hui Zhu                == PackageManager.PERMISSION_GRANTED) {
73fb2fd5f52c3de68ea8395eb0b5e5543e8ab26763Teng-Hui Zhu            mPlayer.setWakeMode(proxy.getContext(), PowerManager.FULL_WAKE_LOCK);
74fb2fd5f52c3de68ea8395eb0b5e5543e8ab26763Teng-Hui Zhu        }
7510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    }
7610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
7710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    // Pause the play and update the play/pause button
7810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    @Override
7910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    public void pauseAndDispatch(HTML5VideoViewProxy proxy) {
8010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        super.pauseAndDispatch(proxy);
8110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    }
8210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
8310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    // Inline Video specific FUNCTIONS:
8410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
85c2b06d5a83f8f118eaf46f093126da08a28715ebTeng-Hui Zhu    public static SurfaceTexture getSurfaceTexture(int videoLayerId) {
863fafd39d0776a15c3613795183043a2c28277691Teng-Hui Zhu        // Create the surface texture.
873fafd39d0776a15c3613795183043a2c28277691Teng-Hui Zhu        if (videoLayerId != mVideoLayerUsingSurfaceTexture
881f5467338115c7e5ad1cfa54c362be86028bd6eaTeng-Hui Zhu            || mSurfaceTexture == null
891f5467338115c7e5ad1cfa54c362be86028bd6eaTeng-Hui Zhu            || mTextureNames == null) {
90c2b06d5a83f8f118eaf46f093126da08a28715ebTeng-Hui Zhu            // The GL texture will store in the VideoLayerManager at native side.
91c2b06d5a83f8f118eaf46f093126da08a28715ebTeng-Hui Zhu            // They will be clean up when requested.
92c2b06d5a83f8f118eaf46f093126da08a28715ebTeng-Hui Zhu            // The reason we recreated GL texture name is for screen shot support.
931f5467338115c7e5ad1cfa54c362be86028bd6eaTeng-Hui Zhu            mTextureNames = new int[1];
941f5467338115c7e5ad1cfa54c362be86028bd6eaTeng-Hui Zhu            GLES20.glGenTextures(1, mTextureNames, 0);
953fafd39d0776a15c3613795183043a2c28277691Teng-Hui Zhu            mSurfaceTexture = new SurfaceTexture(mTextureNames[0]);
963fafd39d0776a15c3613795183043a2c28277691Teng-Hui Zhu        }
973fafd39d0776a15c3613795183043a2c28277691Teng-Hui Zhu        mVideoLayerUsingSurfaceTexture = videoLayerId;
9810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        return mSurfaceTexture;
9910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    }
10010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
101c3a2858de909145a382e7932d5fb044e1388c0b3Teng-Hui Zhu    public static boolean surfaceTextureDeleted() {
1023fafd39d0776a15c3613795183043a2c28277691Teng-Hui Zhu        return (mSurfaceTexture == null);
1033fafd39d0776a15c3613795183043a2c28277691Teng-Hui Zhu    }
1043fafd39d0776a15c3613795183043a2c28277691Teng-Hui Zhu
10510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    @Override
10610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    public void deleteSurfaceTexture() {
107fdd646b2b105e23cdc8517ac055448340a667e37Teng-Hui Zhu        cleanupSurfaceTexture();
108fdd646b2b105e23cdc8517ac055448340a667e37Teng-Hui Zhu        return;
109fdd646b2b105e23cdc8517ac055448340a667e37Teng-Hui Zhu    }
110fdd646b2b105e23cdc8517ac055448340a667e37Teng-Hui Zhu
111fdd646b2b105e23cdc8517ac055448340a667e37Teng-Hui Zhu    public static void cleanupSurfaceTexture() {
11210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        mSurfaceTexture = null;
1133fafd39d0776a15c3613795183043a2c28277691Teng-Hui Zhu        mVideoLayerUsingSurfaceTexture = -1;
11410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        return;
11510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    }
11610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
11710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    @Override
11810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    public int getTextureName() {
1193fafd39d0776a15c3613795183043a2c28277691Teng-Hui Zhu        if (mTextureNames != null) {
1203fafd39d0776a15c3613795183043a2c28277691Teng-Hui Zhu            return mTextureNames[0];
1213fafd39d0776a15c3613795183043a2c28277691Teng-Hui Zhu        } else {
1223fafd39d0776a15c3613795183043a2c28277691Teng-Hui Zhu            return 0;
1233fafd39d0776a15c3613795183043a2c28277691Teng-Hui Zhu        }
12410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    }
12510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
12610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    private void setFrameAvailableListener(SurfaceTexture.OnFrameAvailableListener l) {
127c3a2858de909145a382e7932d5fb044e1388c0b3Teng-Hui Zhu        if (mSurfaceTexture != null) {
128c3a2858de909145a382e7932d5fb044e1388c0b3Teng-Hui Zhu            mSurfaceTexture.setOnFrameAvailableListener(l);
129c3a2858de909145a382e7932d5fb044e1388c0b3Teng-Hui Zhu        }
13010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    }
13110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
13210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu}
133