CallButtonPresenter.java revision 55e998472730cae27a82eed49cf7b020699b9286
1241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng/*
2241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng * Copyright (C) 2013 The Android Open Source Project
3241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng *
4241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng * Licensed under the Apache License, Version 2.0 (the "License");
5241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng * you may not use this file except in compliance with the License.
6241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng * You may obtain a copy of the License at
7241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng *
8241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng *      http://www.apache.org/licenses/LICENSE-2.0
9241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng *
10241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng * Unless required by applicable law or agreed to in writing, software
11241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng * distributed under the License is distributed on an "AS IS" BASIS,
12241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng * See the License for the specific language governing permissions and
14241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng * limitations under the License
15241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng */
16241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng
17241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Chengpackage com.android.incallui;
18241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng
1955e998472730cae27a82eed49cf7b020699b9286Christine Chenimport com.android.contacts.common.util.PhoneNumberHelper;
2055e998472730cae27a82eed49cf7b020699b9286Christine Chenimport com.android.contacts.common.util.TelephonyManagerUtils;
21dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordonimport com.android.incallui.AudioModeProvider.AudioModeListener;
22671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordonimport com.android.incallui.InCallPresenter.InCallState;
23671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordonimport com.android.incallui.InCallPresenter.InCallStateListener;
24c155f799fc0d4a2c9577f1e0688a3f1f5b436aefChristine Chenimport com.android.incallui.InCallPresenter.IncomingCallListener;
25dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordonimport com.android.services.telephony.common.AudioMode;
26671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordonimport com.android.services.telephony.common.Call;
27bc168c4fb0638846c5076a5a35a2e75ee4947908Santos Cordonimport com.android.services.telephony.common.Call.Capabilities;
28671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon
2955e998472730cae27a82eed49cf7b020699b9286Christine Chenimport android.app.Fragment;
302ce872d6f7dd8a7eb0275b4195336f779972f698Makoto Onuki
31241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng/**
32241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng * Logic for call buttons.
33241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng */
34150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordonpublic class CallButtonPresenter extends Presenter<CallButtonPresenter.CallButtonUi>
35c155f799fc0d4a2c9577f1e0688a3f1f5b436aefChristine Chen        implements InCallStateListener, AudioModeListener, IncomingCallListener {
36241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng
37671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon    private Call mCall;
38e08284ea58e98666e6f1b45734d9901de91c2bb4Yorke Lee    private boolean mAutomaticallyMuted = false;
39e08284ea58e98666e6f1b45734d9901de91c2bb4Yorke Lee    private boolean mPreviousMuteState = false;
40241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng
4146c57f18a63d5923b0b93f1988a56bb4beb9cc5dChristine Chen    private boolean mShowGenericMerge = false;
4246c57f18a63d5923b0b93f1988a56bb4beb9cc5dChristine Chen    private boolean mShowManageConference = false;
4346c57f18a63d5923b0b93f1988a56bb4beb9cc5dChristine Chen
442ce872d6f7dd8a7eb0275b4195336f779972f698Makoto Onuki    private InCallState mPreviousState = null;
452ce872d6f7dd8a7eb0275b4195336f779972f698Makoto Onuki
469de3d7c5188c02cabf03799f87d494ee7dc702cbSantos Cordon    public CallButtonPresenter() {
47241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng    }
48241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng
49241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng    @Override
50241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng    public void onUiReady(CallButtonUi ui) {
51241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng        super.onUiReady(ui);
528b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng
53b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon        AudioModeProvider.getInstance().addListener(this);
54b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon
55b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon        // register for call state changes last
56b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon        InCallPresenter.getInstance().addListener(this);
57c155f799fc0d4a2c9577f1e0688a3f1f5b436aefChristine Chen        InCallPresenter.getInstance().addIncomingCallListener(this);
58dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    }
59dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon
60dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    @Override
61dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    public void onUiUnready(CallButtonUi ui) {
6222c678c74fa38e921ea22b09962062fce6148047Christine Chen        super.onUiUnready(ui);
6322c678c74fa38e921ea22b09962062fce6148047Christine Chen
64b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon        InCallPresenter.getInstance().removeListener(this);
65b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon        AudioModeProvider.getInstance().removeListener(this);
66c155f799fc0d4a2c9577f1e0688a3f1f5b436aefChristine Chen        InCallPresenter.getInstance().removeIncomingCallListener(this);
67241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng    }
68241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng
69150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon    @Override
70671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon    public void onStateChange(InCallState state, CallList callList) {
7155e998472730cae27a82eed49cf7b020699b9286Christine Chen        CallButtonUi ui = getUi();
729be240faad1857e122614a70fd6e632b143ddc41Christine Chen
73e7be13fb0556e62b07bc271b130412d82d7f7521Santos Cordon        if (state == InCallState.OUTGOING) {
74e7be13fb0556e62b07bc271b130412d82d7f7521Santos Cordon            mCall = callList.getOutgoingCall();
75e7be13fb0556e62b07bc271b130412d82d7f7521Santos Cordon        } else if (state == InCallState.INCALL) {
76efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon            mCall = callList.getActiveOrBackgroundCall();
772ce872d6f7dd8a7eb0275b4195336f779972f698Makoto Onuki
782ce872d6f7dd8a7eb0275b4195336f779972f698Makoto Onuki            // When connected to voice mail, automatically shows the dialpad.
792ce872d6f7dd8a7eb0275b4195336f779972f698Makoto Onuki            // (On previous releases we showed it when in-call shows up, before waiting for
802ce872d6f7dd8a7eb0275b4195336f779972f698Makoto Onuki            // OUTGOING.  We may want to do that once we start showing "Voice mail" label on
812ce872d6f7dd8a7eb0275b4195336f779972f698Makoto Onuki            // the dialpad too.)
8255e998472730cae27a82eed49cf7b020699b9286Christine Chen            if (ui != null) {
8355e998472730cae27a82eed49cf7b020699b9286Christine Chen                final Fragment callButtonFragment = (Fragment) ui;
8455e998472730cae27a82eed49cf7b020699b9286Christine Chen                if (mPreviousState == InCallState.OUTGOING && mCall != null
8555e998472730cae27a82eed49cf7b020699b9286Christine Chen                        && TelephonyManagerUtils.isVoiceMailNumber(mCall.getNumber(),
8655e998472730cae27a82eed49cf7b020699b9286Christine Chen                                callButtonFragment.getActivity())) {
8755e998472730cae27a82eed49cf7b020699b9286Christine Chen                    ui.displayDialpad(true);
8855e998472730cae27a82eed49cf7b020699b9286Christine Chen                }
892ce872d6f7dd8a7eb0275b4195336f779972f698Makoto Onuki            }
90c155f799fc0d4a2c9577f1e0688a3f1f5b436aefChristine Chen        } else if (state == InCallState.INCOMING) {
9155e998472730cae27a82eed49cf7b020699b9286Christine Chen            if (ui != null) {
9255e998472730cae27a82eed49cf7b020699b9286Christine Chen                ui.displayDialpad(false);
9355e998472730cae27a82eed49cf7b020699b9286Christine Chen            }
94c155f799fc0d4a2c9577f1e0688a3f1f5b436aefChristine Chen            mCall = null;
95671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon        } else {
96671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon            mCall = null;
97671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon        }
98bc168c4fb0638846c5076a5a35a2e75ee4947908Santos Cordon        updateUi(state, mCall);
992ce872d6f7dd8a7eb0275b4195336f779972f698Makoto Onuki
1002ce872d6f7dd8a7eb0275b4195336f779972f698Makoto Onuki        mPreviousState = state;
101241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng    }
102241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng
103dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    @Override
104c155f799fc0d4a2c9577f1e0688a3f1f5b436aefChristine Chen    public void onIncomingCall(InCallState state, Call call) {
105c155f799fc0d4a2c9577f1e0688a3f1f5b436aefChristine Chen        onStateChange(state, CallList.getInstance());
106c155f799fc0d4a2c9577f1e0688a3f1f5b436aefChristine Chen    }
107c155f799fc0d4a2c9577f1e0688a3f1f5b436aefChristine Chen
108c155f799fc0d4a2c9577f1e0688a3f1f5b436aefChristine Chen    @Override
109dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    public void onAudioMode(int mode) {
1108b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        if (getUi() != null) {
1118b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            getUi().setAudio(mode);
1128b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        }
113dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    }
114dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon
115dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    @Override
116dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    public void onSupportedAudioMode(int mask) {
1178b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        if (getUi() != null) {
1188b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            getUi().setSupportedAudio(mask);
1198b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        }
120dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    }
121dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon
1223e69e4fe0e6dbce738cc6b3f9a71fc177e9fe1b6Santos Cordon    @Override
1233e69e4fe0e6dbce738cc6b3f9a71fc177e9fe1b6Santos Cordon    public void onMute(boolean muted) {
1243e69e4fe0e6dbce738cc6b3f9a71fc177e9fe1b6Santos Cordon        if (getUi() != null) {
1253e69e4fe0e6dbce738cc6b3f9a71fc177e9fe1b6Santos Cordon            getUi().setMute(muted);
1263e69e4fe0e6dbce738cc6b3f9a71fc177e9fe1b6Santos Cordon        }
1273e69e4fe0e6dbce738cc6b3f9a71fc177e9fe1b6Santos Cordon    }
1283e69e4fe0e6dbce738cc6b3f9a71fc177e9fe1b6Santos Cordon
129dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    public int getAudioMode() {
130b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon        return AudioModeProvider.getInstance().getAudioMode();
131dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    }
132dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon
133dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    public int getSupportedAudio() {
134b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon        return AudioModeProvider.getInstance().getSupportedModes();
135dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    }
136dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon
137dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    public void setAudioMode(int mode) {
138dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon
139dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon        // TODO: Set a intermediate state in this presenter until we get
140dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon        // an update for onAudioMode().  This will make UI response immediate
141dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon        // if it turns out to be slow
142dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon
1431a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng        Log.d(this, "Sending new Audio Mode: " + AudioMode.toString(mode));
144dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon        CallCommandClient.getInstance().setAudioMode(mode);
145dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    }
146dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon
147dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    /**
148dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon     * Function assumes that bluetooth is not supported.
149dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon     */
150dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    public void toggleSpeakerphone() {
151dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon        // this function should not be called if bluetooth is available
1529de3d7c5188c02cabf03799f87d494ee7dc702cbSantos Cordon        if (0 != (AudioMode.BLUETOOTH & getSupportedAudio())) {
153dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon
1549de3d7c5188c02cabf03799f87d494ee7dc702cbSantos Cordon            // It's clear the UI is wrong, so update the supported mode once again.
1551a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng            Log.e(this, "toggling speakerphone not allowed when bluetooth supported.");
1569de3d7c5188c02cabf03799f87d494ee7dc702cbSantos Cordon            getUi().setSupportedAudio(getSupportedAudio());
157dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon            return;
158dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon        }
159dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon
160dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon        int newMode = AudioMode.SPEAKER;
161dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon
162dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon        // if speakerphone is already on, change to wired/earpiece
1639de3d7c5188c02cabf03799f87d494ee7dc702cbSantos Cordon        if (getAudioMode() == AudioMode.SPEAKER) {
164dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon            newMode = AudioMode.WIRED_OR_EARPIECE;
165dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon        }
166dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon
167dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon        setAudioMode(newMode);
168dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    }
169dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon
170b94803e83573734d21a32047b21f348cb2305155Chiao Cheng    public void endCallClicked() {
171e286f91abd12dee037de19c3836d8002e450a9c9Santos Cordon        if (mCall == null) {
172e286f91abd12dee037de19c3836d8002e450a9c9Santos Cordon            return;
173e286f91abd12dee037de19c3836d8002e450a9c9Santos Cordon        }
174671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon
175671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon        CallCommandClient.getInstance().disconnectCall(mCall.getCallId());
176b94803e83573734d21a32047b21f348cb2305155Chiao Cheng    }
177b94803e83573734d21a32047b21f348cb2305155Chiao Cheng
1780f09a02be361d5bb36fac6981649204f5d6987faChristine Chen    public void manageConferenceButtonClicked() {
1790f09a02be361d5bb36fac6981649204f5d6987faChristine Chen        getUi().displayManageConferencePanel(true);
1800f09a02be361d5bb36fac6981649204f5d6987faChristine Chen    }
1810f09a02be361d5bb36fac6981649204f5d6987faChristine Chen
182241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng    public void muteClicked(boolean checked) {
1831a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng        Log.d(this, "turning on mute: " + checked);
1849be240faad1857e122614a70fd6e632b143ddc41Christine Chen
1853552ee4b7111b995735d330b2e89bfabc2fd9b61Chiao Cheng        CallCommandClient.getInstance().mute(checked);
186241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng    }
187241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng
1888193bc3df6b0726d36a5b7b889ec91c4d59f40c1Santos Cordon    public void holdClicked(boolean checked) {
189e286f91abd12dee037de19c3836d8002e450a9c9Santos Cordon        if (mCall == null) {
190e286f91abd12dee037de19c3836d8002e450a9c9Santos Cordon            return;
191e286f91abd12dee037de19c3836d8002e450a9c9Santos Cordon        }
192671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon
1931a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng        Log.d(this, "holding: " + mCall.getCallId());
194efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon
195671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon        CallCommandClient.getInstance().hold(mCall.getCallId(), checked);
1968193bc3df6b0726d36a5b7b889ec91c4d59f40c1Santos Cordon    }
1978193bc3df6b0726d36a5b7b889ec91c4d59f40c1Santos Cordon
19861b7737bc556865097f9ca846bddb562371013fdSantos Cordon    public void mergeClicked() {
19961b7737bc556865097f9ca846bddb562371013fdSantos Cordon        CallCommandClient.getInstance().merge();
20061b7737bc556865097f9ca846bddb562371013fdSantos Cordon    }
20161b7737bc556865097f9ca846bddb562371013fdSantos Cordon
20261b7737bc556865097f9ca846bddb562371013fdSantos Cordon    public void addCallClicked() {
203e08284ea58e98666e6f1b45734d9901de91c2bb4Yorke Lee        // Automatically mute the current call
204e08284ea58e98666e6f1b45734d9901de91c2bb4Yorke Lee        mAutomaticallyMuted = true;
205b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon        mPreviousMuteState = AudioModeProvider.getInstance().getMute();
206a485665ec253f0a04cf7e411cb7acc2738196c63Yorke Lee        // Simulate a click on the mute button
207a485665ec253f0a04cf7e411cb7acc2738196c63Yorke Lee        muteClicked(true);
208e08284ea58e98666e6f1b45734d9901de91c2bb4Yorke Lee
20961b7737bc556865097f9ca846bddb562371013fdSantos Cordon        CallCommandClient.getInstance().addCall();
21061b7737bc556865097f9ca846bddb562371013fdSantos Cordon    }
21161b7737bc556865097f9ca846bddb562371013fdSantos Cordon
21261b7737bc556865097f9ca846bddb562371013fdSantos Cordon    public void swapClicked() {
21361b7737bc556865097f9ca846bddb562371013fdSantos Cordon        CallCommandClient.getInstance().swap();
21461b7737bc556865097f9ca846bddb562371013fdSantos Cordon    }
21561b7737bc556865097f9ca846bddb562371013fdSantos Cordon
2165b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    public void showDialpadClicked(boolean checked) {
2171a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng        Log.v(this, "Show dialpad " + String.valueOf(checked));
2185b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        getUi().displayDialpad(checked);
21946c57f18a63d5923b0b93f1988a56bb4beb9cc5dChristine Chen        updateExtraButtonRow();
2205b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    }
2215b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen
222bc168c4fb0638846c5076a5a35a2e75ee4947908Santos Cordon    private void updateUi(InCallState state, Call call) {
223bc168c4fb0638846c5076a5a35a2e75ee4947908Santos Cordon        final CallButtonUi ui = getUi();
224bc168c4fb0638846c5076a5a35a2e75ee4947908Santos Cordon        if (ui == null) {
225bc168c4fb0638846c5076a5a35a2e75ee4947908Santos Cordon            return;
226bc168c4fb0638846c5076a5a35a2e75ee4947908Santos Cordon        }
227bc168c4fb0638846c5076a5a35a2e75ee4947908Santos Cordon
22818db3795cd475434ee28841de75b3d85eab5fa57Ben Gilad        final boolean isEnabled = state.isConnectingOrConnected() &&
229066e3c2737dcc5288fec577324eb95dd94eb826eChristine Chen                !state.isIncoming() && call != null;
230bc168c4fb0638846c5076a5a35a2e75ee4947908Santos Cordon
23118db3795cd475434ee28841de75b3d85eab5fa57Ben Gilad        ui.setEnabled(isEnabled);
23261b7737bc556865097f9ca846bddb562371013fdSantos Cordon
2331a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng        Log.d(this, "Updating call UI for call: ", call);
23461b7737bc556865097f9ca846bddb562371013fdSantos Cordon
23518db3795cd475434ee28841de75b3d85eab5fa57Ben Gilad        if (isEnabled) {
236fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen            Log.v(this, "Show hold ", call.can(Capabilities.SUPPORT_HOLD));
237fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen            Log.v(this, "Enable hold", call.can(Capabilities.HOLD));
2381a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng            Log.v(this, "Show merge ", call.can(Capabilities.MERGE_CALLS));
2391a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng            Log.v(this, "Show swap ", call.can(Capabilities.SWAP_CALLS));
2401a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng            Log.v(this, "Show add call ", call.can(Capabilities.ADD_CALL));
241fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen            Log.v(this, "Show mute ", call.can(Capabilities.MUTE));
242bc168c4fb0638846c5076a5a35a2e75ee4947908Santos Cordon
243fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen            final boolean canMerge = call.can(Capabilities.MERGE_CALLS);
244fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen            final boolean canAdd = call.can(Capabilities.ADD_CALL);
245625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            final boolean isGenericConference = call.can(Capabilities.GENERIC_CONFERENCE);
246fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen
24746c57f18a63d5923b0b93f1988a56bb4beb9cc5dChristine Chen
248625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            final boolean showMerge = !isGenericConference && canMerge;
249625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon
250625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            if (showMerge) {
251fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen                ui.showMerge(true);
252fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen                ui.showAddCall(false);
253fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen            } else {
254fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen                ui.showMerge(false);
255fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen                ui.showAddCall(true);
256fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen                ui.enableAddCall(canAdd);
257fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen            }
258fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen
2597714909164b748baf13609a56719be1ec8817cd1Christine Chen            final boolean canHold = call.can(Capabilities.HOLD);
2607714909164b748baf13609a56719be1ec8817cd1Christine Chen            final boolean canSwap = call.can(Capabilities.SWAP_CALLS);
2617714909164b748baf13609a56719be1ec8817cd1Christine Chen            final boolean supportHold = call.can(Capabilities.SUPPORT_HOLD);
2627714909164b748baf13609a56719be1ec8817cd1Christine Chen
2637714909164b748baf13609a56719be1ec8817cd1Christine Chen            if (canHold) {
2647714909164b748baf13609a56719be1ec8817cd1Christine Chen                ui.showHold(true);
2657714909164b748baf13609a56719be1ec8817cd1Christine Chen                ui.setHold(call.getState() == Call.State.ONHOLD);
2667714909164b748baf13609a56719be1ec8817cd1Christine Chen                ui.enableHold(true);
2677714909164b748baf13609a56719be1ec8817cd1Christine Chen                ui.showSwap(false);
2687714909164b748baf13609a56719be1ec8817cd1Christine Chen            } else if (canSwap) {
2697714909164b748baf13609a56719be1ec8817cd1Christine Chen                ui.showHold(false);
2707714909164b748baf13609a56719be1ec8817cd1Christine Chen                ui.showSwap(true);
2717714909164b748baf13609a56719be1ec8817cd1Christine Chen            } else {
2727714909164b748baf13609a56719be1ec8817cd1Christine Chen                // Neither "Hold" nor "Swap" is available.  This can happen for two
2737714909164b748baf13609a56719be1ec8817cd1Christine Chen                // reasons:
2747714909164b748baf13609a56719be1ec8817cd1Christine Chen                //   (1) this is a transient state on a device that *can*
2757714909164b748baf13609a56719be1ec8817cd1Christine Chen                //       normally hold or swap, or
2767714909164b748baf13609a56719be1ec8817cd1Christine Chen                //   (2) this device just doesn't have the concept of hold/swap.
2777714909164b748baf13609a56719be1ec8817cd1Christine Chen                //
2787714909164b748baf13609a56719be1ec8817cd1Christine Chen                // In case (1), show the "Hold" button in a disabled state.  In case
2797714909164b748baf13609a56719be1ec8817cd1Christine Chen                // (2), remove the button entirely.  (This means that the button row
2807714909164b748baf13609a56719be1ec8817cd1Christine Chen                // will only have 4 buttons on some devices.)
2817714909164b748baf13609a56719be1ec8817cd1Christine Chen
2827714909164b748baf13609a56719be1ec8817cd1Christine Chen                if (supportHold) {
2837714909164b748baf13609a56719be1ec8817cd1Christine Chen                    ui.showHold(true);
2847714909164b748baf13609a56719be1ec8817cd1Christine Chen                    ui.enableHold(false);
2857714909164b748baf13609a56719be1ec8817cd1Christine Chen                    ui.setHold(call.getState() == Call.State.ONHOLD);
2867714909164b748baf13609a56719be1ec8817cd1Christine Chen                    ui.showSwap(false);
2877714909164b748baf13609a56719be1ec8817cd1Christine Chen                } else {
2887714909164b748baf13609a56719be1ec8817cd1Christine Chen                    ui.showHold(false);
2897714909164b748baf13609a56719be1ec8817cd1Christine Chen                    ui.showSwap(false);
2907714909164b748baf13609a56719be1ec8817cd1Christine Chen                }
2917714909164b748baf13609a56719be1ec8817cd1Christine Chen            }
292e08284ea58e98666e6f1b45734d9901de91c2bb4Yorke Lee
293fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen            ui.enableMute(call.can(Capabilities.MUTE));
2940f09a02be361d5bb36fac6981649204f5d6987faChristine Chen
2950f09a02be361d5bb36fac6981649204f5d6987faChristine Chen            // Finally, update the "extra button row": It's displayed above the
2960f09a02be361d5bb36fac6981649204f5d6987faChristine Chen            // "End" button, but only if necessary.  Also, it's never displayed
2970f09a02be361d5bb36fac6981649204f5d6987faChristine Chen            // while the dialpad is visible (since it would overlap.)
2980f09a02be361d5bb36fac6981649204f5d6987faChristine Chen            //
2990f09a02be361d5bb36fac6981649204f5d6987faChristine Chen            // The row contains two buttons:
3000f09a02be361d5bb36fac6981649204f5d6987faChristine Chen            //
3010f09a02be361d5bb36fac6981649204f5d6987faChristine Chen            // - "Manage conference" (used only on GSM devices)
3020f09a02be361d5bb36fac6981649204f5d6987faChristine Chen            // - "Merge" button (used only on CDMA devices)
303625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon
30446c57f18a63d5923b0b93f1988a56bb4beb9cc5dChristine Chen            mShowGenericMerge = isGenericConference && canMerge;
30546c57f18a63d5923b0b93f1988a56bb4beb9cc5dChristine Chen            mShowManageConference = (call.isConferenceCall() && !isGenericConference);
30646c57f18a63d5923b0b93f1988a56bb4beb9cc5dChristine Chen
30746c57f18a63d5923b0b93f1988a56bb4beb9cc5dChristine Chen            updateExtraButtonRow();
30846c57f18a63d5923b0b93f1988a56bb4beb9cc5dChristine Chen        }
30946c57f18a63d5923b0b93f1988a56bb4beb9cc5dChristine Chen    }
31046c57f18a63d5923b0b93f1988a56bb4beb9cc5dChristine Chen
31146c57f18a63d5923b0b93f1988a56bb4beb9cc5dChristine Chen    private void updateExtraButtonRow() {
31246c57f18a63d5923b0b93f1988a56bb4beb9cc5dChristine Chen        final boolean showExtraButtonRow = (mShowGenericMerge || mShowManageConference) &&
31346c57f18a63d5923b0b93f1988a56bb4beb9cc5dChristine Chen                !getUi().isDialpadVisible();
31446c57f18a63d5923b0b93f1988a56bb4beb9cc5dChristine Chen
31546c57f18a63d5923b0b93f1988a56bb4beb9cc5dChristine Chen        Log.d(this, "isGeneric: " + mShowGenericMerge);
31646c57f18a63d5923b0b93f1988a56bb4beb9cc5dChristine Chen        Log.d(this, "mShowManageConference : " + mShowManageConference);
31746c57f18a63d5923b0b93f1988a56bb4beb9cc5dChristine Chen        Log.d(this, "mShowGenericMerge: " + mShowGenericMerge);
31846c57f18a63d5923b0b93f1988a56bb4beb9cc5dChristine Chen        if (showExtraButtonRow) {
31946c57f18a63d5923b0b93f1988a56bb4beb9cc5dChristine Chen            if (mShowGenericMerge) {
32046c57f18a63d5923b0b93f1988a56bb4beb9cc5dChristine Chen                getUi().showGenericMergeButton();
32146c57f18a63d5923b0b93f1988a56bb4beb9cc5dChristine Chen            } else if (mShowManageConference) {
32246c57f18a63d5923b0b93f1988a56bb4beb9cc5dChristine Chen                getUi().showManageConferenceCallButton();
3230f09a02be361d5bb36fac6981649204f5d6987faChristine Chen            }
32446c57f18a63d5923b0b93f1988a56bb4beb9cc5dChristine Chen        } else {
32546c57f18a63d5923b0b93f1988a56bb4beb9cc5dChristine Chen            getUi().hideExtraRow();
326bc168c4fb0638846c5076a5a35a2e75ee4947908Santos Cordon        }
327bc168c4fb0638846c5076a5a35a2e75ee4947908Santos Cordon    }
328bc168c4fb0638846c5076a5a35a2e75ee4947908Santos Cordon
329eb7244f3001ca3b001b17bda99ab5c790eb1b2d3Christine Chen    public void refreshMuteState() {
330eb7244f3001ca3b001b17bda99ab5c790eb1b2d3Christine Chen        // Restore the previous mute state
331eb7244f3001ca3b001b17bda99ab5c790eb1b2d3Christine Chen        if (mAutomaticallyMuted &&
332eb7244f3001ca3b001b17bda99ab5c790eb1b2d3Christine Chen                AudioModeProvider.getInstance().getMute() != mPreviousMuteState) {
333eb7244f3001ca3b001b17bda99ab5c790eb1b2d3Christine Chen            if (getUi() == null) {
334eb7244f3001ca3b001b17bda99ab5c790eb1b2d3Christine Chen                return;
335eb7244f3001ca3b001b17bda99ab5c790eb1b2d3Christine Chen            }
336eb7244f3001ca3b001b17bda99ab5c790eb1b2d3Christine Chen            muteClicked(mPreviousMuteState);
337eb7244f3001ca3b001b17bda99ab5c790eb1b2d3Christine Chen        }
338eb7244f3001ca3b001b17bda99ab5c790eb1b2d3Christine Chen        mAutomaticallyMuted = false;
339eb7244f3001ca3b001b17bda99ab5c790eb1b2d3Christine Chen    }
340eb7244f3001ca3b001b17bda99ab5c790eb1b2d3Christine Chen
341241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng    public interface CallButtonUi extends Ui {
34218db3795cd475434ee28841de75b3d85eab5fa57Ben Gilad        void setEnabled(boolean on);
343241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng        void setMute(boolean on);
344fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen        void enableMute(boolean enabled);
3458193bc3df6b0726d36a5b7b889ec91c4d59f40c1Santos Cordon        void setHold(boolean on);
346bc168c4fb0638846c5076a5a35a2e75ee4947908Santos Cordon        void showHold(boolean show);
347fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen        void enableHold(boolean enabled);
34861b7737bc556865097f9ca846bddb562371013fdSantos Cordon        void showMerge(boolean show);
34961b7737bc556865097f9ca846bddb562371013fdSantos Cordon        void showSwap(boolean show);
35061b7737bc556865097f9ca846bddb562371013fdSantos Cordon        void showAddCall(boolean show);
351fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen        void enableAddCall(boolean enabled);
3525b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        void displayDialpad(boolean on);
3530f09a02be361d5bb36fac6981649204f5d6987faChristine Chen        boolean isDialpadVisible();
354dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon        void setAudio(int mode);
355dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon        void setSupportedAudio(int mask);
3560f09a02be361d5bb36fac6981649204f5d6987faChristine Chen        void showManageConferenceCallButton();
357625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        void showGenericMergeButton();
3580f09a02be361d5bb36fac6981649204f5d6987faChristine Chen        void hideExtraRow();
3590f09a02be361d5bb36fac6981649204f5d6987faChristine Chen        void displayManageConferencePanel(boolean on);
360241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng    }
361241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng}
362