Snap for 4683893 from 1f3efbd7efd8d72bafdf5f64bcea2358bbbebdce to pi-release
Change-Id: I1d2676186c9e462db2199e102e223040ab4bedc9
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index f3adb3f..f7f3c79 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -1734,20 +1734,28 @@
disconnect(0);
}
- /**
- * Attempts to disconnect the call through the connection service.
- */
@VisibleForTesting
- public void disconnect(long disconnectionTimeout) {
- disconnect(disconnectionTimeout, "internal" /** callingPackage */);
+ public void disconnect(String reason) {
+ disconnect(0, reason);
}
/**
* Attempts to disconnect the call through the connection service.
*/
@VisibleForTesting
- public void disconnect(long disconnectionTimeout, String callingPackage) {
- Log.addEvent(this, LogUtils.Events.REQUEST_DISCONNECT, callingPackage);
+ public void disconnect(long disconnectionTimeout) {
+ disconnect(disconnectionTimeout, "internal" /** reason */);
+ }
+
+ /**
+ * Attempts to disconnect the call through the connection service.
+ * @param reason the reason for the disconnect; used for logging purposes only. In some cases
+ * this can be a package name if the disconnect was initiated through an API such
+ * as TelecomManager.
+ */
+ @VisibleForTesting
+ public void disconnect(long disconnectionTimeout, String reason) {
+ Log.addEvent(this, LogUtils.Events.REQUEST_DISCONNECT, reason);
// Track that the call is now locally disconnecting.
setLocallyDisconnecting(true);
@@ -1868,7 +1876,7 @@
*/
@VisibleForTesting
public void reject(boolean rejectWithMessage, String textMessage) {
- reject(rejectWithMessage, textMessage, "internal" /** callingPackage */);
+ reject(rejectWithMessage, textMessage, "internal" /** reason */);
}
/**
@@ -1876,9 +1884,11 @@
*
* @param rejectWithMessage Whether to send a text message as part of the call rejection.
* @param textMessage An optional text message to send as part of the rejection.
+ * @param reason The reason for the reject; used for logging purposes. May be a package name
+ * if the reject is initiated from an API such as TelecomManager.
*/
@VisibleForTesting
- public void reject(boolean rejectWithMessage, String textMessage, String callingPackage) {
+ public void reject(boolean rejectWithMessage, String textMessage, String reason) {
// Check to verify that the call is still in the ringing state. A call can change states
// between the time the user hits 'reject' and Telecomm receives the command.
if (isRinging("reject")) {
@@ -1891,7 +1901,7 @@
Log.e(this, new NullPointerException(),
"reject call failed due to null CS callId=%s", getId());
}
- Log.addEvent(this, LogUtils.Events.REQUEST_REJECT, callingPackage);
+ Log.addEvent(this, LogUtils.Events.REQUEST_REJECT, reason);
}
}
@@ -1900,6 +1910,10 @@
*/
@VisibleForTesting
public void hold() {
+ hold(null /* reason */);
+ }
+
+ public void hold(String reason) {
if (mState == CallState.ACTIVE) {
if (mConnectionService != null) {
mConnectionService.hold(this);
@@ -1907,7 +1921,7 @@
Log.e(this, new NullPointerException(),
"hold call failed due to null CS callId=%s", getId());
}
- Log.addEvent(this, LogUtils.Events.REQUEST_HOLD);
+ Log.addEvent(this, LogUtils.Events.REQUEST_HOLD, reason);
}
}
@@ -1916,6 +1930,10 @@
*/
@VisibleForTesting
public void unhold() {
+ unhold(null /* reason */);
+ }
+
+ public void unhold(String reason) {
if (mState == CallState.ON_HOLD) {
if (mConnectionService != null) {
mConnectionService.unhold(this);
@@ -1923,7 +1941,7 @@
Log.e(this, new NullPointerException(),
"unhold call failed due to null CS callId=%s", getId());
}
- Log.addEvent(this, LogUtils.Events.REQUEST_UNHOLD);
+ Log.addEvent(this, LogUtils.Events.REQUEST_UNHOLD, reason);
}
}
diff --git a/src/com/android/server/telecom/CallAudioManager.java b/src/com/android/server/telecom/CallAudioManager.java
index 7bc2519..56f8db9 100644
--- a/src/com/android/server/telecom/CallAudioManager.java
+++ b/src/com/android/server/telecom/CallAudioManager.java
@@ -388,7 +388,8 @@
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
public void onRingerModeChange() {
- mCallAudioModeStateMachine.sendMessage(CallAudioModeStateMachine.RINGER_MODE_CHANGE);
+ mCallAudioModeStateMachine.sendMessageWithArgs(
+ CallAudioModeStateMachine.RINGER_MODE_CHANGE, makeArgsForModeStateMachine());
}
@VisibleForTesting
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index ac3500e..334667c 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -286,7 +286,8 @@
ConnectionServiceFocusManager.ConnectionServiceFocus connectionService) {
mCalls.stream()
.filter(c -> c.getConnectionServiceWrapper().equals(connectionService))
- .forEach(c -> c.disconnect());
+ .forEach(c -> c.disconnect("release " +
+ connectionService.getComponentName().getPackageName()));
}
@Override
@@ -1491,7 +1492,7 @@
// service, then disconnect it, otherwise allow the connection service to
// figure out the right states.
if (activeCall.getConnectionService() != call.getConnectionService()) {
- activeCall.disconnect();
+ activeCall.disconnect("Can't hold when answering " + call.getId());
}
}
}
@@ -1683,25 +1684,27 @@
Log.w(this, "Unknown call (%s) asked to be removed from hold", call);
} else {
Call activeCall = (Call) mConnectionSvrFocusMgr.getCurrentFocusCall();
+ String activeCallId = null;
if (activeCall != null) {
+ activeCallId = activeCall.getId();
if (canHold(activeCall)) {
- activeCall.hold();
- Log.addEvent(activeCall, LogUtils.Events.SWAP);
- Log.addEvent(call, LogUtils.Events.SWAP);
+ activeCall.hold("Swap to " + call.getId());
+ Log.addEvent(activeCall, LogUtils.Events.SWAP, "To " + call.getId());
+ Log.addEvent(call, LogUtils.Events.SWAP, "From " + activeCall.getId());
} else {
// This call does not support hold. If it is from a different connection
// service, then disconnect it, otherwise invoke call.hold() and allow the
// connection service to handle the situation.
if (activeCall.getConnectionService() != call.getConnectionService()) {
- activeCall.disconnect();
+ activeCall.disconnect("Swap to " + call.getId());
} else {
- activeCall.hold();
+ activeCall.hold("Swap to " + call.getId());
}
}
}
mConnectionSvrFocusMgr.requestFocus(
call,
- new RequestCallback(new ActionUnHoldCall(call)));
+ new RequestCallback(new ActionUnHoldCall(call, activeCallId)));
}
}
@@ -1879,7 +1882,7 @@
if (makeRoomForOutgoingCall(call, false /* isEmergencyCall */)) {
call.startCreateConnection(mPhoneAccountRegistrar);
} else {
- call.disconnect();
+ call.disconnect("no room");
}
if (setDefault) {
@@ -2838,7 +2841,7 @@
if (isEmergency && !canHold(liveCall)) {
call.getAnalytics().setCallIsAdditional(true);
liveCall.getAnalytics().setCallIsInterrupted(true);
- liveCall.disconnect();
+ liveCall.disconnect("emergency, can't hold");
return true;
}
@@ -2881,7 +2884,7 @@
Log.i(this, "makeRoomForOutgoingCall: holding live call.");
call.getAnalytics().setCallIsAdditional(true);
liveCall.getAnalytics().setCallIsInterrupted(true);
- liveCall.hold();
+ liveCall.hold("calling " + call.getId());
return true;
}
@@ -3180,7 +3183,7 @@
// We are going to place the new outgoing call, so disconnect any ongoing self-managed
// calls which are ongoing at this time.
- disconnectSelfManagedCalls();
+ disconnectSelfManagedCalls("outgoing call " + callId);
// Kick of the new outgoing call intent from where it left off prior to confirming the
// call.
@@ -3242,14 +3245,14 @@
/**
* Disconnects all self-managed calls.
*/
- private void disconnectSelfManagedCalls() {
+ private void disconnectSelfManagedCalls(String reason) {
// Disconnect all self-managed calls to make priority for emergency call.
// Use Call.disconnect() to command the ConnectionService to disconnect the calls.
// CallsManager.markCallAsDisconnected doesn't actually tell the ConnectionService to
// disconnect.
mCalls.stream()
.filter(c -> c.isSelfManaged())
- .forEach(c -> c.disconnect());
+ .forEach(c -> c.disconnect(reason));
// When disconnecting all self-managed calls, switch audio routing back to the baseline
// route. This ensures if, for example, the self-managed ConnectionService was routed to
@@ -3259,11 +3262,13 @@
}
private void disconnectCallsHaveDifferentConnectionService(Call exceptCall) {
+ String csPackage = exceptCall.getConnectionService() != null ?
+ exceptCall.getConnectionService().getComponentName().toShortString() : "null";
mCalls.stream().filter(c ->
c.getConnectionService() != exceptCall.getConnectionService()
&& c.getConnectionManagerPhoneAccount()
!= exceptCall.getConnectionManagerPhoneAccount())
- .forEach(c -> c.disconnect());
+ .forEach(c -> c.disconnect("CS not " + csPackage));
}
/**
@@ -3392,7 +3397,7 @@
ConnectionServiceWrapper service = call.getConnectionService();
service.handoverFailed(call, reason);
call.setDisconnectCause(new DisconnectCause(DisconnectCause.CANCELED));
- call.disconnect();
+ call.disconnect("handover failed");
}
/**
@@ -3572,7 +3577,7 @@
} else {
if (call.isEmergencyCall()) {
// Disconnect all self-managed calls to make priority for emergency call.
- disconnectSelfManagedCalls();
+ disconnectSelfManagedCalls("emergency call");
}
call.startCreateConnection(mPhoneAccountRegistrar);
@@ -3789,15 +3794,17 @@
private final class ActionUnHoldCall implements PendingAction {
private final Call mCall;
+ private final String mPreviouslyHeldCallId;
- ActionUnHoldCall(Call call) {
+ ActionUnHoldCall(Call call, String previouslyHeldCallId) {
mCall = call;
+ mPreviouslyHeldCallId = previouslyHeldCallId;
}
@Override
public void performAction() {
Log.d(this, "perform unhold call for %s", mCall);
- mCall.unhold();
+ mCall.unhold("held " + mPreviouslyHeldCallId);
}
}
diff --git a/src/com/android/server/telecom/ConnectionServiceFocusManager.java b/src/com/android/server/telecom/ConnectionServiceFocusManager.java
index f296502..649a9d1 100644
--- a/src/com/android/server/telecom/ConnectionServiceFocusManager.java
+++ b/src/com/android/server/telecom/ConnectionServiceFocusManager.java
@@ -17,6 +17,7 @@
package com.android.server.telecom;
import android.annotation.Nullable;
+import android.content.ComponentName;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -64,6 +65,12 @@
* @see {@link ConnectionServiceFocusListener}.
*/
void setConnectionServiceFocusListener(ConnectionServiceFocusListener listener);
+
+ /**
+ * Get the {@link ComponentName} of the ConnectionService for logging purposes.
+ * @return the {@link ComponentName}.
+ */
+ ComponentName getComponentName();
}
/**
diff --git a/src/com/android/server/telecom/ServiceBinder.java b/src/com/android/server/telecom/ServiceBinder.java
index 44ddc24..f7844b4 100644
--- a/src/com/android/server/telecom/ServiceBinder.java
+++ b/src/com/android/server/telecom/ServiceBinder.java
@@ -309,7 +309,7 @@
}
}
- final ComponentName getComponentName() {
+ public final ComponentName getComponentName() {
return mComponentName;
}
diff --git a/testapps/res/layout/self_managed_call_list_item.xml b/testapps/res/layout/self_managed_call_list_item.xml
index 7e149a8..66b5b21 100644
--- a/testapps/res/layout/self_managed_call_list_item.xml
+++ b/testapps/res/layout/self_managed_call_list_item.xml
@@ -72,5 +72,10 @@
android:layout_height="wrap_content"
android:text="Earpiece"
android:id="@+id/earpieceButton" />
+ <CheckBox
+ android:id="@+id/holdable"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" android:layout_weight="1"
+ android:text="Holdable"/>
</LinearLayout>
</LinearLayout>
\ No newline at end of file
diff --git a/testapps/res/layout/self_managed_sample_main.xml b/testapps/res/layout/self_managed_sample_main.xml
index e55de33..68ae65c 100644
--- a/testapps/res/layout/self_managed_sample_main.xml
+++ b/testapps/res/layout/self_managed_sample_main.xml
@@ -30,43 +30,42 @@
android:layout_height="wrap_content"
android:text="This app provides two sample implementations of the self-managed ConnectionService API. Use this UI to add simulated self-managed calls:" />
- <RadioGroup
+ <LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
- <RadioButton
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Sample Source 1"
- android:id="@+id/useAcct1Button"
- android:background="@color/test_call_a_color"/>
- <RadioButton
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Sample Source 2"
- android:id="@+id/useAcct2Button"
- android:background="@color/test_call_b_color"/>
- </RadioGroup>
-
- <RadioGroup
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
- <RadioButton
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Video Call"
- android:id="@+id/videoCallButton"/>
- <RadioButton
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Audio Call"
- android:id="@+id/audioCallButton"/>
- </RadioGroup>
+ <TextView
+ android:id="@+id/textView"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" android:layout_weight="1"
+ android:text="Acct:"/>
+ <RadioGroup
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="1" android:orientation="horizontal">
+ <RadioButton
+ android:id="@+id/useAcct1Button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:background="@color/test_call_a_color"
+ android:checked="true" android:text="1"/>
+ <RadioButton
+ android:id="@+id/useAcct2Button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:background="@color/test_call_b_color"
+ android:text="2"/>
+ </RadioGroup>
+ <TextView
+ android:id="@+id/hasFocus"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" android:layout_weight="1"
+ android:text="👎 No Focus 👎"/>
+ </LinearLayout>
<LinearLayout android:orientation="horizontal"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -76,6 +75,16 @@
android:layout_height="wrap_content"
android:id="@+id/phoneNumber"
android:text="tel:555-1212"/>
+ <CheckBox
+ android:id="@+id/holdable"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" android:layout_weight="1"
+ android:checked="true" android:text="Holdable"/>
+ <CheckBox
+ android:id="@+id/videoCall"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" android:layout_weight="1"
+ android:text="Video"/>
</LinearLayout>
<LinearLayout android:orientation="horizontal"
@@ -83,20 +92,20 @@
android:layout_height="wrap_content">
<Button
+ android:id="@+id/placeOutgoingCallButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="Outgoing Call"
- android:id="@+id/placeOutgoingCallButton" />
+ android:text="Outgoing"/>
<Button
+ android:id="@+id/placeIncomingCallButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="Incoming Call"
- android:id="@+id/placeIncomingCallButton" />
+ android:text="Incoming"/>
<Button
+ android:id="@+id/handoverFrom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="Handover From"
- android:id="@+id/handoverFrom" />
+ android:text="Accept Handover"/>
</LinearLayout>
<ListView
diff --git a/testapps/src/com/android/server/telecom/testapps/SelfManagedCallList.java b/testapps/src/com/android/server/telecom/testapps/SelfManagedCallList.java
index f9bce35..8518adc 100644
--- a/testapps/src/com/android/server/telecom/testapps/SelfManagedCallList.java
+++ b/testapps/src/com/android/server/telecom/testapps/SelfManagedCallList.java
@@ -40,6 +40,8 @@
public void onCreateIncomingConnectionFailed(ConnectionRequest request) {};
public void onCreateOutgoingConnectionFailed(ConnectionRequest request) {};
public void onConnectionListChanged() {};
+ public void onConnectionServiceFocusLost() {};
+ public void onConnectionServiceFocusGained() {};
}
public static String SELF_MANAGED_ACCOUNT_1 = "1";
@@ -136,6 +138,18 @@
}
}
+ public void notifyConnectionServiceFocusGained() {
+ if (mListener != null) {
+ mListener.onConnectionServiceFocusGained();
+ }
+ }
+
+ public void notifyConnectionServiceFocusLost() {
+ if (mListener != null) {
+ mListener.onConnectionServiceFocusLost();
+ }
+ }
+
public void addConnection(SelfManagedConnection connection) {
Log.i(this, "addConnection %s", connection);
mConnections.add(connection);
diff --git a/testapps/src/com/android/server/telecom/testapps/SelfManagedCallListAdapter.java b/testapps/src/com/android/server/telecom/testapps/SelfManagedCallListAdapter.java
index 71e8922..8eaa282 100644
--- a/testapps/src/com/android/server/telecom/testapps/SelfManagedCallListAdapter.java
+++ b/testapps/src/com/android/server/telecom/testapps/SelfManagedCallListAdapter.java
@@ -17,6 +17,7 @@
package com.android.server.telecom.testapps;
import android.telecom.CallAudioState;
+import android.telecom.Connection;
import android.telecom.DisconnectCause;
import android.telecom.PhoneAccountHandle;
import android.util.Log;
@@ -24,6 +25,7 @@
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
+import android.widget.CheckBox;
import android.widget.TextView;
import com.android.server.telecom.testapps.R;
@@ -102,6 +104,22 @@
}
};
+ private View.OnClickListener mHoldableListener = new View.OnClickListener() {
+ @Override
+ public void onClick (View v) {
+ View parent = (View) v.getParent().getParent();
+ SelfManagedConnection connection = (SelfManagedConnection) parent.getTag();
+ int capabilities = connection.getConnectionCapabilities();
+ if ((capabilities & Connection.CAPABILITY_HOLD) == Connection.CAPABILITY_HOLD) {
+ capabilities &= ~(Connection.CAPABILITY_HOLD | Connection.CAPABILITY_SUPPORT_HOLD);
+ } else {
+ capabilities |= (Connection.CAPABILITY_HOLD | Connection.CAPABILITY_SUPPORT_HOLD);
+ }
+ connection.setConnectionCapabilities(capabilities);
+ notifyDataSetChanged();
+ }
+ };
+
private final LayoutInflater mLayoutInflater;
private List<SelfManagedConnection> mConnections;
@@ -175,7 +193,8 @@
}
setInfoForRow(result, phoneAccountHandle.getId(), connection.getAddress().toString(),
android.telecom.Connection.stateToString(connection.getState()), audioRoute,
- callType, connection.getState() == android.telecom.Connection.STATE_RINGING);
+ callType, connection.getState() == android.telecom.Connection.STATE_RINGING,
+ connection.isHoldable());
result.setTag(connection);
return result;
}
@@ -188,7 +207,7 @@
private void setInfoForRow(View view, String accountName, String number,
String status, String audioRoute, String callType,
- boolean isRinging) {
+ boolean isRinging, boolean isHoldable) {
TextView numberTextView = (TextView) view.findViewById(R.id.phoneNumber);
TextView statusTextView = (TextView) view.findViewById(R.id.callState);
@@ -207,6 +226,9 @@
missedButton.setVisibility(isRinging ? View.VISIBLE : View.GONE);
setHeldButton.setVisibility(!isRinging ? View.VISIBLE : View.GONE);
disconnectButton.setVisibility(!isRinging ? View.VISIBLE : View.GONE);
+ CheckBox holdableCheckbox = view.findViewById(R.id.holdable);
+ holdableCheckbox.setOnClickListener(mHoldableListener);
+ holdableCheckbox.setChecked(isHoldable);
numberTextView.setText(accountName + " - " + number + " (" + audioRoute + ")");
statusTextView.setText(callType + " - Status: " + status);
}
diff --git a/testapps/src/com/android/server/telecom/testapps/SelfManagedCallingActivity.java b/testapps/src/com/android/server/telecom/testapps/SelfManagedCallingActivity.java
index 6139e33..a7b1350 100644
--- a/testapps/src/com/android/server/telecom/testapps/SelfManagedCallingActivity.java
+++ b/testapps/src/com/android/server/telecom/testapps/SelfManagedCallingActivity.java
@@ -31,6 +31,7 @@
import android.widget.EditText;
import android.widget.ListView;
import android.widget.RadioButton;
+import android.widget.TextView;
import android.widget.Toast;
import com.android.server.telecom.testapps.R;
@@ -50,10 +51,12 @@
private Button mHandoverFrom;
private RadioButton mUseAcct1Button;
private RadioButton mUseAcct2Button;
- private RadioButton mVideoCallButton;
- private RadioButton mAudioCallButton;
+ private CheckBox mHoldableCheckbox;
+ private CheckBox mVideoCallCheckbox;
private EditText mNumber;
private ListView mListView;
+ private TextView mHasFocus;
+
private SelfManagedCallListAdapter mListAdapter;
private SelfManagedCallList.Listener mCallListListener = new SelfManagedCallList.Listener() {
@@ -76,6 +79,16 @@
Log.i(TAG, "onConnectionListChanged");
mListAdapter.updateConnections();
};
+
+ @Override
+ public void onConnectionServiceFocusLost() {
+ mHasFocus.setText("\uD83D\uDC4E No Focus \uD83D\uDC4E");
+ };
+
+ @Override
+ public void onConnectionServiceFocusGained() {
+ mHasFocus.setText("\uD83D\uDC4D Has Focus \uD83D\uDC4D");
+ };
};
@Override
@@ -109,10 +122,11 @@
placeIncomingCall(true /* isHandoverFrom */);
}));
- mUseAcct1Button = (RadioButton) findViewById(R.id.useAcct1Button);
- mUseAcct2Button = (RadioButton) findViewById(R.id.useAcct2Button);
- mVideoCallButton = (RadioButton) findViewById(R.id.videoCallButton);
- mAudioCallButton = (RadioButton) findViewById(R.id.audioCallButton);
+ mUseAcct1Button = findViewById(R.id.useAcct1Button);
+ mUseAcct2Button = findViewById(R.id.useAcct2Button);
+ mHasFocus = findViewById(R.id.hasFocus);
+ mVideoCallCheckbox = findViewById(R.id.videoCall);
+ mHoldableCheckbox = findViewById(R.id.holdable);
mNumber = (EditText) findViewById(R.id.phoneNumber);
mListView = (ListView) findViewById(R.id.callList);
mCallList.setListener(mCallListListener);
@@ -146,10 +160,14 @@
Bundle extras = new Bundle();
extras.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
getSelectedPhoneAccountHandle());
- if (mVideoCallButton.isChecked()) {
+ if (mVideoCallCheckbox.isChecked()) {
extras.putInt(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE,
VideoProfile.STATE_BIDIRECTIONAL);
}
+ Bundle clientExtras = new Bundle();
+ clientExtras.putBoolean(SelfManagedConnectionService.EXTRA_HOLDABLE,
+ mHoldableCheckbox.isChecked());
+ extras.putBundle(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, clientExtras);
tm.placeCall(Uri.parse(mNumber.getText().toString()), extras);
}
@@ -167,7 +185,9 @@
Bundle extras = new Bundle();
extras.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS,
Uri.parse(mNumber.getText().toString()));
- if (mVideoCallButton.isChecked()) {
+ extras.putBoolean(SelfManagedConnectionService.EXTRA_HOLDABLE,
+ mHoldableCheckbox.isChecked());
+ if (mVideoCallCheckbox.isChecked()) {
extras.putInt(TelecomManager.EXTRA_INCOMING_VIDEO_STATE,
VideoProfile.STATE_BIDIRECTIONAL);
}
diff --git a/testapps/src/com/android/server/telecom/testapps/SelfManagedConnection.java b/testapps/src/com/android/server/telecom/testapps/SelfManagedConnection.java
index a84dd90..8d0af04 100644
--- a/testapps/src/com/android/server/telecom/testapps/SelfManagedConnection.java
+++ b/testapps/src/com/android/server/telecom/testapps/SelfManagedConnection.java
@@ -138,11 +138,17 @@
@Override
public void onHold() {
+ if (mMediaPlayer != null) {
+ mMediaPlayer.pause();
+ }
setOnHold();
}
@Override
public void onUnhold() {
+ if (mMediaPlayer != null) {
+ mMediaPlayer.start();
+ }
setActive();
}
@@ -218,6 +224,10 @@
return mIsHandover;
}
+ public boolean isHoldable() {
+ return (getConnectionCapabilities() & Connection.CAPABILITY_HOLD) != 0;
+ }
+
private MediaPlayer createMediaPlayer(Context context) {
int audioToPlay = (Math.random() > 0.5f) ? R.raw.sample_audio : R.raw.sample_audio2;
MediaPlayer mediaPlayer = MediaPlayer.create(context, audioToPlay);
diff --git a/testapps/src/com/android/server/telecom/testapps/SelfManagedConnectionService.java b/testapps/src/com/android/server/telecom/testapps/SelfManagedConnectionService.java
index 12d1552..d5d79af 100644
--- a/testapps/src/com/android/server/telecom/testapps/SelfManagedConnectionService.java
+++ b/testapps/src/com/android/server/telecom/testapps/SelfManagedConnectionService.java
@@ -35,6 +35,7 @@
* See {@link android.telecom} for more information on self-managed {@link ConnectionService}s.
*/
public class SelfManagedConnectionService extends ConnectionService {
+ public static final String EXTRA_HOLDABLE = "com.android.server.telecom.testapps.HOLDABLE";
private static final String[] TEST_NAMES = {"Tom Smith", "Jane Appleseed", "Joseph Engleton",
"Claudia McPherson", "Chris P. Bacon", "Seymour Butz", "Hugh Mungus", "Anita Bath"};
private final SelfManagedCallList mCallList = SelfManagedCallList.getInstance();
@@ -65,6 +66,17 @@
mCallList.notifyCreateOutgoingConnectionFailed(request);
}
+ @Override
+ public void onConnectionServiceFocusLost() {
+ mCallList.notifyConnectionServiceFocusLost();
+ connectionServiceFocusReleased();
+ }
+
+ @Override
+ public void onConnectionServiceFocusGained() {
+ mCallList.notifyConnectionServiceFocusGained();
+ }
+
private Connection createSelfManagedConnection(ConnectionRequest request, boolean isIncoming) {
SelfManagedConnection connection = new SelfManagedConnection(mCallList,
getApplicationContext(), isIncoming);
@@ -83,11 +95,17 @@
}
Bundle requestExtras = request.getExtras();
if (requestExtras != null) {
- Log.i(this, "createConnection: isHandover=%b, handoverFrom=%s",
+ boolean isHoldable = requestExtras.getBoolean(EXTRA_HOLDABLE, false);
+ Log.i(this, "createConnection: isHandover=%b, handoverFrom=%s, holdable=%b",
requestExtras.getBoolean(TelecomManager.EXTRA_IS_HANDOVER),
- requestExtras.getString(TelecomManager.EXTRA_HANDOVER_FROM_PHONE_ACCOUNT));
+ requestExtras.getString(TelecomManager.EXTRA_HANDOVER_FROM_PHONE_ACCOUNT),
+ isHoldable);
connection.setIsHandover(requestExtras.getBoolean(TelecomManager.EXTRA_IS_HANDOVER,
false));
+ if (isHoldable) {
+ connection.setConnectionCapabilities(connection.getConnectionCapabilities() |
+ Connection.CAPABILITY_HOLD | Connection.CAPABILITY_SUPPORT_HOLD);
+ }
if (!isIncoming && connection.isHandover()) {
Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION | Intent.FLAG_ACTIVITY_NEW_TASK);