Captured video always sent in correct orientation.
Temporarily blocked rotation of phone in video call activity.
This commit is contained in:
parent
3a5ae54b1d
commit
2f1c9548d2
14 changed files with 324 additions and 130 deletions
|
@ -10,4 +10,4 @@
|
||||||
# Indicates whether an apk should be generated for each density.
|
# Indicates whether an apk should be generated for each density.
|
||||||
split.density=false
|
split.density=false
|
||||||
# Project target.
|
# Project target.
|
||||||
target=android-8
|
target=android-9
|
||||||
|
|
|
@ -8,5 +8,5 @@
|
||||||
<item android:id="@+id/videocall_menu_terminate_call" android:title="@string/menu_videocall_terminate_call_title"></item>
|
<item android:id="@+id/videocall_menu_terminate_call" android:title="@string/menu_videocall_terminate_call_title"></item>
|
||||||
<item android:id="@+id/videocall_menu_change_resolution" android:title="@string/menu_videocall_change_resolution_title"></item>
|
<item android:id="@+id/videocall_menu_change_resolution" android:title="@string/menu_videocall_change_resolution_title"></item>
|
||||||
<item android:id="@+id/videocall_menu_back_to_dialer" android:title="@string/menu_videocall_back_to_dialer_title"></item>
|
<item android:id="@+id/videocall_menu_back_to_dialer" android:title="@string/menu_videocall_back_to_dialer_title"></item>
|
||||||
<!--<item android:title="@string/menu_videocall_switch_camera_title" android:id="@+id/videocall_menu_switch_camera"></item>-->
|
<item android:title="@string/menu_videocall_switch_camera_title" android:id="@+id/videocall_menu_switch_camera"></item>
|
||||||
</menu>
|
</menu>
|
||||||
|
|
|
@ -28,7 +28,6 @@ public class BandwidthManager {
|
||||||
public static final int HIGH_RESOLUTION = 0;
|
public static final int HIGH_RESOLUTION = 0;
|
||||||
public static final int LOW_RESOLUTION = 1;
|
public static final int LOW_RESOLUTION = 1;
|
||||||
public static final int LOW_BANDWIDTH = 2;
|
public static final int LOW_BANDWIDTH = 2;
|
||||||
private static final boolean portraitMode = true; // FIXME: preference?
|
|
||||||
|
|
||||||
private static final int[][] bandwidthes = {{256,256}, {128,128}, {80,80}};
|
private static final int[][] bandwidthes = {{256,256}, {128,128}, {80,80}};
|
||||||
private static BandwidthManager instance;
|
private static BandwidthManager instance;
|
||||||
|
@ -71,7 +70,7 @@ public class BandwidthManager {
|
||||||
lc.setDownloadBandwidth(bandwidthes[newProfile][1]);
|
lc.setDownloadBandwidth(bandwidthes[newProfile][1]);
|
||||||
|
|
||||||
if (lc.isIncall()) {
|
if (lc.isIncall()) {
|
||||||
InviteManager.getInstance().reinvite();
|
CallManager.getInstance().reinvite();
|
||||||
} else {
|
} else {
|
||||||
updateWithProfileSettings(lc, null);
|
updateWithProfileSettings(lc, null);
|
||||||
}
|
}
|
||||||
|
@ -80,11 +79,9 @@ public class BandwidthManager {
|
||||||
|
|
||||||
public void updateWithProfileSettings(LinphoneCore lc, LinphoneCallParams callParams) {
|
public void updateWithProfileSettings(LinphoneCore lc, LinphoneCallParams callParams) {
|
||||||
// Setting Linphone Core Preferred Video Size
|
// Setting Linphone Core Preferred Video Size
|
||||||
AndroidCameraRecordManager cameraManager = AndroidCameraRecordManager.getInstance();
|
|
||||||
|
|
||||||
boolean bandwidthOKForVideo = isVideoPossible();
|
boolean bandwidthOKForVideo = isVideoPossible();
|
||||||
if (bandwidthOKForVideo) {
|
if (bandwidthOKForVideo) {
|
||||||
VideoSize targetVideoSize = cameraManager.doYouSupportThisVideoSize(getMaximumVideoSize());
|
VideoSize targetVideoSize = getMaximumVideoSize();
|
||||||
|
|
||||||
lc.setPreferredVideoSize(targetVideoSize);
|
lc.setPreferredVideoSize(targetVideoSize);
|
||||||
VideoSize actualVideoSize = lc.getPreferredVideoSize();
|
VideoSize actualVideoSize = lc.getPreferredVideoSize();
|
||||||
|
@ -106,12 +103,12 @@ public class BandwidthManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private VideoSize maximumVideoSize(int profile) {
|
private VideoSize maximumVideoSize(int profile, boolean cameraIsPortrait) {
|
||||||
switch (profile) {
|
switch (profile) {
|
||||||
case LOW_RESOLUTION:
|
case LOW_RESOLUTION:
|
||||||
return VideoSize.createStandard(VideoSize.QCIF, portraitMode);
|
return VideoSize.createStandard(VideoSize.QCIF, cameraIsPortrait);
|
||||||
case HIGH_RESOLUTION:
|
case HIGH_RESOLUTION:
|
||||||
return VideoSize.createStandard(VideoSize.QVGA, portraitMode);
|
return VideoSize.createStandard(VideoSize.QVGA, cameraIsPortrait);
|
||||||
default:
|
default:
|
||||||
throw new RuntimeException("profile not managed : " + profile);
|
throw new RuntimeException("profile not managed : " + profile);
|
||||||
}
|
}
|
||||||
|
@ -123,6 +120,6 @@ public class BandwidthManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public VideoSize getMaximumVideoSize() {
|
public VideoSize getMaximumVideoSize() {
|
||||||
return maximumVideoSize(currentProfile);
|
return maximumVideoSize(currentProfile, AndroidCameraRecordManager.getInstance().outputIsPortrait());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
InviteManager.java
|
CallManager.java
|
||||||
Copyright (C) 2010 Belledonne Communications, Grenoble, France
|
Copyright (C) 2010 Belledonne Communications, Grenoble, France
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
This program is free software; you can redistribute it and/or
|
||||||
|
@ -25,13 +25,19 @@ import org.linphone.core.LinphoneCallParams;
|
||||||
import org.linphone.core.LinphoneCore;
|
import org.linphone.core.LinphoneCore;
|
||||||
import org.linphone.core.LinphoneCoreException;
|
import org.linphone.core.LinphoneCoreException;
|
||||||
|
|
||||||
public class InviteManager {
|
/**
|
||||||
|
* Handle call updating, reinvites.
|
||||||
|
*
|
||||||
|
* @author Guillaume Beraudo
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CallManager {
|
||||||
|
|
||||||
private static InviteManager instance;
|
private static CallManager instance;
|
||||||
|
|
||||||
private InviteManager() {}
|
private CallManager() {}
|
||||||
public static final synchronized InviteManager getInstance() {
|
public static final synchronized CallManager getInstance() {
|
||||||
if (instance == null) instance = new InviteManager();
|
if (instance == null) instance = new CallManager();
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,4 +113,14 @@ public class InviteManager {
|
||||||
lc.updateCall(lCall, params);
|
lc.updateCall(lCall, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update current call, without reinvite.
|
||||||
|
*/
|
||||||
|
public void updateCall() {
|
||||||
|
LinphoneCore lc = lc();
|
||||||
|
LinphoneCall lCall = lc.getCurrentCall();
|
||||||
|
LinphoneCallParams params = lCall.getCurrentParamsCopy();
|
||||||
|
bm().updateWithProfileSettings(lc, params);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -168,7 +168,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
|
||||||
mAddVideo.setOnClickListener(new OnClickListener() {
|
mAddVideo.setOnClickListener(new OnClickListener() {
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
// If no in video call; try to reinvite with video
|
// If no in video call; try to reinvite with video
|
||||||
boolean alreadyInVideoCall = !InviteManager.getInstance().reinviteWithVideo();
|
boolean alreadyInVideoCall = !CallManager.getInstance().reinviteWithVideo();
|
||||||
if (alreadyInVideoCall) {
|
if (alreadyInVideoCall) {
|
||||||
// In video call; going back to video call activity
|
// In video call; going back to video call activity
|
||||||
startVideoView(VIDEO_VIEW_ACTIVITY);
|
startVideoView(VIDEO_VIEW_ACTIVITY);
|
||||||
|
@ -364,6 +364,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
|
||||||
if (mWakeLock.isHeld()) mWakeLock.release();
|
if (mWakeLock.isHeld()) mWakeLock.release();
|
||||||
theDialer=null;
|
theDialer=null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
@ -522,6 +523,8 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
|
||||||
private void resetCameraFromPreferences() {
|
private void resetCameraFromPreferences() {
|
||||||
boolean useFrontCam = mPref.getBoolean(getString(R.string.pref_video_use_front_camera_key), false);
|
boolean useFrontCam = mPref.getBoolean(getString(R.string.pref_video_use_front_camera_key), false);
|
||||||
AndroidCameraRecordManager.getInstance().setUseFrontCamera(useFrontCam);
|
AndroidCameraRecordManager.getInstance().setUseFrontCamera(useFrontCam);
|
||||||
|
final int phoneOrientation = 90 * getWindowManager().getDefaultDisplay().getOrientation();
|
||||||
|
AndroidCameraRecordManager.getInstance().setPhoneOrientation(phoneOrientation);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void exitCallMode() {
|
private void exitCallMode() {
|
||||||
|
@ -605,7 +608,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
|
||||||
boolean prefVideoEnable = mPref.getBoolean(getString(R.string.pref_video_enable_key), false);
|
boolean prefVideoEnable = mPref.getBoolean(getString(R.string.pref_video_enable_key), false);
|
||||||
boolean prefInitiateWithVideo = mPref.getBoolean(getString(R.string.pref_video_initiate_call_with_video_key), false);
|
boolean prefInitiateWithVideo = mPref.getBoolean(getString(R.string.pref_video_initiate_call_with_video_key), false);
|
||||||
resetCameraFromPreferences();
|
resetCameraFromPreferences();
|
||||||
InviteManager.getInstance().inviteAddress(lAddress, prefVideoEnable && prefInitiateWithVideo);
|
CallManager.getInstance().inviteAddress(lAddress, prefVideoEnable && prefInitiateWithVideo);
|
||||||
|
|
||||||
} catch (LinphoneCoreException e) {
|
} catch (LinphoneCoreException e) {
|
||||||
Toast toast = Toast.makeText(DialerActivity.this
|
Toast toast = Toast.makeText(DialerActivity.this
|
||||||
|
|
|
@ -54,7 +54,6 @@ import android.net.ConnectivityManager;
|
||||||
import android.net.NetworkInfo;
|
import android.net.NetworkInfo;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.PowerManager;
|
|
||||||
import android.os.Vibrator;
|
import android.os.Vibrator;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
|
@ -22,12 +22,12 @@ package org.linphone;
|
||||||
|
|
||||||
import org.linphone.core.AndroidCameraRecordManager;
|
import org.linphone.core.AndroidCameraRecordManager;
|
||||||
import org.linphone.core.LinphoneCore;
|
import org.linphone.core.LinphoneCore;
|
||||||
|
import org.linphone.core.Version;
|
||||||
import org.linphone.core.VideoSize;
|
import org.linphone.core.VideoSize;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.ActivityInfo;
|
import android.content.pm.ActivityInfo;
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.os.PowerManager.WakeLock;
|
import android.os.PowerManager.WakeLock;
|
||||||
|
@ -47,7 +47,8 @@ public class VideoCallActivity extends Activity {
|
||||||
private WakeLock mWakeLock;
|
private WakeLock mWakeLock;
|
||||||
private static final int capturePreviewLargestDimension = 150;
|
private static final int capturePreviewLargestDimension = 150;
|
||||||
// private static final float similarRatio = 0.1f;
|
// private static final float similarRatio = 0.1f;
|
||||||
private static final int version = Integer.parseInt(Build.VERSION.SDK);
|
private int previousPhoneOrientation;
|
||||||
|
private int phoneOrientation;
|
||||||
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
launched = true;
|
launched = true;
|
||||||
|
@ -61,9 +62,10 @@ public class VideoCallActivity extends Activity {
|
||||||
|
|
||||||
mVideoCaptureView = (SurfaceView) findViewById(R.id.video_capture_surface);
|
mVideoCaptureView = (SurfaceView) findViewById(R.id.video_capture_surface);
|
||||||
|
|
||||||
final int rotation = getWindowManager().getDefaultDisplay().getOrientation();
|
previousPhoneOrientation = AndroidCameraRecordManager.getInstance().getPhoneOrientation();
|
||||||
|
phoneOrientation = 90 * getWindowManager().getDefaultDisplay().getOrientation();
|
||||||
recordManager = AndroidCameraRecordManager.getInstance();
|
recordManager = AndroidCameraRecordManager.getInstance();
|
||||||
recordManager.setSurfaceView(mVideoCaptureView, rotation);
|
recordManager.setSurfaceView(mVideoCaptureView, phoneOrientation);
|
||||||
mVideoCaptureView.setZOrderOnTop(true);
|
mVideoCaptureView.setZOrderOnTop(true);
|
||||||
|
|
||||||
if (!recordManager.isMuted()) sendStaticImage(false);
|
if (!recordManager.isMuted()) sendStaticImage(false);
|
||||||
|
@ -71,15 +73,32 @@ public class VideoCallActivity extends Activity {
|
||||||
mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK|PowerManager.ON_AFTER_RELEASE,"Linphone");
|
mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK|PowerManager.ON_AFTER_RELEASE,"Linphone");
|
||||||
mWakeLock.acquire();
|
mWakeLock.acquire();
|
||||||
|
|
||||||
if (version < 8) {
|
if (Version.sdkBelow(8)) {
|
||||||
// Force to display in portrait orientation for old devices
|
// Force to display in portrait orientation for old devices
|
||||||
// as they do not support surfaceView rotation
|
// as they do not support surfaceView rotation
|
||||||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
|
setRequestedOrientation(recordManager.isCameraOrientationPortrait() ?
|
||||||
|
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT :
|
||||||
|
ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle the fact that the preferred size may have a ratio /an orientation different from the one
|
// Base capture frame on streamed dimensions and orientation.
|
||||||
// in the videocall.xml as the front camera on Samsung captures in landscape.
|
resizeCapturePreview(mVideoCaptureView, lc.getPreferredVideoSize());
|
||||||
resizeCapturePreviewForOldPhones(mVideoCaptureView, lc.getPreferredVideoSize());
|
}
|
||||||
|
|
||||||
|
private void updateCallIfOrientationChanged() {
|
||||||
|
if (Version.sdkAbove(8) && previousPhoneOrientation != phoneOrientation) {
|
||||||
|
CallManager.getInstance().updateCall();
|
||||||
|
// camera will be restarted when mediastreamer chain is recreated and setParameters is called
|
||||||
|
|
||||||
|
// Base capture frame on streamed dimensions and orientation.
|
||||||
|
resizeCapturePreview(mVideoCaptureView, LinphoneService.getLc().getPreferredVideoSize());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
updateCallIfOrientationChanged();
|
||||||
|
super.onResume();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -109,6 +128,9 @@ public class VideoCallActivity extends Activity {
|
||||||
rewriteToggleCameraItem(menu.findItem(R.id.videocall_menu_toggle_camera));
|
rewriteToggleCameraItem(menu.findItem(R.id.videocall_menu_toggle_camera));
|
||||||
rewriteChangeResolutionItem(menu.findItem(R.id.videocall_menu_change_resolution));
|
rewriteChangeResolutionItem(menu.findItem(R.id.videocall_menu_change_resolution));
|
||||||
|
|
||||||
|
if (!recordManager.hasSeveralCameras()) {
|
||||||
|
menu.findItem(R.id.videocall_menu_switch_camera).setVisible(false);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,9 +145,7 @@ public class VideoCallActivity extends Activity {
|
||||||
* @param sv capture surface view to resize the layout
|
* @param sv capture surface view to resize the layout
|
||||||
* @param vs video size from which to calculate the dimensions
|
* @param vs video size from which to calculate the dimensions
|
||||||
*/
|
*/
|
||||||
private void resizeCapturePreviewForOldPhones(SurfaceView sv, VideoSize vs) {
|
private void resizeCapturePreview(SurfaceView sv, VideoSize vs) {
|
||||||
if (version >= 8) return;
|
|
||||||
|
|
||||||
LayoutParams lp = sv.getLayoutParams();
|
LayoutParams lp = sv.getLayoutParams();
|
||||||
float newRatio = ratioWidthHeight(vs);
|
float newRatio = ratioWidthHeight(vs);
|
||||||
|
|
||||||
|
@ -158,7 +178,7 @@ public class VideoCallActivity extends Activity {
|
||||||
|
|
||||||
// Resize preview frame
|
// Resize preview frame
|
||||||
VideoSize newVideoSize = LinphoneService.getLc().getPreferredVideoSize();
|
VideoSize newVideoSize = LinphoneService.getLc().getPreferredVideoSize();
|
||||||
resizeCapturePreviewForOldPhones(mVideoCaptureView, newVideoSize);
|
resizeCapturePreview(mVideoCaptureView, newVideoSize);
|
||||||
break;
|
break;
|
||||||
case R.id.videocall_menu_terminate_call:
|
case R.id.videocall_menu_terminate_call:
|
||||||
LinphoneCore lc = LinphoneService.getLc();
|
LinphoneCore lc = LinphoneService.getLc();
|
||||||
|
@ -171,13 +191,17 @@ public class VideoCallActivity extends Activity {
|
||||||
sendStaticImage(recordManager.toggleMute());
|
sendStaticImage(recordManager.toggleMute());
|
||||||
rewriteToggleCameraItem(item);
|
rewriteToggleCameraItem(item);
|
||||||
break;
|
break;
|
||||||
/* case R.id.videocall_menu_switch_camera:
|
case R.id.videocall_menu_switch_camera:
|
||||||
recordManager.stopVideoRecording();
|
recordManager.stopVideoRecording();
|
||||||
|
sendStaticImage(true);
|
||||||
recordManager.toggleUseFrontCamera();
|
recordManager.toggleUseFrontCamera();
|
||||||
InviteManager.getInstance().reinvite();
|
CallManager.getInstance().updateCall();
|
||||||
// camera will be restarted when mediastreamer chain is recreated and setParameters is called
|
// camera will be restarted when mediastreamer chain is recreated and setParameters is called
|
||||||
|
|
||||||
|
// Base capture frame on streamed dimensions and orientation.
|
||||||
|
resizeCapturePreview(mVideoCaptureView, LinphoneService.getLc().getPreferredVideoSize());
|
||||||
break;
|
break;
|
||||||
*/ default:
|
default:
|
||||||
Log.e(LinphoneService.TAG, "Unknown menu item ["+item+"]");
|
Log.e(LinphoneService.TAG, "Unknown menu item ["+item+"]");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,14 +39,12 @@ public abstract class AndroidCameraRecord {
|
||||||
|
|
||||||
private PreviewCallback storedPreviewCallback;
|
private PreviewCallback storedPreviewCallback;
|
||||||
private boolean previewStarted;
|
private boolean previewStarted;
|
||||||
protected int displayOrientation;
|
|
||||||
protected static final String tag="Linphone";
|
protected static final String tag="Linphone";
|
||||||
private List <Size> supportedVideoSizes;
|
private List <Size> supportedVideoSizes;
|
||||||
private Size currentPreviewSize;
|
private Size currentPreviewSize;
|
||||||
|
|
||||||
public AndroidCameraRecord(RecorderParams parameters) {
|
public AndroidCameraRecord(RecorderParams parameters) {
|
||||||
this.params = parameters;
|
this.params = parameters;
|
||||||
setDisplayOrientation(parameters.rotation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List<Size> getSupportedPreviewSizes(Camera.Parameters parameters) {
|
protected List<Size> getSupportedPreviewSizes(Camera.Parameters parameters) {
|
||||||
|
@ -67,7 +65,7 @@ public abstract class AndroidCameraRecord {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
camera=Camera.open();
|
camera = openCamera(params.cameraId);
|
||||||
camera.setErrorCallback(new ErrorCallback() {
|
camera.setErrorCallback(new ErrorCallback() {
|
||||||
public void onError(int error, Camera camera) {
|
public void onError(int error, Camera camera) {
|
||||||
Log.e(tag, "Camera error : " + error);
|
Log.e(tag, "Camera error : " + error);
|
||||||
|
@ -84,9 +82,10 @@ public abstract class AndroidCameraRecord {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!params.videoDimensionsInverted) {
|
if (params.width >= params.height) {
|
||||||
parameters.setPreviewSize(params.width, params.height);
|
parameters.setPreviewSize(params.width, params.height);
|
||||||
} else {
|
} else {
|
||||||
|
// invert height and width
|
||||||
parameters.setPreviewSize(params.height, params.width);
|
parameters.setPreviewSize(params.height, params.width);
|
||||||
}
|
}
|
||||||
parameters.setPreviewFrameRate(Math.round(params.fps));
|
parameters.setPreviewFrameRate(Math.round(params.fps));
|
||||||
|
@ -126,6 +125,10 @@ public abstract class AndroidCameraRecord {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
protected Camera openCamera(int cameraId) {
|
||||||
|
return Camera.open();
|
||||||
|
}
|
||||||
|
|
||||||
protected void onSettingCameraParameters(Parameters parameters) {}
|
protected void onSettingCameraParameters(Parameters parameters) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -164,24 +167,8 @@ public abstract class AndroidCameraRecord {
|
||||||
|
|
||||||
protected abstract void lowLevelSetPreviewCallback(Camera camera, PreviewCallback cb);
|
protected abstract void lowLevelSetPreviewCallback(Camera camera, PreviewCallback cb);
|
||||||
|
|
||||||
public void setDisplayOrientation(int rotation) {
|
|
||||||
displayOrientation = rotation;
|
|
||||||
}
|
|
||||||
protected int getDisplayOrientation() {return displayOrientation;}
|
|
||||||
|
|
||||||
protected int rotateCapturedFrame() {
|
|
||||||
if (params.videoDimensionsInverted) {
|
|
||||||
return 1; // always rotate 90°
|
|
||||||
} else if (params.cameraId == 2) {
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
return (4 + 1 - displayOrientation) % 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static class RecorderParams {
|
public static class RecorderParams {
|
||||||
public float fps;
|
public float fps;
|
||||||
public int height;
|
public int height;
|
||||||
|
@ -191,7 +178,6 @@ public abstract class AndroidCameraRecord {
|
||||||
public int cameraId;
|
public int cameraId;
|
||||||
public int rotation;
|
public int rotation;
|
||||||
public SurfaceView surfaceView;
|
public SurfaceView surfaceView;
|
||||||
public boolean videoDimensionsInverted;
|
|
||||||
|
|
||||||
public RecorderParams(long ptr) {
|
public RecorderParams(long ptr) {
|
||||||
filterDataNativePtr = ptr;
|
filterDataNativePtr = ptr;
|
||||||
|
@ -200,7 +186,6 @@ public abstract class AndroidCameraRecord {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public boolean isStarted() {
|
public boolean isStarted() {
|
||||||
return previewStarted;
|
return previewStarted;
|
||||||
}
|
}
|
||||||
|
@ -215,4 +200,5 @@ public abstract class AndroidCameraRecord {
|
||||||
|
|
||||||
return currentPreviewSize.width * currentPreviewSize.height * 3 /2;
|
return currentPreviewSize.width * currentPreviewSize.height * 3 /2;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,9 +26,9 @@ import android.hardware.Camera.Size;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
|
||||||
public class AndroidCameraRecordImplAPI5 extends AndroidCameraRecordImpl {
|
public class AndroidCameraRecord5Impl extends AndroidCameraRecordImpl {
|
||||||
|
|
||||||
public AndroidCameraRecordImplAPI5(RecorderParams parameters) {
|
public AndroidCameraRecord5Impl(RecorderParams parameters) {
|
||||||
super(parameters);
|
super(parameters);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,10 +30,10 @@ import android.util.Log;
|
||||||
* @author Guillaume Beraudo
|
* @author Guillaume Beraudo
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class AndroidCameraRecordAPI8Impl extends AndroidCameraRecordImplAPI5 {
|
public class AndroidCameraRecord8Impl extends AndroidCameraRecord5Impl {
|
||||||
|
|
||||||
|
|
||||||
public AndroidCameraRecordAPI8Impl(RecorderParams parameters) {
|
public AndroidCameraRecord8Impl(RecorderParams parameters) {
|
||||||
super(parameters);
|
super(parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,10 +66,6 @@ public class AndroidCameraRecordAPI8Impl extends AndroidCameraRecordImplAPI5 {
|
||||||
protected void onSettingCameraParameters(Parameters parameters) {
|
protected void onSettingCameraParameters(Parameters parameters) {
|
||||||
super.onSettingCameraParameters(parameters);
|
super.onSettingCameraParameters(parameters);
|
||||||
// Only on v8 hardware
|
// Only on v8 hardware
|
||||||
camera.setDisplayOrientation(90 * getPreviewCaptureRotation());
|
camera.setDisplayOrientation(rotation);
|
||||||
}
|
|
||||||
|
|
||||||
private int getPreviewCaptureRotation() {
|
|
||||||
return (4 + 1 - displayOrientation) % 4;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
40
src/org/linphone/core/AndroidCameraRecord9Impl.java
Normal file
40
src/org/linphone/core/AndroidCameraRecord9Impl.java
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
AndroidCameraRecord9Impl.java
|
||||||
|
Copyright (C) 2010 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.
|
||||||
|
*/
|
||||||
|
package org.linphone.core;
|
||||||
|
|
||||||
|
import android.hardware.Camera;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Android >= 9 (2.3) version.
|
||||||
|
* @author Guillaume Beraudo
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class AndroidCameraRecord9Impl extends AndroidCameraRecord8Impl {
|
||||||
|
|
||||||
|
|
||||||
|
public AndroidCameraRecord9Impl(RecorderParams parameters) {
|
||||||
|
super(parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Camera openCamera(int cameraId) {
|
||||||
|
return Camera.open(cameraId);
|
||||||
|
}
|
||||||
|
}
|
|
@ -34,19 +34,19 @@ public class AndroidCameraRecordImpl extends AndroidCameraRecord implements Prev
|
||||||
private double timeElapsedBetweenFrames = 0;
|
private double timeElapsedBetweenFrames = 0;
|
||||||
private long lastFrameTime = 0;
|
private long lastFrameTime = 0;
|
||||||
private final double expectedTimeBetweenFrames;
|
private final double expectedTimeBetweenFrames;
|
||||||
private boolean sizesInverted;
|
protected final int rotation;
|
||||||
|
|
||||||
public AndroidCameraRecordImpl(RecorderParams parameters) {
|
public AndroidCameraRecordImpl(RecorderParams parameters) {
|
||||||
super(parameters);
|
super(parameters);
|
||||||
expectedTimeBetweenFrames = 1d / Math.round(parameters.fps);
|
expectedTimeBetweenFrames = 1d / Math.round(parameters.fps);
|
||||||
filterCtxPtr = parameters.filterDataNativePtr;
|
filterCtxPtr = parameters.filterDataNativePtr;
|
||||||
sizesInverted = parameters.videoDimensionsInverted;
|
rotation = parameters.rotation;
|
||||||
|
|
||||||
storePreviewCallBack(this);
|
storePreviewCallBack(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private native void putImage(long filterCtxPtr, byte[] buffer, int rotate, boolean sizesInverted);
|
private native void putImage(long filterCtxPtr, byte[] buffer, int rotate);
|
||||||
|
|
||||||
|
|
||||||
public void onPreviewFrame(byte[] data, Camera camera) {
|
public void onPreviewFrame(byte[] data, Camera camera) {
|
||||||
|
@ -69,7 +69,7 @@ public class AndroidCameraRecordImpl extends AndroidCameraRecord implements Prev
|
||||||
long curTime = System.currentTimeMillis();
|
long curTime = System.currentTimeMillis();
|
||||||
if (lastFrameTime == 0) {
|
if (lastFrameTime == 0) {
|
||||||
lastFrameTime = curTime;
|
lastFrameTime = curTime;
|
||||||
putImage(filterCtxPtr, data, rotateCapturedFrame(), sizesInverted);
|
putImage(filterCtxPtr, data, rotation);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ public class AndroidCameraRecordImpl extends AndroidCameraRecord implements Prev
|
||||||
timeElapsedBetweenFrames = currentTimeElapsed;
|
timeElapsedBetweenFrames = currentTimeElapsed;
|
||||||
|
|
||||||
// Log.d("onPreviewFrame: ", Integer.toString(data.length));
|
// Log.d("onPreviewFrame: ", Integer.toString(data.length));
|
||||||
putImage(filterCtxPtr, data, rotateCapturedFrame(), sizesInverted);
|
putImage(filterCtxPtr, data, rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -92,6 +92,4 @@ public class AndroidCameraRecordImpl extends AndroidCameraRecord implements Prev
|
||||||
camera.setPreviewCallback(cb);
|
camera.setPreviewCallback(cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ import java.util.List;
|
||||||
|
|
||||||
import org.linphone.core.AndroidCameraRecord.RecorderParams;
|
import org.linphone.core.AndroidCameraRecord.RecorderParams;
|
||||||
|
|
||||||
|
import android.hardware.Camera;
|
||||||
import android.hardware.Camera.Size;
|
import android.hardware.Camera.Size;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
@ -38,14 +39,9 @@ import android.view.SurfaceHolder.Callback;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class AndroidCameraRecordManager {
|
public class AndroidCameraRecordManager {
|
||||||
private static final int version = Integer.parseInt(Build.VERSION.SDK);
|
|
||||||
private static final String tag = "Linphone";
|
private static final String tag = "Linphone";
|
||||||
private static AndroidCameraRecordManager instance;
|
private static AndroidCameraRecordManager instance;
|
||||||
|
|
||||||
// singleton
|
|
||||||
private AndroidCameraRecordManager() {}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return instance
|
* @return instance
|
||||||
*/
|
*/
|
||||||
|
@ -59,31 +55,76 @@ public class AndroidCameraRecordManager {
|
||||||
private AndroidCameraRecord.RecorderParams parameters;
|
private AndroidCameraRecord.RecorderParams parameters;
|
||||||
private SurfaceView surfaceView;
|
private SurfaceView surfaceView;
|
||||||
private boolean muted;
|
private boolean muted;
|
||||||
|
private int cameraId;
|
||||||
|
|
||||||
private AndroidCameraRecord recorder;
|
private AndroidCameraRecord recorder;
|
||||||
|
|
||||||
|
|
||||||
private List<Size> supportedVideoSizes;
|
private List<Size> supportedVideoSizes;
|
||||||
private int rotation;
|
private int phoneOrientation;
|
||||||
|
public int getPhoneOrientation() {return phoneOrientation;}
|
||||||
|
public void setPhoneOrientation(int degrees) {this.phoneOrientation = degrees;}
|
||||||
|
|
||||||
private boolean useFrontCamera;
|
private int frontCameraId;
|
||||||
|
private int rearCameraId;
|
||||||
|
|
||||||
|
// singleton
|
||||||
|
private AndroidCameraRecordManager() {
|
||||||
|
findFrontAndRearCameraIds();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void findFrontAndRearCameraIds() {
|
||||||
|
if (Version.sdkAbove(9)) {
|
||||||
|
findFrontAndRearCameraIds9();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Build.DEVICE.startsWith("GT-I9000")) {
|
||||||
|
// Galaxy S has 2 cameras
|
||||||
|
frontCameraId = 2;
|
||||||
|
rearCameraId = 1;
|
||||||
|
cameraId = rearCameraId;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// default to 0/0
|
||||||
|
}
|
||||||
|
|
||||||
|
private void findFrontAndRearCameraIds9() {
|
||||||
|
for (int id=0; id < getNumberOfCameras9(); id++) {
|
||||||
|
if (isFrontCamera9(id)) {
|
||||||
|
frontCameraId = id;
|
||||||
|
} else {
|
||||||
|
rearCameraId = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasSeveralCameras() {
|
||||||
|
return frontCameraId != rearCameraId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setUseFrontCamera(boolean value) {
|
public void setUseFrontCamera(boolean value) {
|
||||||
if (useFrontCamera == value) return;
|
if (isFrontCamera() == value) return; // already OK
|
||||||
this.useFrontCamera = value;
|
|
||||||
|
toggleUseFrontCamera();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isUseFrontCamera() {return isFrontCamera();}
|
||||||
|
public boolean toggleUseFrontCamera() {
|
||||||
|
boolean previousUseFront = isFrontCamera();
|
||||||
|
|
||||||
|
cameraId = previousUseFront ? rearCameraId : frontCameraId;
|
||||||
|
|
||||||
if (parameters != null) {
|
if (parameters != null) {
|
||||||
parameters.cameraId = cameraId();
|
parameters.cameraId = cameraId;
|
||||||
if (isRecording()) {
|
if (isRecording()) {
|
||||||
stopVideoRecording();
|
stopVideoRecording();
|
||||||
tryToStartVideoRecording();
|
tryToStartVideoRecording();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
public boolean isUseFrontCamera() {return useFrontCamera;}
|
return !previousUseFront;
|
||||||
public boolean toggleUseFrontCamera() {
|
|
||||||
setUseFrontCamera(!useFrontCamera);
|
|
||||||
return useFrontCamera;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -94,16 +135,14 @@ public class AndroidCameraRecordManager {
|
||||||
p.fps = fps;
|
p.fps = fps;
|
||||||
p.width = width;
|
p.width = width;
|
||||||
p.height = height;
|
p.height = height;
|
||||||
p.cameraId = cameraId();
|
p.cameraId = cameraId;
|
||||||
p.videoDimensionsInverted = width < height;
|
|
||||||
// width and height will be inverted in Recorder on startPreview
|
|
||||||
parameters = p;
|
parameters = p;
|
||||||
tryToStartVideoRecording();
|
tryToStartVideoRecording();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public final void setSurfaceView(final SurfaceView sv, final int rotation) {
|
public final void setSurfaceView(final SurfaceView sv, final int phoneOrientation) {
|
||||||
this.rotation = useFrontCamera ? 1 : rotation;
|
this.phoneOrientation = phoneOrientation;
|
||||||
SurfaceHolder holder = sv.getHolder();
|
SurfaceHolder holder = sv.getHolder();
|
||||||
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
|
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
|
||||||
|
|
||||||
|
@ -152,12 +191,15 @@ public class AndroidCameraRecordManager {
|
||||||
private void tryToStartVideoRecording() {
|
private void tryToStartVideoRecording() {
|
||||||
if (muted || surfaceView == null || parameters == null) return;
|
if (muted || surfaceView == null || parameters == null) return;
|
||||||
|
|
||||||
parameters.rotation = rotation;
|
parameters.rotation = bufferRotationForCorrectImageOrientation();
|
||||||
|
|
||||||
parameters.surfaceView = surfaceView;
|
parameters.surfaceView = surfaceView;
|
||||||
if (version >= 8) {
|
if (Version.sdkAbove(9)) {
|
||||||
recorder = new AndroidCameraRecordAPI8Impl(parameters);
|
recorder = new AndroidCameraRecord9Impl(parameters);
|
||||||
} else if (version >= 5) {
|
} else if (Version.sdkAbove(8)) {
|
||||||
recorder = new AndroidCameraRecordImplAPI5(parameters);
|
recorder = new AndroidCameraRecord8Impl(parameters);
|
||||||
|
} else if (Version.sdkAbove(5)) {
|
||||||
|
recorder = new AndroidCameraRecord5Impl(parameters);
|
||||||
} else {
|
} else {
|
||||||
recorder = new AndroidCameraRecordImpl(parameters);
|
recorder = new AndroidCameraRecordImpl(parameters);
|
||||||
}
|
}
|
||||||
|
@ -188,8 +230,8 @@ public class AndroidCameraRecordManager {
|
||||||
if (supportedVideoSizes != null) return supportedVideoSizes;
|
if (supportedVideoSizes != null) return supportedVideoSizes;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= 5) {
|
if (Version.sdkAbove(5)) {
|
||||||
supportedVideoSizes = AndroidCameraRecordImplAPI5.oneShotSupportedVideoSizes();
|
supportedVideoSizes = AndroidCameraRecord5Impl.oneShotSupportedVideoSizes();
|
||||||
}
|
}
|
||||||
|
|
||||||
// eventually null
|
// eventually null
|
||||||
|
@ -212,34 +254,86 @@ public class AndroidCameraRecordManager {
|
||||||
parameters = null;
|
parameters = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public boolean outputIsPortrait() {
|
||||||
* Naive simple version.
|
final int rotation = bufferRotationForCorrectImageOrientation();
|
||||||
* @param askedSize
|
final boolean isPortrait = (rotation % 180) == 90;
|
||||||
* @return
|
|
||||||
*/
|
Log.d(tag, "Camera sensor in portrait orientation ?" + isPortrait);
|
||||||
public VideoSize doYouSupportThisVideoSize(VideoSize askedSize) {
|
return isPortrait;
|
||||||
Log.d(tag, "Asking camera if it supports size "+askedSize);
|
|
||||||
if (useFrontCamera && askedSize.isPortrait()) {
|
|
||||||
return askedSize.createInverted(); // only landscape supported
|
|
||||||
} else {
|
|
||||||
return askedSize;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private VideoSize closestVideoSize(VideoSize vSize, int defaultSizeCode, boolean defaultIsPortrait) {
|
|
||||||
VideoSize testSize = vSize.isPortrait() ? vSize.createInverted() : vSize;
|
|
||||||
|
public static int getNumberOfCameras() {
|
||||||
for (Size s : AndroidCameraRecordManager.getInstance().supportedVideoSizes()) {
|
if (Version.sdkAbove(9)) return getNumberOfCameras9();
|
||||||
if (s.height == testSize.height && s.width == testSize.width) {
|
|
||||||
return vSize;
|
// Use hacks to guess the number of cameras
|
||||||
}
|
if (Build.DEVICE.startsWith("GT-I9000")) {
|
||||||
}
|
// Galaxy S has 2 cameras
|
||||||
|
return 2;
|
||||||
return VideoSize.createStandard(defaultSizeCode, defaultIsPortrait);
|
} else
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final int rearCamId() {return 1;}
|
private static int getNumberOfCameras9() {
|
||||||
private static final int frontCamId() {return 2;}
|
return Camera.getNumberOfCameras();
|
||||||
private final int cameraId() {return useFrontCamera? frontCamId() : rearCamId(); }
|
}
|
||||||
|
|
||||||
|
public boolean isCameraOrientationPortrait() {
|
||||||
|
return (getCameraOrientation() % 180) == 90;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCameraOrientation() {
|
||||||
|
if (Version.sdkAbove(9)) return getCameraOrientation9();
|
||||||
|
|
||||||
|
// Use hacks to guess orientation of the camera
|
||||||
|
if (cameraId == 2 && Build.DEVICE.startsWith("GT-I9000")) {
|
||||||
|
// Galaxy S rear camera
|
||||||
|
// mounted in landscape for a portrait phone orientation
|
||||||
|
return 90;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private int getCameraOrientation9() {
|
||||||
|
android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
|
||||||
|
Camera.getCameraInfo(cameraId, info);
|
||||||
|
return info.orientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFrontCamera() {
|
||||||
|
if (Version.sdkAbove(9)) return isFrontCamera9();
|
||||||
|
|
||||||
|
// Use hacks to guess facing of the camera
|
||||||
|
|
||||||
|
if (cameraId == 2 && Build.DEVICE.startsWith("GT-I9000")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isFrontCamera9() {
|
||||||
|
return isFrontCamera9(cameraId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private boolean isFrontCamera9(int cameraId) {
|
||||||
|
android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
|
||||||
|
Camera.getCameraInfo(cameraId, info);
|
||||||
|
return info.facing == android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int bufferRotationForCorrectImageOrientation() {
|
||||||
|
final int cameraOrientation = getCameraOrientation();
|
||||||
|
final int rotation = Version.sdkAbove(8) ?
|
||||||
|
(360 - cameraOrientation + 90 - phoneOrientation) % 360
|
||||||
|
: 0;
|
||||||
|
Log.d(tag, "Capture video buffer will need a rotation of " + rotation
|
||||||
|
+ " degrees : camera " + cameraOrientation
|
||||||
|
+ ", phone " + phoneOrientation);
|
||||||
|
return rotation;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
41
src/org/linphone/core/Version.java
Normal file
41
src/org/linphone/core/Version.java
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
Version.java
|
||||||
|
Copyright (C) 2010 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.
|
||||||
|
*/
|
||||||
|
package org.linphone.core;
|
||||||
|
|
||||||
|
import android.os.Build;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Centralize version access and allow simulation of lower versions.
|
||||||
|
* @author Guillaume Beraudo
|
||||||
|
*/
|
||||||
|
public class Version {
|
||||||
|
|
||||||
|
private static final int buildVersion =
|
||||||
|
// Integer.parseInt(Build.VERSION.SDK);
|
||||||
|
7; // 2.1
|
||||||
|
|
||||||
|
public static final boolean sdkAbove(int value) {
|
||||||
|
return buildVersion >= value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final boolean sdkBelow(int value) {
|
||||||
|
return buildVersion < value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue