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
commit6cc5b8a51ea9804fd39030fc7879a112cd7899f0 (patch)
tree3b87365857ec9391066387f453f46fe5c765144d
parentb6ef8696d2d0f7631665f57aabd185393e2e9480 (diff)
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--InCallUI/src/com/android/incallui/AccelerometerListener.java13
-rw-r--r--InCallUI/src/com/android/incallui/InCallServiceImpl.java5
-rw-r--r--InCallUI/src/com/android/incallui/ProximitySensor.java67
-rw-r--r--InCallUI/tests/src/com/android/incallui/ProximitySensorTest.java64
4 files changed, 142 insertions, 7 deletions
diff --git a/InCallUI/src/com/android/incallui/AccelerometerListener.java b/InCallUI/src/com/android/incallui/AccelerometerListener.java
index ca8e7d0a4..b5ad29675 100644
--- a/InCallUI/src/com/android/incallui/AccelerometerListener.java
+++ b/InCallUI/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/InCallUI/src/com/android/incallui/InCallServiceImpl.java b/InCallUI/src/com/android/incallui/InCallServiceImpl.java
index 89fa1326c..8e65f1af5 100644
--- a/InCallUI/src/com/android/incallui/InCallServiceImpl.java
+++ b/InCallUI/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/InCallUI/src/com/android/incallui/ProximitySensor.java b/InCallUI/src/com/android/incallui/ProximitySensor.java
index 05a86d35c..401ebd129 100644
--- a/InCallUI/src/com/android/incallui/ProximitySensor.java
+++ b/InCallUI/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/InCallUI/tests/src/com/android/incallui/ProximitySensorTest.java b/InCallUI/tests/src/com/android/incallui/ProximitySensorTest.java
new file mode 100644
index 000000000..d7b2f64b6
--- /dev/null
+++ b/InCallUI/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);
+ }
+}