summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorke Lee <yorkelee@google.com>2015-09-04 15:31:10 -0700
committerYorke Lee <yorkelee@google.com>2015-09-04 15:34:41 -0700
commit49691487b9924c610c16f42d3fbfdd3092def425 (patch)
tree17bebb7b77743d2d075e73de77c4e4d59d978233
parentf053e4b3f423caa5b3215792f5c021168c7bacb0 (diff)
downloadInCallUI-49691487b9924c610c16f42d3fbfdd3092def425.tar.gz
Disable AccelerometerListener when display is off
Unregister the accelerometer listener when the screen is off to reduce power consumption. Slight refactor of component constructors to facilitate testing. Add test. Bug: 23498050 Change-Id: If1971a39e8a418253f6611116c855e3c6cf81b93
-rw-r--r--src/com/android/incallui/AccelerometerListener.java13
-rw-r--r--src/com/android/incallui/InCallServiceImpl.java5
-rw-r--r--src/com/android/incallui/ProximitySensor.java67
-rw-r--r--tests/src/com/android/incallui/ProximitySensorTest.java64
4 files changed, 142 insertions, 7 deletions
diff --git a/src/com/android/incallui/AccelerometerListener.java b/src/com/android/incallui/AccelerometerListener.java
index ca8e7d0a..b5ad2967 100644
--- a/src/com/android/incallui/AccelerometerListener.java
+++ b/src/com/android/incallui/AccelerometerListener.java
@@ -30,7 +30,7 @@ import android.util.Log;
* orientation of the phone. The client of this class is notified when
* the orientation changes between horizontal and vertical.
*/
-public final class AccelerometerListener {
+public class AccelerometerListener {
private static final String TAG = "AccelerometerListener";
private static final boolean DEBUG = true;
private static final boolean VDEBUG = false;
@@ -63,12 +63,15 @@ public final class AccelerometerListener {
public void orientationChanged(int orientation);
}
- public AccelerometerListener(Context context, OrientationListener listener) {
- mListener = listener;
+ public AccelerometerListener(Context context) {
mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
}
+ public void setListener(OrientationListener listener) {
+ mListener = listener;
+ }
+
public void enable(boolean enable) {
if (DEBUG) Log.d(TAG, "enable(" + enable + ")");
synchronized (this) {
@@ -155,7 +158,9 @@ public final class AccelerometerListener {
: (mOrientation == ORIENTATION_VERTICAL ? "vertical"
: "unknown")));
}
- mListener.orientationChanged(mOrientation);
+ if (mListener != null) {
+ mListener.orientationChanged(mOrientation);
+ }
}
break;
}
diff --git a/src/com/android/incallui/InCallServiceImpl.java b/src/com/android/incallui/InCallServiceImpl.java
index 89fa1326..8e65f1af 100644
--- a/src/com/android/incallui/InCallServiceImpl.java
+++ b/src/com/android/incallui/InCallServiceImpl.java
@@ -68,7 +68,10 @@ public class InCallServiceImpl extends InCallService {
AudioModeProvider.getInstance(),
new StatusBarNotifier(context, contactInfoCache),
contactInfoCache,
- new ProximitySensor(context, AudioModeProvider.getInstance())
+ new ProximitySensor(
+ context,
+ AudioModeProvider.getInstance(),
+ new AccelerometerListener(context))
);
InCallPresenter.getInstance().onServiceBind();
InCallPresenter.getInstance().maybeStartRevealAnimation(intent);
diff --git a/src/com/android/incallui/ProximitySensor.java b/src/com/android/incallui/ProximitySensor.java
index 05a86d35..401ebd12 100644
--- a/src/com/android/incallui/ProximitySensor.java
+++ b/src/com/android/incallui/ProximitySensor.java
@@ -18,8 +18,11 @@ package com.android.incallui;
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;
@@ -44,6 +47,7 @@ public class ProximitySensor implements AccelerometerListener.OrientationListene
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;
@@ -53,7 +57,8 @@ public class ProximitySensor implements AccelerometerListener.OrientationListene
// Gets updated whenever there is a Configuration change
private boolean mIsHardKeyboardOpen;
- public ProximitySensor(Context context, AudioModeProvider audioModeProvider) {
+ 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(
@@ -62,7 +67,13 @@ public class ProximitySensor implements AccelerometerListener.OrientationListene
Log.w(TAG, "Device does not support proximity wake lock.");
mProximityWakeLock = null;
}
- mAccelerometerListener = new AccelerometerListener(context, this);
+ mAccelerometerListener = accelerometerListener;
+ mAccelerometerListener.setListener(this);
+
+ mDisplayListener = new ProximityDisplayListener(
+ (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE));
+ mDisplayListener.register();
+
mAudioModeProvider = audioModeProvider;
mAudioModeProvider.addListener(this);
}
@@ -71,6 +82,7 @@ public class ProximitySensor implements AccelerometerListener.OrientationListene
mAudioModeProvider.removeListener(this);
mAccelerometerListener.enable(false);
+ mDisplayListener.unregister();
turnOffProximitySensor(true);
}
@@ -151,10 +163,16 @@ public class ProximitySensor implements AccelerometerListener.OrientationListene
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();
@@ -251,4 +269,49 @@ public class ProximitySensor implements AccelerometerListener.OrientationListene
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) {
+ }
+ }
}
diff --git a/tests/src/com/android/incallui/ProximitySensorTest.java b/tests/src/com/android/incallui/ProximitySensorTest.java
new file mode 100644
index 00000000..d7b2f64b
--- /dev/null
+++ b/tests/src/com/android/incallui/ProximitySensorTest.java
@@ -0,0 +1,64 @@
+/*
+ * 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 static org.mockito.Mockito.anyBoolean;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.test.InstrumentationTestCase;
+
+import com.android.incallui.InCallPresenter.InCallState;
+
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+public class ProximitySensorTest extends InstrumentationTestCase {
+ @Mock private AccelerometerListener mAccelerometerListener;
+ private MockCallListWrapper mCallList;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ System.setProperty("dexmaker.dexcache",
+ getInstrumentation().getTargetContext().getCacheDir().getPath());
+ MockitoAnnotations.initMocks(this);
+ mCallList = new MockCallListWrapper();
+ }
+
+ public void testAccelerometerBehaviorOnDisplayChange() {
+ final ProximitySensor proximitySensor =
+ new ProximitySensor(
+ getInstrumentation().getContext(),
+ new AudioModeProvider(),
+ mAccelerometerListener);
+ verify(mAccelerometerListener, never()).enable(anyBoolean());
+ proximitySensor.onStateChange(null, InCallState.OUTGOING, mCallList.getCallList());
+ verify(mAccelerometerListener).enable(true);
+ verify(mAccelerometerListener, never()).enable(false);
+
+ proximitySensor.onDisplayStateChanged(false);
+ verify(mAccelerometerListener).enable(true);
+ verify(mAccelerometerListener).enable(false);
+
+ proximitySensor.onDisplayStateChanged(true);
+ verify(mAccelerometerListener, times(2)).enable(true);
+ verify(mAccelerometerListener).enable(false);
+ }
+}