Merge "DO NOT MERGE - Restrict ability to add call based on device provision status" into lmp-mr1-dev am: b204dee494 am: bb2dbba478 am: b34b14a3f8 -s ours
am: c5798bda68
* commit 'c5798bda686b5273ce83ef024dc15d07419162e3':
DO NOT MERGE - Restrict ability to add call based on device provision status
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 2cf0fd8..5f5d386 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -17,7 +17,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="telecommAppLabel" product="default" msgid="9166784827254469057">"Foonoproepbestuur"</string>
- <string name="userCallActivityLabel" product="default" msgid="5415173590855187131">"Foon"</string>
+ <string name="userCallActivityLabel" product="default" msgid="5415173590855187131">"Bel"</string>
<string name="unknown" msgid="6878797917991465859">"Onbekend"</string>
<string name="notification_missedCallTitle" msgid="7554385905572364535">"Gemiste oproep"</string>
<string name="notification_missedCallsTitle" msgid="1361677948941502522">"Gemiste oproepe"</string>
diff --git a/res/values-mn-rMN/strings.xml b/res/values-mn-rMN/strings.xml
index ec359db..37f3dea 100644
--- a/res/values-mn-rMN/strings.xml
+++ b/res/values-mn-rMN/strings.xml
@@ -17,7 +17,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="telecommAppLabel" product="default" msgid="9166784827254469057">"Гар утасны Дуудлагын Удирдлага"</string>
- <string name="userCallActivityLabel" product="default" msgid="5415173590855187131">"Гар утас"</string>
+ <string name="userCallActivityLabel" product="default" msgid="5415173590855187131">"Утас"</string>
<string name="unknown" msgid="6878797917991465859">"Тодорхойгүй"</string>
<string name="notification_missedCallTitle" msgid="7554385905572364535">"Аваагүй дуудлага"</string>
<string name="notification_missedCallsTitle" msgid="1361677948941502522">"Аваагүй дуудлагууд"</string>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 06dc193..db7f713 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -39,7 +39,7 @@
<string name="enable_account_preference_title" msgid="2021848090086481720">"Oproepaccounts"</string>
<string name="outgoing_call_not_allowed_user_restriction" msgid="8504993498756056279">"Alleen noodoproepen zijn toegestaan door de apparaateigenaar."</string>
<string name="outgoing_call_not_allowed_no_permission" msgid="1996571596464271228">"Deze app kan geen uitgaande oproepen starten zonder telefoonrechten."</string>
- <string name="outgoing_call_error_no_phone_number_supplied" msgid="1940125199802007505">"Als u wilt bellen, moet u een geldig nummer invoeren."</string>
+ <string name="outgoing_call_error_no_phone_number_supplied" msgid="1940125199802007505">"Als je wilt bellen, moet je een geldig nummer invoeren."</string>
<string name="duplicate_video_call_not_allowed" msgid="3749211605014548386">"Oproep kan momenteel niet worden toegevoegd."</string>
<string name="video_call_not_allowed_if_tty_enabled" msgid="7593649283571253283">"Schakel de TTY-modus uit om videogesprekken te voeren."</string>
<string name="no_vm_number" msgid="4164780423805688336">"Voicemailnummer ontbreekt"</string>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index b3dfff6..abfbb3d 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -17,7 +17,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="telecommAppLabel" product="default" msgid="9166784827254469057">"Gestão de chamadas do telemóvel"</string>
- <string name="userCallActivityLabel" product="default" msgid="5415173590855187131">"Telemóvel"</string>
+ <string name="userCallActivityLabel" product="default" msgid="5415173590855187131">"Telefone"</string>
<string name="unknown" msgid="6878797917991465859">"Desconhecido"</string>
<string name="notification_missedCallTitle" msgid="7554385905572364535">"Chamada não atendida"</string>
<string name="notification_missedCallsTitle" msgid="1361677948941502522">"Chamadas não atendidas"</string>
diff --git a/src/com/android/server/telecom/BluetoothPhoneServiceImpl.java b/src/com/android/server/telecom/BluetoothPhoneServiceImpl.java
index 9deffbe..dab4545 100644
--- a/src/com/android/server/telecom/BluetoothPhoneServiceImpl.java
+++ b/src/com/android/server/telecom/BluetoothPhoneServiceImpl.java
@@ -767,13 +767,13 @@
case CallState.NEW:
case CallState.ABORTED:
case CallState.DISCONNECTED:
- case CallState.CONNECTING:
- case CallState.SELECT_PHONE_ACCOUNT:
return CALL_STATE_IDLE;
case CallState.ACTIVE:
return CALL_STATE_ACTIVE;
+ case CallState.CONNECTING:
+ case CallState.SELECT_PHONE_ACCOUNT:
case CallState.DIALING:
// Yes, this is correctly returning ALERTING.
// "Dialing" for BT means that we have sent information to the service provider
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index 603ea7e..6c923f2 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -365,7 +365,6 @@
mContactsAsyncHelper = contactsAsyncHelper;
mCallerInfoAsyncQueryFactory = callerInfoAsyncQueryFactory;
setHandle(handle);
- setHandle(handle, TelecomManager.PRESENTATION_ALLOWED);
mGatewayInfo = gatewayInfo;
setConnectionManagerPhoneAccount(connectionManagerPhoneAccountHandle);
setTargetPhoneAccount(targetPhoneAccountHandle);
@@ -634,8 +633,12 @@
}
}
- mIsEmergencyCall = mHandle != null && PhoneNumberUtils.isLocalEmergencyNumber(mContext,
- mHandle.getSchemeSpecificPart());
+ // Let's not allow resetting of the emergency flag. Once a call becomes an emergency
+ // call, it will remain so for the rest of it's lifetime.
+ if (!mIsEmergencyCall) {
+ mIsEmergencyCall = mHandle != null && PhoneNumberUtils.isLocalEmergencyNumber(
+ mContext, mHandle.getSchemeSpecificPart());
+ }
startCallerInfoLookup();
for (Listener l : mListeners) {
l.onHandleChanged(this);
@@ -1664,4 +1667,13 @@
}
return CallState.DISCONNECTED;
}
+
+ /**
+ * Determines if this call is in disconnected state and waiting to be destroyed.
+ *
+ * @return {@code true} if this call is disconected.
+ */
+ public boolean isDisconnected() {
+ return (getState() == CallState.DISCONNECTED || getState() == CallState.ABORTED);
+ }
}
diff --git a/src/com/android/server/telecom/CallAudioManager.java b/src/com/android/server/telecom/CallAudioManager.java
index da3deb6..23284e3 100644
--- a/src/com/android/server/telecom/CallAudioManager.java
+++ b/src/com/android/server/telecom/CallAudioManager.java
@@ -16,11 +16,19 @@
package com.android.server.telecom;
+import android.app.ActivityManagerNative;
import android.content.Context;
+import android.content.pm.UserInfo;
import android.media.AudioManager;
+import android.media.IAudioService;
+import android.os.Binder;
import android.os.Handler;
+import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
import android.telecom.CallAudioState;
import com.android.internal.util.IndentingPrintWriter;
@@ -86,9 +94,27 @@
case MSG_AUDIO_MANAGER_SET_MICROPHONE_MUTE: {
boolean mute = (msg.arg1 != 0);
if (mute != mAudioManager.isMicrophoneMute()) {
- Log.i(this, "changing microphone mute state to: %b", mute);
- mAudioManager.setMicrophoneMute(mute);
+ IAudioService audio = getAudioService();
+ Log.i(this, "changing microphone mute state to: %b [serviceIsNull=%b]",
+ mute, audio == null);
+ if (audio != null) {
+ try {
+ // We use the audio service directly here so that we can specify
+ // the current user. Telecom runs in the system_server process which
+ // may run as a separate user from the foreground user. If we
+ // used AudioManager directly, we would change mute for the system's
+ // user and not the current foreground, which we want to avoid.
+ audio.setMicrophoneMute(
+ mute, mContext.getOpPackageName(), getCurrentUserId());
+
+ } catch (RemoteException e) {
+ Log.e(this, e, "Remote exception while toggling mute.");
+ }
+ // TODO: Check microphone state after attempting to set to ensure that
+ // our state corroborates AudioManager's state.
+ }
}
+
break;
}
case MSG_AUDIO_MANAGER_REQUEST_AUDIO_FOCUS_FOR_CALL: {
@@ -520,7 +546,8 @@
Log.v(this, "updateAudioStreamAndMode : no foreground, speeding up MT audio.");
requestAudioFocusAndSetMode(AudioManager.STREAM_VOICE_CALL,
AudioManager.MODE_IN_CALL);
- } else if (foregroundCall != null && waitingForAccountSelectionCall == null) {
+ } else if (foregroundCall != null && !foregroundCall.isDisconnected() &&
+ waitingForAccountSelectionCall == null) {
// In the case where there is a call that is waiting for account selection,
// this will fall back to abandonAudioFocus() below, which temporarily exits
// the in-call audio mode. This is to allow TalkBack to speak the "Call with"
@@ -538,7 +565,7 @@
Log.v(this, "updateAudioStreamAndMode : tone playing");
requestAudioFocusAndSetMode(
AudioManager.STREAM_VOICE_CALL, mMostRecentlyUsedMode);
- } else if (!hasRingingForegroundCall()) {
+ } else if (!hasRingingForegroundCall() && mCallsManager.hasOnlyDisconnectedCalls()) {
Log.v(this, "updateAudioStreamAndMode : no ringing call");
abandonAudioFocus();
} else {
@@ -700,6 +727,23 @@
return mAudioFocusStreamType != STREAM_NONE;
}
+ private IAudioService getAudioService() {
+ return IAudioService.Stub.asInterface(ServiceManager.getService(Context.AUDIO_SERVICE));
+ }
+
+ private int getCurrentUserId() {
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ UserInfo currentUser = ActivityManagerNative.getDefault().getCurrentUser();
+ return currentUser.id;
+ } catch (RemoteException e) {
+ // Activity manager not running, nothing we can do assume user 0.
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ return UserHandle.USER_OWNER;
+ }
+
/**
* Translates an {@link AudioManager} stream type to a human-readable string description.
*
diff --git a/src/com/android/server/telecom/CallIntentProcessor.java b/src/com/android/server/telecom/CallIntentProcessor.java
index cfec90c..a6840b9 100644
--- a/src/com/android/server/telecom/CallIntentProcessor.java
+++ b/src/com/android/server/telecom/CallIntentProcessor.java
@@ -8,6 +8,7 @@
import android.os.Bundle;
import android.os.Trace;
import android.os.UserHandle;
+import android.telecom.Connection;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
@@ -87,6 +88,12 @@
clientExtras = new Bundle();
}
+ // Ensure call subject is passed on to the connection service.
+ if (intent.hasExtra(TelecomManager.EXTRA_CALL_SUBJECT)) {
+ String callsubject = intent.getStringExtra(TelecomManager.EXTRA_CALL_SUBJECT);
+ clientExtras.putString(TelecomManager.EXTRA_CALL_SUBJECT, callsubject);
+ }
+
final boolean isPrivilegedDialer = intent.getBooleanExtra(KEY_IS_PRIVILEGED_DIALER, false);
// Send to CallsManager to ensure the InCallUI gets kicked off before the broadcast returns
diff --git a/src/com/android/server/telecom/CallLogManager.java b/src/com/android/server/telecom/CallLogManager.java
index 2007f6e..1fe491e 100755
--- a/src/com/android/server/telecom/CallLogManager.java
+++ b/src/com/android/server/telecom/CallLogManager.java
@@ -148,7 +148,8 @@
// TODO(vt): Once data usage is available, wire it up here.
int callFeatures = getCallFeatures(call.getVideoStateHistory());
logCall(call.getCallerInfo(), logNumber, call.getHandlePresentation(),
- callLogType, callFeatures, accountHandle, creationTime, age, null);
+ callLogType, callFeatures, accountHandle, creationTime, age, null,
+ call.isEmergencyCall());
}
/**
@@ -162,6 +163,7 @@
* @param start The start time of the call, in milliseconds.
* @param duration The duration of the call, in milliseconds.
* @param dataUsage The data usage for the call, null if not applicable.
+ * @param isEmergency {@code true} if this is an emergency call, {@code false} otherwise.
*/
private void logCall(
CallerInfo callerInfo,
@@ -172,8 +174,8 @@
PhoneAccountHandle accountHandle,
long start,
long duration,
- Long dataUsage) {
- boolean isEmergencyNumber = PhoneNumberUtils.isLocalEmergencyNumber(mContext, number);
+ Long dataUsage,
+ boolean isEmergency) {
// On some devices, to avoid accidental redialing of emergency numbers, we *never* log
// emergency calls to the Call Log. (This behavior is set on a per-product basis, based
@@ -182,7 +184,7 @@
mContext.getResources().getBoolean(R.bool.allow_emergency_numbers_in_call_log);
// Don't log emergency numbers if the device doesn't allow it.
- final boolean isOkToLogThisCall = !isEmergencyNumber || okToLogEmergencyNumber;
+ final boolean isOkToLogThisCall = !isEmergency || okToLogEmergencyNumber;
sendAddCallBroadcast(callType, duration);
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index 346fbea..fe7fbb7 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -89,6 +89,7 @@
private static final int MAXIMUM_LIVE_CALLS = 1;
private static final int MAXIMUM_HOLD_CALLS = 1;
private static final int MAXIMUM_RINGING_CALLS = 1;
+ private static final int MAXIMUM_DIALING_CALLS = 1;
private static final int MAXIMUM_OUTGOING_CALLS = 1;
private static final int MAXIMUM_TOP_LEVEL_CALLS = 2;
@@ -245,7 +246,7 @@
Log.d(this, "onSuccessfulIncomingCall");
setCallState(incomingCall, CallState.RINGING, "successful incoming call");
- if (hasMaximumRingingCalls()) {
+ if (hasMaximumRingingCalls() || hasMaximumDialingCalls()) {
incomingCall.reject(false, null);
// since the call was not added to the list of calls, we have to call the missed
// call notifier and the call logger manually.
@@ -439,6 +440,15 @@
return false;
}
+ boolean hasOnlyDisconnectedCalls() {
+ for (Call call : mCalls) {
+ if (!call.isDisconnected()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
boolean hasVideoCall() {
for (Call call : mCalls) {
if (VideoProfile.isVideo(call.getVideoState())) {
@@ -624,13 +634,11 @@
call.setTargetPhoneAccount(phoneAccountHandle);
- boolean isEmergencyCall = TelephonyUtil.shouldProcessAsEmergency(mContext,
- call.getHandle());
boolean isPotentialInCallMMICode = isPotentialInCallMMICode(handle);
// Do not support any more live calls. Our options are to move a call to hold, disconnect
// a call, or cancel this call altogether.
- if (!isPotentialInCallMMICode && !makeRoomForOutgoingCall(call, isEmergencyCall)) {
+ if (!isPotentialInCallMMICode && !makeRoomForOutgoingCall(call, call.isEmergencyCall())) {
// just cancel at this point.
Log.i(this, "No remaining room for outgoing call: %s", call);
if (mCalls.contains(call)) {
@@ -642,7 +650,7 @@
}
boolean needsAccountSelection = phoneAccountHandle == null && accounts.size() > 1 &&
- !isEmergencyCall;
+ !call.isEmergencyCall();
if (needsAccountSelection) {
// This is the state where the user is expected to select an account
@@ -707,14 +715,12 @@
}
call.setStartWithSpeakerphoneOn(speakerphoneOn || mDockManager.isDocked());
- boolean isEmergencyCall = TelephonyUtil.shouldProcessAsEmergency(mContext,
- call.getHandle());
- if (isEmergencyCall) {
+ if (call.isEmergencyCall()) {
// Emergency -- CreateConnectionProcessor will choose accounts automatically
call.setTargetPhoneAccount(null);
}
- if (call.getTargetPhoneAccount() != null || isEmergencyCall) {
+ if (call.getTargetPhoneAccount() != null || call.isEmergencyCall()) {
// If the account has been set, proceed to place the outgoing call.
// Otherwise the connection will be initiated when the account is set by the user.
call.startCreateConnection(mPhoneAccountRegistrar);
@@ -1470,6 +1476,10 @@
return MAXIMUM_OUTGOING_CALLS <= getNumCallsWithState(OUTGOING_CALL_STATES);
}
+ private boolean hasMaximumDialingCalls() {
+ return MAXIMUM_DIALING_CALLS <= getNumCallsWithState(CallState.DIALING);
+ }
+
private boolean makeRoomForOutgoingCall(Call call, boolean isEmergency) {
if (hasMaximumLiveCalls()) {
// NOTE: If the amount of live calls changes beyond 1, this logic will probably
diff --git a/src/com/android/server/telecom/CreateConnectionProcessor.java b/src/com/android/server/telecom/CreateConnectionProcessor.java
index 6126e66..b846470 100644
--- a/src/com/android/server/telecom/CreateConnectionProcessor.java
+++ b/src/com/android/server/telecom/CreateConnectionProcessor.java
@@ -297,7 +297,7 @@
// If we are possibly attempting to call a local emergency number, ensure that the
// plain PSTN connection services are listed, and nothing else.
private void adjustAttemptsForEmergency() {
- if (TelephonyUtil.shouldProcessAsEmergency(mContext, mCall.getHandle())) {
+ if (mCall.isEmergencyCall()) {
Log.i(this, "Emergency number detected");
mAttemptRecords.clear();
List<PhoneAccount> allAccounts = mPhoneAccountRegistrar.getAllPhoneAccounts();
diff --git a/src/com/android/server/telecom/CreateConnectionTimeout.java b/src/com/android/server/telecom/CreateConnectionTimeout.java
index 45305d5..06dc9ed 100644
--- a/src/com/android/server/telecom/CreateConnectionTimeout.java
+++ b/src/com/android/server/telecom/CreateConnectionTimeout.java
@@ -17,14 +17,10 @@
package com.android.server.telecom;
import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
import android.os.Handler;
import android.os.Looper;
import android.telecom.PhoneAccountHandle;
import android.telephony.TelephonyManager;
-import android.telephony.PhoneStateListener;
-import android.telephony.ServiceState;
import java.util.Collection;
import java.util.Objects;
@@ -32,7 +28,7 @@
/**
* Registers a timeout for a call and disconnects the call when the timeout expires.
*/
-final class CreateConnectionTimeout extends PhoneStateListener implements Runnable {
+final class CreateConnectionTimeout implements Runnable {
private final Context mContext;
private final PhoneAccountRegistrar mPhoneAccountRegistrar;
private final ConnectionServiceWrapper mConnectionService;
@@ -43,7 +39,6 @@
CreateConnectionTimeout(Context context, PhoneAccountRegistrar phoneAccountRegistrar,
ConnectionServiceWrapper service, Call call) {
- super(Looper.getMainLooper());
mContext = context;
mPhoneAccountRegistrar = phoneAccountRegistrar;
mConnectionService = service;
@@ -53,7 +48,7 @@
boolean isTimeoutNeededForCall(Collection<PhoneAccountHandle> accounts,
PhoneAccountHandle currentAccount) {
// Non-emergency calls timeout automatically at the radio layer. No need for a timeout here.
- if (!TelephonyUtil.shouldProcessAsEmergency(mContext, mCall.getHandle())) {
+ if (!mCall.isEmergencyCall()) {
return false;
}
@@ -69,27 +64,27 @@
return false;
}
- // To reduce the number of scenarios where a timeout is needed, only use a timeout if
- // we're connected to Wi-Fi. This ensures that the fallback connection manager has an
- // alternate route to place the call. TODO: remove this condition or allow connection
- // managers to specify transports. See http://b/19199181.
- if (!isConnectedToWifi()) {
+ // Timeout is only supported for SIM call managers that are set by the carrier.
+ if (!Objects.equals(connectionManager.getComponentName(),
+ mPhoneAccountRegistrar.getSystemSimCallManagerComponent())) {
+ Log.d(this, "isTimeoutNeededForCall, not a system sim call manager");
return false;
}
- Log.d(this, "isTimeoutNeededForCall, returning true");
+ Log.i(this, "isTimeoutNeededForCall, returning true");
return true;
}
void registerTimeout() {
Log.d(this, "registerTimeout");
mIsRegistered = true;
- // First find out the cellular service state. Based on the state we decide whether a timeout
- // will actually be enforced and if so how long it should be.
- TelephonyManager telephonyManager =
- (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
- telephonyManager.listen(this, PhoneStateListener.LISTEN_SERVICE_STATE);
- telephonyManager.listen(this, 0);
+
+ long timeoutLengthMillis = getTimeoutLengthMillis();
+ if (timeoutLengthMillis <= 0) {
+ Log.d(this, "registerTimeout, timeout set to %d, skipping", timeoutLengthMillis);
+ } else {
+ mHandler.postDelayed(this, timeoutLengthMillis);
+ }
}
void unregisterTimeout() {
@@ -103,24 +98,9 @@
}
@Override
- public void onServiceStateChanged(ServiceState serviceState) {
- long timeoutLengthMillis = getTimeoutLengthMillis(serviceState);
- if (!mIsRegistered) {
- Log.d(this, "onServiceStateChanged, timeout no longer registered, skipping");
- } else if (timeoutLengthMillis <= 0) {
- Log.d(this, "onServiceStateChanged, timeout set to %d, skipping", timeoutLengthMillis);
- } else if (serviceState.getState() == ServiceState.STATE_IN_SERVICE) {
- // If cellular service is available then don't bother with a timeout.
- Log.d(this, "onServiceStateChanged, cellular service available, skipping");
- } else {
- mHandler.postDelayed(this, timeoutLengthMillis);
- }
- }
-
- @Override
public void run() {
if (mIsRegistered && isCallBeingPlaced(mCall)) {
- Log.d(this, "run, call timed out, calling disconnect");
+ Log.i(this, "run, call timed out, calling disconnect");
mIsCallTimedOut = true;
mConnectionService.disconnect(mCall);
}
@@ -133,24 +113,16 @@
|| state == CallState.DIALING;
}
- private long getTimeoutLengthMillis(ServiceState serviceState) {
+ private long getTimeoutLengthMillis() {
// If the radio is off then use a longer timeout. This gives us more time to power on the
// radio.
- if (serviceState.getState() == ServiceState.STATE_POWER_OFF) {
+ TelephonyManager telephonyManager =
+ (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
+ if (telephonyManager.isRadioOn()) {
+ return Timeouts.getEmergencyCallTimeoutMillis(mContext.getContentResolver());
+ } else {
return Timeouts.getEmergencyCallTimeoutRadioOffMillis(
mContext.getContentResolver());
- } else {
- return Timeouts.getEmergencyCallTimeoutMillis(mContext.getContentResolver());
}
}
-
- private boolean isConnectedToWifi() {
- ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(
- Context.CONNECTIVITY_SERVICE);
- if (cm != null) {
- NetworkInfo ni = cm.getActiveNetworkInfo();
- return ni != null && ni.isConnected() && ni.getType() == ConnectivityManager.TYPE_WIFI;
- }
- return false;
- }
}
diff --git a/src/com/android/server/telecom/PhoneAccountRegistrar.java b/src/com/android/server/telecom/PhoneAccountRegistrar.java
index 65847b8..a795d6f 100644
--- a/src/com/android/server/telecom/PhoneAccountRegistrar.java
+++ b/src/com/android/server/telecom/PhoneAccountRegistrar.java
@@ -286,6 +286,19 @@
return getSimCallManager(user);
}
+ public ComponentName getSystemSimCallManagerComponent() {
+ String defaultSimCallManager = null;
+ CarrierConfigManager configManager = (CarrierConfigManager) mContext.getSystemService(
+ Context.CARRIER_CONFIG_SERVICE);
+ PersistableBundle configBundle = configManager.getConfig();
+ if (configBundle != null) {
+ defaultSimCallManager = configBundle.getString(
+ CarrierConfigManager.KEY_DEFAULT_SIM_CALL_MANAGER_STRING);
+ }
+ return TextUtils.isEmpty(defaultSimCallManager)
+ ? null : ComponentName.unflattenFromString(defaultSimCallManager);
+ }
+
/**
* Returns the {@link PhoneAccountHandle} corresponding to the currently active SIM Call
* Manager. SIM Call Manager returned corresponds to the following priority order:
@@ -300,17 +313,7 @@
String dialerPackage = DefaultDialerManager.getDefaultDialerApplication(mContext, user);
// Check carrier config.
- String defaultSimCallManager = null;
- CarrierConfigManager configManager = (CarrierConfigManager) mContext.getSystemService(
- Context.CARRIER_CONFIG_SERVICE);
- PersistableBundle configBundle = configManager.getConfig();
- if (configBundle != null) {
- defaultSimCallManager = configBundle.getString(
- CarrierConfigManager.KEY_DEFAULT_SIM_CALL_MANAGER_STRING);
- }
-
- ComponentName systemSimCallManagerComponent = TextUtils.isEmpty(defaultSimCallManager) ?
- null : ComponentName.unflattenFromString(defaultSimCallManager);
+ ComponentName systemSimCallManagerComponent = getSystemSimCallManagerComponent();
PhoneAccountHandle dialerSimCallManager = null;
PhoneAccountHandle systemSimCallManager = null;
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
index 3ceaa73..9c4585d 100644
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
@@ -229,7 +229,7 @@
.getAllPhoneAccounts();
List<PhoneAccount> profilePhoneAccounts = new ArrayList<>(
allPhoneAccounts.size());
- for (PhoneAccount phoneAccount : profilePhoneAccounts) {
+ for (PhoneAccount phoneAccount : allPhoneAccounts) {
if (isVisibleToCaller(phoneAccount)) {
profilePhoneAccounts.add(phoneAccount);
}
diff --git a/src/com/android/server/telecom/WiredHeadsetManager.java b/src/com/android/server/telecom/WiredHeadsetManager.java
index a61dd6e..ef5f38c 100644
--- a/src/com/android/server/telecom/WiredHeadsetManager.java
+++ b/src/com/android/server/telecom/WiredHeadsetManager.java
@@ -39,7 +39,7 @@
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_HEADSET_PLUG)) {
- boolean isPluggedIn = intent.getIntExtra("state", 0) == 1;
+ boolean isPluggedIn = mAudioManager.isWiredHeadsetOn();
Log.v(WiredHeadsetManager.this, "ACTION_HEADSET_PLUG event, plugged in: %b",
isPluggedIn);
onHeadsetPluggedInChanged(isPluggedIn);
@@ -48,6 +48,7 @@
}
private final WiredHeadsetBroadcastReceiver mReceiver;
+ private final AudioManager mAudioManager;
private boolean mIsPluggedIn;
/**
* ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
@@ -60,8 +61,8 @@
WiredHeadsetManager(Context context) {
mReceiver = new WiredHeadsetBroadcastReceiver();
- AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
- mIsPluggedIn = audioManager.isWiredHeadsetOn();
+ mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+ mIsPluggedIn = mAudioManager.isWiredHeadsetOn();
// Register for misc other intent broadcasts.
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);
diff --git a/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java b/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java
index f1d1078..b4392ae 100644
--- a/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java
+++ b/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java
@@ -50,10 +50,13 @@
import android.telecom.DisconnectCause;
import android.telecom.PhoneAccount;
import android.telephony.PhoneNumberUtils;
+import android.telephony.TelephonyManager;
import android.text.BidiFormatter;
import android.text.TextDirectionHeuristics;
import android.text.TextUtils;
+import java.util.Locale;
+
// TODO: Needed for move to system service: import com.android.internal.R;
/**
@@ -158,7 +161,22 @@
mContext.getString(R.string.notification_missedCallsMsg, mMissedCallCount);
}
- // Create the notification.
+ // Create a public viewable version of the notification, suitable for display when sensitive
+ // notification content is hidden.
+ Notification.Builder publicBuilder = new Notification.Builder(mContext);
+ publicBuilder.setSmallIcon(android.R.drawable.stat_notify_missed_call)
+ .setColor(mContext.getResources().getColor(R.color.theme_color))
+ .setWhen(call.getCreationTimeMillis())
+ // Show "Phone" for notification title.
+ .setContentTitle(mContext.getText(R.string.userCallActivityLabel))
+ // Notification details shows that there are missed call(s), but does not reveal
+ // the missed caller information.
+ .setContentText(mContext.getText(titleResId))
+ .setContentIntent(createCallLogPendingIntent())
+ .setAutoCancel(true)
+ .setDeleteIntent(createClearMissedCallsPendingIntent());
+
+ // Create the notification suitable for display when sensitive information is showing.
Notification.Builder builder = new Notification.Builder(mContext);
builder.setSmallIcon(android.R.drawable.stat_notify_missed_call)
.setColor(mContext.getResources().getColor(R.color.theme_color))
@@ -167,7 +185,11 @@
.setContentText(expandedText)
.setContentIntent(createCallLogPendingIntent())
.setAutoCancel(true)
- .setDeleteIntent(createClearMissedCallsPendingIntent());
+ .setDeleteIntent(createClearMissedCallsPendingIntent())
+ // Include a public version of the notification to be shown when the missed call
+ // notification is shown on the user's lock screen and they have chosen to hide
+ // sensitive notification information.
+ .setPublicVersion(publicBuilder.build());
Uri handleUri = call.getHandle();
String handle = handleUri == null ? null : handleUri.getSchemeSpecificPart();
@@ -182,9 +204,11 @@
mContext.getString(R.string.notification_missedCall_call_back),
createCallBackPendingIntent(handleUri));
- builder.addAction(R.drawable.ic_message_24dp,
- mContext.getString(R.string.notification_missedCall_message),
- createSendSmsFromNotificationPendingIntent(handleUri));
+ if (canRespondViaSms(call)) {
+ builder.addAction(R.drawable.ic_message_24dp,
+ mContext.getString(R.string.notification_missedCall_message),
+ createSendSmsFromNotificationPendingIntent(handleUri));
+ }
}
Bitmap photoIcon = call.getPhotoIcon();
@@ -234,6 +258,18 @@
String handle = call.getHandle() == null ? null : call.getHandle().getSchemeSpecificPart();
String name = call.getName();
+ if (!TextUtils.isEmpty(handle)) {
+ String formattedNumber = PhoneNumberUtils.formatNumber(handle,
+ getCurrentCountryIso(mContext));
+
+ // The formatted number will be null if there was a problem formatting it, but we can
+ // default to using the unformatted number instead (e.g. a SIP URI may not be able to
+ // be formatted.
+ if (!TextUtils.isEmpty(formattedNumber)) {
+ handle = formattedNumber;
+ }
+ }
+
if (!TextUtils.isEmpty(name) && TextUtils.isGraphic(name)) {
return name;
} else if (!TextUtils.isEmpty(handle)) {
@@ -249,6 +285,26 @@
}
/**
+ * @return The ISO 3166-1 two letters country code of the country the user is in based on the
+ * network location. If the network location does not exist, fall back to the locale
+ * setting.
+ */
+ private String getCurrentCountryIso(Context context) {
+ // Without framework function calls, this seems to be the most accurate location service
+ // we can rely on.
+ final TelephonyManager telephonyManager =
+ (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+ String countryIso = telephonyManager.getNetworkCountryIso().toUpperCase();
+
+ if (countryIso == null) {
+ countryIso = Locale.getDefault().getCountry();
+ Log.w(this, "No CountryDetector; falling back to countryIso based on locale: "
+ + countryIso);
+ }
+ return countryIso;
+ }
+
+ /**
* Creates a new pending intent that sends the user to the call log.
*
* @return The pending intent.
@@ -312,6 +368,12 @@
notification.defaults |= Notification.DEFAULT_LIGHTS;
}
+ private boolean canRespondViaSms(Call call) {
+ // Only allow respond-via-sms for "tel:" calls.
+ return call.getHandle() != null &&
+ PhoneAccount.SCHEME_TEL.equals(call.getHandle().getScheme());
+ }
+
/**
* Adds the missed call notification on startup if there are unread missed calls.
*/
diff --git a/testapps/src/com/android/server/telecom/testapps/CallServiceNotifier.java b/testapps/src/com/android/server/telecom/testapps/CallServiceNotifier.java
index cd0800e..c1ced80 100644
--- a/testapps/src/com/android/server/telecom/testapps/CallServiceNotifier.java
+++ b/testapps/src/com/android/server/telecom/testapps/CallServiceNotifier.java
@@ -111,7 +111,8 @@
.setAddress(Uri.parse("tel:555-TEST"))
.setSubscriptionAddress(Uri.parse("tel:555-TEST"))
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER |
- PhoneAccount.CAPABILITY_VIDEO_CALLING)
+ PhoneAccount.CAPABILITY_VIDEO_CALLING |
+ PhoneAccount.CAPABILITY_CALL_SUBJECT)
.setIcon(Icon.createWithResource(
context.getResources(), R.drawable.stat_sys_phone_call))
// TODO: Add icon tint (Color.RED)
@@ -129,7 +130,8 @@
.setSubscriptionAddress(Uri.parse("tel:555-TSIM"))
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER |
PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION |
- PhoneAccount.CAPABILITY_VIDEO_CALLING)
+ PhoneAccount.CAPABILITY_VIDEO_CALLING |
+ PhoneAccount.CAPABILITY_CALL_SUBJECT)
.setIcon(Icon.createWithResource(
context.getResources(), R.drawable.stat_sys_phone_call))
// TODO: Add icon tint (Color.GREEN)
diff --git a/testapps/src/com/android/server/telecom/testapps/TestConnectionService.java b/testapps/src/com/android/server/telecom/testapps/TestConnectionService.java
index 45896f4..7964355 100644
--- a/testapps/src/com/android/server/telecom/testapps/TestConnectionService.java
+++ b/testapps/src/com/android/server/telecom/testapps/TestConnectionService.java
@@ -36,6 +36,7 @@
import android.telecom.TelecomManager;
import android.telecom.VideoProfile;
import android.util.Log;
+import android.widget.Toast;
import com.android.server.telecom.testapps.R;
@@ -299,6 +300,13 @@
String gatewayPackage = extras.getString(TelecomManager.GATEWAY_PROVIDER_PACKAGE);
Uri originalHandle = extras.getParcelable(TelecomManager.GATEWAY_ORIGINAL_ADDRESS);
+ if (extras.containsKey(TelecomManager.EXTRA_CALL_SUBJECT)) {
+ String callSubject = extras.getString(TelecomManager.EXTRA_CALL_SUBJECT);
+ log("Got subject: " + callSubject);
+ Toast.makeText(getApplicationContext(), "Got subject :" + callSubject,
+ Toast.LENGTH_SHORT).show();
+ }
+
log("gateway package [" + gatewayPackage + "], original handle [" +
originalHandle + "]");
@@ -354,6 +362,24 @@
VideoProfile.STATE_BIDIRECTIONAL :
VideoProfile.STATE_AUDIO_ONLY;
connection.setVideoState(videoState);
+
+ Bundle connectionExtras = connection.getExtras();
+ if (connectionExtras == null) {
+ connectionExtras = new Bundle();
+ }
+
+ // Randomly choose a varying length call subject.
+ int subjectFormat = mRandom.nextInt(3);
+ if (subjectFormat == 0) {
+ connectionExtras.putString(Connection.EXTRA_CALL_SUBJECT,
+ "This is a test of call subject lines. Subjects for a call can be long " +
+ " and can go even longer.");
+ } else if (subjectFormat == 1) {
+ connectionExtras.putString(Connection.EXTRA_CALL_SUBJECT,
+ "This is a test of call subject lines.");
+ }
+ connection.setExtras(connectionExtras);
+
setAddress(connection, address);
addVideoProvider(connection);