Merge "Rename KEY_ALLOW_HOLDING_VIDEO_CALL_BOOL."
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 39daea8..d75e484 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1447,6 +1447,17 @@
<string name="alert_dialog_no">No</string>
<!-- ECM: ECM exit dialog choice -->
<string name="alert_dialog_dismiss">Dismiss</string>
+ <!-- ECM: Notification body wihout data restriction hint -->
+ <string name="phone_in_ecm_call_notification_text_without_data_restriction_hint">The phone is in emergency callback mode</string>
+ <!-- ECM: Displays the time when ECM will end without data restriction hint, Example: "Until 10:45 AM" -->
+ <string name="phone_in_ecm_notification_complete_time_without_data_restriction_hint">Until <xliff:g id="completeTime">%s</xliff:g></string>
+ <!-- ECM: Dialog box message without data restriction hint for exiting from the notifications screen -->
+ <plurals name="alert_dialog_exit_ecm_without_data_restriction_hint">
+ <!-- number of minutes is one -->
+ <item quantity="one">The phone will be in emergency callback mode for <xliff:g id="count">%s</xliff:g> minute.\nDo you want to exit now?</item>
+ <!-- number of minutes is not equal to one -->
+ <item quantity="other">The phone will be in emergency callback mode for <xliff:g id="count">%s</xliff:g> minutes.\nDo you want to exit now?</item>
+ </plurals>
<!-- For incoming calls, this is a string we can get from a CDMA network instead of
the actual phone number, to indicate there's no number present. DO NOT TRANSLATE. -->
diff --git a/src/com/android/phone/CallBarringEditPreference.java b/src/com/android/phone/CallBarringEditPreference.java
index 4541926..5d83de1 100644
--- a/src/com/android/phone/CallBarringEditPreference.java
+++ b/src/com/android/phone/CallBarringEditPreference.java
@@ -35,6 +35,7 @@
import android.widget.TextView;
import android.widget.Toast;
+import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.CommandException;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneFactory;
@@ -108,7 +109,7 @@
if (!skipReading) {
// Query call barring status
mPhone.getCallBarring(mFacility, "", mHandler.obtainMessage(
- MyHandler.MESSAGE_GET_CALL_BARRING), 0);
+ MyHandler.MESSAGE_GET_CALL_BARRING), CommandsInterface.SERVICE_CLASS_VOICE);
if (mTcpListener != null) {
mTcpListener.onStarted(this, true);
}
@@ -202,7 +203,8 @@
}
// Send set call barring message to RIL layer.
mPhone.setCallBarring(mFacility, !mIsActivated, password,
- mHandler.obtainMessage(MyHandler.MESSAGE_SET_CALL_BARRING), 0);
+ mHandler.obtainMessage(MyHandler.MESSAGE_SET_CALL_BARRING),
+ CommandsInterface.SERVICE_CLASS_VOICE);
if (mTcpListener != null) {
mTcpListener.onStarted(this, false);
}
@@ -326,7 +328,7 @@
"",
obtainMessage(MESSAGE_GET_CALL_BARRING, 0, MESSAGE_SET_CALL_BARRING,
ar.exception),
- 0);
+ CommandsInterface.SERVICE_CLASS_VOICE);
}
}
}
diff --git a/src/com/android/phone/CallForwardEditPreference.java b/src/com/android/phone/CallForwardEditPreference.java
index 76f17b1..c1f219c 100644
--- a/src/com/android/phone/CallForwardEditPreference.java
+++ b/src/com/android/phone/CallForwardEditPreference.java
@@ -159,6 +159,7 @@
mPhone.setCallForwardingOption(action,
reason,
number,
+ mServiceClass,
time,
mHandler.obtainMessage(MyHandler.MESSAGE_SET_CF,
action,
@@ -216,7 +217,7 @@
*/
void startCallForwardOptionsQuery() {
if (!mCallForwardByUssd) {
- mPhone.getCallForwardingOption(reason,
+ mPhone.getCallForwardingOption(reason, mServiceClass,
mHandler.obtainMessage(MyHandler.MESSAGE_GET_CF,
// unused in this case
CommandsInterface.CF_ACTION_DISABLE,
@@ -423,7 +424,7 @@
}
Log.d(LOG_TAG, "handleSetCFResponse: re get");
if (!mCallForwardByUssd) {
- mPhone.getCallForwardingOption(reason,
+ mPhone.getCallForwardingOption(reason, mServiceClass,
obtainMessage(MESSAGE_GET_CF, msg.arg1, MESSAGE_SET_CF, ar.exception));
} else {
mHandler.sendMessage(mHandler.obtainMessage(mHandler.MESSAGE_GET_CF_USSD,
diff --git a/src/com/android/phone/CarrierConfigLoader.java b/src/com/android/phone/CarrierConfigLoader.java
index daff69b..ef7f5b8 100644
--- a/src/com/android/phone/CarrierConfigLoader.java
+++ b/src/com/android/phone/CarrierConfigLoader.java
@@ -95,6 +95,8 @@
private PersistableBundle[] mOverrideConfigs;
// Service connection for binding to config app.
private CarrierServiceConnection[] mServiceConnection;
+ // Whether we are bound to a service for each phone
+ private boolean[] mServiceBound;
// Whether we have sent config change bcast for each phone id.
private boolean[] mHasSentConfigChange;
// SubscriptionInfoUpdater
@@ -265,7 +267,7 @@
final CarrierServiceConnection conn = (CarrierServiceConnection) msg.obj;
// If new service connection has been created, unbind.
if (mServiceConnection[phoneId] != conn || conn.service == null) {
- unbindIfConnected(mContext, conn);
+ unbindIfBound(mContext, conn, phoneId);
break;
}
final CarrierIdentifier carrierId = getCarrierIdentifierForPhoneId(phoneId);
@@ -274,7 +276,7 @@
new ResultReceiver(this) {
@Override
public void onReceiveResult(int resultCode, Bundle resultData) {
- unbindIfConnected(mContext, conn);
+ unbindIfBound(mContext, conn, phoneId);
// If new service connection has been created, this is stale.
if (mServiceConnection[phoneId] != conn) {
loge("Received response for stale request.");
@@ -308,7 +310,7 @@
} catch (RemoteException e) {
loge("Failed to get carrier config from default app: " +
mPlatformCarrierConfigPackage + " err: " + e.toString());
- unbindIfConnected(mContext, conn);
+ unbindIfBound(mContext, conn, phoneId);
break; // So we don't set a timeout.
}
sendMessageDelayed(
@@ -328,7 +330,7 @@
if (mServiceConnection[phoneId] != null) {
// If a ResponseReceiver callback is in the queue when this happens, we will
// unbind twice and throw an exception.
- unbindIfConnected(mContext, mServiceConnection[phoneId]);
+ unbindIfBound(mContext, mServiceConnection[phoneId], phoneId);
broadcastConfigChangedIntent(phoneId);
}
notifySubscriptionInfoUpdater(phoneId);
@@ -394,7 +396,7 @@
final CarrierServiceConnection conn = (CarrierServiceConnection) msg.obj;
// If new service connection has been created, unbind.
if (mServiceConnection[phoneId] != conn || conn.service == null) {
- unbindIfConnected(mContext, conn);
+ unbindIfBound(mContext, conn, phoneId);
break;
}
final CarrierIdentifier carrierId = getCarrierIdentifierForPhoneId(phoneId);
@@ -403,7 +405,7 @@
new ResultReceiver(this) {
@Override
public void onReceiveResult(int resultCode, Bundle resultData) {
- unbindIfConnected(mContext, conn);
+ unbindIfBound(mContext, conn, phoneId);
// If new service connection has been created, this is stale.
if (mServiceConnection[phoneId] != conn) {
loge("Received response for stale request.");
@@ -438,7 +440,7 @@
+ " carrierid: " + carrierId.toString());
} catch (RemoteException e) {
loge("Failed to get carrier config: " + e.toString());
- unbindIfConnected(mContext, conn);
+ unbindIfBound(mContext, conn, phoneId);
break; // So we don't set a timeout.
}
sendMessageDelayed(
@@ -458,7 +460,7 @@
if (mServiceConnection[phoneId] != null) {
// If a ResponseReceiver callback is in the queue when this happens, we will
// unbind twice and throw an exception.
- unbindIfConnected(mContext, mServiceConnection[phoneId]);
+ unbindIfBound(mContext, mServiceConnection[phoneId], phoneId);
broadcastConfigChangedIntent(phoneId);
}
notifySubscriptionInfoUpdater(phoneId);
@@ -537,6 +539,7 @@
mPersistentOverrideConfigs = new PersistableBundle[numPhones];
mOverrideConfigs = new PersistableBundle[numPhones];
mServiceConnection = new CarrierServiceConnection[numPhones];
+ mServiceBound = new boolean[numPhones];
mHasSentConfigChange = new boolean[numPhones];
// Make this service available through ServiceManager.
ServiceManager.addService(Context.CARRIER_CONFIG_SERVICE, this);
@@ -644,8 +647,13 @@
carrierService.setPackage(pkgName);
mServiceConnection[phoneId] = new CarrierServiceConnection(phoneId, eventId);
try {
- return mContext.bindService(carrierService, mServiceConnection[phoneId],
- Context.BIND_AUTO_CREATE);
+ if (mContext.bindService(carrierService, mServiceConnection[phoneId],
+ Context.BIND_AUTO_CREATE)) {
+ mServiceBound[phoneId] = true;
+ return true;
+ } else {
+ return false;
+ }
} catch (SecurityException ex) {
return false;
}
@@ -1127,8 +1135,10 @@
}
}
- private static void unbindIfConnected(Context context, CarrierServiceConnection conn) {
- if (conn.connected) {
+ private void unbindIfBound(Context context, CarrierServiceConnection conn,
+ int phoneId) {
+ if (mServiceBound[phoneId]) {
+ mServiceBound[phoneId] = false;
context.unbindService(conn);
}
}
@@ -1137,7 +1147,6 @@
int phoneId;
int eventId;
IBinder service;
- boolean connected = false;
public CarrierServiceConnection(int phoneId, int eventId) {
this.phoneId = phoneId;
@@ -1148,7 +1157,6 @@
public void onServiceConnected(ComponentName name, IBinder service) {
log("Connected to config app: " + name.flattenToString());
this.service = service;
- connected = true;
mHandler.sendMessage(mHandler.obtainMessage(eventId, phoneId, -1, this));
}
@@ -1156,21 +1164,18 @@
public void onServiceDisconnected(ComponentName name) {
log("Disconnected from config app: " + name.flattenToString());
this.service = null;
- connected = false;
}
@Override
public void onBindingDied(ComponentName name) {
log("Binding died from config app: " + name.flattenToString());
this.service = null;
- connected = false;
}
@Override
public void onNullBinding(ComponentName name) {
log("Null binding from config app: " + name.flattenToString());
this.service = null;
- connected = false;
}
}
diff --git a/src/com/android/phone/EmergencyCallbackModeExitDialog.java b/src/com/android/phone/EmergencyCallbackModeExitDialog.java
index dcfa024..6edc155 100644
--- a/src/com/android/phone/EmergencyCallbackModeExitDialog.java
+++ b/src/com/android/phone/EmergencyCallbackModeExitDialog.java
@@ -300,8 +300,14 @@
return String.format(getResources().getQuantityText(
R.plurals.alert_dialog_not_avaialble_in_ecm, minutes).toString(), time);
case EXIT_ECM_DIALOG:
- return String.format(getResources().getQuantityText(R.plurals.alert_dialog_exit_ecm,
- minutes).toString(), time);
+ boolean shouldRestrictData = mPhone.getImsPhone() != null
+ && mPhone.getImsPhone().isInImsEcm();
+ return String.format(getResources().getQuantityText(
+ // During IMS ECM, data restriction hint should be removed.
+ shouldRestrictData
+ ? R.plurals.alert_dialog_exit_ecm_without_data_restriction_hint
+ : R.plurals.alert_dialog_exit_ecm,
+ minutes).toString(), time);
}
return null;
}
diff --git a/src/com/android/phone/EmergencyCallbackModeService.java b/src/com/android/phone/EmergencyCallbackModeService.java
index 41d83c4..012a670 100644
--- a/src/com/android/phone/EmergencyCallbackModeService.java
+++ b/src/com/android/phone/EmergencyCallbackModeService.java
@@ -194,7 +194,11 @@
// Format notification string
String text = null;
if(mInEmergencyCall) {
- text = getText(R.string.phone_in_ecm_call_notification_text).toString();
+ text = getText(
+ // During IMS ECM, data restriction hint should be removed.
+ (imsPhone != null && imsPhone.isInImsEcm())
+ ? R.string.phone_in_ecm_call_notification_text_without_data_restriction_hint
+ : R.string.phone_in_ecm_call_notification_text).toString();
} else {
// Calculate the time in ms when the notification will be finished.
long finishedCountMs = millisUntilFinished + System.currentTimeMillis();
@@ -205,7 +209,11 @@
String completeTime = SimpleDateFormat.getTimeInstance(SimpleDateFormat.SHORT).format(
finishedCountMs);
- text = getResources().getString(R.string.phone_in_ecm_notification_complete_time,
+ text = getResources().getString(
+ // During IMS ECM, data restriction hint should be removed.
+ (imsPhone != null && imsPhone.isInImsEcm())
+ ? R.string.phone_in_ecm_notification_complete_time_without_data_restriction_hint
+ : R.string.phone_in_ecm_notification_complete_time,
completeTime);
}
builder.setContentText(text);
diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index fe55335..fccceec 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -470,7 +470,7 @@
private Intent getShowVoicemailIntentForDefaultDialer(UserHandle userHandle) {
String dialerPackage = mContext.getSystemService(TelecomManager.class)
- .getDefaultDialerPackage(userHandle.getIdentifier());
+ .getDefaultDialerPackage(userHandle);
return new Intent(TelephonyManager.ACTION_SHOW_VOICEMAIL_NOTIFICATION)
.setPackage(dialerPackage);
}
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 4eb1788..8e6e7c8 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -35,7 +35,6 @@
import android.content.pm.ComponentInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
-import android.net.NetworkStats;
import android.net.Uri;
import android.os.AsyncResult;
import android.os.Binder;
@@ -3210,8 +3209,8 @@
@Override
public void registerImsRegistrationCallback(int subId, IImsRegistrationCallback c)
throws RemoteException {
- //TODO: b/147498511 will add TelephonyPermissions#checkCallingOrSelfReadPrecisePhoneState
- enforceReadPrivilegedPermission("registerImsRegistrationCallback");
+ TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
+ mApp, subId, "registerImsRegistrationCallback");
if (!ImsManager.isImsSupportedOnDevice(mApp)) {
throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
@@ -3236,8 +3235,8 @@
*/
@Override
public void unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback c) {
- //TODO: b/147498511 will add TelephonyPermissions#checkCallingOrSelfReadPrecisePhoneState
- enforceReadPrivilegedPermission("unregisterImsRegistrationCallback");
+ TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
+ mApp, subId, "unregisterImsRegistrationCallback");
if (!SubscriptionManager.isValidSubscriptionId(subId)) {
throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
}
@@ -3293,8 +3292,8 @@
*/
@Override
public void getImsMmTelRegistrationTransportType(int subId, IIntegerConsumer consumer) {
- //TODO: b/147498511 will add TelephonyPermissions#checkCallingOrSelfReadPrecisePhoneState
- enforceReadPrivilegedPermission("getImsMmTelRegistrationTransportType");
+ TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
+ mApp, subId, "getImsMmTelRegistrationTransportType");
if (!ImsManager.isImsSupportedOnDevice(mApp)) {
throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
"IMS not available on device.");
@@ -3333,8 +3332,8 @@
@Override
public void registerMmTelCapabilityCallback(int subId, IImsCapabilityCallback c)
throws RemoteException {
- //TODO: b/147498511 will add TelephonyPermissions#checkCallingOrSelfReadPrecisePhoneState
- enforceReadPrivilegedPermission("registerMmTelCapabilityCallback");
+ TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
+ mApp, subId, "registerMmTelCapabilityCallback");
if (!ImsManager.isImsSupportedOnDevice(mApp)) {
throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
"IMS not available on device.");
@@ -3358,8 +3357,8 @@
*/
@Override
public void unregisterMmTelCapabilityCallback(int subId, IImsCapabilityCallback c) {
- //TODO: b/147498511 will add TelephonyPermissions#checkCallingOrSelfReadPrecisePhoneState
- enforceReadPrivilegedPermission("unregisterMmTelCapabilityCallback");
+ TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
+ mApp, subId, "unregisterMmTelCapabilityCallback");
if (!SubscriptionManager.isValidSubscriptionId(subId)) {
throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
}
@@ -3455,8 +3454,8 @@
*/
@Override
public boolean isAdvancedCallingSettingEnabled(int subId) {
- //TODO: b/147498511 will add TelephonyPermissions#checkCallingOrSelfReadPrecisePhoneState
- enforceReadPrivilegedPermission("isAdvancedCallingSettingEnabled");
+ TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
+ mApp, subId, "isAdvancedCallingSettingEnabled");
// TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
final long token = Binder.clearCallingIdentity();
@@ -3492,8 +3491,8 @@
*/
@Override
public boolean isVtSettingEnabled(int subId) {
- //TODO: b/147498511 will add TelephonyPermissions#checkCallingOrSelfReadPrecisePhoneState
- enforceReadPrivilegedPermission("isVtSettingEnabled");
+ TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
+ mApp, subId, "isVtSettingEnabled");
final long identity = Binder.clearCallingIdentity();
try {
// TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
@@ -3526,8 +3525,8 @@
*/
@Override
public boolean isVoWiFiSettingEnabled(int subId) {
- //TODO: b/147498511 will add TelephonyPermissions#checkCallingOrSelfReadPrecisePhoneState
- enforceReadPrivilegedPermission("isVoWiFiSettingEnabled");
+ TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
+ mApp, subId, "isVoWiFiSettingEnabled");
final long identity = Binder.clearCallingIdentity();
try {
// TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
@@ -3561,8 +3560,8 @@
*/
@Override
public boolean isVoWiFiRoamingSettingEnabled(int subId) {
- //TODO: b/147498511 will add TelephonyPermissions#checkCallingOrSelfReadPrecisePhoneState
- enforceReadPrivilegedPermission("isVoWiFiRoamingSettingEnabled");
+ TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
+ mApp, subId, "isVoWiFiRoamingSettingEnabled");
final long identity = Binder.clearCallingIdentity();
try {
// TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
@@ -3613,8 +3612,8 @@
*/
@Override
public int getVoWiFiModeSetting(int subId) {
- //TODO: b/147498511 will add TelephonyPermissions#checkCallingOrSelfReadPrecisePhoneState
- enforceReadPrivilegedPermission("getVoWiFiModeSetting");
+ TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
+ mApp, subId, "getVoWiFiModeSetting");
final long identity = Binder.clearCallingIdentity();
try {
// TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
@@ -3695,8 +3694,8 @@
*/
@Override
public boolean isTtyOverVolteEnabled(int subId) {
- //TODO: b/147498511 will add TelephonyPermissions#checkCallingOrSelfReadPrecisePhoneState
- enforceReadPrivilegedPermission("isTtyOverVolteEnabled");
+ TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
+ mApp, subId, "isTtyOverVolteEnabled");
final long identity = Binder.clearCallingIdentity();
try {
// TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
@@ -7158,33 +7157,6 @@
}
/**
- * Get aggregated video call data usage since boot.
- *
- * @param perUidStats True if requesting data usage per uid, otherwise overall usage.
- * @return Snapshot of video call data usage
- * {@hide}
- */
- @Override
- public NetworkStats getVtDataUsage(int subId, boolean perUidStats) {
- mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_NETWORK_USAGE_HISTORY,
- null);
-
- final long identity = Binder.clearCallingIdentity();
- try {
- // NetworkStatsService keeps tracking the active network interface and identity. It
- // records the delta with the corresponding network identity.
- // We just return the total video call data usage snapshot since boot.
- Phone phone = getPhone(subId);
- if (phone != null) {
- return phone.getVtDataUsage(perUidStats);
- }
- return null;
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
-
- /**
* Policy control of data connection. Usually used when data limit is passed.
* @param enabled True if enabling the data, otherwise disabling.
* @param subId Subscription index
@@ -7701,7 +7673,8 @@
@Override
public int getCdmaRoamingMode(int subId) {
- TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+ TelephonyPermissions
+ .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
mApp, subId, "getCdmaRoamingMode");
final long identity = Binder.clearCallingIdentity();
diff --git a/src/com/android/phone/settings/CallForwardInfoUtil.java b/src/com/android/phone/settings/CallForwardInfoUtil.java
index 1983fab..b963df8 100644
--- a/src/com/android/phone/settings/CallForwardInfoUtil.java
+++ b/src/com/android/phone/settings/CallForwardInfoUtil.java
@@ -82,6 +82,7 @@
phone.setCallForwardingOption(commandInterfaceCfAction,
info.reason,
info.number,
+ info.serviceClass,
info.timeSeconds,
message);
}
@@ -93,10 +94,12 @@
*/
public static CallForwardInfo getCallForwardInfo(CallForwardInfo[] infos, int reason) {
CallForwardInfo info = null;
- for (int i = 0 ; i < infos.length; i++) {
- if (isServiceClassVoice(infos[i])) {
- info = infos[i];
- break;
+ if (infos != null) {
+ for (int i = 0 ; i < infos.length; i++) {
+ if (isServiceClassVoice(infos[i])) {
+ info = infos[i];
+ break;
+ }
}
}
diff --git a/src/com/android/phone/settings/VoicemailSettingsActivity.java b/src/com/android/phone/settings/VoicemailSettingsActivity.java
index e18dc93..66b1af9 100644
--- a/src/com/android/phone/settings/VoicemailSettingsActivity.java
+++ b/src/com/android/phone/settings/VoicemailSettingsActivity.java
@@ -43,6 +43,7 @@
import android.widget.Toast;
import com.android.internal.telephony.CallForwardInfo;
+import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.util.NotificationChannelController;
@@ -733,6 +734,7 @@
for (int i = 0; i < mForwardingReadResults.length; i++) {
mPhone.getCallForwardingOption(
VoicemailProviderSettings.FORWARDING_SETTINGS_REASONS[i],
+ CommandsInterface.SERVICE_CLASS_VOICE,
mGetOptionComplete.obtainMessage(EVENT_FORWARDING_GET_COMPLETED, i, 0));
}
showDialogIfForeground(VoicemailDialogUtil.VM_FWD_READING_DIALOG);
diff --git a/src/com/android/services/telephony/CdmaConference.java b/src/com/android/services/telephony/CdmaConference.java
index 32badd0..7458195 100644
--- a/src/com/android/services/telephony/CdmaConference.java
+++ b/src/com/android/services/telephony/CdmaConference.java
@@ -17,6 +17,7 @@
package com.android.services.telephony;
import android.content.Context;
+import android.net.Uri;
import android.os.PersistableBundle;
import android.telecom.Connection;
import android.telecom.PhoneAccountHandle;
@@ -73,6 +74,12 @@
}
@Override
+ public void onAddConferenceParticipants(List<Uri> participants) {
+ Log.e(this, new Exception(), "Adding Conference Participants not supported " +
+ " for CDMA conference call.");
+ }
+
+ @Override
public void onAnswer(int videoState) {
Log.e(this, new Exception(), "Answer not supported for CDMA conference call.");
}
diff --git a/src/com/android/services/telephony/ConferenceParticipantConnection.java b/src/com/android/services/telephony/ConferenceParticipantConnection.java
index ac3928f..b7ecd48 100644
--- a/src/com/android/services/telephony/ConferenceParticipantConnection.java
+++ b/src/com/android/services/telephony/ConferenceParticipantConnection.java
@@ -19,13 +19,13 @@
import android.net.Uri;
import android.telecom.Connection;
import android.telecom.DisconnectCause;
-import com.android.telephony.Rlog;
import android.telephony.SubscriptionInfo;
import android.text.TextUtils;
import com.android.ims.internal.ConferenceParticipant;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
+import com.android.telephony.Rlog;
/**
* Represents a participant in a conference call.
@@ -215,7 +215,7 @@
sb.append(" connectTime:");
sb.append(getConnectTimeMillis());
sb.append(" connectElapsedTime:");
- sb.append(getConnectElapsedTimeMillis());
+ sb.append(getConnectionStartElapsedRealtimeMillis());
sb.append("]");
return sb.toString();
diff --git a/src/com/android/services/telephony/ImsConference.java b/src/com/android/services/telephony/ImsConference.java
index f5f5c66..c11a1ca 100644
--- a/src/com/android/services/telephony/ImsConference.java
+++ b/src/com/android/services/telephony/ImsConference.java
@@ -30,7 +30,6 @@
import android.telecom.VideoProfile;
import android.telephony.CarrierConfigManager;
import android.telephony.PhoneNumberUtils;
-import com.android.telephony.Rlog;
import android.util.Pair;
import com.android.ims.internal.ConferenceParticipant;
@@ -42,6 +41,7 @@
import com.android.phone.PhoneGlobals;
import com.android.phone.PhoneUtils;
import com.android.phone.R;
+import com.android.telephony.Rlog;
import java.util.ArrayList;
import java.util.Arrays;
@@ -313,10 +313,10 @@
long connectTime = conferenceHost.getOriginalConnection().getConnectTime();
long connectElapsedTime = conferenceHost.getOriginalConnection().getConnectTimeReal();
setConnectionTime(connectTime);
- setConnectionStartElapsedRealTime(connectElapsedTime);
+ setConnectionStartElapsedRealtimeMillis(connectElapsedTime);
// Set the connectTime in the connection as well.
conferenceHost.setConnectTimeMillis(connectTime);
- conferenceHost.setConnectionStartElapsedRealTime(connectElapsedTime);
+ conferenceHost.setConnectionStartElapsedRealtimeMillis(connectElapsedTime);
mTelephonyConnectionService = telephonyConnectionService;
setConferenceHost(conferenceHost);
@@ -374,6 +374,10 @@
Connection.CAPABILITY_CAN_PAUSE_VIDEO,
mConferenceHost.getVideoPauseSupported() && isVideoCapable());
+ conferenceCapabilities = changeBitmask(conferenceCapabilities,
+ Connection.CAPABILITY_ADD_PARTICIPANT,
+ (capabilities & Connection.CAPABILITY_ADD_PARTICIPANT) != 0);
+
return conferenceCapabilities;
}
@@ -522,6 +526,19 @@
}
/**
+ * Supports adding participants to an existing conference call
+ *
+ * @param participants that are pulled to existing conference call
+ */
+ @Override
+ public void onAddConferenceParticipants(List<Uri> participants) {
+ if (mConferenceHost == null) {
+ return;
+ }
+ mConferenceHost.performAddConferenceParticipants(participants);
+ }
+
+ /**
* Invoked when the conference is answered.
*/
@Override
@@ -741,7 +758,8 @@
setAddress(mConferenceHost.getAddress(), mConferenceHost.getAddressPresentation());
setCallerDisplayName(mConferenceHost.getCallerDisplayName(),
mConferenceHost.getCallerDisplayNamePresentation());
- setConnectionStartElapsedRealTime(mConferenceHost.getConnectElapsedTimeMillis());
+ setConnectionStartElapsedRealtimeMillis(
+ mConferenceHost.getConnectionStartElapsedRealtimeMillis());
setConnectionTime(mConferenceHost.getConnectTimeMillis());
}
@@ -959,7 +977,8 @@
Log.d(this,
"stopEmulatingSinglePartyCall: restored lone participant connect time");
loneParticipant.setConnectTimeMillis(getConnectionTime());
- loneParticipant.setConnectionStartElapsedRealTime(getConnectionStartElapsedRealTime());
+ loneParticipant.setConnectionStartElapsedRealtimeMillis(
+ getConnectionStartElapsedRealtimeMillis());
}
// Tell Telecom its a conference again.
@@ -999,7 +1018,8 @@
setAddress(entry.getAddress(), entry.getAddressPresentation());
setCallerDisplayName(entry.getCallerDisplayName(),
entry.getCallerDisplayNamePresentation());
- setConnectionStartElapsedRealTime(entry.getConnectElapsedTimeMillis());
+ setConnectionStartElapsedRealtimeMillis(
+ entry.getConnectionStartElapsedRealtimeMillis());
setConnectionTime(entry.getConnectTimeMillis());
mLoneParticipantIdentity = new Pair<>(entry.getUserEntity(), entry.getEndpoint());
@@ -1043,10 +1063,11 @@
!isConferenceHost() /* isRemotelyHosted */);
if (participant.getConnectTime() == 0) {
connection.setConnectTimeMillis(parent.getConnectTimeMillis());
- connection.setConnectionStartElapsedRealTime(parent.getConnectElapsedTimeMillis());
+ connection.setConnectionStartElapsedRealtimeMillis(
+ parent.getConnectionStartElapsedRealtimeMillis());
} else {
connection.setConnectTimeMillis(participant.getConnectTime());
- connection.setConnectionStartElapsedRealTime(participant.getConnectElapsedTime());
+ connection.setConnectionStartElapsedRealtimeMillis(participant.getConnectElapsedTime());
}
// Indicate whether this is an MT or MO call to Telecom; the participant has the cached
// data from the time of merge.
@@ -1212,7 +1233,8 @@
c.updateState();
// Copy the connect time from the conferenceHost
c.setConnectTimeMillis(mConferenceHost.getConnectTimeMillis());
- c.setConnectionStartElapsedRealTime(mConferenceHost.getConnectElapsedTimeMillis());
+ c.setConnectionStartElapsedRealtimeMillis(
+ mConferenceHost.getConnectionStartElapsedRealtimeMillis());
mTelephonyConnectionService.addExistingConnection(phoneAccountHandle, c);
mTelephonyConnectionService.addConnectionToConferenceController(c);
} // CDMA case not applicable for SRVCC
diff --git a/src/com/android/services/telephony/TelephonyConference.java b/src/com/android/services/telephony/TelephonyConference.java
index d720639..7e4693f 100644
--- a/src/com/android/services/telephony/TelephonyConference.java
+++ b/src/com/android/services/telephony/TelephonyConference.java
@@ -16,6 +16,7 @@
package com.android.services.telephony;
+import android.net.Uri;
import android.telecom.Connection;
import android.telecom.PhoneAccountHandle;
@@ -103,6 +104,12 @@
}
@Override
+ public void onAddConferenceParticipants(List<Uri> participants) {
+ Log.e(this, new Exception(), "Adding Conference Participants not supported " +
+ " for GSM conference call.");
+ }
+
+ @Override
public void onMerge(Connection connection) {
try {
Phone phone = ((TelephonyConnection) connection).getPhone();
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index 29b65d0..2f8ac24 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -40,7 +40,6 @@
import android.telephony.CarrierConfigManager;
import android.telephony.DisconnectCause;
import android.telephony.PhoneNumberUtils;
-import com.android.telephony.Rlog;
import android.telephony.ServiceState;
import android.telephony.ServiceState.RilRadioTechnology;
import android.telephony.SubscriptionManager;
@@ -51,6 +50,7 @@
import android.util.Pair;
import com.android.ims.ImsCall;
+import com.android.ims.ImsException;
import com.android.ims.internal.ConferenceParticipant;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.SomeArgs;
@@ -63,12 +63,14 @@
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.gsm.SuppServiceNotification;
import com.android.internal.telephony.imsphone.ImsPhone;
+import com.android.internal.telephony.imsphone.ImsPhoneCall;
import com.android.internal.telephony.imsphone.ImsPhoneCallTracker;
import com.android.internal.telephony.imsphone.ImsPhoneConnection;
import com.android.phone.ImsUtil;
import com.android.phone.PhoneGlobals;
import com.android.phone.PhoneUtils;
import com.android.phone.R;
+import com.android.telephony.Rlog;
import java.util.ArrayList;
import java.util.Arrays;
@@ -870,6 +872,11 @@
}
@Override
+ public void onAddConferenceParticipants(List<Uri> participants) {
+ performAddConferenceParticipants(participants);
+ }
+
+ @Override
public void onAbort() {
Log.v(this, "onAbort");
mHandler.obtainMessage(MSG_HANGUP, android.telephony.DisconnectCause.LOCAL).sendToTarget();
@@ -1120,6 +1127,29 @@
}
}
+ private String[] getAddConferenceParticipants(List<Uri> participants) {
+ String[] addConfParticipants = new String[participants.size()];
+ int i = 0;
+ for (Uri participant : participants) {
+ addConfParticipants[i] = participant.getSchemeSpecificPart();
+ i++;
+ }
+ return addConfParticipants;
+ }
+
+ public void performAddConferenceParticipants(List<Uri> participants) {
+ Log.v(this, "performAddConferenceParticipants");
+ if (mOriginalConnection.getCall() instanceof ImsPhoneCall) {
+ ImsPhoneCall imsPhoneCall = (ImsPhoneCall)mOriginalConnection.getCall();
+ try {
+ imsPhoneCall.getImsCall().inviteParticipants(
+ getAddConferenceParticipants(participants));
+ } catch(ImsException e) {
+ Log.e(this, e, "failed to add conference participants");
+ }
+ }
+ }
+
/**
* Builds connection capabilities common to all TelephonyConnections. Namely, apply IMS-based
* capabilities.
@@ -1153,6 +1183,7 @@
newCapabilities = applyConferenceTerminationCapabilities(newCapabilities);
newCapabilities = changeBitmask(newCapabilities, CAPABILITY_SUPPORT_DEFLECT,
isImsConnection() && canDeflectImsCalls());
+ newCapabilities = applyAddParticipantCapabilities(newCapabilities);
if (getConnectionCapabilities() != newCapabilities) {
setConnectionCapabilities(newCapabilities);
@@ -1186,7 +1217,7 @@
isExternalConnection());
newProperties = changeBitmask(newProperties, PROPERTY_HAS_CDMA_VOICE_PRIVACY,
mIsCdmaVoicePrivacyEnabled);
- newProperties = changeBitmask(newProperties, PROPERTY_ASSISTED_DIALING_USED,
+ newProperties = changeBitmask(newProperties, PROPERTY_ASSISTED_DIALING,
mIsUsingAssistedDialing);
newProperties = changeBitmask(newProperties, PROPERTY_IS_RTT, isRtt());
newProperties = changeBitmask(newProperties, PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL,
@@ -1580,6 +1611,75 @@
|| !VideoProfile.isVideo(getVideoState()));
}
+ private boolean isConferenceHosted() {
+ boolean isHosted = false;
+ if (getTelephonyConnectionService() != null) {
+ for (Conference current : getTelephonyConnectionService().getAllConferences()) {
+ if (current instanceof ImsConference) {
+ ImsConference other = (ImsConference) current;
+ if (getState() == current.getState()) {
+ continue;
+ }
+ if (other.isConferenceHost()) {
+ isHosted = true;
+ break;
+ }
+ }
+ }
+ }
+ return isHosted;
+ }
+
+ private boolean isAddParticipantCapable() {
+ // not add participant capable for non ims phones
+ if (getPhone() == null || getPhone().getPhoneType() != PhoneConstants.PHONE_TYPE_IMS) {
+ return false;
+ }
+
+ if (!getCarrierConfig()
+ .getBoolean(CarrierConfigManager.KEY_SUPPORT_ADD_CONFERENCE_PARTICIPANTS_BOOL)) {
+ return false;
+ }
+
+ boolean isCapable = !mTreatAsEmergencyCall && (mConnectionState == Call.State.ACTIVE ||
+ mConnectionState == Call.State.HOLDING);
+
+ // add participant capable if current connection is a host connection or
+ // if conference is not hosted on the device
+ isCapable = isCapable && ((mOriginalConnection != null &&
+ mOriginalConnection.isConferenceHost()) ||
+ !isConferenceHosted());
+
+ /**
+ * For individual IMS calls, if the extra for remote conference support is
+ * - indicated, then consider the same for add participant capability
+ * - not indicated, then the add participant capability is same as before.
+ */
+ if (isCapable && (mOriginalConnection != null) && !mIsMultiParty) {
+ isCapable = mOriginalConnectionExtras.getBoolean(
+ ImsCallProfile.EXTRA_CONFERENCE_AVAIL, isCapable);
+ }
+ return isCapable;
+ }
+
+ /**
+ * Applies the add participant capabilities to the {@code CallCapabilities} bit-mask.
+ *
+ * @param callCapabilities The {@code CallCapabilities} bit-mask.
+ * @return The capabilities with the add participant capabilities applied.
+ */
+ private int applyAddParticipantCapabilities(int callCapabilities) {
+ int currentCapabilities = callCapabilities;
+ if (isAddParticipantCapable()) {
+ currentCapabilities = changeBitmask(currentCapabilities,
+ Connection.CAPABILITY_ADD_PARTICIPANT, true);
+ } else {
+ currentCapabilities = changeBitmask(currentCapabilities,
+ Connection.CAPABILITY_ADD_PARTICIPANT, false);
+ }
+ return currentCapabilities;
+ }
+
@VisibleForTesting
public PersistableBundle getCarrierConfig() {
Phone phone = getPhone();
@@ -1842,6 +1942,12 @@
// Ensure extras are propagated to Telecom.
putTelephonyExtras(mOriginalConnectionExtras);
+ // If extras contain Conference support information,
+ // then ensure capabilities are updated.
+ if (mOriginalConnectionExtras.containsKey(
+ ImsCallProfile.EXTRA_CONFERENCE_AVAIL)) {
+ updateConnectionCapabilities();
+ }
} else {
Log.d(this, "Extras update not required");
}