Confirm managed call when there are ongoing self-managed calls.
When the user places a managed call while there are ongoing self-managed calls, the system will now display a dialog giving the user the option of NOT placing the managed call, or placing the managed call and disconnecting the ongoing self-managed call(s). This is done by stopping the outgoing call during startOutgoingCall and bringing up a dialog to confirm whether the user wants to place the call. If they chose to place the call, ongoing self-mgds calls are disconnected, the call is added, and the NewutgoingCallBroadcast is sent as usual. If the user chooses not to start the call, the call is cancelled. Test: Manual Bug: 37828805 Change-Id: I8539b0601cf5f324d2fb204485ee0d9bbf03426d
This commit is contained in:
parent
fa1b42cae1
commit
bbd78a76f8
|
@ -212,6 +212,8 @@
|
|||
<action android:name="com.android.server.telecom.ACTION_SEND_SMS_FROM_NOTIFICATION" />
|
||||
<action android:name="com.android.server.telecom.ACTION_ANSWER_FROM_NOTIFICATION" />
|
||||
<action android:name="com.android.server.telecom.ACTION_REJECT_FROM_NOTIFICATION" />
|
||||
<action android:name="com.android.server.telecom.PROCEED_WITH_CALL" />
|
||||
<action android:name="com.android.server.telecom.CANCEL_CALL" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
|
@ -254,6 +256,14 @@
|
|||
android:process=":ui">
|
||||
</activity>
|
||||
|
||||
<activity android:name=".ui.ConfirmCallDialogActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
android:excludeFromRecents="true"
|
||||
android:launchMode="singleInstance"
|
||||
android:theme="@style/Theme.Telecomm.Transparent"
|
||||
android:process=":ui">
|
||||
</activity>
|
||||
|
||||
<activity android:name=".components.ChangeDefaultDialerDialog"
|
||||
android:label="@string/change_default_dialer_dialog_title"
|
||||
android:excludeFromRecents="true"
|
||||
|
@ -265,7 +275,6 @@
|
|||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".testapps.IncomingSelfManagedCallActivity" />
|
||||
|
||||
<receiver android:name=".components.PrimaryCallReceiver"
|
||||
android:exported="true"
|
||||
|
|
|
@ -252,4 +252,8 @@
|
|||
<string name="notification_channel_incoming_call">Incoming calls</string>
|
||||
<!-- Notification channel name for a channel containing missed call notifications. -->
|
||||
<string name="notification_channel_missed_call">Missed calls</string>
|
||||
|
||||
<!-- Alert dialog content used to inform the user that placing a new outgoing call will end the
|
||||
ongoing call in the app "other_app". -->
|
||||
<string name="alert_outgoing_call">Placing this call will end your <xliff:g id="other_app">%1$s</xliff:g> call.</string>
|
||||
</resources>
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package com.android.server.telecom;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
|
@ -317,6 +318,12 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable {
|
|||
|
||||
private Bundle mIntentExtras = new Bundle();
|
||||
|
||||
/**
|
||||
* The {@link Intent} which originally created this call. Only populated when we are putting a
|
||||
* call into a pending state and need to pick up initiation of the call later.
|
||||
*/
|
||||
private Intent mOriginalCallIntent = null;
|
||||
|
||||
/** Set of listeners on this call.
|
||||
*
|
||||
* ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
|
||||
|
@ -1786,6 +1793,14 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable {
|
|||
mIntentExtras = extras;
|
||||
}
|
||||
|
||||
public Intent getOriginalCallIntent() {
|
||||
return mOriginalCallIntent;
|
||||
}
|
||||
|
||||
public void setOriginalCallIntent(Intent intent) {
|
||||
mOriginalCallIntent = intent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the uri of the contact associated with this call.
|
||||
*/
|
||||
|
|
|
@ -9,7 +9,6 @@ import android.os.Bundle;
|
|||
import android.os.Trace;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.telecom.Connection;
|
||||
import android.telecom.DefaultDialerManager;
|
||||
import android.telecom.Log;
|
||||
import android.telecom.PhoneAccount;
|
||||
|
@ -128,8 +127,6 @@ public class CallIntentProcessor {
|
|||
VideoProfile.STATE_AUDIO_ONLY);
|
||||
clientExtras.putInt(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, videoState);
|
||||
|
||||
final boolean isPrivilegedDialer = intent.getBooleanExtra(KEY_IS_PRIVILEGED_DIALER, false);
|
||||
|
||||
boolean fixedInitiatingUser = fixInitiatingUserIfNecessary(context, intent);
|
||||
// Show the toast to warn user that it is a personal call though initiated in work profile.
|
||||
if (fixedInitiatingUser) {
|
||||
|
@ -140,23 +137,31 @@ public class CallIntentProcessor {
|
|||
|
||||
// Send to CallsManager to ensure the InCallUI gets kicked off before the broadcast returns
|
||||
Call call = callsManager
|
||||
.startOutgoingCall(handle, phoneAccountHandle, clientExtras, initiatingUser);
|
||||
.startOutgoingCall(handle, phoneAccountHandle, clientExtras, initiatingUser,
|
||||
intent);
|
||||
|
||||
if (call != null) {
|
||||
// Asynchronous calls should not usually be made inside a BroadcastReceiver because once
|
||||
// onReceive is complete, the BroadcastReceiver's process runs the risk of getting
|
||||
// killed if memory is scarce. However, this is OK here because the entire Telecom
|
||||
// process will be running throughout the duration of the phone call and should never
|
||||
// be killed.
|
||||
NewOutgoingCallIntentBroadcaster broadcaster = new NewOutgoingCallIntentBroadcaster(
|
||||
context, callsManager, call, intent, callsManager.getPhoneNumberUtilsAdapter(),
|
||||
isPrivilegedDialer);
|
||||
final int result = broadcaster.processIntent();
|
||||
final boolean success = result == DisconnectCause.NOT_DISCONNECTED;
|
||||
sendNewOutgoingCallIntent(context, call, callsManager, intent);
|
||||
}
|
||||
}
|
||||
|
||||
if (!success && call != null) {
|
||||
disconnectCallAndShowErrorDialog(context, call, result);
|
||||
}
|
||||
static void sendNewOutgoingCallIntent(Context context, Call call, CallsManager callsManager,
|
||||
Intent intent) {
|
||||
// Asynchronous calls should not usually be made inside a BroadcastReceiver because once
|
||||
// onReceive is complete, the BroadcastReceiver's process runs the risk of getting
|
||||
// killed if memory is scarce. However, this is OK here because the entire Telecom
|
||||
// process will be running throughout the duration of the phone call and should never
|
||||
// be killed.
|
||||
final boolean isPrivilegedDialer = intent.getBooleanExtra(KEY_IS_PRIVILEGED_DIALER, false);
|
||||
|
||||
NewOutgoingCallIntentBroadcaster broadcaster = new NewOutgoingCallIntentBroadcaster(
|
||||
context, callsManager, call, intent, callsManager.getPhoneNumberUtilsAdapter(),
|
||||
isPrivilegedDialer);
|
||||
final int result = broadcaster.processIntent();
|
||||
final boolean success = result == DisconnectCause.NOT_DISCONNECTED;
|
||||
|
||||
if (!success && call != null) {
|
||||
disconnectCallAndShowErrorDialog(context, call, result);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -65,6 +65,7 @@ import com.android.server.telecom.callfiltering.CallScreeningServiceFilter;
|
|||
import com.android.server.telecom.callfiltering.DirectToVoicemailCallFilter;
|
||||
import com.android.server.telecom.callfiltering.IncomingCallFilter;
|
||||
import com.android.server.telecom.components.ErrorDialogActivity;
|
||||
import com.android.server.telecom.ui.ConfirmCallDialogActivity;
|
||||
import com.android.server.telecom.ui.IncomingCallNotifier;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -207,6 +208,12 @@ public class CallsManager extends Call.ListenerBase
|
|||
private final Set<Call> mCalls = Collections.newSetFromMap(
|
||||
new ConcurrentHashMap<Call, Boolean>(8, 0.9f, 1));
|
||||
|
||||
/**
|
||||
* A pending call is one which requires user-intervention in order to be placed.
|
||||
* Used by {@link #startCallConfirmation(Call)}.
|
||||
*/
|
||||
private Call mPendingCall;
|
||||
|
||||
/**
|
||||
* The current telecom call ID. Used when creating new instances of {@link Call}. Should
|
||||
* only be accessed using the {@link #getNextCallId()} method which synchronizes on the
|
||||
|
@ -994,15 +1001,15 @@ public class CallsManager extends Call.ListenerBase
|
|||
* For managed connections, this is the first step to launching the Incall UI.
|
||||
* For self-managed connections, we don't expect the Incall UI to launch, but this is still a
|
||||
* first step in getting the self-managed ConnectionService to create the connection.
|
||||
*
|
||||
* @param handle Handle to connect the call with.
|
||||
* @param phoneAccountHandle The phone account which contains the component name of the
|
||||
* connection service to use for this call.
|
||||
* @param extras The optional extras Bundle passed with the intent used for the incoming call.
|
||||
* @param initiatingUser {@link UserHandle} of user that place the outgoing call.
|
||||
* @param originalIntent
|
||||
*/
|
||||
Call startOutgoingCall(Uri handle, PhoneAccountHandle phoneAccountHandle, Bundle extras,
|
||||
UserHandle initiatingUser) {
|
||||
UserHandle initiatingUser, Intent originalIntent) {
|
||||
boolean isReusedCall = true;
|
||||
Call call = reuseOutgoingCall(handle);
|
||||
|
||||
|
@ -1042,7 +1049,6 @@ public class CallsManager extends Call.ListenerBase
|
|||
}
|
||||
|
||||
call.setInitiatingUser(initiatingUser);
|
||||
|
||||
isReusedCall = false;
|
||||
}
|
||||
|
||||
|
@ -1160,9 +1166,15 @@ public class CallsManager extends Call.ListenerBase
|
|||
}
|
||||
setIntentExtrasAndStartTime(call, extras);
|
||||
|
||||
// Do not add the call if it is a potential MMI code.
|
||||
if ((isPotentialMMICode(handle) || isPotentialInCallMMICode) && !needsAccountSelection) {
|
||||
if ((isPotentialMMICode(handle) || isPotentialInCallMMICode)
|
||||
&& !needsAccountSelection) {
|
||||
// Do not add the call if it is a potential MMI code.
|
||||
call.addListener(this);
|
||||
} else if (!isSelfManaged && hasSelfManagedCalls() && !call.isEmergencyCall()) {
|
||||
// Adding a managed call and there are ongoing self-managed call(s).
|
||||
call.setOriginalCallIntent(originalIntent);
|
||||
startCallConfirmation(call);
|
||||
return null;
|
||||
} else if (!mCalls.contains(call)) {
|
||||
// We check if mCalls already contains the call because we could potentially be reusing
|
||||
// a call which was previously added (See {@link #reuseOutgoingCall}).
|
||||
|
@ -1235,23 +1247,11 @@ public class CallsManager extends Call.ListenerBase
|
|||
if (call.isSelfManaged() && !isOutgoingCallPermitted) {
|
||||
notifyCreateConnectionFailed(call.getTargetPhoneAccount(), call);
|
||||
} else if (!call.isSelfManaged() && hasSelfManagedCalls() && !call.isEmergencyCall()) {
|
||||
Call activeCall = getActiveCall();
|
||||
CharSequence errorMessage;
|
||||
if (activeCall == null) {
|
||||
// Realistically this shouldn't happen, but best to handle gracefully
|
||||
errorMessage = mContext.getText(R.string.cant_call_due_to_ongoing_unknown_call);
|
||||
} else {
|
||||
errorMessage = mContext.getString(R.string.cant_call_due_to_ongoing_call,
|
||||
activeCall.getTargetPhoneAccountLabel());
|
||||
}
|
||||
// Call is managed and there are ongoing self-managed calls.
|
||||
markCallAsDisconnected(call, new DisconnectCause(DisconnectCause.ERROR,
|
||||
errorMessage, errorMessage, "Ongoing call in another app."));
|
||||
markCallAsRemoved(call);
|
||||
markCallDisconnectedDueToSelfManagedCall(call);
|
||||
} else {
|
||||
if (call.isEmergencyCall()) {
|
||||
// Disconnect all self-managed calls to make priority for emergency call.
|
||||
mCalls.stream().filter(c -> c.isSelfManaged()).forEach(c -> c.disconnect());
|
||||
disconnectSelfManagedCalls();
|
||||
}
|
||||
|
||||
call.startCreateConnection(mPhoneAccountRegistrar);
|
||||
|
@ -1749,6 +1749,33 @@ public class CallsManager extends Call.ListenerBase
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a call, marks the call as disconnected and removes it. Set the error message to
|
||||
* indicate to the user that the call cannot me placed due to an ongoing call in another app.
|
||||
*
|
||||
* Used when there are ongoing self-managed calls and the user tries to make an outgoing managed
|
||||
* call. Called by {@link #startCallConfirmation(Call)} when the user is already confirming an
|
||||
* outgoing call. Realistically this should almost never be called since in practice the user
|
||||
* won't make multiple outgoing calls at the same time.
|
||||
*
|
||||
* @param call The call to mark as disconnected.
|
||||
*/
|
||||
void markCallDisconnectedDueToSelfManagedCall(Call call) {
|
||||
Call activeCall = getActiveCall();
|
||||
CharSequence errorMessage;
|
||||
if (activeCall == null) {
|
||||
// Realistically this shouldn't happen, but best to handle gracefully
|
||||
errorMessage = mContext.getText(R.string.cant_call_due_to_ongoing_unknown_call);
|
||||
} else {
|
||||
errorMessage = mContext.getString(R.string.cant_call_due_to_ongoing_call,
|
||||
activeCall.getTargetPhoneAccountLabel());
|
||||
}
|
||||
// Call is managed and there are ongoing self-managed calls.
|
||||
markCallAsDisconnected(call, new DisconnectCause(DisconnectCause.ERROR,
|
||||
errorMessage, errorMessage, "Ongoing call in another app."));
|
||||
markCallAsRemoved(call);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up any calls currently associated with the specified connection service when the
|
||||
* service binder disconnects unexpectedly.
|
||||
|
@ -2760,6 +2787,97 @@ public class CallsManager extends Call.ListenerBase
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to confirm creation of an outgoing call which was marked as pending confirmation in
|
||||
* {@link #startOutgoingCall(Uri, PhoneAccountHandle, Bundle, UserHandle, Intent)}.
|
||||
* Called via {@link TelecomBroadcastIntentProcessor} for a call which was confirmed via
|
||||
* {@link ConfirmCallDialogActivity}.
|
||||
* @param callId The call ID of the call to confirm.
|
||||
*/
|
||||
public void confirmPendingCall(String callId) {
|
||||
Log.i(this, "confirmPendingCall: callId=%s", callId);
|
||||
if (mPendingCall != null && mPendingCall.getId().equals(callId)) {
|
||||
Log.addEvent(mPendingCall, LogUtils.Events.USER_CONFIRMED);
|
||||
addCall(mPendingCall);
|
||||
|
||||
// We are going to place the new outgoing call, so disconnect any ongoing self-managed
|
||||
// calls which are ongoing at this time.
|
||||
disconnectSelfManagedCalls();
|
||||
|
||||
// Kick of the new outgoing call intent from where it left off prior to confirming the
|
||||
// call.
|
||||
CallIntentProcessor.sendNewOutgoingCallIntent(mContext, mPendingCall, this,
|
||||
mPendingCall.getOriginalCallIntent());
|
||||
mPendingCall = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to cancel an outgoing call which was marked as pending confirmation in
|
||||
* {@link #startOutgoingCall(Uri, PhoneAccountHandle, Bundle, UserHandle, Intent)}.
|
||||
* Called via {@link TelecomBroadcastIntentProcessor} for a call which was confirmed via
|
||||
* {@link ConfirmCallDialogActivity}.
|
||||
* @param callId The call ID of the call to cancel.
|
||||
*/
|
||||
public void cancelPendingCall(String callId) {
|
||||
Log.i(this, "cancelPendingCall: callId=%s", callId);
|
||||
if (mPendingCall != null && mPendingCall.getId().equals(callId)) {
|
||||
Log.addEvent(mPendingCall, LogUtils.Events.USER_CANCELLED);
|
||||
markCallAsDisconnected(mPendingCall, new DisconnectCause(DisconnectCause.CANCELED));
|
||||
markCallAsRemoved(mPendingCall);
|
||||
mPendingCall = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from {@link #startOutgoingCall(Uri, PhoneAccountHandle, Bundle, UserHandle, Intent)} when
|
||||
* a managed call is added while there are ongoing self-managed calls. Starts
|
||||
* {@link ConfirmCallDialogActivity} to prompt the user to see if they wish to place the
|
||||
* outgoing call or not.
|
||||
* @param call The call to confirm.
|
||||
*/
|
||||
private void startCallConfirmation(Call call) {
|
||||
if (mPendingCall != null) {
|
||||
Log.i(this, "startCallConfirmation: call %s is already pending; disconnecting %s",
|
||||
mPendingCall.getId(), call.getId());
|
||||
markCallDisconnectedDueToSelfManagedCall(call);
|
||||
return;
|
||||
}
|
||||
Log.addEvent(call, LogUtils.Events.USER_CONFIRMATION);
|
||||
mPendingCall = call;
|
||||
|
||||
// Figure out the name of the app in charge of the self-managed call(s).
|
||||
Call selfManagedCall = mCalls.stream()
|
||||
.filter(c -> c.isSelfManaged())
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
CharSequence ongoingAppName = "";
|
||||
if (selfManagedCall != null) {
|
||||
ongoingAppName = selfManagedCall.getTargetPhoneAccountLabel();
|
||||
}
|
||||
Log.i(this, "startCallConfirmation: callId=%s, ongoingApp=%s", call.getId(),
|
||||
ongoingAppName);
|
||||
|
||||
Intent confirmIntent = new Intent(mContext, ConfirmCallDialogActivity.class);
|
||||
confirmIntent.putExtra(ConfirmCallDialogActivity.EXTRA_OUTGOING_CALL_ID, call.getId());
|
||||
confirmIntent.putExtra(ConfirmCallDialogActivity.EXTRA_ONGOING_APP_NAME, ongoingAppName);
|
||||
confirmIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
mContext.startActivityAsUser(confirmIntent, UserHandle.CURRENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects all self-managed calls.
|
||||
*/
|
||||
private void disconnectSelfManagedCalls() {
|
||||
// Disconnect all self-managed calls to make priority for emergency call.
|
||||
// Use Call.disconnect() to command the ConnectionService to disconnect the calls.
|
||||
// CallsManager.markCallAsDisconnected doesn't actually tell the ConnectionService to
|
||||
// disconnect.
|
||||
mCalls.stream()
|
||||
.filter(c -> c.isSelfManaged())
|
||||
.forEach(c -> c.disconnect());
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the state of the {@link CallsManager}.
|
||||
*
|
||||
|
@ -2776,6 +2894,11 @@ public class CallsManager extends Call.ListenerBase
|
|||
pw.decreaseIndent();
|
||||
}
|
||||
|
||||
if (mPendingCall != null) {
|
||||
pw.print("mPendingCall:");
|
||||
pw.println(mPendingCall.getId());
|
||||
}
|
||||
|
||||
if (mCallAudioManager != null) {
|
||||
pw.println("mCallAudioManager:");
|
||||
pw.increaseIndent();
|
||||
|
@ -2903,7 +3026,7 @@ public class CallsManager extends Call.ListenerBase
|
|||
extras.putParcelable(TelecomManager.EXTRA_CALL_AUDIO_STATE,
|
||||
mCallAudioManager.getCallAudioState());
|
||||
Call handoverToCall = startOutgoingCall(handoverFromCall.getHandle(), handoverToHandle,
|
||||
extras, getCurrentUserHandle());
|
||||
extras, getCurrentUserHandle(), null /* originalIntent */);
|
||||
Log.addEvent(handoverFromCall, LogUtils.Events.START_HANDOVER,
|
||||
"handOverFrom=%s, handOverTo=%s", handoverFromCall.getId(), handoverToCall.getId());
|
||||
handoverFromCall.setHandoverToCall(handoverToCall);
|
||||
|
|
|
@ -54,6 +54,9 @@ public class LogUtils {
|
|||
|
||||
public final static class Events {
|
||||
public static final String CREATED = "CREATED";
|
||||
public static final String USER_CONFIRMATION = "USER_CONFIRMATION";
|
||||
public static final String USER_CONFIRMED = "USER_CONFIRMED";
|
||||
public static final String USER_CANCELLED = "USER_CANCELLED";
|
||||
public static final String DESTROYED = "DESTROYED";
|
||||
public static final String SET_CONNECTING = "SET_CONNECTING";
|
||||
public static final String SET_DIALING = "SET_DIALING";
|
||||
|
|
|
@ -21,6 +21,8 @@ import android.content.Intent;
|
|||
import android.os.UserHandle;
|
||||
import android.telecom.Log;
|
||||
|
||||
import com.android.server.telecom.ui.ConfirmCallDialogActivity;
|
||||
|
||||
public final class TelecomBroadcastIntentProcessor {
|
||||
/** The action used to send SMS response for the missed call notification. */
|
||||
public static final String ACTION_SEND_SMS_FROM_NOTIFICATION =
|
||||
|
@ -48,6 +50,20 @@ public final class TelecomBroadcastIntentProcessor {
|
|||
public static final String ACTION_REJECT_FROM_NOTIFICATION =
|
||||
"com.android.server.telecom.ACTION_REJECT_FROM_NOTIFICATION";
|
||||
|
||||
/**
|
||||
* The action used to proceed with a call being confirmed via
|
||||
* {@link com.android.server.telecom.ui.ConfirmCallDialogActivity}.
|
||||
*/
|
||||
public static final String ACTION_PROCEED_WITH_CALL =
|
||||
"com.android.server.telecom.PROCEED_WITH_CALL";
|
||||
|
||||
/**
|
||||
* The action used to cancel a call being confirmed via
|
||||
* {@link com.android.server.telecom.ui.ConfirmCallDialogActivity}.
|
||||
*/
|
||||
public static final String ACTION_CANCEL_CALL =
|
||||
"com.android.server.telecom.CANCEL_CALL";
|
||||
|
||||
public static final String EXTRA_USERHANDLE = "userhandle";
|
||||
|
||||
private final Context mContext;
|
||||
|
@ -112,6 +128,7 @@ public final class TelecomBroadcastIntentProcessor {
|
|||
} else if (ACTION_REJECT_FROM_NOTIFICATION.equals(action)) {
|
||||
Log.startSession("TBIP.aRFM");
|
||||
try {
|
||||
|
||||
// Reject the current ringing call.
|
||||
Call incomingCall = mCallsManager.getIncomingCallNotifier().getIncomingCall();
|
||||
if (incomingCall != null) {
|
||||
|
@ -120,6 +137,24 @@ public final class TelecomBroadcastIntentProcessor {
|
|||
} finally {
|
||||
Log.endSession();
|
||||
}
|
||||
} else if (ACTION_PROCEED_WITH_CALL.equals(action)) {
|
||||
Log.startSession("TBIP.aPWC");
|
||||
try {
|
||||
String callId = intent.getStringExtra(
|
||||
ConfirmCallDialogActivity.EXTRA_OUTGOING_CALL_ID);
|
||||
mCallsManager.confirmPendingCall(callId);
|
||||
} finally {
|
||||
Log.endSession();
|
||||
}
|
||||
} else if (ACTION_CANCEL_CALL.equals(action)) {
|
||||
Log.startSession("TBIP.aCC");
|
||||
try {
|
||||
String callId = intent.getStringExtra(
|
||||
ConfirmCallDialogActivity.EXTRA_OUTGOING_CALL_ID);
|
||||
mCallsManager.cancelPendingCall(callId);
|
||||
} finally {
|
||||
Log.endSession();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Copyright (C) 2017 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.os.Bundle;
|
||||
import android.telecom.Log;
|
||||
|
||||
/**
|
||||
* Dialog activity used when there is an ongoing self-managed call and the user initiates a new
|
||||
* outgoing managed call. The dialog prompts the user to see if they want to disconnect the ongoing
|
||||
* self-managed call in order to place the new managed call.
|
||||
*/
|
||||
public class ConfirmCallDialogActivity extends Activity {
|
||||
public static final String EXTRA_OUTGOING_CALL_ID = "android.telecom.extra.OUTGOING_CALL_ID";
|
||||
public static final String EXTRA_ONGOING_APP_NAME = "android.telecom.extra.ONGOING_APP_NAME";
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
final String callId = getIntent().getStringExtra(EXTRA_OUTGOING_CALL_ID);
|
||||
final CharSequence ongoingAppName = getIntent().getCharSequenceExtra(
|
||||
EXTRA_ONGOING_APP_NAME);
|
||||
showDialog(callId, ongoingAppName);
|
||||
}
|
||||
|
||||
private void showDialog(final String callId, CharSequence ongoingAppName) {
|
||||
Log.i(this, "showDialog: confirming callId=%s, ongoing=%s", callId, ongoingAppName);
|
||||
CharSequence message = getString(R.string.alert_outgoing_call, ongoingAppName);
|
||||
final AlertDialog errorDialog = new AlertDialog.Builder(this)
|
||||
.setMessage(message)
|
||||
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
Intent proceedWithCall = new Intent(
|
||||
TelecomBroadcastIntentProcessor.ACTION_PROCEED_WITH_CALL, null,
|
||||
ConfirmCallDialogActivity.this,
|
||||
TelecomBroadcastReceiver.class);
|
||||
proceedWithCall.putExtra(EXTRA_OUTGOING_CALL_ID, callId);
|
||||
sendBroadcast(proceedWithCall);
|
||||
dialog.dismiss();
|
||||
finish();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
Intent cancelCall = new Intent(
|
||||
TelecomBroadcastIntentProcessor.ACTION_CANCEL_CALL, null,
|
||||
ConfirmCallDialogActivity.this,
|
||||
TelecomBroadcastReceiver.class);
|
||||
cancelCall.putExtra(EXTRA_OUTGOING_CALL_ID, callId);
|
||||
sendBroadcast(cancelCall);
|
||||
dialog.dismiss();
|
||||
finish();
|
||||
}
|
||||
})
|
||||
.setOnCancelListener(new DialogInterface.OnCancelListener() {
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialog) {
|
||||
Intent cancelCall = new Intent(
|
||||
TelecomBroadcastIntentProcessor.ACTION_CANCEL_CALL, null,
|
||||
ConfirmCallDialogActivity.this,
|
||||
TelecomBroadcastReceiver.class);
|
||||
cancelCall.putExtra(EXTRA_OUTGOING_CALL_ID, callId);
|
||||
sendBroadcast(cancelCall);
|
||||
dialog.dismiss();
|
||||
finish();
|
||||
}
|
||||
})
|
||||
.create();
|
||||
|
||||
errorDialog.show();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue