CallButtonPresenter.java revision c155f799fc0d4a2c9577f1e0688a3f1f5b436aef
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
19dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordonimport com.android.incallui.AudioModeProvider.AudioModeListener;
20671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordonimport com.android.incallui.InCallPresenter.InCallState;
21671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordonimport com.android.incallui.InCallPresenter.InCallStateListener;
22c155f799fc0d4a2c9577f1e0688a3f1f5b436aefChristine Chenimport com.android.incallui.InCallPresenter.IncomingCallListener;
23dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordonimport com.android.services.telephony.common.AudioMode;
24671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordonimport com.android.services.telephony.common.Call;
25bc168c4fb0638846c5076a5a35a2e75ee4947908Santos Cordonimport com.android.services.telephony.common.Call.Capabilities;
26671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon
272ce872d6f7dd8a7eb0275b4195336f779972f698Makoto Onukiimport android.telephony.PhoneNumberUtils;
282ce872d6f7dd8a7eb0275b4195336f779972f698Makoto Onuki
29241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng/**
30241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng * Logic for call buttons.
31241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng */
32150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordonpublic class CallButtonPresenter extends Presenter<CallButtonPresenter.CallButtonUi>
33c155f799fc0d4a2c9577f1e0688a3f1f5b436aefChristine Chen        implements InCallStateListener, AudioModeListener, IncomingCallListener {
34241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng
35671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon    private Call mCall;
363c2a439eb67ec6fb89daf1914ab3ce05e8aaa428Santos Cordon    private ProximitySensor mProximitySensor;
37e08284ea58e98666e6f1b45734d9901de91c2bb4Yorke Lee    private boolean mAutomaticallyMuted = false;
38e08284ea58e98666e6f1b45734d9901de91c2bb4Yorke Lee    private boolean mPreviousMuteState = false;
39241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng
402ce872d6f7dd8a7eb0275b4195336f779972f698Makoto Onuki    private InCallState mPreviousState = null;
412ce872d6f7dd8a7eb0275b4195336f779972f698Makoto Onuki
429de3d7c5188c02cabf03799f87d494ee7dc702cbSantos Cordon    public CallButtonPresenter() {
43241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng    }
44241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng
45241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng    @Override
46241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng    public void onUiReady(CallButtonUi ui) {
47241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng        super.onUiReady(ui);
488b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng
49b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon        mProximitySensor = InCallPresenter.getInstance().getProximitySensor();
50b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon        AudioModeProvider.getInstance().addListener(this);
51b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon
52b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon        // register for call state changes last
53b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon        InCallPresenter.getInstance().addListener(this);
54c155f799fc0d4a2c9577f1e0688a3f1f5b436aefChristine Chen        InCallPresenter.getInstance().addIncomingCallListener(this);
55dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    }
56dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon
57dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    @Override
58dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    public void onUiUnready(CallButtonUi ui) {
5922c678c74fa38e921ea22b09962062fce6148047Christine Chen        super.onUiUnready(ui);
6022c678c74fa38e921ea22b09962062fce6148047Christine Chen
61b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon        InCallPresenter.getInstance().removeListener(this);
62b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon        AudioModeProvider.getInstance().removeListener(this);
63c155f799fc0d4a2c9577f1e0688a3f1f5b436aefChristine Chen        InCallPresenter.getInstance().removeIncomingCallListener(this);
64b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon
65b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon        mProximitySensor = null;
66241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng    }
67241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng
68150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon    @Override
69671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon    public void onStateChange(InCallState state, CallList callList) {
70e7be13fb0556e62b07bc271b130412d82d7f7521Santos Cordon        if (state == InCallState.OUTGOING) {
71e7be13fb0556e62b07bc271b130412d82d7f7521Santos Cordon            mCall = callList.getOutgoingCall();
72e7be13fb0556e62b07bc271b130412d82d7f7521Santos Cordon        } else if (state == InCallState.INCALL) {
73efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon            mCall = callList.getActiveOrBackgroundCall();
742ce872d6f7dd8a7eb0275b4195336f779972f698Makoto Onuki
752ce872d6f7dd8a7eb0275b4195336f779972f698Makoto Onuki            // When connected to voice mail, automatically shows the dialpad.
762ce872d6f7dd8a7eb0275b4195336f779972f698Makoto Onuki            // (On previous releases we showed it when in-call shows up, before waiting for
772ce872d6f7dd8a7eb0275b4195336f779972f698Makoto Onuki            // OUTGOING.  We may want to do that once we start showing "Voice mail" label on
782ce872d6f7dd8a7eb0275b4195336f779972f698Makoto Onuki            // the dialpad too.)
792ce872d6f7dd8a7eb0275b4195336f779972f698Makoto Onuki            if (mPreviousState == InCallState.OUTGOING
80042692d73b964d33ebd4d7bacfd548b5fda6a24dMakoto Onuki                    && mCall != null && PhoneNumberUtils.isVoiceMailNumber(mCall.getNumber())) {
812ce872d6f7dd8a7eb0275b4195336f779972f698Makoto Onuki                getUi().displayDialpad(true);
822ce872d6f7dd8a7eb0275b4195336f779972f698Makoto Onuki            }
83c155f799fc0d4a2c9577f1e0688a3f1f5b436aefChristine Chen        } else if (state == InCallState.INCOMING) {
84c155f799fc0d4a2c9577f1e0688a3f1f5b436aefChristine Chen            getUi().displayDialpad(false);
85c155f799fc0d4a2c9577f1e0688a3f1f5b436aefChristine Chen            mCall = null;
86671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon        } else {
87671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon            mCall = null;
88671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon        }
89bc168c4fb0638846c5076a5a35a2e75ee4947908Santos Cordon        updateUi(state, mCall);
902ce872d6f7dd8a7eb0275b4195336f779972f698Makoto Onuki
912ce872d6f7dd8a7eb0275b4195336f779972f698Makoto Onuki        mPreviousState = state;
92241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng    }
93241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng
94dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    @Override
95c155f799fc0d4a2c9577f1e0688a3f1f5b436aefChristine Chen    public void onIncomingCall(InCallState state, Call call) {
96c155f799fc0d4a2c9577f1e0688a3f1f5b436aefChristine Chen        onStateChange(state, CallList.getInstance());
97c155f799fc0d4a2c9577f1e0688a3f1f5b436aefChristine Chen    }
98c155f799fc0d4a2c9577f1e0688a3f1f5b436aefChristine Chen
99c155f799fc0d4a2c9577f1e0688a3f1f5b436aefChristine Chen    @Override
100dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    public void onAudioMode(int mode) {
1018b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        if (getUi() != null) {
1028b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            getUi().setAudio(mode);
1038b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        }
104dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    }
105dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon
106dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    @Override
107dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    public void onSupportedAudioMode(int mask) {
1088b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        if (getUi() != null) {
1098b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            getUi().setSupportedAudio(mask);
1108b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        }
111dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    }
112dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon
1133e69e4fe0e6dbce738cc6b3f9a71fc177e9fe1b6Santos Cordon    @Override
1143e69e4fe0e6dbce738cc6b3f9a71fc177e9fe1b6Santos Cordon    public void onMute(boolean muted) {
1153e69e4fe0e6dbce738cc6b3f9a71fc177e9fe1b6Santos Cordon        if (getUi() != null) {
1163e69e4fe0e6dbce738cc6b3f9a71fc177e9fe1b6Santos Cordon            getUi().setMute(muted);
1173e69e4fe0e6dbce738cc6b3f9a71fc177e9fe1b6Santos Cordon        }
1183e69e4fe0e6dbce738cc6b3f9a71fc177e9fe1b6Santos Cordon    }
1193e69e4fe0e6dbce738cc6b3f9a71fc177e9fe1b6Santos Cordon
120dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    public int getAudioMode() {
121b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon        return AudioModeProvider.getInstance().getAudioMode();
122dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    }
123dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon
124dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    public int getSupportedAudio() {
125b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon        return AudioModeProvider.getInstance().getSupportedModes();
126dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    }
127dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon
128dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    public void setAudioMode(int mode) {
129dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon
130dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon        // TODO: Set a intermediate state in this presenter until we get
131dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon        // an update for onAudioMode().  This will make UI response immediate
132dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon        // if it turns out to be slow
133dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon
1341a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng        Log.d(this, "Sending new Audio Mode: " + AudioMode.toString(mode));
135dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon        CallCommandClient.getInstance().setAudioMode(mode);
136dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    }
137dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon
138dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    /**
139dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon     * Function assumes that bluetooth is not supported.
140dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon     */
141dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    public void toggleSpeakerphone() {
142dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon        // this function should not be called if bluetooth is available
1439de3d7c5188c02cabf03799f87d494ee7dc702cbSantos Cordon        if (0 != (AudioMode.BLUETOOTH & getSupportedAudio())) {
144dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon
1459de3d7c5188c02cabf03799f87d494ee7dc702cbSantos Cordon            // It's clear the UI is wrong, so update the supported mode once again.
1461a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng            Log.e(this, "toggling speakerphone not allowed when bluetooth supported.");
1479de3d7c5188c02cabf03799f87d494ee7dc702cbSantos Cordon            getUi().setSupportedAudio(getSupportedAudio());
148dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon            return;
149dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon        }
150dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon
151dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon        int newMode = AudioMode.SPEAKER;
152dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon
153dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon        // if speakerphone is already on, change to wired/earpiece
1549de3d7c5188c02cabf03799f87d494ee7dc702cbSantos Cordon        if (getAudioMode() == AudioMode.SPEAKER) {
155dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon            newMode = AudioMode.WIRED_OR_EARPIECE;
156dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon        }
157dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon
158dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon        setAudioMode(newMode);
159dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon    }
160dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon
161b94803e83573734d21a32047b21f348cb2305155Chiao Cheng    public void endCallClicked() {
162e286f91abd12dee037de19c3836d8002e450a9c9Santos Cordon        if (mCall == null) {
163e286f91abd12dee037de19c3836d8002e450a9c9Santos Cordon            return;
164e286f91abd12dee037de19c3836d8002e450a9c9Santos Cordon        }
165671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon
166671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon        CallCommandClient.getInstance().disconnectCall(mCall.getCallId());
167b94803e83573734d21a32047b21f348cb2305155Chiao Cheng    }
168b94803e83573734d21a32047b21f348cb2305155Chiao Cheng
1690f09a02be361d5bb36fac6981649204f5d6987faChristine Chen    public void manageConferenceButtonClicked() {
1700f09a02be361d5bb36fac6981649204f5d6987faChristine Chen        getUi().displayManageConferencePanel(true);
1710f09a02be361d5bb36fac6981649204f5d6987faChristine Chen    }
1720f09a02be361d5bb36fac6981649204f5d6987faChristine Chen
173241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng    public void muteClicked(boolean checked) {
1741a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng        Log.d(this, "turning on mute: " + checked);
1753552ee4b7111b995735d330b2e89bfabc2fd9b61Chiao Cheng        CallCommandClient.getInstance().mute(checked);
176241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng    }
177241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng
1788193bc3df6b0726d36a5b7b889ec91c4d59f40c1Santos Cordon    public void holdClicked(boolean checked) {
179e286f91abd12dee037de19c3836d8002e450a9c9Santos Cordon        if (mCall == null) {
180e286f91abd12dee037de19c3836d8002e450a9c9Santos Cordon            return;
181e286f91abd12dee037de19c3836d8002e450a9c9Santos Cordon        }
182671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon
1831a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng        Log.d(this, "holding: " + mCall.getCallId());
184efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon
185671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon        CallCommandClient.getInstance().hold(mCall.getCallId(), checked);
1868193bc3df6b0726d36a5b7b889ec91c4d59f40c1Santos Cordon        getUi().setHold(checked);
1878193bc3df6b0726d36a5b7b889ec91c4d59f40c1Santos Cordon    }
1888193bc3df6b0726d36a5b7b889ec91c4d59f40c1Santos Cordon
18961b7737bc556865097f9ca846bddb562371013fdSantos Cordon    public void mergeClicked() {
19061b7737bc556865097f9ca846bddb562371013fdSantos Cordon        CallCommandClient.getInstance().merge();
19161b7737bc556865097f9ca846bddb562371013fdSantos Cordon    }
19261b7737bc556865097f9ca846bddb562371013fdSantos Cordon
19361b7737bc556865097f9ca846bddb562371013fdSantos Cordon    public void addCallClicked() {
194e08284ea58e98666e6f1b45734d9901de91c2bb4Yorke Lee        // Automatically mute the current call
195e08284ea58e98666e6f1b45734d9901de91c2bb4Yorke Lee        mAutomaticallyMuted = true;
196b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon        mPreviousMuteState = AudioModeProvider.getInstance().getMute();
197a485665ec253f0a04cf7e411cb7acc2738196c63Yorke Lee        // Simulate a click on the mute button
198a485665ec253f0a04cf7e411cb7acc2738196c63Yorke Lee        muteClicked(true);
199e08284ea58e98666e6f1b45734d9901de91c2bb4Yorke Lee
20061b7737bc556865097f9ca846bddb562371013fdSantos Cordon        CallCommandClient.getInstance().addCall();
20161b7737bc556865097f9ca846bddb562371013fdSantos Cordon    }
20261b7737bc556865097f9ca846bddb562371013fdSantos Cordon
20361b7737bc556865097f9ca846bddb562371013fdSantos Cordon    public void swapClicked() {
20461b7737bc556865097f9ca846bddb562371013fdSantos Cordon        CallCommandClient.getInstance().swap();
20561b7737bc556865097f9ca846bddb562371013fdSantos Cordon    }
20661b7737bc556865097f9ca846bddb562371013fdSantos Cordon
2075b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    public void showDialpadClicked(boolean checked) {
2081a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng        Log.v(this, "Show dialpad " + String.valueOf(checked));
2095b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        getUi().displayDialpad(checked);
2103c2a439eb67ec6fb89daf1914ab3ce05e8aaa428Santos Cordon        mProximitySensor.onDialpadVisible(checked);
2115b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    }
2125b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen
213bc168c4fb0638846c5076a5a35a2e75ee4947908Santos Cordon    private void updateUi(InCallState state, Call call) {
214bc168c4fb0638846c5076a5a35a2e75ee4947908Santos Cordon        final CallButtonUi ui = getUi();
215bc168c4fb0638846c5076a5a35a2e75ee4947908Santos Cordon        if (ui == null) {
216bc168c4fb0638846c5076a5a35a2e75ee4947908Santos Cordon            return;
217bc168c4fb0638846c5076a5a35a2e75ee4947908Santos Cordon        }
218bc168c4fb0638846c5076a5a35a2e75ee4947908Santos Cordon
219bc168c4fb0638846c5076a5a35a2e75ee4947908Santos Cordon        final boolean isVisible = state.isConnectingOrConnected() &&
220066e3c2737dcc5288fec577324eb95dd94eb826eChristine Chen                !state.isIncoming() && call != null;
221bc168c4fb0638846c5076a5a35a2e75ee4947908Santos Cordon
22261b7737bc556865097f9ca846bddb562371013fdSantos Cordon        ui.setVisible(isVisible);
22361b7737bc556865097f9ca846bddb562371013fdSantos Cordon
2241a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng        Log.d(this, "Updating call UI for call: ", call);
22561b7737bc556865097f9ca846bddb562371013fdSantos Cordon
226066e3c2737dcc5288fec577324eb95dd94eb826eChristine Chen        if (isVisible) {
227fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen            Log.v(this, "Show hold ", call.can(Capabilities.SUPPORT_HOLD));
228fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen            Log.v(this, "Enable hold", call.can(Capabilities.HOLD));
2291a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng            Log.v(this, "Show merge ", call.can(Capabilities.MERGE_CALLS));
2301a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng            Log.v(this, "Show swap ", call.can(Capabilities.SWAP_CALLS));
2311a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng            Log.v(this, "Show add call ", call.can(Capabilities.ADD_CALL));
232fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen            Log.v(this, "Show mute ", call.can(Capabilities.MUTE));
233bc168c4fb0638846c5076a5a35a2e75ee4947908Santos Cordon
234fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen            final boolean canMerge = call.can(Capabilities.MERGE_CALLS);
235fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen            final boolean canAdd = call.can(Capabilities.ADD_CALL);
236625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            final boolean isGenericConference = call.can(Capabilities.GENERIC_CONFERENCE);
237fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen
238625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            final boolean showGenericMerge = isGenericConference && canMerge;
239625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            final boolean showMerge = !isGenericConference && canMerge;
240625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon
241625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            if (showMerge) {
242fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen                ui.showMerge(true);
243fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen                ui.showAddCall(false);
244fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen            } else {
245fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen                ui.showMerge(false);
246fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen                ui.showAddCall(true);
247fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen                ui.enableAddCall(canAdd);
248fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen            }
249fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen
2507714909164b748baf13609a56719be1ec8817cd1Christine Chen            final boolean canHold = call.can(Capabilities.HOLD);
2517714909164b748baf13609a56719be1ec8817cd1Christine Chen            final boolean canSwap = call.can(Capabilities.SWAP_CALLS);
2527714909164b748baf13609a56719be1ec8817cd1Christine Chen            final boolean supportHold = call.can(Capabilities.SUPPORT_HOLD);
2537714909164b748baf13609a56719be1ec8817cd1Christine Chen
2547714909164b748baf13609a56719be1ec8817cd1Christine Chen            if (canHold) {
2557714909164b748baf13609a56719be1ec8817cd1Christine Chen                ui.showHold(true);
2567714909164b748baf13609a56719be1ec8817cd1Christine Chen                ui.setHold(call.getState() == Call.State.ONHOLD);
2577714909164b748baf13609a56719be1ec8817cd1Christine Chen                ui.enableHold(true);
2587714909164b748baf13609a56719be1ec8817cd1Christine Chen                ui.showSwap(false);
2597714909164b748baf13609a56719be1ec8817cd1Christine Chen            } else if (canSwap) {
2607714909164b748baf13609a56719be1ec8817cd1Christine Chen                ui.showHold(false);
2617714909164b748baf13609a56719be1ec8817cd1Christine Chen                ui.showSwap(true);
2627714909164b748baf13609a56719be1ec8817cd1Christine Chen            } else {
2637714909164b748baf13609a56719be1ec8817cd1Christine Chen                // Neither "Hold" nor "Swap" is available.  This can happen for two
2647714909164b748baf13609a56719be1ec8817cd1Christine Chen                // reasons:
2657714909164b748baf13609a56719be1ec8817cd1Christine Chen                //   (1) this is a transient state on a device that *can*
2667714909164b748baf13609a56719be1ec8817cd1Christine Chen                //       normally hold or swap, or
2677714909164b748baf13609a56719be1ec8817cd1Christine Chen                //   (2) this device just doesn't have the concept of hold/swap.
2687714909164b748baf13609a56719be1ec8817cd1Christine Chen                //
2697714909164b748baf13609a56719be1ec8817cd1Christine Chen                // In case (1), show the "Hold" button in a disabled state.  In case
2707714909164b748baf13609a56719be1ec8817cd1Christine Chen                // (2), remove the button entirely.  (This means that the button row
2717714909164b748baf13609a56719be1ec8817cd1Christine Chen                // will only have 4 buttons on some devices.)
2727714909164b748baf13609a56719be1ec8817cd1Christine Chen
2737714909164b748baf13609a56719be1ec8817cd1Christine Chen                if (supportHold) {
2747714909164b748baf13609a56719be1ec8817cd1Christine Chen                    ui.showHold(true);
2757714909164b748baf13609a56719be1ec8817cd1Christine Chen                    ui.enableHold(false);
2767714909164b748baf13609a56719be1ec8817cd1Christine Chen                    ui.setHold(call.getState() == Call.State.ONHOLD);
2777714909164b748baf13609a56719be1ec8817cd1Christine Chen                    ui.showSwap(false);
2787714909164b748baf13609a56719be1ec8817cd1Christine Chen                } else {
2797714909164b748baf13609a56719be1ec8817cd1Christine Chen                    ui.showHold(false);
2807714909164b748baf13609a56719be1ec8817cd1Christine Chen                    ui.showSwap(false);
2817714909164b748baf13609a56719be1ec8817cd1Christine Chen                }
2827714909164b748baf13609a56719be1ec8817cd1Christine Chen            }
283e08284ea58e98666e6f1b45734d9901de91c2bb4Yorke Lee
284fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen            ui.enableMute(call.can(Capabilities.MUTE));
2850f09a02be361d5bb36fac6981649204f5d6987faChristine Chen
2860f09a02be361d5bb36fac6981649204f5d6987faChristine Chen            // Finally, update the "extra button row": It's displayed above the
2870f09a02be361d5bb36fac6981649204f5d6987faChristine Chen            // "End" button, but only if necessary.  Also, it's never displayed
2880f09a02be361d5bb36fac6981649204f5d6987faChristine Chen            // while the dialpad is visible (since it would overlap.)
2890f09a02be361d5bb36fac6981649204f5d6987faChristine Chen            //
2900f09a02be361d5bb36fac6981649204f5d6987faChristine Chen            // The row contains two buttons:
2910f09a02be361d5bb36fac6981649204f5d6987faChristine Chen            //
2920f09a02be361d5bb36fac6981649204f5d6987faChristine Chen            // - "Manage conference" (used only on GSM devices)
2930f09a02be361d5bb36fac6981649204f5d6987faChristine Chen            // - "Merge" button (used only on CDMA devices)
294625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon
295625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            final boolean showManageConference = (call.isConferenceCall() && !isGenericConference);
296625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            final boolean showExtraButtonRow = (showGenericMerge || showManageConference) &&
297625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon                    !getUi().isDialpadVisible();
298625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon
299625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            Log.i(this, "isGeneric: " + isGenericConference);
300625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            Log.i(this, "showManageConference : " + showManageConference);
301625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            Log.i(this, "showGenericMerge: " + showGenericMerge);
3020f09a02be361d5bb36fac6981649204f5d6987faChristine Chen            if (showExtraButtonRow) {
303625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon                if (showGenericMerge) {
304625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon                    getUi().showGenericMergeButton();
305625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon                } else if (showManageConference) {
3060f09a02be361d5bb36fac6981649204f5d6987faChristine Chen                    getUi().showManageConferenceCallButton();
3070f09a02be361d5bb36fac6981649204f5d6987faChristine Chen                }
3080f09a02be361d5bb36fac6981649204f5d6987faChristine Chen            } else {
3090f09a02be361d5bb36fac6981649204f5d6987faChristine Chen                getUi().hideExtraRow();
3100f09a02be361d5bb36fac6981649204f5d6987faChristine Chen            }
311bc168c4fb0638846c5076a5a35a2e75ee4947908Santos Cordon        }
312bc168c4fb0638846c5076a5a35a2e75ee4947908Santos Cordon    }
313bc168c4fb0638846c5076a5a35a2e75ee4947908Santos Cordon
314eb7244f3001ca3b001b17bda99ab5c790eb1b2d3Christine Chen    public void refreshMuteState() {
315eb7244f3001ca3b001b17bda99ab5c790eb1b2d3Christine Chen        // Restore the previous mute state
316eb7244f3001ca3b001b17bda99ab5c790eb1b2d3Christine Chen        if (mAutomaticallyMuted &&
317eb7244f3001ca3b001b17bda99ab5c790eb1b2d3Christine Chen                AudioModeProvider.getInstance().getMute() != mPreviousMuteState) {
318eb7244f3001ca3b001b17bda99ab5c790eb1b2d3Christine Chen            if (getUi() == null) {
319eb7244f3001ca3b001b17bda99ab5c790eb1b2d3Christine Chen                return;
320eb7244f3001ca3b001b17bda99ab5c790eb1b2d3Christine Chen            }
321eb7244f3001ca3b001b17bda99ab5c790eb1b2d3Christine Chen            muteClicked(mPreviousMuteState);
322eb7244f3001ca3b001b17bda99ab5c790eb1b2d3Christine Chen        }
323eb7244f3001ca3b001b17bda99ab5c790eb1b2d3Christine Chen        mAutomaticallyMuted = false;
324eb7244f3001ca3b001b17bda99ab5c790eb1b2d3Christine Chen    }
325eb7244f3001ca3b001b17bda99ab5c790eb1b2d3Christine Chen
326241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng    public interface CallButtonUi extends Ui {
3274df10e20c8a4a5c2b6b1e9d0c895cf205929e8ddChiao Cheng        void setVisible(boolean on);
328241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng        void setMute(boolean on);
329fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen        void enableMute(boolean enabled);
3308193bc3df6b0726d36a5b7b889ec91c4d59f40c1Santos Cordon        void setHold(boolean on);
331bc168c4fb0638846c5076a5a35a2e75ee4947908Santos Cordon        void showHold(boolean show);
332fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen        void enableHold(boolean enabled);
33361b7737bc556865097f9ca846bddb562371013fdSantos Cordon        void showMerge(boolean show);
33461b7737bc556865097f9ca846bddb562371013fdSantos Cordon        void showSwap(boolean show);
33561b7737bc556865097f9ca846bddb562371013fdSantos Cordon        void showAddCall(boolean show);
336fe09b09a955c574d1131932211a05f862ee9e50fChristine Chen        void enableAddCall(boolean enabled);
3375b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        void displayDialpad(boolean on);
3380f09a02be361d5bb36fac6981649204f5d6987faChristine Chen        boolean isDialpadVisible();
339dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon        void setAudio(int mode);
340dab149c9b2185be82cbca63cc3980e41444900c0Santos Cordon        void setSupportedAudio(int mask);
3410f09a02be361d5bb36fac6981649204f5d6987faChristine Chen        void showManageConferenceCallButton();
342625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        void showGenericMergeButton();
3430f09a02be361d5bb36fac6981649204f5d6987faChristine Chen        void hideExtraRow();
3440f09a02be361d5bb36fac6981649204f5d6987faChristine Chen        void displayManageConferencePanel(boolean on);
345241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng    }
346241d50d5f523eb0b644d8a9c1cf7fd2eb418ab88Chiao Cheng}
347