diff --git a/src/com/android/phone/AccelerometerListener.java b/src/com/android/phone/AccelerometerListener.java index 49d4a72e9..3b21dd41c 100644 --- a/src/com/android/phone/AccelerometerListener.java +++ b/src/com/android/phone/AccelerometerListener.java @@ -48,16 +48,21 @@ public final class AccelerometerListener { private OrientationListener mListener; - // Device orientation - public static final int ORIENTATION_UNKNOWN = 0; - public static final int ORIENTATION_VERTICAL = 1; - public static final int ORIENTATION_HORIZONTAL = 2; + // Device orientation + public static final int ORIENTATION_UNKNOWN = 0; + public static final int ORIENTATION_VERTICAL = 1; + public static final int ORIENTATION_HORIZONTAL = 2; - private static final int ORIENTATION_CHANGED = 1234; + public static final int ORIENTATION_FLIPDOWN = 3; + public static final int ORIENTATION_PICKUP = 4; - private static final int VERTICAL_DEBOUNCE = 100; - private static final int HORIZONTAL_DEBOUNCE = 500; - private static final double VERTICAL_ANGLE = 50.0; + private static final int ORIENTATION_CHANGED = 1234; + + private static final int VERTICAL_DEBOUNCE = 100; + private static final int HORIZONTAL_DEBOUNCE = 500; + private static final double VERTICAL_ANGLE = 50.0; + + private boolean mEnable = false; public interface OrientationListener { public void orientationChanged(int orientation); @@ -68,7 +73,11 @@ public AccelerometerListener(Context context, OrientationListener listener) { mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE); mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); } - + + public boolean isEnabled() { + return mEnable; + } + public void enable(boolean enable) { if (DEBUG) Log.d(TAG, "enable(" + enable + ")"); synchronized (this) { @@ -82,6 +91,8 @@ public void enable(boolean enable) { mHandler.removeMessages(ORIENTATION_CHANGED); } } + + mEnable = enable; } private void setOrientation(int orientation) { @@ -126,6 +137,17 @@ private void onSensorEvent(double x, double y, double z) { // convert to degrees angle = angle * 180.0 / Math.PI; int orientation = (angle > VERTICAL_ANGLE ? ORIENTATION_VERTICAL : ORIENTATION_HORIZONTAL); + + // check for flipdown + if (z < -8.5) { + orientation = ORIENTATION_FLIPDOWN; + } + + // check for pickup + if (y > 7) { + orientation = ORIENTATION_PICKUP; + } + if (VDEBUG) Log.d(TAG, "angle: " + angle + " orientation: " + orientation); setOrientation(orientation); } diff --git a/src/com/android/phone/InCallScreen.java b/src/com/android/phone/InCallScreen.java index 26733ed54..690ffe2cb 100755 --- a/src/com/android/phone/InCallScreen.java +++ b/src/com/android/phone/InCallScreen.java @@ -3331,7 +3331,7 @@ private void dismissProgressIndication() { * Answer a ringing call. This method does nothing if there's no * ringing or waiting call. */ - private void internalAnswerCall() { + public void internalAnswerCall() { log("internalAnswerCall()..."); // if (DBG) PhoneUtils.dumpCallState(mPhone); diff --git a/src/com/android/phone/PhoneApp.java b/src/com/android/phone/PhoneApp.java index 1b7964ce3..0b789c1eb 100644 --- a/src/com/android/phone/PhoneApp.java +++ b/src/com/android/phone/PhoneApp.java @@ -16,6 +16,8 @@ package com.android.phone; +//import android.widget.Toast; + import android.app.Activity; import android.app.Application; import android.app.KeyguardManager; @@ -67,6 +69,12 @@ import android.app.PendingIntent; import android.os.HandlerThread; +// motion call +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; + /** * Top-level Application class for the Phone app. */ @@ -108,6 +116,8 @@ public class PhoneApp extends Application implements AccelerometerListener.Orien private static final int EVENT_TTY_MODE_GET = 15; private static final int EVENT_TTY_MODE_SET = 16; private static final int EVENT_START_SIP_SERVICE = 17; + + public static final int TEST = 1; // The MMI codes are also used by the InCallScreen. public static final int MMI_INITIATE = 51; @@ -204,6 +214,8 @@ public enum WakeState { private KeyguardManager mKeyguardManager; private AccelerometerListener mAccelerometerListener; private int mOrientation = AccelerometerListener.ORIENTATION_UNKNOWN; + + private int mLastOrientation = AccelerometerListener.ORIENTATION_FLIPDOWN; // Broadcast receiver for various intent broadcasts (see onCreate()) private final BroadcastReceiver mReceiver = new PhoneAppBroadcastReceiver(); @@ -246,6 +258,13 @@ public enum WakeState { private AlarmManager mAM; private HandlerThread mVibrationThread; private Handler mVibrationHandler; + + //motion call sensor variables + private SensorManager mSensorManager; + private Sensor mSensor; + private boolean isNearFace; + private boolean mEnabled = false; + private boolean wasAlreadyNotNearFace = false; /** * Set the restore mute state flag. Used when we are setting the mute state @@ -701,6 +720,40 @@ BluetoothHandsfree getBluetoothHandsfree() { static String getCallScreenClassName() { return InCallScreen.class.getName(); } + + /** + * SensorEventListener to listen to Proximity Sensor needed to motion accept + * a call + */ + SensorEventListener mSensorListener = new SensorEventListener() { + public void onSensorChanged(SensorEvent event) { + onProximitySensorEvent(event.values[0]); + if (event.values[0] > 0) { + wasAlreadyNotNearFace = true; + } + } + + public void onAccuracyChanged(Sensor sensor, int accuracy) { + // ignore + } + }; + + private void onProximitySensorEvent(float sensorValue) { + isNearFace = (sensorValue > 0) ? false : true; + } + + private void enableProximitySensor(boolean enable) { + if (enable) { + mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); + mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); + mSensorManager.registerListener(mSensorListener, mSensor, + SensorManager.SENSOR_DELAY_NORMAL); + mEnabled = true; + } else { + mSensorManager.unregisterListener(mSensorListener); + mEnabled = false; + } + } /** * Starts the InCallScreen Activity. @@ -1103,7 +1156,20 @@ private void updatePokeLock() { + ", showingDisc " + showingDisconnectedConnection + ")"); // keepScreenOn == true means we'll hold a full wake lock: requestWakeState(keepScreenOn ? WakeState.FULL : WakeState.SLEEP); - } + + // if phone is ringing, enable AccelerometerListener + // to check for flipdown and pickup + if (isRinging) { + if (!mAccelerometerListener.isEnabled()) { + mAccelerometerListener.enable(true); + } + if (!mEnabled) { + Log.w(LOG_TAG, "if (!mEnabled)"); + enableProximitySensor(true); + } + Log.w(LOG_TAG, "isRinging"); + } + } /** * Wrapper around the PowerManagerService.preventScreenOn() API. @@ -1198,7 +1264,14 @@ private void updatePokeLock() { */ /* package */ void updateProximitySensorMode(Phone.State state) { if (VDBG) Log.d(LOG_TAG, "updateProximitySensorMode: state = " + state); - + + if (state == Phone.State.IDLE) { + mLastOrientation = AccelerometerListener.ORIENTATION_FLIPDOWN; + + if (mAccelerometerListener.isEnabled()) mAccelerometerListener.enable(false); + if (mEnabled) enableProximitySensor(false); + } + if (proximitySensorModeEnabled()) { synchronized (mProximityWakeLock) { // turn proximity sensor off and turn screen on immediately if @@ -1246,10 +1319,32 @@ private void updatePokeLock() { } } - public void orientationChanged(int orientation) { - mOrientation = orientation; - updateProximitySensorMode(mCM.getState()); - } + public void orientationChanged(int orientation) { + mOrientation = orientation; + updateProximitySensorMode(mCM.getState()); + switch (orientation) { + case AccelerometerListener.ORIENTATION_FLIPDOWN: + if ((mLastOrientation != AccelerometerListener.ORIENTATION_FLIPDOWN)) { + mInCallScreen.hangupRingingCall(); + } + break; + case AccelerometerListener.ORIENTATION_PICKUP: + if (isNearFace) { + if (wasAlreadyNotNearFace) { + mInCallScreen.internalAnswerCall(); + } else { + //Toast.makeText(this, "NOT wasAlreadyNotNearFace", + // Toast.LENGTH_SHORT).show(); + } + } else { + //Toast.makeText(this, "NOT isNearFace", Toast.LENGTH_SHORT) + // .show(); + } + break; + } + + mLastOrientation = orientation; + } /** * Notifies the phone app when the phone state changes.