Merge commit '21c5e2d' into mergemeister
Change-Id: I4203215f522fd2efda575aa56d7f7d75f856add8
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index dd6593b..e3a6dcd 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -533,6 +533,12 @@
android:uiOptions="splitActionBarWhenNarrow">
</activity>
+ <activity android:name="ImsEditor"
+ android:theme="@style/DialerSettingsLight"
+ android:configChanges="orientation|screenSize|keyboardHidden"
+ android:uiOptions="splitActionBarWhenNarrow">
+ </activity>
+
<!-- End SIP -->
<activity android:name="ErrorDialogActivity"
diff --git a/res/values/array.xml b/res/values/array.xml
new file mode 100644
index 0000000..79b6034
--- /dev/null
+++ b/res/values/array.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+
+<!-- Array resources for the Phone app. -->
+<resources>
+ <!-- Array resource for IMS VT call quality entries-->
+ <string-array translatable="true" name="ims_vt_call_quality_entries">
+ <item>@string/ims_vt_call_quality_low</item>
+ <item>@string/ims_vt_call_quality_high</item>
+ </string-array>
+
+ <!-- Array resource for IMS VT call quality values-->
+ <string-array translatable="false" name="ims_vt_call_quality_values">
+ <item>0</item>
+ <item>1</item>
+ </string-array>
+</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index e49310d..408d570 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -758,7 +758,8 @@
<string name="tty_mode_option_summary">Set TTY mode</string>
<string name="auto_retry_mode_title">Auto-retry</string>
<string name="auto_retry_mode_summary">Enable Auto-retry mode</string>
-
+ <!-- TTY Mode change is NOT allowed during a video call -->
+ <string name="tty_mode_not_allowed_video_call">TTY Mode change is not allowed during a video call</string>
<!-- FDN list screen: menu item label -->
<string name="menu_add">Add contact</string>
<!-- FDN list screen: menu item label -->
@@ -1300,4 +1301,18 @@
<!-- String used in place of a message that could not be properly decoded (e.g. bad base64
data was received.) [CHAR LIMIT=none] -->
<string name="message_decode_error">There was an error while decoding the message.</string>
+
+ <!-- IMS settings related strings -->
+ <!-- Title of the ims editor screen. [CHAR LIMIT=NONE] -->
+ <string name="ims_edit_title">IMS account details</string>
+ <!-- Title displayed IMS account settings in the sip settings category. [CHAR LIMIT=NONE] -->
+ <string name="ims_accounts_title">IMS Account</string>
+
+ <!-- VT call quality settings. -->
+ <string translatable="false" name="ims_vt_call_quality">VtCallQuality</string>
+ <string name="ims_vt_call_quality_title">VT Call Quality</string>
+ <string name="ims_vt_call_quality_low">Low</string>
+ <string name="ims_vt_call_quality_high">High</string>
+ <string name="ims_vt_call_quality_unknown">Unknown</string>
+ <string name="ims_vt_call_quality_set_failed">Failed to set video quality</string>
</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 3c192cc..9d2d47f 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -262,6 +262,7 @@
<item name="android:windowBackground">@color/emergency_dialer_background</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
+ <item name="android:homeAsUpIndicator">@drawable/ic_back_arrow</item>
</style>
<style name="SimImportTheme" parent="@android:style/Theme.Material.Light">
diff --git a/res/xml/call_feature_setting.xml b/res/xml/call_feature_setting.xml
index f696e2c..52a8815 100644
--- a/res/xml/call_feature_setting.xml
+++ b/res/xml/call_feature_setting.xml
@@ -82,4 +82,14 @@
</PreferenceScreen>
+ <PreferenceScreen
+ android:key="ims_account_settings_key"
+ android:title="@string/ims_accounts_title"
+ android:persistent="false">
+
+ <intent android:action="android.intent.action.MAIN"
+ android:targetPackage="com.android.phone"
+ android:targetClass="com.android.phone.ImsEditor" />
+ </PreferenceScreen>
+
</PreferenceScreen>
diff --git a/res/xml/ims_edit.xml b/res/xml/ims_edit.xml
new file mode 100644
index 0000000..f16e2f5
--- /dev/null
+++ b/res/xml/ims_edit.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+ android:title="@string/ims_edit_title"
+ android:persistent="false">
+
+ <ListPreference
+ android:key="@string/ims_vt_call_quality"
+ android:title="@string/ims_vt_call_quality_title"
+ android:entries="@array/ims_vt_call_quality_entries"
+ android:entryValues="@array/ims_vt_call_quality_values"
+ android:summary="@string/ims_vt_call_quality_unknown"
+ android:persistent="false"
+ android:enabled="true"
+ android:dialogTitle="@string/ims_vt_call_quality_title"/>
+
+</PreferenceScreen>
diff --git a/src/com/android/phone/ims/ImsEditor.java b/src/com/android/phone/ims/ImsEditor.java
new file mode 100644
index 0000000..bbd4526
--- /dev/null
+++ b/src/com/android/phone/ims/ImsEditor.java
@@ -0,0 +1,170 @@
+/* Copyright (C) 2015 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.phone;
+
+import android.os.Bundle;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceScreen;
+import android.telephony.SubscriptionManager;
+import android.util.Log;
+import android.widget.Toast;
+
+import com.android.ims.ImsConfig;
+import com.android.ims.ImsConfigListener;
+import com.android.ims.ImsException;
+import com.android.ims.ImsManager;
+import com.android.phone.R;
+
+/**
+ * The activity class for editing a new or existing IMS profile.
+ */
+public class ImsEditor extends PreferenceActivity
+ implements Preference.OnPreferenceChangeListener {
+
+ private static final String TAG = ImsEditor.class.getSimpleName();
+
+ private ListPreference mVideoCallQuality;
+ private ImsConfig mImsConfig;
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ Log.d(TAG, "onResume");
+ getVideoQuality();
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ Log.v(TAG, "start profile editor");
+ super.onCreate(savedInstanceState);
+
+ addPreferencesFromResource(R.xml.ims_edit);
+ PreferenceScreen screen = getPreferenceScreen();
+
+ mVideoCallQuality = (ListPreference) screen
+ .findPreference(getString(R.string.ims_vt_call_quality));
+ mVideoCallQuality.setOnPreferenceChangeListener(this);
+
+ try {
+ ImsManager imsManager = ImsManager.getInstance(getBaseContext(),
+ SubscriptionManager.getDefaultVoiceSubId());
+ mImsConfig = imsManager.getConfigInterface();
+ } catch (ImsException e) {
+ mImsConfig = null;
+ Log.e(TAG, "ImsService is not running");
+ }
+ }
+
+ private ImsConfigListener imsConfigListener = new ImsConfigListener.Stub() {
+ public void onGetVideoQuality(int status, int quality) {
+ if (hasRequestFailed(status)) {
+ quality = ImsConfig.OperationValuesConstants.VIDEO_QUALITY_UNKNOWN;
+ Log.e(TAG, "onGetVideoQuality: failed. errorCode = " + status);
+ }
+ Log.d(TAG, "onGetVideoQuality: value = " + quality);
+ loadVideoCallQualityPrefs(quality);
+ }
+
+ public void onSetVideoQuality(int status) {
+ if (hasRequestFailed(status)) {
+ Log.e(TAG, "onSetVideoQuality: set failed. errorCode = " + status);
+ Toast.makeText(getApplicationContext(), R.string.ims_vt_call_quality_set_failed,
+ Toast.LENGTH_SHORT).show();
+ getVideoQuality(); // Set request failed, get current value.
+ } else {
+ Log.d(TAG, "onSetVideoQuality: set succeeded.");
+ }
+ }
+
+ public void onGetFeatureResponse(int feature, int network, int value, int status) {
+ //TODO not required as of now
+ }
+
+ public void onSetFeatureResponse(int feature, int network, int value, int status) {
+ //TODO not required as of now
+ }
+ };
+
+ @Override
+ public boolean onPreferenceChange(Preference pref, Object newValue) {
+ if (pref.equals(mVideoCallQuality)) {
+ if (newValue == null) {
+ Log.e(TAG, "onPreferenceChange invalid value received");
+ } else {
+ final int quality = Integer.parseInt(newValue.toString());
+ boolean result = setVideoQuality(quality);
+ if (result) {
+ loadVideoCallQualityPrefs(quality);
+ }
+ return result;
+ }
+ }
+ return true;
+ }
+
+ private void loadVideoCallQualityPrefs(int vqValue) {
+ Log.d(TAG, "loadVideoCallQualityPrefs, vqValue = " + vqValue);
+ final String videoQuality = videoQualityToString(vqValue);
+ mVideoCallQuality.setValue(String.valueOf(vqValue));
+ mVideoCallQuality.setSummary(videoQuality);
+ }
+
+ private void getVideoQuality() {
+ try {
+ if (mImsConfig != null) {
+ mImsConfig.getVideoQuality(imsConfigListener);
+ } else {
+ loadVideoCallQualityPrefs(ImsConfig.OperationValuesConstants.VIDEO_QUALITY_UNKNOWN);
+ Log.e(TAG, "getVideoQuality failed. mImsConfig is null");
+ }
+ } catch (ImsException e) {
+ Log.e(TAG, "getVideoQuality failed. Exception = " + e);
+ }
+ }
+
+ private boolean setVideoQuality(int quality) {
+ try {
+ if (mImsConfig != null) {
+ mImsConfig.setVideoQuality(quality, imsConfigListener);
+ } else {
+ Log.e(TAG, "setVideoQuality failed. mImsConfig is null");
+ return false;
+ }
+ } catch (ImsException e) {
+ Log.e(TAG, "setVideoQuality failed. Exception = " + e);
+ return false;
+ }
+ return true;
+ }
+
+ private boolean hasRequestFailed(int result) {
+ return (result != ImsConfig.OperationStatusConstants.SUCCESS);
+ }
+
+ private String videoQualityToString(int quality) {
+ switch (quality) {
+ case ImsConfig.OperationValuesConstants.VIDEO_QUALITY_HIGH:
+ return getString(R.string.ims_vt_call_quality_high);
+ case ImsConfig.OperationValuesConstants.VIDEO_QUALITY_LOW:
+ return getString(R.string.ims_vt_call_quality_low);
+ case ImsConfig.OperationValuesConstants.VIDEO_QUALITY_UNKNOWN:
+ default:
+ return getString(R.string.ims_vt_call_quality_unknown);
+ }
+ }
+}
diff --git a/src/com/android/phone/settings/VoicemailDialogUtil.java b/src/com/android/phone/settings/VoicemailDialogUtil.java
index 26bc227..32cb37a 100644
--- a/src/com/android/phone/settings/VoicemailDialogUtil.java
+++ b/src/com/android/phone/settings/VoicemailDialogUtil.java
@@ -34,11 +34,12 @@
public static final int VM_FWD_SAVING_DIALOG = 601;
public static final int VM_FWD_READING_DIALOG = 602;
public static final int VM_REVERTING_DIALOG = 603;
+ public static final int TTY_SET_RESPONSE_ERROR = 800;
public static Dialog getDialog(VoicemailSettingsActivity parent, int id) {
if ((id == VM_RESPONSE_ERROR_DIALOG) || (id == VM_NOCHANGE_ERROR_DIALOG) ||
(id == FWD_SET_RESPONSE_ERROR_DIALOG) || (id == FWD_GET_RESPONSE_ERROR_DIALOG) ||
- (id == VM_CONFIRM_DIALOG)) {
+ (id == VM_CONFIRM_DIALOG) || (id == TTY_SET_RESPONSE_ERROR)) {
AlertDialog.Builder b = new AlertDialog.Builder(parent);
@@ -74,6 +75,12 @@
b.setPositiveButton(R.string.alert_dialog_yes, parent);
b.setNegativeButton(R.string.alert_dialog_no, parent);
break;
+ case TTY_SET_RESPONSE_ERROR:
+ titleId = R.string.tty_mode_option_title;
+ msgId = R.string.tty_mode_not_allowed_video_call;
+ b.setIconAttribute(android.R.attr.alertDialogIcon);
+ b.setPositiveButton(R.string.ok, parent);
+ break;
default:
msgId = R.string.exception_error;
// Set Button 3, tells the activity that the error is
diff --git a/src/com/android/services/telephony/CdmaConnection.java b/src/com/android/services/telephony/CdmaConnection.java
index 74e0673..d2250d4 100644
--- a/src/com/android/services/telephony/CdmaConnection.java
+++ b/src/com/android/services/telephony/CdmaConnection.java
@@ -155,13 +155,16 @@
mIsCallWaiting = originalConnection != null &&
originalConnection.getState() == Call.State.WAITING;
- if (state == android.telecom.Connection.STATE_DIALING) {
- if (isEmergency()) {
- mEmergencyTonePlayer.start();
+ if (mEmergencyTonePlayer != null) {
+ if (state == android.telecom.Connection.STATE_DIALING) {
+ if (isEmergency()) {
+ mEmergencyTonePlayer.start();
+ }
+ } else {
+ // No need to check if it is an emergency call, since it is a no-op if it
+ // isn't started.
+ mEmergencyTonePlayer.stop();
}
- } else {
- // No need to check if it is an emergency call, since it is a no-op if it isn't started.
- mEmergencyTonePlayer.stop();
}
super.onStateChanged(state);
diff --git a/src/com/android/services/telephony/ImsConference.java b/src/com/android/services/telephony/ImsConference.java
index 46b3eef..ced36a1 100644
--- a/src/com/android/services/telephony/ImsConference.java
+++ b/src/com/android/services/telephony/ImsConference.java
@@ -21,7 +21,11 @@
import android.telecom.ConferenceParticipant;
import android.telecom.Connection;
import android.telecom.DisconnectCause;
+import android.telecom.Log;
import android.telecom.PhoneAccountHandle;
+import android.telecom.VideoProfile;
+import android.telecom.Conference.Listener;
+import android.telecom.Connection.VideoProvider;
import com.android.internal.telephony.Call;
import com.android.internal.telephony.CallStateException;
@@ -145,6 +149,28 @@
TelephonyConnection telephonyConnection = (TelephonyConnection) c;
handleConferenceParticipantsUpdate(telephonyConnection, participants);
}
+
+ @Override
+ public void onVideoStateChanged(android.telecom.Connection c, int videoState) {
+ Log.d(this, "onVideoStateChanged video state %d", videoState);
+ setVideoState(c, videoState);
+ }
+
+ @Override
+ public void onVideoProviderChanged(android.telecom.Connection c,
+ Connection.VideoProvider videoProvider) {
+ Log.d(this, "onVideoProviderChanged: Connection: %s, VideoProvider: %s", c,
+ videoProvider);
+ setVideoProvider(c, videoProvider);
+ }
+
+ @Override
+ public void onConnectionCapabilitiesChanged(Connection c, int connectionCapabilities) {
+ Log.d(this, "onCallCapabilitiesChanged: Connection: %s, callCapabilities: %s", c,
+ connectionCapabilities);
+ int capabilites = ImsConference.this.getCapabilities();
+ setCapabilities(applyVideoCapabilities(capabilites, connectionCapabilities));
+ }
};
/**
@@ -192,6 +218,47 @@
Connection.CAPABILITY_HOLD |
Connection.CAPABILITY_MUTE
);
+
+ if (conferenceHost != null && conferenceHost.getCall() != null
+ && conferenceHost.getCall().getPhone() != null) {
+ mPhoneAccount = PhoneUtils.makePstnPhoneAccountHandle(
+ conferenceHost.getCall().getPhone());
+ Log.v(this, "set phacc to " + mPhoneAccount);
+ }
+
+ int capabilities = Connection.CAPABILITY_SUPPORT_HOLD | Connection.CAPABILITY_HOLD |
+ Connection.CAPABILITY_MUTE;
+
+ capabilities = applyVideoCapabilities(capabilities, mConferenceHost.getCallCapabilities());
+ setConnectionCapabilities(capabilities);
+
+ }
+
+ private int applyVideoCapabilities(int conferenceCapabilities, int capabilities) {
+ if (can(capabilities, Connection.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL)) {
+ conferenceCapabilities = applyCapability(conferenceCapabilities,
+ Connection.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL);
+ } else {
+ conferenceCapabilities = removeCapability(conferenceCapabilities,
+ Connection.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL);
+ }
+
+ if (can(capabilities, Connection.CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL)) {
+ conferenceCapabilities = applyCapability(conferenceCapabilities,
+ Connection.CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL);
+ } else {
+ conferenceCapabilities = removeCapability(conferenceCapabilities,
+ Connection.CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL);
+ }
+
+ if (can(capabilities, Connection.CAPABILITY_CAN_UPGRADE_TO_VIDEO)) {
+ conferenceCapabilities = applyCapability(conferenceCapabilities,
+ Connection.CAPABILITY_CAN_UPGRADE_TO_VIDEO);
+ } else {
+ conferenceCapabilities = removeCapability(conferenceCapabilities,
+ Connection.CAPABILITY_CAN_UPGRADE_TO_VIDEO);
+ }
+ return conferenceCapabilities;
}
/**
@@ -205,6 +272,32 @@
}
/**
+ * Returns VideoProvider of the conference. This can be null.
+ *
+ * @hide
+ */
+ @Override
+ public VideoProvider getVideoProvider() {
+ if (mConferenceHost != null) {
+ return mConferenceHost.getVideoProvider();
+ }
+ return null;
+ }
+
+ /**
+ * Returns video state of conference
+ *
+ * @hide
+ */
+ @Override
+ public int getVideoState() {
+ if (mConferenceHost != null) {
+ return mConferenceHost.getVideoState();
+ }
+ return VideoProfile.VideoState.AUDIO_ONLY;
+ }
+
+ /**
* Invoked when the Conference and all its {@link Connection}s should be disconnected.
* <p>
* Hangs up the call via the conference host connection. When the host connection has been
@@ -317,6 +410,16 @@
// No-op
}
+ private int applyCapability(int capabilities, int capability) {
+ int newCapabilities = capabilities | capability;
+ return newCapabilities;
+ }
+
+ private int removeCapability(int capabilities, int capability) {
+ int newCapabilities = capabilities & ~capability;
+ return newCapabilities;
+ }
+
/**
* Updates the manage conference capability of the conference. Where there are one or more
* conference event package participants, the conference management is permitted. Where there
@@ -352,6 +455,7 @@
mConferenceHost = conferenceHost;
mConferenceHost.addConnectionListener(mConferenceHostListener);
mConferenceHost.addTelephonyConnectionListener(mTelephonyConnectionListener);
+ setState(mConferenceHost.getState());
}
/**
diff --git a/src/com/android/services/telephony/PstnPhoneCapabilitiesNotifier.java b/src/com/android/services/telephony/PstnPhoneCapabilitiesNotifier.java
new file mode 100644
index 0000000..48568d3
--- /dev/null
+++ b/src/com/android/services/telephony/PstnPhoneCapabilitiesNotifier.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2015 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.services.telephony;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.Uri;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.Message;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.PhoneProxy;
+import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.util.Preconditions;
+import com.android.phone.PhoneUtils;
+
+/**
+ * Listens to phone's capabilities changed event and notifies Telecomm. One instance of these exists
+ * for each of the telephony-based call services.
+ */
+final class PstnPhoneCapabilitiesNotifier {
+ private static final int EVENT_VIDEO_CAPABILITIES_CHANGED = 1;
+
+ private final PhoneProxy mPhoneProxy;
+ private Phone mPhoneBase;
+
+ private final Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case EVENT_VIDEO_CAPABILITIES_CHANGED:
+ handleVideoCapabilitesChanged((AsyncResult) msg.obj);
+ break;
+ default:
+ break;
+ }
+ }
+ };
+
+ private final BroadcastReceiver mRatReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED.equals(action)) {
+ String newPhone = intent.getStringExtra(PhoneConstants.PHONE_NAME_KEY);
+ Log.d(this, "Radio technology switched. Now %s is active.", newPhone);
+
+ registerForNotifications();
+ }
+ }
+ };
+
+ /*package*/
+ PstnPhoneCapabilitiesNotifier(PhoneProxy phoneProxy) {
+ Preconditions.checkNotNull(phoneProxy);
+
+ mPhoneProxy = phoneProxy;
+
+ registerForNotifications();
+
+ IntentFilter intentFilter =
+ new IntentFilter(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED);
+ mPhoneProxy.getContext().registerReceiver(mRatReceiver, intentFilter);
+ }
+
+ /*package*/
+ void teardown() {
+ unregisterForNotifications();
+ mPhoneProxy.getContext().unregisterReceiver(mRatReceiver);
+ }
+
+ private void registerForNotifications() {
+ Phone newPhone = mPhoneProxy.getActivePhone();
+ if (newPhone != mPhoneBase) {
+ unregisterForNotifications();
+
+ if (newPhone != null) {
+ Log.d(this, "Registering: " + newPhone);
+ mPhoneBase = newPhone;
+ mPhoneBase.registerForVideoCapabilityChanged(
+ mHandler, EVENT_VIDEO_CAPABILITIES_CHANGED, null);
+ }
+ }
+ }
+
+ private void unregisterForNotifications() {
+ if (mPhoneBase != null) {
+ Log.d(this, "Unregistering: " + mPhoneBase);
+ mPhoneBase.unregisterForVideoCapabilityChanged(mHandler);
+ }
+ }
+
+ private void handleVideoCapabilitesChanged(AsyncResult ar) {
+ try {
+ boolean isVideoCapable = (Boolean) ar.result;
+ Log.d(this, "handleVideoCapabilitesChanged. Video capability - " + isVideoCapable);
+ PhoneAccountHandle accountHandle =
+ PhoneUtils.makePstnPhoneAccountHandle(mPhoneProxy);
+ TelecomManager telecomMgr = TelecomManager.from(mPhoneProxy.getContext());
+ PhoneAccount oldPhoneAccount = telecomMgr.getPhoneAccount(accountHandle);
+ PhoneAccount.Builder builder = new PhoneAccount.Builder(oldPhoneAccount);
+
+ int capabilites = newCapabilities(oldPhoneAccount.getCapabilities(),
+ PhoneAccount.CAPABILITY_VIDEO_CALLING, isVideoCapable);
+ builder.setCapabilities(capabilites);
+ telecomMgr.registerPhoneAccount(builder.build());
+ } catch (Exception e) {
+ Log.d(this, "handleVideoCapabilitesChanged. Exception=" + e);
+ }
+ }
+
+ private int newCapabilities(int capabilities, int capability, boolean set) {
+ if (set) {
+ capabilities |= capability;
+ } else {
+ capabilities &= ~capability;
+ }
+ return capabilities;
+ }
+}
diff --git a/src/com/android/services/telephony/TelecomAccountRegistry.java b/src/com/android/services/telephony/TelecomAccountRegistry.java
index 799d844..866118c 100644
--- a/src/com/android/services/telephony/TelecomAccountRegistry.java
+++ b/src/com/android/services/telephony/TelecomAccountRegistry.java
@@ -57,6 +57,7 @@
private final Phone mPhone;
private final PhoneAccount mAccount;
private final PstnIncomingCallNotifier mIncomingCallNotifier;
+ private final PstnPhoneCapabilitiesNotifier mPhoneCapabilitiesNotifier;
AccountEntry(Phone phone, boolean isEmergency, boolean isDummy) {
mPhone = phone;
@@ -64,10 +65,12 @@
Log.d(this, "Registered phoneAccount: %s with handle: %s",
mAccount, mAccount.getAccountHandle());
mIncomingCallNotifier = new PstnIncomingCallNotifier((PhoneProxy) mPhone);
+ mPhoneCapabilitiesNotifier = new PstnPhoneCapabilitiesNotifier((PhoneProxy) mPhone);
}
void teardown() {
mIncomingCallNotifier.teardown();
+ mPhoneCapabilitiesNotifier.teardown();
}
/**
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index d272252..1df63e7 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -192,6 +192,17 @@
public void onConferenceParticipantsChanged(List<ConferenceParticipant> participants) {
updateConferenceParticipants(participants);
}
+
+ /**
+ * Used by the {@link com.android.internal.telephony.Connection} to report a change in the
+ * substate of the current call
+ *
+ * @param callSubstate The call substate.
+ */
+ @Override
+ public void onCallSubstateChanged(int callSubstate) {
+ setCallSubstate(callSubstate);
+ }
};
private com.android.internal.telephony.Connection mOriginalConnection;
@@ -519,11 +530,13 @@
// Set video state and capabilities
setVideoState(mOriginalConnection.getVideoState());
+ updateState();
setLocalVideoCapable(mOriginalConnection.isLocalVideoCapable());
setRemoteVideoCapable(mOriginalConnection.isRemoteVideoCapable());
setWifi(mOriginalConnection.isWifi());
setVideoProvider(mOriginalConnection.getVideoProvider());
setAudioQuality(mOriginalConnection.getAudioQuality());
+ setCallSubstate(mOriginalConnection.getCallSubstate());
if (isImsConnection()) {
mWasImsConnection = true;
@@ -677,6 +690,7 @@
break;
}
}
+ updateStatusHints();
updateConnectionCapabilities();
updateAddress();
updateMultiparty();
@@ -876,9 +890,9 @@
}
private void updateStatusHints() {
- if (mIsWifi && (mOriginalConnection.getState() == Call.State.INCOMING
- || mOriginalConnection.getState() == Call.State.ACTIVE)) {
- int labelId = mOriginalConnection.getState() == Call.State.INCOMING
+ boolean isIncoming = isValidRingingCall();
+ if (mIsWifi && (isIncoming || getState() == STATE_ACTIVE)) {
+ int labelId = isIncoming
? R.string.status_hint_label_incoming_wifi_call
: R.string.status_hint_label_wifi_call;