CreateConnectionProcessor.java revision 6e6f6d1f7b7e5b5b506c198e6719c9c68e205042
1664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal/*
2664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal * Copyright 2014, The Android Open Source Project
3664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal *
4664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal * Licensed under the Apache License, Version 2.0 (the "License");
5664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal * you may not use this file except in compliance with the License.
6664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal * You may obtain a copy of the License at
7664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal *
8664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal *     http://www.apache.org/licenses/LICENSE-2.0
9664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal *
10664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal * Unless required by applicable law or agreed to in writing, software
11664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal * distributed under the License is distributed on an "AS IS" BASIS,
12664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal * See the License for the specific language governing permissions and
14664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal * limitations under the License.
15664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal */
16664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
17664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepalpackage com.android.telecomm;
18664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
1972890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordonimport android.telecomm.ParcelableConnection;
207957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepalimport android.telecomm.PhoneAccount;
2189176375c8d97db25588f720952a4fadbce2f9a3Evan Charltonimport android.telecomm.PhoneAccountHandle;
22664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepalimport android.telephony.DisconnectCause;
23664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
24664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepalimport java.util.ArrayList;
25664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepalimport java.util.Iterator;
26664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepalimport java.util.List;
27293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awadimport java.util.Objects;
28664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
29664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal/**
30664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal * This class creates connections to place new outgoing calls to attached to an existing incoming
31664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal * call. In either case, this class cycles through a set of connection services until:
32664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal *   - a connection service returns a newly created connection in which case the call is displayed
33664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal *     to the user
34664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal *   - a connection service cancels the process, in which case the call is aborted
35664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal */
36664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepalfinal class CreateConnectionProcessor {
37293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad
38293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad    // Describes information required to attempt to make a phone call
39293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad    private static class CallAttemptRecord {
40293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad        // The PhoneAccount describing the target connection service which we will
41293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad        // contact in order to process an attempt
42b78b27693afbe9736f0a54ec473328955251f885Ihab Awad        public final PhoneAccountHandle connectionManagerPhoneAccount;
43293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad        // The PhoneAccount which we will tell the target connection service to use
44293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad        // for attempting to make the actual phone call
45b78b27693afbe9736f0a54ec473328955251f885Ihab Awad        public final PhoneAccountHandle targetPhoneAccount;
46293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad
47293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad        public CallAttemptRecord(
48b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                PhoneAccountHandle connectionManagerPhoneAccount,
49b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                PhoneAccountHandle targetPhoneAccount) {
50b78b27693afbe9736f0a54ec473328955251f885Ihab Awad            this.connectionManagerPhoneAccount = connectionManagerPhoneAccount;
51b78b27693afbe9736f0a54ec473328955251f885Ihab Awad            this.targetPhoneAccount = targetPhoneAccount;
52293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad        }
53293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad
54293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad        @Override
55293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad        public String toString() {
56293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad            return "CallAttemptRecord("
57b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                    + Objects.toString(connectionManagerPhoneAccount) + ","
58b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                    + Objects.toString(targetPhoneAccount) + ")";
59293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad        }
606e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn
616e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn        /**
626e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn         * Determines if this instance of {@code CallAttemptRecord} has the same underlying
636e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn         * {@code PhoneAccountHandle}s as another instance.
646e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn         *
656e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn         * @param obj The other instance to compare against.
666e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn         * @return {@code True} if the {@code CallAttemptRecord}s are equal.
676e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn         */
686e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn        @Override
696e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn        public boolean equals(Object obj) {
706e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn            if (obj instanceof CallAttemptRecord) {
716e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn                CallAttemptRecord other = (CallAttemptRecord) obj;
726e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn                return Objects.equals(connectionManagerPhoneAccount,
736e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn                        other.connectionManagerPhoneAccount) &&
746e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn                        Objects.equals(targetPhoneAccount, other.targetPhoneAccount);
756e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn            }
766e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn            return false;
776e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn        }
78293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad    }
79293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad
80664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    private final Call mCall;
81664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    private final ConnectionServiceRepository mRepository;
82293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad    private List<CallAttemptRecord> mAttemptRecords;
83293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad    private Iterator<CallAttemptRecord> mAttemptRecordIterator;
84664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    private CreateConnectionResponse mResponse;
85fd6ca447a45c47aeb3956964103770475c655a26Santos Cordon    private int mLastErrorCode = DisconnectCause.OUTGOING_FAILURE;
86664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    private String mLastErrorMsg;
87664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
88664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    CreateConnectionProcessor(
89664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            Call call, ConnectionServiceRepository repository, CreateConnectionResponse response) {
90664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        mCall = call;
91664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        mRepository = repository;
92664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        mResponse = response;
93664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    }
94664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
95664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    void process() {
96664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        Log.v(this, "process");
97293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad        mAttemptRecords = new ArrayList<>();
98b78b27693afbe9736f0a54ec473328955251f885Ihab Awad        if (mCall.getTargetPhoneAccount() != null) {
997957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal            mAttemptRecords.add(new CallAttemptRecord(
1007957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal                    mCall.getTargetPhoneAccount(), mCall.getTargetPhoneAccount()));
101664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        }
1027957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        adjustAttemptsForConnectionManager();
103293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad        adjustAttemptsForEmergency();
104293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad        mAttemptRecordIterator = mAttemptRecords.iterator();
10569eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad        attemptNextPhoneAccount();
106664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    }
107664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
108664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    void abort() {
109664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        Log.v(this, "abort");
110664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
111664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        // Clear the response first to prevent attemptNextConnectionService from attempting any
112664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        // more services.
113664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        CreateConnectionResponse response = mResponse;
114664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        mResponse = null;
115664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
116664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        ConnectionServiceWrapper service = mCall.getConnectionService();
117664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        if (service != null) {
118664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            service.abort(mCall);
119664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            mCall.clearConnectionService();
120664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        }
121664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        if (response != null) {
122fb5560d634aef745466e8869f8acf496447da17bIhab Awad            response.handleCreateConnectionFailure(DisconnectCause.OUTGOING_CANCELED, null);
123664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        }
124664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    }
125664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
12669eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad    private void attemptNextPhoneAccount() {
12769eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad        Log.v(this, "attemptNextPhoneAccount");
128664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
129293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad        if (mResponse != null && mAttemptRecordIterator.hasNext()) {
130293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad            CallAttemptRecord attempt = mAttemptRecordIterator.next();
131293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad            Log.i(this, "Trying attempt %s", attempt);
13294d01629010a61f6112713f22330d5fd4baae851Evan Charlton            ConnectionServiceWrapper service =
133b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                    mRepository.getService(
134b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                            attempt.connectionManagerPhoneAccount.getComponentName());
135664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            if (service == null) {
136293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad                Log.i(this, "Found no connection service for attempt %s", attempt);
13769eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad                attemptNextPhoneAccount();
138664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            } else {
139b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                mCall.setConnectionManagerPhoneAccount(attempt.connectionManagerPhoneAccount);
140b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                mCall.setTargetPhoneAccount(attempt.targetPhoneAccount);
141664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal                mCall.setConnectionService(service);
142664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal                Log.i(this, "Attempting to call from %s", service.getComponentName());
143664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal                service.createConnection(mCall, new Response(service));
144664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            }
145664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        } else {
14669eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad            Log.v(this, "attemptNextPhoneAccount, no more accounts, failing");
147664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            if (mResponse != null) {
148fb5560d634aef745466e8869f8acf496447da17bIhab Awad                mResponse.handleCreateConnectionFailure(mLastErrorCode, mLastErrorMsg);
149664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal                mResponse = null;
150664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal                mCall.clearConnectionService();
151664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            }
152664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        }
153664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    }
154664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
1557957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal    private boolean shouldSetConnectionManager() {
1567957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        if (mAttemptRecords.size() == 0) {
1577957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal            return false;
158293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad        }
1597957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal
1607957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        if (mAttemptRecords.size() > 1) {
1617957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal            Log.d(this, "shouldSetConnectionManager, error, mAttemptRecords should not have more "
1627957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal                    + "than 1 record");
1637957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal            return false;
1647957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        }
1657957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal
1667957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        PhoneAccountRegistrar registrar = TelecommApp.getInstance().getPhoneAccountRegistrar();
1677957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        PhoneAccountHandle connectionManager = registrar.getSimCallManager();
1687957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        if (connectionManager == null) {
1697957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal            return false;
1707957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        }
1717957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal
1727957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        PhoneAccountHandle targetPhoneAccountHandle = mAttemptRecords.get(0).targetPhoneAccount;
1737957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        if (Objects.equals(connectionManager, targetPhoneAccountHandle)) {
1747957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal            return false;
1757957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        }
1767957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal
1777957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        // Connection managers are only allowed to manage SIM subscriptions.
1787957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        PhoneAccount targetPhoneAccount = registrar.getPhoneAccount(targetPhoneAccountHandle);
1797957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        boolean isSimSubscription = (targetPhoneAccount.getCapabilities() &
1807957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal                PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) != 0;
1817957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        if (!isSimSubscription) {
1827957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal            return false;
1837957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        }
1847957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal
1857957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        return true;
1867957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal    }
1877957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal
1887957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal    // If there exists a registered connection manager then use it.
1897957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal    private void adjustAttemptsForConnectionManager() {
1907957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        if (shouldSetConnectionManager()) {
1917957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal            CallAttemptRecord record = new CallAttemptRecord(
1927957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal                    TelecommApp.getInstance().getPhoneAccountRegistrar().getSimCallManager(),
1937957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal                    mAttemptRecords.get(0).targetPhoneAccount);
1947957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal            Log.v(this, "setConnectionManager, changing %s -> %s",
1957957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal                    mAttemptRecords.get(0).targetPhoneAccount, record);
1967957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal            mAttemptRecords.set(0, record);
1977957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        } else {
1987957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal            Log.v(this, "setConnectionManager, not changing");
199293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad        }
200293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad    }
201293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad
202664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    // If we are possibly attempting to call a local emergency number, ensure that the
20369eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad    // plain PSTN connection services are listed, and nothing else.
204293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad    private void adjustAttemptsForEmergency()  {
20569eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad        if (TelephonyUtil.shouldProcessAsEmergency(TelecommApp.getInstance(), mCall.getHandle())) {
20669eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad            Log.i(this, "Emergency number detected");
207293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad            mAttemptRecords.clear();
20894d01629010a61f6112713f22330d5fd4baae851Evan Charlton            List<PhoneAccountHandle> allAccountHandles = TelecommApp.getInstance()
2096fb37c87836b5245046bd3b14320823ab839a10cIhab Awad                    .getPhoneAccountRegistrar().getOutgoingPhoneAccounts();
2106e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn            // First, add the PSTN phone account
21194d01629010a61f6112713f22330d5fd4baae851Evan Charlton            for (int i = 0; i < allAccountHandles.size(); i++) {
21294d01629010a61f6112713f22330d5fd4baae851Evan Charlton                if (TelephonyUtil.isPstnComponentName(
21394d01629010a61f6112713f22330d5fd4baae851Evan Charlton                        allAccountHandles.get(i).getComponentName())) {
21494d01629010a61f6112713f22330d5fd4baae851Evan Charlton                    Log.i(this, "Will try PSTN account %s for emergency", allAccountHandles.get(i));
215293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad                    mAttemptRecords.add(
216293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad                            new CallAttemptRecord(
217293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad                                    allAccountHandles.get(i),
218293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad                                    allAccountHandles.get(i)));
219664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal                }
220664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            }
2216e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn
2226e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn            // Next, add the connection manager account as a backup.
2236e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn            PhoneAccountHandle callManager = TelecommApp.getInstance()
2246e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn                    .getPhoneAccountRegistrar().getSimCallManager();
2256e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn            CallAttemptRecord callAttemptRecord = new CallAttemptRecord(callManager,
2266e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn                    TelecommApp.getInstance().getPhoneAccountRegistrar().
2276e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn                            getDefaultOutgoingPhoneAccount());
2286e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn
2296e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn            if (callManager != null && !mAttemptRecords.contains(callAttemptRecord)) {
2306e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn                Log.i(this, "Will try Connection Manager account %s for emergency",
2316e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn                        callManager);
2326e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn                mAttemptRecords.add(callAttemptRecord);
2336e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn            }
234664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        }
235664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    }
236664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
237664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    private class Response implements CreateConnectionResponse {
238664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        private final ConnectionServiceWrapper mService;
239664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
240664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        Response(ConnectionServiceWrapper service) {
241664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            mService = service;
242664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        }
243664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
244664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        @Override
245fb5560d634aef745466e8869f8acf496447da17bIhab Awad        public void handleCreateConnectionSuccess(ParcelableConnection connection) {
246664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            if (mResponse == null) {
247fb5560d634aef745466e8869f8acf496447da17bIhab Awad                // Nobody is listening for this connection attempt any longer; ask the responsible
248fb5560d634aef745466e8869f8acf496447da17bIhab Awad                // ConnectionService to tear down any resources associated with the call
249664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal                mService.abort(mCall);
250664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            } else {
251fb5560d634aef745466e8869f8acf496447da17bIhab Awad                // Success -- share the good news and remember that we are no longer interested
252fb5560d634aef745466e8869f8acf496447da17bIhab Awad                // in hearing about any more attempts
253fb5560d634aef745466e8869f8acf496447da17bIhab Awad                mResponse.handleCreateConnectionSuccess(connection);
25472890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon                mResponse = null;
255664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            }
256664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        }
257664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
258664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        @Override
259fb5560d634aef745466e8869f8acf496447da17bIhab Awad        public void handleCreateConnectionFailure(int code, String msg) {
260fb5560d634aef745466e8869f8acf496447da17bIhab Awad            // Failure of some sort; record the reasons for failure and try again if possible
261fb5560d634aef745466e8869f8acf496447da17bIhab Awad            Log.d(CreateConnectionProcessor.this, "Connection failed: %d (%s)", code, msg);
262664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            mLastErrorCode = code;
263664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            mLastErrorMsg = msg;
26469eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad            attemptNextPhoneAccount();
265664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        }
266664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    }
267664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal}
268