How to render a protected egl surface to external screen of an android phone

499 views Asked by At

I hava an android phone with type-c port and it can connect to an external display. I want to use Opengles to render some drm content to the external display , so I create protected EGLContext and EGLSurface with "EGL_PROTECTED_CONTENT_EXT" flag . It works fine on the phone screen, but it can not work on the connected external display.

add logcat files :

no protected surface: https://drive.google.com/file/d/14Dmj1flVXqb8tCqUgS8hcwz58pTbmDqv/view?usp=sharing

protected surface: https://drive.google.com/file/d/15p3lmy1siZ5uSVUcDzu7trX7u5a7E8ti/view?usp=sharing

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.app.Presentation;
import android.hardware.display.DisplayManager;
import android.opengl.EGL14;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.text.Layout;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.Toast;

import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.egl.EGLSurface;
import javax.microedition.khronos.opengles.GL10;

public class MainActivity extends AppCompatActivity  {
    private static String TAG = "MainActivity";
    Presentation presentation;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        showPresentation(true);
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    @Override
    protected void onPause() {
        super.onPause();
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    private static final int EGL_PROTECTED_CONTENT_EXT = 0x32C0;
    private void showPresentation(boolean requireSecureContext){
        Log.d(TAG, "begin showPresentation " + requireSecureContext);
        DisplayManager displayManager = (DisplayManager) getSystemService(DISPLAY_SERVICE);
        Display displays[] = displayManager.getDisplays();
        if(displays.length == 1){
            Toast.makeText(this, "can not find external display", Toast.LENGTH_LONG);
            return;
        }
        Log.d(TAG, "showPresentation at displayID:" + displays[displays.length-1].getDisplayId());

        presentation = new Presentation(this, displays[displays.length-1]);
        GLSurfaceView surfaceView = new GLSurfaceView(this);
        surfaceView.setSecure(true);
        surfaceView.setEGLContextClientVersion(2);
        surfaceView.setEGLConfigChooser(8, 8, 8, 8, 8, 0);
        surfaceView.setEGLContextClientVersion(3);
        surfaceView.setKeepScreenOn(true);

        surfaceView.setEGLContextFactory(
                new GLSurfaceView.EGLContextFactory() {
                    @Override
                    public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
                        int[] glAttributes;
                        if (requireSecureContext) {
                            glAttributes =
                                    new int[] {
                                            EGL14.EGL_CONTEXT_CLIENT_VERSION,
                                            3,
                                            EGL_PROTECTED_CONTENT_EXT,
                                            EGL14.EGL_TRUE,
                                            EGL10.EGL_NONE
                                    };
                        } else {
                            glAttributes = new int[] {EGL14.EGL_CONTEXT_CLIENT_VERSION, 3, EGL10.EGL_NONE};
                        }
                        return egl.eglCreateContext(
                                display, eglConfig, /* share_context= */ EGL10.EGL_NO_CONTEXT, glAttributes);
                    }

                    @Override
                    public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
                        egl.eglDestroyContext(display, context);
                    }
                });
        surfaceView.setEGLWindowSurfaceFactory(
                new GLSurfaceView.EGLWindowSurfaceFactory() {
                    @Override
                    public EGLSurface createWindowSurface(
                            EGL10 egl, EGLDisplay display, EGLConfig config, Object nativeWindow) {
                        int[] attribsList =
                                requireSecureContext
                                        ? new int[] {EGL_PROTECTED_CONTENT_EXT, EGL14.EGL_TRUE, EGL10.EGL_NONE}
                                        : new int[] {EGL10.EGL_NONE};
                        return egl.eglCreateWindowSurface(display, config, nativeWindow, attribsList);
                    }

                    @Override
                    public void destroySurface(EGL10 egl, EGLDisplay display, EGLSurface surface) {
                        egl.eglDestroySurface(display, surface);
                    }
                });

        surfaceView.setRenderer(new GLSurfaceView.Renderer() {
            @Override
            public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {

            }

            @Override
            public void onSurfaceChanged(GL10 gl10, int i, int i1) {

            }

            @Override
            public void onDrawFrame(GL10 gl10) {
                GLES20.glClearColor(1.f, 0.f,0.f,1.f);
                GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
            }
        });

        surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(@NonNull SurfaceHolder surfaceHolder) {
            }

            @Override
            public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int i, int i1, int i2) {

            }

            @Override
            public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {

            }
        });

        presentation.setContentView(surfaceView);

        presentation.show();
        presentation.getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
        Log.d(TAG, "showPresentation end");
    }
}
0

There are 0 answers