Loading AndroidManifest.xml +0 −8 Original line number Original line Diff line number Diff line Loading @@ -291,14 +291,6 @@ android:process=":ui"> android:process=":ui"> </activity> </activity> <activity android:name=".ui.CallRedirectionConfirmDialogActivity" android:configChanges="orientation|screenSize|keyboardHidden" android:excludeFromRecents="true" android:launchMode="singleInstance" android:theme="@style/Theme.Telecomm.Transparent" android:process=":ui"> </activity> <activity android:name=".ui.CallRedirectionTimeoutDialogActivity" <activity android:name=".ui.CallRedirectionTimeoutDialogActivity" android:configChanges="orientation|screenSize|keyboardHidden" android:configChanges="orientation|screenSize|keyboardHidden" android:excludeFromRecents="true" android:excludeFromRecents="true" Loading src/com/android/server/telecom/CallsManager.java +115 −11 Original line number Original line Diff line number Diff line Loading @@ -31,15 +31,19 @@ import static android.telecom.TelecomManager.VERY_SHORT_CALL_TIME_MS; import android.Manifest; import android.Manifest; import android.annotation.NonNull; import android.annotation.NonNull; import android.app.ActivityManager; import android.app.ActivityManager; import android.app.AlertDialog; import android.app.KeyguardManager; import android.app.KeyguardManager; import android.content.BroadcastReceiver; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ComponentName; import android.content.Context; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.Intent; import android.content.IntentFilter; import android.content.IntentFilter; import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.content.pm.UserInfo; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.media.AudioManager; import android.media.AudioManager; import android.media.AudioSystem; import android.media.AudioSystem; import android.media.ToneGenerator; import android.media.ToneGenerator; Loading Loading @@ -85,6 +89,11 @@ import android.util.Pair; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting; import android.telecom.CallerInfo; import android.telecom.CallerInfo; import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; import android.widget.Button; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.IndentingPrintWriter; import com.android.server.telecom.bluetooth.BluetoothRouteManager; import com.android.server.telecom.bluetooth.BluetoothRouteManager; import com.android.server.telecom.bluetooth.BluetoothStateReceiver; import com.android.server.telecom.bluetooth.BluetoothStateReceiver; Loading @@ -99,9 +108,9 @@ import com.android.server.telecom.callfiltering.IncomingCallFilterGraph; import com.android.server.telecom.callfiltering.NewCallScreeningServiceFilter; import com.android.server.telecom.callfiltering.NewCallScreeningServiceFilter; import com.android.server.telecom.callredirection.CallRedirectionProcessor; import com.android.server.telecom.callredirection.CallRedirectionProcessor; import com.android.server.telecom.components.ErrorDialogActivity; import com.android.server.telecom.components.ErrorDialogActivity; import com.android.server.telecom.components.TelecomBroadcastReceiver; import com.android.server.telecom.settings.BlockedNumbersUtil; import com.android.server.telecom.settings.BlockedNumbersUtil; import com.android.server.telecom.ui.AudioProcessingNotification; import com.android.server.telecom.ui.AudioProcessingNotification; import com.android.server.telecom.ui.CallRedirectionConfirmDialogActivity; import com.android.server.telecom.ui.CallRedirectionTimeoutDialogActivity; import com.android.server.telecom.ui.CallRedirectionTimeoutDialogActivity; import com.android.server.telecom.ui.ConfirmCallDialogActivity; import com.android.server.telecom.ui.ConfirmCallDialogActivity; import com.android.server.telecom.ui.DisconnectedCallNotifier; import com.android.server.telecom.ui.DisconnectedCallNotifier; Loading Loading @@ -2028,23 +2037,106 @@ public class CallsManager extends Call.ListenerBase + "callId=%s, callRedirectionAppName=%s", + "callId=%s, callRedirectionAppName=%s", call.getId(), callRedirectionApp); call.getId(), callRedirectionApp); Intent confirmIntent = new Intent(mContext, showRedirectionDialog(call.getId()); CallRedirectionConfirmDialogActivity.class); confirmIntent.putExtra( CallRedirectionConfirmDialogActivity.EXTRA_REDIRECTION_OUTGOING_CALL_ID, call.getId()); confirmIntent.putExtra(CallRedirectionConfirmDialogActivity.EXTRA_REDIRECTION_APP_NAME, mRoleManagerAdapter.getApplicationLabelForPackageName(callRedirectionApp)); confirmIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mContext.startActivityAsUser(confirmIntent, UserHandle.CURRENT); } else { } else { call.setTargetPhoneAccount(phoneAccountHandle); call.setTargetPhoneAccount(phoneAccountHandle); placeOutgoingCall(call, handle, gatewayInfo, speakerphoneOn, videoState); placeOutgoingCall(call, handle, gatewayInfo, speakerphoneOn, videoState); } } } } /** * Shows the call redirection confirmation dialog. This is explicitly done here instead of in * an activity class such as {@link ConfirmCallDialogActivity}. This was originally done with * an activity class, however due to the fact that the InCall UI is being spun up at the same * time as the dialog activity, there is a potential race condition where the InCall UI will * often be shown instead of the dialog. Activity manager chooses not to show the redirection * dialog in that case since the new top activity from dialer is going to show. * By showing the dialog here we're able to set the dialog's window type to * {@link WindowManager.LayoutParams#TYPE_SYSTEM_ALERT} which guarantees it shows above other * content on the screen. * @param callId The ID of the call to show the redirection dialog for. */ private void showRedirectionDialog(@NonNull String callId) { AlertDialog confirmDialog = new AlertDialog.Builder(mContext).create(); LayoutInflater layoutInflater = LayoutInflater.from(mContext); View dialogView = layoutInflater.inflate(R.layout.call_redirection_confirm_dialog, null); Button buttonFirstLine = (Button) dialogView.findViewById(R.id.buttonFirstLine); buttonFirstLine.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent proceedWithoutRedirectedCall = new Intent( TelecomBroadcastIntentProcessor.ACTION_PLACE_UNREDIRECTED_CALL, null, mContext, TelecomBroadcastReceiver.class); proceedWithoutRedirectedCall.putExtra( TelecomBroadcastIntentProcessor.EXTRA_REDIRECTION_OUTGOING_CALL_ID, callId); mContext.sendBroadcast(proceedWithoutRedirectedCall); confirmDialog.dismiss(); } }); Button buttonSecondLine = (Button) dialogView.findViewById(R.id.buttonSecondLine); buttonSecondLine.setText(mContext.getText( R.string.alert_place_outgoing_call_with_redirection)); buttonSecondLine.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent proceedWithRedirectedCall = new Intent( TelecomBroadcastIntentProcessor.ACTION_PLACE_REDIRECTED_CALL, null, mContext, TelecomBroadcastReceiver.class); proceedWithRedirectedCall.putExtra( TelecomBroadcastIntentProcessor.EXTRA_REDIRECTION_OUTGOING_CALL_ID, callId); mContext.sendBroadcast(proceedWithRedirectedCall); confirmDialog.dismiss(); } }); Button buttonThirdLine = (Button) dialogView.findViewById(R.id.buttonThirdLine); buttonThirdLine.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { cancelRedirection(callId); confirmDialog.dismiss(); } }); confirmDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { @Override public void onCancel(DialogInterface dialog) { cancelRedirection(callId); confirmDialog.dismiss(); } }); confirmDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); confirmDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); confirmDialog.setCancelable(false); confirmDialog.setCanceledOnTouchOutside(false); confirmDialog.setView(dialogView); confirmDialog.show(); } /** * Signals to Telecom that redirection of the call is to be cancelled. */ private void cancelRedirection(String callId) { Intent cancelRedirectedCall = new Intent( TelecomBroadcastIntentProcessor.ACTION_CANCEL_REDIRECTED_CALL, null, mContext, TelecomBroadcastReceiver.class); cancelRedirectedCall.putExtra( TelecomBroadcastIntentProcessor.EXTRA_REDIRECTION_OUTGOING_CALL_ID, callId); mContext.sendBroadcastAsUser(cancelRedirectedCall, UserHandle.CURRENT); } public void processRedirectedOutgoingCallAfterUserInteraction(String callId, String action) { public void processRedirectedOutgoingCallAfterUserInteraction(String callId, String action) { Log.i(this, "processRedirectedOutgoingCallAfterUserInteraction for Call ID %s", callId); Log.i(this, "processRedirectedOutgoingCallAfterUserInteraction for Call ID %s, action=%s", callId, action); if (mPendingRedirectedOutgoingCall != null && mPendingRedirectedOutgoingCall.getId() if (mPendingRedirectedOutgoingCall != null && mPendingRedirectedOutgoingCall.getId() .equals(callId)) { .equals(callId)) { if (action.equals(TelecomBroadcastIntentProcessor.ACTION_PLACE_REDIRECTED_CALL)) { if (action.equals(TelecomBroadcastIntentProcessor.ACTION_PLACE_REDIRECTED_CALL)) { Loading Loading @@ -4383,6 +4475,18 @@ public class CallsManager extends Call.ListenerBase pw.println(mPendingCall.getId()); pw.println(mPendingCall.getId()); } } if (mPendingRedirectedOutgoingCallInfo.size() > 0) { pw.print("mPendingRedirectedOutgoingCallInfo:"); pw.println(mPendingRedirectedOutgoingCallInfo.keySet().stream().collect( Collectors.joining(", "))); } if (mPendingUnredirectedOutgoingCallInfo.size() > 0) { pw.print("mPendingUnredirectedOutgoingCallInfo:"); pw.println(mPendingUnredirectedOutgoingCallInfo.keySet().stream().collect( Collectors.joining(", "))); } if (mCallAudioManager != null) { if (mCallAudioManager != null) { pw.println("mCallAudioManager:"); pw.println("mCallAudioManager:"); pw.increaseIndent(); pw.increaseIndent(); Loading src/com/android/server/telecom/TelecomBroadcastIntentProcessor.java +13 −13 Original line number Original line Diff line number Diff line Loading @@ -24,7 +24,6 @@ import android.os.UserHandle; import android.telecom.Log; import android.telecom.Log; import android.widget.Toast; import android.widget.Toast; import com.android.server.telecom.ui.CallRedirectionConfirmDialogActivity; import com.android.server.telecom.ui.ConfirmCallDialogActivity; import com.android.server.telecom.ui.ConfirmCallDialogActivity; import com.android.server.telecom.ui.DisconnectedCallNotifier; import com.android.server.telecom.ui.DisconnectedCallNotifier; Loading Loading @@ -80,27 +79,31 @@ public final class TelecomBroadcastIntentProcessor { "com.android.server.telecom.CANCEL_CALL"; "com.android.server.telecom.CANCEL_CALL"; /** /** * The action used to proceed with a redirected call being confirmed via * The action used to proceed with a redirected call being confirmed via the call redirection * {@link com.android.server.telecom.ui.CallRedirectionConfirmDialogActivity}. * confirmation dialog. */ */ public static final String ACTION_PLACE_REDIRECTED_CALL = public static final String ACTION_PLACE_REDIRECTED_CALL = "com.android.server.telecom.PROCEED_WITH_REDIRECTED_CALL"; "com.android.server.telecom.PROCEED_WITH_REDIRECTED_CALL"; /** /** * The action used to confirm to proceed the call without redirection via * The action used to confirm to proceed the call without redirection via the call redirection * {@link com.android.server.telecom.ui.CallRedirectionConfirmDialogActivity}. * confirmation dialog. */ */ public static final String ACTION_PLACE_UNREDIRECTED_CALL = public static final String ACTION_PLACE_UNREDIRECTED_CALL = "com.android.server.telecom.PROCEED_WITH_UNREDIRECTED_CALL"; "com.android.server.telecom.PROCEED_WITH_UNREDIRECTED_CALL"; /** /** * The action used to cancel a redirected call being confirmed via * The action used to cancel a redirected call being confirmed via the call redirection * {@link com.android.server.telecom.ui.CallRedirectionConfirmDialogActivity}. * confirmation dialog. */ */ public static final String ACTION_CANCEL_REDIRECTED_CALL = public static final String ACTION_CANCEL_REDIRECTED_CALL = "com.android.server.telecom.CANCEL_REDIRECTED_CALL"; "com.android.server.telecom.CANCEL_REDIRECTED_CALL"; public static final String EXTRA_USERHANDLE = "userhandle"; public static final String EXTRA_USERHANDLE = "userhandle"; public static final String EXTRA_REDIRECTION_OUTGOING_CALL_ID = "android.telecom.extra.REDIRECTION_OUTGOING_CALL_ID"; public static final String EXTRA_REDIRECTION_APP_NAME = "android.telecom.extra.REDIRECTION_APP_NAME"; private final Context mContext; private final Context mContext; private final CallsManager mCallsManager; private final CallsManager mCallsManager; Loading Loading @@ -214,8 +217,7 @@ public final class TelecomBroadcastIntentProcessor { Log.startSession("TBIP.aPRC"); Log.startSession("TBIP.aPRC"); try { try { mCallsManager.processRedirectedOutgoingCallAfterUserInteraction( mCallsManager.processRedirectedOutgoingCallAfterUserInteraction( intent.getStringExtra(CallRedirectionConfirmDialogActivity intent.getStringExtra(EXTRA_REDIRECTION_OUTGOING_CALL_ID), .EXTRA_REDIRECTION_OUTGOING_CALL_ID), ACTION_PLACE_REDIRECTED_CALL); ACTION_PLACE_REDIRECTED_CALL); } finally { } finally { Log.endSession(); Log.endSession(); Loading @@ -224,8 +226,7 @@ public final class TelecomBroadcastIntentProcessor { Log.startSession("TBIP.aPUC"); Log.startSession("TBIP.aPUC"); try { try { mCallsManager.processRedirectedOutgoingCallAfterUserInteraction( mCallsManager.processRedirectedOutgoingCallAfterUserInteraction( intent.getStringExtra(CallRedirectionConfirmDialogActivity intent.getStringExtra(EXTRA_REDIRECTION_OUTGOING_CALL_ID), .EXTRA_REDIRECTION_OUTGOING_CALL_ID), ACTION_PLACE_UNREDIRECTED_CALL); ACTION_PLACE_UNREDIRECTED_CALL); } finally { } finally { Log.endSession(); Log.endSession(); Loading @@ -234,8 +235,7 @@ public final class TelecomBroadcastIntentProcessor { Log.startSession("TBIP.aCRC"); Log.startSession("TBIP.aCRC"); try { try { mCallsManager.processRedirectedOutgoingCallAfterUserInteraction( mCallsManager.processRedirectedOutgoingCallAfterUserInteraction( intent.getStringExtra(CallRedirectionConfirmDialogActivity intent.getStringExtra(EXTRA_REDIRECTION_OUTGOING_CALL_ID), .EXTRA_REDIRECTION_OUTGOING_CALL_ID), ACTION_CANCEL_REDIRECTED_CALL); ACTION_CANCEL_REDIRECTED_CALL); } finally { } finally { Log.endSession(); Log.endSession(); Loading src/com/android/server/telecom/ui/CallRedirectionConfirmDialogActivity.javadeleted 100644 → 0 +0 −161 Original line number Original line Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License */ package com.android.server.telecom.ui; import com.android.server.telecom.R; import com.android.server.telecom.TelecomBroadcastIntentProcessor; import com.android.server.telecom.components.TelecomBroadcastReceiver; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.os.Bundle; import android.telecom.Log; import android.view.LayoutInflater; import android.view.View.OnClickListener; import android.view.View; import android.widget.Button; /** * Dialog activity used when there is an ongoing call redirected by the call redirection service. * The dialog prompts the user to see if they want to place the redirected outgoing call. */ public class CallRedirectionConfirmDialogActivity extends Activity { public static final String EXTRA_REDIRECTION_OUTGOING_CALL_ID = "android.telecom.extra.REDIRECTION_OUTGOING_CALL_ID"; public static final String EXTRA_REDIRECTION_APP_NAME = "android.telecom.extra.REDIRECTION_APP_NAME"; private String mCallId; private AlertDialog mConfirmDialog; /** * Tracks whether the activity has stopped due to a loss of focus (e.g. use hitting the home * button) or whether its going to stop because a button in the dialog was pressed. */ private boolean mHasLostFocus = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.i(this, "CallRedirectionConfirmDialogActivity onCreate."); final CharSequence redirectionAppName = getIntent().getStringExtra( EXTRA_REDIRECTION_APP_NAME); mCallId = getIntent().getStringExtra(EXTRA_REDIRECTION_OUTGOING_CALL_ID); showDialog(redirectionAppName); } @Override protected void onStop() { super.onStop(); if (mHasLostFocus) { Log.i(this, "onStop: dialog lost focus; canceling redirection for call %s", mCallId); mConfirmDialog.dismiss(); cancelRedirection(); } } private void showDialog(final CharSequence redirectionAppName) { Log.i(this, "showDialog: confirming redirection with %s", redirectionAppName); mConfirmDialog = new AlertDialog.Builder(this).create(); LayoutInflater layoutInflater = LayoutInflater.from(this); View dialogView = layoutInflater.inflate(R.layout.call_redirection_confirm_dialog, null); Button buttonFirstLine = (Button) dialogView.findViewById(R.id.buttonFirstLine); buttonFirstLine.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent proceedWithoutRedirectedCall = new Intent( TelecomBroadcastIntentProcessor.ACTION_PLACE_UNREDIRECTED_CALL, null, CallRedirectionConfirmDialogActivity.this, TelecomBroadcastReceiver.class); proceedWithoutRedirectedCall.putExtra(EXTRA_REDIRECTION_OUTGOING_CALL_ID, mCallId); sendBroadcast(proceedWithoutRedirectedCall); mConfirmDialog.dismiss(); mHasLostFocus = false; finish(); } }); Button buttonSecondLine = (Button) dialogView.findViewById(R.id.buttonSecondLine); buttonSecondLine.setText(getString(R.string.alert_place_outgoing_call_with_redirection, redirectionAppName)); buttonSecondLine.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent proceedWithRedirectedCall = new Intent( TelecomBroadcastIntentProcessor .ACTION_PLACE_REDIRECTED_CALL, null, CallRedirectionConfirmDialogActivity.this, TelecomBroadcastReceiver.class); proceedWithRedirectedCall.putExtra(EXTRA_REDIRECTION_OUTGOING_CALL_ID, mCallId); sendBroadcast(proceedWithRedirectedCall); mConfirmDialog.dismiss(); mHasLostFocus = false; finish(); } }); Button buttonThirdLine = (Button) dialogView.findViewById(R.id.buttonThirdLine); buttonThirdLine.setOnClickListener(new OnClickListener() { public void onClick(View v) { Intent cancelRedirectedCall = new Intent( TelecomBroadcastIntentProcessor.ACTION_CANCEL_REDIRECTED_CALL, null, CallRedirectionConfirmDialogActivity.this, TelecomBroadcastReceiver.class); cancelRedirectedCall.putExtra(EXTRA_REDIRECTION_OUTGOING_CALL_ID, mCallId); sendBroadcast(cancelRedirectedCall); mConfirmDialog.dismiss(); mHasLostFocus = false; finish(); } }); mConfirmDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { @Override public void onCancel(DialogInterface dialog) { cancelRedirection(); dialog.dismiss(); mHasLostFocus = false; finish(); } }); mConfirmDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); mConfirmDialog.setCancelable(false); mConfirmDialog.setCanceledOnTouchOutside(false); mConfirmDialog.setView(dialogView); mConfirmDialog.show(); } /** * Signals to Telecom that redirection of the call is to be cancelled. */ private void cancelRedirection() { Intent cancelRedirectedCall = new Intent( TelecomBroadcastIntentProcessor.ACTION_CANCEL_REDIRECTED_CALL, null, CallRedirectionConfirmDialogActivity.this, TelecomBroadcastReceiver.class); cancelRedirectedCall.putExtra(EXTRA_REDIRECTION_OUTGOING_CALL_ID, mCallId); sendBroadcast(cancelRedirectedCall); } } Loading
AndroidManifest.xml +0 −8 Original line number Original line Diff line number Diff line Loading @@ -291,14 +291,6 @@ android:process=":ui"> android:process=":ui"> </activity> </activity> <activity android:name=".ui.CallRedirectionConfirmDialogActivity" android:configChanges="orientation|screenSize|keyboardHidden" android:excludeFromRecents="true" android:launchMode="singleInstance" android:theme="@style/Theme.Telecomm.Transparent" android:process=":ui"> </activity> <activity android:name=".ui.CallRedirectionTimeoutDialogActivity" <activity android:name=".ui.CallRedirectionTimeoutDialogActivity" android:configChanges="orientation|screenSize|keyboardHidden" android:configChanges="orientation|screenSize|keyboardHidden" android:excludeFromRecents="true" android:excludeFromRecents="true" Loading
src/com/android/server/telecom/CallsManager.java +115 −11 Original line number Original line Diff line number Diff line Loading @@ -31,15 +31,19 @@ import static android.telecom.TelecomManager.VERY_SHORT_CALL_TIME_MS; import android.Manifest; import android.Manifest; import android.annotation.NonNull; import android.annotation.NonNull; import android.app.ActivityManager; import android.app.ActivityManager; import android.app.AlertDialog; import android.app.KeyguardManager; import android.app.KeyguardManager; import android.content.BroadcastReceiver; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ComponentName; import android.content.Context; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.Intent; import android.content.IntentFilter; import android.content.IntentFilter; import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.content.pm.UserInfo; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.media.AudioManager; import android.media.AudioManager; import android.media.AudioSystem; import android.media.AudioSystem; import android.media.ToneGenerator; import android.media.ToneGenerator; Loading Loading @@ -85,6 +89,11 @@ import android.util.Pair; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting; import android.telecom.CallerInfo; import android.telecom.CallerInfo; import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; import android.widget.Button; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.IndentingPrintWriter; import com.android.server.telecom.bluetooth.BluetoothRouteManager; import com.android.server.telecom.bluetooth.BluetoothRouteManager; import com.android.server.telecom.bluetooth.BluetoothStateReceiver; import com.android.server.telecom.bluetooth.BluetoothStateReceiver; Loading @@ -99,9 +108,9 @@ import com.android.server.telecom.callfiltering.IncomingCallFilterGraph; import com.android.server.telecom.callfiltering.NewCallScreeningServiceFilter; import com.android.server.telecom.callfiltering.NewCallScreeningServiceFilter; import com.android.server.telecom.callredirection.CallRedirectionProcessor; import com.android.server.telecom.callredirection.CallRedirectionProcessor; import com.android.server.telecom.components.ErrorDialogActivity; import com.android.server.telecom.components.ErrorDialogActivity; import com.android.server.telecom.components.TelecomBroadcastReceiver; import com.android.server.telecom.settings.BlockedNumbersUtil; import com.android.server.telecom.settings.BlockedNumbersUtil; import com.android.server.telecom.ui.AudioProcessingNotification; import com.android.server.telecom.ui.AudioProcessingNotification; import com.android.server.telecom.ui.CallRedirectionConfirmDialogActivity; import com.android.server.telecom.ui.CallRedirectionTimeoutDialogActivity; import com.android.server.telecom.ui.CallRedirectionTimeoutDialogActivity; import com.android.server.telecom.ui.ConfirmCallDialogActivity; import com.android.server.telecom.ui.ConfirmCallDialogActivity; import com.android.server.telecom.ui.DisconnectedCallNotifier; import com.android.server.telecom.ui.DisconnectedCallNotifier; Loading Loading @@ -2028,23 +2037,106 @@ public class CallsManager extends Call.ListenerBase + "callId=%s, callRedirectionAppName=%s", + "callId=%s, callRedirectionAppName=%s", call.getId(), callRedirectionApp); call.getId(), callRedirectionApp); Intent confirmIntent = new Intent(mContext, showRedirectionDialog(call.getId()); CallRedirectionConfirmDialogActivity.class); confirmIntent.putExtra( CallRedirectionConfirmDialogActivity.EXTRA_REDIRECTION_OUTGOING_CALL_ID, call.getId()); confirmIntent.putExtra(CallRedirectionConfirmDialogActivity.EXTRA_REDIRECTION_APP_NAME, mRoleManagerAdapter.getApplicationLabelForPackageName(callRedirectionApp)); confirmIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mContext.startActivityAsUser(confirmIntent, UserHandle.CURRENT); } else { } else { call.setTargetPhoneAccount(phoneAccountHandle); call.setTargetPhoneAccount(phoneAccountHandle); placeOutgoingCall(call, handle, gatewayInfo, speakerphoneOn, videoState); placeOutgoingCall(call, handle, gatewayInfo, speakerphoneOn, videoState); } } } } /** * Shows the call redirection confirmation dialog. This is explicitly done here instead of in * an activity class such as {@link ConfirmCallDialogActivity}. This was originally done with * an activity class, however due to the fact that the InCall UI is being spun up at the same * time as the dialog activity, there is a potential race condition where the InCall UI will * often be shown instead of the dialog. Activity manager chooses not to show the redirection * dialog in that case since the new top activity from dialer is going to show. * By showing the dialog here we're able to set the dialog's window type to * {@link WindowManager.LayoutParams#TYPE_SYSTEM_ALERT} which guarantees it shows above other * content on the screen. * @param callId The ID of the call to show the redirection dialog for. */ private void showRedirectionDialog(@NonNull String callId) { AlertDialog confirmDialog = new AlertDialog.Builder(mContext).create(); LayoutInflater layoutInflater = LayoutInflater.from(mContext); View dialogView = layoutInflater.inflate(R.layout.call_redirection_confirm_dialog, null); Button buttonFirstLine = (Button) dialogView.findViewById(R.id.buttonFirstLine); buttonFirstLine.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent proceedWithoutRedirectedCall = new Intent( TelecomBroadcastIntentProcessor.ACTION_PLACE_UNREDIRECTED_CALL, null, mContext, TelecomBroadcastReceiver.class); proceedWithoutRedirectedCall.putExtra( TelecomBroadcastIntentProcessor.EXTRA_REDIRECTION_OUTGOING_CALL_ID, callId); mContext.sendBroadcast(proceedWithoutRedirectedCall); confirmDialog.dismiss(); } }); Button buttonSecondLine = (Button) dialogView.findViewById(R.id.buttonSecondLine); buttonSecondLine.setText(mContext.getText( R.string.alert_place_outgoing_call_with_redirection)); buttonSecondLine.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent proceedWithRedirectedCall = new Intent( TelecomBroadcastIntentProcessor.ACTION_PLACE_REDIRECTED_CALL, null, mContext, TelecomBroadcastReceiver.class); proceedWithRedirectedCall.putExtra( TelecomBroadcastIntentProcessor.EXTRA_REDIRECTION_OUTGOING_CALL_ID, callId); mContext.sendBroadcast(proceedWithRedirectedCall); confirmDialog.dismiss(); } }); Button buttonThirdLine = (Button) dialogView.findViewById(R.id.buttonThirdLine); buttonThirdLine.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { cancelRedirection(callId); confirmDialog.dismiss(); } }); confirmDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { @Override public void onCancel(DialogInterface dialog) { cancelRedirection(callId); confirmDialog.dismiss(); } }); confirmDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); confirmDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); confirmDialog.setCancelable(false); confirmDialog.setCanceledOnTouchOutside(false); confirmDialog.setView(dialogView); confirmDialog.show(); } /** * Signals to Telecom that redirection of the call is to be cancelled. */ private void cancelRedirection(String callId) { Intent cancelRedirectedCall = new Intent( TelecomBroadcastIntentProcessor.ACTION_CANCEL_REDIRECTED_CALL, null, mContext, TelecomBroadcastReceiver.class); cancelRedirectedCall.putExtra( TelecomBroadcastIntentProcessor.EXTRA_REDIRECTION_OUTGOING_CALL_ID, callId); mContext.sendBroadcastAsUser(cancelRedirectedCall, UserHandle.CURRENT); } public void processRedirectedOutgoingCallAfterUserInteraction(String callId, String action) { public void processRedirectedOutgoingCallAfterUserInteraction(String callId, String action) { Log.i(this, "processRedirectedOutgoingCallAfterUserInteraction for Call ID %s", callId); Log.i(this, "processRedirectedOutgoingCallAfterUserInteraction for Call ID %s, action=%s", callId, action); if (mPendingRedirectedOutgoingCall != null && mPendingRedirectedOutgoingCall.getId() if (mPendingRedirectedOutgoingCall != null && mPendingRedirectedOutgoingCall.getId() .equals(callId)) { .equals(callId)) { if (action.equals(TelecomBroadcastIntentProcessor.ACTION_PLACE_REDIRECTED_CALL)) { if (action.equals(TelecomBroadcastIntentProcessor.ACTION_PLACE_REDIRECTED_CALL)) { Loading Loading @@ -4383,6 +4475,18 @@ public class CallsManager extends Call.ListenerBase pw.println(mPendingCall.getId()); pw.println(mPendingCall.getId()); } } if (mPendingRedirectedOutgoingCallInfo.size() > 0) { pw.print("mPendingRedirectedOutgoingCallInfo:"); pw.println(mPendingRedirectedOutgoingCallInfo.keySet().stream().collect( Collectors.joining(", "))); } if (mPendingUnredirectedOutgoingCallInfo.size() > 0) { pw.print("mPendingUnredirectedOutgoingCallInfo:"); pw.println(mPendingUnredirectedOutgoingCallInfo.keySet().stream().collect( Collectors.joining(", "))); } if (mCallAudioManager != null) { if (mCallAudioManager != null) { pw.println("mCallAudioManager:"); pw.println("mCallAudioManager:"); pw.increaseIndent(); pw.increaseIndent(); Loading
src/com/android/server/telecom/TelecomBroadcastIntentProcessor.java +13 −13 Original line number Original line Diff line number Diff line Loading @@ -24,7 +24,6 @@ import android.os.UserHandle; import android.telecom.Log; import android.telecom.Log; import android.widget.Toast; import android.widget.Toast; import com.android.server.telecom.ui.CallRedirectionConfirmDialogActivity; import com.android.server.telecom.ui.ConfirmCallDialogActivity; import com.android.server.telecom.ui.ConfirmCallDialogActivity; import com.android.server.telecom.ui.DisconnectedCallNotifier; import com.android.server.telecom.ui.DisconnectedCallNotifier; Loading Loading @@ -80,27 +79,31 @@ public final class TelecomBroadcastIntentProcessor { "com.android.server.telecom.CANCEL_CALL"; "com.android.server.telecom.CANCEL_CALL"; /** /** * The action used to proceed with a redirected call being confirmed via * The action used to proceed with a redirected call being confirmed via the call redirection * {@link com.android.server.telecom.ui.CallRedirectionConfirmDialogActivity}. * confirmation dialog. */ */ public static final String ACTION_PLACE_REDIRECTED_CALL = public static final String ACTION_PLACE_REDIRECTED_CALL = "com.android.server.telecom.PROCEED_WITH_REDIRECTED_CALL"; "com.android.server.telecom.PROCEED_WITH_REDIRECTED_CALL"; /** /** * The action used to confirm to proceed the call without redirection via * The action used to confirm to proceed the call without redirection via the call redirection * {@link com.android.server.telecom.ui.CallRedirectionConfirmDialogActivity}. * confirmation dialog. */ */ public static final String ACTION_PLACE_UNREDIRECTED_CALL = public static final String ACTION_PLACE_UNREDIRECTED_CALL = "com.android.server.telecom.PROCEED_WITH_UNREDIRECTED_CALL"; "com.android.server.telecom.PROCEED_WITH_UNREDIRECTED_CALL"; /** /** * The action used to cancel a redirected call being confirmed via * The action used to cancel a redirected call being confirmed via the call redirection * {@link com.android.server.telecom.ui.CallRedirectionConfirmDialogActivity}. * confirmation dialog. */ */ public static final String ACTION_CANCEL_REDIRECTED_CALL = public static final String ACTION_CANCEL_REDIRECTED_CALL = "com.android.server.telecom.CANCEL_REDIRECTED_CALL"; "com.android.server.telecom.CANCEL_REDIRECTED_CALL"; public static final String EXTRA_USERHANDLE = "userhandle"; public static final String EXTRA_USERHANDLE = "userhandle"; public static final String EXTRA_REDIRECTION_OUTGOING_CALL_ID = "android.telecom.extra.REDIRECTION_OUTGOING_CALL_ID"; public static final String EXTRA_REDIRECTION_APP_NAME = "android.telecom.extra.REDIRECTION_APP_NAME"; private final Context mContext; private final Context mContext; private final CallsManager mCallsManager; private final CallsManager mCallsManager; Loading Loading @@ -214,8 +217,7 @@ public final class TelecomBroadcastIntentProcessor { Log.startSession("TBIP.aPRC"); Log.startSession("TBIP.aPRC"); try { try { mCallsManager.processRedirectedOutgoingCallAfterUserInteraction( mCallsManager.processRedirectedOutgoingCallAfterUserInteraction( intent.getStringExtra(CallRedirectionConfirmDialogActivity intent.getStringExtra(EXTRA_REDIRECTION_OUTGOING_CALL_ID), .EXTRA_REDIRECTION_OUTGOING_CALL_ID), ACTION_PLACE_REDIRECTED_CALL); ACTION_PLACE_REDIRECTED_CALL); } finally { } finally { Log.endSession(); Log.endSession(); Loading @@ -224,8 +226,7 @@ public final class TelecomBroadcastIntentProcessor { Log.startSession("TBIP.aPUC"); Log.startSession("TBIP.aPUC"); try { try { mCallsManager.processRedirectedOutgoingCallAfterUserInteraction( mCallsManager.processRedirectedOutgoingCallAfterUserInteraction( intent.getStringExtra(CallRedirectionConfirmDialogActivity intent.getStringExtra(EXTRA_REDIRECTION_OUTGOING_CALL_ID), .EXTRA_REDIRECTION_OUTGOING_CALL_ID), ACTION_PLACE_UNREDIRECTED_CALL); ACTION_PLACE_UNREDIRECTED_CALL); } finally { } finally { Log.endSession(); Log.endSession(); Loading @@ -234,8 +235,7 @@ public final class TelecomBroadcastIntentProcessor { Log.startSession("TBIP.aCRC"); Log.startSession("TBIP.aCRC"); try { try { mCallsManager.processRedirectedOutgoingCallAfterUserInteraction( mCallsManager.processRedirectedOutgoingCallAfterUserInteraction( intent.getStringExtra(CallRedirectionConfirmDialogActivity intent.getStringExtra(EXTRA_REDIRECTION_OUTGOING_CALL_ID), .EXTRA_REDIRECTION_OUTGOING_CALL_ID), ACTION_CANCEL_REDIRECTED_CALL); ACTION_CANCEL_REDIRECTED_CALL); } finally { } finally { Log.endSession(); Log.endSession(); Loading
src/com/android/server/telecom/ui/CallRedirectionConfirmDialogActivity.javadeleted 100644 → 0 +0 −161 Original line number Original line Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License */ package com.android.server.telecom.ui; import com.android.server.telecom.R; import com.android.server.telecom.TelecomBroadcastIntentProcessor; import com.android.server.telecom.components.TelecomBroadcastReceiver; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.os.Bundle; import android.telecom.Log; import android.view.LayoutInflater; import android.view.View.OnClickListener; import android.view.View; import android.widget.Button; /** * Dialog activity used when there is an ongoing call redirected by the call redirection service. * The dialog prompts the user to see if they want to place the redirected outgoing call. */ public class CallRedirectionConfirmDialogActivity extends Activity { public static final String EXTRA_REDIRECTION_OUTGOING_CALL_ID = "android.telecom.extra.REDIRECTION_OUTGOING_CALL_ID"; public static final String EXTRA_REDIRECTION_APP_NAME = "android.telecom.extra.REDIRECTION_APP_NAME"; private String mCallId; private AlertDialog mConfirmDialog; /** * Tracks whether the activity has stopped due to a loss of focus (e.g. use hitting the home * button) or whether its going to stop because a button in the dialog was pressed. */ private boolean mHasLostFocus = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.i(this, "CallRedirectionConfirmDialogActivity onCreate."); final CharSequence redirectionAppName = getIntent().getStringExtra( EXTRA_REDIRECTION_APP_NAME); mCallId = getIntent().getStringExtra(EXTRA_REDIRECTION_OUTGOING_CALL_ID); showDialog(redirectionAppName); } @Override protected void onStop() { super.onStop(); if (mHasLostFocus) { Log.i(this, "onStop: dialog lost focus; canceling redirection for call %s", mCallId); mConfirmDialog.dismiss(); cancelRedirection(); } } private void showDialog(final CharSequence redirectionAppName) { Log.i(this, "showDialog: confirming redirection with %s", redirectionAppName); mConfirmDialog = new AlertDialog.Builder(this).create(); LayoutInflater layoutInflater = LayoutInflater.from(this); View dialogView = layoutInflater.inflate(R.layout.call_redirection_confirm_dialog, null); Button buttonFirstLine = (Button) dialogView.findViewById(R.id.buttonFirstLine); buttonFirstLine.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent proceedWithoutRedirectedCall = new Intent( TelecomBroadcastIntentProcessor.ACTION_PLACE_UNREDIRECTED_CALL, null, CallRedirectionConfirmDialogActivity.this, TelecomBroadcastReceiver.class); proceedWithoutRedirectedCall.putExtra(EXTRA_REDIRECTION_OUTGOING_CALL_ID, mCallId); sendBroadcast(proceedWithoutRedirectedCall); mConfirmDialog.dismiss(); mHasLostFocus = false; finish(); } }); Button buttonSecondLine = (Button) dialogView.findViewById(R.id.buttonSecondLine); buttonSecondLine.setText(getString(R.string.alert_place_outgoing_call_with_redirection, redirectionAppName)); buttonSecondLine.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent proceedWithRedirectedCall = new Intent( TelecomBroadcastIntentProcessor .ACTION_PLACE_REDIRECTED_CALL, null, CallRedirectionConfirmDialogActivity.this, TelecomBroadcastReceiver.class); proceedWithRedirectedCall.putExtra(EXTRA_REDIRECTION_OUTGOING_CALL_ID, mCallId); sendBroadcast(proceedWithRedirectedCall); mConfirmDialog.dismiss(); mHasLostFocus = false; finish(); } }); Button buttonThirdLine = (Button) dialogView.findViewById(R.id.buttonThirdLine); buttonThirdLine.setOnClickListener(new OnClickListener() { public void onClick(View v) { Intent cancelRedirectedCall = new Intent( TelecomBroadcastIntentProcessor.ACTION_CANCEL_REDIRECTED_CALL, null, CallRedirectionConfirmDialogActivity.this, TelecomBroadcastReceiver.class); cancelRedirectedCall.putExtra(EXTRA_REDIRECTION_OUTGOING_CALL_ID, mCallId); sendBroadcast(cancelRedirectedCall); mConfirmDialog.dismiss(); mHasLostFocus = false; finish(); } }); mConfirmDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { @Override public void onCancel(DialogInterface dialog) { cancelRedirection(); dialog.dismiss(); mHasLostFocus = false; finish(); } }); mConfirmDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); mConfirmDialog.setCancelable(false); mConfirmDialog.setCanceledOnTouchOutside(false); mConfirmDialog.setView(dialogView); mConfirmDialog.show(); } /** * Signals to Telecom that redirection of the call is to be cancelled. */ private void cancelRedirection() { Intent cancelRedirectedCall = new Intent( TelecomBroadcastIntentProcessor.ACTION_CANCEL_REDIRECTED_CALL, null, CallRedirectionConfirmDialogActivity.this, TelecomBroadcastReceiver.class); cancelRedirectedCall.putExtra(EXTRA_REDIRECTION_OUTGOING_CALL_ID, mCallId); sendBroadcast(cancelRedirectedCall); } }