release-request-fca2b5ac-03eb-4055-a549-b4fc2b292b64-for-git_oc-release-4049993 snap-temp-L04900000068539456
Change-Id: Ibf15bc238feea7fc70d46ead8f8ddb8722f21bf7
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index ecdf105..7ca9f11 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -1870,6 +1870,23 @@
}
}
+ /**
+ * Sets this {@link Call} to has the specified {@code parentCall}. Also sets the parent to
+ * have this call as a child.
+ * @param parentCall
+ */
+ void setParentAndChildCall(Call parentCall) {
+ setParentCall(parentCall);
+ setChildOf(parentCall);
+ }
+
+ /**
+ * Unlike {@link #setParentAndChildCall(Call)}, only sets the parent call but does NOT set
+ * the child.
+ * TODO: This is only required when adding existing connections as a workaround so that we
+ * can avoid sending the "onParentChanged" callback until later.
+ * @param parentCall The new parent call.
+ */
void setParentCall(Call parentCall) {
if (parentCall == this) {
Log.e(this, new Exception(), "setting the parent to self");
@@ -1879,20 +1896,35 @@
// nothing to do
return;
}
- Preconditions.checkState(parentCall == null || mParentCall == null);
-
- Call oldParent = mParentCall;
if (mParentCall != null) {
mParentCall.removeChildCall(this);
}
mParentCall = parentCall;
- if (mParentCall != null) {
- mParentCall.addChildCall(this);
+ }
+
+ /**
+ * To be called after {@link #setParentCall(Call)} to complete setting the parent by adding
+ * this call as a child of another call.
+ * <p>
+ * Note: The fact that the {@link Listener#onParentChanged(Call)} callback is called here seems
+ * counter-intuitive; it is done here so that when this method is called from
+ * {@link CallsManager#createCallForExistingConnection(String, ParcelableConnection)} we can
+ * delay informing InCallServices of the change in parent relationship until AFTER the call has
+ * been added to Telecom.
+ * @param parentCall The new parent for this call.
+ */
+ void setChildOf(Call parentCall) {
+ if (parentCall == null) {
+ return;
}
- Log.addEvent(this, LogUtils.Events.SET_PARENT, mParentCall);
- for (Listener l : mListeners) {
- l.onParentChanged(this);
+ if (!parentCall.getChildCalls().contains(this)) {
+ parentCall.addChildCall(this);
+
+ Log.addEvent(this, LogUtils.Events.SET_PARENT, parentCall);
+ for (Listener l : mListeners) {
+ l.onParentChanged(this);
+ }
}
}
@@ -2011,7 +2043,7 @@
* that the insurance policy lives in the framework side of things.
*/
private void fixParentAfterDisconnect() {
- setParentCall(null);
+ setParentAndChildCall(null);
}
/**
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index eb44273..499061d 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -2069,7 +2069,7 @@
Trace.beginSection("removeCall");
Log.v(this, "removeCall(%s)", call);
- call.setParentCall(null); // need to clean up parent relationship before destroying.
+ call.setParentAndChildCall(null); // clean up parent relationship before destroying.
call.removeListener(this);
call.clearConnectionService();
// TODO: clean up RTT pipes
@@ -2520,7 +2520,29 @@
if (extras != null && extras.containsKey(Connection.EXTRA_ORIGINAL_CONNECTION_ID)) {
call.setOriginalConnectionId(extras.getString(Connection.EXTRA_ORIGINAL_CONNECTION_ID));
}
+ Log.i(this, "createCallForExistingConnection: %s", connection);
+ Call parentCall = null;
+ if (!TextUtils.isEmpty(connection.getParentCallId())) {
+ String parentId = connection.getParentCallId();
+ parentCall = mCalls
+ .stream()
+ .filter(c -> c.getId().equals(parentId))
+ .findFirst()
+ .orElse(null);
+ if (parentCall != null) {
+ Log.i(this, "createCallForExistingConnection: %s added as child of %s.",
+ call.getId(),
+ parentCall.getId());
+ // Set JUST the parent property, which won't send an update to the Incall UI.
+ call.setParentCall(parentCall);
+ }
+ }
addCall(call);
+ if (parentCall != null) {
+ // Now, set the call as a child of the parent since it has been added to Telecom. This
+ // is where we will inform InCall.
+ call.setChildOf(parentCall);
+ }
return call;
}
diff --git a/src/com/android/server/telecom/ConnectionServiceWrapper.java b/src/com/android/server/telecom/ConnectionServiceWrapper.java
index 9104efe..b395adc 100644
--- a/src/com/android/server/telecom/ConnectionServiceWrapper.java
+++ b/src/com/android/server/telecom/ConnectionServiceWrapper.java
@@ -329,10 +329,10 @@
if (childCall != null) {
if (conferenceCallId == null) {
Log.d(this, "unsetting parent: %s", conferenceCallId);
- childCall.setParentCall(null);
+ childCall.setParentAndChildCall(null);
} else {
Call conferenceCall = mCallIdMapper.getCall(conferenceCallId);
- childCall.setParentCall(conferenceCall);
+ childCall.setParentAndChildCall(conferenceCall);
}
} else {
// Log.w(this, "setIsConferenced, unknown call id: %s", args.arg1);
@@ -445,7 +445,7 @@
Call childCall = mCallIdMapper.getCall(connId);
Log.d(this, "found child: %s", connId);
if (childCall != null) {
- childCall.setParentCall(conferenceCall);
+ childCall.setParentAndChildCall(conferenceCall);
}
}
}