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
This commit is contained in:
Yorke Lee 2014-08-25 15:03:51 -07:00
parent 309f9ef2ad
commit d7255872e2
6 changed files with 215 additions and 11 deletions

View File

@ -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. -->
<activity android:name="CallActivity"
android:theme="@android:style/Theme.NoDisplay"
android:theme="@style/Theme.Telecomm.Transparent"
android:permission="android.permission.CALL_PHONE"
android:excludeFromRecents="true">
<!-- CALL action intent filters for the various ways of initiating an outgoing call. -->
@ -209,5 +209,12 @@
</intent-filter>
</activity>
<activity android:name=".ErrorDialogActivity"
android:configChanges="orientation|screenSize|keyboardHidden"
android:excludeFromRecents="true"
android:launchMode="singleInstance"
android:theme="@style/Theme.Telecomm.Transparent">
</activity>
</application>
</manifest>

View File

@ -95,6 +95,17 @@
due to a user restriction -->
<string name="outgoing_call_not_allowed">This user is not allowed to make non-emergency phone calls</string>
<!-- Call failure message displayed in an error dialog used to indicate that a phone number was not provided -->
<string name="outgoing_call_error_no_phone_number_supplied">Call not sent, no valid number entered.</string>
<!-- missing voicemail number -->
<!-- Title of the "Missing voicemail number" dialog -->
<string name="no_vm_number">Missing voicemail number</string>
<!-- Body text of the "Missing voicemail number" dialog -->
<string name="no_vm_number_msg">No voicemail number is stored on the SIM card.</string>
<!-- Button label on the "Missing voicemail number" dialog -->
<string name="add_vm_number_str">Add number</string>
<!-- DO NOT TRANSLATE. Label for test Subscription 0. -->
<string name="test_account_0_label">Q Mobile</string>
<!-- DO NOT TRANSLATE. Label for test Subscription 1. -->

27
res/values/styles.xml Normal file
View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 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.
-->
<resources>
<style name="Theme.Telecomm.Transparent" parent="@android:style/Theme.Material.Light">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">true</item>
<item name="android:backgroundDimEnabled">true</item>
<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
</style>
</resources>

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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;
}
/**