CreateConnectionProcessor.java revision 646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288
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
177cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnpackage com.android.server.telecom;
18664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
1991d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunnimport android.content.Context;
20646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepalimport android.telecom.CallState;
21701dc006ac11625b55d872f1639107b028933895Andrew Leeimport android.telecom.DisconnectCause;
227cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.ParcelableConnection;
2391d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunnimport android.telecom.Phone;
247cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.PhoneAccount;
257cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.PhoneAccountHandle;
26646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepalimport android.telephony.TelephonyManager;
27646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepalimport android.telephony.PhoneStateListener;
28646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepalimport android.telephony.ServiceState;
29664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
3091d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn// TODO: Needed for move to system service: import com.android.internal.R;
3191d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn
32664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepalimport java.util.ArrayList;
33646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepalimport java.util.Collection;
34646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepalimport java.util.HashSet;
35664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepalimport java.util.Iterator;
36664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepalimport java.util.List;
37646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepalimport java.util.Set;
38293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awadimport java.util.Objects;
39664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
40664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal/**
419250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee * This class creates connections to place new outgoing calls or to attach to an existing incoming
42664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal * call. In either case, this class cycles through a set of connection services until:
43664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal *   - a connection service returns a newly created connection in which case the call is displayed
44664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal *     to the user
45664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal *   - a connection service cancels the process, in which case the call is aborted
46664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal */
47664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepalfinal class CreateConnectionProcessor {
48293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad
49293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad    // Describes information required to attempt to make a phone call
50293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad    private static class CallAttemptRecord {
51293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad        // The PhoneAccount describing the target connection service which we will
52293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad        // contact in order to process an attempt
53b78b27693afbe9736f0a54ec473328955251f885Ihab Awad        public final PhoneAccountHandle connectionManagerPhoneAccount;
54293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad        // The PhoneAccount which we will tell the target connection service to use
55293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad        // for attempting to make the actual phone call
56b78b27693afbe9736f0a54ec473328955251f885Ihab Awad        public final PhoneAccountHandle targetPhoneAccount;
57293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad
58293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad        public CallAttemptRecord(
59b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                PhoneAccountHandle connectionManagerPhoneAccount,
60b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                PhoneAccountHandle targetPhoneAccount) {
61b78b27693afbe9736f0a54ec473328955251f885Ihab Awad            this.connectionManagerPhoneAccount = connectionManagerPhoneAccount;
62b78b27693afbe9736f0a54ec473328955251f885Ihab Awad            this.targetPhoneAccount = targetPhoneAccount;
63293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad        }
64293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad
65293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad        @Override
66293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad        public String toString() {
67293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad            return "CallAttemptRecord("
68b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                    + Objects.toString(connectionManagerPhoneAccount) + ","
69b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                    + Objects.toString(targetPhoneAccount) + ")";
70293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad        }
716e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn
726e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn        /**
736e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn         * Determines if this instance of {@code CallAttemptRecord} has the same underlying
746e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn         * {@code PhoneAccountHandle}s as another instance.
756e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn         *
766e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn         * @param obj The other instance to compare against.
776e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn         * @return {@code True} if the {@code CallAttemptRecord}s are equal.
786e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn         */
796e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn        @Override
806e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn        public boolean equals(Object obj) {
816e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn            if (obj instanceof CallAttemptRecord) {
826e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn                CallAttemptRecord other = (CallAttemptRecord) obj;
836e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn                return Objects.equals(connectionManagerPhoneAccount,
846e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn                        other.connectionManagerPhoneAccount) &&
856e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn                        Objects.equals(targetPhoneAccount, other.targetPhoneAccount);
866e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn            }
876e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn            return false;
886e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn        }
89293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad    }
90293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad
91664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    private final Call mCall;
92664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    private final ConnectionServiceRepository mRepository;
93293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad    private List<CallAttemptRecord> mAttemptRecords;
94293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad    private Iterator<CallAttemptRecord> mAttemptRecordIterator;
95664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    private CreateConnectionResponse mResponse;
96701dc006ac11625b55d872f1639107b028933895Andrew Lee    private DisconnectCause mLastErrorDisconnectCause;
9791d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn    private final PhoneAccountRegistrar mPhoneAccountRegistrar;
9891d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn    private final Context mContext;
99bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal    private boolean mShouldUseConnectionManager = true;
100646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal    private CreateConnectionTimeout mTimeout;
101664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
102664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    CreateConnectionProcessor(
10391d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn            Call call, ConnectionServiceRepository repository, CreateConnectionResponse response,
10491d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn            PhoneAccountRegistrar phoneAccountRegistrar, Context context) {
105664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        mCall = call;
106664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        mRepository = repository;
107664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        mResponse = response;
10891d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn        mPhoneAccountRegistrar = phoneAccountRegistrar;
10991d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn        mContext = context;
110664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    }
111664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
112752cacbc0b88b9b4cb4ab7bd547e17b5d2690693Sailesh Nepal    boolean isProcessingComplete() {
113752cacbc0b88b9b4cb4ab7bd547e17b5d2690693Sailesh Nepal        return mResponse == null;
114752cacbc0b88b9b4cb4ab7bd547e17b5d2690693Sailesh Nepal    }
115752cacbc0b88b9b4cb4ab7bd547e17b5d2690693Sailesh Nepal
116646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal    boolean isCallTimedOut() {
117646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal        return mTimeout != null && mTimeout.isCallTimedOut();
118646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal    }
119646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal
120664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    void process() {
121664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        Log.v(this, "process");
122646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal        clearTimeout();
123293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad        mAttemptRecords = new ArrayList<>();
124b78b27693afbe9736f0a54ec473328955251f885Ihab Awad        if (mCall.getTargetPhoneAccount() != null) {
1257957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal            mAttemptRecords.add(new CallAttemptRecord(
1267957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal                    mCall.getTargetPhoneAccount(), mCall.getTargetPhoneAccount()));
127664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        }
1287957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        adjustAttemptsForConnectionManager();
129293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad        adjustAttemptsForEmergency();
130293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad        mAttemptRecordIterator = mAttemptRecords.iterator();
13169eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad        attemptNextPhoneAccount();
132664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    }
133664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
134752cacbc0b88b9b4cb4ab7bd547e17b5d2690693Sailesh Nepal    boolean hasMorePhoneAccounts() {
135752cacbc0b88b9b4cb4ab7bd547e17b5d2690693Sailesh Nepal        return mAttemptRecordIterator.hasNext();
136752cacbc0b88b9b4cb4ab7bd547e17b5d2690693Sailesh Nepal    }
137752cacbc0b88b9b4cb4ab7bd547e17b5d2690693Sailesh Nepal
138752cacbc0b88b9b4cb4ab7bd547e17b5d2690693Sailesh Nepal    void continueProcessingIfPossible(CreateConnectionResponse response,
139752cacbc0b88b9b4cb4ab7bd547e17b5d2690693Sailesh Nepal            DisconnectCause disconnectCause) {
140752cacbc0b88b9b4cb4ab7bd547e17b5d2690693Sailesh Nepal        Log.v(this, "continueProcessingIfPossible");
141752cacbc0b88b9b4cb4ab7bd547e17b5d2690693Sailesh Nepal        mResponse = response;
142752cacbc0b88b9b4cb4ab7bd547e17b5d2690693Sailesh Nepal        mLastErrorDisconnectCause = disconnectCause;
143752cacbc0b88b9b4cb4ab7bd547e17b5d2690693Sailesh Nepal        attemptNextPhoneAccount();
144752cacbc0b88b9b4cb4ab7bd547e17b5d2690693Sailesh Nepal    }
145752cacbc0b88b9b4cb4ab7bd547e17b5d2690693Sailesh Nepal
146664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    void abort() {
147664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        Log.v(this, "abort");
148664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
149664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        // Clear the response first to prevent attemptNextConnectionService from attempting any
150664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        // more services.
151664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        CreateConnectionResponse response = mResponse;
152664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        mResponse = null;
153646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal        clearTimeout();
154664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
155664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        ConnectionServiceWrapper service = mCall.getConnectionService();
156664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        if (service != null) {
157664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            service.abort(mCall);
158664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            mCall.clearConnectionService();
159664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        }
160664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        if (response != null) {
161701dc006ac11625b55d872f1639107b028933895Andrew Lee            response.handleCreateConnectionFailure(new DisconnectCause(DisconnectCause.LOCAL));
162664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        }
163664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    }
164664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
16569eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad    private void attemptNextPhoneAccount() {
16669eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad        Log.v(this, "attemptNextPhoneAccount");
167cb59b679e98d346c9725697ce08b05dd4c2f0a69Tyler Gunn        CallAttemptRecord attempt = null;
168cb59b679e98d346c9725697ce08b05dd4c2f0a69Tyler Gunn        if (mAttemptRecordIterator.hasNext()) {
169cb59b679e98d346c9725697ce08b05dd4c2f0a69Tyler Gunn            attempt = mAttemptRecordIterator.next();
170664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
17191d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn            if (!mPhoneAccountRegistrar.phoneAccountHasPermission(
17291d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn                    attempt.connectionManagerPhoneAccount)) {
173cb59b679e98d346c9725697ce08b05dd4c2f0a69Tyler Gunn                Log.w(this,
174cb59b679e98d346c9725697ce08b05dd4c2f0a69Tyler Gunn                        "Connection mgr does not have BIND_CONNECTION_SERVICE for attempt: %s",
175cb59b679e98d346c9725697ce08b05dd4c2f0a69Tyler Gunn                        attempt);
176cb59b679e98d346c9725697ce08b05dd4c2f0a69Tyler Gunn                attemptNextPhoneAccount();
177cb59b679e98d346c9725697ce08b05dd4c2f0a69Tyler Gunn                return;
178cb59b679e98d346c9725697ce08b05dd4c2f0a69Tyler Gunn            }
179cb59b679e98d346c9725697ce08b05dd4c2f0a69Tyler Gunn
180cb59b679e98d346c9725697ce08b05dd4c2f0a69Tyler Gunn            // If the target PhoneAccount differs from the ConnectionManager phone acount, ensure it
181cb59b679e98d346c9725697ce08b05dd4c2f0a69Tyler Gunn            // also has BIND_CONNECTION_SERVICE permission.
182cb59b679e98d346c9725697ce08b05dd4c2f0a69Tyler Gunn            if (!attempt.connectionManagerPhoneAccount.equals(attempt.targetPhoneAccount) &&
18391d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn                    !mPhoneAccountRegistrar.phoneAccountHasPermission(attempt.targetPhoneAccount)) {
184cb59b679e98d346c9725697ce08b05dd4c2f0a69Tyler Gunn                Log.w(this,
185cb59b679e98d346c9725697ce08b05dd4c2f0a69Tyler Gunn                        "Target PhoneAccount does not have BIND_CONNECTION_SERVICE for attempt: %s",
186cb59b679e98d346c9725697ce08b05dd4c2f0a69Tyler Gunn                        attempt);
187cb59b679e98d346c9725697ce08b05dd4c2f0a69Tyler Gunn                attemptNextPhoneAccount();
188cb59b679e98d346c9725697ce08b05dd4c2f0a69Tyler Gunn                return;
189cb59b679e98d346c9725697ce08b05dd4c2f0a69Tyler Gunn            }
190cb59b679e98d346c9725697ce08b05dd4c2f0a69Tyler Gunn        }
191cb59b679e98d346c9725697ce08b05dd4c2f0a69Tyler Gunn
192cb59b679e98d346c9725697ce08b05dd4c2f0a69Tyler Gunn        if (mResponse != null && attempt != null) {
193293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad            Log.i(this, "Trying attempt %s", attempt);
194105d977687d1d0de7cd9420fc140b01404261df1Evan Charlton            PhoneAccountHandle phoneAccount = attempt.connectionManagerPhoneAccount;
19594d01629010a61f6112713f22330d5fd4baae851Evan Charlton            ConnectionServiceWrapper service =
196b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                    mRepository.getService(
197105d977687d1d0de7cd9420fc140b01404261df1Evan Charlton                            phoneAccount.getComponentName(),
198105d977687d1d0de7cd9420fc140b01404261df1Evan Charlton                            phoneAccount.getUserHandle());
199664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            if (service == null) {
200293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad                Log.i(this, "Found no connection service for attempt %s", attempt);
20169eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad                attemptNextPhoneAccount();
202664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            } else {
203b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                mCall.setConnectionManagerPhoneAccount(attempt.connectionManagerPhoneAccount);
204b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                mCall.setTargetPhoneAccount(attempt.targetPhoneAccount);
205664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal                mCall.setConnectionService(service);
206646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal                setTimeoutIfNeeded(service, attempt);
207646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal
208664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal                Log.i(this, "Attempting to call from %s", service.getComponentName());
209664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal                service.createConnection(mCall, new Response(service));
210664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            }
211664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        } else {
21269eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad            Log.v(this, "attemptNextPhoneAccount, no more accounts, failing");
213664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            if (mResponse != null) {
214646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal                clearTimeout();
215f211ce79c1034315d454289ed233c11dd3aa4d0fJay Shrauner                mResponse.handleCreateConnectionFailure(mLastErrorDisconnectCause != null ?
216f211ce79c1034315d454289ed233c11dd3aa4d0fJay Shrauner                        mLastErrorDisconnectCause : new DisconnectCause(DisconnectCause.ERROR));
217664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal                mResponse = null;
218664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal                mCall.clearConnectionService();
219664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            }
220664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        }
221664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    }
222664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
223646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal    private void setTimeoutIfNeeded(ConnectionServiceWrapper service, CallAttemptRecord attempt) {
224646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal        clearTimeout();
225646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal
226646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal        CreateConnectionTimeout timeout = new CreateConnectionTimeout(
227646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal                mContext, mPhoneAccountRegistrar, service, mCall);
228646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal        if (timeout.isTimeoutNeededForCall(getConnectionServices(mAttemptRecords),
229646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal                attempt.connectionManagerPhoneAccount)) {
230646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal            mTimeout = timeout;
231646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal            timeout.registerTimeout();
232646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal        }
233646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal    }
234646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal
235646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal    private void clearTimeout() {
236646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal        if (mTimeout != null) {
237646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal            mTimeout.unregisterTimeout();
238646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal            mTimeout = null;
239646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal        }
240646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal    }
241646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal
2427957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal    private boolean shouldSetConnectionManager() {
243bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal        if (!mShouldUseConnectionManager) {
244bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal            return false;
245bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal        }
246bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal
2477957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        if (mAttemptRecords.size() == 0) {
2487957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal            return false;
249293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad        }
2507957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal
2517957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        if (mAttemptRecords.size() > 1) {
2527957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal            Log.d(this, "shouldSetConnectionManager, error, mAttemptRecords should not have more "
2537957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal                    + "than 1 record");
2547957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal            return false;
2557957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        }
2567957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal
25791d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn        PhoneAccountHandle connectionManager = mPhoneAccountRegistrar.getSimCallManager();
2587957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        if (connectionManager == null) {
2597957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal            return false;
2607957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        }
2617957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal
2627957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        PhoneAccountHandle targetPhoneAccountHandle = mAttemptRecords.get(0).targetPhoneAccount;
2637957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        if (Objects.equals(connectionManager, targetPhoneAccountHandle)) {
2647957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal            return false;
2657957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        }
2667957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal
2677957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        // Connection managers are only allowed to manage SIM subscriptions.
26891d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn        PhoneAccount targetPhoneAccount = mPhoneAccountRegistrar.getPhoneAccount(
26991d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn                targetPhoneAccountHandle);
2707957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        boolean isSimSubscription = (targetPhoneAccount.getCapabilities() &
2717957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal                PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) != 0;
2727957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        if (!isSimSubscription) {
2737957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal            return false;
2747957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        }
2757957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal
2767957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        return true;
2777957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal    }
2787957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal
2797957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal    // If there exists a registered connection manager then use it.
2807957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal    private void adjustAttemptsForConnectionManager() {
2817957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        if (shouldSetConnectionManager()) {
2827957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal            CallAttemptRecord record = new CallAttemptRecord(
28391d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn                    mPhoneAccountRegistrar.getSimCallManager(),
2847957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal                    mAttemptRecords.get(0).targetPhoneAccount);
28510a5831cf61b3ab3b126329044ea05dc3181fa63mike dooley            Log.v(this, "setConnectionManager, changing %s -> %s", mAttemptRecords.get(0), record);
2867957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal            mAttemptRecords.set(0, record);
2877957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal        } else {
2887957f9ca486703ba1c2d5f63a8537d65ac3f1f94Sailesh Nepal            Log.v(this, "setConnectionManager, not changing");
289293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad        }
290293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad    }
291293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad
292664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    // If we are possibly attempting to call a local emergency number, ensure that the
29369eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad    // plain PSTN connection services are listed, and nothing else.
294293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad    private void adjustAttemptsForEmergency()  {
29591d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn        if (TelephonyUtil.shouldProcessAsEmergency(mContext, mCall.getHandle())) {
29669eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad            Log.i(this, "Emergency number detected");
297293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad            mAttemptRecords.clear();
29891d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn            List<PhoneAccount> allAccounts = mPhoneAccountRegistrar.getAllPhoneAccounts();
299c127211ffd269bffc8a393a3c5ebfe7bdd99896bYorke Lee
300c127211ffd269bffc8a393a3c5ebfe7bdd99896bYorke Lee            if (allAccounts.isEmpty()) {
301c127211ffd269bffc8a393a3c5ebfe7bdd99896bYorke Lee                // If the list of phone accounts is empty at this point, it means Telephony hasn't
302c127211ffd269bffc8a393a3c5ebfe7bdd99896bYorke Lee                // registered any phone accounts yet. Add a fallback emergency phone account so
303c127211ffd269bffc8a393a3c5ebfe7bdd99896bYorke Lee                // that emergency calls can still go through. We create a new ArrayLists here just
304c127211ffd269bffc8a393a3c5ebfe7bdd99896bYorke Lee                // in case the implementation of PhoneAccountRegistrar ever returns an unmodifiable
305c127211ffd269bffc8a393a3c5ebfe7bdd99896bYorke Lee                // list.
306c127211ffd269bffc8a393a3c5ebfe7bdd99896bYorke Lee                allAccounts = new ArrayList<PhoneAccount>();
307c127211ffd269bffc8a393a3c5ebfe7bdd99896bYorke Lee                allAccounts.add(TelephonyUtil.getDefaultEmergencyPhoneAccount());
308c127211ffd269bffc8a393a3c5ebfe7bdd99896bYorke Lee            }
309c127211ffd269bffc8a393a3c5ebfe7bdd99896bYorke Lee
310c127211ffd269bffc8a393a3c5ebfe7bdd99896bYorke Lee
3118e0fef4e1fd09116e4df4ba2ecc18f06cebe71c2Tyler Gunn            // First, add SIM phone accounts which can place emergency calls.
3128e0fef4e1fd09116e4df4ba2ecc18f06cebe71c2Tyler Gunn            for (PhoneAccount phoneAccount : allAccounts) {
3138e0fef4e1fd09116e4df4ba2ecc18f06cebe71c2Tyler Gunn                if (phoneAccount.hasCapabilities(PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS) &&
3148e0fef4e1fd09116e4df4ba2ecc18f06cebe71c2Tyler Gunn                        phoneAccount.hasCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)) {
3158e0fef4e1fd09116e4df4ba2ecc18f06cebe71c2Tyler Gunn                    Log.i(this, "Will try PSTN account %s for emergency",
3168e0fef4e1fd09116e4df4ba2ecc18f06cebe71c2Tyler Gunn                            phoneAccount.getAccountHandle());
317293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad                    mAttemptRecords.add(
318293edf245f3e37691073c8bf4a1fc271ecbc5370Ihab Awad                            new CallAttemptRecord(
3198e0fef4e1fd09116e4df4ba2ecc18f06cebe71c2Tyler Gunn                                    phoneAccount.getAccountHandle(),
3208e0fef4e1fd09116e4df4ba2ecc18f06cebe71c2Tyler Gunn                                    phoneAccount.getAccountHandle()));
321664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal                }
322664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            }
3236e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn
3248e0fef4e1fd09116e4df4ba2ecc18f06cebe71c2Tyler Gunn            // Next, add the connection manager account as a backup if it can place emergency calls.
32591d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn            PhoneAccountHandle callManagerHandle = mPhoneAccountRegistrar.getSimCallManager();
326646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal            if (mShouldUseConnectionManager && callManagerHandle != null) {
32791d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn                PhoneAccount callManager = mPhoneAccountRegistrar
32891d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn                        .getPhoneAccount(callManagerHandle);
3298e0fef4e1fd09116e4df4ba2ecc18f06cebe71c2Tyler Gunn                if (callManager.hasCapabilities(PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS)) {
3308e0fef4e1fd09116e4df4ba2ecc18f06cebe71c2Tyler Gunn                    CallAttemptRecord callAttemptRecord = new CallAttemptRecord(callManagerHandle,
33191d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn                            mPhoneAccountRegistrar.
3328e0fef4e1fd09116e4df4ba2ecc18f06cebe71c2Tyler Gunn                                    getDefaultOutgoingPhoneAccount(mCall.getHandle().getScheme())
3338e0fef4e1fd09116e4df4ba2ecc18f06cebe71c2Tyler Gunn                    );
3348e0fef4e1fd09116e4df4ba2ecc18f06cebe71c2Tyler Gunn
3358e0fef4e1fd09116e4df4ba2ecc18f06cebe71c2Tyler Gunn                    if (!mAttemptRecords.contains(callAttemptRecord)) {
3368e0fef4e1fd09116e4df4ba2ecc18f06cebe71c2Tyler Gunn                        Log.i(this, "Will try Connection Manager account %s for emergency",
3378e0fef4e1fd09116e4df4ba2ecc18f06cebe71c2Tyler Gunn                                callManager);
3388e0fef4e1fd09116e4df4ba2ecc18f06cebe71c2Tyler Gunn                        mAttemptRecords.add(callAttemptRecord);
3398e0fef4e1fd09116e4df4ba2ecc18f06cebe71c2Tyler Gunn                    }
3408e0fef4e1fd09116e4df4ba2ecc18f06cebe71c2Tyler Gunn                }
3416e6f6d1f7b7e5b5b506c198e6719c9c68e205042Tyler Gunn            }
342664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        }
343664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    }
344664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
345646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal    /** Returns all connection services used by the call attempt records. */
346646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal    private static Collection<PhoneAccountHandle> getConnectionServices(
347646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal            List<CallAttemptRecord> records) {
348646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal        HashSet<PhoneAccountHandle> result = new HashSet<>();
349646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal        for (CallAttemptRecord record : records) {
350646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal            result.add(record.connectionManagerPhoneAccount);
351646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal        }
352646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal        return result;
353646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal    }
354646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal
355664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    private class Response implements CreateConnectionResponse {
356664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        private final ConnectionServiceWrapper mService;
357664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
358664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        Response(ConnectionServiceWrapper service) {
359664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            mService = service;
360664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        }
361664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
362664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        @Override
3638000845a81fd6a88ff69cb11e1b6dff5f47c2332Ihab Awad        public void handleCreateConnectionSuccess(
3648000845a81fd6a88ff69cb11e1b6dff5f47c2332Ihab Awad                CallIdMapper idMapper,
3658000845a81fd6a88ff69cb11e1b6dff5f47c2332Ihab Awad                ParcelableConnection connection) {
366664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            if (mResponse == null) {
367fb5560d634aef745466e8869f8acf496447da17bIhab Awad                // Nobody is listening for this connection attempt any longer; ask the responsible
368fb5560d634aef745466e8869f8acf496447da17bIhab Awad                // ConnectionService to tear down any resources associated with the call
369664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal                mService.abort(mCall);
370664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            } else {
371fb5560d634aef745466e8869f8acf496447da17bIhab Awad                // Success -- share the good news and remember that we are no longer interested
372fb5560d634aef745466e8869f8acf496447da17bIhab Awad                // in hearing about any more attempts
3738000845a81fd6a88ff69cb11e1b6dff5f47c2332Ihab Awad                mResponse.handleCreateConnectionSuccess(idMapper, connection);
37472890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon                mResponse = null;
375646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal                // If there's a timeout running then don't clear it. The timeout can be triggered
376646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal                // after the call has successfully been created but before it has become active.
377664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            }
378664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        }
379664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
380bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal        private boolean shouldFallbackToNoConnectionManager(DisconnectCause cause) {
381bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal            PhoneAccountHandle handle = mCall.getConnectionManagerPhoneAccount();
382bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal            if (handle == null || !handle.equals(mPhoneAccountRegistrar.getSimCallManager())) {
383bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal                return false;
384bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal            }
385bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal
386bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal            ConnectionServiceWrapper connectionManager = mCall.getConnectionService();
387bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal            if (connectionManager == null) {
388bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal                return false;
389bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal            }
390bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal
391bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal            if (cause.getCode() == DisconnectCause.CONNECTION_MANAGER_NOT_SUPPORTED) {
392bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal                Log.d(CreateConnectionProcessor.this, "Connection manager declined to handle the "
393bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal                        + "call, falling back to not using a connection manager");
394bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal                return true;
395bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal            }
396bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal
397bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal            if (!connectionManager.isServiceValid("createConnection")) {
398bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal                Log.d(CreateConnectionProcessor.this, "Connection manager unbound while trying "
399bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal                        + "create a connection, falling back to not using a connection manager");
400bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal                return true;
401bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal            }
402bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal
403bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal            return false;
404bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal        }
405bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal
406664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        @Override
407701dc006ac11625b55d872f1639107b028933895Andrew Lee        public void handleCreateConnectionFailure(DisconnectCause errorDisconnectCause) {
408fb5560d634aef745466e8869f8acf496447da17bIhab Awad            // Failure of some sort; record the reasons for failure and try again if possible
409701dc006ac11625b55d872f1639107b028933895Andrew Lee            Log.d(CreateConnectionProcessor.this, "Connection failed: (%s)", errorDisconnectCause);
410701dc006ac11625b55d872f1639107b028933895Andrew Lee            mLastErrorDisconnectCause = errorDisconnectCause;
411bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal            if (shouldFallbackToNoConnectionManager(errorDisconnectCause)) {
412bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal                mShouldUseConnectionManager = false;
413bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal                // Restart from the beginning.
414bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal                process();
415bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal            } else {
416bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal                attemptNextPhoneAccount();
417bafadce53332c7e0f7be0482cf04333c72487a70Sailesh Nepal            }
418664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        }
419664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    }
420664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal}
421