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 17 package com.android.incallui; 18 19 import android.content.Context; 20 import android.net.Uri; 21 import android.telecom.PhoneCapabilities; 22 import android.text.TextUtils; 23 24 import com.android.incallui.ContactInfoCache.ContactCacheEntry; 25 import com.android.incallui.InCallPresenter.InCallState; 26 import com.android.incallui.InCallPresenter.InCallStateListener; 27 28 import com.google.common.base.Preconditions; 29 30 /** 31 * Logic for call buttons. 32 */ 33 public class ConferenceManagerPresenter 34 extends Presenter<ConferenceManagerPresenter.ConferenceManagerUi> 35 implements InCallStateListener { 36 37 private static final int MAX_CALLERS_IN_CONFERENCE = 5; 38 39 private String[] mCallerIds; 40 private Context mContext; 41 42 @Override onUiReady(ConferenceManagerUi ui)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 onUiUnready(ConferenceManagerUi ui)51 public void onUiUnready(ConferenceManagerUi ui) { 52 super.onUiUnready(ui); 53 54 InCallPresenter.getInstance().removeListener(this); 55 } 56 57 @Override onStateChange(InCallState oldState, InCallState newState, CallList callList)58 public void onStateChange(InCallState oldState, InCallState newState, CallList callList) { 59 if (getUi().isFragmentVisible()) { 60 Log.v(this, "onStateChange" + newState); 61 if (newState == 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 init(Context context, CallList callList)76 public void init(Context context, CallList callList) { 77 mContext = Preconditions.checkNotNull(context); 78 mContext = context; 79 update(callList); 80 } 81 update(CallList callList)82 private void update(CallList callList) { 83 // callList is non null, but getActiveOrBackgroundCall() may return null 84 final Call currentCall = callList.getActiveOrBackgroundCall(); 85 if (currentCall != null) { 86 // getChildCallIds() always returns a valid Set 87 mCallerIds = currentCall.getChildCallIds().toArray(new String[0]); 88 } else { 89 mCallerIds = new String[0]; 90 } 91 Log.d(this, "Number of calls is " + String.valueOf(mCallerIds.length)); 92 93 // Users can split out a call from the conference call if there either the active call 94 // or the holding call is empty. If both are filled at the moment, users can not split out 95 // another call. 96 final boolean hasActiveCall = (callList.getActiveCall() != null); 97 final boolean hasHoldingCall = (callList.getBackgroundCall() != null); 98 boolean canSeparate = !(hasActiveCall && hasHoldingCall); 99 100 for (int i = 0; i < MAX_CALLERS_IN_CONFERENCE; i++) { 101 if (i < mCallerIds.length) { 102 int callCapabilities = 103 callList.getCallById(currentCall.getChildCallIds().get(i)) 104 .getTelecommCall().getDetails().getCallCapabilities(); 105 boolean thisRowCanSeparate = canSeparate && 106 ((callCapabilities & PhoneCapabilities.SEPARATE_FROM_CONFERENCE) != 0); 107 boolean thisRowCanDisconnect = 108 ((callCapabilities & PhoneCapabilities.DISCONNECT_FROM_CONFERENCE) != 0); 109 // Fill in the row in the UI for this caller. 110 final ContactCacheEntry contactCache = ContactInfoCache.getInstance(mContext). 111 getInfo(mCallerIds[i]); 112 updateManageConferenceRow( 113 i, 114 contactCache, 115 thisRowCanSeparate, 116 thisRowCanDisconnect); 117 } else { 118 // Blank out this row in the UI 119 updateManageConferenceRow(i, null, false, false); 120 } 121 } 122 } 123 124 /** 125 * Updates a single row of the "Manage conference" UI. (One row in this 126 * UI represents a single caller in the conference.) 127 * 128 * @param i the row to update 129 * @param contactCacheEntry the contact details corresponding to this caller. 130 * If null, that means this is an "empty slot" in the conference, 131 * so hide this row in the UI. 132 * @param canSeparate if true, show a "Separate" (i.e. "Private") button 133 * on this row in the UI. 134 * @param canDisconnect if true, show a "Disconnect" button on this row in the UI. 135 */ updateManageConferenceRow(final int i, final ContactCacheEntry contactCacheEntry, boolean canSeparate, boolean canDisconnect)136 public void updateManageConferenceRow(final int i, 137 final ContactCacheEntry contactCacheEntry, 138 boolean canSeparate, 139 boolean canDisconnect) { 140 141 if (contactCacheEntry != null) { 142 // Activate this row of the Manage conference panel: 143 getUi().setRowVisible(i, true); 144 145 String name = contactCacheEntry.name; 146 String number = contactCacheEntry.number; 147 148 if (TextUtils.isEmpty(name)) { 149 name = number; 150 number = null; 151 } 152 153 getUi().setupSeparateButtonForRow(i, canSeparate); 154 getUi().setupEndButtonForRow(i, canDisconnect); 155 getUi().displayCallerInfoForConferenceRow(i, name, number, contactCacheEntry.label, 156 contactCacheEntry.lookupKey, contactCacheEntry.displayPhotoUri); 157 } else { 158 // Disable this row of the Manage conference panel: 159 getUi().setRowVisible(i, false); 160 } 161 } 162 getMaxCallersInConference()163 public int getMaxCallersInConference() { 164 return MAX_CALLERS_IN_CONFERENCE; 165 } 166 separateConferenceConnection(int rowId)167 public void separateConferenceConnection(int rowId) { 168 if (rowId < mCallerIds.length) { 169 TelecomAdapter.getInstance().separateCall(mCallerIds[rowId]); 170 } 171 } 172 endConferenceConnection(int rowId)173 public void endConferenceConnection(int rowId) { 174 if (rowId < mCallerIds.length) { 175 TelecomAdapter.getInstance().disconnectCall(mCallerIds[rowId]); 176 } 177 } 178 179 public interface ConferenceManagerUi extends Ui { setVisible(boolean on)180 void setVisible(boolean on); isFragmentVisible()181 boolean isFragmentVisible(); setRowVisible(int rowId, boolean on)182 void setRowVisible(int rowId, boolean on); displayCallerInfoForConferenceRow(int rowId, String callerName, String callerNumber, String callerNumberType, String lookupKey, Uri photoUri)183 void displayCallerInfoForConferenceRow(int rowId, String callerName, String callerNumber, 184 String callerNumberType, String lookupKey, Uri photoUri); setupSeparateButtonForRow(int rowId, boolean canSeparate)185 void setupSeparateButtonForRow(int rowId, boolean canSeparate); setupEndButtonForRow(int rowId, boolean canDisconnect)186 void setupEndButtonForRow(int rowId, boolean canDisconnect); 187 } 188 } 189