Merge "Support CDMA emergency callback. (2/2)" into lmp-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 43a1f5e..1fcfd23 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. -->
<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. -->
@@ -202,12 +202,19 @@
<activity android:name=".PhoneAccountPreferencesActivity"
android:label="@string/phone_account_preferences_title"
- android:configChanges="orientation|screenSize|keyboardHidden">
- android:exported="true" >
+ android:configChanges="orientation|screenSize|keyboardHidden"
+ android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</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>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index b9f3999..b9ffa44 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -36,8 +36,7 @@
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Бърз отговор"</string>
<string name="respond_via_sms_menu_reset_default_activity" msgid="1461742052902053466">"Възст. на станд. настройки"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"До <xliff:g id="PHONE_NUMBER">%s</xliff:g> бе изпратено съобщение."</string>
- <!-- no translation found for phone_account_preferences_title (5042332049625236956) -->
- <skip />
+ <string name="phone_account_preferences_title" msgid="5042332049625236956">"Настройки на профила за телефона"</string>
<string name="default_outgoing_account_title" msgid="8261079649574578970">"Стандартен профил за изходящи обаждания"</string>
<string name="sim_call_manager_account" msgid="2559930293628077755">"Профил за обаждане през Wi-Fi"</string>
<string name="account_ask_every_time" msgid="944077828070287407">"Извеждане на запитване всеки път"</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 364dcbc..92ef8a6 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -41,5 +41,5 @@
<string name="sim_call_manager_account" msgid="2559930293628077755">"Konto für WLAN-Anrufe"</string>
<string name="account_ask_every_time" msgid="944077828070287407">"Jedes Mal fragen"</string>
<string name="do_not_use_sim_call_manager" msgid="5519252524007323694">"Keine WLAN-Anrufe nutzen"</string>
- <string name="outgoing_call_not_allowed" msgid="1434784869685645427">"Dieser Nutzer darf abgesehen von Notrufen keine Telefonanrufe tätigen."</string>
+ <string name="outgoing_call_not_allowed" msgid="1434784869685645427">"Dieser Nutzer darf abgesehen von Notrufen keine Anrufe tätigen."</string>
</resources>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 2083071..b7344f9 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -36,8 +36,7 @@
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Pikavastaukset"</string>
<string name="respond_via_sms_menu_reset_default_activity" msgid="1461742052902053466">"Palauta oletussovellus"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Viesti lähetetty numeroon <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
- <!-- no translation found for phone_account_preferences_title (5042332049625236956) -->
- <skip />
+ <string name="phone_account_preferences_title" msgid="5042332049625236956">"Puhelintilin asetukset"</string>
<string name="default_outgoing_account_title" msgid="8261079649574578970">"Lähtevien puheluiden oletustili"</string>
<string name="sim_call_manager_account" msgid="2559930293628077755">"Wi-Fi-puhelutili"</string>
<string name="account_ask_every_time" msgid="944077828070287407">"Kysy aina"</string>
diff --git a/res/values-ka-rGE/strings.xml b/res/values-ka-rGE/strings.xml
index b5f7def..a5b7315 100644
--- a/res/values-ka-rGE/strings.xml
+++ b/res/values-ka-rGE/strings.xml
@@ -36,8 +36,7 @@
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"სწრაფი პასუხი"</string>
<string name="respond_via_sms_menu_reset_default_activity" msgid="1461742052902053466">"ნაგულისხმევი აპის ისევ დაყენება"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"შეტყობინება გაიგზავნა <xliff:g id="PHONE_NUMBER">%s</xliff:g>-თან."</string>
- <!-- no translation found for phone_account_preferences_title (5042332049625236956) -->
- <skip />
+ <string name="phone_account_preferences_title" msgid="5042332049625236956">"ტელეფონის ანგარიშის პარამეტრები"</string>
<string name="default_outgoing_account_title" msgid="8261079649574578970">"ნაგულისხმევი გამავალი ანგარიში"</string>
<string name="sim_call_manager_account" msgid="2559930293628077755">"ანგარიში Wi-Fi დარეკვისთვის"</string>
<string name="account_ask_every_time" msgid="944077828070287407">"მკითხე ყოველ ჯერზე"</string>
diff --git a/res/values-ms-rMY/strings.xml b/res/values-ms-rMY/strings.xml
index 882c775..a3c49cc 100644
--- a/res/values-ms-rMY/strings.xml
+++ b/res/values-ms-rMY/strings.xml
@@ -36,8 +36,7 @@
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Respons pantas"</string>
<string name="respond_via_sms_menu_reset_default_activity" msgid="1461742052902053466">"Tetapkan semula apl lalai"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Mesej dihantar ke <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
- <!-- no translation found for phone_account_preferences_title (5042332049625236956) -->
- <skip />
+ <string name="phone_account_preferences_title" msgid="5042332049625236956">"Tetapan akaun telefon"</string>
<string name="default_outgoing_account_title" msgid="8261079649574578970">"Akaun keluar lalai"</string>
<string name="sim_call_manager_account" msgid="2559930293628077755">"Akaun panggilan Wi-Fi"</string>
<string name="account_ask_every_time" msgid="944077828070287407">"Tanya setiap kali"</string>
diff --git a/res/values-ne-rNP/strings.xml b/res/values-ne-rNP/strings.xml
index 37e185e..0fe8775 100644
--- a/res/values-ne-rNP/strings.xml
+++ b/res/values-ne-rNP/strings.xml
@@ -36,11 +36,10 @@
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"द्रुत प्रतिक्रिया"</string>
<string name="respond_via_sms_menu_reset_default_activity" msgid="1461742052902053466">"पूर्वनिर्धारित अनुप्रयोग पुनःसेट गर्नुहोस्"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"<xliff:g id="PHONE_NUMBER">%s</xliff:g> लाई सन्देश पठाइयो।"</string>
- <!-- no translation found for phone_account_preferences_title (5042332049625236956) -->
- <skip />
+ <string name="phone_account_preferences_title" msgid="5042332049625236956">"फोन खाता सेटिङहरू"</string>
<string name="default_outgoing_account_title" msgid="8261079649574578970">"बहिर्गमन पूर्वनिर्धारित खाता"</string>
<string name="sim_call_manager_account" msgid="2559930293628077755">"वाइफाइ कल गर्ने खाता"</string>
<string name="account_ask_every_time" msgid="944077828070287407">"प्रत्येक चोटि सोध्नुहोस्"</string>
<string name="do_not_use_sim_call_manager" msgid="5519252524007323694">"वाइफाइ कल प्रयोग नगर्नुहोस्"</string>
- <string name="outgoing_call_not_allowed" msgid="1434784869685645427">"यो प्रयोगकर्ता लाई गैर-आकस्मिक फोन कल गर्न अनुमति छैन"</string>
+ <string name="outgoing_call_not_allowed" msgid="1434784869685645427">"यो प्रयोगकर्तालाई गैर-आकस्मिक फोन कल गर्न अनुमति छैन"</string>
</resources>
diff --git a/res/values-si-rLK/strings.xml b/res/values-si-rLK/strings.xml
index 95e06e2..91f9f29 100644
--- a/res/values-si-rLK/strings.xml
+++ b/res/values-si-rLK/strings.xml
@@ -36,8 +36,7 @@
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"ක්ෂණික ප්රතිචාරය"</string>
<string name="respond_via_sms_menu_reset_default_activity" msgid="1461742052902053466">"සුපුරුදු යෙදුම යළි සකසන්න"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"<xliff:g id="PHONE_NUMBER">%s</xliff:g> හට පණිවිඩය යවන්න."</string>
- <!-- no translation found for phone_account_preferences_title (5042332049625236956) -->
- <skip />
+ <string name="phone_account_preferences_title" msgid="5042332049625236956">"දුරකථන ගිණුම සැකසීම"</string>
<string name="default_outgoing_account_title" msgid="8261079649574578970">"සුපුරුදු එළියට යෑමේ ගිණුම"</string>
<string name="sim_call_manager_account" msgid="2559930293628077755">"Wi-Fi ඇමතුම් ගැනීමේ ගිණුම"</string>
<string name="account_ask_every_time" msgid="944077828070287407">"සෑම වේලාවේම අසන්න"</string>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 76f1ee8..4a5ad27 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -36,8 +36,7 @@
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"快速回复"</string>
<string name="respond_via_sms_menu_reset_default_activity" msgid="1461742052902053466">"重置默认应用"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"讯息已发送至 <xliff:g id="PHONE_NUMBER">%s</xliff:g>。"</string>
- <!-- no translation found for phone_account_preferences_title (5042332049625236956) -->
- <skip />
+ <string name="phone_account_preferences_title" msgid="5042332049625236956">"电话帐户设置"</string>
<string name="default_outgoing_account_title" msgid="8261079649574578970">"默认拨出帐户"</string>
<string name="sim_call_manager_account" msgid="2559930293628077755">"WLAN通话帐户"</string>
<string name="account_ask_every_time" msgid="944077828070287407">"每次都询问"</string>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index 650776d..26516e4 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -41,5 +41,5 @@
<string name="sim_call_manager_account" msgid="2559930293628077755">"Wi-Fi 通話帳戶"</string>
<string name="account_ask_every_time" msgid="944077828070287407">"每次都詢問"</string>
<string name="do_not_use_sim_call_manager" msgid="5519252524007323694">"不要使用 Wi-Fi 通話功能"</string>
- <string name="outgoing_call_not_allowed" msgid="1434784869685645427">"這位使用者只能撥打緊急電話"</string>
+ <string name="outgoing_call_not_allowed" msgid="1434784869685645427">"這位使用者只可撥打緊急電話"</string>
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 8f4a2e8..d50d830 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -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. -->
diff --git a/res/values/styles.xml b/res/values/styles.xml
new file mode 100644
index 0000000..6b6c1bb
--- /dev/null
+++ b/res/values/styles.xml
@@ -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>
diff --git a/src/com/android/telecomm/Call.java b/src/com/android/telecomm/Call.java
index 4fa39e8..dc3fa07 100644
--- a/src/com/android/telecomm/Call.java
+++ b/src/com/android/telecomm/Call.java
@@ -616,7 +616,9 @@
}
@Override
- public void handleCreateConnectionSuccess(ParcelableConnection connection) {
+ public void handleCreateConnectionSuccess(
+ CallIdMapper idMapper,
+ ParcelableConnection connection) {
Log.v(this, "handleCreateConnectionSuccessful %s", connection);
mCreateConnectionProcessor = null;
setTargetPhoneAccount(connection.getPhoneAccount());
@@ -630,6 +632,11 @@
setAudioModeIsVoip(connection.getAudioModeIsVoip());
setStatusHints(connection.getStatusHints());
+ mConferenceableCalls.clear();
+ for (String id : connection.getConferenceableConnectionIds()) {
+ mConferenceableCalls.add(idMapper.getCall(id));
+ }
+
if (mIsIncoming) {
// We do not handle incoming calls immediately when they are verified by the connection
// service. We allow the caller-info-query code to execute first so that we can read the
diff --git a/src/com/android/telecomm/CallActivity.java b/src/com/android/telecomm/CallActivity.java
index 95dee18..0d36c8a 100644
--- a/src/com/android/telecomm/CallActivity.java
+++ b/src/com/android/telecomm/CallActivity.java
@@ -26,6 +26,7 @@
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 @@
* 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 @@
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 @@
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/ConnectionServiceWrapper.java b/src/com/android/telecomm/ConnectionServiceWrapper.java
index 7d1f01a..5fcb9bd 100644
--- a/src/com/android/telecomm/ConnectionServiceWrapper.java
+++ b/src/com/android/telecomm/ConnectionServiceWrapper.java
@@ -894,7 +894,8 @@
} else {
// Successful connection
if (mPendingResponses.containsKey(callId)) {
- mPendingResponses.remove(callId).handleCreateConnectionSuccess(connection);
+ mPendingResponses.remove(callId)
+ .handleCreateConnectionSuccess(mCallIdMapper, connection);
}
}
}
diff --git a/src/com/android/telecomm/CreateConnectionProcessor.java b/src/com/android/telecomm/CreateConnectionProcessor.java
index d8fd00a..cc2e8c0 100644
--- a/src/com/android/telecomm/CreateConnectionProcessor.java
+++ b/src/com/android/telecomm/CreateConnectionProcessor.java
@@ -272,7 +272,9 @@
}
@Override
- public void handleCreateConnectionSuccess(ParcelableConnection connection) {
+ public void handleCreateConnectionSuccess(
+ CallIdMapper idMapper,
+ ParcelableConnection connection) {
if (mResponse == null) {
// Nobody is listening for this connection attempt any longer; ask the responsible
// ConnectionService to tear down any resources associated with the call
@@ -280,7 +282,7 @@
} else {
// Success -- share the good news and remember that we are no longer interested
// in hearing about any more attempts
- mResponse.handleCreateConnectionSuccess(connection);
+ mResponse.handleCreateConnectionSuccess(idMapper, connection);
mResponse = null;
}
}
diff --git a/src/com/android/telecomm/CreateConnectionResponse.java b/src/com/android/telecomm/CreateConnectionResponse.java
index b907e3a..13d1573 100644
--- a/src/com/android/telecomm/CreateConnectionResponse.java
+++ b/src/com/android/telecomm/CreateConnectionResponse.java
@@ -22,6 +22,6 @@
* A callback for providing the result of creating a connection.
*/
interface CreateConnectionResponse {
- void handleCreateConnectionSuccess(ParcelableConnection connection);
+ void handleCreateConnectionSuccess(CallIdMapper idMapper, ParcelableConnection connection);
void handleCreateConnectionFailure(int code, String message);
}
diff --git a/src/com/android/telecomm/ErrorDialogActivity.java b/src/com/android/telecomm/ErrorDialogActivity.java
new file mode 100644
index 0000000..098a15f
--- /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 a45f4ef..1c44fb2 100644
--- a/src/com/android/telecomm/NewOutgoingCallIntentBroadcaster.java
+++ b/src/com/android/telecomm/NewOutgoingCallIntentBroadcaster.java
@@ -26,6 +26,7 @@
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 @@
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 @@
* - 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 @@
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 @@
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 @@
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 @@
}
broadcastIntent(intent, handle, context, !callImmediately);
- return true;
+ return DisconnectCause.NOT_DISCONNECTED;
}
/**
diff --git a/src/com/android/telecomm/PhoneAccountPreferencesActivity.java b/src/com/android/telecomm/PhoneAccountPreferencesActivity.java
index 9d30b87..7b64631 100644
--- a/src/com/android/telecomm/PhoneAccountPreferencesActivity.java
+++ b/src/com/android/telecomm/PhoneAccountPreferencesActivity.java
@@ -57,7 +57,7 @@
mDefaultOutgoingAccount.setModel(
registrar,
registrar.getOutgoingPhoneAccounts(),
- registrar.getDefaultOutgoingPhoneAccount(),
+ registrar.getUserSelectedOutgoingPhoneAccount(),
getString(R.string.account_ask_every_time));
mSimCallManagerAccount.setModel(
diff --git a/src/com/android/telecomm/PhoneAccountRegistrar.java b/src/com/android/telecomm/PhoneAccountRegistrar.java
index db05fff..f7cce27 100644
--- a/src/com/android/telecomm/PhoneAccountRegistrar.java
+++ b/src/com/android/telecomm/PhoneAccountRegistrar.java
@@ -65,6 +65,9 @@
*/
public final class PhoneAccountRegistrar {
+ public static final PhoneAccountHandle NO_ACCOUNT_SELECTED =
+ new PhoneAccountHandle(new ComponentName("null", "null"), "NO_ACCOUNT_SELECTED");
+
public abstract static class Listener {
public void onAccountsChanged(PhoneAccountRegistrar registrar) {}
public void onDefaultOutgoingChanged(PhoneAccountRegistrar registrar) {}
@@ -92,16 +95,9 @@
}
public PhoneAccountHandle getDefaultOutgoingPhoneAccount() {
- if (mState.defaultOutgoing != null) {
- // Return the registered outgoing default iff it still exists (we keep a sticky
- // default to survive account deletion and re-addition)
- for (int i = 0; i < mState.accounts.size(); i++) {
- if (mState.accounts.get(i).getAccountHandle().equals(mState.defaultOutgoing)) {
- return mState.defaultOutgoing;
- }
- }
- // At this point, there was a registered default but it has been deleted; proceed
- // as though there were no default
+ final PhoneAccountHandle userSelected = getUserSelectedOutgoingPhoneAccount();
+ if (userSelected != null) {
+ return userSelected;
}
List<PhoneAccountHandle> outgoing = getOutgoingPhoneAccounts();
@@ -118,6 +114,21 @@
}
}
+ PhoneAccountHandle getUserSelectedOutgoingPhoneAccount() {
+ if (mState.defaultOutgoing != null) {
+ // Return the registered outgoing default iff it still exists (we keep a sticky
+ // default to survive account deletion and re-addition)
+ for (int i = 0; i < mState.accounts.size(); i++) {
+ if (mState.accounts.get(i).getAccountHandle().equals(mState.defaultOutgoing)) {
+ return mState.defaultOutgoing;
+ }
+ }
+ // At this point, there was a registered default but it has been deleted; proceed
+ // as though there were no default
+ }
+ return null;
+ }
+
public void setDefaultOutgoingPhoneAccount(PhoneAccountHandle accountHandle) {
if (accountHandle == null) {
// Asking to clear the default outgoing is a valid request
@@ -164,8 +175,11 @@
Log.d(this, "setSimCallManager: Not a call manager: %s", callManagerAccount);
return;
}
+ } else {
+ callManager = NO_ACCOUNT_SELECTED;
}
mState.simCallManager = callManager;
+
write();
fireSimCallManagerChanged();
}
@@ -176,6 +190,9 @@
}
if (mState.simCallManager != null) {
+ if (NO_ACCOUNT_SELECTED.equals(mState.simCallManager)) {
+ return null;
+ }
// Return the registered sim call manager iff it still exists (we keep a sticky
// setting to survive account deletion and re-addition)
for (int i = 0; i < mState.accounts.size(); i++) {
diff --git a/src/com/android/telecomm/ProximitySensorManager.java b/src/com/android/telecomm/ProximitySensorManager.java
index c6b018a..287c6d4 100644
--- a/src/com/android/telecomm/ProximitySensorManager.java
+++ b/src/com/android/telecomm/ProximitySensorManager.java
@@ -74,7 +74,7 @@
if (mProximityWakeLock.isHeld()) {
Log.i(this, "Releasing proximity wake lock");
int flags =
- (screenOnImmediately ? 0 : PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE);
+ (screenOnImmediately ? 0 : PowerManager.WAIT_FOR_DISTANT_PROXIMITY);
mProximityWakeLock.release(flags);
} else {
Log.i(this, "Proximity wake lock already released");
diff --git a/src/com/android/telecomm/TelecommServiceImpl.java b/src/com/android/telecomm/TelecommServiceImpl.java
index 7af1534..05f0e0a 100644
--- a/src/com/android/telecomm/TelecommServiceImpl.java
+++ b/src/com/android/telecomm/TelecommServiceImpl.java
@@ -29,7 +29,7 @@
import android.os.Looper;
import android.os.Message;
import android.os.ServiceManager;
-import android.phone.PhoneManager;
+import android.os.UserHandle;
import android.telecomm.CallState;
import android.telecomm.PhoneAccount;
import android.telecomm.PhoneAccountHandle;
@@ -250,10 +250,10 @@
}
/**
- * @see TelecommManager#isInAPhoneCall
+ * @see TelecommManager#isInCall
*/
@Override
- public boolean isInAPhoneCall() {
+ public boolean isInCall() {
enforceReadPermission();
// Do not use sendRequest() with this method since it could cause a deadlock with
// audio service, which we call into from the main thread: AudioManager.setMode().
@@ -288,16 +288,16 @@
}
/**
- * @see PhoneManager#showCallScreen
+ * @see TelecommManager#showInCallScreen
*/
@Override
- public void showCallScreen(boolean showDialpad) {
+ public void showInCallScreen(boolean showDialpad) {
enforceReadPermissionOrDefaultDialer();
sendRequestAsync(MSG_SHOW_CALL_SCREEN, showDialpad ? 1 : 0);
}
/**
- * @see PhoneManager#cancelMissedCallsNotification
+ * @see TelecommManager#cancelMissedCallsNotification
*/
@Override
public void cancelMissedCallsNotification() {
@@ -306,7 +306,7 @@
}
/**
- * @see PhoneManager#handlePinMmi
+ * @see TelecommManager#handleMmi
*/
@Override
public boolean handlePinMmi(String dialString) {
@@ -356,7 +356,7 @@
}
long token = Binder.clearCallingIdentity();
- TelecommApp.getInstance().startActivity(intent);
+ TelecommApp.getInstance().startActivityAsUser(intent, UserHandle.CURRENT);
Binder.restoreCallingIdentity(token);
}
}
@@ -441,10 +441,6 @@
mAppOpsManager.checkPackage(Binder.getCallingUid(), packageName);
}
- private void showCallScreenInternal(boolean showDialpad) {
- CallsManager.getInstance().getInCallController().bringToForeground(showDialpad);
- }
-
private boolean isDefaultDialerCalling() {
ComponentName defaultDialerComponent = getDefaultPhoneApp();
if (defaultDialerComponent != null) {
diff --git a/tests/src/com/android/telecomm/testapps/CallNotificationReceiver.java b/tests/src/com/android/telecomm/testapps/CallNotificationReceiver.java
index e941c2d..fb44069 100644
--- a/tests/src/com/android/telecomm/testapps/CallNotificationReceiver.java
+++ b/tests/src/com/android/telecomm/testapps/CallNotificationReceiver.java
@@ -70,7 +70,7 @@
private void sendIncomingCallIntent(Context context, boolean isVideoCall) {
PhoneAccountHandle phoneAccount = new PhoneAccountHandle(
new ComponentName(context, TestConnectionService.class),
- CallServiceNotifier.CALL_PROVIDER_ID);
+ CallServiceNotifier.SIM_SUBSCRIPTION_ID);
// For the purposes of testing, indicate whether the incoming call is a video call by
// stashing an indicator in the EXTRA_INCOMING_CALL_EXTRAS.
diff --git a/tests/src/com/android/telecomm/testapps/TestConnectionManager.java b/tests/src/com/android/telecomm/testapps/TestConnectionManager.java
index 902ace7..95f0718 100644
--- a/tests/src/com/android/telecomm/testapps/TestConnectionManager.java
+++ b/tests/src/com/android/telecomm/testapps/TestConnectionManager.java
@@ -19,28 +19,28 @@
import android.app.PendingIntent;
import android.net.Uri;
import android.telecomm.AudioState;
+import android.telecomm.Conference;
import android.telecomm.Connection;
import android.telecomm.ConnectionRequest;
import android.telecomm.ConnectionService;
import android.telecomm.PhoneAccountHandle;
+import android.telecomm.RemoteConference;
import android.telecomm.RemoteConnection;
import android.telecomm.StatusHints;
import android.util.Log;
-import java.util.Random;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
/**
* Service which acts as a fake ConnectionManager if so configured.
* TODO(santoscordon): Rename all classes in the directory to Dummy* (e.g., DummyConnectionService).
*/
public class TestConnectionManager extends ConnectionService {
- /**
- * Random number generator used to generate phone numbers.
- */
- private Random mRandom = new Random();
-
- private final class TestManagedConnection extends Connection {
- private final RemoteConnection.Listener mProxyListener = new RemoteConnection.Listener() {
+ public final class TestManagedConnection extends Connection {
+ private final RemoteConnection.Listener mRemoteListener = new RemoteConnection.Listener() {
@Override
public void onStateChanged(RemoteConnection connection, int state) {
setState(state);
@@ -103,62 +103,76 @@
@Override
public void onDestroyed(RemoteConnection connection) {
destroy();
+ mManagedConnectionByRemote.remove(mRemote);
+ }
+
+ @Override
+ public void onConferenceableConnectionsChanged(
+ RemoteConnection connect,
+ List<RemoteConnection> conferenceable) {
+ List<Connection> c = new ArrayList<>();
+ for (RemoteConnection remote : conferenceable) {
+ if (mManagedConnectionByRemote.containsKey(remote)) {
+ c.add(mManagedConnectionByRemote.get(remote));
+ }
+ }
+ setConferenceableConnections(c);
}
};
- private final RemoteConnection mRemoteConnection;
+ private final RemoteConnection mRemote;
private final boolean mIsIncoming;
- TestManagedConnection(RemoteConnection remoteConnection, boolean isIncoming) {
- mRemoteConnection = remoteConnection;
+ TestManagedConnection(RemoteConnection remote, boolean isIncoming) {
+ mRemote = remote;
mIsIncoming = isIncoming;
- mRemoteConnection.addListener(mProxyListener);
- setState(mRemoteConnection.getState());
+ mRemote.addListener(mRemoteListener);
+ setState(mRemote.getState());
}
@Override
public void onAbort() {
- mRemoteConnection.abort();
+ mRemote.abort();
}
/** ${inheritDoc} */
@Override
public void onAnswer(int videoState) {
- mRemoteConnection.answer(videoState);
+ mRemote.answer(videoState);
}
/** ${inheritDoc} */
@Override
public void onDisconnect() {
- mRemoteConnection.disconnect();
+ mRemote.disconnect();
}
@Override
public void onPlayDtmfTone(char c) {
- mRemoteConnection.playDtmfTone(c);
+ mRemote.playDtmfTone(c);
}
/** ${inheritDoc} */
@Override
public void onHold() {
- mRemoteConnection.hold();
+ mRemote.hold();
}
/** ${inheritDoc} */
@Override
public void onReject() {
- mRemoteConnection.reject();
+ mRemote.reject();
}
/** ${inheritDoc} */
@Override
public void onUnhold() {
- mRemoteConnection.unhold();
+ mRemote.unhold();
}
@Override
public void onSetAudioState(AudioState state) {
- mRemoteConnection.setAudioState(state);
+ mRemote.setAudioState(state);
}
private void setState(int state) {
@@ -180,29 +194,125 @@
}
}
+ public final class TestManagedConference extends Conference {
+ private final RemoteConference.Listener mRemoteListener = new RemoteConference.Listener() {
+ @Override
+ public void onStateChanged(RemoteConference conference, int oldState, int newState) {
+ switch (newState) {
+ case Connection.STATE_DISCONNECTED:
+ // See onDisconnected below
+ break;
+ case Connection.STATE_HOLDING:
+ setOnHold();
+ break;
+ case Connection.STATE_ACTIVE:
+ setActive();
+ break;
+ default:
+ log("unrecognized state for Conference: " + newState);
+ break;
+ }
+ }
+
+ @Override
+ public void onDisconnected(RemoteConference conference, int cause, String message) {
+ setDisconnected(cause, message);
+ }
+
+ @Override
+ public void onConnectionAdded(
+ RemoteConference conference,
+ RemoteConnection connection) {
+ TestManagedConnection c = mManagedConnectionByRemote.get(connection);
+ if (c == null) {
+ log("onConnectionAdded cannot find remote connection: " + connection);
+ } else {
+ addConnection(c);
+ }
+ }
+
+ @Override
+ public void onConnectionRemoved(
+ RemoteConference conference,
+ RemoteConnection connection) {
+ TestManagedConnection c = mManagedConnectionByRemote.get(connection);
+ if (c == null) {
+ log("onConnectionRemoved cannot find remote connection: " + connection);
+ } else {
+ removeConnection(c);
+ }
+ }
+
+ @Override
+ public void onCapabilitiesChanged(RemoteConference conference, int capabilities) {
+ setCapabilities(capabilities);
+ }
+
+ @Override
+ public void onDestroyed(RemoteConference conference) {
+ destroy();
+ mRemote.removeListener(mRemoteListener);
+ mManagedConferenceByRemote.remove(mRemote);
+ }
+ };
+
+ private final RemoteConference mRemote;
+
+ public TestManagedConference(RemoteConference remote) {
+ super(null);
+ mRemote = remote;
+ remote.addListener(mRemoteListener);
+ setActive();
+ for (RemoteConnection r : remote.getConnections()) {
+ TestManagedConnection c = mManagedConnectionByRemote.get(r);
+ if (c != null) {
+ addConnection(c);
+ }
+ }
+ }
+ }
+
private static void log(String msg) {
Log.w("telecomtestcs", "[TestConnectionManager] " + msg);
}
+ private final Map<RemoteConference, TestManagedConference> mManagedConferenceByRemote
+ = new HashMap<>();
+ private final Map<RemoteConnection, TestManagedConnection> mManagedConnectionByRemote
+ = new HashMap<>();
+
@Override
public Connection onCreateOutgoingConnection(
PhoneAccountHandle connectionManagerAccount,
final ConnectionRequest request) {
- return new TestManagedConnection(
- createRemoteOutgoingConnection(
- request.getAccountHandle(),
- request),
- false);
+ return makeConnection(request, false);
}
@Override
public Connection onCreateIncomingConnection(
PhoneAccountHandle connectionManagerAccount,
final ConnectionRequest request) {
- return new TestManagedConnection(
- createRemoteIncomingConnection(
- request.getAccountHandle(),
- request),
- true);
+ return makeConnection(request, true);
+ }
+
+ @Override
+ public void onConference(Connection a, Connection b) {
+ conferenceRemoteConnections(
+ ((TestManagedConnection) a).mRemote,
+ ((TestManagedConnection) b).mRemote);
+ }
+
+ @Override
+ public void onRemoteConferenceAdded(RemoteConference remoteConference) {
+ addConference(new TestManagedConference(remoteConference));
+ }
+
+ private Connection makeConnection(ConnectionRequest request, boolean incoming) {
+ RemoteConnection remote = incoming
+ ? createRemoteIncomingConnection(request.getAccountHandle(), request)
+ : createRemoteOutgoingConnection(request.getAccountHandle(), request);
+ TestManagedConnection local = new TestManagedConnection(remote, false);
+ mManagedConnectionByRemote.put(remote, local);
+ return local;
}
}
diff --git a/tests/src/com/android/telecomm/testapps/TestConnectionService.java b/tests/src/com/android/telecomm/testapps/TestConnectionService.java
index 09a8929..c50e7ab 100644
--- a/tests/src/com/android/telecomm/testapps/TestConnectionService.java
+++ b/tests/src/com/android/telecomm/testapps/TestConnectionService.java
Binary files differ