diff options
author | Santos Cordon <santoscordon@google.com> | 2013-09-05 13:22:07 -0700 |
---|---|---|
committer | Santos Cordon <santoscordon@google.com> | 2013-09-09 12:18:12 -0700 |
commit | 1f63d2d8e8db3616c16886952813b3d0473216e7 (patch) | |
tree | 9ffb5c9a744cc5679c59091e617c00acc4209193 /InCallUI/src/com/android/incallui/ProximitySensor.java | |
parent | 24deb0f78f1854bfc273bb888e7fd4ac123bcc22 (diff) |
Improve lifecycle ordering for InCallUI
This CL rearranges startup and teardown of InCallUI to reduce the number
of race conditions resulting in runtime exceptions and app crashes.
At a high level this CL fixes the following:
- TeleService should be able to unbind and rebind at any time without
causing problems in the UI. (Fixes to InCallPresenter)
- On weird occasions we were seeing secondary UIs pop up if we
rebound while the older UI was still up and one of the UIs would be
orphaned on the foreground.
- call notifications can be sent during (1) activity startup, (2)
activity lifetime, (3) activity destruction, (4) no activity...and
nothing should crash.
- Lots of crashes when notifications came during destruction and
startup. (Fixed setup in InCallActivity + presenters, and
startup/teardown ordering in InCallPresenter)
Details:
(1) InCallPresenter handed out instances of member classes to the UI
classes, but upon unbinding and rebinding, the classes were
recreated. This meant that the activity which was potentially still up
had stale versions of AudioModeProvider and ProximitySensor.
- Classes created/used by CallHandlerService are now singletons so that
they do not change from one bind to the other. If the service tries
to initialize InCallPresenter while the activity is still up (and so
we haven't yet torn down) we reuse the reuse the previous
initialization since there is no need to recreate them, and classes
in the Activity dont ever become stale.
(2) We were recreating new copies of InCallActivity on updates that
occur while tearing down the previous activity. This caused weird
errors where second emptier activities were up after all calls ended.
- Solution to this was to ignore all updates while we are finishing the
activity. When the activity is finally finished, we check if we
should bring up a new activity in case some update came while we were
finishing.
(3) We set listeners on presenters from a parent class that wasn't aware
of UI transitions.
- All Presenters are not responsible for setting and unsetting their
listeners. This allows them to unset them before their UI goes away.
+ renamed HIDDEN to NO_CALLS as hidden was confusing to developers
which associated the term with foreground/backgroundness of the app.
+ Improved some logging
bug:10573125
Change-Id: I2d1af6a6e972b3b3bd93af839054e879f0b74b4f
Diffstat (limited to 'InCallUI/src/com/android/incallui/ProximitySensor.java')
-rw-r--r-- | InCallUI/src/com/android/incallui/ProximitySensor.java | 40 |
1 files changed, 22 insertions, 18 deletions
diff --git a/InCallUI/src/com/android/incallui/ProximitySensor.java b/InCallUI/src/com/android/incallui/ProximitySensor.java index 4befb2b25..c28a69e5e 100644 --- a/InCallUI/src/com/android/incallui/ProximitySensor.java +++ b/InCallUI/src/com/android/incallui/ProximitySensor.java @@ -24,6 +24,7 @@ import com.android.incallui.AudioModeProvider.AudioModeListener; import com.android.incallui.InCallPresenter.InCallState; import com.android.incallui.InCallPresenter.InCallStateListener; import com.android.services.telephony.common.AudioMode; +import com.google.common.base.Objects; /** * Class manages the proximity sensor for the in-call UI. @@ -83,13 +84,17 @@ public class ProximitySensor implements AccelerometerListener.OrientationListene public void onStateChange(InCallState state, CallList callList) { // We ignore incoming state because we do not want to enable proximity // sensor during incoming call screen - mIsPhoneOffhook = (InCallState.INCALL == state + boolean isOffhook = (InCallState.INCALL == state || InCallState.OUTGOING == state); - mOrientation = AccelerometerListener.ORIENTATION_UNKNOWN; - mAccelerometerListener.enable(mIsPhoneOffhook); + if (isOffhook != mIsPhoneOffhook) { + mIsPhoneOffhook = isOffhook; - updateProximitySensorMode(); + mOrientation = AccelerometerListener.ORIENTATION_UNKNOWN; + mAccelerometerListener.enable(mIsPhoneOffhook); + + updateProximitySensorMode(); + } } @Override @@ -169,17 +174,10 @@ public class ProximitySensor implements AccelerometerListener.OrientationListene * 4) If the slider is open(i.e. the hardkeyboard is *not* hidden) */ private void updateProximitySensorMode() { - Log.i(this, "updateProximitySensorMode"); - if (proximitySensorModeEnabled()) { - Log.i(this, "keyboard open: " + mIsHardKeyboardOpen); - Log.i(this, "dialpad visible: " + mDialpadVisible); - Log.v(this, "isOffhook: ", mIsPhoneOffhook); - synchronized (mProximityWakeLock) { final int audioMode = mAudioModeProvider.getAudioMode(); - Log.i(this, "audioMode: " + AudioMode.toString(audioMode)); // turn proximity sensor off and turn screen on immediately if // we are using a headset, the keyboard is open, or the device @@ -194,7 +192,6 @@ public class ProximitySensor implements AccelerometerListener.OrientationListene // proximity sensor goes negative. final boolean horizontal = (mOrientation == AccelerometerListener.ORIENTATION_HORIZONTAL); - Log.i(this, "horizontal: " + horizontal); screenOnImmediately |= !mUiShowing && horizontal; // We do not keep the screen off when dialpad is visible, we are horizontal, and @@ -205,22 +202,29 @@ public class ProximitySensor implements AccelerometerListener.OrientationListene 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("aud", audioMode) + .add("hor", horizontal ? 1 : 0).toString()); + if (mIsPhoneOffhook && !screenOnImmediately) { - Log.i(this, "turning on proximity sensor"); + final String logStr = "turning off proximity sensor: "; // Phone is in use! Arrange for the screen to turn off // automatically when the sensor detects a close object. if (!mProximityWakeLock.isHeld()) { - Log.d(this, "updateProximitySensorMode: acquiring..."); + Log.i(this, logStr + "acquiring"); mProximityWakeLock.acquire(); } else { - Log.v(this, "updateProximitySensorMode: lock already held."); + Log.i(this, logStr + "already acquired"); } } else { - Log.i(this, "turning off proximity sensor"); + final String logStr = "turning off proximity sensor: "; // Phone is either idle, or ringing. We don't want any // special proximity sensor behavior in either case. if (mProximityWakeLock.isHeld()) { - Log.d(this, "updateProximitySensorMode: releasing..."); + Log.i(this, logStr + "releasing"); // Wait until user has moved the phone away from his head if we are // releasing due to the phone call ending. // Qtherwise, turn screen on immediately @@ -228,7 +232,7 @@ public class ProximitySensor implements AccelerometerListener.OrientationListene (screenOnImmediately ? 0 : PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE); mProximityWakeLock.release(flags); } else { - Log.v(this, "updateProximitySensorMode: lock already released."); + Log.i(this, logStr + "already released"); } } } |