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.app.Activity; 20 import android.net.Uri; 21 import android.os.Bundle; 22 import android.telecom.ConnectionRequest; 23 import android.telecom.PhoneAccountHandle; 24 import android.telecom.TelecomManager; 25 import android.telecom.VideoProfile; 26 import android.util.Log; 27 import android.view.View; 28 import android.view.WindowManager; 29 import android.widget.Button; 30 import android.widget.CheckBox; 31 import android.widget.EditText; 32 import android.widget.ListView; 33 import android.widget.RadioButton; 34 import android.widget.TextView; 35 import android.widget.Toast; 36 37 import com.android.server.telecom.testapps.R; 38 39 import java.util.Objects; 40 41 /** 42 * Provides a sample third-party calling app UX which implements the self managed connection service 43 * APIs. 44 */ 45 public class SelfManagedCallingActivity extends Activity { 46 private static final String TAG = "SelfMgCallActivity"; 47 private SelfManagedCallList mCallList = SelfManagedCallList.getInstance(); 48 private CheckBox mCheckIfPermittedBeforeCalling; 49 private Button mPlaceOutgoingCallButton; 50 private Button mPlaceIncomingCallButton; 51 private Button mHandoverFrom; 52 private RadioButton mUseAcct1Button; 53 private RadioButton mUseAcct2Button; 54 private CheckBox mHoldableCheckbox; 55 private CheckBox mVideoCallCheckbox; 56 private EditText mNumber; 57 private ListView mListView; 58 private TextView mHasFocus; 59 60 private SelfManagedCallListAdapter mListAdapter; 61 62 private SelfManagedCallList.Listener mCallListListener = new SelfManagedCallList.Listener() { 63 @Override 64 public void onCreateIncomingConnectionFailed(ConnectionRequest request) { 65 Log.i(TAG, "onCreateIncomingConnectionFailed " + request); 66 Toast.makeText(SelfManagedCallingActivity.this, 67 R.string.incomingCallNotPermittedCS , Toast.LENGTH_SHORT).show(); 68 }; 69 70 @Override 71 public void onCreateOutgoingConnectionFailed(ConnectionRequest request) { 72 Log.i(TAG, "onCreateOutgoingConnectionFailed " + request); 73 Toast.makeText(SelfManagedCallingActivity.this, 74 R.string.outgoingCallNotPermittedCS , Toast.LENGTH_SHORT).show(); 75 }; 76 77 @Override 78 public void onConnectionListChanged() { 79 Log.i(TAG, "onConnectionListChanged"); 80 mListAdapter.updateConnections(); 81 }; 82 83 @Override 84 public void onConnectionServiceFocusLost() { 85 mHasFocus.setText("\uD83D\uDC4E No Focus \uD83D\uDC4E"); 86 }; 87 88 @Override 89 public void onConnectionServiceFocusGained() { 90 mHasFocus.setText("\uD83D\uDC4D Has Focus \uD83D\uDC4D"); 91 }; 92 }; 93 94 @Override onCreate(Bundle savedInstanceState)95 public void onCreate(Bundle savedInstanceState) { 96 super.onCreate(savedInstanceState); 97 int flags = 98 WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED 99 | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON 100 | WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES; 101 102 getWindow().addFlags(flags); 103 setContentView(R.layout.self_managed_sample_main); 104 mCheckIfPermittedBeforeCalling = (CheckBox) findViewById( 105 R.id.checkIfPermittedBeforeCalling); 106 mPlaceOutgoingCallButton = (Button) findViewById(R.id.placeOutgoingCallButton); 107 mPlaceOutgoingCallButton.setOnClickListener(new View.OnClickListener() { 108 @Override 109 public void onClick(View v) { 110 placeOutgoingCall(); 111 } 112 }); 113 mPlaceIncomingCallButton = (Button) findViewById(R.id.placeIncomingCallButton); 114 mPlaceIncomingCallButton.setOnClickListener(new View.OnClickListener() { 115 @Override 116 public void onClick(View v) { 117 placeIncomingCall(false /* isHandoverFrom */); 118 } 119 }); 120 mHandoverFrom = (Button) findViewById(R.id.handoverFrom); 121 mHandoverFrom.setOnClickListener((v -> { 122 placeIncomingCall(true /* isHandoverFrom */); 123 })); 124 125 mUseAcct1Button = findViewById(R.id.useAcct1Button); 126 mUseAcct2Button = findViewById(R.id.useAcct2Button); 127 mHasFocus = findViewById(R.id.hasFocus); 128 mVideoCallCheckbox = findViewById(R.id.videoCall); 129 mHoldableCheckbox = findViewById(R.id.holdable); 130 mNumber = (EditText) findViewById(R.id.phoneNumber); 131 mListView = (ListView) findViewById(R.id.callList); 132 mCallList.setListener(mCallListListener); 133 mCallList.registerPhoneAccounts(this); 134 mListAdapter = new SelfManagedCallListAdapter(getLayoutInflater(), 135 mCallList.getConnections()); 136 mListView.setAdapter(mListAdapter); 137 Log.i(TAG, "onCreate - mCallList id " + Objects.hashCode(mCallList)); 138 } 139 getSelectedPhoneAccountHandle()140 private PhoneAccountHandle getSelectedPhoneAccountHandle() { 141 if (mUseAcct1Button.isChecked()) { 142 return mCallList.getPhoneAccountHandle(SelfManagedCallList.SELF_MANAGED_ACCOUNT_1); 143 } else if (mUseAcct2Button.isChecked()) { 144 return mCallList.getPhoneAccountHandle(SelfManagedCallList.SELF_MANAGED_ACCOUNT_2); 145 } 146 return null; 147 } 148 placeOutgoingCall()149 private void placeOutgoingCall() { 150 TelecomManager tm = TelecomManager.from(this); 151 PhoneAccountHandle phoneAccountHandle = getSelectedPhoneAccountHandle(); 152 153 if (mCheckIfPermittedBeforeCalling.isChecked()) { 154 if (!tm.isOutgoingCallPermitted(phoneAccountHandle)) { 155 Toast.makeText(this, R.string.outgoingCallNotPermitted , Toast.LENGTH_SHORT).show(); 156 return; 157 } 158 } 159 160 Bundle extras = new Bundle(); 161 extras.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, 162 getSelectedPhoneAccountHandle()); 163 if (mVideoCallCheckbox.isChecked()) { 164 extras.putInt(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, 165 VideoProfile.STATE_BIDIRECTIONAL); 166 } 167 Bundle clientExtras = new Bundle(); 168 clientExtras.putBoolean(SelfManagedConnectionService.EXTRA_HOLDABLE, 169 mHoldableCheckbox.isChecked()); 170 extras.putBundle(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, clientExtras); 171 tm.placeCall(Uri.parse(mNumber.getText().toString()), extras); 172 } 173 placeIncomingCall(boolean isHandoverFrom)174 private void placeIncomingCall(boolean isHandoverFrom) { 175 TelecomManager tm = TelecomManager.from(this); 176 PhoneAccountHandle phoneAccountHandle = getSelectedPhoneAccountHandle(); 177 178 if (mCheckIfPermittedBeforeCalling.isChecked()) { 179 if (!tm.isIncomingCallPermitted(phoneAccountHandle)) { 180 Toast.makeText(this, R.string.incomingCallNotPermitted , Toast.LENGTH_SHORT).show(); 181 return; 182 } 183 } 184 185 Bundle extras = new Bundle(); 186 extras.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, 187 Uri.parse(mNumber.getText().toString())); 188 extras.putBoolean(SelfManagedConnectionService.EXTRA_HOLDABLE, 189 mHoldableCheckbox.isChecked()); 190 if (mVideoCallCheckbox.isChecked()) { 191 extras.putInt(TelecomManager.EXTRA_INCOMING_VIDEO_STATE, 192 VideoProfile.STATE_BIDIRECTIONAL); 193 } 194 if (isHandoverFrom) { 195 extras.putBoolean(TelecomManager.EXTRA_IS_HANDOVER, true); 196 } 197 tm.addNewIncomingCall(getSelectedPhoneAccountHandle(), extras); 198 } 199 }