1 /*
2  * Copyright (C) 2017 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.server.telecom.testapps;
18 
19 import android.telecom.CallAudioState;
20 import android.telecom.Connection;
21 import android.telecom.DisconnectCause;
22 import android.telecom.PhoneAccountHandle;
23 import android.util.Log;
24 import android.view.LayoutInflater;
25 import android.view.View;
26 import android.view.ViewGroup;
27 import android.widget.BaseAdapter;
28 import android.widget.CheckBox;
29 import android.widget.TextView;
30 
31 import com.android.server.telecom.testapps.R;
32 
33 import java.util.List;
34 
35 public class SelfManagedCallListAdapter extends BaseAdapter {
36 
37     private static final String TAG = "SelfMgCallListAd";
38     /**
39      * Listener used to handle tap of the "disconnect" button for a connection.
40      */
41     private View.OnClickListener mDisconnectListener = new View.OnClickListener() {
42         @Override
43         public void onClick(View v) {
44             View parent = (View) v.getParent().getParent();
45             SelfManagedConnection connection = (SelfManagedConnection) parent.getTag();
46             connection.setConnectionDisconnected(DisconnectCause.LOCAL);
47             SelfManagedCallList.getInstance().removeConnection(connection);
48         }
49     };
50 
51     /**
52      * Listener used to handle tap of the "active" button for a connection.
53      */
54     private View.OnClickListener mActiveListener = new View.OnClickListener() {
55         @Override
56         public void onClick(View v) {
57             View parent = (View) v.getParent().getParent();
58             SelfManagedConnection connection = (SelfManagedConnection) parent.getTag();
59             connection.setConnectionActive();
60             notifyDataSetChanged();
61         }
62     };
63 
64     /**
65      * Listener used to handle tap of the "missed" button for a connection.
66      */
67     private View.OnClickListener mMissedListener = new View.OnClickListener() {
68         @Override
69         public void onClick(View v) {
70             View parent = (View) v.getParent().getParent();
71             SelfManagedConnection connection = (SelfManagedConnection) parent.getTag();
72             connection.setConnectionDisconnected(DisconnectCause.MISSED);
73             SelfManagedCallList.getInstance().removeConnection(connection);
74         }
75     };
76 
77     private View.OnClickListener mHeldListener = new View.OnClickListener() {
78         @Override
79         public void onClick(View v) {
80             View parent = (View) v.getParent().getParent();
81             SelfManagedConnection connection = (SelfManagedConnection) parent.getTag();
82             connection.setConnectionHeld();
83             notifyDataSetChanged();
84         }
85     };
86 
87     private View.OnClickListener mSpeakerListener = new View.OnClickListener() {
88         @Override
89         public void onClick(View v) {
90             View parent = (View) v.getParent().getParent();
91             SelfManagedConnection connection = (SelfManagedConnection) parent.getTag();
92             connection.setAudioRoute(CallAudioState.ROUTE_SPEAKER);
93             notifyDataSetChanged();
94         }
95     };
96 
97     private View.OnClickListener mEarpieceListener = new View.OnClickListener() {
98         @Override
99         public void onClick(View v) {
100             View parent = (View) v.getParent().getParent();
101             SelfManagedConnection connection = (SelfManagedConnection) parent.getTag();
102             connection.setAudioRoute(CallAudioState.ROUTE_EARPIECE);
103             notifyDataSetChanged();
104         }
105     };
106 
107     private View.OnClickListener mBluetoothListener = new View.OnClickListener() {
108         @Override
109         public void onClick(View v) {
110             View parent = (View) v.getParent().getParent();
111             SelfManagedConnection connection = (SelfManagedConnection) parent.getTag();
112             connection.setAudioRoute(CallAudioState.ROUTE_BLUETOOTH);
113             notifyDataSetChanged();
114         }
115     };
116 
117     private View.OnClickListener mHoldableListener = new View.OnClickListener() {
118         @Override
119         public void onClick (View v) {
120             View parent = (View) v.getParent().getParent();
121             SelfManagedConnection connection = (SelfManagedConnection) parent.getTag();
122             int capabilities = connection.getConnectionCapabilities();
123             if ((capabilities & Connection.CAPABILITY_HOLD) == Connection.CAPABILITY_HOLD) {
124                 capabilities &= ~(Connection.CAPABILITY_HOLD | Connection.CAPABILITY_SUPPORT_HOLD);
125             } else {
126                 capabilities |= (Connection.CAPABILITY_HOLD | Connection.CAPABILITY_SUPPORT_HOLD);
127             }
128             connection.setConnectionCapabilities(capabilities);
129             notifyDataSetChanged();
130         }
131     };
132 
133     private final LayoutInflater mLayoutInflater;
134 
135     private List<SelfManagedConnection> mConnections;
136 
SelfManagedCallListAdapter(LayoutInflater layoutInflater, List<SelfManagedConnection> connections)137     public SelfManagedCallListAdapter(LayoutInflater layoutInflater,
138                                       List<SelfManagedConnection> connections) {
139 
140         mLayoutInflater = layoutInflater;
141         mConnections = connections;
142     }
143 
144     @Override
getCount()145     public int getCount() {
146         return mConnections.size();
147     }
148 
149     @Override
getItem(int position)150     public Object getItem(int position) {
151         return mConnections.get(position);
152     }
153 
154     @Override
getItemId(int position)155     public long getItemId(int position) {
156         return position;
157     }
158 
159     @Override
getView(int position, View convertView, ViewGroup parent)160     public View getView(int position, View convertView, ViewGroup parent) {
161         View result = convertView == null
162                 ? mLayoutInflater.inflate(R.layout.self_managed_call_list_item, parent, false)
163                 : convertView;
164         SelfManagedConnection connection = mConnections.get(position);
165         PhoneAccountHandle phoneAccountHandle = connection.getExtras().getParcelable(
166                 SelfManagedConnection.EXTRA_PHONE_ACCOUNT_HANDLE);
167         if (phoneAccountHandle.getId().equals(SelfManagedCallList.SELF_MANAGED_ACCOUNT_1)) {
168             result.setBackgroundColor(result.getContext().getColor(R.color.test_call_a_color));
169         } else {
170             result.setBackgroundColor(result.getContext().getColor(R.color.test_call_b_color));
171         }
172 
173         CallAudioState audioState = connection.getCallAudioState();
174         String audioRoute = "?";
175         if (audioState != null) {
176             switch (audioState.getRoute()) {
177                 case CallAudioState.ROUTE_BLUETOOTH:
178                     audioRoute = "BT";
179                     break;
180                 case CallAudioState.ROUTE_SPEAKER:
181                     audioRoute = "\uD83D\uDD0A";
182                     break;
183                 case CallAudioState.ROUTE_EARPIECE:
184                     audioRoute = "\uD83D\uDC42";
185                     break;
186                 case CallAudioState.ROUTE_WIRED_HEADSET:
187                     audioRoute = "\uD83D\uDD0C";
188                     break;
189                 default:
190                     audioRoute = "?";
191                     break;
192             }
193         }
194         String callType;
195         if (connection.isIncomingCall()) {
196             if (connection.isIncomingCallUiShowing()) {
197                 callType = "Incoming(our ux) ";
198             } else {
199                 callType = "Incoming(sys ux) ";
200             }
201         } else {
202             callType = "Outgoing";
203         }
204         setInfoForRow(result, phoneAccountHandle.getId(), connection.getAddress().toString(),
205                 android.telecom.Connection.stateToString(connection.getState()), audioRoute,
206                 callType, connection.getState() == android.telecom.Connection.STATE_RINGING,
207                 connection.isHoldable());
208         result.setTag(connection);
209         return result;
210     }
211 
updateConnections()212     public void updateConnections() {
213         Log.i(TAG, "updateConnections "+ mConnections.size());
214 
215         notifyDataSetChanged();
216     }
217 
setInfoForRow(View view, String accountName, String number, String status, String audioRoute, String callType, boolean isRinging, boolean isHoldable)218     private void setInfoForRow(View view, String accountName, String number,
219                                String status, String audioRoute, String callType,
220             boolean isRinging, boolean isHoldable) {
221 
222         TextView numberTextView = (TextView) view.findViewById(R.id.phoneNumber);
223         TextView statusTextView = (TextView) view.findViewById(R.id.callState);
224         View activeButton = view.findViewById(R.id.setActiveButton);
225         activeButton.setOnClickListener(mActiveListener);
226         View disconnectButton = view.findViewById(R.id.disconnectButton);
227         disconnectButton.setOnClickListener(mDisconnectListener);
228         View setHeldButton = view.findViewById(R.id.setHeldButton);
229         setHeldButton.setOnClickListener(mHeldListener);
230         View speakerButton = view.findViewById(R.id.speakerButton);
231         speakerButton.setOnClickListener(mSpeakerListener);
232         View earpieceButton = view.findViewById(R.id.earpieceButton);
233         earpieceButton.setOnClickListener(mEarpieceListener);
234         View bluetoothButton = view.findViewById(R.id.bluetoothButton);
235         bluetoothButton.setOnClickListener(mBluetoothListener);
236         View missedButton = view.findViewById(R.id.missedButton);
237         missedButton.setOnClickListener(mMissedListener);
238         missedButton.setVisibility(isRinging ? View.VISIBLE : View.GONE);
239         setHeldButton.setVisibility(!isRinging ? View.VISIBLE : View.GONE);
240         disconnectButton.setVisibility(!isRinging ? View.VISIBLE : View.GONE);
241         CheckBox holdableCheckbox = view.findViewById(R.id.holdable);
242         holdableCheckbox.setOnClickListener(mHoldableListener);
243         holdableCheckbox.setChecked(isHoldable);
244         numberTextView.setText(accountName + " - " + number + " (" + audioRoute + ")");
245         statusTextView.setText(callType + " - Status: " + status);
246     }
247 }
248