예제 #1
0
  /* package */
  void resumeWaitingOrHolding() throws CallStateException {
    if (DBG) log("resumeWaitingOrHolding");

    try {
      if (mForegroundCall.getState().isAlive()) {
        // resume foreground call after holding background call
        // they were switched before holding
        ImsCall imsCall = mForegroundCall.getImsCall();
        if (imsCall != null) imsCall.resume();
      } else if (mRingingCall.getState() == ImsPhoneCall.State.WAITING) {
        // accept waiting call after holding background call
        ImsCall imsCall = mRingingCall.getImsCall();
        if (imsCall != null) imsCall.accept(ImsCallProfile.CALL_TYPE_VOICE);
      } else {
        // Just resume background call.
        // To distinguish resuming call with swapping calls
        // we do not switch calls.here
        // ImsPhoneConnection.update will chnage the parent when completed
        ImsCall imsCall = mBackgroundCall.getImsCall();
        if (imsCall != null) imsCall.resume();
      }
    } catch (ImsException e) {
      throw new CallStateException(e.getMessage());
    }
  }
예제 #2
0
  void conference() {
    if (DBG) log("conference");

    ImsCall fgImsCall = mForegroundCall.getImsCall();
    if (fgImsCall == null) {
      log("conference no foreground ims call");
      return;
    }

    ImsCall bgImsCall = mBackgroundCall.getImsCall();
    if (bgImsCall == null) {
      log("conference no background ims call");
      return;
    }

    // Keep track of the connect time of the earliest call so that it can be set on the
    // {@code ImsConference} when it is created.
    long conferenceConnectTime =
        Math.min(
            mForegroundCall.getEarliestConnectTime(), mBackgroundCall.getEarliestConnectTime());
    ImsPhoneConnection foregroundConnection = mForegroundCall.getFirstConnection();
    if (foregroundConnection != null) {
      foregroundConnection.setConferenceConnectTime(conferenceConnectTime);
    }

    try {
      fgImsCall.merge(bgImsCall);
    } catch (ImsException e) {
      log("conference " + e.getMessage());
    }
  }
예제 #3
0
  void switchWaitingOrHoldingAndActive() throws CallStateException {
    if (DBG) log("switchWaitingOrHoldingAndActive");

    if (mRingingCall.getState() == ImsPhoneCall.State.INCOMING) {
      throw new CallStateException("cannot be in the incoming state");
    }

    if (mForegroundCall.getState() == ImsPhoneCall.State.ACTIVE) {
      ImsCall imsCall = mForegroundCall.getImsCall();
      if (imsCall == null) {
        throw new CallStateException("no ims call");
      }

      // Swap the ImsCalls pointed to by the foreground and background ImsPhoneCalls.
      // If hold or resume later fails, we will swap them back.
      mSwitchingFgAndBgCalls = true;
      mCallExpectedToResume = mBackgroundCall.getImsCall();
      mForegroundCall.switchWith(mBackgroundCall);

      // Hold the foreground call; once the foreground call is held, the background call will
      // be resumed.
      try {
        imsCall.hold();
      } catch (ImsException e) {
        mForegroundCall.switchWith(mBackgroundCall);
        throw new CallStateException(e.getMessage());
      }
    } else if (mBackgroundCall.getState() == ImsPhoneCall.State.HOLDING) {
      resumeWaitingOrHolding();
    }
  }
