AnswerPresenter.java revision 12947a3d7ca33792fabf594b413c1e9a4b8235bf
1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.incallui;
18
19import android.telecomm.CallCapabilities;
20
21import java.util.List;
22
23/**
24 * Presenter for the Incoming call widget.
25 */
26public class AnswerPresenter extends Presenter<AnswerPresenter.AnswerUi>
27        implements CallList.CallUpdateListener, CallList.Listener {
28
29    private static final String TAG = AnswerPresenter.class.getSimpleName();
30
31    private String mCallId;
32    private Call mCall = null;
33
34    @Override
35    public void onUiReady(AnswerUi ui) {
36        super.onUiReady(ui);
37
38        final CallList calls = CallList.getInstance();
39        final Call call = calls.getIncomingCall();
40        // TODO: change so that answer presenter never starts up if it's not incoming.
41        if (call != null) {
42            processIncomingCall(call);
43        }
44
45        // Listen for incoming calls.
46        calls.addListener(this);
47    }
48
49    @Override
50    public void onUiUnready(AnswerUi ui) {
51        super.onUiUnready(ui);
52
53        CallList.getInstance().removeListener(this);
54
55        // This is necessary because the activity can be destroyed while an incoming call exists.
56        // This happens when back button is pressed while incoming call is still being shown.
57        if (mCallId != null) {
58            CallList.getInstance().removeCallUpdateListener(mCallId, this);
59        }
60    }
61
62    @Override
63    public void onCallListChange(CallList callList) {
64        // no-op
65    }
66
67    @Override
68    public void onDisconnect(Call call) {
69        // no-op
70    }
71
72    @Override
73    public void onIncomingCall(Call call) {
74        // TODO: Ui is being destroyed when the fragment detaches.  Need clean up step to stop
75        // getting updates here.
76        Log.d(this, "onIncomingCall: " + this);
77        if (getUi() != null) {
78            if (!call.getId().equals(mCallId)) {
79                // A new call is coming in.
80                processIncomingCall(call);
81            }
82        }
83    }
84
85    private void processIncomingCall(Call call) {
86        mCallId = call.getId();
87        mCall = call;
88
89        // Listen for call updates for the current call.
90        CallList.getInstance().addCallUpdateListener(mCallId, this);
91
92        Log.d(TAG, "Showing incoming for call id: " + mCallId + " " + this);
93        final List<String> textMsgs = CallList.getInstance().getTextResponses(call.getId());
94        getUi().showAnswerUi(true);
95
96        boolean withSms = call.can(CallCapabilities.RESPOND_VIA_TEXT) && textMsgs != null;
97        if (call.isVideoCall()) {
98            if (withSms) {
99                getUi().showTargets(AnswerFragment.TARGET_SET_FOR_VIDEO_WITH_SMS);
100                getUi().configureMessageDialog(textMsgs);
101            } else {
102                getUi().showTargets(AnswerFragment.TARGET_SET_FOR_VIDEO_WITHOUT_SMS);
103            }
104        } else {
105            if (withSms) {
106                getUi().showTargets(AnswerFragment.TARGET_SET_FOR_AUDIO_WITH_SMS);
107                getUi().configureMessageDialog(textMsgs);
108            } else {
109                getUi().showTargets(AnswerFragment.TARGET_SET_FOR_AUDIO_WITHOUT_SMS);
110            }
111        }
112    }
113
114    @Override
115    public void onCallChanged(Call call) {
116        Log.d(this, "onCallStateChange() " + call + " " + this);
117        if (call.getState() != Call.State.INCOMING && call.getState() != Call.State.CALL_WAITING) {
118            // Stop listening for updates.
119            CallList.getInstance().removeCallUpdateListener(mCallId, this);
120
121            getUi().showAnswerUi(false);
122
123            // mCallId will hold the state of the call. We don't clear the mCall variable here as
124            // it may be useful for sending text messages after phone disconnects.
125            mCallId = null;
126        }
127    }
128
129    public void onAnswer(int videoState) {
130        if (mCallId == null) {
131            return;
132        }
133
134        Log.d(this, "onAnswer " + mCallId);
135        TelecommAdapter.getInstance().answerCall(mCall.getId(), videoState);
136    }
137
138    /**
139     * TODO: We are using reject and decline interchangeably. We should settle on
140     * reject since it seems to be more prevalent.
141     */
142    public void onDecline() {
143        Log.d(this, "onDecline " + mCallId);
144        TelecommAdapter.getInstance().rejectCall(mCall.getId(), false, null);
145    }
146
147    public void onText() {
148        if (getUi() != null) {
149            getUi().showMessageDialog();
150        }
151    }
152
153    public void rejectCallWithMessage(String message) {
154        Log.d(this, "sendTextToDefaultActivity()...");
155        TelecommAdapter.getInstance().rejectCall(mCall.getId(), true, message);
156
157        onDismissDialog();
158    }
159
160    public void onDismissDialog() {
161        InCallPresenter.getInstance().onDismissDialog();
162    }
163
164    interface AnswerUi extends Ui {
165        public void showAnswerUi(boolean show);
166        public void showTargets(int targetSet);
167        public void showMessageDialog();
168        public void configureMessageDialog(List<String> textResponses);
169    }
170}
171