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-09 10:46:56 -0700
commitbc6ad72707bb3eebce0b3dd8ef408b49957148a7 (patch)
tree5700f0791a86d5fc146234a9b9e1bfbdb30e36b1
parent7aa3c70e32c26933db5e7e98069ed3c8a814b979 (diff)
DO NOT MERGE 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 e1a34117c..b9a5aae87 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);
+ }
+}