summaryrefslogtreecommitdiff
path: root/InCallUI
diff options
context:
space:
mode:
authorNivedita Sarkar <nsarkar@codeaurora.org>2015-12-07 23:04:47 +0000
committerandroid-build-merger <android-build-merger@google.com>2015-12-07 23:04:47 +0000
commitcac542abb894522d183f5cb6cdc33589198b9fec (patch)
tree3cededc215c5abaac190b186a582e2f45d2ec643 /InCallUI
parentf9c9b82a58766639ad4442509ce31fc9e1df0b02 (diff)
parent70c216c16d28552d851aadcc0bf6928522f0da6b (diff)
IMS-VT: Listen to sensor orientation changes and update camera preview
am: 6ae35c6ecd * commit '6ae35c6ecdb08230362dd5d9ada09da408819ce7': IMS-VT: Listen to sensor orientation changes and update camera preview
Diffstat (limited to 'InCallUI')
-rw-r--r--InCallUI/src/com/android/incallui/InCallActivity.java77
-rw-r--r--InCallUI/src/com/android/incallui/InCallOrientationEventListener.java151
-rw-r--r--InCallUI/src/com/android/incallui/InCallPresenter.java67
-rw-r--r--InCallUI/src/com/android/incallui/VideoCallFragment.java27
-rw-r--r--InCallUI/src/com/android/incallui/VideoCallPresenter.java43
5 files changed, 240 insertions, 125 deletions
diff --git a/InCallUI/src/com/android/incallui/InCallActivity.java b/InCallUI/src/com/android/incallui/InCallActivity.java
index a807a12ea..3dc2c9daf 100644
--- a/InCallUI/src/com/android/incallui/InCallActivity.java
+++ b/InCallUI/src/com/android/incallui/InCallActivity.java
@@ -90,6 +90,7 @@ public class InCallActivity extends TransactionSafeActivity implements FragmentD
private FragmentManager mChildFragmentManager;
private AlertDialog mDialog;
+ private InCallOrientationEventListener mInCallOrientationEventListener;
/**
* Use to pass 'showDialpad' from {@link #onNewIntent} to {@link #onResume}
@@ -146,11 +147,6 @@ public class InCallActivity extends TransactionSafeActivity implements FragmentD
*/
private OrientationEventListener mOrientationEventListener;
- /**
- * Used to determine if a change in rotation has occurred.
- */
- private static int sPreviousRotation = -1;
-
@Override
protected void onCreate(Bundle icicle) {
Log.d(this, "onCreate()... this = " + this);
@@ -218,41 +214,7 @@ public class InCallActivity extends TransactionSafeActivity implements FragmentD
}
}
- mOrientationEventListener = new OrientationEventListener(this,
- SensorManager.SENSOR_DELAY_NORMAL) {
- @Override
- public void onOrientationChanged(int orientation) {
- // Device is flat, don't change orientation.
- if (orientation == OrientationEventListener.ORIENTATION_UNKNOWN) {
- return;
- }
-
- int newRotation;
- // We only shift if we're within 22.5 (23) degrees of the target
- // orientation. This avoids flopping back and forth when holding
- // the device at 45 degrees or so.
- if (orientation >= 337 || orientation <= 23) {
- newRotation = Surface.ROTATION_0;
- } else if (orientation >= 67 && orientation <= 113) {
- // Why not 90? Because screen and sensor orientation are
- // reversed.
- newRotation = Surface.ROTATION_270;
- } else if (orientation >= 157 && orientation <= 203) {
- newRotation = Surface.ROTATION_180;
- } else if (orientation >= 247 && orientation <= 293) {
- newRotation = Surface.ROTATION_90;
- } else {
- // Device is between orientations, so leave orientation the same.
- return;
- }
-
- // Orientation is the current device orientation in degrees. Ultimately we want
- // the rotation (in fixed 90 degree intervals).
- if (newRotation != sPreviousRotation) {
- doOrientationChanged(newRotation);
- }
- }
- };
+ mInCallOrientationEventListener = new InCallOrientationEventListener(this);
Log.d(this, "onCreate(): exit");
}
@@ -283,6 +245,8 @@ public class InCallActivity extends TransactionSafeActivity implements FragmentD
// setting activity should be last thing in setup process
InCallPresenter.getInstance().setActivity(this);
+ enableInCallOrientationEventListener(getRequestedOrientation() ==
+ InCallOrientationEventListener.FULL_SENSOR_SCREEN_ORIENTATION);
InCallPresenter.getInstance().onActivityStarted();
}
@@ -331,6 +295,7 @@ public class InCallActivity extends TransactionSafeActivity implements FragmentD
@Override
protected void onStop() {
Log.d(this, "onStop()...");
+ enableInCallOrientationEventListener(false);
InCallPresenter.getInstance().updateIsChangingConfigurations();
InCallPresenter.getInstance().onActivityStopped();
mOrientationEventListener.disable();
@@ -547,25 +512,6 @@ public class InCallActivity extends TransactionSafeActivity implements FragmentD
return false;
}
- /**
- * Handles changes in device rotation.
- *
- * @param rotation The new device rotation (one of: {@link Surface#ROTATION_0},
- * {@link Surface#ROTATION_90}, {@link Surface#ROTATION_180},
- * {@link Surface#ROTATION_270}).
- */
- private void doOrientationChanged(int rotation) {
- Log.d(this, "doOrientationChanged prevOrientation=" + sPreviousRotation +
- " newOrientation=" + rotation);
- // Check to see if the rotation changed to prevent triggering rotation change events
- // for other configuration changes.
- if (rotation != sPreviousRotation) {
- sPreviousRotation = rotation;
- InCallPresenter.getInstance().onDeviceRotationChange(rotation);
- InCallPresenter.getInstance().onDeviceOrientationChange(sPreviousRotation);
- }
- }
-
public CallButtonFragment getCallButtonFragment() {
return mCallButtonFragment;
}
@@ -944,4 +890,17 @@ public class InCallActivity extends TransactionSafeActivity implements FragmentD
public void setDispatchTouchEventListener(OnTouchListener mDispatchTouchEventListener) {
this.mDispatchTouchEventListener = mDispatchTouchEventListener;
}
+
+ /**
+ * Enables the OrientationEventListener if enable flag is true. Disables it if enable is
+ * false
+ * @param enable true or false.
+ */
+ public void enableInCallOrientationEventListener(boolean enable) {
+ if (enable) {
+ mInCallOrientationEventListener.enable(enable);
+ } else {
+ mInCallOrientationEventListener.disable();
+ }
+ }
}
diff --git a/InCallUI/src/com/android/incallui/InCallOrientationEventListener.java b/InCallUI/src/com/android/incallui/InCallOrientationEventListener.java
new file mode 100644
index 000000000..d3334a3ef
--- /dev/null
+++ b/InCallUI/src/com/android/incallui/InCallOrientationEventListener.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.incallui;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.view.OrientationEventListener;
+import android.hardware.SensorManager;
+import android.view.Surface;
+import android.content.pm.ActivityInfo;
+
+/**
+ * This class listens to Orientation events and overrides onOrientationChanged which gets
+ * invoked when an orientation change occurs. When that happens, we notify InCallUI registrants
+ * of the change.
+ */
+public class InCallOrientationEventListener extends OrientationEventListener {
+
+ /**
+ * Screen orientation angles one of 0, 90, 180, 270, 360 in degrees.
+ */
+ public static int SCREEN_ORIENTATION_0 = 0;
+ public static int SCREEN_ORIENTATION_90 = 90;
+ public static int SCREEN_ORIENTATION_180 = 180;
+ public static int SCREEN_ORIENTATION_270 = 270;
+ public static int SCREEN_ORIENTATION_360 = 360;
+
+ public static int FULL_SENSOR_SCREEN_ORIENTATION =
+ ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR;
+
+ public static int NO_SENSOR_SCREEN_ORIENTATION =
+ ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
+
+ /**
+ * This is to identify dead zones where we won't notify others of orientation changed.
+ * Say for e.g our threshold is x degrees. We will only notify UI when our current rotation is
+ * within x degrees right or left of the screen orientation angles. If it's not within those
+ * ranges, we return SCREEN_ORIENTATION_UNKNOWN and ignore it.
+ */
+ private static int SCREEN_ORIENTATION_UNKNOWN = -1;
+
+ // Rotation threshold is 10 degrees. So if the rotation angle is within 10 degrees of any of
+ // the above angles, we will notify orientation changed.
+ private static int ROTATION_THRESHOLD = 10;
+
+
+ /**
+ * Cache the current rotation of the device.
+ */
+ private static int sCurrentOrientation = SCREEN_ORIENTATION_0;
+
+ public InCallOrientationEventListener(Context context) {
+ super(context);
+ }
+
+ /**
+ * Handles changes in device orientation. Notifies InCallPresenter of orientation changes.
+ *
+ * Note that this API receives sensor rotation in degrees as a param and we convert that to
+ * one of our screen orientation constants - (one of: {@link SCREEN_ORIENTATION_0},
+ * {@link SCREEN_ORIENTATION_90}, {@link SCREEN_ORIENTATION_180},
+ * {@link SCREEN_ORIENTATION_270}).
+ *
+ * @param rotation The new device sensor rotation in degrees
+ */
+ @Override
+ public void onOrientationChanged(int rotation) {
+ if (rotation == OrientationEventListener.ORIENTATION_UNKNOWN) {
+ return;
+ }
+
+ final int orientation = toScreenOrientation(rotation);
+
+ if (orientation != SCREEN_ORIENTATION_UNKNOWN && sCurrentOrientation != orientation) {
+ sCurrentOrientation = orientation;
+ InCallPresenter.getInstance().onDeviceOrientationChange(sCurrentOrientation);
+ }
+ }
+
+ /**
+ * Enables the OrientationEventListener and notifies listeners of current orientation if
+ * notify flag is true
+ * @param notify true or false. Notify device orientation changed if true.
+ */
+ public void enable(boolean notify) {
+ super.enable();
+ if (notify) {
+ InCallPresenter.getInstance().onDeviceOrientationChange(sCurrentOrientation);
+ }
+ }
+
+ /**
+ * Enables the OrientationEventListener with notify flag defaulting to false.
+ */
+ public void enable() {
+ enable(false);
+ }
+
+ /**
+ * Converts sensor rotation in degrees to screen orientation constants.
+ * @param rotation sensor rotation angle in degrees
+ * @return Screen orientation angle in degrees (0, 90, 180, 270). Returns -1 for degrees not
+ * within threshold to identify zones where orientation change should not be trigerred.
+ */
+ private int toScreenOrientation(int rotation) {
+ // Sensor orientation 90 is equivalent to screen orientation 270 and vice versa. This
+ // function returns the screen orientation. So we convert sensor rotation 90 to 270 and
+ // vice versa here.
+ if (isInLeftRange(rotation, SCREEN_ORIENTATION_360, ROTATION_THRESHOLD) ||
+ isInRightRange(rotation, SCREEN_ORIENTATION_0, ROTATION_THRESHOLD)) {
+ return SCREEN_ORIENTATION_0;
+ } else if (isWithinThreshold(rotation, SCREEN_ORIENTATION_90, ROTATION_THRESHOLD)) {
+ return SCREEN_ORIENTATION_270;
+ } else if (isWithinThreshold(rotation, SCREEN_ORIENTATION_180, ROTATION_THRESHOLD)) {
+ return SCREEN_ORIENTATION_180;
+ } else if (isWithinThreshold(rotation, SCREEN_ORIENTATION_270, ROTATION_THRESHOLD)) {
+ return SCREEN_ORIENTATION_90;
+ }
+ return SCREEN_ORIENTATION_UNKNOWN;
+ }
+
+ private static boolean isWithinRange(int value, int begin, int end) {
+ return value >= begin && value < end;
+ }
+
+ private static boolean isWithinThreshold(int value, int center, int threshold) {
+ return isWithinRange(value, center - threshold, center + threshold);
+ }
+
+ private static boolean isInLeftRange(int value, int center, int threshold) {
+ return isWithinRange(value, center - threshold, center);
+ }
+
+ private static boolean isInRightRange(int value, int center, int threshold) {
+ return isWithinRange(value, center, center + threshold);
+ }
+}
diff --git a/InCallUI/src/com/android/incallui/InCallPresenter.java b/InCallUI/src/com/android/incallui/InCallPresenter.java
index c8fe0cb77..836c9242e 100644
--- a/InCallUI/src/com/android/incallui/InCallPresenter.java
+++ b/InCallUI/src/com/android/incallui/InCallPresenter.java
@@ -1525,64 +1525,32 @@ public class InCallPresenter implements CallList.Listener,
}
/**
- * Handles changes to the device rotation.
+ * Notifies listeners of changes in orientation and notify calls of rotation angle change.
*
- * @param rotation The device rotation (one of: {@link Surface#ROTATION_0},
- * {@link Surface#ROTATION_90}, {@link Surface#ROTATION_180},
- * {@link Surface#ROTATION_270}).
+ * @param orientation The screen orientation of the device (one of:
+ * {@link InCallOrientationEventListener#SCREEN_ORIENTATION_0},
+ * {@link InCallOrientationEventListener#SCREEN_ORIENTATION_90},
+ * {@link InCallOrientationEventListener#SCREEN_ORIENTATION_180},
+ * {@link InCallOrientationEventListener#SCREEN_ORIENTATION_270}).
*/
- public void onDeviceRotationChange(int rotation) {
- Log.d(this, "onDeviceRotationChange: rotation=" + rotation);
- // First translate to rotation in degrees.
+ public void onDeviceOrientationChange(int orientation) {
+ Log.d(this, "onDeviceOrientationChange: orientation= " + orientation);
+
if (mCallList != null) {
- mCallList.notifyCallsOfDeviceRotation(toRotationAngle(rotation));
+ mCallList.notifyCallsOfDeviceRotation(orientation);
} else {
- Log.w(this, "onDeviceRotationChange: CallList is null.");
+ Log.w(this, "onDeviceOrientationChange: CallList is null.");
}
- }
- /**
- * Converts rotation constants to rotation in degrees.
- * @param rotation Rotation constants (one of: {@link Surface#ROTATION_0},
- * {@link Surface#ROTATION_90}, {@link Surface#ROTATION_180},
- * {@link Surface#ROTATION_270}).
- */
- public static int toRotationAngle(int rotation) {
- int rotationAngle;
- switch (rotation) {
- case Surface.ROTATION_0:
- rotationAngle = 0;
- break;
- case Surface.ROTATION_90:
- rotationAngle = 90;
- break;
- case Surface.ROTATION_180:
- rotationAngle = 180;
- break;
- case Surface.ROTATION_270:
- rotationAngle = 270;
- break;
- default:
- rotationAngle = 0;
- }
- return rotationAngle;
- }
-
- /**
- * Notifies listeners of changes in orientation (e.g. portrait/landscape).
- *
- * @param orientation The orientation of the device (one of: {@link Surface#ROTATION_0},
- * {@link Surface#ROTATION_90}, {@link Surface#ROTATION_180},
- * {@link Surface#ROTATION_270}).
- */
- public void onDeviceOrientationChange(int orientation) {
+ // Notify listeners of device orientation changed.
for (InCallOrientationListener listener : mOrientationListeners) {
listener.onDeviceOrientationChanged(orientation);
}
}
/**
- * Configures the in-call UI activity so it can change orientations or not.
+ * Configures the in-call UI activity so it can change orientations or not. Enables the
+ * orientation event listener if allowOrientationChange is true, disables it if false.
*
* @param allowOrientationChange {@code True} if the in-call UI can change between portrait
* and landscape. {@Code False} if the in-call UI should be locked in portrait.
@@ -1594,12 +1562,15 @@ public class InCallPresenter implements CallList.Listener,
}
if (!allowOrientationChange) {
- mInCallActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
+ mInCallActivity.setRequestedOrientation(
+ InCallOrientationEventListener.NO_SENSOR_SCREEN_ORIENTATION);
} else {
// Using SCREEN_ORIENTATION_FULL_SENSOR allows for reverse-portrait orientation, where
// SCREEN_ORIENTATION_SENSOR does not.
- mInCallActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
+ mInCallActivity.setRequestedOrientation(
+ InCallOrientationEventListener.FULL_SENSOR_SCREEN_ORIENTATION);
}
+ mInCallActivity.enableInCallOrientationEventListener(allowOrientationChange);
}
public void enableScreenTimeout(boolean enable) {
diff --git a/InCallUI/src/com/android/incallui/VideoCallFragment.java b/InCallUI/src/com/android/incallui/VideoCallFragment.java
index eca9ab883..7c83f6e7e 100644
--- a/InCallUI/src/com/android/incallui/VideoCallFragment.java
+++ b/InCallUI/src/com/android/incallui/VideoCallFragment.java
@@ -697,6 +697,33 @@ public class VideoCallFragment extends BaseFragment<VideoCallPresenter,
}
}
+ /**
+ * Sets the rotation of the preview surface. Called when the dimensions change due to a
+ * device orientation change.
+ *
+ * Please note that the screen orientation passed in is subtracted from 360 to get the actual
+ * preview rotation values.
+ *
+ * @param rotation The screen orientation. One of -
+ * {@link InCallOrientationEventListener#SCREEN_ORIENTATION_0},
+ * {@link InCallOrientationEventListener#SCREEN_ORIENTATION_90},
+ * {@link InCallOrientationEventListener#SCREEN_ORIENTATION_180},
+ * {@link InCallOrientationEventListener#SCREEN_ORIENTATION_270}).
+ */
+ @Override
+ public void setPreviewRotation(int orientation) {
+ Log.d(this, "setPreviewRotation: orientation=" + orientation);
+ if (sPreviewSurface != null) {
+ TextureView preview = sPreviewSurface.getTextureView();
+
+ if (preview == null ) {
+ return;
+ }
+
+ preview.setRotation(orientation);
+ }
+ }
+
@Override
public void setPreviewSurfaceSize(int width, int height) {
final boolean isPreviewSurfaceAvailable = sPreviewSurface != null;
diff --git a/InCallUI/src/com/android/incallui/VideoCallPresenter.java b/InCallUI/src/com/android/incallui/VideoCallPresenter.java
index eb9b62005..262adb46d 100644
--- a/InCallUI/src/com/android/incallui/VideoCallPresenter.java
+++ b/InCallUI/src/com/android/incallui/VideoCallPresenter.java
@@ -153,7 +153,7 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
/**
* Determines the device orientation (portrait/lanscape).
*/
- private int mDeviceOrientation;
+ private int mDeviceOrientation = InCallOrientationEventListener.SCREEN_ORIENTATION_0;
/**
* Tracks the state of the preview surface negotiation with the telephony layer.
@@ -247,7 +247,6 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
InCallVideoCallCallbackNotifier.getInstance().addSessionModificationListener(this);
mCurrentVideoState = VideoProfile.STATE_AUDIO_ONLY;
mCurrentCallState = Call.State.INVALID;
- mDeviceOrientation = ui.getCurrentRotation();
}
/**
@@ -697,12 +696,7 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
videoCall.setDisplaySurface(ui.getDisplayVideoSurface());
}
- final int rotation = ui.getCurrentRotation();
- if (rotation != VideoCallFragment.ORIENTATION_UNKNOWN) {
- videoCall.setDeviceOrientation(InCallPresenter.toRotationAngle(rotation));
- onDeviceOrientationChanged(rotation);
- }
-
+ videoCall.setDeviceOrientation(mDeviceOrientation);
enableCamera(videoCall, isCameraRequired(newVideoState));
}
mCurrentVideoState = newVideoState;
@@ -1010,21 +1004,31 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
/**
* Handles changes to the device orientation.
- *
- * @param orientation The device orientation (one of: {@link Surface#ROTATION_0},
- * {@link Surface#ROTATION_90}, {@link Surface#ROTATION_180},
- * {@link Surface#ROTATION_270}).
+ * @param orientation The screen orientation of the device (one of:
+ * {@link InCallOrientationEventListener#SCREEN_ORIENTATION_0},
+ * {@link InCallOrientationEventListener#SCREEN_ORIENTATION_90},
+ * {@link InCallOrientationEventListener#SCREEN_ORIENTATION_180},
+ * {@link InCallOrientationEventListener#SCREEN_ORIENTATION_270}).
*/
@Override
public void onDeviceOrientationChanged(int orientation) {
mDeviceOrientation = orientation;
- Point previewDimensions = getUi().getPreviewSize();
+
+ VideoCallUi ui = getUi();
+ if (ui == null) {
+ Log.e(this, "onDeviceOrientationChanged: VideoCallUi is null");
+ return;
+ }
+
+ Point previewDimensions = ui.getPreviewSize();
if (previewDimensions == null) {
return;
}
Log.d(this, "onDeviceOrientationChanged: orientation=" + orientation + " size: "
+ previewDimensions);
changePreviewDimensions(previewDimensions.x, previewDimensions.y);
+
+ ui.setPreviewRotation(mDeviceOrientation);
}
@Override
@@ -1074,10 +1078,12 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
/**
* Sets the preview surface size based on the current device orientation.
+ * See: {@link InCallOrientationEventListener#SCREEN_ORIENTATION_0},
+ * {@link InCallOrientationEventListener#SCREEN_ORIENTATION_90},
+ * {@link InCallOrientationEventListener#SCREEN_ORIENTATION_180},
+ * {@link InCallOrientationEventListener#SCREEN_ORIENTATION_270}).
*
- * @param orientation The device orientation (one of: {@link Surface#ROTATION_0},
- * {@link Surface#ROTATION_90}, {@link Surface#ROTATION_180},
- * {@link Surface#ROTATION_270}).
+ * @param orientation The device orientation
* @param aspectRatio The aspect ratio of the camera (width / height).
*/
private void setPreviewSize(int orientation, float aspectRatio) {
@@ -1089,8 +1095,8 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
int height;
int width;
- if (orientation == Surface.ROTATION_90 || orientation == Surface.ROTATION_270) {
- // Landscape or reverse landscape orientation.
+ if (orientation == InCallOrientationEventListener.SCREEN_ORIENTATION_90 ||
+ orientation == InCallOrientationEventListener.SCREEN_ORIENTATION_270) {
width = (int) (mMinimumVideoDimension * aspectRatio);
height = (int) mMinimumVideoDimension;
} else {
@@ -1374,5 +1380,6 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
void cleanupSurfaces();
ImageView getPreviewPhotoView();
void adjustPreviewLocation(boolean shiftUp, int offset);
+ void setPreviewRotation(int orientation);
}
}