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.content.Context;
20
21import com.android.incallui.ContactInfoCache.ContactCacheEntry;
22import com.android.incallui.InCallPresenter.InCallState;
23import com.android.incallui.InCallPresenter.InCallStateListener;
24import com.android.services.telephony.common.Call;
25
26import com.google.common.base.Preconditions;
27import com.google.common.collect.ImmutableSortedSet;
28
29/**
30 * Logic for call buttons.
31 */
32public class ConferenceManagerPresenter
33        extends Presenter<ConferenceManagerPresenter.ConferenceManagerUi>
34        implements InCallStateListener {
35
36    private static final int MAX_CALLERS_IN_CONFERENCE = 5;
37
38    private int mNumCallersInConference;
39    private Integer[] mCallerIds;
40    private Context mContext;
41
42    @Override
43    public void onUiReady(ConferenceManagerUi ui) {
44        super.onUiReady(ui);
45
46        // register for call state changes last
47        InCallPresenter.getInstance().addListener(this);
48    }
49
50    @Override
51    public void onUiUnready(ConferenceManagerUi ui) {
52        super.onUiUnready(ui);
53
54        InCallPresenter.getInstance().removeListener(this);
55    }
56
57    @Override
58    public void onStateChange(InCallState state, CallList callList) {
59        if (getUi().isFragmentVisible()) {
60            Log.v(this, "onStateChange" + state);
61            if (state == InCallState.INCALL) {
62                final Call call = callList.getActiveOrBackgroundCall();
63                if (call != null && call.isConferenceCall()) {
64                    Log.v(this, "Number of existing calls is " +
65                            String.valueOf(call.getChildCallIds().size()));
66                    update(callList);
67                } else {
68                    getUi().setVisible(false);
69                }
70            } else {
71                getUi().setVisible(false);
72            }
73        }
74    }
75
76    public void init(Context context, CallList callList) {
77        mContext = Preconditions.checkNotNull(context);
78        mContext = context;
79        update(callList);
80    }
81
82    private void update(CallList callList) {
83        mCallerIds = null;
84        mCallerIds = callList.getActiveOrBackgroundCall().getChildCallIds().toArray(new Integer[0]);
85        mNumCallersInConference = mCallerIds.length;
86        Log.v(this, "Number of calls is " + String.valueOf(mNumCallersInConference));
87
88        // Users can split out a call from the conference call if there either the active call
89        // or the holding call is empty. If both are filled at the moment, users can not split out
90        // another call.
91        final boolean hasActiveCall = (callList.getActiveCall() != null);
92        final boolean hasHoldingCall = (callList.getBackgroundCall() != null);
93        boolean canSeparate = !(hasActiveCall && hasHoldingCall);
94
95        for (int i = 0; i < MAX_CALLERS_IN_CONFERENCE; i++) {
96            if (i < mNumCallersInConference) {
97                // Fill in the row in the UI for this caller.
98
99                final ContactCacheEntry contactCache = ContactInfoCache.getInstance(mContext).
100                        getInfo(mCallerIds[i]);
101                updateManageConferenceRow(i, contactCache, canSeparate);
102            } else {
103                // Blank out this row in the UI
104                updateManageConferenceRow(i, null, false);
105            }
106        }
107    }
108
109    /**
110      * Updates a single row of the "Manage conference" UI.  (One row in this
111      * UI represents a single caller in the conference.)
112      *
113      * @param i the row to update
114      * @param contactCacheEntry the contact details corresponding to this caller.
115      *        If null, that means this is an "empty slot" in the conference,
116      *        so hide this row in the UI.
117      * @param canSeparate if true, show a "Separate" (i.e. "Private") button
118      *        on this row in the UI.
119      */
120    public void updateManageConferenceRow(final int i,
121                                          final ContactCacheEntry contactCacheEntry,
122                                          boolean canSeparate) {
123
124        if (contactCacheEntry != null) {
125            // Activate this row of the Manage conference panel:
126            getUi().setRowVisible(i, true);
127
128            final String name = contactCacheEntry.name;
129            final String number = contactCacheEntry.number;
130
131            if (canSeparate) {
132                getUi().setCanSeparateButtonForRow(i, canSeparate);
133            }
134            // display the CallerInfo.
135            getUi().setupEndButtonForRow(i);
136            getUi().displayCallerInfoForConferenceRow(i, name, number, contactCacheEntry.label);
137        } else {
138            // Disable this row of the Manage conference panel:
139            getUi().setRowVisible(i, false);
140        }
141    }
142
143    public void manageConferenceDoneClicked() {
144        getUi().setVisible(false);
145    }
146
147    public int getMaxCallersInConference() {
148        return MAX_CALLERS_IN_CONFERENCE;
149    }
150
151    public void separateConferenceConnection(int rowId) {
152        CallCommandClient.getInstance().separateCall(mCallerIds[rowId]);
153    }
154
155    public void endConferenceConnection(int rowId) {
156        CallCommandClient.getInstance().disconnectCall(mCallerIds[rowId]);
157    }
158
159    public interface ConferenceManagerUi extends Ui {
160        void setVisible(boolean on);
161        boolean isFragmentVisible();
162        void setRowVisible(int rowId, boolean on);
163        void displayCallerInfoForConferenceRow(int rowId, String callerName, String callerNumber,
164                String callerNumberType);
165        void setCanSeparateButtonForRow(int rowId, boolean canSeparate);
166        void setupEndButtonForRow(int rowId);
167        void startConferenceTime(long base);
168        void stopConferenceTime();
169    }
170}
171