summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSrinivas Visvanathan <sriniv@google.com>2017-04-17 16:57:51 -0700
committerSrinivas Visvanathan <sriniv@google.com>2017-04-18 10:45:22 -0700
commitde4cf995d62280d139c05a9639832a9bf781b480 (patch)
tree13f19b47451e5c54ef86a67b7dcadc013f74ea98
parent42fd6617649dc6bdd9df6f36fc00cdef716a5002 (diff)
downloadDialer-de4cf995d62280d139c05a9639832a9bf781b480.tar.gz
Killing CallList + crash fix
- Replacing UiCallList and subclass with simple HashMap in TelecomUiCallManager. TelecomUiCallManager.getOrCreateCallContainer now does simple map search. Removed synchronization since callbacks from InCallServiceImpl are on main thread AFAICT; double-checked with logging. - OngoingCallFragment crash fix: Don't unset uiBluetoothMonitor since the fragment object can be re-used by TelecomActivity for next call. TelecomActivity only passes uiBluetoothMonitor the first time after construction. - Fixing UiCall.disconnectClause -> UiCall.disconnectCause. Bug: 37251324 Test: Made test calls, incoming, outgoing, conference. Change-Id: I63f24cc9793b4b2c4547146a836205413f106c83
-rw-r--r--src/com/android/car/dialer/OngoingCallFragment.java3
-rw-r--r--src/com/android/car/dialer/telecom/UiCall.java10
-rw-r--r--src/com/android/car/dialer/telecom/UiCallList.java86
-rw-r--r--src/com/android/car/dialer/telecom/embedded/TelecomUiCallList.java82
-rw-r--r--src/com/android/car/dialer/telecom/embedded/TelecomUiCallManager.java87
5 files changed, 74 insertions, 194 deletions
diff --git a/src/com/android/car/dialer/OngoingCallFragment.java b/src/com/android/car/dialer/OngoingCallFragment.java
index 9c322412..2eb659e2 100644
--- a/src/com/android/car/dialer/OngoingCallFragment.java
+++ b/src/com/android/car/dialer/OngoingCallFragment.java
@@ -125,7 +125,6 @@ public class OngoingCallFragment extends Fragment {
mHandler = null;
mUiCallManager = null;
mLoadedNumber = null;
- mUiBluetoothMonitor = null;
}
@Override
@@ -297,7 +296,7 @@ public class OngoingCallFragment extends Fragment {
// Toggle the visibility between the active call controls, ringing call controls,
// and no controls.
CharSequence disconnectCauseLabel = mLastRemovedCall == null ?
- null : mLastRemovedCall.getDisconnectClause();
+ null : mLastRemovedCall.getDisconnectCause();
if (mPrimaryCall == null && !TextUtils.isEmpty(disconnectCauseLabel)) {
closeDialpad();
setStateText(disconnectCauseLabel);
diff --git a/src/com/android/car/dialer/telecom/UiCall.java b/src/com/android/car/dialer/telecom/UiCall.java
index 523d893d..7b98c649 100644
--- a/src/com/android/car/dialer/telecom/UiCall.java
+++ b/src/com/android/car/dialer/telecom/UiCall.java
@@ -26,7 +26,7 @@ public class UiCall {
private int mState;
private boolean mHasParent;
private String mNumber;
- private CharSequence mDisconnectClause;
+ private CharSequence mDisconnectCause;
private boolean mHasChildren;
private Uri mGatewayInfoOriginalAddress;
private long connectTimeMillis;
@@ -71,12 +71,12 @@ public class UiCall {
mNumber = number;
}
- public CharSequence getDisconnectClause() {
- return mDisconnectClause;
+ public CharSequence getDisconnectCause() {
+ return mDisconnectCause;
}
- public void setDisconnectClause(CharSequence disconnectClause) {
- mDisconnectClause = disconnectClause;
+ public void setDisconnectCause(CharSequence disconnectCause) {
+ mDisconnectCause = disconnectCause;
}
public Uri getGatewayInfoOriginalAddress() {
diff --git a/src/com/android/car/dialer/telecom/UiCallList.java b/src/com/android/car/dialer/telecom/UiCallList.java
deleted file mode 100644
index cb730f19..00000000
--- a/src/com/android/car/dialer/telecom/UiCallList.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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.car.dialer.telecom;
-
-import android.support.v4.util.Pair;
-import android.util.SparseArray;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Holds a list of {@link UiCall} and implements convenient mapping from underlying
- * {@code Call} class to {@link UiCall}.
- */
-public abstract class UiCallList<C> {
- private Map<C, UiCall> mCallToCallInfoMap = new HashMap<>();
- private SparseArray<Pair<UiCall, C>> mIdToCallMap = new SparseArray<>();
-
- /**
- * Creates or gets existing {@code CallInfo} instance for a given key
- */
- public UiCall getOrCreate(C call) {
- if (call == null) {
- return null;
- }
- UiCall uiCall = mCallToCallInfoMap.get(call);
- if (uiCall == null) {
- uiCall = createUiCall(call);
- mCallToCallInfoMap.put(call, uiCall);
- mIdToCallMap.append(uiCall.getId(), new Pair<>(uiCall, call));
- }
- return uiCall;
- }
-
- /**
- * Returns a list of existing {@code CallInfo}.
- */
- public List<UiCall> getCalls() {
- return new ArrayList<>(mCallToCallInfoMap.values());
- }
-
- /**
- * Clears a list.
- */
- public void clearCalls() {
- mCallToCallInfoMap.clear();
- mIdToCallMap.clear();
- }
-
- /**
- * Removes {@code CallInfo} by given key.
- */
- public void remove(UiCall uiCall) {
- int callId = uiCall.getId();
- C call = getCall(callId);
- if (mCallToCallInfoMap.containsKey(call)) {
- mCallToCallInfoMap.remove(call);
- }
- mIdToCallMap.remove(callId);
- }
-
- protected C getCall(int callId) {
- return mIdToCallMap.get(callId).second;
- }
-
- public UiCall getUiCall(int callId) {
- return mIdToCallMap.get(callId).first;
- }
-
- abstract protected UiCall createUiCall(C call);
-}
diff --git a/src/com/android/car/dialer/telecom/embedded/TelecomUiCallList.java b/src/com/android/car/dialer/telecom/embedded/TelecomUiCallList.java
deleted file mode 100644
index 17e1df87..00000000
--- a/src/com/android/car/dialer/telecom/embedded/TelecomUiCallList.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * 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.car.dialer.telecom.embedded;
-
-import com.android.car.dialer.telecom.UiCall;
-import com.android.car.dialer.telecom.UiCallList;
-
-import android.telecom.Call;
-import android.telecom.DisconnectCause;
-import android.telecom.GatewayInfo;
-import android.util.Log;
-
-/**
- * Represents a list of {@link UiCall} for underlying {@link android.telecom.Call}.
- */
-public class TelecomUiCallList extends UiCallList<Call> {
- private final static String TAG = "Em.UiCallList";
-
- private volatile static int nextCarPhoneCallId = 0;
-
- private int getNewCarPhoneCallId() {
- return nextCarPhoneCallId++;
- }
-
- @Override
- protected UiCall createUiCall(Call telecomCall) {
- int id = getNewCarPhoneCallId();
-
- UiCall uiCall = new UiCall(id);
- updateCallContainerFromTelecom(uiCall, telecomCall);
- return uiCall;
- }
-
- static void updateCallContainerFromTelecom(UiCall uiCall, Call telecomCall) {
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "updateCallContainerFromTelecom: call: " + uiCall + ", telecomCall: "
- + telecomCall);
- }
-
- uiCall.setState(telecomCall.getState());
- uiCall.setHasChildren(!telecomCall.getChildren().isEmpty());
- uiCall.setHasParent(telecomCall.getParent() != null);
-
- Call.Details details = telecomCall.getDetails();
- if (details != null) {
- uiCall.setConnectTimeMillis(details.getConnectTimeMillis());
-
- DisconnectCause cause = details.getDisconnectCause();
- CharSequence causeLabel = cause == null ? null : cause.getLabel();
- uiCall.setDisconnectClause(causeLabel == null ? null : causeLabel.toString());
-
- GatewayInfo gatewayInfo = details.getGatewayInfo();
- uiCall.setGatewayInfoOriginalAddress(
- gatewayInfo == null ? null : gatewayInfo.getOriginalAddress());
-
- String number = "";
- if (gatewayInfo != null) {
- number = gatewayInfo.getOriginalAddress().getSchemeSpecificPart();
- } else if (details.getHandle() != null) {
- number = details.getHandle().getSchemeSpecificPart();
- }
- uiCall.setNumber(number);
- }
- }
-
- public Call getTelecomCall(UiCall uiCall) {
- return uiCall != null ? getCall(uiCall.getId()) : null;
- }
-}
diff --git a/src/com/android/car/dialer/telecom/embedded/TelecomUiCallManager.java b/src/com/android/car/dialer/telecom/embedded/TelecomUiCallManager.java
index f81dec32..357512f7 100644
--- a/src/com/android/car/dialer/telecom/embedded/TelecomUiCallManager.java
+++ b/src/com/android/car/dialer/telecom/embedded/TelecomUiCallManager.java
@@ -27,12 +27,17 @@ import android.os.IBinder;
import android.telecom.Call;
import android.telecom.Call.Details;
import android.telecom.CallAudioState;
+import android.telecom.DisconnectCause;
+import android.telecom.GatewayInfo;
import android.telecom.InCallService.VideoCall;
import android.telecom.TelecomManager;
import android.util.Log;
import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
/**
@@ -40,11 +45,14 @@ import java.util.concurrent.CopyOnWriteArrayList;
*/
public class TelecomUiCallManager extends UiCallManager {
- private static final String TAG = "Em.TelecomMgrImpl";
+ private static final String TAG = "Em.TelecomUiCallMgr";
+
+ // Used to assign id's to UiCall objects as they're created.
+ private static int nextCarPhoneCallId = 0;
private TelecomManager mTelecomManager;
private InCallServiceImpl mInCallService;
- private TelecomUiCallList mCallList = new TelecomUiCallList();
+ private Map<UiCall, Call> mCallMapping = new HashMap<>();
private List<CallListener> mCallListeners = new CopyOnWriteArrayList<>();
@@ -62,7 +70,7 @@ public class TelecomUiCallManager extends UiCallManager {
mContext.unbindService(mInCallServiceConnection);
mInCallService = null;
}
- mCallList.clearCalls();
+ mCallMapping.clear();
}
@Override
@@ -97,7 +105,7 @@ public class TelecomUiCallManager extends UiCallManager {
Log.d(TAG, "answerCall: " + uiCall);
}
- Call telecomCall = mCallList.getTelecomCall(uiCall);
+ Call telecomCall = mCallMapping.get(uiCall);
if (telecomCall != null) {
telecomCall.answer(0);
}
@@ -110,7 +118,7 @@ public class TelecomUiCallManager extends UiCallManager {
+ "textMessage: " + textMessage);
}
- Call telecomCall = mCallList.getTelecomCall(uiCall);
+ Call telecomCall = mCallMapping.get(uiCall);
if (telecomCall != null) {
telecomCall.reject(rejectWithMessage, textMessage);
}
@@ -122,7 +130,7 @@ public class TelecomUiCallManager extends UiCallManager {
Log.d(TAG, "disconnectCall: " + uiCall);
}
- Call telecomCall = mCallList.getTelecomCall(uiCall);
+ Call telecomCall = mCallMapping.get(uiCall);
if (telecomCall != null) {
telecomCall.disconnect();
}
@@ -130,7 +138,7 @@ public class TelecomUiCallManager extends UiCallManager {
@Override
public List<UiCall> getCalls() {
- return mCallList.getCalls();
+ return new ArrayList<>(mCallMapping.keySet());
}
@Override
@@ -189,7 +197,7 @@ public class TelecomUiCallManager extends UiCallManager {
Log.d(TAG, "holdCall: " + uiCall);
}
- Call telecomCall = mCallList.getTelecomCall(uiCall);
+ Call telecomCall = mCallMapping.get(uiCall);
if (telecomCall != null) {
telecomCall.hold();
}
@@ -201,7 +209,7 @@ public class TelecomUiCallManager extends UiCallManager {
Log.d(TAG, "unholdCall: " + uiCall);
}
- Call telecomCall = mCallList.getTelecomCall(uiCall);
+ Call telecomCall = mCallMapping.get(uiCall);
if (telecomCall != null) {
telecomCall.unhold();
}
@@ -213,7 +221,7 @@ public class TelecomUiCallManager extends UiCallManager {
Log.d(TAG, "playDtmfTone: call: " + uiCall + ", digit: " + digit);
}
- Call telecomCall = mCallList.getTelecomCall(uiCall);
+ Call telecomCall = mCallMapping.get(uiCall);
if (telecomCall != null) {
telecomCall.playDtmfTone(digit);
}
@@ -225,7 +233,7 @@ public class TelecomUiCallManager extends UiCallManager {
Log.d(TAG, "stopDtmfTone: call: " + uiCall);
}
- Call telecomCall = mCallList.getTelecomCall(uiCall);
+ Call telecomCall = mCallMapping.get(uiCall);
if (telecomCall != null) {
telecomCall.stopDtmfTone();
}
@@ -237,7 +245,7 @@ public class TelecomUiCallManager extends UiCallManager {
Log.d(TAG, "postDialContinue: call: " + uiCall + ", proceed: " + proceed);
}
- Call telecomCall = mCallList.getTelecomCall(uiCall);
+ Call telecomCall = mCallMapping.get(uiCall);
if (telecomCall != null) {
telecomCall.postDialContinue(proceed);
}
@@ -249,8 +257,8 @@ public class TelecomUiCallManager extends UiCallManager {
Log.d(TAG, "conference: call: " + uiCall + ", otherCall: " + otherUiCall);
}
- Call telecomCall = mCallList.getTelecomCall(uiCall);
- Call otherTelecomCall = mCallList.getTelecomCall(otherUiCall);
+ Call telecomCall = mCallMapping.get(uiCall);
+ Call otherTelecomCall = mCallMapping.get(otherUiCall);
if (telecomCall != null) {
telecomCall.conference(otherTelecomCall);
}
@@ -262,7 +270,7 @@ public class TelecomUiCallManager extends UiCallManager {
Log.d(TAG, "splitFromConference: call: " + uiCall);
}
- Call telecomCall = mCallList.getTelecomCall(uiCall);
+ Call telecomCall = mCallMapping.get(uiCall);
if (telecomCall != null) {
telecomCall.splitFromConference();
}
@@ -292,7 +300,7 @@ public class TelecomUiCallManager extends UiCallManager {
private void doTelecomCallRemoved(Call telecomCall) {
UiCall uiCall = getOrCreateCallContainer(telecomCall);
- mCallList.remove(uiCall);
+ mCallMapping.remove(uiCall);
for (CallListener listener : mCallListeners) {
listener.onCallRemoved(uiCall);
@@ -377,7 +385,7 @@ public class TelecomUiCallManager extends UiCallManager {
TelecomUiCallManager manager = mCarTelecomMangerRef.get();
UiCall uiCall = mCallContainerRef.get();
if (manager != null && uiCall != null) {
- TelecomUiCallList.updateCallContainerFromTelecom(uiCall, telecomCall);
+ updateCallContainerFromTelecom(uiCall, telecomCall);
manager.onCallUpdated(uiCall);
}
}
@@ -430,9 +438,50 @@ public class TelecomUiCallManager extends UiCallManager {
};
private UiCall getOrCreateCallContainer(Call telecomCall) {
- synchronized (mCallList) {
- return mCallList.getOrCreate(telecomCall);
+ for (Map.Entry<UiCall, Call> entry : mCallMapping.entrySet()) {
+ if (entry.getValue() == telecomCall) {
+ return entry.getKey();
+ }
+ }
+
+ UiCall uiCall = new UiCall(nextCarPhoneCallId++);
+ updateCallContainerFromTelecom(uiCall, telecomCall);
+ mCallMapping.put(uiCall, telecomCall);
+ return uiCall;
+ }
+
+ private static void updateCallContainerFromTelecom(UiCall uiCall, Call telecomCall) {
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "updateCallContainerFromTelecom: call: " + uiCall + ", telecomCall: "
+ + telecomCall);
+ }
+
+ uiCall.setState(telecomCall.getState());
+ uiCall.setHasChildren(!telecomCall.getChildren().isEmpty());
+ uiCall.setHasParent(telecomCall.getParent() != null);
+
+ Call.Details details = telecomCall.getDetails();
+ if (details == null) {
+ return;
}
+
+ uiCall.setConnectTimeMillis(details.getConnectTimeMillis());
+
+ DisconnectCause cause = details.getDisconnectCause();
+ uiCall.setDisconnectCause(cause == null ? null : cause.getLabel());
+
+ GatewayInfo gatewayInfo = details.getGatewayInfo();
+ uiCall.setGatewayInfoOriginalAddress(
+ gatewayInfo == null ? null : gatewayInfo.getOriginalAddress());
+
+ String number = "";
+ if (gatewayInfo != null) {
+ number = gatewayInfo.getOriginalAddress().getSchemeSpecificPart();
+ } else if (details.getHandle() != null) {
+ number = details.getHandle().getSchemeSpecificPart();
+ }
+ uiCall.setNumber(number);
+
}
private CallAudioState getCallAudioStateOrNull() {