CallButtonPresenter.java revision 3c2a439eb67ec6fb89daf1914ab3ce05e8aaa428
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.media.AudioManager;
20
21import com.android.incallui.AudioModeProvider.AudioModeListener;
22import com.android.incallui.InCallPresenter.InCallState;
23import com.android.incallui.InCallPresenter.InCallStateListener;
24import com.android.services.telephony.common.AudioMode;
25import com.android.services.telephony.common.Call;
26import com.android.services.telephony.common.Call.Capabilities;
27
28/**
29 * Logic for call buttons.
30 */
31public class CallButtonPresenter extends Presenter<CallButtonPresenter.CallButtonUi>
32        implements InCallStateListener, AudioModeListener {
33
34    private Call mCall;
35    private AudioModeProvider mAudioModeProvider;
36    private ProximitySensor mProximitySensor;
37
38    public CallButtonPresenter() {
39    }
40
41    @Override
42    public void onUiReady(CallButtonUi ui) {
43        super.onUiReady(ui);
44        if (mAudioModeProvider != null) {
45            mAudioModeProvider.addListener(this);
46        }
47    }
48
49    @Override
50    public void onUiUnready(CallButtonUi ui) {
51        if (mAudioModeProvider != null) {
52            mAudioModeProvider.removeListener(this);
53        }
54    }
55
56    @Override
57    public void onStateChange(InCallState state, CallList callList) {
58        if (state == InCallState.OUTGOING) {
59            mCall = callList.getOutgoingCall();
60        } else if (state == InCallState.INCALL) {
61            mCall = callList.getActiveOrBackgroundCall();
62        } else {
63            mCall = null;
64        }
65
66        updateUi(state, mCall);
67    }
68
69    @Override
70    public void onAudioMode(int mode) {
71        getUi().setAudio(mode);
72    }
73
74    @Override
75    public void onSupportedAudioMode(int mask) {
76        getUi().setSupportedAudio(mask);
77    }
78
79    public int getAudioMode() {
80        if (mAudioModeProvider != null) {
81            return mAudioModeProvider.getAudioMode();
82        }
83        return AudioMode.EARPIECE;
84    }
85
86    public int getSupportedAudio() {
87        if (mAudioModeProvider != null) {
88            return mAudioModeProvider.getSupportedModes();
89        }
90
91        return 0;
92    }
93
94    public void setAudioMode(int mode) {
95
96        // TODO: Set a intermediate state in this presenter until we get
97        // an update for onAudioMode().  This will make UI response immediate
98        // if it turns out to be slow
99
100        Logger.d(this, "Sending new Audio Mode: " + AudioMode.toString(mode));
101        CallCommandClient.getInstance().setAudioMode(mode);
102    }
103
104    /**
105     * Function assumes that bluetooth is not supported.
106     */
107    public void toggleSpeakerphone() {
108        // this function should not be called if bluetooth is available
109        if (0 != (AudioMode.BLUETOOTH & getSupportedAudio())) {
110
111            // It's clear the UI is wrong, so update the supported mode once again.
112            Logger.e(this, "toggling speakerphone not allowed when bluetooth supported.");
113            getUi().setSupportedAudio(getSupportedAudio());
114            return;
115        }
116
117        int newMode = AudioMode.SPEAKER;
118
119        // if speakerphone is already on, change to wired/earpiece
120        if (getAudioMode() == AudioMode.SPEAKER) {
121            newMode = AudioMode.WIRED_OR_EARPIECE;
122        }
123
124        setAudioMode(newMode);
125    }
126
127    public void endCallClicked() {
128        if (mCall == null) {
129            return;
130        }
131
132        // TODO(klp): hook up call id.
133        CallCommandClient.getInstance().disconnectCall(mCall.getCallId());
134    }
135
136    public void muteClicked(boolean checked) {
137        Logger.d(this, "turning on mute: " + checked);
138
139        CallCommandClient.getInstance().mute(checked);
140        getUi().setMute(checked);
141    }
142
143    public void holdClicked(boolean checked) {
144        if (mCall == null) {
145            return;
146        }
147
148        Logger.d(this, "holding: " + mCall.getCallId());
149
150        // TODO(klp): use appropriate hold callId.
151        CallCommandClient.getInstance().hold(mCall.getCallId(), checked);
152        getUi().setHold(checked);
153    }
154
155    public void mergeClicked() {
156        CallCommandClient.getInstance().merge();
157    }
158
159    public void addCallClicked() {
160        CallCommandClient.getInstance().addCall();
161    }
162
163    public void swapClicked() {
164        CallCommandClient.getInstance().swap();
165    }
166
167    public void showDialpadClicked(boolean checked) {
168        Logger.v(this, "Show dialpad " + String.valueOf(checked));
169        getUi().displayDialpad(checked);
170        mProximitySensor.onDialpadVisible(checked);
171    }
172
173    private void updateUi(InCallState state, Call call) {
174        final CallButtonUi ui = getUi();
175        if (ui == null) {
176            return;
177        }
178
179        final boolean isVisible = state.isConnectingOrConnected() &&
180                !state.isIncoming();
181
182        ui.setVisible(isVisible);
183
184        Logger.d(this, "Updating call UI for call: ", call);
185
186        if (isVisible && call != null) {
187            Logger.v(this, "Show hold ", call.can(Capabilities.HOLD));
188            Logger.v(this, "Show merge ", call.can(Capabilities.MERGE_CALLS));
189            Logger.v(this, "Show swap ", call.can(Capabilities.SWAP_CALLS));
190            Logger.v(this, "Show add call ", call.can(Capabilities.ADD_CALL));
191
192            ui.setHold(call.getState() == Call.State.ONHOLD);
193
194            ui.showHold(call.can(Capabilities.HOLD));
195            ui.showMerge(call.can(Capabilities.MERGE_CALLS));
196            ui.showSwap(call.can(Capabilities.SWAP_CALLS));
197            ui.showAddCall(call.can(Capabilities.ADD_CALL));
198        }
199    }
200
201    public void setAudioModeProvider(AudioModeProvider audioModeProvider) {
202        // AudioModeProvider works effectively as a pass through. However, if we
203        // had this presenter listen for changes directly, it would have to live forever
204        // or risk missing important updates.
205        mAudioModeProvider = audioModeProvider;
206        mAudioModeProvider.addListener(this);
207    }
208
209    public void setProximitySensor(ProximitySensor proximitySensor) {
210        mProximitySensor = proximitySensor;
211    }
212
213    public interface CallButtonUi extends Ui {
214        void setVisible(boolean on);
215        void setMute(boolean on);
216        void setHold(boolean on);
217        void showHold(boolean show);
218        void showMerge(boolean show);
219        void showSwap(boolean show);
220        void showAddCall(boolean show);
221        void displayDialpad(boolean on);
222        void setAudio(int mode);
223        void setSupportedAudio(int mask);
224    }
225}
226