/** * UI policy helper function for the couple of places in the UI that have some way of indicating * that "bluetooth is in use." * * @return true if the onscreen UI should indicate that "bluetooth is in use", based on the * specified bluetooth headset state, and the current state of the phone. * @see showBluetoothIndication() */ private static boolean shouldShowBluetoothIndication( int bluetoothState, int bluetoothAudioState, Phone phone) { // 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; } }
/** * Internal implemenation of silenceRinger(). This should only be called from the main thread of * the Phone app. * * @see silenceRinger */ private void silenceRingerInternal() { if ((mPhone.getState() == Phone.State.RINGING) && mApp.notifier.isRinging()) { // Ringer is actually playing, so silence it. if (DBG) log("silenceRingerInternal: silencing..."); mApp.notifier.silenceRinger(); } }
/** * 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. * * @return true if we intercepted the CALL keypress (i.e. the phone was in use) * @see DialerActivity#onCreate */ boolean handleInCallOrRinging() { 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; }
public static int getSlotNotIdle(Phone phone) { Assert.assertNotNull(phone); if (phone instanceof GeminiPhone) { GeminiPhone gPhone = (GeminiPhone) phone; int[] geminiSlots = GeminiUtils.getSlots(); for (int slot : geminiSlots) { if (gPhone.getPhonebyId(slot).getState() != PhoneConstants.State.IDLE) { return slot; } } } else { if (phone.getState() != PhoneConstants.State.IDLE) { return GeminiConstants.SLOT_ID_1; } } return -1; }
public void dial(String number) { if (DBG) log("dial: " + number); // No permission check needed here: This is just a wrapper around the // ACTION_DIAL intent, which is available to any app since it puts up // the UI before it does anything. String url = createTelUrl(number); if (url == null) { return; } // PENDING: should we just silently fail if phone is offhook or ringing? Phone.State state = mPhone.getState(); if (state != Phone.State.OFFHOOK && state != Phone.State.RINGING) { Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url)); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mApp.mContext.startActivity(intent); } }
public int getCallState() { return DefaultPhoneNotifier.convertCallState(mPhone.getState()); }
public boolean isIdle() { return (mPhone.getState() == Phone.State.IDLE); }
public boolean isRinging() { return (mPhone.getState() == Phone.State.RINGING); }
public boolean isOffhook() { return (mPhone.getState() == Phone.State.OFFHOOK); }
/** * Sets the wake state and screen timeout based on the current state of the phone, and the current * state of the in-call UI. * * <p>This method is a "UI Policy" wrapper around {@link PhoneApp#requestWakeState} and {@link * PhoneApp#setScreenTimeout}. * * <p>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.) */ /* package */ void updateWakeState() { 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); setScreenTimeout( mSettings.mScreenAwake ? ScreenTimeoutDuration.DEFAULT : 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); }
@Override 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); // 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 ICC status IccCard sim = phone.getIccCard(); if (sim != null) { if (Config.LOGV) Log.v(LOG_TAG, "register for ICC 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); intentFilter.addAction(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED); intentFilter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED); intentFilter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED); intentFilter.addAction(ACTION_VIBRATE_45); 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://icc/adn")); // start with the default value to set the mute state. mShouldRestoreMuteOnInCallResume = false; // add by cytown mSettings = CallFeaturesSetting.getInstance(PreferenceManager.getDefaultSharedPreferences(this)); if (mVibrator == null) { mVibrator = (Vibrator) this.getSystemService(Context.VIBRATOR_SERVICE); mAM = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE); mVibrateIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_VIBRATE_45), 0); } // Register for Cdma Information Records // TODO(Moto): Merge // phone.registerCdmaInformationRecord(mHandler, EVENT_UNSOL_CDMA_INFO_RECORD, null); if (phone.getPhoneName().equals("CDMA")) { // Create an instance of CdmaPhoneCallState and initialize it to IDLE cdmaPhoneCallState = new CdmaPhoneCallState(); cdmaPhoneCallState.CdmaPhoneCallStateInit(); } }