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 if (phoneAccountHandle.getId().equals(SelfManagedCallList.SELF_MANAGED_ACCOUNT_2)) {
170             result.setBackgroundColor(result.getContext().getColor(R.color.test_call_b_color));
171         } else {
172             result.setBackgroundColor(result.getContext().getColor(R.color.test_call_c_color));
173         }
174 
175         CallAudioState audioState = connection.getCallAudioState();
176         String audioRoute = "?";
177         if (audioState != null) {
178             switch (audioState.getRoute()) {
179                 case CallAudioState.ROUTE_BLUETOOTH:
180                     audioRoute = "BT";
181                     break;
182                 case CallAudioState.ROUTE_SPEAKER:
183                     audioRoute = "\uD83D\uDD0A";
184                     break;
185                 case CallAudioState.ROUTE_EARPIECE:
186                     audioRoute = "\uD83D\uDC42";
187                     break;
188                 case CallAudioState.ROUTE_WIRED_HEADSET:
189                     audioRoute = "\uD83D\uDD0C";
190                     break;
191                 default:
192                     audioRoute = "?";
193                     break;
194             }
195         }
196         String callType;
197         if (connection.isIncomingCall()) {
198             if (connection.isIncomingCallUiShowing()) {
199                 callType = "Incoming(our ux) ";
200             } else {
201                 callType = "Incoming(sys ux) ";
202             }
203         } else {
204             callType = "Outgoing";
205         }
206         setInfoForRow(result, phoneAccountHandle.getId(), connection.getAddress().toString(),
207                 android.telecom.Connection.stateToString(connection.getState()), audioRoute,
208                 callType, connection.getState() == android.telecom.Connection.STATE_RINGING,
209                 connection.isHoldable());
210         result.setTag(connection);
211         return result;
212     }
213 
updateConnections()214     public void updateConnections() {
215         Log.i(TAG, "updateConnections "+ mConnections.size());
216 
217         notifyDataSetChanged();
218     }
219 
setInfoForRow(View view, String accountName, String number, String status, String audioRoute, String callType, boolean isRinging, boolean isHoldable)220     private void setInfoForRow(View view, String accountName, String number,
221                                String status, String audioRoute, String callType,
222             boolean isRinging, boolean isHoldable) {
223 
224         TextView numberTextView = (TextView) view.findViewById(R.id.phoneNumber);
225         TextView statusTextView = (TextView) view.findViewById(R.id.callState);
226         View activeButton = view.findViewById(R.id.setActiveButton);
227         activeButton.setOnClickListener(mActiveListener);
228         View disconnectButton = view.findViewById(R.id.disconnectButton);
229         disconnectButton.setOnClickListener(mDisconnectListener);
230         View setHeldButton = view.findViewById(R.id.setHeldButton);
231         setHeldButton.setOnClickListener(mHeldListener);
232         View speakerButton = view.findViewById(R.id.speakerButton);
233         speakerButton.setOnClickListener(mSpeakerListener);
234         View earpieceButton = view.findViewById(R.id.earpieceButton);
235         earpieceButton.setOnClickListener(mEarpieceListener);
236         View bluetoothButton = view.findViewById(R.id.bluetoothButton);
237         bluetoothButton.setOnClickListener(mBluetoothListener);
238         View missedButton = view.findViewById(R.id.missedButton);
239         missedButton.setOnClickListener(mMissedListener);
240         missedButton.setVisibility(isRinging ? View.VISIBLE : View.GONE);
241         setHeldButton.setVisibility(!isRinging ? View.VISIBLE : View.GONE);
242         disconnectButton.setVisibility(!isRinging ? View.VISIBLE : View.GONE);
243         CheckBox holdableCheckbox = view.findViewById(R.id.holdable);
244         holdableCheckbox.setOnClickListener(mHoldableListener);
245         holdableCheckbox.setChecked(isHoldable);
246         numberTextView.setText(accountName + " - " + number + " (" + audioRoute + ")");
247         statusTextView.setText(callType + " - Status: " + status);
248     }
249 }
250