From d7255872e2204a074bc5dfb5dceb4da13574864c Mon Sep 17 00:00:00 2001 From: Yorke Lee Date: Mon, 25 Aug 2014 15:03:51 -0700 Subject: [PATCH] Add error dialogs to Telecomm * Add error dialog popups for DisconnectCause.INVALID_NUMBER and VOICEMAIL_NUMBER_MISSING * Move ErrorDialogActivity from Telephony to Telecomm * NewOutgoingCallBroadcaster.processIntent now returns an error code rather than a boolean Bug: 17209051 Bug: 17196776 Change-Id: Ifc8b23472510fefc0c2763d28f9c990b4598cadd --- AndroidManifest.xml | 9 +- res/values/strings.xml | 11 ++ res/values/styles.xml | 27 ++++ src/com/android/telecomm/CallActivity.java | 27 +++- .../android/telecomm/ErrorDialogActivity.java | 127 ++++++++++++++++++ .../NewOutgoingCallIntentBroadcaster.java | 25 ++-- 6 files changed, 215 insertions(+), 11 deletions(-) create mode 100644 res/values/styles.xml create mode 100644 src/com/android/telecomm/ErrorDialogActivity.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 43a1f5eaf..d5fb1671e 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -71,7 +71,7 @@ URL with the schemes "tel", "sip", and "voicemail". It also handles URLs linked to contacts provider entries. Any data not fitting the schema described is ignored. --> @@ -209,5 +209,12 @@ + + + diff --git a/res/values/strings.xml b/res/values/strings.xml index 8f4a2e85f..d50d830ad 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -95,6 +95,17 @@ due to a user restriction --> This user is not allowed to make non-emergency phone calls + + Call not sent, no valid number entered. + + + + Missing voicemail number + + No voicemail number is stored on the SIM card. + + Add number + Q Mobile diff --git a/res/values/styles.xml b/res/values/styles.xml new file mode 100644 index 000000000..6b6c1bb47 --- /dev/null +++ b/res/values/styles.xml @@ -0,0 +1,27 @@ + + + + + + diff --git a/src/com/android/telecomm/CallActivity.java b/src/com/android/telecomm/CallActivity.java index 95dee18ab..0d36c8ac6 100644 --- a/src/com/android/telecomm/CallActivity.java +++ b/src/com/android/telecomm/CallActivity.java @@ -26,6 +26,7 @@ import android.os.Bundle; import android.os.UserManager; import android.telecomm.PhoneAccountHandle; import android.telecomm.TelecommManager; +import android.telephony.DisconnectCause; import android.telephony.PhoneNumberUtils; import android.text.TextUtils; import android.widget.Toast; @@ -47,6 +48,7 @@ import android.widget.Toast; * non-emergency numbers just like it did pre-L. */ public class CallActivity extends Activity { + private CallsManager mCallsManager = CallsManager.getInstance(); private boolean mIsVoiceCapable; @@ -149,9 +151,11 @@ public class CallActivity extends Activity { NewOutgoingCallIntentBroadcaster broadcaster = new NewOutgoingCallIntentBroadcaster( mCallsManager, call, intent, isDefaultDialer()); - final boolean success = broadcaster.processIntent(); + final int result = broadcaster.processIntent(); + final boolean success = result == DisconnectCause.NOT_DISCONNECTED; + if (!success && call != null) { - call.disconnect(); + disconnectCallAndShowErrorDialog(call, result); } setResult(success ? RESULT_OK : RESULT_CANCELED); } @@ -209,4 +213,23 @@ public class CallActivity extends Activity { return getApplicationContext().getResources().getBoolean( com.android.internal.R.bool.config_voice_capable); } + + private void disconnectCallAndShowErrorDialog(Call call, int errorCode) { + call.disconnect(); + final Intent errorIntent = new Intent(this, ErrorDialogActivity.class); + int errorMessageId = -1; + switch (errorCode) { + case DisconnectCause.INVALID_NUMBER: + errorMessageId = R.string.outgoing_call_error_no_phone_number_supplied; + break; + case DisconnectCause.VOICEMAIL_NUMBER_MISSING: + errorIntent.putExtra(ErrorDialogActivity.SHOW_MISSING_VOICEMAIL_NO_DIALOG_EXTRA, + true); + break; + } + if (errorMessageId != -1) { + errorIntent.putExtra(ErrorDialogActivity.ERROR_MESSAGE_ID_EXTRA, errorMessageId); + } + startActivity(errorIntent); + } } diff --git a/src/com/android/telecomm/ErrorDialogActivity.java b/src/com/android/telecomm/ErrorDialogActivity.java new file mode 100644 index 000000000..098a15f2c --- /dev/null +++ b/src/com/android/telecomm/ErrorDialogActivity.java @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2013 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.telecomm; + +import android.app.Activity; +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.os.Bundle; +import android.telecomm.TelecommManager; + +/** + * Used to display an error dialog from within the Telecomm service when an outgoing call fails + */ +public class ErrorDialogActivity extends Activity { + private static final String TAG = ErrorDialogActivity.class.getSimpleName(); + + public static final String SHOW_MISSING_VOICEMAIL_NO_DIALOG_EXTRA = "show_missing_voicemail"; + public static final String ERROR_MESSAGE_ID_EXTRA = "error_message_id"; + + /** + * Intent action to bring up Voicemail Provider settings. + */ + public static final String ACTION_ADD_VOICEMAIL = + "com.android.phone.CallFeaturesSetting.ADD_VOICEMAIL"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + final boolean showVoicemailDialog = getIntent().getBooleanExtra( + SHOW_MISSING_VOICEMAIL_NO_DIALOG_EXTRA, false); + + if (showVoicemailDialog) { + showMissingVoicemailErrorDialog(); + } else { + final int error = getIntent().getIntExtra(ERROR_MESSAGE_ID_EXTRA, -1); + if (error == -1) { + Log.w(TAG, "ErrorDialogActivity called with no error type extra."); + finish(); + } else { + showGenericErrorDialog(error); + } + } + } + + private void showGenericErrorDialog(int resid) { + final CharSequence msg = getResources().getText(resid); + final DialogInterface.OnClickListener clickListener; + final DialogInterface.OnCancelListener cancelListener; + + clickListener = new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + finish(); + } + }; + + cancelListener = new DialogInterface.OnCancelListener() { + @Override + public void onCancel(DialogInterface dialog) { + finish(); + } + }; + + final AlertDialog errorDialog = new AlertDialog.Builder(this) + .setMessage(msg).setPositiveButton(android.R.string.ok, clickListener) + .setOnCancelListener(cancelListener).create(); + + errorDialog.show(); + } + + private void showMissingVoicemailErrorDialog() { + new AlertDialog.Builder(this) + .setTitle(R.string.no_vm_number) + .setMessage(R.string.no_vm_number_msg) + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + finish(); + }}) + .setNegativeButton(R.string.add_vm_number_str, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + addVoiceMailNumberPanel(dialog); + }}) + .setOnCancelListener(new DialogInterface.OnCancelListener() { + @Override + public void onCancel(DialogInterface dialog) { + finish(); + }}).show(); + } + + + private void addVoiceMailNumberPanel(DialogInterface dialog) { + if (dialog != null) { + dialog.dismiss(); + } + + // Navigate to the Voicemail setting in the Call Settings activity. + Intent intent = new Intent(ACTION_ADD_VOICEMAIL); + startActivity(intent); + finish(); + } + + @Override + public void finish() { + super.finish(); + // Don't show the return to previous task animation to avoid showing a black screen. + // Just dismiss the dialog and undim the previous activity immediately. + overridePendingTransition(0, 0); + } +} diff --git a/src/com/android/telecomm/NewOutgoingCallIntentBroadcaster.java b/src/com/android/telecomm/NewOutgoingCallIntentBroadcaster.java index a45f4efec..1c44fb2d7 100644 --- a/src/com/android/telecomm/NewOutgoingCallIntentBroadcaster.java +++ b/src/com/android/telecomm/NewOutgoingCallIntentBroadcaster.java @@ -26,6 +26,7 @@ import android.os.UserHandle; import android.telecomm.GatewayInfo; import android.telecomm.TelecommManager; import android.telecomm.VideoProfile; +import android.telephony.DisconnectCause; import android.telephony.PhoneNumberUtils; import android.text.TextUtils; @@ -66,6 +67,7 @@ class NewOutgoingCallIntentBroadcaster { private static final String SCHEME_TEL = "tel"; private static final String SCHEME_SIP = "sip"; + private static final String SCHEME_VOICEMAIL = "voicemail"; private final CallsManager mCallsManager; private final Call mCall; @@ -150,9 +152,10 @@ class NewOutgoingCallIntentBroadcaster { * - CALL_PRIVILEGED (intent launched by system apps e.g. system Dialer, voice Dialer) * - CALL_EMERGENCY (intent launched by lock screen emergency dialer) * - * @return whether or not the caller was allowed to start the outgoing call. + * @return {@link CallActivity#OUTGOING_CALL_SUCCEEDED} if the call succeeded, and an + * appropriate {@link DisconnectCause} if the call did not, describing why it failed. */ - boolean processIntent() { + int processIntent() { Log.v(this, "Processing call intent in OutgoingCallIntentBroadcaster."); final Context context = TelecommApp.getInstance(); @@ -161,8 +164,14 @@ class NewOutgoingCallIntentBroadcaster { String handle = PhoneNumberUtils.getNumberFromIntent(intent, context); if (TextUtils.isEmpty(handle)) { - Log.w(this, "Empty handle obtained from the call intent."); - return false; + final Uri data = intent.getData(); + if (data != null && SCHEME_VOICEMAIL.equals(data.getScheme())) { + Log.w(this, "Voicemail scheme provided but no voicemail number set."); + return DisconnectCause.VOICEMAIL_NUMBER_MISSING; + } else { + Log.w(this, "Empty handle obtained from the call intent."); + return DisconnectCause.INVALID_NUMBER; + } } boolean isUriNumber = PhoneNumberUtils.isUriNumber(handle); @@ -187,7 +196,7 @@ class NewOutgoingCallIntentBroadcaster { Log.w(this, "Cannot call potential emergency number %s with CALL Intent %s " + "unless caller is system or default dialer.", handle, intent); launchSystemDialer(context, intent.getData()); - return false; + return DisconnectCause.OUTGOING_CANCELED; } else { callImmediately = true; } @@ -196,12 +205,12 @@ class NewOutgoingCallIntentBroadcaster { if (!isPotentialEmergencyNumber) { Log.w(this, "Cannot call non-potential-emergency number %s with EMERGENCY_CALL " + "Intent %s.", handle, intent); - return false; + return DisconnectCause.OUTGOING_CANCELED; } callImmediately = true; } else { Log.w(this, "Unhandled Intent %s. Ignoring and not placing call.", intent); - return false; + return DisconnectCause.INVALID_NUMBER; } if (callImmediately) { @@ -223,7 +232,7 @@ class NewOutgoingCallIntentBroadcaster { } broadcastIntent(intent, handle, context, !callImmediately); - return true; + return DisconnectCause.NOT_DISCONNECTED; } /**