예제 #4
0
  /* package */ void hangup(ImsPhoneCall call) throws CallStateException {
    if (DBG) log("hangup call");

    if (call.getConnections().size() == 0) {
      throw new CallStateException("no connections");
    }

    ImsCall imsCall = call.getImsCall();
    boolean rejectCall = false;

    if (call == mRingingCall) {
      if (Phone.DEBUG_PHONE) log("(ringing) hangup incoming");
      rejectCall = true;
    } else if (call == mForegroundCall) {
      if (call.isDialingOrAlerting()) {
        if (Phone.DEBUG_PHONE) {
          log("(foregnd) hangup dialing or alerting...");
        }
      } else {
        if (Phone.DEBUG_PHONE) {
          log("(foregnd) hangup foreground");
        }
        // held call will be resumed by onCallTerminated
      }
    } else if (call == mBackgroundCall) {
      if (Phone.DEBUG_PHONE) {
        log("(backgnd) hangup waiting or background");
      }
    } else {
      throw new CallStateException(
          "ImsPhoneCall " + call + "does not belong to ImsPhoneCallTracker " + this);
    }

    call.onHangupLocal();

    try {
      if (imsCall != null) {
        if (rejectCall) imsCall.reject(ImsReasonInfo.CODE_USER_DECLINE);
        else imsCall.terminate(ImsReasonInfo.CODE_USER_TERMINATED);
      } else if (mPendingMO != null && call == mForegroundCall) {
        // is holding a foreground call
        mPendingMO.update(null, ImsPhoneCall.State.DISCONNECTED);
        mPendingMO.onDisconnect();
        removeConnection(mPendingMO);
        mPendingMO = null;
        updatePhoneState();
        removeMessages(EVENT_DIAL_PENDINGMO);
      }
    } catch (ImsException e) {
      throw new CallStateException(e.getMessage());
    }

    mPhone.notifyPreciseCallStateChanged();
  }
예제 #5
0
  @Override
  protected String readValue() {
    ImsLboPcscf[] lboPcscfs = null;

    try {
      ImsConfig imsConfig = mImsManager.getConfigInterface();
      lboPcscfs = imsConfig.getMasterLboPcscfValue();
    } catch (ImsException e) {
      e.printStackTrace();
    }

    return lboPcscfs[mIndex].getLboPcscfAddress();
  }
예제 #6
0
  @Override
  protected void writeValue(String value) {
    ImsLboPcscf[] values = null;

    try {
      ImsConfig imsConfig = mImsManager.getConfigInterface();
      values = imsConfig.getMasterLboPcscfValue();

      values[mIndex].setLboPcscfAddress(value);
      imsConfig.setProvisionedLboPcscfValue(values);
    } catch (ImsException e) {
      e.printStackTrace();
    }
  }
