Fix some issues including video memory leak

This commit is contained in:
Sylvain Berfini 2012-08-03 17:48:54 +02:00
parent 3a9030925a
commit 6b5efb975e
15 changed files with 140 additions and 69 deletions

View file

@ -73,7 +73,7 @@
<activity android:name="org.linphone.InCallActivity"
android:theme="@android:style/Theme.NoTitleBar"
android:noHistory="true"
android:launchMode="singleTop">
android:launchMode="singleInstance">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>

View file

@ -34,7 +34,9 @@
android:paddingTop="20dp"
android:src="@drawable/switch_camera"
android:visibility="gone" />
<!-- TODO Add numpad -->
<LinearLayout
android:id="@+id/menu"
android:layout_width="match_parent"

View file

@ -10,7 +10,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="@android:color/white"
android:textSize="22dp"
android:textSize="30dp"
android:background="@drawable/dialer_address_background"
android:inputType="textEmailAddress"
android:hint="@string/addressHint"
@ -57,4 +57,4 @@
</LinearLayout>
</LinearLayout>
</LinearLayout>

View file

@ -7,7 +7,7 @@
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
android:layout_height="match_parent" >
<LinearLayout
android:id="@+id/fragmentContainer"
@ -199,4 +199,4 @@
</LinearLayout>
</RelativeLayout>
</RelativeLayout>

View file

@ -1,12 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/topLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentTop="true">
<LinearLayout
@ -112,4 +113,4 @@
</LinearLayout>
</RelativeLayout>
</RelativeLayout>

View file

@ -263,7 +263,7 @@
<string name="status_in_progress">CONNECTING</string>
<string name="status_error">ERROR</string>
<string name="addressHint">Number or adress</string>
<string name="addressHint">Number or address</string>
<!-- Used by Android to help blind people by describing them images -->
<string name="content_description_add_contact">Add to contacts button</string>

View file

