Merge "Protect against INCALL->RINGING transition in AudioManager" into lmp-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 3877edf..5d11fb3 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -36,6 +36,7 @@
<uses-permission android:name="android.permission.BIND_CONNECTION_SERVICE" />
<uses-permission android:name="android.permission.BIND_INCALL_SERVICE" />
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
+ <uses-permission android:name="android.permission.BROADCAST_CALLLOG_INFO" />
<!-- Protects the ability to register any PhoneAccount with a capability flags of either
PhoneAccount#CAPABILITY_CALL_PROVIDER or PhoneAccount#CAPABILITY_SIM_SUBSCRIPTION. -->
@@ -44,6 +45,16 @@
android:label="Register CALL_PROVIDER or SIM_SUBSCRIPTION PhoneAccount"
android:protectionLevel="signature"/>
+ <permission
+ android:name="android.permission.BROADCAST_CALLLOG_INFO"
+ android:label="Broadcast the call type/duration information"
+ android:protectionLevel="signature|system"/>
+
+ <permission
+ android:name="android.permission.PROCESS_CALLLOG_INFO"
+ android:label="Register to handle the broadcasted call type/duration information"
+ android:protectionLevel="signature|system"/>
+
<!-- Declare which SDK level this application was built against. This is needed so that IDEs
can check for incompatible APIs. -->
<uses-sdk android:minSdkVersion="19" />
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index debd49b..f49074f 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -30,15 +30,15 @@
<string name="respond_via_sms_canned_response_2" msgid="4074450431532859214">"मैं आपको वापस कॉल करूंगा/करूंगी."</string>
<string name="respond_via_sms_canned_response_3" msgid="3496079065723960450">"मैं आपको बाद में कॉल करूंगा/करूंगी."</string>
<string name="respond_via_sms_canned_response_4" msgid="1698989243040062190">"अभी बात नहीं हो सकती. बाद में कॉल करें?"</string>
- <string name="respond_via_sms_setting_title" msgid="3754000371039709383">"त्वरित प्रतिसाद"</string>
- <string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"त्वरित प्रतिसाद संपादित करें"</string>
+ <string name="respond_via_sms_setting_title" msgid="3754000371039709383">"झटपट उत्तर"</string>
+ <string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"झटपट उत्तर संपादित करें"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
- <string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"त्वरित प्रतिसाद"</string>
+ <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>
<string name="outgoing_call_not_allowed" msgid="1434784869685645427">"इस उपयोगकर्ता को गैर-आपातकालीन फ़ोन कॉल करने की अनुमति नहीं है"</string>
<string name="outgoing_call_error_no_phone_number_supplied" msgid="4987143284589568716">"कॉल नहीं भेजा गया, कोई मान्य नंबर नहीं डाला गया था."</string>
- <string name="no_vm_number" msgid="4164780423805688336">"गुम ध्वनिमेल नंबर"</string>
- <string name="no_vm_number_msg" msgid="1300729501030053828">"सिम कार्ड पर कोई ध्वनिमेल नंबर संग्रहीत नहीं है."</string>
+ <string name="no_vm_number" msgid="4164780423805688336">"गुम वॉयस मेल नंबर"</string>
+ <string name="no_vm_number_msg" msgid="1300729501030053828">"सिम कार्ड पर कोई वॉयस मेल नंबर संग्रहीत नहीं है."</string>
<string name="add_vm_number_str" msgid="4676479471644687453">"नंबर जोड़ें"</string>
</resources>
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index edb3a38..a0a8a62 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -557,8 +557,12 @@
}
void setCallCapabilities(int callCapabilities) {
+ setCallCapabilities(callCapabilities, false /* forceUpdate */);
+ }
+
+ void setCallCapabilities(int callCapabilities, boolean forceUpdate) {
Log.v(this, "setCallCapabilities: %s", PhoneCapabilities.toString(callCapabilities));
- if (mCallCapabilities != callCapabilities) {
+ if (forceUpdate || mCallCapabilities != callCapabilities) {
mCallCapabilities = callCapabilities;
for (Listener l : mListeners) {
l.onCallCapabilitiesChanged(this);
diff --git a/src/com/android/server/telecom/CallAudioManager.java b/src/com/android/server/telecom/CallAudioManager.java
index 719e525..a89dcea 100644
--- a/src/com/android/server/telecom/CallAudioManager.java
+++ b/src/com/android/server/telecom/CallAudioManager.java
@@ -330,7 +330,7 @@
}
private void updateAudioStreamAndMode() {
- Log.v(this, "updateAudioStreamAndMode, mIsRinging: %b, mIsTonePlaying: %b", mIsRinging,
+ Log.i(this, "updateAudioStreamAndMode, mIsRinging: %b, mIsTonePlaying: %b", mIsRinging,
mIsTonePlaying);
if (mIsRinging) {
requestAudioFocusAndSetMode(AudioManager.STREAM_RING, AudioManager.MODE_RINGTONE);
@@ -359,7 +359,7 @@
}
private void requestAudioFocusAndSetMode(int stream, int mode) {
- Log.v(this, "requestAudioFocusAndSetMode, stream: %d -> %d", mAudioFocusStreamType, stream);
+ Log.i(this, "requestAudioFocusAndSetMode, stream: %d -> %d", mAudioFocusStreamType, stream);
Preconditions.checkState(stream != STREAM_NONE);
// Even if we already have focus, if the stream is different we update audio manager to give
diff --git a/src/com/android/server/telecom/CallLogManager.java b/src/com/android/server/telecom/CallLogManager.java
old mode 100644
new mode 100755
index 89d9316..658af10
--- a/src/com/android/server/telecom/CallLogManager.java
+++ b/src/com/android/server/telecom/CallLogManager.java
@@ -17,6 +17,8 @@
package com.android.server.telecom;
import android.content.Context;
+import android.content.Intent;
+import android.Manifest.permission;
import android.net.Uri;
import android.os.AsyncTask;
import android.provider.CallLog.Calls;
@@ -83,6 +85,12 @@
private static final String TAG = CallLogManager.class.getSimpleName();
private final Context mContext;
+ private static final String ACTION_CALLS_TABLE_ADD_ENTRY =
+ "com.android.server.telecom.intent.action.CALLS_ADD_ENTRY";
+ private static final String PERMISSION_PROCESS_CALLLOG_INFO =
+ "android.permission.PROCESS_CALLLOG_INFO";
+ private static final String CALL_TYPE = "callType";
+ private static final String CALL_DURATION = "duration";
public CallLogManager(Context context) {
mContext = context;
@@ -174,6 +182,8 @@
// Don't log emergency numbers if the device doesn't allow it.
final boolean isOkToLogThisCall = !isEmergencyNumber || okToLogEmergencyNumber;
+ sendAddCallBroadcast(callType, duration);
+
if (isOkToLogThisCall) {
Log.d(TAG, "Logging Calllog entry: " + callerInfo + ", "
+ Log.pii(number) + "," + presentation + ", " + callType
@@ -293,4 +303,11 @@
}
}
}
+
+ private void sendAddCallBroadcast(int callType, long duration) {
+ Intent callAddIntent = new Intent(ACTION_CALLS_TABLE_ADD_ENTRY);
+ callAddIntent.putExtra(CALL_TYPE, callType);
+ callAddIntent.putExtra(CALL_DURATION, duration);
+ mContext.sendBroadcast(callAddIntent, PERMISSION_PROCESS_CALLLOG_INFO);
+ }
}
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index 932084b..d714a6b 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -447,12 +447,7 @@
call.setExtras(extras);
// Do not add the call if it is a potential MMI code.
- // We also want to skip adding the call if there is a broadcast receiver which could
- // intercept the outgoing call and cancel it. We do this to ensure that we do not show the
- // InCall UI for the cancelled call. If the call is not intercepted, it will be added in
- // {@link CallsManager#onSuccessfulOutgoingCall}.
- if (isPotentialMMICode(handle) || isPotentialInCallMMICode ||
- (!isEmergencyCall && canOutgoingCallBroadcastsBeIntercepted())) {
+ if (isPotentialMMICode(handle) || isPotentialInCallMMICode) {
call.addListener(this);
} else {
addCall(call);
@@ -1001,6 +996,14 @@
}
updateForegroundCall();
}
+
+ // Now that a call has been removed, other calls may gain new call capabilities (for
+ // example, if only one call is left, it is now add-call capable again). Trigger the
+ // recalculation of the call's current capabilities by forcing an update. (See
+ // InCallController.toParcelableCall()).
+ for (Call otherCall : mCalls) {
+ otherCall.setCallCapabilities(call.getCallCapabilities(), true /* forceUpdate */);
+ }
}
/**
@@ -1203,28 +1206,6 @@
}
/**
- * Determines if the {@link Intent#ACTION_NEW_OUTGOING_CALL} intent can be received by another
- * package with priority 0, potentially providing the ability to cancel the intent before it
- * is received.
- *
- * @return {@code true} if the intent can be intercepted by another
- */
- private boolean canOutgoingCallBroadcastsBeIntercepted() {
- PackageManager packageManager = mContext.getPackageManager();
- Intent intent = new Intent(Intent.ACTION_NEW_OUTGOING_CALL);
- List<ResolveInfo> receivers = packageManager.queryBroadcastReceivers(intent, 0);
-
- for (ResolveInfo info : receivers) {
- // Check for an interceptor with priority 0; this would potentially receive the
- // broadcast before Telecom and cancel it.
- if (info.priority == 0) {
- return true;
- }
- }
- return false;
- }
-
- /**
* Dumps the state of the {@link CallsManager}.
*
* @param pw The {@code IndentingPrintWriter} to write the state to.
diff --git a/src/com/android/server/telecom/CreateConnectionProcessor.java b/src/com/android/server/telecom/CreateConnectionProcessor.java
index 0c6e25d..fab2679 100644
--- a/src/com/android/server/telecom/CreateConnectionProcessor.java
+++ b/src/com/android/server/telecom/CreateConnectionProcessor.java
@@ -238,6 +238,18 @@
Log.i(this, "Emergency number detected");
mAttemptRecords.clear();
List<PhoneAccount> allAccounts = mPhoneAccountRegistrar.getAllPhoneAccounts();
+
+ if (allAccounts.isEmpty()) {
+ // If the list of phone accounts is empty at this point, it means Telephony hasn't
+ // registered any phone accounts yet. Add a fallback emergency phone account so
+ // that emergency calls can still go through. We create a new ArrayLists here just
+ // in case the implementation of PhoneAccountRegistrar ever returns an unmodifiable
+ // list.
+ allAccounts = new ArrayList<PhoneAccount>();
+ allAccounts.add(TelephonyUtil.getDefaultEmergencyPhoneAccount());
+ }
+
+
// First, add SIM phone accounts which can place emergency calls.
for (PhoneAccount phoneAccount : allAccounts) {
if (phoneAccount.hasCapabilities(PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS) &&
diff --git a/src/com/android/server/telecom/MissedCallNotifier.java b/src/com/android/server/telecom/MissedCallNotifier.java
index 8abd5b7..76d0ae8 100644
--- a/src/com/android/server/telecom/MissedCallNotifier.java
+++ b/src/com/android/server/telecom/MissedCallNotifier.java
@@ -29,6 +29,7 @@
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
+import android.os.UserHandle;
import android.provider.CallLog;
import android.provider.CallLog.Calls;
import android.telecom.CallState;
@@ -166,7 +167,8 @@
configureLedOnNotification(notification);
Log.i(this, "Adding missed call notification for %s.", call);
- mNotificationManager.notify(MISSED_CALL_NOTIFICATION_ID, notification);
+ mNotificationManager.notifyAsUser(
+ null /* tag */ , MISSED_CALL_NOTIFICATION_ID, notification, UserHandle.CURRENT);
}
/** Cancels the "missed call" notification. */
diff --git a/src/com/android/server/telecom/TelephonyUtil.java b/src/com/android/server/telecom/TelephonyUtil.java
index 29b6f89..a130522 100644
--- a/src/com/android/server/telecom/TelephonyUtil.java
+++ b/src/com/android/server/telecom/TelephonyUtil.java
@@ -19,6 +19,8 @@
import android.content.ComponentName;
import android.content.Context;
import android.net.Uri;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
import android.telephony.PhoneNumberUtils;
/**
@@ -33,8 +35,25 @@
private static final String PSTN_CALL_SERVICE_CLASS_NAME =
"com.android.services.telephony.TelephonyConnectionService";
+ private static final PhoneAccountHandle DEFAULT_EMERGENCY_PHONE_ACCOUNT_HANDLE =
+ new PhoneAccountHandle(
+ new ComponentName(TELEPHONY_PACKAGE_NAME, PSTN_CALL_SERVICE_CLASS_NAME), "E");
+
private TelephonyUtil() {}
+ /**
+ * @return fallback {@link PhoneAccount} to be used by Telecom for emergency calls in the
+ * rare case that Telephony has not registered any phone accounts yet. Details about this
+ * account are not expected to be displayed in the UI, so the description, etc are not
+ * populated.
+ */
+ static PhoneAccount getDefaultEmergencyPhoneAccount() {
+ return PhoneAccount.builder(DEFAULT_EMERGENCY_PHONE_ACCOUNT_HANDLE, "E")
+ .setCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION |
+ PhoneAccount.CAPABILITY_CALL_PROVIDER |
+ PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS).build();
+ }
+
static boolean isPstnComponentName(ComponentName componentName) {
final ComponentName pstnComponentName = new ComponentName(
TELEPHONY_PACKAGE_NAME, PSTN_CALL_SERVICE_CLASS_NAME);