예제 #7
0
  @Override
  public void configureDmTree(MdmTree tree) {
    ImsConfig imsConfig = null;
    try {
      imsConfig = mImsManager.getConfigInterface();
    } catch (ImsException e) {
      e.printStackTrace();
    }

    // Normal Nodes
    registerNodeIoHandler(
        tree, "P-CSCF_Address", ConfigConstants.IMS_MO_PCSCF, true, StringHandler.class);
    registerNodeIoHandler(
        tree, "Timer_T1", ConfigConstants.SIP_T1_TIMER, true, IntegerHandler.class);
    registerNodeIoHandler(
        tree, "Timer_T2", ConfigConstants.SIP_T2_TIMER, true, IntegerHandler.class);
    registerNodeIoHandler(
        tree, "Timer_T4", ConfigConstants.SIP_TF_TIMER, true, IntegerHandler.class);
    registerNodeIoHandler(
        tree, "Private_user_identity", ConfigConstants.IMS_MO_IMPI, false, StringHandler.class);
    registerNodeIoHandler(
        tree,
        "Home_network_domain_name",
        ConfigConstants.IMS_MO_DOMAIN,
        false,
        StringHandler.class);
    registerNodeIoHandler(
        tree,
        "Resource_Allocation_Mode",
        ConfigConstants.IMS_MO_RESOURCE,
        true,
        BooleanHandler.class);
    registerNodeIoHandler(
        tree,
        "Voice_Domain_Preference_E_UTRAN",
        ConfigConstants.IMS_MO_VOICE_E,
        true,
        IntegerHandler.class);
    registerNodeIoHandler(
        tree,
        "SMS_Over_IP_Networks_Indication",
        ConfigConstants.IMS_MO_SMS,
        true,
        BooleanHandler.class);
    registerNodeIoHandler(
        tree, "Keep_Alive_Enabled", ConfigConstants.IMS_MO_KEEPALIVE, true, BooleanHandler.class);
    registerNodeIoHandler(
        tree,
        "Voice_Domain_Preference_UTRAN",
        ConfigConstants.IMS_MO_VOICE_U,
        true,
        IntegerHandler.class);
    registerNodeIoHandler(
        tree,
        "Mobility_Management_IMS_Voice_Termination",
        ConfigConstants.IMS_MO_MOBILITY,
        true,
        BooleanHandler.class);
    registerNodeIoHandler(
        tree, "RegRetryBaseTime", ConfigConstants.IMS_MO_REG_BASE, true, IntegerHandler.class);
    registerNodeIoHandler(
        tree, "RegRetryMaxTime", ConfigConstants.IMS_MO_REG_MAX, true, IntegerHandler.class);
    // Public User Identity List
    try {
      // 1. clear old nodes
      for (String child : tree.listChildren(PUBLIC_USER_IDENTITY_LIST_PATH)) {
        tree.deleteNode(MdmTree.makeUri(PUBLIC_USER_IDENTITY_LIST_PATH, child));
      }
      // 2. create new nodes
      String[] publicUserIdentities =
          imsConfig.getMasterStringArrayValue(ConfigConstants.IMS_MO_IMPU);
      for (int i = 0; i < publicUserIdentities.length; ++i) {
        Log.d(TAG.NODEIOHANDLER, "publicUserIdentities[i] is " + publicUserIdentities[i]);
        if (publicUserIdentities[i] == null) {
          continue;
        }
        String nodeXId = Integer.toString(i + 1);
        tree.addInteriorChildNode(PUBLIC_USER_IDENTITY_LIST_PATH, nodeXId, null);
        String leafUri =
            MdmTree.makeUri(PUBLIC_USER_IDENTITY_LIST_PATH, nodeXId, "Public_user_identity");
        Utilities.addLeafNodeChecked(
            tree, leafUri, "chr", null, publicUserIdentities[i].getBytes());
        tree.replaceACL(leafUri, "Get=*");
      }
    } catch (MdmException e) {
      throw new Error(e);
    } catch (ImsException e) {
      throw new Error(e);
    }

    // ICSI List
    try {
      // 1. clear old nodes
      for (String child : tree.listChildren(ICSI_LIST_PATH)) {
        tree.deleteNode(MdmTree.makeUri(ICSI_LIST_PATH, child));
      }
      // 2. create new nodes & register handlers
      ImsIcsi[] icsiList = imsConfig.getMasterIcsiValue();
      for (int i = 0; i < icsiList.length; ++i) {
        if (icsiList[i] == null) {
          continue;
        }
        String nodeXId = Integer.toString(i + 1);
        tree.addInteriorChildNode(ICSI_LIST_PATH, nodeXId, null);
        String leafUri = MdmTree.makeUri(ICSI_LIST_PATH, nodeXId, "ICSI");
        String data = icsiList[i].getIcsi();
        Utilities.addLeafNodeChecked(
            tree, leafUri, "chr", null, (data == null ? null : data.getBytes()));
        tree.replaceACL(leafUri, "Get=*&Replace=*");
        tree.registerNodeIoHandler(leafUri, new ICSIHandler(leafUri, mImsManager, i));
        leafUri = MdmTree.makeUri(ICSI_LIST_PATH, nodeXId, "ICSI_Resource_Allocation_Mode");
        Utilities.addLeafNodeChecked(
            tree, leafUri, "bool", null, (icsiList[i].getIsAllocated() ? "1" : "0").getBytes());
        tree.replaceACL(leafUri, "Get=*&Replace=*");
        tree.registerNodeIoHandler(leafUri, new ICSIModeHandler(leafUri, mImsManager, i));
      }
    } catch (MdmException e) {
      throw new Error(e);
    } catch (ImsException e) {
      throw new Error(e);
    }

    // LBO P-CSCF Address
    try {
      // 1. clear old nodes
      for (String child : tree.listChildren(LBO_PCSCF_ADDRESS_PATH)) {
        tree.deleteNode(MdmTree.makeUri(LBO_PCSCF_ADDRESS_PATH, child));
      }
      // 2. create new nodes & register handlers
      ImsLboPcscf[] addressList = imsConfig.getMasterLboPcscfValue();
      for (int i = 0; i < addressList.length; ++i) {
        if (addressList[i] == null) {
          continue;
        }
        String nodeXId = Integer.toString(i + 1);
        tree.addInteriorChildNode(LBO_PCSCF_ADDRESS_PATH, nodeXId, null);
        String leafUri = MdmTree.makeUri(LBO_PCSCF_ADDRESS_PATH, nodeXId, "Address");
        String data = addressList[i].getLboPcscfAddress();
        Utilities.addLeafNodeChecked(
            tree, leafUri, "chr", null, (data == null ? null : data.getBytes()));
        tree.replaceACL(leafUri, "Get=*&Replace=*");
        tree.registerNodeIoHandler(leafUri, new PCSCFAddressHandler(leafUri, mImsManager, i));
        leafUri = MdmTree.makeUri(LBO_PCSCF_ADDRESS_PATH, nodeXId, "AddressType");
        data = addressList[i].getLboPcscfAddressType();
        Utilities.addLeafNodeChecked(
            tree, leafUri, "chr", null, (data == null ? null : data.getBytes()));
        tree.replaceACL(leafUri, "Get=*&Replace=*");
        tree.registerNodeIoHandler(leafUri, new PCSCFAddressTypeHandler(leafUri, mImsManager, i));
      }
    } catch (MdmException e) {
      throw new Error(e);
    } catch (ImsException e) {
      throw new Error(e);
    }

    // Phone Context List
    try {
      // 1. clear old nodes
      for (String child : tree.listChildren(PHONE_CONTEXT_LIST_PATH)) {
        tree.deleteNode(MdmTree.makeUri(PHONE_CONTEXT_LIST_PATH, child));
      }
      // 2. create new nodes & register handlers
      ImsPhoneCtx[] contextList = imsConfig.getMasterImsPhoneCtxValue();
      for (int i = 0; i < contextList.length; ++i) {
        if (contextList[i] == null) {
          continue;
        }
        String nodeXId = Integer.toString(i + 1);
        tree.addInteriorChildNode(PHONE_CONTEXT_LIST_PATH, nodeXId, null);
        String leafUri = MdmTree.makeUri(PHONE_CONTEXT_LIST_PATH, nodeXId, "PhoneContext");
        String data = contextList[i].getPhoneCtx();
        Utilities.addLeafNodeChecked(
            tree, leafUri, "chr", null, (data == null ? null : data.getBytes()));
        tree.replaceACL(leafUri, "Get=*&Replace=*");
        tree.registerNodeIoHandler(leafUri, new PhoneContextHandler(leafUri, mImsManager, i));
        leafUri = MdmTree.makeUri(PHONE_CONTEXT_LIST_PATH, nodeXId, "Public_user_identity");
        data = contextList[i].getPhoneCtxIpuis()[0];
        Utilities.addLeafNodeChecked(
            tree, leafUri, "chr", null, (data == null ? null : data.getBytes()));
        tree.replaceACL(leafUri, "Get=*&Replace=*");
        tree.registerNodeIoHandler(
            leafUri, new PhoneContextIdentityHandler(leafUri, mImsManager, i));
      }
    } catch (MdmException e) {
      throw new Error(e);
    } catch (ImsException e) {
      throw new Error(e);
    }

    // RCS-related
    try {
      String uri = MdmTree.makeUri(RCS_PATH, "AuthType");
      tree.registerNodeIoHandler(uri, new RCSAuthTypeHandler(uri, mImsManager));
      uri = MdmTree.makeUri(RCS_PATH, "Realm");
      tree.registerNodeIoHandler(uri, new RCSRealmHandler(uri, mImsManager));
      uri = MdmTree.makeUri(RCS_PATH, "UserName");
      tree.registerNodeIoHandler(uri, new RCSUserNameHandler(uri, mImsManager));
      uri = MdmTree.makeUri(RCS_PATH, "UserPwd");
      tree.registerNodeIoHandler(uri, new RCSUserPwdHandler(uri, mImsManager));
    } catch (MdmException e) {
      throw new Error(e);
    }

    // Write back
    try {
      tree.writeToPersistentStorage();
    } catch (MdmException e) {
      throw new Error(e);
    }
  }
