示例#1
0
  /**
   * 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();
   }
 }
示例#3
0
 /**
  * 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;
 }
示例#4
0
 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);
 }
示例#10
0
  /**
   * 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);
  }
示例#11
0
  @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();
    }
  }