From e333e5a58a43ff456e839505ebb77c1245c82e90 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 14 Dec 2018 17:00:19 +0100 Subject: [PATCH] Split video overlay into 2 classes --- .../java/org/linphone/LinphoneService.java | 15 +- .../views/LinphoneGL2JNIViewOverlay.java | 182 ++++++++++++++++++ .../org/linphone/views/LinphoneOverlay.java | 149 +------------- .../views/LinphoneTextureViewOverlay.java | 158 +++++++++++++++ 4 files changed, 357 insertions(+), 147 deletions(-) create mode 100644 app/src/main/java/org/linphone/views/LinphoneGL2JNIViewOverlay.java create mode 100644 app/src/main/java/org/linphone/views/LinphoneTextureViewOverlay.java diff --git a/app/src/main/java/org/linphone/LinphoneService.java b/app/src/main/java/org/linphone/LinphoneService.java index da79ce4d4..1169f0dda 100644 --- a/app/src/main/java/org/linphone/LinphoneService.java +++ b/app/src/main/java/org/linphone/LinphoneService.java @@ -52,7 +52,9 @@ import org.linphone.receivers.BluetoothManager; import org.linphone.receivers.KeepAliveReceiver; import org.linphone.settings.LinphonePreferences; import org.linphone.utils.LinphoneUtils; +import org.linphone.views.LinphoneGL2JNIViewOverlay; import org.linphone.views.LinphoneOverlay; +import org.linphone.views.LinphoneTextureViewOverlay; /** * Linphone service, reacting to Incoming calls, ...
@@ -290,19 +292,24 @@ public final class LinphoneService extends Service { public void createOverlay() { if (mOverlay != null) destroyOverlay(); - Call call = LinphoneManager.getLc().getCurrentCall(); + Core core = LinphoneManager.getLc(); + Call call = core.getCurrentCall(); if (call == null || !call.getCurrentParams().videoEnabled()) return; - mOverlay = new LinphoneOverlay(this); + if ("MSAndroidOpenGLDisplay".equals(core.getVideoDisplayFilter())) { + mOverlay = new LinphoneGL2JNIViewOverlay(this); + } else { + mOverlay = new LinphoneTextureViewOverlay(this); + } WindowManager.LayoutParams params = mOverlay.getWindowManagerLayoutParams(); params.x = 0; params.y = 0; - mWindowManager.addView(mOverlay, params); + mOverlay.addToWindowManager(mWindowManager, params); } public void destroyOverlay() { if (mOverlay != null) { - mWindowManager.removeViewImmediate(mOverlay); + mOverlay.removeFromWindowManager(mWindowManager); mOverlay.destroy(); } mOverlay = null; diff --git a/app/src/main/java/org/linphone/views/LinphoneGL2JNIViewOverlay.java b/app/src/main/java/org/linphone/views/LinphoneGL2JNIViewOverlay.java new file mode 100644 index 000000000..bb9deb774 --- /dev/null +++ b/app/src/main/java/org/linphone/views/LinphoneGL2JNIViewOverlay.java @@ -0,0 +1,182 @@ +package org.linphone.views; + +/* +LinphoneGL2JNIViewOverlay.java +Copyright (C) 2017 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +import android.content.Context; +import android.content.Intent; +import android.graphics.PixelFormat; +import android.os.Build; +import android.util.AttributeSet; +import android.util.DisplayMetrics; +import android.view.Gravity; +import android.view.MotionEvent; +import android.view.SurfaceView; +import android.view.View; +import android.view.WindowManager; +import org.linphone.LinphoneActivity; +import org.linphone.LinphoneManager; +import org.linphone.LinphoneService; +import org.linphone.core.Call; +import org.linphone.core.CallParams; +import org.linphone.mediastream.Version; +import org.linphone.mediastream.video.AndroidVideoWindowImpl; + +public class LinphoneGL2JNIViewOverlay extends org.linphone.mediastream.video.display.GL2JNIView + implements LinphoneOverlay { + private final WindowManager mWindowManager; + private final WindowManager.LayoutParams mParams; + private final DisplayMetrics mMetrics; + private float mX, mY, mTouchX, mTouchY; + private boolean mDragEnabled; + private final AndroidVideoWindowImpl mAndroidVideoWindowImpl; + + public LinphoneGL2JNIViewOverlay(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs); + mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + + int LAYOUT_FLAG; + if (Build.VERSION.SDK_INT >= Version.API26_O_80) { + LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; + } else { + LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_PHONE; + } + + mParams = + new WindowManager.LayoutParams( + WindowManager.LayoutParams.WRAP_CONTENT, + WindowManager.LayoutParams.WRAP_CONTENT, + LAYOUT_FLAG, + WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, + PixelFormat.TRANSLUCENT); + mParams.gravity = Gravity.TOP | Gravity.LEFT; + mMetrics = new DisplayMetrics(); + mWindowManager.getDefaultDisplay().getMetrics(mMetrics); + + mAndroidVideoWindowImpl = + new AndroidVideoWindowImpl( + this, + null, + new AndroidVideoWindowImpl.VideoWindowListener() { + public void onVideoRenderingSurfaceReady( + AndroidVideoWindowImpl vw, SurfaceView surface) { + LinphoneManager.getLc().setNativeVideoWindowId(vw); + } + + public void onVideoRenderingSurfaceDestroyed( + AndroidVideoWindowImpl vw) {} + + public void onVideoPreviewSurfaceReady( + AndroidVideoWindowImpl vw, SurfaceView surface) {} + + public void onVideoPreviewSurfaceDestroyed(AndroidVideoWindowImpl vw) {} + }); + + Call call = LinphoneManager.getLc().getCurrentCall(); + CallParams callParams = call.getCurrentParams(); + mParams.width = callParams.getReceivedVideoDefinition().getWidth(); + mParams.height = callParams.getReceivedVideoDefinition().getHeight(); + LinphoneManager.getLc().setNativeVideoWindowId(mAndroidVideoWindowImpl); + + setOnClickListener( + new OnClickListener() { + @Override + public void onClick(View v) { + Context context = LinphoneService.instance(); + Intent intent = + new Intent(context, LinphoneActivity.class) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + } + }); + setOnLongClickListener( + new OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + mDragEnabled = true; + return true; + } + }); + } + + public LinphoneGL2JNIViewOverlay(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public LinphoneGL2JNIViewOverlay(Context context) { + this(context, null); + } + + @Override + public void destroy() { + mAndroidVideoWindowImpl.release(); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + mX = event.getRawX(); + mY = event.getRawY(); + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + mTouchX = event.getX(); + mTouchY = event.getY(); + break; + case MotionEvent.ACTION_MOVE: + if (mDragEnabled) { + updateViewPostion(); + } + break; + case MotionEvent.ACTION_CANCEL: + case MotionEvent.ACTION_UP: + mTouchX = mTouchY = 0; + mDragEnabled = false; + break; + default: + break; + } + return super.onTouchEvent(event); + } + + private void updateViewPostion() { + mParams.x = + Math.min( + Math.max(0, (int) (mX - mTouchX)), + mMetrics.widthPixels - getMeasuredWidth()); + mParams.y = + Math.min( + Math.max(0, (int) (mY - mTouchY)), + mMetrics.heightPixels - getMeasuredHeight()); + mWindowManager.updateViewLayout(this, mParams); + } + + @Override + public WindowManager.LayoutParams getWindowManagerLayoutParams() { + return mParams; + } + + @Override + public void addToWindowManager(WindowManager windowManager, WindowManager.LayoutParams params) { + windowManager.addView(this, params); + } + + @Override + public void removeFromWindowManager(WindowManager windowManager) { + windowManager.removeViewImmediate(this); + } +} diff --git a/app/src/main/java/org/linphone/views/LinphoneOverlay.java b/app/src/main/java/org/linphone/views/LinphoneOverlay.java index 4fc54b3cf..ff946c38e 100644 --- a/app/src/main/java/org/linphone/views/LinphoneOverlay.java +++ b/app/src/main/java/org/linphone/views/LinphoneOverlay.java @@ -2,7 +2,7 @@ package org.linphone.views; /* LinphoneOverlay.java -Copyright (C) 2017 Belledonne Communications, Grenoble, France +Copyright (C) 2018 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 @@ -19,151 +19,14 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import android.content.Context; -import android.content.Intent; -import android.graphics.PixelFormat; -import android.os.Build; -import android.util.AttributeSet; -import android.util.DisplayMetrics; -import android.view.Gravity; -import android.view.MotionEvent; -import android.view.SurfaceView; -import android.view.View; import android.view.WindowManager; -import org.linphone.LinphoneActivity; -import org.linphone.LinphoneManager; -import org.linphone.LinphoneService; -import org.linphone.core.Call; -import org.linphone.core.CallParams; -import org.linphone.mediastream.Version; -import org.linphone.mediastream.video.AndroidVideoWindowImpl; -public class LinphoneOverlay extends org.linphone.mediastream.video.display.GL2JNIView { - private final WindowManager mWindowManager; - private final WindowManager.LayoutParams mParams; - private final DisplayMetrics mMetrics; - private float mX, mY, mTouchX, mTouchY; - private boolean mDragEnabled; - private final AndroidVideoWindowImpl mAndroidVideoWindowImpl; +public interface LinphoneOverlay { + WindowManager.LayoutParams getWindowManagerLayoutParams(); - public LinphoneOverlay(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs); - mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + void addToWindowManager(WindowManager mWindowManager, WindowManager.LayoutParams params); - int LAYOUT_FLAG; - if (Build.VERSION.SDK_INT >= Version.API26_O_80) { - LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; - } else { - LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_PHONE; - } + void removeFromWindowManager(WindowManager mWindowManager); - mParams = - new WindowManager.LayoutParams( - WindowManager.LayoutParams.WRAP_CONTENT, - WindowManager.LayoutParams.WRAP_CONTENT, - LAYOUT_FLAG, - WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, - PixelFormat.TRANSLUCENT); - mParams.gravity = Gravity.TOP | Gravity.LEFT; - mMetrics = new DisplayMetrics(); - mWindowManager.getDefaultDisplay().getMetrics(mMetrics); - - mAndroidVideoWindowImpl = - new AndroidVideoWindowImpl( - this, - null, - new AndroidVideoWindowImpl.VideoWindowListener() { - public void onVideoRenderingSurfaceReady( - AndroidVideoWindowImpl vw, SurfaceView surface) { - LinphoneManager.getLc().setNativeVideoWindowId(vw); - } - - public void onVideoRenderingSurfaceDestroyed( - AndroidVideoWindowImpl vw) {} - - public void onVideoPreviewSurfaceReady( - AndroidVideoWindowImpl vw, SurfaceView surface) {} - - public void onVideoPreviewSurfaceDestroyed(AndroidVideoWindowImpl vw) {} - }); - - Call call = LinphoneManager.getLc().getCurrentCall(); - CallParams callParams = call.getCurrentParams(); - mParams.width = callParams.getReceivedVideoDefinition().getWidth(); - mParams.height = callParams.getReceivedVideoDefinition().getHeight(); - LinphoneManager.getLc().setNativeVideoWindowId(mAndroidVideoWindowImpl); - - setOnClickListener( - new OnClickListener() { - @Override - public void onClick(View v) { - Context context = LinphoneService.instance(); - Intent intent = - new Intent(context, LinphoneActivity.class) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - context.startActivity(intent); - } - }); - setOnLongClickListener( - new OnLongClickListener() { - @Override - public boolean onLongClick(View v) { - mDragEnabled = true; - return true; - } - }); - } - - public LinphoneOverlay(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public LinphoneOverlay(Context context) { - this(context, null); - } - - public void destroy() { - mAndroidVideoWindowImpl.release(); - } - - @Override - public boolean onTouchEvent(MotionEvent event) { - mX = event.getRawX(); - mY = event.getRawY(); - switch (event.getAction()) { - case MotionEvent.ACTION_DOWN: - mTouchX = event.getX(); - mTouchY = event.getY(); - break; - case MotionEvent.ACTION_MOVE: - if (mDragEnabled) { - updateViewPostion(); - } - break; - case MotionEvent.ACTION_CANCEL: - case MotionEvent.ACTION_UP: - mTouchX = mTouchY = 0; - mDragEnabled = false; - break; - default: - break; - } - return super.onTouchEvent(event); - } - - private void updateViewPostion() { - mParams.x = - Math.min( - Math.max(0, (int) (mX - mTouchX)), - mMetrics.widthPixels - getMeasuredWidth()); - mParams.y = - Math.min( - Math.max(0, (int) (mY - mTouchY)), - mMetrics.heightPixels - getMeasuredHeight()); - mWindowManager.updateViewLayout(this, mParams); - } - - public WindowManager.LayoutParams getWindowManagerLayoutParams() { - return mParams; - } + void destroy(); } diff --git a/app/src/main/java/org/linphone/views/LinphoneTextureViewOverlay.java b/app/src/main/java/org/linphone/views/LinphoneTextureViewOverlay.java new file mode 100644 index 000000000..dc9ecb2ed --- /dev/null +++ b/app/src/main/java/org/linphone/views/LinphoneTextureViewOverlay.java @@ -0,0 +1,158 @@ +package org.linphone.views; + +/* +LinphoneTextureViewOverlay.java +Copyright (C) 2018 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +import android.content.Context; +import android.content.Intent; +import android.graphics.PixelFormat; +import android.os.Build; +import android.util.AttributeSet; +import android.util.DisplayMetrics; +import android.view.Gravity; +import android.view.MotionEvent; +import android.view.TextureView; +import android.view.View; +import android.view.WindowManager; +import org.linphone.LinphoneActivity; +import org.linphone.LinphoneManager; +import org.linphone.LinphoneService; +import org.linphone.core.Call; +import org.linphone.core.CallParams; +import org.linphone.mediastream.Version; + +public class LinphoneTextureViewOverlay extends TextureView implements LinphoneOverlay { + private final WindowManager mWindowManager; + private final WindowManager.LayoutParams mParams; + private final DisplayMetrics mMetrics; + private float mX, mY, mTouchX, mTouchY; + private boolean mDragEnabled; + + public LinphoneTextureViewOverlay(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs); + mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + + int LAYOUT_FLAG; + if (Build.VERSION.SDK_INT >= Version.API26_O_80) { + LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; + } else { + LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_PHONE; + } + + mParams = + new WindowManager.LayoutParams( + WindowManager.LayoutParams.WRAP_CONTENT, + WindowManager.LayoutParams.WRAP_CONTENT, + LAYOUT_FLAG, + WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, + PixelFormat.TRANSLUCENT); + mParams.gravity = Gravity.TOP | Gravity.LEFT; + mMetrics = new DisplayMetrics(); + mWindowManager.getDefaultDisplay().getMetrics(mMetrics); + + Call call = LinphoneManager.getLc().getCurrentCall(); + CallParams callParams = call.getCurrentParams(); + mParams.width = callParams.getReceivedVideoDefinition().getWidth(); + mParams.height = callParams.getReceivedVideoDefinition().getHeight(); + LinphoneManager.getLc().setNativeVideoWindowId(this); + + setOnClickListener( + new OnClickListener() { + @Override + public void onClick(View v) { + Context context = LinphoneService.instance(); + Intent intent = + new Intent(context, LinphoneActivity.class) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + } + }); + setOnLongClickListener( + new OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + mDragEnabled = true; + return true; + } + }); + } + + public LinphoneTextureViewOverlay(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public LinphoneTextureViewOverlay(Context context) { + this(context, null); + } + + @Override + public void destroy() {} + + @Override + public boolean onTouchEvent(MotionEvent event) { + mX = event.getRawX(); + mY = event.getRawY(); + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + mTouchX = event.getX(); + mTouchY = event.getY(); + break; + case MotionEvent.ACTION_MOVE: + if (mDragEnabled) { + updateViewPostion(); + } + break; + case MotionEvent.ACTION_CANCEL: + case MotionEvent.ACTION_UP: + mTouchX = mTouchY = 0; + mDragEnabled = false; + break; + default: + break; + } + return super.onTouchEvent(event); + } + + private void updateViewPostion() { + mParams.x = + Math.min( + Math.max(0, (int) (mX - mTouchX)), + mMetrics.widthPixels - getMeasuredWidth()); + mParams.y = + Math.min( + Math.max(0, (int) (mY - mTouchY)), + mMetrics.heightPixels - getMeasuredHeight()); + mWindowManager.updateViewLayout(this, mParams); + } + + @Override + public WindowManager.LayoutParams getWindowManagerLayoutParams() { + return mParams; + } + + @Override + public void addToWindowManager(WindowManager windowManager, WindowManager.LayoutParams params) { + windowManager.addView(this, params); + } + + @Override + public void removeFromWindowManager(WindowManager windowManager) { + windowManager.removeViewImmediate(this); + } +}