예제 #8
0
  /** oirMode is one of the CLIR_ constants */
  synchronized Connection dial(String dialString, int clirMode, int videoState)
      throws CallStateException {
    boolean isPhoneInEcmMode =
        SystemProperties.getBoolean(TelephonyProperties.PROPERTY_INECM_MODE, false);
    boolean isEmergencyNumber = PhoneNumberUtils.isEmergencyNumber(dialString);

    if (DBG) log("dial clirMode=" + clirMode);

    // note that this triggers call state changed notif
    clearDisconnected();

    if (mImsManager == null) {
      throw new CallStateException("service not available");
    }

    if (!canDial()) {
      throw new CallStateException("cannot dial in current state");
    }

    if (isPhoneInEcmMode && isEmergencyNumber) {
      handleEcmTimer(ImsPhone.CANCEL_ECM_TIMER);
    }

    boolean holdBeforeDial = false;

    // The new call must be assigned to the foreground call.
    // That call must be idle, so place anything that's
    // there on hold
    if (mForegroundCall.getState() == ImsPhoneCall.State.ACTIVE) {
      if (mBackgroundCall.getState() != ImsPhoneCall.State.IDLE) {
        // we should have failed in !canDial() above before we get here
        throw new CallStateException("cannot dial in current state");
      }
      // foreground call is empty for the newly dialed connection
      holdBeforeDial = true;
      switchWaitingOrHoldingAndActive();
    }

    ImsPhoneCall.State fgState = ImsPhoneCall.State.IDLE;
    ImsPhoneCall.State bgState = ImsPhoneCall.State.IDLE;

    mClirMode = clirMode;

    synchronized (mSyncHold) {
      if (holdBeforeDial) {
        fgState = mForegroundCall.getState();
        bgState = mBackgroundCall.getState();

        // holding foreground call failed
        if (fgState == ImsPhoneCall.State.ACTIVE) {
          throw new CallStateException("cannot dial in current state");
        }

        // holding foreground call succeeded
        if (bgState == ImsPhoneCall.State.HOLDING) {
          holdBeforeDial = false;
        }
      }

      mPendingMO =
          new ImsPhoneConnection(
              mPhone.getContext(), checkForTestEmergencyNumber(dialString), this, mForegroundCall);
    }
    addConnection(mPendingMO);

    if (!holdBeforeDial) {
      if ((!isPhoneInEcmMode) || (isPhoneInEcmMode && isEmergencyNumber)) {
        dialInternal(mPendingMO, clirMode, videoState);
      } else {
        try {
          getEcbmInterface().exitEmergencyCallbackMode();
        } catch (ImsException e) {
          e.printStackTrace();
          throw new CallStateException("service not available");
        }
        mPhone.setOnEcbModeExitResponse(this, EVENT_EXIT_ECM_RESPONSE_CDMA, null);
        pendingCallClirMode = clirMode;
        pendingCallVideoState = videoState;
        pendingCallInEcm = true;
      }
    }

    updatePhoneState();
    mPhone.notifyPreciseCallStateChanged();

    return mPendingMO;
  }