summaryrefslogtreecommitdiff
path: root/InCallUI/src/com/android/incallui/ProximitySensor.java
diff options
context:
space:
mode:
Diffstat (limited to 'InCallUI/src/com/android/incallui/ProximitySensor.java')
-rw-r--r--InCallUI/src/com/android/incallui/ProximitySensor.java317
1 files changed, 0 insertions, 317 deletions
diff --git a/InCallUI/src/com/android/incallui/ProximitySensor.java b/InCallUI/src/com/android/incallui/ProximitySensor.java
deleted file mode 100644
index 3c9fd9370..000000000
--- a/InCallUI/src/com/android/incallui/ProximitySensor.java
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Copyright (C) 2013 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 com.google.common.base.Objects;
-
-import android.content.Context;
-import android.content.res.Configuration;
-import android.hardware.display.DisplayManager;
-import android.hardware.display.DisplayManager.DisplayListener;
-import android.os.PowerManager;
-import android.telecom.CallAudioState;
-import android.view.Display;
-
-import com.android.incallui.AudioModeProvider.AudioModeListener;
-import com.android.incallui.InCallPresenter.InCallState;
-import com.android.incallui.InCallPresenter.InCallStateListener;
-
-/**
- * Class manages the proximity sensor for the in-call UI.
- * We enable the proximity sensor while the user in a phone call. The Proximity sensor turns off
- * the touchscreen and display when the user is close to the screen to prevent user's cheek from
- * causing touch events.
- * The class requires special knowledge of the activity and device state to know when the proximity
- * sensor should be enabled and disabled. Most of that state is fed into this class through
- * public methods.
- */
-public class ProximitySensor implements AccelerometerListener.OrientationListener,
- InCallStateListener, AudioModeListener {
- private static final String TAG = ProximitySensor.class.getSimpleName();
-
- private final PowerManager mPowerManager;
- private final PowerManager.WakeLock mProximityWakeLock;
- private final AudioModeProvider mAudioModeProvider;
- private final AccelerometerListener mAccelerometerListener;
- private final ProximityDisplayListener mDisplayListener;
- private int mOrientation = AccelerometerListener.ORIENTATION_UNKNOWN;
- private boolean mUiShowing = false;
- private boolean mIsPhoneOffhook = false;
- private boolean mDialpadVisible;
-
- // True if the keyboard is currently *not* hidden
- // Gets updated whenever there is a Configuration change
- private boolean mIsHardKeyboardOpen;
-
- public ProximitySensor(Context context, AudioModeProvider audioModeProvider,
- AccelerometerListener accelerometerListener) {
- mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
- if (mPowerManager.isWakeLockLevelSupported(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)) {
- mProximityWakeLock = mPowerManager.newWakeLock(
- PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, TAG);
- } else {
- Log.w(TAG, "Device does not support proximity wake lock.");
- mProximityWakeLock = null;
- }
- mAccelerometerListener = accelerometerListener;
- mAccelerometerListener.setListener(this);
-
- mDisplayListener = new ProximityDisplayListener(
- (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE));
- mDisplayListener.register();
-
- mAudioModeProvider = audioModeProvider;
- mAudioModeProvider.addListener(this);
- }
-
- public void tearDown() {
- mAudioModeProvider.removeListener(this);
-
- mAccelerometerListener.enable(false);
- mDisplayListener.unregister();
-
- turnOffProximitySensor(true);
- }
-
- /**
- * Called to identify when the device is laid down flat.
- */
- @Override
- public void orientationChanged(int orientation) {
- mOrientation = orientation;
- updateProximitySensorMode();
- }
-
- /**
- * Called to keep track of the overall UI state.
- */
- @Override
- public void onStateChange(InCallState oldState, InCallState newState, CallList callList) {
- // We ignore incoming state because we do not want to enable proximity
- // sensor during incoming call screen. We check hasLiveCall() because a disconnected call
- // can also put the in-call screen in the INCALL state.
- boolean hasOngoingCall = InCallState.INCALL == newState && callList.hasLiveCall();
- boolean isOffhook = (InCallState.OUTGOING == newState) || hasOngoingCall;
-
- if (isOffhook != mIsPhoneOffhook) {
- mIsPhoneOffhook = isOffhook;
-
- mOrientation = AccelerometerListener.ORIENTATION_UNKNOWN;
- mAccelerometerListener.enable(mIsPhoneOffhook);
-
- updateProximitySensorMode();
- }
- }
-
- @Override
- public void onSupportedAudioMode(int modeMask) {
- }
-
- @Override
- public void onMute(boolean muted) {
- }
-
- /**
- * Called when the audio mode changes during a call.
- */
- @Override
- public void onAudioMode(int mode) {
- updateProximitySensorMode();
- }
-
- public void onDialpadVisible(boolean visible) {
- mDialpadVisible = visible;
- updateProximitySensorMode();
- }
-
- /**
- * Called by InCallActivity to listen for hard keyboard events.
- */
- public void onConfigurationChanged(Configuration newConfig) {
- mIsHardKeyboardOpen = newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO;
-
- // Update the Proximity sensor based on keyboard state
- updateProximitySensorMode();
- }
-
- /**
- * Used to save when the UI goes in and out of the foreground.
- */
- public void onInCallShowing(boolean showing) {
- if (showing) {
- mUiShowing = true;
-
- // We only consider the UI not showing for instances where another app took the foreground.
- // If we stopped showing because the screen is off, we still consider that showing.
- } else if (mPowerManager.isScreenOn()) {
- mUiShowing = false;
- }
- updateProximitySensorMode();
- }
-
- void onDisplayStateChanged(boolean isDisplayOn) {
- Log.i(this, "isDisplayOn: " + isDisplayOn);
- mAccelerometerListener.enable(isDisplayOn);
- }
-
- /**
- * TODO: There is no way to determine if a screen is off due to proximity or if it is
- * legitimately off, but if ever we can do that in the future, it would be useful here.
- * Until then, this function will simply return true of the screen is off.
- * TODO: Investigate whether this can be replaced with the ProximityDisplayListener.
- */
- public boolean isScreenReallyOff() {
- return !mPowerManager.isScreenOn();
- }
-
- private void turnOnProximitySensor() {
- if (mProximityWakeLock != null) {
- if (!mProximityWakeLock.isHeld()) {
- Log.i(this, "Acquiring proximity wake lock");
- mProximityWakeLock.acquire();
- } else {
- Log.i(this, "Proximity wake lock already acquired");
- }
- }
- }
-
- private void turnOffProximitySensor(boolean screenOnImmediately) {
- if (mProximityWakeLock != null) {
- if (mProximityWakeLock.isHeld()) {
- Log.i(this, "Releasing proximity wake lock");
- int flags =
- (screenOnImmediately ? 0 : PowerManager.RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY);
- mProximityWakeLock.release(flags);
- } else {
- Log.i(this, "Proximity wake lock already released");
- }
- }
- }
-
- /**
- * Updates the wake lock used to control proximity sensor behavior,
- * based on the current state of the phone.
- *
- * On devices that have a proximity sensor, to avoid false touches
- * during a call, we hold a PROXIMITY_SCREEN_OFF_WAKE_LOCK wake lock
- * whenever the phone is off hook. (When held, that wake lock causes
- * the screen to turn off automatically when the sensor detects an
- * object close to the screen.)
- *
- * This method is a no-op for devices that don't have a proximity
- * sensor.
- *
- * Proximity wake lock will *not* be held if any one of the
- * conditions is true while on a call:
- * 1) If the audio is routed via Bluetooth
- * 2) If a wired headset is connected
- * 3) if the speaker is ON
- * 4) If the slider is open(i.e. the hardkeyboard is *not* hidden)
- */
- private synchronized void updateProximitySensorMode() {
- final int audioMode = mAudioModeProvider.getAudioMode();
-
- // turn proximity sensor off and turn screen on immediately if
- // we are using a headset, the keyboard is open, or the device
- // is being held in a horizontal position.
- boolean screenOnImmediately = (CallAudioState.ROUTE_WIRED_HEADSET == audioMode
- || CallAudioState.ROUTE_SPEAKER == audioMode
- || CallAudioState.ROUTE_BLUETOOTH == audioMode
- || mIsHardKeyboardOpen);
-
- // We do not keep the screen off when the user is outside in-call screen and we are
- // horizontal, but we do not force it on when we become horizontal until the
- // proximity sensor goes negative.
- final boolean horizontal =
- (mOrientation == AccelerometerListener.ORIENTATION_HORIZONTAL);
- screenOnImmediately |= !mUiShowing && horizontal;
-
- // We do not keep the screen off when dialpad is visible, we are horizontal, and
- // the in-call screen is being shown.
- // At that moment we're pretty sure users want to use it, instead of letting the
- // proximity sensor turn off the screen by their hands.
- screenOnImmediately |= mDialpadVisible && horizontal;
-
- Log.v(this, "screenonImmediately: ", screenOnImmediately);
-
- Log.i(this, Objects.toStringHelper(this)
- .add("keybrd", mIsHardKeyboardOpen ? 1 : 0)
- .add("dpad", mDialpadVisible ? 1 : 0)
- .add("offhook", mIsPhoneOffhook ? 1 : 0)
- .add("hor", horizontal ? 1 : 0)
- .add("ui", mUiShowing ? 1 : 0)
- .add("aud", CallAudioState.audioRouteToString(audioMode))
- .toString());
-
- if (mIsPhoneOffhook && !screenOnImmediately) {
- Log.d(this, "Turning on proximity sensor");
- // Phone is in use! Arrange for the screen to turn off
- // automatically when the sensor detects a close object.
- turnOnProximitySensor();
- } else {
- Log.d(this, "Turning off proximity sensor");
- // Phone is either idle, or ringing. We don't want any special proximity sensor
- // behavior in either case.
- turnOffProximitySensor(screenOnImmediately);
- }
- }
-
- /**
- * Implementation of a {@link DisplayListener} that maintains a binary state:
- * Screen on vs screen off. Used by the proximity sensor manager to decide whether or not
- * it needs to listen to accelerometer events.
- */
- public class ProximityDisplayListener implements DisplayListener {
- private DisplayManager mDisplayManager;
- private boolean mIsDisplayOn = true;
-
- ProximityDisplayListener(DisplayManager displayManager) {
- mDisplayManager = displayManager;
- }
-
- void register() {
- mDisplayManager.registerDisplayListener(this, null);
- }
-
- void unregister() {
- mDisplayManager.unregisterDisplayListener(this);
- }
-
- @Override
- public void onDisplayRemoved(int displayId) {
- }
-
- @Override
- public void onDisplayChanged(int displayId) {
- if (displayId == Display.DEFAULT_DISPLAY) {
- final Display display = mDisplayManager.getDisplay(displayId);
-
- final boolean isDisplayOn = display.getState() != Display.STATE_OFF;
- // For call purposes, we assume that as long as the screen is not truly off, it is
- // considered on, even if it is in an unknown or low power idle state.
- if (isDisplayOn != mIsDisplayOn) {
- mIsDisplayOn = isDisplayOn;
- onDisplayStateChanged(mIsDisplayOn);
- }
- }
- }
-
- @Override
- public void onDisplayAdded(int displayId) {
- }
- }
-}