@ -51,7 +51,6 @@ public class AudioCallFragment extends Fragment {
private RelativeLayout callsList;
private LayoutInflater inflater;
private ViewGroup container;
private InCallActivity inCallActivity;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
@ -144,20 +143,20 @@ public class AudioCallFragment extends Fragment {
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
inCallActivity = (InCallActivity) activity;
inCallActivity.bindAudioFragment(this);
if (InCallActivity.isInstanciated()) {
InCallActivity.instance().bindAudioFragment(this);
}
}
@Override
public void onStart() {
super.onStart();
if (inCallActivity == null) {
return;
}
// Just to be sure we have incall controls
inCallActivity.setCallControlsVisibleAndRemoveCallbacks();
if (InCallActivity.isInstanciated()) {
InCallActivity.instance().setCallControlsVisibleAndRemoveCallbacks();
}
}
@Override
@ -177,7 +176,7 @@ public class AudioCallFragment extends Fragment {
int index = 0;
if (LinphoneManager.getLc().getCallsNb() == 0) {
inCallActivity.goBackToDialer();
InCallActivity.instance().goBackToDialer();
return;
}

View file

@ -41,9 +41,11 @@ import android.support.v4.app.FragmentTransaction;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.LinearLayout;
@ -367,16 +369,20 @@ public class InCallActivity extends FragmentActivity implements
public void displayVideoCallControlsIfHidden() {
if (mControlsLayout != null) {
if (mControlsLayout.getVisibility() == View.GONE) {
if (InCallActivity.this.getResources().getBoolean(R.bool.disable_animations)) {
if (getResources().getBoolean(R.bool.disable_animations)) {
mControlsLayout.setVisibility(View.VISIBLE);
switchCamera.setVisibility(View.VISIBLE);
if (AndroidCameraConfiguration.retrieveCameras().length > 1) {
switchCamera.setVisibility(View.VISIBLE);
}
} else {
Animation animation = AnimationUtils.loadAnimation(this, R.anim.slide_in_bottom_to_top);
animation.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
mControlsLayout.setVisibility(View.VISIBLE);
switchCamera.setVisibility(View.VISIBLE);
if (AndroidCameraConfiguration.retrieveCameras().length > 1) {
switchCamera.setVisibility(View.VISIBLE);
}
}
@Override
@ -390,9 +396,9 @@ public class InCallActivity extends FragmentActivity implements
mControlsLayout.startAnimation(animation);
switchCamera.startAnimation(AnimationUtils.loadAnimation(this, R.anim.slide_in_top_to_bottom));
}
resetControlsHidingCallBack();
}
resetControlsHidingCallBack();
}
}
@ -400,20 +406,21 @@ public class InCallActivity extends FragmentActivity implements
if (controlsHandler != null && mControls != null) {
controlsHandler.removeCallbacks(mControls);
}
mControls = null;
if (isVideoEnabled) {
controlsHandler.postDelayed(mControls = new Runnable() {
public void run() {
hideNumpad();
if (InCallActivity.this.getResources().getBoolean(R.bool.disable_animations)) {
if (getResources().getBoolean(R.bool.disable_animations)) {
transfer.setVisibility(View.INVISIBLE);
addCall.setVisibility(View.INVISIBLE);
mControlsLayout.setVisibility(View.GONE);
switchCamera.setVisibility(View.INVISIBLE);
options.setImageResource(R.drawable.options);
} else {
Animation animation = AnimationUtils.loadAnimation(InCallActivity.this, R.anim.slide_out_top_to_bottom);
Animation animation = AnimationUtils.loadAnimation(instance, R.anim.slide_out_top_to_bottom);
animation.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
@ -435,7 +442,7 @@ public class InCallActivity extends FragmentActivity implements
}
});
mControlsLayout.startAnimation(animation);
switchCamera.startAnimation(AnimationUtils.loadAnimation(InCallActivity.this, R.anim.slide_out_bottom_to_top));
switchCamera.startAnimation(AnimationUtils.loadAnimation(instance, R.anim.slide_out_bottom_to_top));
}
}
}, SECONDS_BEFORE_HIDING_CONTROLS);
@ -445,8 +452,8 @@ public class InCallActivity extends FragmentActivity implements
public void setCallControlsVisibleAndRemoveCallbacks() {
if (controlsHandler != null && mControls != null) {
controlsHandler.removeCallbacks(mControls);
mControls = null;
}
mControls = null;
mControlsLayout.setVisibility(View.VISIBLE);
switchCamera.setVisibility(View.INVISIBLE);
@ -483,6 +490,10 @@ public class InCallActivity extends FragmentActivity implements
}
private void hideOrDisplayNumpad() {
if (numpad == null) {
return;
}
if (numpad.getVisibility() == View.VISIBLE) {
hideNumpad();
} else {
@ -599,8 +610,7 @@ public class InCallActivity extends FragmentActivity implements
}
@Override
public void onCallStateChanged(LinphoneCall call, State state,
String message) {
public void onCallStateChanged(LinphoneCall call, State state, String message) {
if (LinphoneManager.getLc().getCallsNb() == 0) {
finish();
return;
@ -630,8 +640,7 @@ public class InCallActivity extends FragmentActivity implements
}
@Override
public void onCallEncryptionChanged(LinphoneCall call, boolean encrypted,
String authenticationToken) {
public void onCallEncryptionChanged(LinphoneCall call, boolean encrypted, String authenticationToken) {
if (status != null) {
status.refreshStatusItems();
}
@ -653,16 +662,36 @@ public class InCallActivity extends FragmentActivity implements
@Override
protected void onPause() {
LinphoneManager.removeListener(this);
LinphoneManager.stopProximitySensorForActivity(this);
super.onPause();
if (controlsHandler != null && mControls != null) {
controlsHandler.removeCallbacks(mControls);
}
mControls = null;
LinphoneManager.stopProximitySensorForActivity(this);
LinphoneManager.removeListener(this);
}
@Override
protected void onDestroy() {
instance = null;
super.onDestroy();
unbindDrawables(findViewById(R.id.topLayout));
instance = null;
System.gc();
}
private void unbindDrawables(View view) {
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup && !(view instanceof AdapterView)) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
}
@Override

View file

@ -60,9 +60,11 @@ import android.support.v4.app.FragmentTransaction;
import android.view.KeyEvent;
import android.view.OrientationEventListener;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
@ -647,20 +649,24 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene
}
@Override
public void onOrientationChanged(final int o) {
if (o == OrientationEventListener.ORIENTATION_UNKNOWN) return;
if (o == OrientationEventListener.ORIENTATION_UNKNOWN) {
return;
}
int degrees=270;
if (o < 45 || o >315) degrees=0;
else if (o<135) degrees=90;
else if (o<225) degrees=180;
int degrees = 270;
if (o < 45 || o >315) degrees = 0;
else if (o < 135) degrees = 90;
else if (o < 225) degrees = 180;
if (mAlwaysChangingPhoneAngle == degrees) return;
if (mAlwaysChangingPhoneAngle == degrees) {
return;
}
mAlwaysChangingPhoneAngle = degrees;
Log.d("Phone orientation changed to ", degrees);
int rotation = (360 - degrees) % 360;
LinphoneCore lc=LinphoneManager.getLcIfManagerNotDestroyedOrNull();
if (lc!=null){
LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
if (lc != null){
lc.setDeviceRotation(rotation);
LinphoneCall currentCall = lc.getCurrentCall();
if (currentCall != null && currentCall.cameraEnabled() && currentCall.getCurrentParamsCopy().getVideoEnabled()) {
@ -822,7 +828,29 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene
chatStorage.close();
chatStorage = null;
}
if (mOrientationHelper != null) {
mOrientationHelper.disable();
mOrientationHelper = null;
}
instance = null;
super.onDestroy();
unbindDrawables(findViewById(R.id.topLayout));
System.gc();
}
private void unbindDrawables(View view) {
if (view != null && view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup && !(view instanceof AdapterView)) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
}
@Override

View file

@ -25,7 +25,6 @@ import org.linphone.core.Log;
import org.linphone.mediastream.video.AndroidVideoWindowImpl;
import org.linphone.mediastream.video.capture.hwconf.AndroidCameraConfiguration;
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.support.v4.app.Fragment;
@ -34,7 +33,6 @@ import android.view.GestureDetector.OnDoubleTapListener;
import android.view.GestureDetector.OnGestureListener;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
@ -49,7 +47,6 @@ public class VideoCallFragment extends Fragment implements OnGestureListener, On
private SurfaceView mVideoView;
private SurfaceView mCaptureView;
private AndroidVideoWindowImpl androidVideoWindowImpl;
private InCallActivity inCallActivity;
private GestureDetector mGestureDetector;
private float mZoomFactor = 1.f;
private float mZoomCenterX, mZoomCenterY;
@ -70,7 +67,6 @@ public class VideoCallFragment extends Fragment implements OnGestureListener, On
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);
@ -107,7 +103,7 @@ public class VideoCallFragment extends Fragment implements OnGestureListener, On
}
mGestureDetector.onTouchEvent(event);
inCallActivity.displayVideoCallControlsIfHidden();
InCallActivity.instance().displayVideoCallControlsIfHidden();
return true;
}
});
@ -115,12 +111,6 @@ public class VideoCallFragment extends Fragment implements OnGestureListener, On
return view;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
inCallActivity = (InCallActivity) activity;
}
private void fixZOrder(SurfaceView video, SurfaceView preview) {
video.setZOrderOnTop(false);
preview.setZOrderOnTop(true);
@ -168,13 +158,13 @@ public class VideoCallFragment extends Fragment implements OnGestureListener, On
LinphoneManager.getLc().setVideoWindow(null);
}
super.onPause();
if (mVideoView != null)
((GLSurfaceView) mVideoView).onPause();
super.onPause();
}
public boolean onScale(ScaleGestureDetector detector) {
public boolean onScale(CompatibilityScaleGestureDetector detector) {
mZoomFactor *= detector.getScaleFactor();
// Don't let the object get too small or too large.
mZoomFactor = Math.max(0.1f, Math.min(mZoomFactor, mVideoView.getHeight() / LinphoneManager.getLc().getPreferredVideoSize().height));
@ -232,10 +222,24 @@ public class VideoCallFragment extends Fragment implements OnGestureListener, On
@Override
public void onDestroy() {
getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
if (androidVideoWindowImpl != null) {
// Prevent linphone from crashing if correspondent hang up while you are rotating
androidVideoWindowImpl.release();
androidVideoWindowImpl = null;
mCaptureView = null;
mVideoView = null;
}
if (mGestureDetector != null) {
mGestureDetector.setOnDoubleTapListener(null);
mGestureDetector = null;
}
if (mScaleDetector != null) {
mScaleDetector.destroy();
mScaleDetector = null;
}
super.onDestroy();
}

View file

@ -165,7 +165,7 @@ public class Compatibility {
public static CompatibilityScaleGestureDetector getScaleGestureDetector(Context context, CompatibilityScaleGestureListener listener) {
if (Version.sdkAboveOrEqual(8)) {
CompatibilityScaleGestureDetector csgd = new CompatibilityScaleGestureDetector(context);
csgd.addListener(listener);
csgd.setOnScaleListener(listener);
return csgd;
}
return null;

View file

@ -14,7 +14,7 @@ public class CompatibilityScaleGestureDetector extends ScaleGestureDetector.Simp
detector = new ScaleGestureDetector(context, this);
}
public void addListener(CompatibilityScaleGestureListener newListener) {
public void setOnScaleListener(CompatibilityScaleGestureListener newListener) {
listener = newListener;
}
@ -28,6 +28,15 @@ public class CompatibilityScaleGestureDetector extends ScaleGestureDetector.Simp
return false;
}
return listener.onScale(detector);
return listener.onScale(this);
}
public float getScaleFactor() {
return detector.getScaleFactor();
}
public void destroy() {
listener = null;
detector = null;
}
}

View file

@ -1,7 +1,6 @@
package org.linphone.compatibility;
import android.view.ScaleGestureDetector;
public interface CompatibilityScaleGestureListener {
public boolean onScale(ScaleGestureDetector detector);
public boolean onScale(CompatibilityScaleGestureDetector detector);
}

View file

@ -56,9 +56,9 @@ public class CallButton extends ImageView implements OnClickListener, AddressAwa
if (getContext().getResources().getBoolean(R.bool.call_last_log_if_adress_is_empty)) {
LinphoneCallLog[] logs = LinphoneManager.getLc().getCallLogs();
LinphoneCallLog log = null;
for (int i = logs.length - 1; i >= 0; i--) {
if (logs[i].getDirection() == CallDirection.Outgoing) {
log = logs[i];
for (LinphoneCallLog l : logs) {
if (l.getDirection() == CallDirection.Outgoing) {
log = l;
break;
}
}

View file

@ -110,7 +110,7 @@ public class Digit extends Button implements AddressAware {
if (lBegin == -1) {
lBegin = mAddress.length();
}
if (lBegin >=0) {
if (lBegin >= 0) {
mAddress.getEditableText().insert(lBegin,String.valueOf(mKeyCode));
}
}
@ -127,11 +127,11 @@ public class Digit extends Button implements AddressAware {
LinphoneCore lc = LinphoneManager.getLc();
if (event.getAction() == MotionEvent.ACTION_DOWN && !mIsDtmfStarted) {
LinphoneManager.getInstance().playDtmf(getContext().getContentResolver(), mKeyCode);
mIsDtmfStarted=true;
mIsDtmfStarted = true;
} else {
if (event.getAction() == MotionEvent.ACTION_UP) {
lc.stopDtmf();
mIsDtmfStarted=false;
mIsDtmfStarted = false;
}
}
return false;
@ -151,7 +151,7 @@ public class Digit extends Button implements AddressAware {
if (lBegin == -1) {
lBegin = mAddress.getEditableText().length();
}
if (lBegin >=0) {
if (lBegin >= 0) {
mAddress.getEditableText().insert(lBegin,"+");
}
return true;