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.dialer.precall.externalreceiver; 18 19 import android.app.Activity; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.os.Bundle; 23 import android.support.annotation.Nullable; 24 import android.telecom.PhoneAccountHandle; 25 import android.telecom.TelecomManager; 26 import android.telecom.VideoProfile; 27 import com.android.dialer.callintent.CallInitiationType.Type; 28 import com.android.dialer.callintent.CallIntentBuilder; 29 import com.android.dialer.common.LogUtil; 30 import com.android.dialer.configprovider.ConfigProvider; 31 import com.android.dialer.configprovider.ConfigProviderComponent; 32 import com.android.dialer.logging.DialerImpression; 33 import com.android.dialer.logging.Logger; 34 import com.android.dialer.precall.PreCall; 35 import com.google.common.collect.ImmutableList; 36 37 /** 38 * Activity that forwards to {@link PreCall#start(Context, CallIntentBuilder)} so the pre-call flow 39 * can be initiated by external apps. This activity is exported but can only be started by apps with 40 * {@link android.Manifest.permission#CALL_PHONE}. Keyguard will be triggered if phone is locked. 41 * 42 * @see CallIntentBuilder 43 */ 44 public class LaunchPreCallActivity extends Activity { 45 46 public static final String ACTION_LAUNCH_PRE_CALL = "com.android.dialer.LAUNCH_PRE_CALL"; 47 48 public static final String EXTRA_PHONE_ACCOUNT_HANDLE = "phone_account_handle"; 49 50 public static final String EXTRA_IS_VIDEO_CALL = "is_video_call"; 51 52 public static final String EXTRA_CALL_SUBJECT = "call_subject"; 53 54 public static final String EXTRA_ALLOW_ASSISTED_DIAL = "allow_assisted_dial"; 55 56 private static final ImmutableList<String> HANDLED_INTENT_EXTRAS = 57 ImmutableList.of( 58 TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, 59 TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, 60 TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, 61 TelecomManager.EXTRA_CALL_SUBJECT, 62 EXTRA_PHONE_ACCOUNT_HANDLE, 63 EXTRA_IS_VIDEO_CALL, 64 EXTRA_CALL_SUBJECT, 65 EXTRA_ALLOW_ASSISTED_DIAL); 66 67 @Override onCreate(@ullable Bundle savedInstanceState)68 public void onCreate(@Nullable Bundle savedInstanceState) { 69 super.onCreate(savedInstanceState); 70 Logger.get(this).logImpression(DialerImpression.Type.PRECALL_INITIATED_EXTERNAL); 71 72 ConfigProvider configProvider = 73 ConfigProviderComponent.get(getApplicationContext()).getConfigProvider(); 74 Intent intent = getIntent(); 75 CallIntentBuilder builder = new CallIntentBuilder(intent.getData(), Type.EXTERNAL_INITIATION); 76 77 PhoneAccountHandle phoneAccountHandle = intent.getParcelableExtra(EXTRA_PHONE_ACCOUNT_HANDLE); 78 if (phoneAccountHandle == null) { 79 phoneAccountHandle = intent.getParcelableExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE); 80 } 81 82 builder 83 .setPhoneAccountHandle(phoneAccountHandle) 84 .setIsVideoCall(intent.getBooleanExtra(EXTRA_IS_VIDEO_CALL, false)) 85 .setCallSubject(intent.getStringExtra(EXTRA_CALL_SUBJECT)) 86 .setAllowAssistedDial( 87 intent.getBooleanExtra( 88 EXTRA_ALLOW_ASSISTED_DIAL, 89 configProvider.getBoolean("assisted_dialing_default_precall_state", false))); 90 filterExtras(intent.getExtras(), builder); 91 PreCall.start(this, builder); 92 finish(); 93 } 94 95 /** 96 * Move key-value pairs that {@link CallIntentBuilder} can handle from {@code intentExtras} to 97 * {@code builder} 98 */ filterExtras(@ullable Bundle intentExtras, CallIntentBuilder builder)99 private void filterExtras(@Nullable Bundle intentExtras, CallIntentBuilder builder) { 100 if (intentExtras == null) { 101 return; 102 } 103 Bundle bundle = new Bundle(); 104 bundle.putAll(intentExtras); 105 106 if (intentExtras.containsKey(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE)) { 107 int videoState = intentExtras.getInt(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE); 108 switch (videoState) { 109 case VideoProfile.STATE_BIDIRECTIONAL: 110 builder.setIsVideoCall(true); 111 break; 112 case VideoProfile.STATE_AUDIO_ONLY: 113 builder.setIsVideoCall(false); 114 break; 115 case VideoProfile.STATE_RX_ENABLED: 116 case VideoProfile.STATE_TX_ENABLED: 117 LogUtil.w( 118 "LaunchPreCallActivity.filterExtras", 119 "unsupported video state " + videoState + ", overriding to STATE_BIDIRECTIONAL"); 120 builder.setIsVideoCall(true); 121 break; 122 default: 123 LogUtil.w("LaunchPreCallActivity.filterExtras", "unknown video state " + videoState); 124 builder.setIsVideoCall(false); 125 } 126 } 127 128 if (intentExtras.containsKey(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS)) { 129 builder 130 .getInCallUiIntentExtras() 131 .putAll(intentExtras.getBundle(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS)); 132 } 133 134 if (intentExtras.containsKey(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE)) { 135 builder.setPhoneAccountHandle( 136 intentExtras.getParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE)); 137 } 138 139 if (intentExtras.containsKey(TelecomManager.EXTRA_CALL_SUBJECT)) { 140 builder.setCallSubject(intentExtras.getString(TelecomManager.EXTRA_CALL_SUBJECT)); 141 } 142 143 for (String handledKey : HANDLED_INTENT_EXTRAS) { 144 bundle.remove(handledKey); 145 } 146 builder.getPlaceCallExtras().putAll(bundle); 147 } 148 } 149