Methods Summary |
---|
boolean | authenticateAgainstCachedSimPin(java.lang.String pin)
return (mCachedSimPin != null && mCachedSimPin.equals(pin));
|
static android.content.Intent | createCallLogIntent()
Intent intent = new Intent(Intent.ACTION_VIEW, null);
intent.setType("vnd.android.cursor.dir/calls");
return intent;
|
static android.content.Intent | createInCallIntent(boolean showDialpad)Variation of createInCallIntent() that also specifies whether the
DTMF dialpad should be initially visible when the InCallScreen
comes up.
Intent intent = createInCallIntent();
intent.putExtra(InCallScreen.SHOW_DIALPAD_EXTRA, showDialpad);
return intent;
|
static android.content.Intent | createInCallIntent()Return an Intent that can be used to bring up the in-call screen.
This intent can only be used from within the Phone app, since the
InCallScreen is not exported from our AndroidManifest.
Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
| Intent.FLAG_ACTIVITY_NO_USER_ACTION);
intent.setClassName("com.android.phone", getCallScreenClassName());
return intent;
|
void | disableKeyguard()Disables the keyguard. This is used by the phone app to allow
interaction with the Phone UI when the keyguard would otherwise be
active (like receiving an incoming call while the device is
locked.)
Any call to this method MUST be followed (eventually)
by a corresponding reenableKeyguard() call.
if (DBG) Log.d(LOG_TAG, "disable keyguard");
// if (DBG) Log.d(LOG_TAG, "disableKeyguard()...", new Throwable("stack dump"));
mKeyguardLock.disableKeyguard();
|
void | dismissCallScreen()Dismisses the in-call UI.
This also ensures that you won't be able to get back to the in-call
UI via the BACK button (since this call removes the InCallScreen
from the activity history.)
if (mInCallScreen != null) {
mInCallScreen.finish();
}
|
void | displayCallScreen()Starts the InCallScreen Activity.
if (VDBG) Log.d(LOG_TAG, "displayCallScreen()...");
startActivity(createInCallIntent());
Profiler.callScreenRequested();
|
BluetoothHandsfree | getBluetoothHandsfree()
return mBtHandsfree;
|
static java.lang.String | getCallScreenClassName()
return InCallScreen.class.getName();
|
static com.android.phone.PhoneApp | getInstance()Returns the singleton instance of the PhoneApp.
return sMe;
|
android.app.KeyguardManager | getKeyguardManager()
return mKeyguardManager;
|
android.app.Activity | getPUKEntryActivity()
return mPUKEntryActivity;
|
android.app.ProgressDialog | getPUKEntryProgressDialog()
return mPUKEntryProgressDialog;
|
boolean | getRestoreMuteOnInCallResume()Get the restore mute state flag.
This is used by the InCallScreen {@link InCallScreen#onResume()} to figure
out if we need to restore the mute state for the current active call.
return mShouldRestoreMuteOnInCallResume;
|
Ringer | getRinger()
return ringer;
|
boolean | handleInCallOrRinging()Helper function to check for one special feature of the CALL key:
Normally, when the phone is idle, CALL takes you to the call log
(see the handler for KEYCODE_CALL in PhoneWindow.onKeyUp().)
But if the phone is in use (either off-hook or ringing) we instead
handle the CALL button by taking you to the in-call UI.
if (phone.getState() != Phone.State.IDLE) {
// Phone is OFFHOOK or RINGING.
if (DBG) Log.v(LOG_TAG,
"handleInCallOrRinging: show call screen");
displayCallScreen();
return true;
}
return false;
|
boolean | isHeadsetPlugged()
return mIsHeadsetPlugged;
|
boolean | isShowingCallScreen()
if (mInCallScreen == null) return false;
return mInCallScreen.isForegroundActivity();
|
boolean | isSimPinEnabled()
return mIsSimPinEnabled;
|
public void | onCreate()
if (Config.LOGV) Log.v(LOG_TAG, "onCreate()...");
ContentResolver resolver = getContentResolver();
if (phone == null) {
// Initialize the telephony framework
PhoneFactory.makeDefaultPhones(this);
// Get the default phone
phone = PhoneFactory.getDefaultPhone();
NotificationMgr.init(this);
phoneMgr = new PhoneInterfaceManager(this, phone);
if (getSystemService(Context.BLUETOOTH_SERVICE) != null) {
mBtHandsfree = new BluetoothHandsfree(this, phone);
startService(new Intent(this, BluetoothHeadsetService.class));
} else {
// Device is not bluetooth capable
mBtHandsfree = null;
}
ringer = new Ringer(phone);
SoundEffect.init();
// before registering for phone state changes
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK
| PowerManager.ACQUIRE_CAUSES_WAKEUP
| PowerManager.ON_AFTER_RELEASE, LOG_TAG);
// lock used to keep the processor awake, when we don't care for the display.
mPartialWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK
| PowerManager.ON_AFTER_RELEASE, LOG_TAG);
mKeyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
mKeyguardLock = mKeyguardManager.newKeyguardLock(LOG_TAG);
// get a handle to the service so that we can use it later when we
// want to set the poke lock.
mPowerManagerService = IPowerManager.Stub.asInterface(
ServiceManager.getService("power"));
notifier = new CallNotifier(this, phone, ringer, mBtHandsfree);
// register for SIM status
SimCard sim = phone.getSimCard();
if (sim != null) {
if (Config.LOGV) Log.v(LOG_TAG, "register for SIM status");
sim.registerForAbsent(mHandler, EVENT_SIM_ABSENT, null);
sim.registerForLocked(mHandler, EVENT_SIM_LOCKED, null);
sim.registerForNetworkLocked(mHandler, EVENT_SIM_NETWORK_LOCKED, null);
}
// register for MMI/USSD
phone.registerForMmiComplete(mHandler, MMI_COMPLETE, null);
// register connection tracking to PhoneUtils
PhoneUtils.initializeConnectionHandler(phone);
// Register for misc other intent broadcasts.
IntentFilter intentFilter =
new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);
intentFilter.addAction(BluetoothIntent.HEADSET_STATE_CHANGED_ACTION);
intentFilter.addAction(BluetoothIntent.HEADSET_AUDIO_STATE_CHANGED_ACTION);
intentFilter.addAction(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
intentFilter.addAction(Intent.ACTION_HEADSET_PLUG);
intentFilter.addAction(Intent.ACTION_BATTERY_LOW);
intentFilter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
registerReceiver(mReceiver, intentFilter);
// Use a separate receiver for ACTION_MEDIA_BUTTON broadcasts,
// since we need to manually adjust its priority (to make sure
// we get these intents *before* the media player.)
IntentFilter mediaButtonIntentFilter =
new IntentFilter(Intent.ACTION_MEDIA_BUTTON);
//
// Make sure we're higher priority than the media player's
// MediaButtonIntentReceiver (which currently has the default
// priority of zero; see apps/Music/AndroidManifest.xml.)
mediaButtonIntentFilter.setPriority(1);
//
registerReceiver(mMediaButtonReceiver, mediaButtonIntentFilter);
//set the default values for the preferences in the phone.
PreferenceManager.setDefaultValues(this, R.xml.network_setting, false);
PreferenceManager.setDefaultValues(this, R.xml.call_feature_setting, false);
// Make sure the audio mode (along with some
// audio-mode-related state of our own) is initialized
// correctly, given the current state of the phone.
switch (phone.getState()) {
case IDLE:
if (DBG) Log.d(LOG_TAG, "Resetting audio state/mode: IDLE");
PhoneUtils.setAudioControlState(PhoneUtils.AUDIO_IDLE);
PhoneUtils.setAudioMode(this, AudioManager.MODE_NORMAL);
break;
case RINGING:
if (DBG) Log.d(LOG_TAG, "Resetting audio state/mode: RINGING");
PhoneUtils.setAudioControlState(PhoneUtils.AUDIO_RINGING);
PhoneUtils.setAudioMode(this, AudioManager.MODE_RINGTONE);
break;
case OFFHOOK:
if (DBG) Log.d(LOG_TAG, "Resetting audio state/mode: OFFHOOK");
PhoneUtils.setAudioControlState(PhoneUtils.AUDIO_OFFHOOK);
PhoneUtils.setAudioMode(this, AudioManager.MODE_IN_CALL);
break;
}
}
// XXX pre-load the SimProvider so that it's ready
resolver.getType(Uri.parse("content://sim/adn"));
// start with the default value to set the mute state.
mShouldRestoreMuteOnInCallResume = false;
|
private void | onMMIComplete(android.os.AsyncResult r)
if (VDBG) Log.d(LOG_TAG, "onMMIComplete()...");
MmiCode mmiCode = (MmiCode) r.result;
PhoneUtils.displayMMIComplete(phone, getInstance(), mmiCode, null, null);
|
void | pokeUserActivity()Manually pokes the PowerManager's userActivity method. Since we
hold the POKE_LOCK_IGNORE_TOUCH_AND_CHEEK_EVENTS poke lock while
the InCallScreen is active, we need to do this for touch events
that really do count as user activity (like DTMF key presses, or
unlocking the "touch lock" overlay.)
if (VDBG) Log.d(LOG_TAG, "pokeUserActivity()...");
try {
mPowerManagerService.userActivity(SystemClock.uptimeMillis(), false);
} catch (RemoteException e) {
Log.w(LOG_TAG, "mPowerManagerService.userActivity() failed: " + e);
}
|
void | preventScreenOn(boolean prevent)Wrapper around the PowerManagerService.preventScreenOn() API.
This allows the in-call UI to prevent the screen from turning on
even if a subsequent call to updateWakeState() causes us to acquire
a full wake lock.
if (VDBG) Log.d(LOG_TAG, "- preventScreenOn(" + prevent + ")...");
try {
mPowerManagerService.preventScreenOn(prevent);
} catch (RemoteException e) {
Log.w(LOG_TAG, "mPowerManagerService.preventScreenOn() failed: " + e);
}
|
void | reenableKeyguard()Re-enables the keyguard after a previous disableKeyguard() call.
Any call to this method MUST correspond to (i.e. be balanced with)
a previous disableKeyguard() call.
if (DBG) Log.d(LOG_TAG, "re-enable keyguard");
// if (DBG) Log.d(LOG_TAG, "reenableKeyguard()...", new Throwable("stack dump"));
mKeyguardLock.reenableKeyguard();
|
void | requestWakeState(com.android.phone.PhoneApp$WakeState ws)Controls whether or not the screen is allowed to sleep.
Once sleep is allowed (WakeState is SLEEP), it will rely on the
settings for the poke lock to determine when to timeout and let
the device sleep {@link PhoneApp#setScreenTimeout}.
if (VDBG) Log.d(LOG_TAG, "requestWakeState(" + ws + ")...");
if (mWakeState != ws) {
switch (ws) {
case PARTIAL:
// acquire the processor wake lock, and release the FULL
// lock if it is being held.
mPartialWakeLock.acquire();
if (mWakeLock.isHeld()) {
mWakeLock.release();
}
break;
case FULL:
// acquire the full wake lock, and release the PARTIAL
// lock if it is being held.
mWakeLock.acquire();
if (mPartialWakeLock.isHeld()) {
mPartialWakeLock.release();
}
break;
case SLEEP:
default:
// release both the PARTIAL and FULL locks.
if (mWakeLock.isHeld()) {
mWakeLock.release();
}
if (mPartialWakeLock.isHeld()) {
mPartialWakeLock.release();
}
break;
}
mWakeState = ws;
}
|
void | setCachedSimPin(java.lang.String pin)
mCachedSimPin = pin;
|
void | setIgnoreTouchUserActivity(boolean ignore)Sets or clears the flag that tells the PowerManager that touch
(and cheek) events should NOT be considered "user activity".
Since the in-call UI is totally insensitive to touch in most
states, we set this flag whenever the InCallScreen is in the
foreground. (Otherwise, repeated unintentional touches could
prevent the device from going to sleep.)
There *are* some some touch events that really do count as user
activity, though. For those, we need to manually poke the
PowerManager's userActivity method; see pokeUserActivity().
if (VDBG) Log.d(LOG_TAG, "setIgnoreTouchUserActivity(" + ignore + ")...");
mIgnoreTouchUserActivity = ignore;
updatePokeLock();
|
void | setInCallScreenInstance(InCallScreen inCallScreen)
mInCallScreen = inCallScreen;
|
void | setPukEntryActivity(android.app.Activity activity)Sets the activity responsible for un-PUK-blocking the device
so that we may close it when we receive a positive result.
mPUKEntryActivity is also used to indicate to the device that
we are trying to un-PUK-lock the phone. In other words, iff
it is NOT null, then we are trying to unlock and waiting for
the SIM to move to READY state.
mPUKEntryActivity = activity;
|
void | setPukEntryProgressDialog(android.app.ProgressDialog dialog)Sets the dialog responsible for notifying the user of un-PUK-
blocking - SIM READYing progress, so that we may dismiss it
when we receive a positive result.
mPUKEntryProgressDialog = dialog;
|
void | setRestoreMuteOnInCallResume(boolean mode)Set the restore mute state flag. Used when we are setting the mute state
OUTSIDE of user interaction {@link PhoneUtils#startNewCall(Phone)}
/*package*/
mShouldRestoreMuteOnInCallResume = mode;
|
void | setScreenTimeout(com.android.phone.PhoneApp$ScreenTimeoutDuration duration)Controls how quickly the screen times out.
The poke lock controls how long it takes before the screen powers
down, and therefore has no immediate effect when the current
WakeState (see {@link PhoneApp#requestWakeState}) is FULL.
If we're in a state where the screen *is* allowed to turn off,
though, the poke lock will determine the timeout interval (long or
short).
if (VDBG) Log.d(LOG_TAG, "setScreenTimeout(" + duration + ")...");
// make sure we don't set the poke lock repeatedly so that we
// avoid triggering the userActivity calls in
// PowerManagerService.setPokeLock().
if (duration == mScreenTimeoutDuration) {
return;
}
mScreenTimeoutDuration = duration;
updatePokeLock();
|
private static boolean | shouldShowBluetoothIndication(int bluetoothState, int bluetoothAudioState, com.android.internal.telephony.Phone phone)UI policy helper function for the couple of places in the UI that
have some way of indicating that "bluetooth is in use."
// We want the UI to indicate that "bluetooth is in use" in two
// slightly different cases:
//
// (a) The obvious case: if a bluetooth headset is currently in
// use for an ongoing call.
//
// (b) The not-so-obvious case: if an incoming call is ringing,
// and we expect that audio *will* be routed to a bluetooth
// headset once the call is answered.
switch (phone.getState()) {
case OFFHOOK:
// This covers normal active calls, and also the case if
// the foreground call is DIALING or ALERTING. In this
// case, bluetooth is considered "active" if a headset
// is connected *and* audio is being routed to it.
return ((bluetoothState == BluetoothHeadset.STATE_CONNECTED)
&& (bluetoothAudioState == BluetoothHeadset.AUDIO_STATE_CONNECTED));
case RINGING:
// If an incoming call is ringing, we're *not* yet routing
// audio to the headset (since there's no in-call audio
// yet!) In this case, if a bluetooth headset is
// connected at all, we assume that it'll become active
// once the user answers the phone.
return (bluetoothState == BluetoothHeadset.STATE_CONNECTED);
default: // Presumably IDLE
return false;
}
|
boolean | showBluetoothIndication()
return mShowBluetoothIndication;
|
void | updateBluetoothIndication(boolean forceUiUpdate)Recomputes the mShowBluetoothIndication flag based on the current
bluetooth state and current telephony state.
This needs to be called any time the bluetooth headset state or the
telephony state changes.
mShowBluetoothIndication = shouldShowBluetoothIndication(mBluetoothHeadsetState,
mBluetoothHeadsetAudioState,
phone);
if (forceUiUpdate) {
// Post Handler messages to the various components that might
// need to be refreshed based on the new state.
if (isShowingCallScreen()) mInCallScreen.updateBluetoothIndication();
mHandler.sendEmptyMessage(EVENT_UPDATE_INCALL_NOTIFICATION);
}
|
private void | updatePokeLock()Update the state of the poke lock held by the phone app,
based on the current desired screen timeout and the
current "ignore user activity on touch" flag.
// This is kind of convoluted, but the basic thing to remember is
// that the poke lock just sends a message to the screen to tell
// it to stay on for a while.
// The default is 0, for a long timeout and should be set that way
// when we are heading back into a the keyguard / screen off
// state, and also when we're trying to keep the screen alive
// while ringing. We'll also want to ignore the cheek events
// regardless of the timeout duration.
// The short timeout is really used whenever we want to give up
// the screen lock, such as when we're in call.
int pokeLockSetting = LocalPowerManager.POKE_LOCK_IGNORE_CHEEK_EVENTS;
switch (mScreenTimeoutDuration) {
case SHORT:
// Set the poke lock to timeout the display after a short
// timeout (5s). This ensures that the screen goes to sleep
// as soon as acceptably possible after we the wake lock
// has been released.
pokeLockSetting |= LocalPowerManager.POKE_LOCK_SHORT_TIMEOUT;
break;
case MEDIUM:
// Set the poke lock to timeout the display after a medium
// timeout (15s). This ensures that the screen goes to sleep
// as soon as acceptably possible after we the wake lock
// has been released.
pokeLockSetting |= LocalPowerManager.POKE_LOCK_MEDIUM_TIMEOUT;
break;
case DEFAULT:
default:
// set the poke lock to timeout the display after a long
// delay by default.
// TODO: it may be nice to be able to disable cheek presses
// for long poke locks (emergency dialer, for instance).
break;
}
if (mIgnoreTouchUserActivity) {
pokeLockSetting |= LocalPowerManager.POKE_LOCK_IGNORE_TOUCH_AND_CHEEK_EVENTS;
}
// Send the request
try {
mPowerManagerService.setPokeLock(pokeLockSetting, mPokeLockToken, LOG_TAG);
} catch (RemoteException e) {
Log.w(LOG_TAG, "mPowerManagerService.setPokeLock() failed: " + e);
}
|
void | updateWakeState()Sets the wake state and screen timeout based on the current state
of the phone, and the current state of the in-call UI.
This method is a "UI Policy" wrapper around
{@link PhoneApp#requestWakeState} and {@link PhoneApp#setScreenTimeout}.
It's safe to call this method regardless of the state of the Phone
(e.g. whether or not it's idle), and regardless of the state of the
Phone UI (e.g. whether or not the InCallScreen is active.)
Phone.State state = phone.getState();
// True if the in-call UI is the foreground activity.
// (Note this will be false if the screen is currently off,
// since in that case *no* activity is in the foreground.)
boolean isShowingCallScreen = isShowingCallScreen();
// True if the InCallScreen's DTMF dialer is currently opened.
// (Note this does NOT imply whether or not the InCallScreen
// itself is visible.)
boolean isDialerOpened = (mInCallScreen != null) && mInCallScreen.isDialerOpened();
// True if the speakerphone is in use. (If so, we *always* use
// the default timeout. Since the user is obviously not holding
// the phone up to his/her face, we don't need to worry about
// false touches, and thus don't need to turn the screen off so
// aggressively.)
// Note that we need to make a fresh call to this method any
// time the speaker state changes. (That happens in
// PhoneUtils.turnOnSpeaker().)
boolean isSpeakerInUse = (state == Phone.State.OFFHOOK) && PhoneUtils.isSpeakerOn(this);
// TODO (bug 1440854): The screen timeout *might* also need to
// depend on the bluetooth state, but this isn't as clear-cut as
// the speaker state (since while using BT it's common for the
// user to put the phone straight into a pocket, in which case the
// timeout should probably still be short.)
if (DBG) Log.d(LOG_TAG, "updateWakeState: callscreen " + isShowingCallScreen
+ ", dialer " + isDialerOpened
+ ", speaker " + isSpeakerInUse + "...");
//
// (1) Set the screen timeout.
//
// Note that the "screen timeout" value we determine here is
// meaningless if the screen is forced on (see (2) below.)
//
if (!isShowingCallScreen || isSpeakerInUse) {
// Use the system-wide default timeout.
setScreenTimeout(ScreenTimeoutDuration.DEFAULT);
} else {
// We're on the in-call screen, and *not* using the speakerphone.
if (isDialerOpened) {
// The DTMF dialpad is up. This case is special because
// the in-call UI has its own "touch lock" mechanism to
// disable the dialpad after a very short amount of idle
// time (to avoid false touches from the user's face while
// in-call.)
//
// In this case the *physical* screen just uses the
// system-wide default timeout.
setScreenTimeout(ScreenTimeoutDuration.DEFAULT);
} else {
// We're on the in-call screen, and not using the DTMF dialpad.
// There's actually no touchable UI onscreen at all in
// this state. Also, the user is (most likely) not
// looking at the screen at all, since they're probably
// holding the phone up to their face. Here we use a
// special screen timeout value specific to the in-call
// screen, purely to save battery life.
setScreenTimeout(ScreenTimeoutDuration.MEDIUM);
}
}
//
// (2) Decide whether to force the screen on or not.
//
// Force the screen to be on if the phone is ringing, or if we're
// displaying the "Call ended" UI for a connection in the
// "disconnected" state.
//
boolean isRinging = (state == Phone.State.RINGING);
boolean showingDisconnectedConnection =
PhoneUtils.hasDisconnectedConnections(phone) && isShowingCallScreen;
boolean keepScreenOn = isRinging || showingDisconnectedConnection;
if (DBG) Log.d(LOG_TAG, "updateWakeState: keepScreenOn = " + keepScreenOn
+ " (isRinging " + isRinging
+ ", showingDisc " + showingDisconnectedConnection + ")");
// keepScreenOn == true means we'll hold a full wake lock:
requestWakeState(keepScreenOn ? WakeState.FULL : WakeState.SLEEP);
|
void | wakeUpScreen()If we are not currently keeping the screen on, then poke the power
manager to wake up the screen for the user activity timeout duration.
if (mWakeState == WakeState.SLEEP) {
if (DBG) Log.d(LOG_TAG, "pulse screen lock");
try {
mPowerManagerService.userActivityWithForce(SystemClock.uptimeMillis(), false, true);
} catch (RemoteException ex) {
// Ignore -- the system process is dead.
}
}
|