• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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.app.Activity;
20 import android.bluetooth.BluetoothDevice;
21 import android.content.Intent;
22 import android.os.Bundle;
23 import android.telecom.Call;
24 import android.telecom.CallAudioState;
25 import android.telecom.PhoneAccount;
26 import android.telecom.PhoneAccountHandle;
27 import android.telecom.TelecomManager;
28 import android.telecom.VideoProfile;
29 import android.util.Log;
30 import android.view.View;
31 import android.view.View.OnClickListener;
32 import android.view.ViewGroup;
33 import android.widget.ArrayAdapter;
34 import android.widget.ListView;
35 import android.widget.Spinner;
36 import android.widget.TextView;
37 import android.widget.Toast;
38 
39 import java.util.Collection;
40 import java.util.List;
41 import java.util.Optional;
42 
43 public class TestInCallUI extends Activity {
44     private class BluetoothDeviceAdapter extends ArrayAdapter<BluetoothDevice> {
BluetoothDeviceAdapter()45         public BluetoothDeviceAdapter() {
46             super(TestInCallUI.this, android.R.layout.simple_spinner_item);
47             setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
48         }
49 
50         @Override
getView(int position, View convertView, ViewGroup parent)51         public View getView(int position, View convertView, ViewGroup parent) {
52             BluetoothDevice info = getItem(position);
53             TextView result = new TextView(TestInCallUI.this);
54             result.setText(info.getName());
55             return result;
56         }
57 
update(Collection<BluetoothDevice> devices)58         public void update(Collection<BluetoothDevice> devices) {
59             clear();
60             addAll(devices);
61         }
62     }
63 
64     public static TestInCallUI sInstance;
65     private ListView mListView;
66     private TestCallList mCallList;
67     private Spinner mBtDeviceList;
68     private BluetoothDeviceAdapter mBluetoothDeviceAdapter;
69     private TextView mCurrentRouteDisplay;
70 
71     /** ${inheritDoc} */
72     @Override
onCreate(Bundle savedInstanceState)73     protected void onCreate(Bundle savedInstanceState) {
74         super.onCreate(savedInstanceState);
75         sInstance = this;
76 
77         setContentView(R.layout.incall_screen);
78 
79         mListView = (ListView) findViewById(R.id.callListView);
80         mListView.setAdapter(new CallListAdapter(this));
81         mListView.setVisibility(View.VISIBLE);
82 
83         mCallList = TestCallList.getInstance();
84         mCallList.addListener(new TestCallList.Listener() {
85             @Override
86             public void onCallRemoved(Call call) {
87                 if (mCallList.size() == 0) {
88                     Log.i(TestInCallUI.class.getSimpleName(), "Ending the incall UI");
89                     finish();
90                 }
91             }
92 
93             @Override
94             public void onRttStarted(Call call) {
95                 Toast.makeText(TestInCallUI.this, "RTT now enabled", Toast.LENGTH_SHORT).show();
96             }
97 
98             @Override
99             public void onRttStopped(Call call) {
100                 Toast.makeText(TestInCallUI.this, "RTT now disabled", Toast.LENGTH_SHORT).show();
101             }
102 
103             @Override
104             public void onRttInitiationFailed(Call call, int reason) {
105                 Toast.makeText(TestInCallUI.this, String.format("RTT failed to init: %d", reason),
106                         Toast.LENGTH_SHORT).show();
107             }
108 
109             @Override
110             public void onRttRequest(Call call, int id) {
111                 Toast.makeText(TestInCallUI.this, String.format("RTT request: %d", id),
112                         Toast.LENGTH_SHORT).show();
113             }
114         });
115 
116         View endCallButton = findViewById(R.id.end_call_button);
117         View holdButton = findViewById(R.id.hold_button);
118         View muteButton = findViewById(R.id.mute_button);
119         View rttIfaceButton = findViewById(R.id.rtt_iface_button);
120         View answerButton = findViewById(R.id.answer_button);
121         View startRttButton = findViewById(R.id.start_rtt_button);
122         View acceptRttButton = findViewById(R.id.accept_rtt_button);
123         View handoverButton = findViewById(R.id.request_handover_button);
124         View setBtDeviceButton = findViewById(R.id.set_bt_device_button);
125         View earpieceButton = findViewById(R.id.earpiece_button);
126         View speakerButton = findViewById(R.id.speaker_button);
127         mBtDeviceList = findViewById(R.id.available_bt_devices);
128         mBluetoothDeviceAdapter = new BluetoothDeviceAdapter();
129         mBtDeviceList.setAdapter(mBluetoothDeviceAdapter);
130         mCurrentRouteDisplay = findViewById(R.id.current_audio_route);
131 
132         endCallButton.setOnClickListener(new OnClickListener() {
133             @Override
134             public void onClick(View view) {
135                 Call call = mCallList.getCall(0);
136                 if (call != null) {
137                     call.disconnect();
138                 }
139             }
140         });
141         holdButton.setOnClickListener(new OnClickListener() {
142             @Override
143             public void onClick(View view) {
144                 Call call = mCallList.getCall(0);
145                 if (call != null) {
146                     if (call.getState() == Call.STATE_HOLDING) {
147                         call.unhold();
148                     } else {
149                         call.hold();
150                     }
151                 }
152             }
153         });
154         muteButton.setOnClickListener(new OnClickListener() {
155             @Override
156             public void onClick(View view) {
157                 Call call = mCallList.getCall(0);
158                 if (call != null) {
159 
160                 }
161             }
162         });
163 
164         rttIfaceButton.setOnClickListener((view) -> {
165             Call call = mCallList.getCall(0);
166             if (call.isRttActive()) {
167                 Intent intent = new Intent(Intent.ACTION_MAIN);
168                 intent.setClass(this, TestRttActivity.class);
169                 startActivity(intent);
170             }
171         });
172 
173         answerButton.setOnClickListener(view -> {
174             Call call = mCallList.getCall(0);
175             if (call.getState() == Call.STATE_RINGING) {
176                 call.answer(VideoProfile.STATE_AUDIO_ONLY);
177             }
178         });
179 
180         startRttButton.setOnClickListener(view -> {
181             Call call = mCallList.getCall(0);
182             if (!call.isRttActive()) {
183                 call.sendRttRequest();
184             }
185         });
186 
187         earpieceButton.setOnClickListener(view -> {
188             TestInCallServiceImpl.sInstance.setAudioRoute(CallAudioState.ROUTE_WIRED_OR_EARPIECE);
189         });
190 
191         speakerButton.setOnClickListener(view -> {
192             TestInCallServiceImpl.sInstance.setAudioRoute(CallAudioState.ROUTE_SPEAKER);
193         });
194 
195         setBtDeviceButton.setOnClickListener(view -> {
196             if (mBtDeviceList.getSelectedItem() != null
197                     && TestInCallServiceImpl.sInstance != null) {
198                 TestInCallServiceImpl.sInstance.requestBluetoothAudio(
199                         (BluetoothDevice) mBtDeviceList.getSelectedItem());
200             }
201         });
202 
203         acceptRttButton.setOnClickListener(view -> {
204             Call call = mCallList.getCall(0);
205             if (!call.isRttActive()) {
206                 call.respondToRttRequest(mCallList.getLastRttRequestId(), true);
207             }
208         });
209 
210         handoverButton.setOnClickListener((v) -> {
211             Call call = mCallList.getCall(0);
212             Bundle extras = new Bundle();
213             extras.putParcelable(Call.EXTRA_HANDOVER_PHONE_ACCOUNT_HANDLE,
214                     getHandoverToPhoneAccountHandle());
215             extras.putInt(Call.EXTRA_HANDOVER_VIDEO_STATE, VideoProfile.STATE_BIDIRECTIONAL);
216             call.sendCallEvent(Call.EVENT_REQUEST_HANDOVER, extras);
217         });
218     }
219 
updateCallAudioState(CallAudioState cas)220     public void updateCallAudioState(CallAudioState cas) {
221         mBluetoothDeviceAdapter.update(cas.getSupportedBluetoothDevices());
222         String routeText;
223         switch (cas.getRoute()) {
224             case CallAudioState.ROUTE_EARPIECE:
225                 routeText = "Earpiece";
226                 break;
227             case CallAudioState.ROUTE_SPEAKER:
228                 routeText = "Speaker";
229                 break;
230             case CallAudioState.ROUTE_WIRED_HEADSET:
231                 routeText = "Wired";
232                 break;
233             case CallAudioState.ROUTE_BLUETOOTH:
234                 BluetoothDevice activeDevice = cas.getActiveBluetoothDevice();
235                 routeText = activeDevice == null ? "null bt" : activeDevice.getName();
236                 break;
237             default:
238                 routeText = "unknown: " + cas.getRoute();
239         }
240         mCurrentRouteDisplay.setText(routeText);
241     }
242 
243     /** ${inheritDoc} */
244     @Override
onDestroy()245     protected void onDestroy() {
246         sInstance = null;
247         super.onDestroy();
248     }
249 
250     @Override
onPause()251     protected void onPause() {
252         super.onPause();
253     }
254 
255     @Override
onStart()256     protected void onStart() {
257         super.onStart();
258     }
259 
260     @Override
onResume()261     protected void onResume() {
262         super.onResume();
263     }
264 
getHandoverToPhoneAccountHandle()265     private PhoneAccountHandle getHandoverToPhoneAccountHandle() {
266         TelecomManager tm = TelecomManager.from(this);
267 
268         List<PhoneAccountHandle> handles = tm.getAllPhoneAccountHandles();
269         Optional<PhoneAccountHandle> found = handles.stream().filter(h -> {
270             PhoneAccount account = tm.getPhoneAccount(h);
271             Bundle extras = account.getExtras();
272             return extras != null && extras.getBoolean(PhoneAccount.EXTRA_SUPPORTS_HANDOVER_TO);
273         }).findFirst();
274         PhoneAccountHandle foundHandle = found.orElse(null);
275         Log.i(TestInCallUI.class.getSimpleName(), "getHandoverToPhoneAccountHandle() = " +
276             foundHandle);
277         return foundHandle;
278     }
279 }
280