All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src.com.android.internal.telephony.imsphone.ImsExternalConnection Maven / Gradle / Ivy

Go to download

A library jar that provides APIs for Applications written for the Google Android Platform.

There is a newer version: 15-robolectric-12650502
Show newest version
/*
 * Copyright (C) 2016 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.internal.telephony.imsphone;

import com.android.internal.R;
import com.android.internal.telephony.Call;
import com.android.internal.telephony.CallStateException;
import com.android.internal.telephony.Connection;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.UUSInfo;

import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.net.Uri;
import android.telecom.PhoneAccount;
import android.telephony.PhoneNumberUtils;
import android.telephony.ims.ImsExternalCallState;

import java.util.Collections;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Represents an IMS call external to the device.  This class is used to represent a call which
 * takes places on a secondary device associated with this one.  Originates from a Dialog Event
 * Package.
 *
 * Dialog event package information is received from the IMS framework via
 * {@link ImsExternalCallState} instances.
 *
 * @hide
 */
public class ImsExternalConnection extends Connection {

    private static final String CONFERENCE_PREFIX = "conf";
    private final Context mContext;

    public interface Listener {
        void onPullExternalCall(ImsExternalConnection connection);
    }

    /**
     * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
     * load factor before resizing, 1 means we only expect a single thread to
     * access the map so make only a single shard
     */
    private final Set mListeners = Collections.newSetFromMap(
            new ConcurrentHashMap(8, 0.9f, 1));

    /**
     * The unqiue dialog event package specified ID associated with this external connection.
     */
    private int mCallId;

    /**
     * A backing call associated with this external connection.
     */
    private ImsExternalCall mCall;

    /**
     * The original address as contained in the dialog event package.
     */
    private Uri mOriginalAddress;

    /**
     * Determines if the call is pullable.
     */
    private boolean mIsPullable;

    protected ImsExternalConnection(Phone phone, int callId, Uri address, boolean isPullable) {
        super(phone.getPhoneType());
        mContext = phone.getContext();
        mCall = new ImsExternalCall(phone, this);
        mCallId = callId;
        setExternalConnectionAddress(address);
        mNumberPresentation = PhoneConstants.PRESENTATION_ALLOWED;
        mIsPullable = isPullable;

        rebuildCapabilities();
        setActive();
    }

    /**
     * @return the unique ID of this connection from the dialog event package data.
     */
    public int getCallId() {
        return mCallId;
    }

    @Override
    public Call getCall() {
        return mCall;
    }

    @Override
    public long getDisconnectTime() {
        return 0;
    }

    @Override
    public long getHoldDurationMillis() {
        return 0;
    }

    @Override
    public String getVendorDisconnectCause() {
        return null;
    }

    @Override
    public void hangup() throws CallStateException {
        // No-op - Hangup is not supported for external calls.
    }

    @Override
    public void deflect(String number) throws CallStateException {
        // Deflect is not supported for external calls.
        throw new CallStateException ("Deflect is not supported for external calls");
    }

    @Override
    public void separate() throws CallStateException {
        // No-op - Separate is not supported for external calls.
    }

    @Override
    public void proceedAfterWaitChar() {
        // No-op - not supported for external calls.
    }

    @Override
    public void proceedAfterWildChar(String str) {
        // No-op - not supported for external calls.
    }

    @Override
    public void cancelPostDial() {
        // No-op - not supported for external calls.
    }

    @Override
    public int getNumberPresentation() {
        return mNumberPresentation;
    }

    @Override
    public UUSInfo getUUSInfo() {
        return null;
    }

    @Override
    public int getPreciseDisconnectCause() {
        return 0;
    }

    @Override
    public boolean isMultiparty() {
        return false;
    }

    /**
     * Called by a {@link android.telecom.Connection} to indicate that this call should be pulled
     * to the local device.
     *
     * Informs all listeners, in this case {@link ImsExternalCallTracker}, of the request to pull
     * the call.
     */
    @Override
    public void pullExternalCall() {
        for (Listener listener : mListeners) {
            listener.onPullExternalCall(this);
        }
    }

    /**
     * Sets this external call as active.
     */
    @UnsupportedAppUsage
    public void setActive() {
        if (mCall == null) {
            return;
        }
        mCall.setActive();
    }

    /**
     * Sets this external call as terminated.
     */
    public void setTerminated() {
        if (mCall == null) {
            return;
        }

        mCall.setTerminated();
    }

    /**
     * Changes whether the call can be pulled or not.
     *
     * @param isPullable {@code true} if the call can be pulled, {@code false} otherwise.
     */
    public void setIsPullable(boolean isPullable) {
        mIsPullable = isPullable;
        rebuildCapabilities();
    }

    /**
     * Sets the address of this external connection.  Ensures that dialog event package SIP
     * {@link Uri}s are converted to a regular telephone number.
     *
     * @param address The address from the dialog event package.
     */
    public void setExternalConnectionAddress(Uri address) {
        mOriginalAddress = address;

        if (PhoneAccount.SCHEME_SIP.equals(address.getScheme())) {
            if (address.getSchemeSpecificPart().startsWith(CONFERENCE_PREFIX)) {
                mCnapName = mContext.getString(com.android.internal.R.string.conference_call);
                mCnapNamePresentation = PhoneConstants.PRESENTATION_ALLOWED;
                mAddress = "";
                mNumberPresentation = PhoneConstants.PRESENTATION_RESTRICTED;
                return;
            }
        }
        Uri telUri = PhoneNumberUtils.convertSipUriToTelUri(address);
        mAddress = telUri.getSchemeSpecificPart();
    }

    public void addListener(Listener listener) {
        mListeners.add(listener);
    }

    public void removeListener(Listener listener) {
        mListeners.remove(listener);
    }

    /**
     * Build a human representation of a connection instance, suitable for debugging.
     * Don't log personal stuff unless in debug mode.
     * @return a string representing the internal state of this connection.
     */
    public String toString() {
        StringBuilder str = new StringBuilder(128);
        str.append("[ImsExternalConnection dialogCallId:");
        str.append(mCallId);
        str.append(" state:");
        if (mCall.getState() == Call.State.ACTIVE) {
            str.append("Active");
        } else if (mCall.getState() == Call.State.DISCONNECTED) {
            str.append("Disconnected");
        }
        str.append("]");
        return str.toString();
    }

    /**
     * Rebuilds the connection capabilities.
     */
    @UnsupportedAppUsage
    private void rebuildCapabilities() {
        int capabilities = Capability.IS_EXTERNAL_CONNECTION;
        if (mIsPullable) {
            capabilities |= Capability.IS_PULLABLE;
        }

        setConnectionCapabilities(capabilities);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy