package org.linphone; /* VideoCallFragment.java Copyright (C) 2012 Belledonne Communications, Grenoble, France This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ import org.linphone.core.LinphoneCore; import org.linphone.core.Log; import org.linphone.mediastream.video.AndroidVideoWindowImpl; import org.linphone.mediastream.video.capture.hwconf.AndroidCameraConfiguration; import android.annotation.TargetApi; import android.content.Context; import android.opengl.GLSurfaceView; import android.os.Bundle; import android.os.PowerManager; import android.os.PowerManager.WakeLock; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.View.OnTouchListener; import android.view.ViewGroup; /** * @author Sylvain Berfini */ @TargetApi(5) public class VideoCallFragment extends Fragment { private static VideoCallFragment instance; private WakeLock mWakeLock; private SurfaceView mVideoView; private SurfaceView mCaptureView; private AndroidVideoWindowImpl androidVideoWindowImpl; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { instance = this; View view = inflater.inflate(R.layout.video, container, false); mVideoView = (SurfaceView) view.findViewById(R.id.videoSurface); mCaptureView = (SurfaceView) view.findViewById(R.id.videoCaptureSurface); mCaptureView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); // Warning useless because value is ignored and automatically set by new APIs. /* force surfaces Z ordering */ fixZOrder(mVideoView, mCaptureView); androidVideoWindowImpl = new AndroidVideoWindowImpl(mVideoView, mCaptureView); androidVideoWindowImpl.setListener(new AndroidVideoWindowImpl.VideoWindowListener() { public void onVideoRenderingSurfaceReady(AndroidVideoWindowImpl vw, SurfaceView surface) { LinphoneManager.getLc().setVideoWindow(vw); mVideoView = surface; } public void onVideoRenderingSurfaceDestroyed(AndroidVideoWindowImpl vw) { Log.d("VIDEO WINDOW destroyed!\n"); LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); if (lc != null) { lc.setVideoWindow(null); } } public void onVideoPreviewSurfaceReady(AndroidVideoWindowImpl vw, SurfaceView surface) { mCaptureView = surface; LinphoneManager.getLc().setPreviewWindow(mCaptureView); } public void onVideoPreviewSurfaceDestroyed(AndroidVideoWindowImpl vw) { // Remove references kept in jni code and restart camera LinphoneManager.getLc().setPreviewWindow(null); } }); androidVideoWindowImpl.init(); PowerManager pm = (PowerManager) getActivity().getSystemService(Context.POWER_SERVICE); mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, Log.TAG); mVideoView.setOnTouchListener(new OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { InCallActivity.instance().displayVideoCallControlsIfHidden(); return false; } }); return view; } /** * @return null if not ready yet */ public static VideoCallFragment instance() { return instance; } private void fixZOrder(SurfaceView video, SurfaceView preview) { video.setZOrderOnTop(false); preview.setZOrderOnTop(true); preview.setZOrderMediaOverlay(true); // Needed to be able to display control layout over } public void switchCamera() { try { int videoDeviceId = LinphoneManager.getLc().getVideoDevice(); videoDeviceId = (videoDeviceId + 1) % AndroidCameraConfiguration.retrieveCameras().length; LinphoneManager.getLc().setVideoDevice(videoDeviceId); CallManager.getInstance().updateCall(); // previous call will cause graph reconstruction -> regive preview // window if (mCaptureView != null) { LinphoneManager.getLc().setPreviewWindow(mCaptureView); } } catch (ArithmeticException ae) { Log.e("Cannot swtich camera : no camera"); } } @Override public void onResume() { super.onResume(); if (mVideoView != null) ((GLSurfaceView) mVideoView).onResume(); if (androidVideoWindowImpl != null) { synchronized (androidVideoWindowImpl) { LinphoneManager.getLc().setVideoWindow(androidVideoWindowImpl); } } mWakeLock.acquire(); } @Override public void onDestroy() { if (androidVideoWindowImpl != null) { // Prevent linphone from crashing if correspondent hang up while you are rotating androidVideoWindowImpl.release(); } instance = null; super.onDestroy(); } @Override public void onPause() { synchronized (androidVideoWindowImpl) { /* * this call will destroy native opengl renderer which is used by * androidVideoWindowImpl */ LinphoneManager.getLc().setVideoWindow(null); } if (mWakeLock.isHeld()) mWakeLock.release(); super.onPause(); if (mVideoView != null) ((GLSurfaceView) mVideoView).onPause(); } }