CreateConnectionProcessor.java revision 69eb0f582babcedc1dc5e6613a27867be6e8d0e0
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
1969eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awadimport android.telecomm.PhoneAccount;
20664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepalimport android.telephony.DisconnectCause;
21664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepalimport android.telecomm.ConnectionRequest;
22664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
23664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepalimport java.util.ArrayList;
24664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepalimport java.util.Iterator;
25664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepalimport java.util.List;
26664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
27664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal/**
28664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal * This class creates connections to place new outgoing calls to attached to an existing incoming
29664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal * call. In either case, this class cycles through a set of connection services until:
30664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal *   - a connection service returns a newly created connection in which case the call is displayed
31664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal *     to the user
32664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal *   - a connection service cancels the process, in which case the call is aborted
33664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal */
34664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepalfinal class CreateConnectionProcessor {
35664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    private final Call mCall;
36664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    private final ConnectionServiceRepository mRepository;
3769eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad    private List<PhoneAccount> mPhoneAccounts;
3869eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad    private Iterator<PhoneAccount> mPhoneAccountIterator;
39664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    private CreateConnectionResponse mResponse;
40664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    private int mLastErrorCode = DisconnectCause.ERROR_UNSPECIFIED;
41664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    private String mLastErrorMsg;
42664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
43664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    CreateConnectionProcessor(
44664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            Call call, ConnectionServiceRepository repository, CreateConnectionResponse response) {
45664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        mCall = call;
46664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        mRepository = repository;
47664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        mResponse = response;
48664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    }
49664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
50664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    void process() {
51664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        Log.v(this, "process");
5269eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad        mPhoneAccounts = new ArrayList<>();
5369eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad        if (mCall.getPhoneAccount() != null) {
5469eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad            mPhoneAccounts.add(mCall.getPhoneAccount());
55664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        }
5669eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad        adjustPhoneAccountsForEmergency();
5769eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad        mPhoneAccountIterator = mPhoneAccounts.iterator();
5869eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad        attemptNextPhoneAccount();
59664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    }
60664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
61664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    void abort() {
62664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        Log.v(this, "abort");
63664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
64664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        // Clear the response first to prevent attemptNextConnectionService from attempting any
65664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        // more services.
66664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        CreateConnectionResponse response = mResponse;
67664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        mResponse = null;
68664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
69664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        ConnectionServiceWrapper service = mCall.getConnectionService();
70664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        if (service != null) {
71664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            service.abort(mCall);
72664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            mCall.clearConnectionService();
73664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        }
74664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        if (response != null) {
75664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            response.handleCreateConnectionCancelled();
76664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        }
77664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    }
78664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
7969eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad    private void attemptNextPhoneAccount() {
8069eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad        Log.v(this, "attemptNextPhoneAccount");
81664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
8269eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad        if (mResponse != null && mPhoneAccountIterator.hasNext()) {
8369eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad            PhoneAccount account = mPhoneAccountIterator.next();
8469eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad            Log.i(this, "Trying account %s", account);
8569eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad            ConnectionServiceWrapper service = mRepository.getService(account.getComponentName());
86664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            if (service == null) {
8769eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad                Log.i(this, "Found no connection service for account %s", account);
8869eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad                attemptNextPhoneAccount();
89664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            } else {
9069eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad                mCall.setPhoneAccount(account);
91664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal                mCall.setConnectionService(service);
92664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal                Log.i(this, "Attempting to call from %s", service.getComponentName());
93664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal                service.createConnection(mCall, new Response(service));
94664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            }
95664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        } else {
9669eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad            Log.v(this, "attemptNextPhoneAccount, no more accounts, failing");
97664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            if (mResponse != null) {
98664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal                mResponse.handleCreateConnectionFailed(mLastErrorCode, mLastErrorMsg);
99664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal                mResponse = null;
100664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal                mCall.clearConnectionService();
101664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            }
102664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        }
103664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    }
104664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
105664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    // If we are possibly attempting to call a local emergency number, ensure that the
10669eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad    // plain PSTN connection services are listed, and nothing else.
10769eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad    private void adjustPhoneAccountsForEmergency()  {
10869eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad        if (TelephonyUtil.shouldProcessAsEmergency(TelecommApp.getInstance(), mCall.getHandle())) {
10969eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad            Log.i(this, "Emergency number detected");
11069eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad            mPhoneAccounts.clear();
11169eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad            List<PhoneAccount> allAccounts = TelecommApp.getInstance().getPhoneAccountRegistrar()
11269eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad                    .getEnabledPhoneAccounts();
11369eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad            for (int i = 0; i < allAccounts.size(); i++) {
11469eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad                if (TelephonyUtil.isPstnComponentName(allAccounts.get(i).getComponentName())) {
11569eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad                    Log.i(this, "Will try PSTN account %s for emergency", allAccounts.get(i));
11669eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad                    mPhoneAccounts.add(allAccounts.get(i));
117664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal                }
118664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            }
119664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        }
120664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    }
121664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
122664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    private class Response implements CreateConnectionResponse {
123664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        private final ConnectionServiceWrapper mService;
124664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
125664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        Response(ConnectionServiceWrapper service) {
126664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            mService = service;
127664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        }
128664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
129664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        @Override
130664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        public void handleCreateConnectionSuccessful(ConnectionRequest request) {
131664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            if (mResponse == null) {
132664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal                mService.abort(mCall);
133664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            } else {
134664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal                mResponse.handleCreateConnectionSuccessful(request);
135664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal                mResponse= null;
136664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            }
137664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        }
138664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
139664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        @Override
140664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        public void handleCreateConnectionFailed(int code, String msg) {
141664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            mLastErrorCode = code;
142664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            mLastErrorMsg = msg;
14369eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad            Log.d(CreateConnectionProcessor.this, "Connection failed: %d (%s)", code, msg);
14469eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad            attemptNextPhoneAccount();
145664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        }
146664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
147664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        @Override
148664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        public void handleCreateConnectionCancelled() {
149664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            if (mResponse != null) {
150664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal                mResponse.handleCreateConnectionCancelled();
151664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal                mResponse = null;
152664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            }
153664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        }
154664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    }
155664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal}
156