Loading res/layout/call_detail.xml +14 −0 Original line number Diff line number Diff line Loading @@ -196,4 +196,18 @@ </LinearLayout> </FrameLayout> </RelativeLayout> <!-- Used to hide the UI when playing a voicemail and the proximity sensor is detecting something near the screen. --> <View android:id="@+id/blank" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:background="#000000" android:visibility="gone" /> </RelativeLayout> src/com/android/contacts/CallDetailActivity.java +79 −1 Original line number Diff line number Diff line Loading @@ -69,9 +69,14 @@ import java.util.List; * This activity can be either started with the URI of a single call log entry, or with the * {@link #EXTRA_CALL_LOG_IDS} extra to specify a group of call log entries. */ public class CallDetailActivity extends Activity { public class CallDetailActivity extends Activity implements ProximitySensorAware { private static final String TAG = "CallDetail"; /** The time to wait before enabling the blank the screen due to the proximity sensor. */ private static final long PROXIMITY_BLANK_DELAY_MILLIS = 100; /** The time to wait before disabling the blank the screen due to the proximity sensor. */ private static final long PROXIMITY_UNBLANK_DELAY_MILLIS = 500; /** The enumeration of {@link AsyncTask} objects used in this class. */ public enum Tasks { MARK_VOICEMAIL_READ, Loading Loading @@ -115,6 +120,60 @@ public class CallDetailActivity extends Activity { /** Whether we should show "edit number before call" in the options menu. */ private boolean mHasEditNumberBeforeCall; private ProximitySensorManager mProximitySensorManager; private final ProximitySensorListener mProximitySensorListener = new ProximitySensorListener(); /** Listener to changes in the proximity sensor state. */ private class ProximitySensorListener implements ProximitySensorManager.Listener { /** Used to show a blank view and hide the action bar. */ private final Runnable mBlankRunnable = new Runnable() { @Override public void run() { View blankView = findViewById(R.id.blank); blankView.setVisibility(View.VISIBLE); getActionBar().hide(); } }; /** Used to remove the blank view and show the action bar. */ private final Runnable mUnblankRunnable = new Runnable() { @Override public void run() { View blankView = findViewById(R.id.blank); blankView.setVisibility(View.GONE); getActionBar().show(); } }; @Override public synchronized void onNear() { clearPendingRequests(); postDelayed(mBlankRunnable, PROXIMITY_BLANK_DELAY_MILLIS); } @Override public synchronized void onFar() { clearPendingRequests(); postDelayed(mUnblankRunnable, PROXIMITY_UNBLANK_DELAY_MILLIS); } /** Removed any delayed requests that may be pending. */ public synchronized void clearPendingRequests() { View blankView = findViewById(R.id.blank); blankView.removeCallbacks(mBlankRunnable); blankView.removeCallbacks(mUnblankRunnable); } /** Post a {@link Runnable} with a delay on the main thread. */ private synchronized void postDelayed(Runnable runnable, long delayMillis) { // Post these instead of executing immediately so that: // - They are guaranteed to be executed on the main thread. // - If the sensor values changes rapidly for some time, the UI will not be // updated immediately. View blankView = findViewById(R.id.blank); blankView.postDelayed(runnable, delayMillis); } } static final String[] CALL_LOG_PROJECTION = new String[] { CallLog.Calls.DATE, CallLog.Calls.DURATION, Loading Loading @@ -189,6 +248,7 @@ public class CallDetailActivity extends Activity { mContactBackgroundView = (ImageView) findViewById(R.id.contact_background); mDefaultCountryIso = ContactsUtils.getCurrentCountryIso(this); mContactPhotoManager = ContactPhotoManager.getInstance(this); mProximitySensorManager = new ProximitySensorManager(this, mProximitySensorListener); configureActionBar(); optionallyHandleVoicemail(); } Loading Loading @@ -770,4 +830,22 @@ public class CallDetailActivity extends Activity { startActivity(intent); finish(); } @Override protected void onPause() { // Immediately stop the proximity sensor. disableProximitySensor(false); mProximitySensorListener.clearPendingRequests(); super.onPause(); } @Override public void enableProximitySensor() { mProximitySensorManager.enable(); } @Override public void disableProximitySensor(boolean waitForFarState) { mProximitySensorManager.disable(waitForFarState); } } src/com/android/contacts/ProximitySensorAware.java 0 → 100644 +33 −0 Original line number Diff line number Diff line /* * Copyright (C) 2011 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.contacts; /** * An object that is aware of the state of the proximity sensor. */ public interface ProximitySensorAware { /** Start tracking the state of the proximity sensor. */ public void enableProximitySensor(); /** * Stop tracking the state of the proximity sensor. * * @param waitForFarState if true and the sensor is currently in the near state, it will wait * until it is again in the far state before stopping to track its state. */ public void disableProximitySensor(boolean waitForFarState); } src/com/android/contacts/ProximitySensorManager.java 0 → 100644 +237 −0 Original line number Diff line number Diff line /* * Copyright (C) 2011 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.contacts; import android.content.Context; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import javax.annotation.concurrent.GuardedBy; /** * Manages the proximity sensor and notifies a listener when enabled. */ public class ProximitySensorManager { /** * Listener of the state of the proximity sensor. * <p> * This interface abstracts two possible states for the proximity sensor, near and far. * <p> * The actual meaning of these states depends on the actual sensor. */ public interface Listener { /** Called when the proximity sensor transitions from the far to the near state. */ public void onNear(); /** Called when the proximity sensor transitions from the near to the far state. */ public void onFar(); } public static enum State { NEAR, FAR } private final ProximitySensorEventListener mProximitySensorListener; /** * The current state of the manager, i.e., whether it is currently tracking the state of the * sensor. */ private boolean mManagerEnabled; /** * The listener to the state of the sensor. * <p> * Contains most of the logic concerning tracking of the sensor. * <p> * After creating an instance of this object, one should call {@link #register()} and * {@link #unregister()} to enable and disable the notifications. * <p> * Instead of calling unregister, one can call {@link #unregisterWhenFar()} to unregister the * listener the next time the sensor reaches the {@link State#FAR} state if currently in the * {@link State#NEAR} state. */ private static class ProximitySensorEventListener implements SensorEventListener { private static final float FAR_THRESHOLD = 5.0f; private final SensorManager mSensorManager; private final Sensor mProximitySensor; private final float mMaxValue; private final Listener mListener; /** * The last state of the sensor. * <p> * Before registering and after unregistering we are always in the {@link State#FAR} state. */ @GuardedBy("this") private State mLastState; /** * If this flag is set to true, we are waiting to reach the {@link State#FAR} state and * should notify the listener and unregister when that happens. */ @GuardedBy("this") private boolean mWaitingForFarState; public ProximitySensorEventListener(SensorManager sensorManager, Sensor proximitySensor, Listener listener) { mSensorManager = sensorManager; mProximitySensor = proximitySensor; mMaxValue = proximitySensor.getMaximumRange(); mListener = listener; // Initialize at far state. mLastState = State.FAR; mWaitingForFarState = false; } @Override public void onSensorChanged(SensorEvent event) { // Make sure we have a valid value. if (event.values == null) return; if (event.values.length == 0) return; float value = event.values[0]; // Convert the sensor into a NEAR/FAR state. State state = getStateFromValue(value); synchronized (this) { // No change in state, do nothing. if (state == mLastState) return; // Keep track of the current state. mLastState = state; // If we are waiting to reach the far state and we are now in it, unregister. if (mWaitingForFarState && mLastState == State.FAR) { unregisterWithoutNotification(); } } // Notify the listener of the state change. switch (state) { case NEAR: mListener.onNear(); break; case FAR: mListener.onFar(); break; } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { // Nothing to do here. } /** Returns the state of the sensor given its current value. */ private State getStateFromValue(float value) { // Determine if the current value corresponds to the NEAR or FAR state. // Take case of the case where the proximity sensor is binary: if the current value is // equal to the maximum, we are always in the FAR state. return (value > FAR_THRESHOLD || value == mMaxValue) ? State.FAR : State.NEAR; } /** * Unregister the next time the sensor reaches the {@link State#FAR} state. */ public synchronized void unregisterWhenFar() { if (mLastState == State.FAR) { // We are already in the far state, just unregister now. unregisterWithoutNotification(); } else { mWaitingForFarState = true; } } /** Register the listener and call the listener as necessary. */ public synchronized void register() { // It is okay to register multiple times. mSensorManager.registerListener(this, mProximitySensor, SensorManager.SENSOR_DELAY_UI); // We should no longer be waiting for the far state if we are registering again. mWaitingForFarState = false; } public void unregister() { State lastState; synchronized (this) { unregisterWithoutNotification(); lastState = mLastState; // Always go back to the FAR state. That way, when we register again we will get a // transition when the sensor gets into the NEAR state. mLastState = State.FAR; } // Notify the listener if we changed the state to FAR while unregistering. if (lastState != State.FAR) { mListener.onFar(); } } @GuardedBy("this") private void unregisterWithoutNotification() { mSensorManager.unregisterListener(this); mWaitingForFarState = false; } } public ProximitySensorManager(Context context, Listener listener) { SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); Sensor proximitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); if (proximitySensor == null) { // If there is no sensor, we should not do anything. mProximitySensorListener = null; } else { mProximitySensorListener = new ProximitySensorEventListener(sensorManager, proximitySensor, listener); } } /** * Enables the proximity manager. * <p> * The listener will start getting notifications of events. * <p> * This method is idempotent. */ public void enable() { if (mProximitySensorListener != null && !mManagerEnabled) { mProximitySensorListener.register(); mManagerEnabled = true; } } /** * Disables the proximity manager. * <p> * The listener will stop receiving notifications of events, possibly after receiving a last * {@link Listener#onFar()} callback. * <p> * If {@code waitForFarState} is true, if the sensor is not currently in the {@link State#FAR} * state, the listener will receive a {@link Listener#onFar()} callback the next time the sensor * actually reaches the {@link State#FAR} state. * <p> * If {@code waitForFarState} is false, the listener will receive a {@link Listener#onFar()} * callback immediately if the sensor is currently not in the {@link State#FAR} state. * <p> * This method is idempotent. */ public void disable(boolean waitForFarState) { if (mProximitySensorListener != null && mManagerEnabled) { if (waitForFarState) { mProximitySensorListener.unregisterWhenFar(); } else { mProximitySensorListener.unregister(); } mManagerEnabled = false; } } } src/com/android/contacts/voicemail/VoicemailPlaybackFragment.java +26 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static com.android.contacts.CallDetailActivity.EXTRA_VOICEMAIL_START_PLAY import static com.android.contacts.CallDetailActivity.EXTRA_VOICEMAIL_URI; import com.android.common.io.MoreCloseables; import com.android.contacts.ProximitySensorAware; import com.android.contacts.R; import com.android.contacts.util.AsyncTaskExecutors; import com.android.ex.variablespeed.MediaPlayerProxy; Loading @@ -36,6 +37,7 @@ import android.database.Cursor; import android.media.AudioManager; import android.net.Uri; import android.os.Bundle; import android.os.PowerManager; import android.provider.VoicemailContract; import android.util.Log; import android.view.LayoutInflater; Loading Loading @@ -91,10 +93,15 @@ public class VoicemailPlaybackFragment extends Fragment { Uri voicemailUri = arguments.getParcelable(EXTRA_VOICEMAIL_URI); Preconditions.checkNotNull(voicemailUri, "fragment must contain EXTRA_VOICEMAIL_URI"); boolean startPlayback = arguments.getBoolean(EXTRA_VOICEMAIL_START_PLAYBACK, false); PowerManager powerManager = (PowerManager) getActivity().getSystemService(Context.POWER_SERVICE); PowerManager.WakeLock wakeLock = powerManager.newWakeLock( PowerManager.SCREEN_DIM_WAKE_LOCK, getClass().getSimpleName()); mPresenter = new VoicemailPlaybackPresenter(createPlaybackViewImpl(), createMediaPlayer(mScheduledExecutorService), voicemailUri, mScheduledExecutorService, startPlayback, AsyncTaskExecutors.createAsyncTaskExecutor()); AsyncTaskExecutors.createAsyncTaskExecutor(), wakeLock); mPresenter.onCreate(savedInstanceState); } Loading Loading @@ -262,6 +269,24 @@ public class VoicemailPlaybackFragment extends Fragment { mStartStopButton.setImageResource(R.drawable.ic_play_holo_dark); } @Override public void enableProximitySensor() { // Only change the state if the activity is still around. Activity activity = mActivityReference.get(); if (activity != null && activity instanceof ProximitySensorAware) { ((ProximitySensorAware) activity).enableProximitySensor(); } } @Override public void disableProximitySensor() { // Only change the state if the activity is still around. Activity activity = mActivityReference.get(); if (activity != null && activity instanceof ProximitySensorAware) { ((ProximitySensorAware) activity).disableProximitySensor(true); } } @Override public void registerContentObserver(Uri uri, ContentObserver observer) { mApplicationContext.getContentResolver().registerContentObserver(uri, false, observer); Loading Loading
res/layout/call_detail.xml +14 −0 Original line number Diff line number Diff line Loading @@ -196,4 +196,18 @@ </LinearLayout> </FrameLayout> </RelativeLayout> <!-- Used to hide the UI when playing a voicemail and the proximity sensor is detecting something near the screen. --> <View android:id="@+id/blank" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:background="#000000" android:visibility="gone" /> </RelativeLayout>
src/com/android/contacts/CallDetailActivity.java +79 −1 Original line number Diff line number Diff line Loading @@ -69,9 +69,14 @@ import java.util.List; * This activity can be either started with the URI of a single call log entry, or with the * {@link #EXTRA_CALL_LOG_IDS} extra to specify a group of call log entries. */ public class CallDetailActivity extends Activity { public class CallDetailActivity extends Activity implements ProximitySensorAware { private static final String TAG = "CallDetail"; /** The time to wait before enabling the blank the screen due to the proximity sensor. */ private static final long PROXIMITY_BLANK_DELAY_MILLIS = 100; /** The time to wait before disabling the blank the screen due to the proximity sensor. */ private static final long PROXIMITY_UNBLANK_DELAY_MILLIS = 500; /** The enumeration of {@link AsyncTask} objects used in this class. */ public enum Tasks { MARK_VOICEMAIL_READ, Loading Loading @@ -115,6 +120,60 @@ public class CallDetailActivity extends Activity { /** Whether we should show "edit number before call" in the options menu. */ private boolean mHasEditNumberBeforeCall; private ProximitySensorManager mProximitySensorManager; private final ProximitySensorListener mProximitySensorListener = new ProximitySensorListener(); /** Listener to changes in the proximity sensor state. */ private class ProximitySensorListener implements ProximitySensorManager.Listener { /** Used to show a blank view and hide the action bar. */ private final Runnable mBlankRunnable = new Runnable() { @Override public void run() { View blankView = findViewById(R.id.blank); blankView.setVisibility(View.VISIBLE); getActionBar().hide(); } }; /** Used to remove the blank view and show the action bar. */ private final Runnable mUnblankRunnable = new Runnable() { @Override public void run() { View blankView = findViewById(R.id.blank); blankView.setVisibility(View.GONE); getActionBar().show(); } }; @Override public synchronized void onNear() { clearPendingRequests(); postDelayed(mBlankRunnable, PROXIMITY_BLANK_DELAY_MILLIS); } @Override public synchronized void onFar() { clearPendingRequests(); postDelayed(mUnblankRunnable, PROXIMITY_UNBLANK_DELAY_MILLIS); } /** Removed any delayed requests that may be pending. */ public synchronized void clearPendingRequests() { View blankView = findViewById(R.id.blank); blankView.removeCallbacks(mBlankRunnable); blankView.removeCallbacks(mUnblankRunnable); } /** Post a {@link Runnable} with a delay on the main thread. */ private synchronized void postDelayed(Runnable runnable, long delayMillis) { // Post these instead of executing immediately so that: // - They are guaranteed to be executed on the main thread. // - If the sensor values changes rapidly for some time, the UI will not be // updated immediately. View blankView = findViewById(R.id.blank); blankView.postDelayed(runnable, delayMillis); } } static final String[] CALL_LOG_PROJECTION = new String[] { CallLog.Calls.DATE, CallLog.Calls.DURATION, Loading Loading @@ -189,6 +248,7 @@ public class CallDetailActivity extends Activity { mContactBackgroundView = (ImageView) findViewById(R.id.contact_background); mDefaultCountryIso = ContactsUtils.getCurrentCountryIso(this); mContactPhotoManager = ContactPhotoManager.getInstance(this); mProximitySensorManager = new ProximitySensorManager(this, mProximitySensorListener); configureActionBar(); optionallyHandleVoicemail(); } Loading Loading @@ -770,4 +830,22 @@ public class CallDetailActivity extends Activity { startActivity(intent); finish(); } @Override protected void onPause() { // Immediately stop the proximity sensor. disableProximitySensor(false); mProximitySensorListener.clearPendingRequests(); super.onPause(); } @Override public void enableProximitySensor() { mProximitySensorManager.enable(); } @Override public void disableProximitySensor(boolean waitForFarState) { mProximitySensorManager.disable(waitForFarState); } }
src/com/android/contacts/ProximitySensorAware.java 0 → 100644 +33 −0 Original line number Diff line number Diff line /* * Copyright (C) 2011 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.contacts; /** * An object that is aware of the state of the proximity sensor. */ public interface ProximitySensorAware { /** Start tracking the state of the proximity sensor. */ public void enableProximitySensor(); /** * Stop tracking the state of the proximity sensor. * * @param waitForFarState if true and the sensor is currently in the near state, it will wait * until it is again in the far state before stopping to track its state. */ public void disableProximitySensor(boolean waitForFarState); }
src/com/android/contacts/ProximitySensorManager.java 0 → 100644 +237 −0 Original line number Diff line number Diff line /* * Copyright (C) 2011 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.contacts; import android.content.Context; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import javax.annotation.concurrent.GuardedBy; /** * Manages the proximity sensor and notifies a listener when enabled. */ public class ProximitySensorManager { /** * Listener of the state of the proximity sensor. * <p> * This interface abstracts two possible states for the proximity sensor, near and far. * <p> * The actual meaning of these states depends on the actual sensor. */ public interface Listener { /** Called when the proximity sensor transitions from the far to the near state. */ public void onNear(); /** Called when the proximity sensor transitions from the near to the far state. */ public void onFar(); } public static enum State { NEAR, FAR } private final ProximitySensorEventListener mProximitySensorListener; /** * The current state of the manager, i.e., whether it is currently tracking the state of the * sensor. */ private boolean mManagerEnabled; /** * The listener to the state of the sensor. * <p> * Contains most of the logic concerning tracking of the sensor. * <p> * After creating an instance of this object, one should call {@link #register()} and * {@link #unregister()} to enable and disable the notifications. * <p> * Instead of calling unregister, one can call {@link #unregisterWhenFar()} to unregister the * listener the next time the sensor reaches the {@link State#FAR} state if currently in the * {@link State#NEAR} state. */ private static class ProximitySensorEventListener implements SensorEventListener { private static final float FAR_THRESHOLD = 5.0f; private final SensorManager mSensorManager; private final Sensor mProximitySensor; private final float mMaxValue; private final Listener mListener; /** * The last state of the sensor. * <p> * Before registering and after unregistering we are always in the {@link State#FAR} state. */ @GuardedBy("this") private State mLastState; /** * If this flag is set to true, we are waiting to reach the {@link State#FAR} state and * should notify the listener and unregister when that happens. */ @GuardedBy("this") private boolean mWaitingForFarState; public ProximitySensorEventListener(SensorManager sensorManager, Sensor proximitySensor, Listener listener) { mSensorManager = sensorManager; mProximitySensor = proximitySensor; mMaxValue = proximitySensor.getMaximumRange(); mListener = listener; // Initialize at far state. mLastState = State.FAR; mWaitingForFarState = false; } @Override public void onSensorChanged(SensorEvent event) { // Make sure we have a valid value. if (event.values == null) return; if (event.values.length == 0) return; float value = event.values[0]; // Convert the sensor into a NEAR/FAR state. State state = getStateFromValue(value); synchronized (this) { // No change in state, do nothing. if (state == mLastState) return; // Keep track of the current state. mLastState = state; // If we are waiting to reach the far state and we are now in it, unregister. if (mWaitingForFarState && mLastState == State.FAR) { unregisterWithoutNotification(); } } // Notify the listener of the state change. switch (state) { case NEAR: mListener.onNear(); break; case FAR: mListener.onFar(); break; } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { // Nothing to do here. } /** Returns the state of the sensor given its current value. */ private State getStateFromValue(float value) { // Determine if the current value corresponds to the NEAR or FAR state. // Take case of the case where the proximity sensor is binary: if the current value is // equal to the maximum, we are always in the FAR state. return (value > FAR_THRESHOLD || value == mMaxValue) ? State.FAR : State.NEAR; } /** * Unregister the next time the sensor reaches the {@link State#FAR} state. */ public synchronized void unregisterWhenFar() { if (mLastState == State.FAR) { // We are already in the far state, just unregister now. unregisterWithoutNotification(); } else { mWaitingForFarState = true; } } /** Register the listener and call the listener as necessary. */ public synchronized void register() { // It is okay to register multiple times. mSensorManager.registerListener(this, mProximitySensor, SensorManager.SENSOR_DELAY_UI); // We should no longer be waiting for the far state if we are registering again. mWaitingForFarState = false; } public void unregister() { State lastState; synchronized (this) { unregisterWithoutNotification(); lastState = mLastState; // Always go back to the FAR state. That way, when we register again we will get a // transition when the sensor gets into the NEAR state. mLastState = State.FAR; } // Notify the listener if we changed the state to FAR while unregistering. if (lastState != State.FAR) { mListener.onFar(); } } @GuardedBy("this") private void unregisterWithoutNotification() { mSensorManager.unregisterListener(this); mWaitingForFarState = false; } } public ProximitySensorManager(Context context, Listener listener) { SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); Sensor proximitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); if (proximitySensor == null) { // If there is no sensor, we should not do anything. mProximitySensorListener = null; } else { mProximitySensorListener = new ProximitySensorEventListener(sensorManager, proximitySensor, listener); } } /** * Enables the proximity manager. * <p> * The listener will start getting notifications of events. * <p> * This method is idempotent. */ public void enable() { if (mProximitySensorListener != null && !mManagerEnabled) { mProximitySensorListener.register(); mManagerEnabled = true; } } /** * Disables the proximity manager. * <p> * The listener will stop receiving notifications of events, possibly after receiving a last * {@link Listener#onFar()} callback. * <p> * If {@code waitForFarState} is true, if the sensor is not currently in the {@link State#FAR} * state, the listener will receive a {@link Listener#onFar()} callback the next time the sensor * actually reaches the {@link State#FAR} state. * <p> * If {@code waitForFarState} is false, the listener will receive a {@link Listener#onFar()} * callback immediately if the sensor is currently not in the {@link State#FAR} state. * <p> * This method is idempotent. */ public void disable(boolean waitForFarState) { if (mProximitySensorListener != null && mManagerEnabled) { if (waitForFarState) { mProximitySensorListener.unregisterWhenFar(); } else { mProximitySensorListener.unregister(); } mManagerEnabled = false; } } }
src/com/android/contacts/voicemail/VoicemailPlaybackFragment.java +26 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static com.android.contacts.CallDetailActivity.EXTRA_VOICEMAIL_START_PLAY import static com.android.contacts.CallDetailActivity.EXTRA_VOICEMAIL_URI; import com.android.common.io.MoreCloseables; import com.android.contacts.ProximitySensorAware; import com.android.contacts.R; import com.android.contacts.util.AsyncTaskExecutors; import com.android.ex.variablespeed.MediaPlayerProxy; Loading @@ -36,6 +37,7 @@ import android.database.Cursor; import android.media.AudioManager; import android.net.Uri; import android.os.Bundle; import android.os.PowerManager; import android.provider.VoicemailContract; import android.util.Log; import android.view.LayoutInflater; Loading Loading @@ -91,10 +93,15 @@ public class VoicemailPlaybackFragment extends Fragment { Uri voicemailUri = arguments.getParcelable(EXTRA_VOICEMAIL_URI); Preconditions.checkNotNull(voicemailUri, "fragment must contain EXTRA_VOICEMAIL_URI"); boolean startPlayback = arguments.getBoolean(EXTRA_VOICEMAIL_START_PLAYBACK, false); PowerManager powerManager = (PowerManager) getActivity().getSystemService(Context.POWER_SERVICE); PowerManager.WakeLock wakeLock = powerManager.newWakeLock( PowerManager.SCREEN_DIM_WAKE_LOCK, getClass().getSimpleName()); mPresenter = new VoicemailPlaybackPresenter(createPlaybackViewImpl(), createMediaPlayer(mScheduledExecutorService), voicemailUri, mScheduledExecutorService, startPlayback, AsyncTaskExecutors.createAsyncTaskExecutor()); AsyncTaskExecutors.createAsyncTaskExecutor(), wakeLock); mPresenter.onCreate(savedInstanceState); } Loading Loading @@ -262,6 +269,24 @@ public class VoicemailPlaybackFragment extends Fragment { mStartStopButton.setImageResource(R.drawable.ic_play_holo_dark); } @Override public void enableProximitySensor() { // Only change the state if the activity is still around. Activity activity = mActivityReference.get(); if (activity != null && activity instanceof ProximitySensorAware) { ((ProximitySensorAware) activity).enableProximitySensor(); } } @Override public void disableProximitySensor() { // Only change the state if the activity is still around. Activity activity = mActivityReference.get(); if (activity != null && activity instanceof ProximitySensorAware) { ((ProximitySensorAware) activity).disableProximitySensor(true); } } @Override public void registerContentObserver(Uri uri, ContentObserver observer) { mApplicationContext.getContentResolver().registerContentObserver(uri, false, observer); Loading